From bb87203147f6e55ca803a8bd2d34e20f55137c6b Mon Sep 17 00:00:00 2001
From: Rushabh Mehta
Date: Wed, 19 Nov 2014 16:23:44 +0530
Subject: [PATCH] [docs] updates to autodoc
---
frappe/core/doctype/comment/comment.py | 21 +++++++++++++
.../doctype/communication/communication.py | 30 +++++++++++++++++--
.../core/doctype/defaultvalue/defaultvalue.py | 13 ++++----
frappe/core/doctype/docfield/docfield.py | 2 +-
frappe/core/doctype/docperm/docperm.py | 3 +-
frappe/core/doctype/doctype/doctype.py | 2 +-
frappe/core/doctype/module_def/module_def.py | 2 +-
frappe/public/js/frappe/views/reportview.js | 2 +-
frappe/templates/autodoc/doctype.html | 14 +++++----
frappe/templates/autodoc/macros.html | 25 ++++++++++++----
frappe/utils/autodoc.py | 19 ++++++++++--
frappe/utils/jinja.py | 3 +-
frappe/website/css/website.css | 4 +++
frappe/website/js/website.js | 6 +++-
14 files changed, 118 insertions(+), 28 deletions(-)
diff --git a/frappe/core/doctype/comment/comment.py b/frappe/core/doctype/comment/comment.py
index 2312064863..4380c74f8c 100644
--- a/frappe/core/doctype/comment/comment.py
+++ b/frappe/core/doctype/comment/comment.py
@@ -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 """{0} {1}: {2}""".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()
diff --git a/frappe/core/doctype/communication/communication.py b/frappe/core/doctype/communication/communication.py
index 47ecaca1e0..f9d3c1ba27 100644
--- a/frappe/core/doctype/communication/communication.py
+++ b/frappe/core/doctype/communication/communication.py
@@ -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(
diff --git a/frappe/core/doctype/defaultvalue/defaultvalue.py b/frappe/core/doctype/defaultvalue/defaultvalue.py
index b2669077b7..7761a34f13 100644
--- a/frappe/core/doctype/defaultvalue/defaultvalue.py
+++ b/frappe/core/doctype/defaultvalue/defaultvalue.py
@@ -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)""")
\ No newline at end of file
+ frappe.db.sql("""alter table `tabDefaultValue`
+ add index defaultvalue_parent_parenttype_index(parent, parenttype)""")
diff --git a/frappe/core/doctype/docfield/docfield.py b/frappe/core/doctype/docfield/docfield.py
index d476f69dd8..9d7121073d 100644
--- a/frappe/core/doctype/docfield/docfield.py
+++ b/frappe/core/doctype/docfield/docfield.py
@@ -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
diff --git a/frappe/core/doctype/docperm/docperm.py b/frappe/core/doctype/docperm/docperm.py
index 00bffbfe52..72a48001c3 100644
--- a/frappe/core/doctype/docperm/docperm.py
+++ b/frappe/core/doctype/docperm/docperm.py
@@ -7,4 +7,5 @@ import frappe
from frappe.model.document import Document
class DocPerm(Document):
- pass
\ No newline at end of file
+ __doclink__ = "https://frappe.io/docs/models/core/docperm"
+ pass
diff --git a/frappe/core/doctype/doctype/doctype.py b/frappe/core/doctype/doctype/doctype.py
index 569613ec9c..78dc7f01e6 100644
--- a/frappe/core/doctype/doctype/doctype.py
+++ b/frappe/core/doctype/doctype/doctype.py
@@ -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
diff --git a/frappe/core/doctype/module_def/module_def.py b/frappe/core/doctype/module_def/module_def.py
index 639fbbccac..fd2d16f513 100644
--- a/frappe/core/doctype/module_def/module_def.py
+++ b/frappe/core/doctype/module_def/module_def.py
@@ -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."""
diff --git a/frappe/public/js/frappe/views/reportview.js b/frappe/public/js/frappe/views/reportview.js
index b9b0901049..0277d42a44 100644
--- a/frappe/public/js/frappe/views/reportview.js
+++ b/frappe/public/js/frappe/views/reportview.js
@@ -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
diff --git a/frappe/templates/autodoc/doctype.html b/frappe/templates/autodoc/doctype.html
index 428b6be325..b8142d3242 100644
--- a/frappe/templates/autodoc/doctype.html
+++ b/frappe/templates/autodoc/doctype.html
@@ -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 %}Single{% endif %}
-{% if doc.istable %}
- Table
+{% if doc.istable %}Child Table{% endif %}
+
+{% if not doc.issingle %}
+ Table Name: tab{{ name }}
{% endif %}
{{ doc.description or "" }}
@@ -30,7 +33,7 @@
{{ df.fieldtype }} |
- {{ df.label }}
+ {{ df.label or "" }}
{% if df.description %}
{{ df.description }} {% endif %}
|
@@ -46,7 +49,8 @@
{% if not doc.istable %}
- {{ controller.__module__ }}
+ Controller
+ {{ controller.__module__ }}
{{ automodule(controller.__module__) }}
{% set parents = frappe.get_list("DocField",
diff --git a/frappe/templates/autodoc/macros.html b/frappe/templates/autodoc/macros.html
index 172ba21c41..7e84750f1b 100644
--- a/frappe/templates/autodoc/macros.html
+++ b/frappe/templates/autodoc/macros.html
@@ -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) %}
+
+ Version {{ autodoc.get_version(name) }}
+
{% 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 %}Public API
+
/api/method/{{ full_name }}
+
{% endif %}
- {{ module_name + "." if module_name else "" }}{{ obj.name }}({{ print_args(obj.args) if obj.args else "" }})
+
+
+ {{ module_name + "." if module_name else "" }}{{ obj.name }}
+ ({{ print_args(obj.args) if obj.args else "" }})
+
{{ obj.docs|markdown }}
{% endmacro %}
{% macro print_args(args) -%}
-{% 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 %}
+ {%- endfor %}
{%- endmacro %}
diff --git a/frappe/utils/autodoc.py b/frappe/utils/autodoc.py
index c3f47c9415..3232ca6db8 100644
--- a/frappe/utils/autodoc.py
+++ b/frappe/utils/autodoc.py
@@ -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
diff --git a/frappe/utils/jinja.py b/frappe/utils/jinja.py
index c53a822445..88cd68802e 100644
--- a/frappe/utils/jinja.py
+++ b/frappe/utils/jinja.py
@@ -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
diff --git a/frappe/website/css/website.css b/frappe/website/css/website.css
index 92b9d8298b..bc3ca2b8cc 100644
--- a/frappe/website/css/website.css
+++ b/frappe/website/css/website.css
@@ -433,6 +433,10 @@ a.active {
cursor: default;
}
+:target {
+ background-color: #ffa;
+}
+
.page-breadcrumbs .breadcrumb {
padding: 0px;
margin-bottom: 2px;
diff --git a/frappe/website/js/website.js b/frappe/website/js/website.js
index f9ea3521eb..33de7a9ae4 100644
--- a/frappe/website/js/website.js
+++ b/frappe/website/js/website.js
@@ -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();
});