[docs] updates to autodoc
This commit is contained in:
parent
022ae69f7e
commit
bb87203147
14 changed files with 118 additions and 28 deletions
|
|
@ -9,19 +9,34 @@ from frappe.website.render import clear_cache
|
|||
from frappe.model.document import Document
|
||||
|
||||
class Comment(Document):
|
||||
"""Comments are added to Documents via forms or views like blogs etc."""
|
||||
__doclink__ = "https://frappe.io/docs/models/core/comment"
|
||||
def get_feed(self):
|
||||
"""Returns feed HTML from Comment."""
|
||||
return """<a href="#Form/{0}/{1}">{0} {1}</a>: <i>{2}</i>""".format(self.comment_doctype, self.comment_docname,
|
||||
self.comment)
|
||||
|
||||
def validate(self):
|
||||
"""Raise exception for more than 50 comments."""
|
||||
if frappe.db.sql("""select count(*) from tabComment where comment_doctype=%s
|
||||
and comment_docname=%s""", (self.doctype, self.name))[0][0] >= 50:
|
||||
frappe.throw(_("Cannot add more than 50 comments"))
|
||||
|
||||
def on_update(self):
|
||||
"""Updates `_comments` property in parent Document."""
|
||||
self.update_comment_in_doc()
|
||||
|
||||
def update_comment_in_doc(self):
|
||||
"""Updates `_comments` (JSON) property in parent Document.
|
||||
Creates a column `_comments` if property does not exist.
|
||||
|
||||
`_comments` format
|
||||
|
||||
{
|
||||
"comment": [String],
|
||||
"by": [user],
|
||||
"name": [Comment Document name]
|
||||
}"""
|
||||
if self.comment_doctype and self.comment_docname and self.comment and self.comment_type=="Comment":
|
||||
try:
|
||||
_comments = self.get_comments_from_parent()
|
||||
|
|
@ -53,11 +68,15 @@ class Comment(Document):
|
|||
raise
|
||||
|
||||
def get_comments_from_parent(self):
|
||||
"""Returns dict of `_comments` from parent."""
|
||||
_comments = frappe.db.get_value(self.comment_doctype,
|
||||
self.comment_docname, "_comments") or "[]"
|
||||
return json.loads(_comments)
|
||||
|
||||
def update_comments_in_parent(self, _comments):
|
||||
"""Updates `_comments` property in parent Document with given dict.
|
||||
|
||||
:param _comments: Dict of comments."""
|
||||
# use sql, so that we do not mess with the timestamp
|
||||
frappe.db.sql("""update `tab%s` set `_comments`=%s where name=%s""" % (self.comment_doctype,
|
||||
"%s", "%s"), (json.dumps(_comments), self.comment_docname))
|
||||
|
|
@ -67,6 +86,7 @@ class Comment(Document):
|
|||
clear_cache(comment_doc.get_route())
|
||||
|
||||
def on_trash(self):
|
||||
"""Removes from `_comments` in parent Document"""
|
||||
if (self.comment_type or "Comment") != "Comment":
|
||||
frappe.only_for("System Manager")
|
||||
|
||||
|
|
@ -78,6 +98,7 @@ class Comment(Document):
|
|||
self.update_comments_in_parent(_comments)
|
||||
|
||||
def on_doctype_update():
|
||||
"""Add index to `tabComment` `(comment_doctype, comment_name)`"""
|
||||
if not frappe.db.sql("""show index from `tabComment`
|
||||
where Key_name="comment_doctype_docname_index" """):
|
||||
frappe.db.commit()
|
||||
|
|
|
|||
|
|
@ -12,11 +12,14 @@ from frappe import _
|
|||
from frappe.model.document import Document
|
||||
|
||||
class Communication(Document):
|
||||
"""Communication represents an external communication like Email."""
|
||||
def validate(self):
|
||||
"""Set default sender email_id from current user."""
|
||||
if not self.sender:
|
||||
self.sender = frappe.db.get_value("User", frappe.session.user, "email")
|
||||
|
||||
def get_parent_doc(self):
|
||||
"""Returns document of `reference_doctype`, `reference_doctype`"""
|
||||
if not hasattr(self, "parent_doc"):
|
||||
if self.reference_doctype and self.reference_name:
|
||||
self.parent_doc = frappe.get_doc(self.reference_doctype, self.reference_name)
|
||||
|
|
@ -25,10 +28,11 @@ class Communication(Document):
|
|||
return self.parent_doc
|
||||
|
||||
def on_update(self):
|
||||
"""Update parent status as `Open` or `Replied`."""
|
||||
self.update_parent()
|
||||
|
||||
def update_parent(self):
|
||||
"""update status of parent Lead or Contact based on who is replying"""
|
||||
"""Update status of parent document based on who is replying."""
|
||||
parent = self.get_parent_doc()
|
||||
if not parent:
|
||||
return
|
||||
|
|
@ -41,6 +45,11 @@ class Communication(Document):
|
|||
|
||||
def send(self, send_me_a_copy=False, print_html=None, print_format=None,
|
||||
attachments=None):
|
||||
"""Send communication via Email.
|
||||
|
||||
:param send_me_a_copy: **cc** to current user.
|
||||
:param print_html: Send given value as HTML attachment.
|
||||
:param print_format: Attach print format of parent document."""
|
||||
if print_format:
|
||||
self.content += self.get_attach_link(print_format)
|
||||
mail = get_email(self.recipients, sender=self.sender, subject=self.subject,
|
||||
|
|
@ -66,6 +75,7 @@ class Communication(Document):
|
|||
frappe.email.smtp.send(mail)
|
||||
|
||||
def get_attach_link(self, print_format):
|
||||
"""Returns public link for the attachment via `templates/emails/print_link.html`."""
|
||||
return frappe.get_template("templates/emails/print_link.html").render({
|
||||
"url": get_url(),
|
||||
"doctype": self.reference_doctype,
|
||||
|
|
@ -75,12 +85,28 @@ class Communication(Document):
|
|||
})
|
||||
|
||||
def on_doctype_update():
|
||||
"""Add index in `tabCommunication` for `(reference_doctype, reference_name)`"""
|
||||
frappe.db.add_index("Communication", ["reference_doctype", "reference_name"])
|
||||
|
||||
@frappe.whitelist()
|
||||
def make(doctype=None, name=None, content=None, subject=None, sent_or_received = "Sent",
|
||||
sender=None, recipients=None, communication_medium="Email", send_email=False,
|
||||
print_html=None, print_format=None, attachments='[]', send_me_a_copy=False, set_lead=True, date=None):
|
||||
print_html=None, print_format=None, attachments='[]', send_me_a_copy=False):
|
||||
"""Make a new communication.
|
||||
|
||||
:param doctype: Reference DocType.
|
||||
:param name: Reference Document name.
|
||||
:param content: Communication body.
|
||||
:param subject: Communication subject.
|
||||
:param sent_or_received: Sent or Received (default **Sent**).
|
||||
:param sender: Communcation sender (default current user).
|
||||
:param recipients: Communication recipients as list.
|
||||
:param communication_medium: Medium of communication (default **Email**).
|
||||
:param send_mail: Send via email (default **False**).
|
||||
:param print_html: HTML Print format to be sent as attachment.
|
||||
:param print_format: Print Format name of parent document to be sent as attachment.
|
||||
:param attachments: List of attachments as list of files or JSON string.
|
||||
:param send_me_a_copy: Set current user as **cc** in email."""
|
||||
|
||||
if doctype and name and not frappe.has_permission(doctype, "email", name):
|
||||
raise frappe.PermissionError("You are not allowed to send emails related to: {doctype} {name}".format(
|
||||
|
|
|
|||
|
|
@ -8,16 +8,17 @@ from frappe.model.document import Document
|
|||
|
||||
class DefaultValue(Document):
|
||||
pass
|
||||
|
||||
|
||||
def on_doctype_update():
|
||||
if not frappe.db.sql("""show index from `tabDefaultValue`
|
||||
"""Create indexes for `tabDefaultValue` on `(parent, defkey)`"""
|
||||
if not frappe.db.sql("""show index from `tabDefaultValue`
|
||||
where Key_name="defaultvalue_parent_defkey_index" """):
|
||||
frappe.db.commit()
|
||||
frappe.db.sql("""alter table `tabDefaultValue`
|
||||
frappe.db.sql("""alter table `tabDefaultValue`
|
||||
add index defaultvalue_parent_defkey_index(parent, defkey)""")
|
||||
|
||||
if not frappe.db.sql("""show index from `tabDefaultValue`
|
||||
if not frappe.db.sql("""show index from `tabDefaultValue`
|
||||
where Key_name="defaultvalue_parent_parenttype_index" """):
|
||||
frappe.db.commit()
|
||||
frappe.db.sql("""alter table `tabDefaultValue`
|
||||
add index defaultvalue_parent_parenttype_index(parent, parenttype)""")
|
||||
frappe.db.sql("""alter table `tabDefaultValue`
|
||||
add index defaultvalue_parent_parenttype_index(parent, parenttype)""")
|
||||
|
|
|
|||
|
|
@ -6,5 +6,5 @@ from __future__ import unicode_literals
|
|||
from frappe.model.document import Document
|
||||
|
||||
class DocField(Document):
|
||||
__doclink__ = "https://frappe.io/developers/modules/core/docfield"
|
||||
__doclink__ = "https://frappe.io/docs/models/core/docfield"
|
||||
pass
|
||||
|
|
|
|||
|
|
@ -7,4 +7,5 @@ import frappe
|
|||
from frappe.model.document import Document
|
||||
|
||||
class DocPerm(Document):
|
||||
pass
|
||||
__doclink__ = "https://frappe.io/docs/models/core/docperm"
|
||||
pass
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ form_grid_templates = {
|
|||
}
|
||||
|
||||
class DocType(Document):
|
||||
__doclink__ = "https://frappe.io/developers/modules/core/doctype"
|
||||
__doclink__ = "https://frappe.io/docs/models/core/doctype"
|
||||
def get_feed(self):
|
||||
return self.name
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import frappe, os
|
|||
from frappe.model.document import Document
|
||||
|
||||
class ModuleDef(Document):
|
||||
__doclink__ = "https://frappe.io/developers/modules/core/module_def"
|
||||
__doclink__ = "https://frappe.io/docs/models/core/module_def"
|
||||
def on_update(self):
|
||||
"""If in `developer_mode`, create folder for module and
|
||||
add in `modules.txt` of app if missing."""
|
||||
|
|
|
|||
|
|
@ -197,7 +197,7 @@ frappe.views.ReportView = frappe.ui.Listing.extend({
|
|||
// get table_name.column_name
|
||||
get_full_column_name: function(v) {
|
||||
if(!v) return;
|
||||
return (v[1] ? ('`tab' + v[1] + '`') : this.tab_name) + '.' + v[0];
|
||||
return (v[1] ? ('`tab' + v[1] + '`') : this.tab_name) + '.`' + v[0] + '`';
|
||||
},
|
||||
|
||||
// build columns for slickgrid
|
||||
|
|
|
|||
|
|
@ -1,11 +1,14 @@
|
|||
{% from "templates/autodoc/macros.html" import automodule %}
|
||||
{% from "templates/autodoc/macros.html" import automodule, version %}
|
||||
{% macro render_doctype(name) %}
|
||||
{% set doc = frappe.get_doc("DocType", name) %}
|
||||
{% set controller = autodoc.get_controller(name) %}
|
||||
{{ version(name) }}
|
||||
|
||||
{% if doc.issingle %}<span class="label label-info">Single</span>{% endif %}
|
||||
{% if doc.istable %}
|
||||
<span class="label label-info">Table</span>
|
||||
{% if doc.istable %}<span class="label label-info">Child Table</span>{% endif %}
|
||||
|
||||
{% if not doc.issingle %}
|
||||
<p><b>Table Name:</b> <code>tab{{ name }}</code></p>
|
||||
{% endif %}
|
||||
|
||||
{{ doc.description or "" }}
|
||||
|
|
@ -30,7 +33,7 @@
|
|||
<td {% if df.fieldtype=="Column Break" %}class="info"{% endif %}>
|
||||
{{ df.fieldtype }}</td>
|
||||
<td {% if df.hidden %}class="text-muted" title="Hidden"{% endif %}>
|
||||
{{ df.label }}
|
||||
{{ df.label or "" }}
|
||||
{% if df.description %}<p class="text-muted small">
|
||||
{{ df.description }}</p>{% endif %}
|
||||
</td>
|
||||
|
|
@ -46,7 +49,8 @@
|
|||
|
||||
{% if not doc.istable %}
|
||||
<hr>
|
||||
<h2>{{ controller.__module__ }}</h2>
|
||||
<h3>Controller</h3>
|
||||
<h4>{{ controller.__module__ }}</h4>
|
||||
|
||||
{{ automodule(controller.__module__) }}
|
||||
{% set parents = frappe.get_list("DocField",
|
||||
|
|
|
|||
|
|
@ -1,12 +1,19 @@
|
|||
{% macro automodule(name) %}
|
||||
{% for obj in autodoc.automodule(name) %}
|
||||
{% set m = autodoc.automodule(name) %}
|
||||
{{ version(name) }}
|
||||
{% for obj in m.members %}
|
||||
{% if obj.type=="function" %}
|
||||
{{ render_function(obj) }}
|
||||
{{ render_function(obj, name) }}
|
||||
{% elif obj.type=="class" %}
|
||||
{{ render_class(obj) }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endmacro %}
|
||||
|
||||
{% macro version(name) %}
|
||||
<p class="text-right">
|
||||
<span class="label label-default">Version {{ autodoc.get_version(name) }}</span>
|
||||
</p>
|
||||
{% endmacro %}
|
||||
|
||||
{% macro render_class(obj) %}
|
||||
|
|
@ -24,15 +31,23 @@
|
|||
{% endmacro %}
|
||||
|
||||
{% macro render_function(obj, module_name) %}
|
||||
{% set full_name = (module_name + "." if module_name else "" ) + obj.name %}
|
||||
{% if obj.whitelisted %}<p><span class="label label-info">Public API</span>
|
||||
<br><code>/api/method/{{ full_name }}</code>
|
||||
</p>{% endif %}
|
||||
<p class="docs-attr-name">
|
||||
{{ module_name + "." if module_name else "" }}<b>{{ obj.name }}</b>({{ print_args(obj.args) if obj.args else "" }})</p>
|
||||
<a name="{{ full_name }}" href="#{{ full_name }}" class="text-muted small">
|
||||
<i class="icon-link small" style="color: #ccc;"></i></a>
|
||||
{{ module_name + "." if module_name else "" }}<b>{{ obj.name }}</b>
|
||||
<i class="text-muted">({{ print_args(obj.args) if obj.args else "" }})</i>
|
||||
</p>
|
||||
<div class="docs-attr-desc">{{ obj.docs|markdown }}</div>
|
||||
<br>
|
||||
{% endmacro %}
|
||||
|
||||
{% macro print_args(args) -%}
|
||||
<i>{% for arg in args[0] -%}
|
||||
{% for arg in args[0] -%}
|
||||
{%- set default_idx = args[3]|len - args[0]|len + (loop.index - 1) if args[3] else -1 -%}
|
||||
{{ arg }}{% if default_idx >= 0 %}={{ args[3][default_idx] }}{% endif %}{% if not loop.last %}, {% endif %}
|
||||
{%- endfor %}</i>
|
||||
{%- endfor %}
|
||||
{%- endmacro %}
|
||||
|
|
|
|||
|
|
@ -39,7 +39,19 @@ def automodule(name):
|
|||
if inspect.isfunction(value):
|
||||
attributes.append(get_function_info(value))
|
||||
|
||||
return filter(None, attributes)
|
||||
return {
|
||||
"members": filter(None, attributes),
|
||||
}
|
||||
|
||||
def get_version(name):
|
||||
def _for_module(m):
|
||||
return importlib.import_module(m.split(".")[0]).__version__
|
||||
|
||||
if "." in name or name=="frappe":
|
||||
return _for_module(name)
|
||||
else:
|
||||
return _for_module(get_controller(name).__module__)
|
||||
|
||||
|
||||
def get_class_info(class_obj, module_name):
|
||||
members = []
|
||||
|
|
@ -69,7 +81,8 @@ def get_function_info(value):
|
|||
"name": value.__name__,
|
||||
"type": "function",
|
||||
"args": inspect.getargspec(value),
|
||||
"docs": parse(docs)
|
||||
"docs": parse(docs),
|
||||
"whitelisted": value in frappe.whitelisted
|
||||
}
|
||||
|
||||
def parse(docs):
|
||||
|
|
@ -91,7 +104,7 @@ def parse(docs):
|
|||
out.append("")
|
||||
title_set = True
|
||||
|
||||
line = re.sub("\s*:param\s([^:]+):(.*)", "- **\g<1>** - \g<2>", line)
|
||||
line = re.sub("\s*:param\s([^:]+):(.*)", "- **`\g<1>`** - \g<2>", line)
|
||||
|
||||
elif title_set and not ":param" in line:
|
||||
# marker for end of list
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ def get_allowed_functions_for_jenv():
|
|||
import frappe
|
||||
import frappe.utils
|
||||
import frappe.utils.data
|
||||
from frappe.utils.autodoc import automodule, get_doclink
|
||||
from frappe.utils.autodoc import automodule, get_doclink, get_version
|
||||
from frappe.model.document import get_controller
|
||||
|
||||
datautils = {}
|
||||
|
|
@ -70,6 +70,7 @@ def get_allowed_functions_for_jenv():
|
|||
"full_name": frappe.local.session.data.full_name
|
||||
},
|
||||
"autodoc": {
|
||||
"get_version": get_version,
|
||||
"get_doclink": get_doclink,
|
||||
"automodule": automodule,
|
||||
"get_controller": get_controller
|
||||
|
|
|
|||
|
|
@ -433,6 +433,10 @@ a.active {
|
|||
cursor: default;
|
||||
}
|
||||
|
||||
:target {
|
||||
background-color: #ffa;
|
||||
}
|
||||
|
||||
.page-breadcrumbs .breadcrumb {
|
||||
padding: 0px;
|
||||
margin-bottom: 2px;
|
||||
|
|
|
|||
|
|
@ -357,7 +357,8 @@ $.extend(frappe, {
|
|||
trigger_ready: function() {
|
||||
var ready = frappe.page_ready_events[frappe.get_pathname()];
|
||||
ready && ready();
|
||||
frappe.bind_filters();
|
||||
},
|
||||
hightlight_code_blocks: function() {
|
||||
if(hljs) {
|
||||
$('pre code').each(function(i, block) {
|
||||
hljs.highlightBlock(block);
|
||||
|
|
@ -580,5 +581,8 @@ $(document).on("page-change", function() {
|
|||
frappe.datetime.refresh_when();
|
||||
frappe.toggle_template_blocks();
|
||||
frappe.trigger_ready();
|
||||
frappe.bind_filters();
|
||||
frappe.hightlight_code_blocks();
|
||||
frappe.hightlight_named_link();
|
||||
frappe.make_navbar_active();
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue