diff --git a/frappe/templates/pages/about.py b/frappe/templates/pages/about.py
index 75b6262716..13554fe53b 100644
--- a/frappe/templates/pages/about.py
+++ b/frappe/templates/pages/about.py
@@ -5,4 +5,4 @@ from __future__ import unicode_literals
import frappe
def get_context(context):
- return { "obj": frappe.bean("About Us Settings", "About Us Settings").get_controller() }
+ return { "obj": frappe.get_doc("About Us Settings", "About Us Settings") }
diff --git a/frappe/templates/pages/blog.py b/frappe/templates/pages/blog.py
index f6f0854f15..7181ff63b4 100644
--- a/frappe/templates/pages/blog.py
+++ b/frappe/templates/pages/blog.py
@@ -5,4 +5,4 @@ from __future__ import unicode_literals
import frappe
def get_context(context):
- return frappe.doc("Blog Settings", "Blog Settings").fields
+ return frappe.get_doc("Blog Settings", "Blog Settings").as_dict()
diff --git a/frappe/templates/pages/contact.py b/frappe/templates/pages/contact.py
index 24fc9237d4..cab5013ab4 100644
--- a/frappe/templates/pages/contact.py
+++ b/frappe/templates/pages/contact.py
@@ -7,17 +7,17 @@ import frappe
from frappe.utils import now
def get_context(context):
- bean = frappe.bean("Contact Us Settings", "Contact Us Settings")
+ doc = frappe.get_doc("Contact Us Settings", "Contact Us Settings")
- query_options = filter(None, bean.doc.query_options.replace(",", "\n").split()) if \
- bean.doc.query_options else ["Sales", "Support", "General"]
+ query_options = filter(None, doc.query_options.replace(",", "\n").split()) if \
+ doc.query_options else ["Sales", "Support", "General"]
- address = frappe.bean("Address", bean.doc.address).doc if bean.doc.address else None
+ address = frappe.get_doc("Address", doc.address) if doc.address else None
out = {
"query_options": query_options
}
- out.update(bean.doc.fields)
+ out.update(doc.as_dict())
return out
diff --git a/frappe/templates/pages/desk.py b/frappe/templates/pages/desk.py
index b596b7e8b1..e91c4e027b 100644
--- a/frappe/templates/pages/desk.py
+++ b/frappe/templates/pages/desk.py
@@ -1,9 +1,10 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
-# MIT License. See license.txt
+# MIT License. See license.txt
from __future__ import unicode_literals
no_sitemap = 1
+no_cache = 1
base_template_path = "templates/pages/desk.html"
import frappe, os
@@ -11,8 +12,8 @@ import frappe, os
def get_context(context):
hooks = frappe.get_hooks()
return {
- "build_version": str(os.path.getmtime(os.path.join(frappe.local.sites_path, "assets", "js",
+ "build_version": str(os.path.getmtime(os.path.join(frappe.local.sites_path, "assets", "js",
"frappe.min.js"))),
"include_js": hooks["app_include_js"],
"include_css": hooks["app_include_css"]
- }
\ No newline at end of file
+ }
diff --git a/frappe/templates/pages/login.py b/frappe/templates/pages/login.py
index f98015af41..fcde1e341c 100644
--- a/frappe/templates/pages/login.py
+++ b/frappe/templates/pages/login.py
@@ -84,10 +84,10 @@ def get_oauth_keys(provider):
if not keys:
# try database
- social = frappe.doc("Social Login Keys", "Social Login Keys")
+ social = frappe.get_doc("Social Login Keys", "Social Login Keys")
keys = {}
for fieldname in ("client_id", "client_secret"):
- value = social.fields.get("{provider}_{fieldname}".format(provider=provider, fieldname=fieldname))
+ value = social.get("{provider}_{fieldname}".format(provider=provider, fieldname=fieldname))
if not value:
keys = {}
break
@@ -183,7 +183,7 @@ def create_oauth_user(data, provider):
if isinstance(data.get("location"), dict):
data["location"] = data.get("location").get("name")
- user = frappe.bean({
+ user = frappe.get_doc({
"doctype":"User",
"first_name": data.get("first_name") or data.get("given_name") or data.get("name"),
"last_name": data.get("last_name") or data.get("family_name"),
@@ -198,18 +198,18 @@ def create_oauth_user(data, provider):
})
if provider=="facebook":
- user.doc.fields.update({
+ user.update({
"fb_username": data["username"],
"fb_userid": data["id"],
"user_image": "https://graph.facebook.com/{username}/picture".format(username=data["username"])
})
elif provider=="google":
- user.doc.google_userid = data["id"]
+ user.google_userid = data["id"]
elif provider=="github":
- user.doc.github_userid = data["id"]
- user.doc.github_username = data["login"]
+ user.github_userid = data["id"]
+ user.github_username = data["login"]
user.ignore_permissions = True
- user.get_controller().no_welcome_mail = True
+ user.no_welcome_mail = True
user.insert()
diff --git a/frappe/templates/pages/rss.py b/frappe/templates/pages/rss.py
index f41239473b..a02f1dda11 100644
--- a/frappe/templates/pages/rss.py
+++ b/frappe/templates/pages/rss.py
@@ -29,7 +29,7 @@ def get_context(context):
else:
modified = now()
- ws = frappe.doc('Website Settings', 'Website Settings')
+ ws = frappe.get_doc('Website Settings', 'Website Settings')
context = {
'title': ws.title_prefix,
diff --git a/frappe/templates/pages/style_settings.py b/frappe/templates/pages/style_settings.py
index fad8848f81..23f2fbbe20 100644
--- a/frappe/templates/pages/style_settings.py
+++ b/frappe/templates/pages/style_settings.py
@@ -9,10 +9,10 @@ base_template_path = "templates/pages/style_settings.css"
def get_context(context):
"""returns web style"""
- doc = frappe.doc("Style Settings", "Style Settings")
+ doc = frappe.get_doc("Style Settings", "Style Settings")
prepare(doc)
- return { "doc": doc.fields }
+ return { "doc": doc.as_dict() }
def prepare(doc):
from frappe.utils import cint, cstr
@@ -28,8 +28,8 @@ def prepare(doc):
}
for d in default_colours:
- if not doc.fields.get(d):
- doc.fields[d] = default_colours[d]
+ if not doc.get(d):
+ doc.set(d, default_colours[d])
if not doc.font_size:
doc.font_size = "14px"
diff --git a/frappe/templates/pages/writers.py b/frappe/templates/pages/writers.py
index 2b3093a551..4a793fd1be 100644
--- a/frappe/templates/pages/writers.py
+++ b/frappe/templates/pages/writers.py
@@ -17,6 +17,6 @@ def get_context(context):
"categories": frappe.db.sql_list("select name from `tabBlog Category` order by name")
}
- writers_context.update(frappe.doc("Blog Settings", "Blog Settings").fields)
+ writers_context.update(frappe.get_doc("Blog Settings", "Blog Settings").as_dict())
return writers_context
diff --git a/frappe/templates/website_group/post.py b/frappe/templates/website_group/post.py
index 1563158975..ebdc15283d 100644
--- a/frappe/templates/website_group/post.py
+++ b/frappe/templates/website_group/post.py
@@ -9,10 +9,10 @@ from frappe.utils.file_manager import save_file
from frappe.templates.generators.website_group import get_pathname
def get_post_context(context):
- post = frappe.doc("Post", frappe.form_dict.name)
+ post = frappe.get_doc("Post", frappe.form_dict.name)
if post.parent_post:
raise frappe.PermissionError
-
+
def _get_post_context():
fullname = get_fullname(post.owner)
return {
@@ -21,42 +21,42 @@ def get_post_context(context):
"post_list_html": get_child_posts_html(post, context),
"parent_post": post.name
}
-
+
cache_key = "website_group_post:{}".format(post.name)
return frappe.cache().get_value(cache_key, lambda: _get_post_context())
-
+
def get_parent_post_html(post, context):
- user = frappe.bean("User", post.owner).doc
+ user = frappe.get_doc("User", post.owner)
for fieldname in ("first_name", "last_name", "user_image", "location"):
- post.fields[fieldname] = user.fields[fieldname]
-
+ post.set(fieldname, user.get(fieldname))
+
return frappe.get_template("templates/includes/inline_post.html")\
- .render({"post": post.fields, "view": context.view})
+ .render({"post": post, "view": context.view})
def get_child_posts_html(post, context):
posts = frappe.db.sql("""select p.*, pr.user_image, pr.first_name, pr.last_name
from tabPost p, tabUser pr
where p.parent_post=%s and pr.name = p.owner
order by p.creation asc""", (post.name,), as_dict=True)
-
+
return frappe.get_template("templates/includes/post_list.html")\
.render({
"posts": posts,
"parent_post": post.name,
"view": context.view
})
-
+
def clear_post_cache(post=None):
cache = frappe.cache()
posts = [post] if post else frappe.db.sql_list("select name from `tabPost`")
for post in posts:
cache.delete_value("website_group_post:{}".format(post))
-
+
@frappe.whitelist(allow_guest=True)
-def add_post(group, content, picture, picture_name, title=None, parent_post=None,
+def add_post(group, content, picture, picture_name, title=None, parent_post=None,
assigned_to=None, status=None, event_datetime=None):
-
+
access = get_access(get_pathname(group))
if not access.get("write"):
raise frappe.PermissionError
@@ -64,56 +64,56 @@ def add_post(group, content, picture, picture_name, title=None, parent_post=None
if parent_post:
if frappe.db.get_value("Post", parent_post, "parent_post"):
frappe.throw("Cannot reply to a reply")
-
- group = frappe.doc("Website Group", group)
- post = frappe.bean({
+
+ group = frappe.get_doc("Website Group", group)
+ post = frappe.get_doc({
"doctype":"Post",
"title": (title or "").title(),
"content": content,
"website_group": group.name,
"parent_post": parent_post or None
})
-
+
if not parent_post:
if group.group_type == "Tasks":
- post.doc.is_task = 1
- post.doc.assigned_to = assigned_to
+ post.is_task = 1
+ post.assigned_to = assigned_to
elif group.group_type == "Events":
- post.doc.is_event = 1
- post.doc.event_datetime = event_datetime
-
+ post.is_event = 1
+ post.event_datetime = event_datetime
+
post.ignore_permissions = True
post.insert()
if picture_name and picture:
process_picture(post, picture_name, picture)
-
+
# send email
if parent_post:
post.run_method("send_email_on_reply")
-
- return post.doc.parent_post or post.doc.name
-
+
+ return post.parent_post or post.name
+
@frappe.whitelist(allow_guest=True)
def save_post(post, content, picture=None, picture_name=None, title=None,
assigned_to=None, status=None, event_datetime=None):
-
- post = frappe.bean("Post", post)
- access = get_access(get_pathname(post.doc.website_group))
-
+
+ post = frappe.get_doc("Post", post)
+ access = get_access(get_pathname(post.website_group))
+
if not access.get("write"):
raise frappe.PermissionError
-
+
# TODO improve error message
- if frappe.session.user != post.doc.owner:
+ if frappe.session.user != post.owner:
for fieldname in ("title", "content"):
- if post.doc.fields.get(fieldname) != locals().get(fieldname):
+ if post.get(fieldname) != locals().get(fieldname):
frappe.throw("You cannot change: {}".format(fieldname.title()))
-
+
if picture and picture_name:
frappe.throw("You cannot change: Picture")
-
- post.doc.fields.update({
+
+ post.update({
"title": (title or "").title(),
"content": content,
"assigned_to": assigned_to,
@@ -122,34 +122,34 @@ def save_post(post, content, picture=None, picture_name=None, title=None,
})
post.ignore_permissions = True
post.save()
-
+
if picture_name and picture:
process_picture(post, picture_name, picture)
-
- return post.doc.parent_post or post.doc.name
-
+
+ return post.parent_post or post.name
+
def process_picture(post, picture_name, picture):
from frappe.templates.generators.website_group import clear_cache
-
- file_data = save_file(picture_name, picture, "Post", post.doc.name, decode=True)
- post.doc.picture_url = file_data.file_name or file_data.file_url
- frappe.db.set_value("Post", post.doc.name, "picture_url", post.doc.picture_url)
- clear_cache(website_group=post.doc.website_group)
-
+
+ file_data = save_file(picture_name, picture, "Post", post.name, decode=True)
+ post.picture_url = file_data.file_name or file_data.file_url
+ frappe.db.set_value("Post", post.name, "picture_url", post.picture_url)
+ clear_cache(website_group=post.website_group)
+
@frappe.whitelist()
def suggest_user(group, term):
"""suggest a user that has read permission in this group tree"""
- users = frappe.db.sql("""select
- pr.name, pr.first_name, pr.last_name,
+ users = frappe.db.sql("""select
+ pr.name, pr.first_name, pr.last_name,
pr.user_image, pr.location
from `tabUser` pr
where (pr.first_name like %(term)s or pr.last_name like %(term)s)
- and pr.user_type = 'Website User' and pr.enabled=1""",
+ and pr.user_type = 'Website User' and pr.enabled=1""",
{"term": "%{}%".format(term), "group": group}, as_dict=True)
-
+
template = frappe.get_template("templates/includes/user_display.html")
return [{
- "value": "{} {}".format(pr.first_name or "", pr.last_name or "").strip(),
+ "value": "{} {}".format(pr.first_name or "", pr.last_name or "").strip(),
"user_html": template.render({"user": pr}),
"user": pr.name
} for pr in users]
diff --git a/frappe/templates/website_group/settings.py b/frappe/templates/website_group/settings.py
index 702263ed40..d7397f7be9 100644
--- a/frappe/templates/website_group/settings.py
+++ b/frappe/templates/website_group/settings.py
@@ -36,7 +36,7 @@ def add_sitemap_permission(group, user):
if not get_access(pathname).get("admin"):
raise frappe.PermissionError
- permission = frappe.bean({
+ permission = frappe.get_doc({
"doctype": "Website Route Permission",
"website_route": pathname,
"user": user,
@@ -44,7 +44,7 @@ def add_sitemap_permission(group, user):
})
permission.insert(ignore_permissions=True)
- user = permission.doc.fields
+ user = permission.as_dict()
user.update(frappe.db.get_value("User", user.user,
["name", "first_name", "last_name", "user_image", "location"], as_dict=True))
@@ -58,8 +58,8 @@ def update_permission(group, user, perm, value):
if not get_access(pathname).get("admin"):
raise frappe.PermissionError
- permission = frappe.bean("Website Route Permission", {"website_route": pathname, "user": user})
- permission.doc.fields[perm] = int(value)
+ permission = frappe.get_doc("Website Route Permission", {"website_route": pathname, "user": user})
+ permission.set(perm, int(value))
permission.save(ignore_permissions=True)
# send email
@@ -79,8 +79,8 @@ def update_description(group, description):
if not get_access(get_pathname(group)).get("admin"):
raise frappe.PermissionError
- group = frappe.bean("Website Group", group)
- group.doc.group_description = description
+ group = frappe.get_doc("Website Group", group)
+ group.group_description = description
group.save(ignore_permissions=True)
@frappe.whitelist()
@@ -91,7 +91,7 @@ def add_website_group(group, new_group, public_read, public_write, group_type="F
parent_website_route = frappe.db.get_value("Website Route",
{"ref_doctype": "Website Group", "docname": group})
- frappe.bean({
+ frappe.get_doc({
"doctype": "Website Group",
"group_name": group + "-" + new_group,
"group_title": new_group,
diff --git a/frappe/test_runner.py b/frappe/test_runner.py
index 9a9fe36e09..6f50abb597 100644
--- a/frappe/test_runner.py
+++ b/frappe/test_runner.py
@@ -4,36 +4,32 @@
from __future__ import unicode_literals
import frappe
-import unittest, sys
-
-from frappe.model.meta import has_field
-from frappe.model.code import load_doctype_module, get_module_name
-from frappe.model.doctype import get_link_fields
+import unittest, sys, json
+import importlib
+from frappe.modules import load_doctype_module, get_module_name
from frappe.utils import cstr
-def main(app=None, module=None, doctype=None, verbose=False):
+def main(app=None, module=None, doctype=None, verbose=False, tests=()):
frappe.flags.print_messages = verbose
frappe.flags.in_test = True
-
+
if not frappe.db:
frappe.connect()
-
+
+ # workaround! since there is no separate test db
+ frappe.clear_cache()
+
if doctype:
- ret = run_unittest(doctype, verbose=verbose)
+ ret = run_tests_for_doctype(doctype, verbose=verbose, tests=tests)
elif module:
- import importlib
-
- test_suite = unittest.TestSuite()
- module = importlib.import_module(module)
- if hasattr(module, "test_dependencies"):
- for doctype in module.test_dependencies:
- make_test_records(doctype, verbose=verbose)
-
- test_suite.addTest(unittest.TestLoader().loadTestsFromModule(module))
- ret = unittest.TextTestRunner(verbosity=1+(verbose and 1 or 0)).run(test_suite)
+ ret = run_tests_for_module(module, verbose=verbose, tests=tests)
else:
ret = run_all_tests(app, verbose)
+
+ # workaround! since there is no separate test db
+ frappe.clear_cache()
+
return ret
def run_all_tests(app=None, verbose=False):
@@ -45,44 +41,68 @@ def run_all_tests(app=None, verbose=False):
for app in apps:
for path, folders, files in os.walk(frappe.get_pymodule_path(app)):
for dontwalk in ('locals', '.git', 'public'):
- if dontwalk in folders:
+ if dontwalk in folders:
folders.remove(dontwalk)
-
+
# print path
for filename in files:
filename = cstr(filename)
if filename.startswith("test_") and filename.endswith(".py"):
# print filename[:-3]
- _run_test(path, filename, verbose, test_suite=test_suite, run=False)
-
+ _add_test(path, filename, verbose, test_suite=test_suite)
+
return unittest.TextTestRunner(verbosity=1+(verbose and 1 or 0)).run(test_suite)
-def _run_test(path, filename, verbose, test_suite=None, run=True):
+def run_tests_for_doctype(doctype, verbose=False, tests=()):
+ module = frappe.db.get_value("DocType", doctype, "module")
+ test_module = get_module_name(doctype, module, "test_")
+ make_test_records(doctype, verbose=verbose)
+ module = frappe.get_module(test_module)
+ return _run_unittest(module, verbose=verbose, tests=tests)
+
+def run_tests_for_module(module, verbose=False, tests=()):
+ module = importlib.import_module(module)
+ if hasattr(module, "test_dependencies"):
+ for doctype in module.test_dependencies:
+ make_test_records(doctype, verbose=verbose)
+
+ return _run_unittest(module=module, verbose=verbose, tests=tests)
+
+def _run_unittest(module, verbose=False, tests=()):
+ test_suite = unittest.TestSuite()
+ module_test_cases = unittest.TestLoader().loadTestsFromModule(module)
+ if tests:
+ for each in module_test_cases:
+ for test_case in each.__dict__["_tests"]:
+ if test_case.__dict__["_testMethodName"] in tests:
+ test_suite.addTest(test_case)
+ else:
+ test_suite.addTest(module_test_cases)
+
+ return unittest.TextTestRunner(verbosity=1+(verbose and 1 or 0)).run(test_suite)
+
+def _add_test(path, filename, verbose, test_suite=None):
import os, imp
- from frappe.modules.utils import peval_doclist
-
+
if not test_suite:
test_suite = unittest.TestSuite()
-
+
if os.path.basename(os.path.dirname(path))=="doctype":
- txt_file = os.path.join(path, filename[5:].replace(".py", ".txt"))
+ txt_file = os.path.join(path, filename[5:].replace(".py", ".json"))
with open(txt_file, 'r') as f:
- doctype_doclist = peval_doclist(f.read())
- doctype = doctype_doclist[0]["name"]
+ doc = json.loads(f.read())
+ doctype = doc["name"]
make_test_records(doctype, verbose)
-
+
module = imp.load_source(filename[:-3], os.path.join(path, filename))
test_suite.addTest(unittest.TestLoader().loadTestsFromModule(module))
-
- if run:
- unittest.TextTestRunner(verbosity=1+(verbose and 1 or 0)).run(test_suite)
def make_test_records(doctype, verbose=0):
frappe.flags.mute_emails = True
-
+
if not frappe.db:
frappe.connect()
-
+
for options in get_dependencies(doctype):
if options.startswith("link:"):
options = options[5:]
@@ -98,7 +118,7 @@ def get_modules(doctype):
module = frappe.db.get_value("DocType", doctype, "module")
try:
test_module = load_doctype_module(doctype, module, "test_")
- if test_module:
+ if test_module:
reload(test_module)
except ImportError, e:
test_module = None
@@ -107,22 +127,29 @@ def get_modules(doctype):
def get_dependencies(doctype):
module, test_module = get_modules(doctype)
-
- options_list = list(set([df.options for df in get_link_fields(doctype)] + [doctype]))
-
+ meta = frappe.get_meta(doctype)
+ link_fields = meta.get_link_fields()
+
+ for df in meta.get_table_fields():
+ link_fields.extend(frappe.get_meta(df.options).get_link_fields())
+
+ options_list = [df.options for df in link_fields] + [doctype]
+
if hasattr(test_module, "test_dependencies"):
options_list += test_module.test_dependencies
-
+
+ options_list = list(set(options_list))
+
if hasattr(test_module, "test_ignore"):
for doctype_name in test_module.test_ignore:
if doctype_name in options_list:
options_list.remove(doctype_name)
-
+
return options_list
def make_test_records_for_doctype(doctype, verbose=0):
module, test_module = get_modules(doctype)
-
+
if verbose:
print "Making for " + doctype
@@ -131,52 +158,50 @@ def make_test_records_for_doctype(doctype, verbose=0):
elif hasattr(test_module, "test_records"):
frappe.local.test_objects[doctype] += make_test_objects(doctype, test_module.test_records, verbose)
- elif verbose:
- print_mandatory_fields(doctype)
+ else:
+ test_records = frappe.get_test_records(doctype)
+ if test_records:
+ frappe.local.test_objects[doctype] += make_test_objects(doctype, test_records, verbose)
+
+ elif verbose:
+ print_mandatory_fields(doctype)
def make_test_objects(doctype, test_records, verbose=None):
records = []
-
- for doclist in test_records:
- if "doctype" not in doclist[0]:
- doclist[0]["doctype"] = doctype
- d = frappe.bean(copy=doclist)
-
- if frappe.local.test_objects.get(d.doc.doctype):
+
+ for doc in test_records:
+ if not doc.get("doctype"):
+ doc["doctype"] = doctype
+
+ d = frappe.copy_doc(doc)
+
+ if frappe.local.test_objects.get(d.doctype):
# do not create test records, if already exists
return []
- if has_field(d.doc.doctype, "naming_series"):
- if not d.doc.naming_series:
- d.doc.naming_series = "_T-" + d.doc.doctype + "-"
+
+ if d.meta.get_field("naming_series"):
+ if not d.naming_series:
+ d.naming_series = "_T-" + d.doctype + "-"
# submit if docstatus is set to 1 for test record
- docstatus = d.doc.docstatus
-
- d.doc.docstatus = 0
+ docstatus = d.docstatus
+
+ d.docstatus = 0
d.insert()
if docstatus == 1:
d.submit()
-
- records.append(d.doc.name)
+
+ records.append(d.name)
return records
def print_mandatory_fields(doctype):
print "Please setup make_test_records for: " + doctype
print "-" * 60
- doctype_obj = frappe.get_doctype(doctype)
- print "Autoname: " + (doctype_obj[0].autoname or "")
+ meta = frappe.get_meta(doctype)
+ print "Autoname: " + (meta.autoname or "")
print "Mandatory Fields: "
- for d in doctype_obj.get({"reqd":1}):
+ for d in meta.get("fields", {"reqd":1}):
print d.parent + ":" + d.fieldname + " | " + d.fieldtype + " | " + (d.options or "")
- print
-
-def run_unittest(doctype, verbose=False):
- module = frappe.db.get_value("DocType", doctype, "module")
- test_module = get_module_name(doctype, module, "test_")
- make_test_records(doctype, verbose=verbose)
- test_suite = unittest.TestSuite()
- module = frappe.get_module(test_module)
- test_suite.addTest(unittest.TestLoader().loadTestsFromModule(module))
- return unittest.TextTestRunner(verbosity=1+(verbose and 1 or 0)).run(test_suite)
+ print
diff --git a/frappe/tests/__init__.py b/frappe/tests/__init__.py
index 5d22462144..00e6b358eb 100644
--- a/frappe/tests/__init__.py
+++ b/frappe/tests/__init__.py
@@ -24,14 +24,14 @@ def get_test_doclist(doctype, name=None):
conf.test_data_path, doctype)
if name:
- with open(os.path.join(doctype_path, scrub(name) + '.txt'), 'r') as txtfile:
+ with open(os.path.join(doctype_path, scrub(name) + ".json"), 'r') as txtfile:
doclist = peval_doclist(txtfile.read())
return doclist
else:
all_doclists = []
- for fname in filter(lambda n: n.endswith('.txt'), os.listdir(doctype_path)):
+ for fname in filter(lambda n: n.endswith(".json"), os.listdir(doctype_path)):
with open(os.path.join(doctype_path, scrub(fname)), 'r') as txtfile:
all_doclists.append(peval_doclist(txtfile.read()))
diff --git a/frappe/tests/test_assign.py b/frappe/tests/test_assign.py
new file mode 100644
index 0000000000..789e135668
--- /dev/null
+++ b/frappe/tests/test_assign.py
@@ -0,0 +1,22 @@
+# Copyright (c) 2014, Web Notes Technologies Pvt. Ltd. and Contributors
+# MIT License. See license.txt
+
+import frappe, unittest
+import frappe.widgets.form.assign_to
+
+class TestAssign(unittest.TestCase):
+ def test_assign(self):
+ todo = frappe.get_doc({"doctype":"ToDo", "description": "test"}).insert()
+ if not frappe.db.exists("User", "test@example.com"):
+ frappe.get_doc({"doctype":"User", "email":"test@example.com", "first_name":"Test"})
+
+ added = frappe.widgets.form.assign_to.add({
+ "assign_to": "test@example.com",
+ "doctype": todo.doctype,
+ "name": todo.name,
+ "description": todo.description,
+ })
+ self.assertTrue("test@example.com" in added)
+
+ removed = frappe.widgets.form.assign_to.remove(todo.doctype, todo.name, "test@example.com")
+ self.assertTrue("test@example.com" not in removed)
diff --git a/frappe/tests/test_data_import.py b/frappe/tests/test_data_import.py
new file mode 100644
index 0000000000..140cd891ab
--- /dev/null
+++ b/frappe/tests/test_data_import.py
@@ -0,0 +1,58 @@
+# Copyright (c) 2014, Web Notes Technologies Pvt. Ltd. and Contributors
+# MIT License. See license.txt
+
+import frappe, unittest
+from frappe.core.page.data_import_tool import exporter
+from frappe.core.page.data_import_tool import importer
+from frappe.utils.datautils import read_csv_content
+
+class TestDataImport(unittest.TestCase):
+ def test_export(self):
+ exporter.get_template("User", all_doctypes="No", with_data="No")
+ content = read_csv_content(frappe.response.result)
+ self.assertTrue(content[1][1], "User")
+
+ def test_export_with_data(self):
+ exporter.get_template("User", all_doctypes="No", with_data="Yes")
+ content = read_csv_content(frappe.response.result)
+ self.assertTrue(content[1][1], "User")
+ self.assertTrue("Administrator" in [c[1] for c in content if len(c)>1])
+
+ def test_export_with_all_doctypes(self):
+ exporter.get_template("User", all_doctypes="Yes", with_data="Yes")
+ content = read_csv_content(frappe.response.result)
+ self.assertTrue(content[1][1], "User")
+ self.assertTrue('"Administrator"' in [c[1] for c in content if len(c)>1])
+ self.assertEquals(content[13][0], "DocType:")
+ self.assertEquals(content[13][1], "User")
+ self.assertTrue("UserRole" in content[13])
+
+ def test_import(self):
+ exporter.get_template("Blog Category", all_doctypes="No", with_data="No")
+ content = read_csv_content(frappe.response.result)
+ content.append(["", "", "test-category", "Test Cateogry"])
+ importer.upload(content)
+ self.assertTrue(frappe.db.get_value("Blog Category", "test-category", "title"), "Test Category")
+
+ # export with data
+ exporter.get_template("Blog Category", all_doctypes="No", with_data="Yes")
+ content = read_csv_content(frappe.response.result)
+
+ # overwrite
+ content[-1][3] = "New Title"
+ importer.upload(content, overwrite=True)
+ self.assertTrue(frappe.db.get_value("Blog Category", "test-category", "title"), "New Title")
+
+ def test_import_with_children(self):
+ exporter.get_template("Event", all_doctypes="Yes", with_data="No")
+ content = read_csv_content(frappe.response.result)
+ content.append([""] * len(content[-2]))
+ content[-1][2] = "__Test Event"
+ content[-1][3] = "Private"
+ content[-1][3] = "2014-01-01 10:00:00.000000"
+ content[-1][content[15].index("person")] = "Administrator"
+ importer.upload(content)
+
+ ev = frappe.get_doc("Event", {"subject":"__Test Event"})
+ self.assertTrue("Administrator" in [d.person for d in ev.event_individuals])
+
\ No newline at end of file
diff --git a/frappe/tests/test_document.py b/frappe/tests/test_document.py
index 965501bcfe..3cc8b1ae1d 100644
--- a/frappe/tests/test_document.py
+++ b/frappe/tests/test_document.py
@@ -4,6 +4,10 @@
import frappe, unittest, time
class TestDocument(unittest.TestCase):
+ def test_get_return_empty_list_for_table_field_if_none(self):
+ d = frappe.get_doc({"doctype":"User"})
+ self.assertEquals(d.get("user_roles"), [])
+
def test_load(self):
d = frappe.get_doc("DocType", "User")
self.assertEquals(d.doctype, "DocType")
@@ -22,14 +26,14 @@ class TestDocument(unittest.TestCase):
def test_insert(self):
d = frappe.get_doc({
"doctype":"Event",
- "subject":"_Test Event 1",
+ "subject":"test-doc-test-event 1",
"starts_on": "2014-01-01",
"event_type": "Public"
})
d.insert()
self.assertTrue(d.name.startswith("EV"))
self.assertEquals(frappe.db.get_value("Event", d.name, "subject"),
- "_Test Event 1")
+ "test-doc-test-event 1")
# test if default values are added
self.assertEquals(d.send_reminder, 1)
@@ -38,7 +42,7 @@ class TestDocument(unittest.TestCase):
def test_insert_with_child(self):
d = frappe.get_doc({
"doctype":"Event",
- "subject":"_Test Event 2",
+ "subject":"test-doc-test-event 2",
"starts_on": "2014-01-01",
"event_type": "Public",
"event_individuals": [
@@ -50,7 +54,7 @@ class TestDocument(unittest.TestCase):
d.insert()
self.assertTrue(d.name.startswith("EV"))
self.assertEquals(frappe.db.get_value("Event", d.name, "subject"),
- "_Test Event 2")
+ "test-doc-test-event 2")
d1 = frappe.get_doc("Event", d.name)
self.assertTrue(d1.event_individuals[0].person, "Administrator")
@@ -109,7 +113,7 @@ class TestDocument(unittest.TestCase):
})
self.assertRaises(frappe.LinkValidationError, d.insert)
d.user_roles = []
- d.set("user_roles", {
+ d.append("user_roles", {
"role": "System Manager"
})
d.insert()
@@ -120,5 +124,6 @@ class TestDocument(unittest.TestCase):
d.starts_on = "2014-01-01"
d.ends_on = "2013-01-01"
self.assertRaises(frappe.ValidationError, d.validate)
+ self.assertRaises(frappe.ValidationError, d.run_method, "validate")
self.assertRaises(frappe.ValidationError, d.save)
diff --git a/frappe/tests/test_filemanager.py b/frappe/tests/test_filemanager.py
new file mode 100644
index 0000000000..45207d8857
--- /dev/null
+++ b/frappe/tests/test_filemanager.py
@@ -0,0 +1,80 @@
+# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
+# MIT License. See license.txt
+
+import frappe
+import os
+import unittest
+
+from frappe.utils.file_manager import save_file, get_file, get_files_path
+
+test_content1 = 'Hello'
+test_content2 = 'Hello World'
+
+def make_test_doc():
+ d = frappe.new_doc('ToDo')
+ d.description = 'Test'
+ d.save()
+ return d.doctype, d.name
+
+class TestSimpleFile(unittest.TestCase):
+
+ def setUp(self):
+ self.attached_to_doctype, self.attached_to_docname = make_test_doc()
+ self.test_content = test_content1
+ self.saved_file = save_file('hello.txt', self.test_content, self.attached_to_doctype, self.attached_to_docname)
+ self.saved_filename = get_files_path(self.saved_file.file_name)
+
+ def test_save(self):
+ filename, content = get_file(self.saved_file.name)
+ self.assertEqual(content, self.test_content)
+
+ def tearDown(self):
+ # File gets deleted on rollback, so blank
+ pass
+
+
+class TestSameFileName(unittest.TestCase):
+
+ def setUp(self):
+ self.attached_to_doctype, self.attached_to_docname = make_test_doc()
+ self.test_content1 = test_content1
+ self.test_content2 = test_content2
+ self.saved_file1 = save_file('hello.txt', self.test_content1, self.attached_to_doctype, self.attached_to_docname)
+ self.saved_file2 = save_file('hello.txt', self.test_content2, self.attached_to_doctype, self.attached_to_docname)
+ self.saved_filename1 = get_files_path(self.saved_file1.file_name)
+ self.saved_filename2 = get_files_path(self.saved_file2.file_name)
+
+ def test_saved_content(self):
+ filename1, content1 = get_file(self.saved_file1.name)
+ self.assertEqual(content1, self.test_content1)
+ filename2, content2 = get_file(self.saved_file2.name)
+ self.assertEqual(content2, self.test_content2)
+
+ def tearDown(self):
+ # File gets deleted on rollback, so blank
+ pass
+
+
+class TestSameContent(unittest.TestCase):
+
+ def setUp(self):
+ self.attached_to_doctype1, self.attached_to_docname1 = make_test_doc()
+ self.attached_to_doctype2, self.attached_to_docname2 = make_test_doc()
+ self.test_content1 = test_content1
+ self.test_content2 = test_content1
+ self.orig_filename = 'hello.txt'
+ self.dup_filename = 'hello2.txt'
+ self.saved_file1 = save_file(self.orig_filename, self.test_content1, self.attached_to_doctype1, self.attached_to_docname1)
+ self.saved_file2 = save_file(self.dup_filename, self.test_content2, self.attached_to_doctype2, self.attached_to_docname2)
+ self.saved_filename1 = get_files_path(self.saved_file1.file_name)
+ self.saved_filename2 = get_files_path(self.saved_file2.file_name)
+
+ def test_saved_content(self):
+ filename1, content1 = get_file(self.saved_file1.name)
+ filename2, content2 = get_file(self.saved_file2.name)
+ self.assertEqual(filename1, filename2)
+ self.assertFalse(os.path.exists(get_files_path(self.dup_filename)))
+
+ def tearDown(self):
+ # File gets deleted on rollback, so blank
+ pass
diff --git a/frappe/tests/test_form_load.py b/frappe/tests/test_form_load.py
new file mode 100644
index 0000000000..79e7f3ecf4
--- /dev/null
+++ b/frappe/tests/test_form_load.py
@@ -0,0 +1,18 @@
+# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
+# MIT License. See license.txt
+
+import frappe, unittest
+from frappe.widgets.form.meta import get_meta
+from frappe.widgets.form.load import getdoctype, getdoc
+
+class TestFormLoad(unittest.TestCase):
+ def test_load(self):
+ getdoctype("DocType")
+ meta = filter(lambda d: d.name=="DocType", frappe.response.docs)[0]
+ self.assertEquals(meta.name, "DocType")
+ self.assertTrue(meta.get("__js"))
+
+ frappe.response.docs = []
+ d = getdoctype("Event")
+ meta = filter(lambda d: d.name=="Event", frappe.response.docs)[0]
+ self.assertTrue(meta.get("__calendar_js"))
diff --git a/frappe/translate.py b/frappe/translate.py
index 223bb4c83e..a54b5a357c 100644
--- a/frappe/translate.py
+++ b/frappe/translate.py
@@ -141,11 +141,11 @@ def get_messages_for_app(app):
def get_messages_from_doctype(name):
messages = []
- meta = frappe.get_doctype(name)
+ meta = frappe.get_meta(name)
- messages = [meta[0].name, meta[0].description, meta[0].module]
+ messages = [meta.name, meta.description, meta.module]
- for d in meta.get({"doctype":"DocField"}):
+ for d in meta.get("fields"):
messages.extend([d.label, d.description])
if d.fieldtype=='Select' and d.options \
@@ -156,7 +156,7 @@ def get_messages_from_doctype(name):
messages.extend(options)
# extract from js, py files
- doctype_file_path = frappe.get_module_path(meta[0].module, "doctype", meta[0].name, meta[0].name)
+ doctype_file_path = frappe.get_module_path(meta.module, "doctype", meta.name, meta.name)
messages.extend(get_messages_from_file(doctype_file_path + ".js"))
return clean(messages)
@@ -164,7 +164,7 @@ def get_messages_from_page(name):
return get_messages_from_page_or_report("Page", name)
def get_messages_from_report(name):
- report = frappe.doc("Report", name)
+ report = frappe.get_doc("Report", name)
messages = get_messages_from_page_or_report("Report", name,
frappe.db.get_value("DocType", report.ref_doctype, "module"))
if report.query:
diff --git a/frappe/utils/__init__.py b/frappe/utils/__init__.py
index 38257a51b3..d722c13087 100644
--- a/frappe/utils/__init__.py
+++ b/frappe/utils/__init__.py
@@ -1,5 +1,5 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
-# MIT License. See license.txt
+# MIT License. See license.txt
# util __init__.py
@@ -9,6 +9,8 @@ import os
import re
import urllib
import frappe
+import datetime
+import math
no_value_fields = ['Section Break', 'Column Break', 'HTML', 'Table', 'FlexTable',
'Button', 'Image', 'Graph']
@@ -19,8 +21,8 @@ default_fields = ['doctype', 'name', 'owner', 'creation', 'modified', 'modified_
# TODO: deprecate it
def getCSVelement(v):
"""
- Returns the CSV value of `v`, For example:
-
+ Returns the CSV value of `v`, For example:
+
* apple becomes "apple"
* hi"there becomes "hi""there"
"""
@@ -35,15 +37,15 @@ def get_fullname(user):
"""get the full name (first name + last name) of the user from User"""
if not hasattr(frappe.local, "fullnames"):
frappe.local.fullnames = {}
-
+
if not frappe.local.fullnames.get(user):
p = frappe.db.get_value("User", user, ["first_name", "last_name"], as_dict=True)
if p:
- frappe.local.fullnames[user] = " ".join(filter(None,
+ frappe.local.fullnames[user] = " ".join(filter(None,
[p.get('first_name'), p.get('last_name')])) or user
else:
frappe.local.fullnames[user] = user
-
+
return frappe.local.fullnames.get(user)
def get_formatted_email(user):
@@ -53,7 +55,7 @@ def get_formatted_email(user):
from email.utils import formataddr
fullname = get_fullname(user)
return formataddr((fullname, user))
-
+
def extract_email_id(email):
"""fetch only the email part of the email id"""
from email.utils import parseaddr
@@ -61,7 +63,7 @@ def extract_email_id(email):
if isinstance(email_id, basestring) and not isinstance(email_id, unicode):
email_id = email_id.decode("utf-8", "ignore")
return email_id
-
+
def validate_email_add(email_str):
"""Validates the email string"""
email = extract_email_id(email_str)
@@ -72,23 +74,23 @@ def random_string(length):
import string
from random import choice
return ''.join([choice(string.letters + string.digits) for i in range(length)])
-
+
def get_traceback():
"""
Returns the traceback of the Exception
"""
import sys, traceback
exc_type, value, tb = sys.exc_info()
-
+
trace_list = traceback.format_tb(tb, None) + \
traceback.format_exception_only(exc_type, value)
body = "Traceback (innermost last):\n" + "%-20s %s" % \
(unicode((b"").join(trace_list[:-1]), 'utf-8'), unicode(trace_list[-1], 'utf-8'))
-
+
if frappe.logger:
frappe.logger.error('Db:'+(frappe.db and frappe.db.cur_db_name or '') \
+ ' - ' + body)
-
+
return body
def log(event, details):
@@ -99,16 +101,14 @@ def getdate(string_date):
"""
Coverts string date (yyyy-mm-dd) to datetime.date object
"""
- import datetime
-
if isinstance(string_date, datetime.date):
return string_date
elif isinstance(string_date, datetime.datetime):
return datetime.date()
-
+
if " " in string_date:
string_date = string_date.split(" ")[0]
-
+
return datetime.datetime.strptime(string_date, "%Y-%m-%d").date()
def add_to_date(date, years=0, months=0, days=0):
@@ -121,7 +121,7 @@ def add_to_date(date, years=0, months=0, days=0):
from dateutil.relativedelta import relativedelta
date += relativedelta(years=years, months=months, days=days)
-
+
if format:
return date.strftime("%Y-%m-%d")
else:
@@ -141,7 +141,7 @@ def date_diff(string_ed_date, string_st_date):
def time_diff(string_ed_date, string_st_date):
return get_datetime(string_ed_date) - get_datetime(string_st_date)
-
+
def time_diff_in_seconds(string_ed_date, string_st_date):
return time_diff(string_ed_date, string_st_date).seconds
@@ -149,16 +149,14 @@ def time_diff_in_hours(string_ed_date, string_st_date):
return round(float(time_diff(string_ed_date, string_st_date).seconds) / 3600, 6)
def now_datetime():
- from datetime import datetime
- return convert_utc_to_user_timezone(datetime.utcnow())
+ return convert_utc_to_user_timezone(datetime.datetime.utcnow())
def get_user_time_zone():
if getattr(frappe.local, "user_time_zone", None) is None:
frappe.local.user_time_zone = frappe.cache().get_value("time_zone")
-
+
if not frappe.local.user_time_zone:
- frappe.local.user_time_zone = frappe.db.get_value('Control Panel', None, 'time_zone') \
- or 'Asia/Calcutta'
+ frappe.local.user_time_zone = frappe.db.get_default('time_zone') or 'Asia/Calcutta'
frappe.cache().set_value("time_zone", frappe.local.user_time_zone)
return frappe.local.user_time_zone
@@ -178,27 +176,26 @@ def now():
now_datetime().strftime('%H:%M:%S.%f')
else:
return now_datetime().strftime('%Y-%m-%d %H:%M:%S.%f')
-
+
def nowdate():
"""return current date as yyyy-mm-dd"""
return now_datetime().strftime('%Y-%m-%d')
def today():
return nowdate()
-
+
def nowtime():
"""return current time in hh:mm"""
- return now_datetime().strftime('%H:%M')
+ return now_datetime().strftime('%H:%M:%S.%f')
def get_first_day(dt, d_years=0, d_months=0):
"""
Returns the first day of the month for the date specified by date object
Also adds `d_years` and `d_months` if specified
"""
- import datetime
dt = getdate(dt)
- # d_years, d_months are "deltas" to apply to dt
+ # d_years, d_months are "deltas" to apply to dt
overflow_years, month = divmod(dt.month + d_months - 1, 12)
year = dt.year + d_years + overflow_years
@@ -209,26 +206,34 @@ def get_last_day(dt):
Returns last day of the month using:
`get_first_day(dt, 0, 1) + datetime.timedelta(-1)`
"""
- import datetime
return get_first_day(dt, 0, 1) + datetime.timedelta(-1)
def get_datetime(datetime_str):
- from datetime import datetime
- if isinstance(datetime_str, datetime):
- return datetime_str.replace(microsecond=0, tzinfo=None)
-
- return datetime.strptime(datetime_str, '%Y-%m-%d %H:%M:%S.%f')
-
+ try:
+ return datetime.datetime.strptime(datetime_str, '%Y-%m-%d %H:%M:%S.%f')
+
+ except TypeError:
+ if isinstance(datetime_str, datetime.datetime):
+ return datetime_str.replace(tzinfo=None)
+ else:
+ raise
+
+ except ValueError:
+ if datetime_str=='0000-00-00 00:00:00.000000':
+ return None
+
+ return datetime.datetime.strptime(datetime_str, '%Y-%m-%d %H:%M:%S')
+
def get_datetime_str(datetime_obj):
if isinstance(datetime_obj, basestring):
datetime_obj = get_datetime(datetime_obj)
-
+
return datetime_obj.strftime('%Y-%m-%d %H:%M:%S.%f')
def formatdate(string_date=None):
"""
Convers the given string date to :data:`user_format`
- User format specified in :term:`Control Panel`
+ User format specified in defaults
Examples:
@@ -240,21 +245,21 @@ def formatdate(string_date=None):
string_date = getdate(string_date)
else:
string_date = now_datetime().date()
-
+
if getattr(frappe.local, "user_format", None) is None:
frappe.local.user_format = frappe.db.get_default("date_format")
-
+
out = frappe.local.user_format
-
+
return out.replace("dd", string_date.strftime("%d"))\
.replace("mm", string_date.strftime("%m"))\
.replace("yyyy", string_date.strftime("%Y"))
-
+
def global_date_format(date):
"""returns date as 1 January 2012"""
formatted_date = getdate(date).strftime("%d %B %Y")
return formatted_date.startswith("0") and formatted_date[1:] or formatted_date
-
+
def dict_to_str(args, sep='&'):
"""
Converts a dictionary to URL
@@ -264,24 +269,10 @@ def dict_to_str(args, sep='&'):
t.append(str(k)+'='+urllib.quote(str(args[k] or '')))
return sep.join(t)
-def timestamps_equal(t1, t2):
- """Returns true if same the two string timestamps are same"""
- scrub = lambda x: x.replace(':', ' ').replace('-',' ').split()
-
- t1, t2 = scrub(t1), scrub(t2)
-
- if len(t1) != len(t2):
- return
-
- for i in range(len(t1)):
- if t1[i]!=t2[i]:
- return
- return 1
-
def has_common(l1, l2):
"""Returns truthy value if there are common elements in lists l1 and l2"""
return set(l1) & set(l2)
-
+
def flt(s, precision=None):
"""Convert to float (ignore commas)"""
if isinstance(s, basestring):
@@ -303,13 +294,13 @@ def cint(s):
def cstr(s):
if isinstance(s, unicode):
return s
- elif s==None:
+ elif s==None:
return ''
elif isinstance(s, basestring):
return unicode(s, 'utf-8')
else:
return unicode(s)
-
+
def _round(num, precision=0):
"""round method for round halfs to nearest even algorithm"""
precision = cint(precision)
@@ -317,16 +308,15 @@ def _round(num, precision=0):
# avoid rounding errors
num = round(num * multiplier if precision else num, 8)
-
- import math
+
floor = math.floor(num)
decimal_part = num - floor
-
+
if decimal_part == 0.5:
num = floor if (floor % 2 == 0) else floor + 1
else:
num = round(num)
-
+
return (num / multiplier) if precision else num
def encode(obj, encoding="utf-8"):
@@ -345,8 +335,6 @@ def encode(obj, encoding="utf-8"):
def parse_val(v):
"""Converts to simple datatypes from SQL query results"""
- import datetime
-
if isinstance(v, (datetime.date, datetime.datetime)):
v = unicode(v)
elif isinstance(v, datetime.timedelta):
@@ -358,20 +346,20 @@ def parse_val(v):
def fmt_money(amount, precision=None, currency=None):
"""
Convert to string with commas for thousands, millions etc
- """
+ """
number_format = frappe.db.get_default("number_format") or "#,###.##"
decimal_str, comma_str, precision = get_number_format_info(number_format)
-
-
+
+
amount = '%.*f' % (precision, flt(amount))
if amount.find('.') == -1:
decimals = ''
- else:
+ else:
decimals = amount.split('.')[1]
parts = []
minus = ''
- if flt(amount) < 0:
+ if flt(amount) < 0:
minus = '-'
amount = cstr(abs(flt(amount))).split('.')[0]
@@ -392,7 +380,7 @@ def fmt_money(amount, precision=None, currency=None):
amount = comma_str.join(parts) + (precision and (decimal_str + decimals) or "")
amount = minus + amount
-
+
if currency:
symbol = frappe.db.get_value("Currency", currency, "symbol")
if symbol:
@@ -411,16 +399,16 @@ number_format_info = {
}
def get_number_format_info(format):
- return number_format_info.get(format) or (".", ",", 2)
+ return number_format_info.get(format) or (".", ",", 2)
#
# convet currency to words
#
def money_in_words(number, main_currency = None, fraction_currency=None):
"""
- Returns string in words with currency and fraction currency.
+ Returns string in words with currency and fraction currency.
"""
-
+
d = get_defaults()
if not main_currency:
main_currency = d.get('currency', 'INR')
@@ -430,14 +418,14 @@ def money_in_words(number, main_currency = None, fraction_currency=None):
n = "%.2f" % flt(number)
main, fraction = n.split('.')
if len(fraction)==1: fraction += '0'
-
-
+
+
number_format = frappe.db.get_value("Currency", main_currency, "number_format") or \
frappe.db.get_default("number_format") or "#,###.##"
-
+
in_million = True
if number_format == "#,##,###.##": in_million = False
-
+
out = main_currency + ' ' + in_words(main, in_million).title()
if cint(fraction):
out = out + ' and ' + in_words(fraction, in_million).title() + ' ' + fraction_currency
@@ -455,15 +443,15 @@ def in_words(integer, in_million=True):
known = {0: 'zero', 1: 'one', 2: 'two', 3: 'three', 4: 'four', 5: 'five', 6: 'six', 7: 'seven', 8: 'eight', 9: 'nine', 10: 'ten',
11: 'eleven', 12: 'twelve', 13: 'thirteen', 14: 'fourteen', 15: 'fifteen', 16: 'sixteen', 17: 'seventeen', 18: 'eighteen',
19: 'nineteen', 20: 'twenty', 30: 'thirty', 40: 'forty', 50: 'fifty', 60: 'sixty', 70: 'seventy', 80: 'eighty', 90: 'ninety'}
-
+
def psn(n, known, xpsn):
- import sys;
+ import sys;
if n in known: return known[n]
bestguess, remainder = str(n), 0
if n<=20:
frappe.errprint(sys.stderr)
- frappe.errprint(n)
+ frappe.errprint(n)
frappe.errprint("How did this happen?")
assert 0
elif n < 100:
@@ -482,7 +470,7 @@ def in_words(integer, in_million=True):
remainder = n%1000000
else:
bestguess= xpsn(n//1000000000, known, xpsn) + ' ' + 'billion'
- remainder = n%1000000000
+ remainder = n%1000000000
else:
if n < 100000:
bestguess= xpsn(n//1000, known, xpsn) + ' ' + 'thousand'
@@ -503,19 +491,19 @@ def in_words(integer, in_million=True):
return bestguess
return psn(n, known, psn)
-
+
# Get Defaults
# ==============================================================================
def get_defaults(key=None):
"""
- Get dictionary of default values from the :term:`Control Panel`, or a value if key is passed
+ Get dictionary of default values from the defaults, or a value if key is passed
"""
return frappe.db.get_defaults(key)
def set_default(key, val):
"""
- Set / add a default value to :term:`Control Panel`
+ Set / add a default value to defaults`
"""
return frappe.db.set_default(key, val)
@@ -530,46 +518,46 @@ def remove_blanks(d):
empty_keys.append(key)
for key in empty_keys:
del d[key]
-
+
return d
-
+
def pprint_dict(d, level=1, no_blanks=True):
"""
Pretty print a dictionary with indents
"""
if no_blanks:
remove_blanks(d)
-
+
# make indent
indent, ret = '', ''
for i in range(0,level): indent += '\t'
-
+
# add lines
comment, lines = '', []
kl = d.keys()
kl.sort()
-
+
# make lines
for key in kl:
if key != '##comment':
tmp = {key: d[key]}
lines.append(indent + str(tmp)[1:-1] )
-
+
# add comment string
if '##comment' in kl:
ret = ('\n' + indent) + '# ' + d['##comment'] + '\n'
# open
ret += indent + '{\n'
-
+
# lines
ret += indent + ',\n\t'.join(lines)
-
+
# close
ret += '\n' + indent + '}'
-
+
return ret
-
+
def get_common(d1,d2):
"""
returns (list of keys) the common part of two dicts
@@ -591,7 +579,7 @@ def get_diff_dict(d1, d2):
return common dictionary of d1 and d2
"""
diff_keys = set(d2.keys()).difference(set(d1.keys()))
-
+
ret = {}
for d in diff_keys: ret[d] = d2[d]
return ret
@@ -602,7 +590,7 @@ def get_file_timestamp(fn):
Returns timestamp of the given file
"""
from frappe.utils import cint
-
+
try:
return str(cint(os.stat(fn).st_mtime))
except OSError, e:
@@ -638,7 +626,7 @@ def unesc(s, esc_chars):
esc_str = '\\' + c
s = s.replace(esc_str, c)
return s
-
+
def is_html(text):
out = False
for key in ["
", "
"""
return re.compile(r'<.*?>').sub('', text)
-
+
def escape_html(text):
html_escape_table = {
"&": "&",
@@ -700,21 +688,20 @@ def pretty_date(iso_datetime):
Ported from PrettyDate by John Resig
"""
if not iso_datetime: return ''
- from datetime import datetime
import math
-
+
if isinstance(iso_datetime, basestring):
- iso_datetime = datetime.strptime(iso_datetime, '%Y-%m-%d %H:%M:%S.%f')
- now_dt = datetime.strptime(now(), '%Y-%m-%d %H:%M:%S.%f')
+ iso_datetime = datetime.datetime.strptime(iso_datetime, '%Y-%m-%d %H:%M:%S.%f')
+ now_dt = datetime.datetime.strptime(now(), '%Y-%m-%d %H:%M:%S.%f')
dt_diff = now_dt - iso_datetime
-
+
# available only in python 2.7+
# dt_diff_seconds = dt_diff.total_seconds()
-
+
dt_diff_seconds = dt_diff.days * 86400.0 + dt_diff.seconds
-
+
dt_diff_days = math.floor(dt_diff_seconds / 86400.0)
-
+
# differnt cases
if dt_diff_seconds < 60.0:
return 'just now'
@@ -736,20 +723,20 @@ def pretty_date(iso_datetime):
return '%s months ago' % cint(math.ceil(dt_diff_days / 30.0))
else:
return 'more than %s year(s) ago' % cint(math.floor(dt_diff_days / 365.0))
-
+
def execute_in_shell(cmd, verbose=0):
# using Popen instead of os.system - as recommended by python docs
from subprocess import Popen
import tempfile
-
+
with tempfile.TemporaryFile() as stdout:
with tempfile.TemporaryFile() as stderr:
p = Popen(cmd, shell=True, stdout=stdout, stderr=stderr)
p.wait()
-
+
stdout.seek(0)
out = stdout.read()
-
+
stderr.seek(0)
err = stderr.read()
@@ -761,10 +748,10 @@ def execute_in_shell(cmd, verbose=0):
def comma_or(some_list):
return comma_sep(some_list, " or ")
-
+
def comma_and(some_list):
return comma_sep(some_list, " and ")
-
+
def comma_sep(some_list, sep):
if isinstance(some_list, (list, tuple)):
# list(some_list) is done to preserve the existing list
@@ -778,36 +765,36 @@ def comma_sep(some_list, sep):
return ", ".join(some_list[:-1]) + sep + some_list[-1]
else:
return some_list
-
+
def filter_strip_join(some_list, sep):
"""given a list, filter None values, strip spaces and join"""
return (cstr(sep)).join((cstr(a).strip() for a in filter(None, some_list)))
-
+
def get_path(*path, **kwargs):
base = kwargs.get('base')
if not base:
base = frappe.local.site_path
return os.path.join(base, *path)
-
+
def get_site_base_path(sites_dir=None, hostname=None):
return frappe.local.site_path
def get_site_path(*path):
return get_path(base=get_site_base_path(), *path)
-
-def get_files_path():
- return get_site_path("public", "files")
+
+def get_files_path(*path):
+ return get_site_path("public", "files", *path)
def get_backups_path():
return get_site_path("private", "backups")
-
+
def get_request_site_address(full_address=False):
return get_url(full_address=full_address)
-
+
def get_url(uri=None, full_address=False):
"""get app url from request"""
host_name = frappe.local.conf.host_name
-
+
if not host_name:
if hasattr(frappe.local, "request") and frappe.local.request and frappe.local.request.host:
protocol = 'https' == frappe.get_request_header('X-Forwarded-Proto', "") and 'https://' or 'http://'
@@ -819,30 +806,30 @@ def get_url(uri=None, full_address=False):
"subdomain")
if host_name and "http" not in host_name:
host_name = "http://" + host_name
-
+
if not host_name:
host_name = "http://localhost"
-
+
if not uri and full_address:
uri = frappe.get_request_header("REQUEST_URI", "")
-
+
url = urllib.basejoin(host_name, uri) if uri else host_name
-
+
return url
def get_url_to_form(doctype, name, base_url=None, label=None):
if not base_url:
base_url = get_url()
-
+
if not label: label = name
-
+
return """%(label)s""" % locals()
-
+
def encode_dict(d, encoding="utf-8"):
for key in d:
if isinstance(d[key], basestring) and isinstance(d[key], unicode):
d[key] = d[key].encode(encoding)
-
+
return d
def decode_dict(d, encoding="utf-8"):
@@ -877,7 +864,7 @@ def compare(val1, condition, val2):
ret = False
if condition in operator_map:
ret = operator_map[condition]((val1, val2))
-
+
return ret
def get_site_name(hostname):
@@ -890,26 +877,26 @@ def get_disk_usage():
return 0
err, out = execute_in_shell("du -hsm {files_path}".format(files_path=files_path))
return cint(out.split("\n")[-2].split("\t")[0])
-
+
def scrub_urls(html):
html = expand_relative_urls(html)
html = quote_urls(html)
return html
-
+
def expand_relative_urls(html):
# expand relative urls
url = get_url()
if url.endswith("/"): url = url[:-1]
-
+
def _expand_relative_urls(match):
to_expand = list(match.groups())
if not to_expand[2].startswith("/"):
to_expand[2] = "/" + to_expand[2]
to_expand.insert(2, url)
return "".join(to_expand)
-
+
return re.sub('(href|src){1}([\s]*=[\s]*[\'"]?)((?!http)[^\'" >]+)([\'"]?)', _expand_relative_urls, html)
-
+
def quote_urls(html):
def _quote_url(match):
groups = list(match.groups())
@@ -926,3 +913,11 @@ def touch_file(path):
def get_test_client():
from frappe.app import application
return Client(application)
+
+def get_hook_method(hook_name, fallback=None):
+ method = (frappe.get_hooks().get(hook_name))
+ if method:
+ method = frappe.get_attr(method[0])
+ return method
+ if fallback:
+ return fallback
diff --git a/frappe/utils/datautils.py b/frappe/utils/datautils.py
index 028391acdd..2bca461f6f 100644
--- a/frappe/utils/datautils.py
+++ b/frappe/utils/datautils.py
@@ -35,7 +35,7 @@ def read_csv_content_from_attached_file(doc):
def read_csv_content(fcontent, ignore_encoding=False):
rows = []
- if isinstance(fcontent, basestring):
+ if not isinstance(fcontent, unicode):
decoded = False
for encoding in ["utf-8", "windows-1250", "windows-1252"]:
try:
@@ -49,7 +49,7 @@ def read_csv_content(fcontent, ignore_encoding=False):
frappe.msgprint(frappe._("Unknown file encoding. Tried utf-8, windows-1250, windows-1252."),
raise_exception=True)
- fcontent = fcontent.encode("utf-8").splitlines(True)
+ fcontent = fcontent.encode("utf-8").splitlines(True)
try:
reader = csv.reader(fcontent)
@@ -92,17 +92,13 @@ class UnicodeWriter:
def getvalue(self):
return self.queue.getvalue()
-def check_record(d, parenttype=None, doctype_dl=None):
+def check_record(d):
"""check for mandatory, select options, dates. these should ideally be in doclist"""
from frappe.utils.dateutils import parse_date
- if parenttype and not d.get('parent'):
- frappe.msgprint(_("Parent is required."), raise_exception=1)
-
- if not doctype_dl:
- doctype_dl = frappe.model.doctype.get(d.doctype)
+ d = frappe.get_doc(d)
for key in d:
- docfield = doctype_dl.get_field(key)
+ docfield = d.meta.get_field(key)
val = d[key]
if docfield:
if docfield.reqd and (val=='' or val==None):
@@ -132,27 +128,27 @@ def import_doc(d, doctype, overwrite, row_idx, submit=False, ignore_links=False)
"""import main (non child) document"""
if d.get("name") and frappe.db.exists(doctype, d['name']):
if overwrite:
- bean = frappe.bean(doctype, d['name'])
- bean.ignore_links = ignore_links
- bean.doc.fields.update(d)
+ doc = frappe.get_doc(doctype, d['name'])
+ doc.ignore_links = ignore_links
+ doc.update(d)
if d.get("docstatus") == 1:
- bean.update_after_submit()
+ doc.update_after_submit()
else:
- bean.save()
+ doc.save()
return 'Updated row (#%d) %s' % (row_idx + 1, getlink(doctype, d['name']))
else:
return 'Ignored row (#%d) %s (exists)' % (row_idx + 1,
getlink(doctype, d['name']))
else:
- bean = frappe.bean([d])
- bean.ignore_links = ignore_links
- bean.insert()
+ doc = frappe.get_doc(d)
+ doc.ignore_links = ignore_links
+ doc.insert()
if submit:
- bean.submit()
+ doc.submit()
return 'Inserted row (#%d) %s' % (row_idx + 1, getlink(doctype,
- bean.doc.fields['name']))
+ doc.get('name')))
def getlink(doctype, name):
return '%(name)s' % locals()
diff --git a/frappe/utils/email_lib/bulk.py b/frappe/utils/email_lib/bulk.py
index ffdd6e2094..d47c4a6d42 100644
--- a/frappe/utils/email_lib/bulk.py
+++ b/frappe/utils/email_lib/bulk.py
@@ -78,7 +78,7 @@ def send(recipients=None, sender=None, doctype='User', email_field='email',
def add(email, sender, subject, formatted, text_content=None,
ref_doctype=None, ref_docname=None):
"""add to bulk mail queue"""
- e = frappe.doc('Bulk Email')
+ e = frappe.new_doc('Bulk Email')
e.sender = sender
e.recipient = email
try:
diff --git a/frappe/utils/email_lib/email_body.py b/frappe/utils/email_lib/email_body.py
index 4c732ad461..527f701a03 100644
--- a/frappe/utils/email_lib/email_body.py
+++ b/frappe/utils/email_lib/email_body.py
@@ -211,7 +211,7 @@ def get_footer(footer=None):
footer = footer or ""
# control panel
- footer += frappe.db.get_value('Control Panel', None, 'mail_footer') or ''
+ footer += frappe.db.get_default('mail_footer') or ''
# hooks
for f in frappe.get_hooks("mail_footer"):
diff --git a/frappe/utils/email_lib/smtp.py b/frappe/utils/email_lib/smtp.py
index 9ba7d9e94a..8547e29898 100644
--- a/frappe/utils/email_lib/smtp.py
+++ b/frappe/utils/email_lib/smtp.py
@@ -36,9 +36,9 @@ def send(email, as_bulk=False):
class SMTPServer:
def __init__(self, login=None, password=None, server=None, port=None, use_ssl=None):
- # get defaults from control panel
+ # get defaults from mail settings
try:
- es = frappe.doc('Outgoing Email Settings', 'Outgoing Email Settings')
+ es = frappe.get_doc('Outgoing Email Settings', 'Outgoing Email Settings')
except frappe.DoesNotExistError:
es = None
diff --git a/frappe/utils/file_manager.py b/frappe/utils/file_manager.py
index f61d901d26..06dea9ee33 100644
--- a/frappe/utils/file_manager.py
+++ b/frappe/utils/file_manager.py
@@ -4,9 +4,12 @@
from __future__ import unicode_literals
import frappe
import os, base64, re
-from frappe.utils import cstr, cint, get_site_path
+import hashlib
+import mimetypes
+from frappe.utils import cstr, cint, get_site_path, get_hook_method, get_files_path
from frappe import _
from frappe import conf
+from copy import copy
class MaxFileSizeReachedError(frappe.ValidationError): pass
@@ -31,7 +34,11 @@ def upload():
elif file_url:
filedata = save_url(file_url, dt, dn)
- return {"fid": filedata.name, "filename": filedata.file_name or filedata.file_url }
+ return {
+ "name": filedata.name,
+ "file_name": filedata.file_name,
+ "file_url": filedata.file_url
+ }
def save_uploaded(dt, dn):
fname, content = get_uploaded_content()
@@ -45,7 +52,7 @@ def save_url(file_url, dt, dn):
# frappe.msgprint("URL must start with 'http://' or 'https://'")
# return None, None
- f = frappe.bean({
+ f = frappe.get_doc({
"doctype": "File Data",
"file_url": file_url,
"attached_to_doctype": dt,
@@ -55,8 +62,8 @@ def save_url(file_url, dt, dn):
try:
f.insert();
except frappe.DuplicateEntryError:
- return frappe.doc("File Data", f.doc.duplicate_entry)
- return f.doc
+ return frappe.get_doc("File Data", f.duplicate_entry)
+ return f
def get_uploaded_content():
# should not be unicode when reading a file, hence using frappe.form
@@ -76,115 +83,66 @@ def extract_images_from_html(doc, fieldname):
data = match.group(1)
headers, content = data.split(",")
filename = headers.split("filename=")[-1]
- filename = save_file(filename, content, doc.doctype, doc.name, decode=True).get("file_name")
+ # TODO fix this
+ file_url = save_file(filename, content, doc.doctype, doc.name, decode=True).get("file_url")
if not frappe.flags.has_dataurl:
frappe.flags.has_dataurl = True
- return '
100:
- frappe.msgprint("Too many versions", raise_exception=True)
-
- return new_fname
-
-def scrub_file_name(fname):
- if '\\' in fname:
- fname = fname.split('\\')[-1]
- if '/' in fname:
- fname = fname.split('/')[-1]
- return fname
+def save_file_on_filesystem(fname, content, content_type=None):
+ import filecmp
+ public_path = os.path.join(frappe.local.site_path, "public")
+ fpath = write_file(content, get_files_path(), fname)
+ path = os.path.relpath(fpath, public_path)
+ return {
+ 'file_name': os.path.basename(path),
+ 'file_url': '/' + path
+ }
def check_max_file_size(content):
max_file_size = conf.get('max_file_size') or 1000000
@@ -196,17 +154,14 @@ def check_max_file_size(content):
return file_size
-def write_file(content, files_path):
+def write_file(content, file_path, fname):
"""write file to disk with a random name (to compare)"""
- # create account folder (if not exists)
- frappe.create_folder(files_path)
- fname = os.path.join(files_path, frappe.generate_hash())
-
+ # create directory (if not exists)
+ frappe.create_folder(get_files_path())
# write the file
- with open(fname, 'w+') as f:
+ with open(os.path.join(file_path, fname), 'w+') as f:
f.write(content)
-
- return fname
+ return get_files_path(fname)
def remove_all(dt, dn):
"""remove all files in a transaction"""
@@ -220,6 +175,19 @@ def remove_all(dt, dn):
def remove_file(fid):
"""Remove file and File Data entry"""
frappe.delete_doc("File Data", fid)
+
+def delete_file_data_content(doc):
+ method = get_hook_method('delete_file_data_content', fallback=delete_file_from_filesystem)
+ method(doc)
+
+def delete_file_from_filesystem(doc):
+ path = doc.file_name
+ if path.startswith("files/"):
+ path = frappe.utils.get_site_path("public", doc.file_name)
+ else:
+ path = frappe.utils.get_site_path("public", "files", doc.file_name)
+ if os.path.exists(path):
+ os.remove(path)
def get_file(fname):
f = frappe.db.sql("""select file_name from `tabFile Data`
@@ -237,3 +205,14 @@ def get_file(fname):
content = f.read()
return [file_name, content]
+
+def get_content_hash(content):
+ return hashlib.md5(content).hexdigest()
+
+def get_file_name(fname, optional_suffix):
+ n_records = frappe.db.sql("select name from `tabFile Data` where file_name='{}'".format(fname))
+ if len(n_records) > 0:
+ partial, extn = fname.rsplit('.', 1)
+ return '{partial}{suffix}.{extn}'.format(partial=partial, extn=extn, suffix=optional_suffix)
+ return fname
+
diff --git a/frappe/utils/fixtures.py b/frappe/utils/fixtures.py
index 816e3eccdb..30284c8e1f 100644
--- a/frappe/utils/fixtures.py
+++ b/frappe/utils/fixtures.py
@@ -1,17 +1,17 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
-# MIT License. See license.txt
+# MIT License. See license.txt
from __future__ import unicode_literals
import frappe, os
-from frappe.core.page.data_import_tool.data_import_tool import import_doclist, export_fixture, export_csv
+from frappe.core.page.data_import_tool.data_import_tool import import_doc, export_fixture, export_csv
def sync_fixtures():
for app in frappe.get_installed_apps():
if os.path.exists(frappe.get_app_path(app, "fixtures")):
for fname in os.listdir(frappe.get_app_path(app, "fixtures")):
if fname.endswith(".json") or fname.endswith(".csv"):
- import_doclist(frappe.get_app_path(app, "fixtures", fname), ignore_links=True, overwrite=True)
+ import_doc(frappe.get_app_path(app, "fixtures", fname), ignore_links=True, overwrite=True)
def export_fixtures():
diff --git a/frappe/utils/install.py b/frappe/utils/install.py
index 96c70bbffc..8d7ed41f26 100644
--- a/frappe/utils/install.py
+++ b/frappe/utils/install.py
@@ -29,12 +29,12 @@ def after_install():
for d in install_docs:
try:
- frappe.bean(d).insert()
+ frappe.get_doc(d).insert()
except NameError:
pass
# all roles to admin
- frappe.bean("User", "Administrator").get_controller().add_roles(*frappe.db.sql_list("""
+ frappe.get_doc("User", "Administrator").add_roles(*frappe.db.sql_list("""
select name from tabRole"""))
# update admin password
diff --git a/frappe/utils/nestedset.py b/frappe/utils/nestedset.py
index 693f2da911..5d4c30521f 100644
--- a/frappe/utils/nestedset.py
+++ b/frappe/utils/nestedset.py
@@ -14,6 +14,7 @@ from __future__ import unicode_literals
import frappe
from frappe import msgprint, _
+from frappe.model.document import Document
class NestedSetRecursionError(frappe.ValidationError): pass
class NestedSetMultipleRootsError(frappe.ValidationError): pass
@@ -21,38 +22,29 @@ class NestedSetChildExistsError(frappe.ValidationError): pass
class NestedSetInvalidMergeError(frappe.ValidationError): pass
# called in the on_update method
-def update_nsm(doc_obj):
+def update_nsm(doc):
# get fields, data from the DocType
opf = 'old_parent'
+ pf = "parent_" + frappe.scrub(doc.doctype)
- if str(doc_obj.__class__)=='frappe.model.doc.Document':
- # passed as a Document object
- d = doc_obj
- pf = "parent_" + frappe.scrub(d.doctype)
- else:
- # passed as a DocType object
- d = doc_obj.doc
- pf = "parent_" + frappe.scrub(d.doctype)
-
- if hasattr(doc_obj,'nsm_parent_field'):
- pf = doc_obj.nsm_parent_field
- if hasattr(doc_obj,'nsm_oldparent_field'):
- opf = doc_obj.nsm_oldparent_field
+ if hasattr(doc,'nsm_parent_field'):
+ pf = doc.nsm_parent_field
+ if hasattr(doc,'nsm_oldparent_field'):
+ opf = doc.nsm_oldparent_field
- p, op = d.fields.get(pf) or None, d.fields.get(opf) or None
+ p, op = doc.get(pf) or None, doc.get(opf) or None
# has parent changed (?) or parent is None (root)
- if not d.lft and not d.rgt:
- update_add_node(d, p or '', pf)
+ if not doc.lft and not doc.rgt:
+ update_add_node(doc, p or '', pf)
elif op != p:
- update_move_node(d, pf)
+ update_move_node(doc, pf)
# set old parent
- d.fields[opf] = p
- frappe.db.set_value(d.doctype, d.name, opf, p or '')
-
- # reload
- d._loadfromdb()
+ doc.set(opf, p)
+ frappe.db.set_value(doc.doctype, doc.name, opf, p or '')
+
+ doc.load_from_db()
def update_add_node(doc, parent, parent_field):
"""
@@ -91,7 +83,7 @@ def update_add_node(doc, parent, parent_field):
def update_move_node(doc, parent_field):
- parent = doc.fields.get(parent_field)
+ parent = doc.get(parent_field)
if parent:
new_parent = frappe.db.sql("""select lft, rgt from `tab%s`
@@ -188,54 +180,54 @@ def validate_loop(doctype, name, lft, rgt):
"%s", "%s"), (lft, rgt)):
frappe.throw("""Item cannot be added to its own descendents.""", NestedSetRecursionError)
-class DocTypeNestedSet(object):
+class NestedSet(Document):
def on_update(self):
update_nsm(self)
self.validate_ledger()
def on_trash(self):
if not self.nsm_parent_field:
- self.nsm_parent_field = frappe.scrub(self.doc.doctype) + "_parent"
+ self.nsm_parent_field = frappe.scrub(self.doctype) + "_parent"
- parent = self.doc.fields[self.nsm_parent_field]
+ parent = self.get(self.nsm_parent_field)
if not parent:
- msgprint(_("Root ") + self.doc.doctype + _(" cannot be deleted."), raise_exception=1)
+ msgprint(_("Root ") + self.doctype + _(" cannot be deleted."), raise_exception=1)
# cannot delete non-empty group
has_children = frappe.db.sql("""select count(name) from `tab{doctype}`
- where `{nsm_parent_field}`=%s""".format(doctype=self.doc.doctype, nsm_parent_field=self.nsm_parent_field),
- (self.doc.name,))[0][0]
+ where `{nsm_parent_field}`=%s""".format(doctype=self.doctype, nsm_parent_field=self.nsm_parent_field),
+ (self.name,))[0][0]
if has_children:
frappe.throw("{cannot_delete}. {children_exist}: {name}.".format(
- children_exist=_("Children exist for"), name=self.doc.name,
+ children_exist=_("Children exist for"), name=self.name,
cannot_delete=_("Cannot delete")), NestedSetChildExistsError)
- self.doc.fields[self.nsm_parent_field] = ""
+ self.set(self.nsm_parent_field, "")
update_nsm(self)
def before_rename(self, olddn, newdn, merge=False, group_fname="is_group"):
if merge:
- is_group = frappe.db.get_value(self.doc.doctype, newdn, group_fname)
- if self.doc.fields[group_fname] != is_group:
+ is_group = frappe.db.get_value(self.doctype, newdn, group_fname)
+ if self.get(group_fname) != is_group:
frappe.throw(_("""Merging is only possible between Group-to-Group or
Ledger-to-Ledger"""), NestedSetInvalidMergeError)
def after_rename(self, olddn, newdn, merge=False):
if merge:
- parent_field = "parent_" + self.doc.doctype.replace(" ", "_").lower()
- rebuild_tree(self.doc.doctype, parent_field)
+ parent_field = "parent_" + self.doctype.replace(" ", "_").lower()
+ rebuild_tree(self.doctype, parent_field)
def validate_one_root(self):
- if not self.doc.fields[self.nsm_parent_field]:
+ if not self.get(self.nsm_parent_field):
if frappe.db.sql("""select count(*) from `tab%s` where
- ifnull(%s, '')=''""" % (self.doc.doctype, self.nsm_parent_field))[0][0] > 1:
+ ifnull(%s, '')=''""" % (self.doctype, self.nsm_parent_field))[0][0] > 1:
frappe.throw(_("""Multiple root nodes not allowed."""), NestedSetMultipleRootsError)
def validate_ledger(self, group_identifier="is_group"):
- if self.doc.fields.get(group_identifier) == "No":
+ if self.get(group_identifier) == "No":
if frappe.db.sql("""select name from `tab%s` where %s=%s and docstatus!=2""" %
- (self.doc.doctype, self.nsm_parent_field, '%s'), (self.doc.name)):
- frappe.throw(self.doc.doctype + ": " + self.doc.name +
+ (self.doctype, self.nsm_parent_field, '%s'), (self.name)):
+ frappe.throw(self.doctype + ": " + self.name +
_(" can not be marked as a ledger as it has existing child"))
def get_root_of(doctype):
diff --git a/frappe/utils/response.py b/frappe/utils/response.py
index 89ac744aa5..ea13fe8bf2 100644
--- a/frappe/utils/response.py
+++ b/frappe/utils/response.py
@@ -9,7 +9,7 @@ import mimetypes
import os
import frappe
from frappe import _
-from frappe.model.doc import Document
+import frappe.model.document
import frappe.utils
import frappe.sessions
import frappe.model.utils
@@ -28,6 +28,9 @@ def report_error(status_code):
return response
def build_response(response_type=None):
+ if "docs" in frappe.local.response and not frappe.local.response.docs:
+ del frappe.local.response["docs"]
+
response_type_map = {
'csv': as_csv,
'download': as_raw,
@@ -54,7 +57,6 @@ def as_raw():
def as_json():
make_logs()
- cleanup_docs()
response = Response()
response.headers["Content-Type"] = "application/json; charset: utf-8"
response = gzip(json.dumps(frappe.local.response, default=json_handler, separators=(',',':')),
@@ -68,14 +70,11 @@ def make_logs():
frappe.response['exc'] = json.dumps([frappe.utils.cstr(d) for d in frappe.local.error_log])
if frappe.local.message_log:
- frappe.response['_server_messages'] = json.dumps([frappe.utils.cstr(d) for d in frappe.local.message_log])
+ frappe.response['_server_messages'] = json.dumps([frappe.utils.cstr(d) for
+ d in frappe.local.message_log])
if frappe.debug_log and frappe.conf.get("logging") or False:
frappe.response['_debug_messages'] = json.dumps(frappe.local.debug_log)
-
-def cleanup_docs():
- if frappe.response.get('docs') and type(frappe.response['docs'])!=dict:
- frappe.response['docs'] = frappe.model.utils.compress(frappe.response['docs'])
def gzip(data, response):
data = data.encode('utf-8')
@@ -101,14 +100,13 @@ def compressBuf(buf):
def json_handler(obj):
"""serialize non-serializable data for json"""
-
# serialize date
if isinstance(obj, (datetime.date, datetime.timedelta, datetime.datetime)):
return unicode(obj)
elif isinstance(obj, LocalProxy):
return unicode(obj)
- elif isinstance(obj, Document):
- return obj.fields
+ elif isinstance(obj, frappe.model.document.Document):
+ return obj.as_dict()
else:
raise TypeError, """Object of type %s with value of %s is not JSON serializable""" % \
(type(obj), repr(obj))
diff --git a/frappe/utils/scheduler.py b/frappe/utils/scheduler.py
index f4d743aaea..c0153956e8 100644
--- a/frappe/utils/scheduler.py
+++ b/frappe/utils/scheduler.py
@@ -97,7 +97,7 @@ def log(method, message=None):
frappe.db.rollback()
frappe.db.begin()
- d = frappe.doc("Scheduler Log")
+ d = frappe.get_doc("Scheduler Log")
d.method = method
d.error = message
d.save()
diff --git a/frappe/utils/user.py b/frappe/utils/user.py
index 1c1d340146..59ce22ea0b 100644
--- a/frappe/utils/user.py
+++ b/frappe/utils/user.py
@@ -195,12 +195,12 @@ def get_system_managers(only_name=False):
return [email.utils.formataddr((p.fullname, p.name)) for p in system_managers]
def add_role(user, role):
- user_wrapper = frappe.bean("User", user).get_controller().add_roles(role)
+ user_wrapper = frappe.get_doc("User", user).add_roles(role)
def add_system_manager(email, first_name=None, last_name=None):
# add user
- user = frappe.new_bean("User")
- user.doc.fields.update({
+ user = frappe.new_doc("User")
+ user.update({
"name": email,
"email": email,
"enabled": 1,
@@ -213,7 +213,7 @@ def add_system_manager(email, first_name=None, last_name=None):
# add roles
roles = frappe.db.sql_list("""select name from `tabRole`
where name not in ("Administrator", "Guest", "All")""")
- user.get_controller().add_roles(*roles)
+ user.add_roles(*roles)
def get_roles(username=None, with_standard=True):
"""get roles of current user"""
diff --git a/frappe/utils/verified_command.py b/frappe/utils/verified_command.py
index 8d4c30a3f4..b3bf4316cc 100644
--- a/frappe/utils/verified_command.py
+++ b/frappe/utils/verified_command.py
@@ -23,12 +23,10 @@ def get_signature(params, nonce, secret=None):
signature.update(params)
return signature.hexdigest()
-def verify_using_bean(bean, signature, cmd):
- controller = bean.get_controller()
- params = controller.get_signature_params()
- return signature == get_signature(params, controller.get_nonce())
+def verify_using_doc(doc, signature, cmd):
+ params = doc.get_signature_params()
+ return signature == get_signature(params, doc.get_nonce())
-def get_url_using_bean(bean, cmd):
- controller = bean.get_controller()
- params = controller.get_signature_params()
- return get_url(cmd, params, controller.get_nonce())
+def get_url_using_doc(doc, cmd):
+ params = doc.get_signature_params()
+ return get_url(cmd, params, doc.get_nonce())
diff --git a/frappe/website/context.py b/frappe/website/context.py
index cf573202fd..15002468af 100644
--- a/frappe/website/context.py
+++ b/frappe/website/context.py
@@ -28,41 +28,37 @@ def get_context(path):
context = build_context(context)
- if can_cache(context.no_cache):
+ if can_cache(context.no_cache):
frappe.cache().set_value(cache_key, context)
else:
context["access"] = get_access(context.pathname)
-
+
if not context.data:
context.data = {}
context.data["path"] = path
context.update(context.data or {})
-
+
# TODO private pages
-
+
return context
-
+
def build_context(sitemap_options):
- """get_context method of bean or module is supposed to render content templates and push it into context"""
+ """get_context method of doc or module is supposed to render content templates and push it into context"""
context = frappe._dict(sitemap_options)
context.update(get_website_settings())
-
- # provide bean
+
+ # provide doc
if context.doctype and context.docname:
- context.bean = frappe.bean(context.doctype, context.docname)
-
+ context.doc = frappe.get_doc(context.doctype, context.docname)
+
if context.controller:
module = frappe.get_module(context.controller)
if module and hasattr(module, "get_context"):
context.update(module.get_context(context) or {})
-
+
if context.get("base_template_path") != context.get("template_path") and not context.get("rendered"):
context.data = render_blocks(context)
-
- # remove bean, as it is not pickle friendly and its purpose is over
- if context.bean:
- del context["bean"]
-
+
return context
diff --git a/frappe/website/doctype/about_us_settings/about_us_settings.json b/frappe/website/doctype/about_us_settings/about_us_settings.json
new file mode 100644
index 0000000000..674fe27d52
--- /dev/null
+++ b/frappe/website/doctype/about_us_settings/about_us_settings.json
@@ -0,0 +1,101 @@
+{
+ "allow_attach": 1,
+ "creation": "2013-03-19 12:02:15.000000",
+ "description": "Settings for the About Us Page",
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "Other",
+ "fields": [
+ {
+ "fieldname": "help",
+ "fieldtype": "HTML",
+ "label": "Help",
+ "options": "
Link for About Us Page is \"/about\"
",
+ "permlevel": 0,
+ "read_only": 0
+ },
+ {
+ "description": "Introduce your company to the website visitor.",
+ "fieldname": "company_introduction",
+ "fieldtype": "Text Editor",
+ "label": "Company Introduction",
+ "permlevel": 0,
+ "read_only": 0
+ },
+ {
+ "fieldname": "sb0",
+ "fieldtype": "Section Break",
+ "label": "Org History",
+ "permlevel": 0,
+ "read_only": 0
+ },
+ {
+ "description": "\"Company History\"",
+ "fieldname": "company_history_heading",
+ "fieldtype": "Data",
+ "label": "Org History Heading",
+ "permlevel": 0,
+ "read_only": 0
+ },
+ {
+ "fieldname": "company_history",
+ "fieldtype": "Table",
+ "label": "Org History",
+ "options": "Company History",
+ "permlevel": 0,
+ "read_only": 0
+ },
+ {
+ "fieldname": "sb1",
+ "fieldtype": "Section Break",
+ "label": "Team Members",
+ "permlevel": 0,
+ "read_only": 0
+ },
+ {
+ "description": "\"Team Members\" or \"Management\"",
+ "fieldname": "team_members_heading",
+ "fieldtype": "Data",
+ "label": "Team Members Heading",
+ "permlevel": 0,
+ "read_only": 0
+ },
+ {
+ "fieldname": "team_members",
+ "fieldtype": "Table",
+ "label": "Team Members",
+ "options": "About Us Team Member",
+ "permlevel": 0,
+ "read_only": 0
+ },
+ {
+ "description": "More content for the bottom of the page.",
+ "fieldname": "footer",
+ "fieldtype": "Text Editor",
+ "label": "Footer",
+ "permlevel": 0,
+ "read_only": 0
+ }
+ ],
+ "icon": "icon-group",
+ "idx": 1,
+ "issingle": 1,
+ "modified": "2013-12-20 19:22:52.000000",
+ "modified_by": "Administrator",
+ "module": "Website",
+ "name": "About Us Settings",
+ "owner": "Administrator",
+ "permissions": [
+ {
+ "create": 1,
+ "email": 1,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 0,
+ "role": "Website Manager",
+ "submit": 0,
+ "write": 1
+ }
+ ]
+}
\ No newline at end of file
diff --git a/frappe/website/doctype/about_us_settings/about_us_settings.py b/frappe/website/doctype/about_us_settings/about_us_settings.py
index 5c272ba8da..8186ac9342 100644
--- a/frappe/website/doctype/about_us_settings/about_us_settings.py
+++ b/frappe/website/doctype/about_us_settings/about_us_settings.py
@@ -6,16 +6,16 @@
from __future__ import unicode_literals
import frappe
-class DocType:
- def __init__(self, d, dl):
- self.doc, self.doclist = d, dl
+from frappe.model.document import Document
+
+class AboutUsSettings(Document):
def on_update(self):
from frappe.website.render import clear_cache
clear_cache("about")
def get_args():
- obj = frappe.get_obj("About Us Settings")
+ obj = frappe.get_doc("About Us Settings")
return {
"obj": obj
}
\ No newline at end of file
diff --git a/frappe/website/doctype/about_us_settings/about_us_settings.txt b/frappe/website/doctype/about_us_settings/about_us_settings.txt
deleted file mode 100644
index 956117c78c..0000000000
--- a/frappe/website/doctype/about_us_settings/about_us_settings.txt
+++ /dev/null
@@ -1,112 +0,0 @@
-[
- {
- "creation": "2013-03-19 12:02:15",
- "docstatus": 0,
- "modified": "2013-12-20 19:22:52",
- "modified_by": "Administrator",
- "owner": "Administrator"
- },
- {
- "allow_attach": 1,
- "description": "Settings for the About Us Page",
- "doctype": "DocType",
- "document_type": "Other",
- "icon": "icon-group",
- "issingle": 1,
- "module": "Website",
- "name": "__common__"
- },
- {
- "doctype": "DocField",
- "name": "__common__",
- "parent": "About Us Settings",
- "parentfield": "fields",
- "parenttype": "DocType",
- "permlevel": 0,
- "read_only": 0
- },
- {
- "create": 1,
- "doctype": "DocPerm",
- "email": 1,
- "name": "__common__",
- "parent": "About Us Settings",
- "parentfield": "permissions",
- "parenttype": "DocType",
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 0,
- "role": "Website Manager",
- "submit": 0,
- "write": 1
- },
- {
- "doctype": "DocType",
- "name": "About Us Settings"
- },
- {
- "doctype": "DocField",
- "fieldname": "help",
- "fieldtype": "HTML",
- "label": "Help",
- "options": "
Link for About Us Page is \"/about\"
"
- },
- {
- "description": "Introduce your company to the website visitor.",
- "doctype": "DocField",
- "fieldname": "company_introduction",
- "fieldtype": "Text Editor",
- "label": "Company Introduction"
- },
- {
- "doctype": "DocField",
- "fieldname": "sb0",
- "fieldtype": "Section Break",
- "label": "Org History"
- },
- {
- "description": "\"Company History\"",
- "doctype": "DocField",
- "fieldname": "company_history_heading",
- "fieldtype": "Data",
- "label": "Org History Heading"
- },
- {
- "doctype": "DocField",
- "fieldname": "company_history",
- "fieldtype": "Table",
- "label": "Org History",
- "options": "Company History"
- },
- {
- "doctype": "DocField",
- "fieldname": "sb1",
- "fieldtype": "Section Break",
- "label": "Team Members"
- },
- {
- "description": "\"Team Members\" or \"Management\"",
- "doctype": "DocField",
- "fieldname": "team_members_heading",
- "fieldtype": "Data",
- "label": "Team Members Heading"
- },
- {
- "doctype": "DocField",
- "fieldname": "team_members",
- "fieldtype": "Table",
- "label": "Team Members",
- "options": "About Us Team Member"
- },
- {
- "description": "More content for the bottom of the page.",
- "doctype": "DocField",
- "fieldname": "footer",
- "fieldtype": "Text Editor",
- "label": "Footer"
- },
- {
- "doctype": "DocPerm"
- }
-]
\ No newline at end of file
diff --git a/frappe/website/doctype/about_us_team_member/about_us_team_member.json b/frappe/website/doctype/about_us_team_member/about_us_team_member.json
new file mode 100644
index 0000000000..11f197ce42
--- /dev/null
+++ b/frappe/website/doctype/about_us_team_member/about_us_team_member.json
@@ -0,0 +1,41 @@
+{
+ "creation": "2013-03-07 11:55:11.000000",
+ "docstatus": 0,
+ "doctype": "DocType",
+ "fields": [
+ {
+ "fieldname": "full_name",
+ "fieldtype": "Data",
+ "in_list_view": 1,
+ "label": "Full Name",
+ "permlevel": 0,
+ "reqd": 1,
+ "width": "150px"
+ },
+ {
+ "fieldname": "image_link",
+ "fieldtype": "Select",
+ "in_list_view": 1,
+ "label": "Image Link",
+ "options": "attach_files:",
+ "permlevel": 0,
+ "width": "150px"
+ },
+ {
+ "fieldname": "bio",
+ "fieldtype": "Small Text",
+ "in_list_view": 1,
+ "label": "Bio",
+ "permlevel": 0,
+ "reqd": 1,
+ "width": "200px"
+ }
+ ],
+ "idx": 1,
+ "istable": 1,
+ "modified": "2013-12-20 19:22:52.000000",
+ "modified_by": "Administrator",
+ "module": "Website",
+ "name": "About Us Team Member",
+ "owner": "Administrator"
+}
\ No newline at end of file
diff --git a/frappe/website/doctype/about_us_team_member/about_us_team_member.py b/frappe/website/doctype/about_us_team_member/about_us_team_member.py
index cb42e2eea2..1dea8b4be3 100644
--- a/frappe/website/doctype/about_us_team_member/about_us_team_member.py
+++ b/frappe/website/doctype/about_us_team_member/about_us_team_member.py
@@ -6,6 +6,7 @@
from __future__ import unicode_literals
import frappe
-class DocType:
- def __init__(self, d, dl):
- self.doc, self.doclist = d, dl
\ No newline at end of file
+from frappe.model.document import Document
+
+class AboutUsTeamMember(Document):
+ pass
\ No newline at end of file
diff --git a/frappe/website/doctype/about_us_team_member/about_us_team_member.txt b/frappe/website/doctype/about_us_team_member/about_us_team_member.txt
deleted file mode 100644
index 8d34a53c4f..0000000000
--- a/frappe/website/doctype/about_us_team_member/about_us_team_member.txt
+++ /dev/null
@@ -1,52 +0,0 @@
-[
- {
- "creation": "2013-03-07 11:55:11",
- "docstatus": 0,
- "modified": "2013-12-20 19:22:52",
- "modified_by": "Administrator",
- "owner": "Administrator"
- },
- {
- "doctype": "DocType",
- "istable": 1,
- "module": "Website",
- "name": "__common__"
- },
- {
- "doctype": "DocField",
- "in_list_view": 1,
- "name": "__common__",
- "parent": "About Us Team Member",
- "parentfield": "fields",
- "parenttype": "DocType",
- "permlevel": 0
- },
- {
- "doctype": "DocType",
- "name": "About Us Team Member"
- },
- {
- "doctype": "DocField",
- "fieldname": "full_name",
- "fieldtype": "Data",
- "label": "Full Name",
- "reqd": 1,
- "width": "150px"
- },
- {
- "doctype": "DocField",
- "fieldname": "image_link",
- "fieldtype": "Select",
- "label": "Image Link",
- "options": "attach_files:",
- "width": "150px"
- },
- {
- "doctype": "DocField",
- "fieldname": "bio",
- "fieldtype": "Small Text",
- "label": "Bio",
- "reqd": 1,
- "width": "200px"
- }
-]
\ No newline at end of file
diff --git a/frappe/website/doctype/blog_category/blog_category.json b/frappe/website/doctype/blog_category/blog_category.json
new file mode 100644
index 0000000000..5d57f4efed
--- /dev/null
+++ b/frappe/website/doctype/blog_category/blog_category.json
@@ -0,0 +1,75 @@
+{
+ "allow_import": 1,
+ "autoname": "field:category_name",
+ "creation": "2013-03-08 09:41:11.000000",
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "Master",
+ "fields": [
+ {
+ "fieldname": "category_name",
+ "fieldtype": "Data",
+ "label": "Category Name",
+ "permlevel": 0,
+ "reqd": 1
+ },
+ {
+ "fieldname": "title",
+ "fieldtype": "Data",
+ "label": "Title",
+ "permlevel": 0,
+ "reqd": 1
+ },
+ {
+ "fieldname": "published",
+ "fieldtype": "Check",
+ "label": "Published",
+ "permlevel": 0
+ },
+ {
+ "default": "blog",
+ "fieldname": "parent_website_route",
+ "fieldtype": "Link",
+ "label": "Parent Website Route",
+ "options": "Website Route",
+ "permlevel": 0,
+ "reqd": 1
+ },
+ {
+ "fieldname": "page_name",
+ "fieldtype": "Data",
+ "label": "Page Name",
+ "permlevel": 0
+ }
+ ],
+ "icon": "icon-tag",
+ "idx": 1,
+ "modified": "2014-02-18 15:25:05.000000",
+ "modified_by": "Administrator",
+ "module": "Website",
+ "name": "Blog Category",
+ "owner": "Administrator",
+ "permissions": [
+ {
+ "cancel": 0,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Website Manager",
+ "write": 1
+ },
+ {
+ "cancel": 0,
+ "delete": 0,
+ "email": 1,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "role": "Blogger"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/frappe/website/doctype/blog_category/blog_category.py b/frappe/website/doctype/blog_category/blog_category.py
index 492ca04eb6..b768a32dd6 100644
--- a/frappe/website/doctype/blog_category/blog_category.py
+++ b/frappe/website/doctype/blog_category/blog_category.py
@@ -6,16 +6,14 @@ import frappe
from frappe.website.website_generator import WebsiteGenerator
from frappe.website.render import clear_cache
-class DocType(WebsiteGenerator):
- def __init__(self, d, dl):
- self.doc, self.doclist = d, dl
+class BlogCategory(WebsiteGenerator):
def autoname(self):
# to override autoname of WebsiteGenerator
- self.doc.name = self.doc.category_name
+ self.name = self.category_name
def get_page_title(self):
- return self.doc.title or self.doc.name
+ return self.title or self.name
def on_update(self):
WebsiteGenerator.on_update(self)
diff --git a/frappe/website/doctype/blog_category/blog_category.txt b/frappe/website/doctype/blog_category/blog_category.txt
deleted file mode 100644
index 3508e60faa..0000000000
--- a/frappe/website/doctype/blog_category/blog_category.txt
+++ /dev/null
@@ -1,90 +0,0 @@
-[
- {
- "creation": "2013-03-08 09:41:11",
- "docstatus": 0,
- "modified": "2014-02-18 15:25:05",
- "modified_by": "Administrator",
- "owner": "Administrator"
- },
- {
- "allow_import": 1,
- "autoname": "field:category_name",
- "doctype": "DocType",
- "document_type": "Master",
- "icon": "icon-tag",
- "module": "Website",
- "name": "__common__"
- },
- {
- "doctype": "DocField",
- "name": "__common__",
- "parent": "Blog Category",
- "parentfield": "fields",
- "parenttype": "DocType",
- "permlevel": 0
- },
- {
- "cancel": 0,
- "doctype": "DocPerm",
- "email": 1,
- "name": "__common__",
- "parent": "Blog Category",
- "parentfield": "permissions",
- "parenttype": "DocType",
- "permlevel": 0,
- "print": 1,
- "read": 1
- },
- {
- "doctype": "DocType",
- "name": "Blog Category"
- },
- {
- "doctype": "DocField",
- "fieldname": "category_name",
- "fieldtype": "Data",
- "label": "Category Name",
- "reqd": 1
- },
- {
- "doctype": "DocField",
- "fieldname": "title",
- "fieldtype": "Data",
- "label": "Title",
- "reqd": 1
- },
- {
- "doctype": "DocField",
- "fieldname": "published",
- "fieldtype": "Check",
- "label": "Published"
- },
- {
- "default": "blog",
- "doctype": "DocField",
- "fieldname": "parent_website_route",
- "fieldtype": "Link",
- "label": "Parent Website Route",
- "options": "Website Route",
- "reqd": 1
- },
- {
- "doctype": "DocField",
- "fieldname": "page_name",
- "fieldtype": "Data",
- "label": "Page Name"
- },
- {
- "create": 1,
- "delete": 1,
- "doctype": "DocPerm",
- "report": 1,
- "role": "Website Manager",
- "write": 1
- },
- {
- "delete": 0,
- "doctype": "DocPerm",
- "role": "Blogger"
- }
-]
\ No newline at end of file
diff --git a/frappe/website/doctype/blog_category/test_blog_category.py b/frappe/website/doctype/blog_category/test_blog_category.py
index 6c6ee45a2a..5a227df02b 100644
--- a/frappe/website/doctype/blog_category/test_blog_category.py
+++ b/frappe/website/doctype/blog_category/test_blog_category.py
@@ -1,17 +1,6 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt
-test_records = [
- [{
- "doctype": "Blog Category",
- "category_name": "_Test Blog Category",
- "title": "_Test Blog Category",
- "parent_website_route": "blog"
- }],
- [{
- "doctype": "Blog Category",
- "category_name": "_Test Blog Category 1",
- "title": "_Test Blog Category 1",
- "parent_website_route": "blog"
- }]
-]
\ No newline at end of file
+import frappe
+
+test_records = frappe.get_test_records('Blog Category')
\ No newline at end of file
diff --git a/frappe/website/doctype/blog_category/test_records.json b/frappe/website/doctype/blog_category/test_records.json
new file mode 100644
index 0000000000..d4533ed27c
--- /dev/null
+++ b/frappe/website/doctype/blog_category/test_records.json
@@ -0,0 +1,14 @@
+[
+ {
+ "category_name": "_Test Blog Category",
+ "doctype": "Blog Category",
+ "parent_website_route": "blog",
+ "title": "_Test Blog Category"
+ },
+ {
+ "category_name": "_Test Blog Category 1",
+ "doctype": "Blog Category",
+ "parent_website_route": "blog",
+ "title": "_Test Blog Category 1"
+ }
+]
\ No newline at end of file
diff --git a/frappe/website/doctype/blog_post/blog_post.js b/frappe/website/doctype/blog_post/blog_post.js
index f02b95ead3..ed555352d7 100644
--- a/frappe/website/doctype/blog_post/blog_post.js
+++ b/frappe/website/doctype/blog_post/blog_post.js
@@ -5,7 +5,7 @@ cur_frm.cscript.refresh = function(doc) {
if(!doc.__islocal && doc.published) {
if(!doc.email_sent) {
cur_frm.add_custom_button('Email Subscribers', function() {
- $c_obj(make_doclist(doc.doctype, doc.name), 'send_emails', '', function(r) {
+ $c_obj(doc, 'send_emails', '', function(r) {
cur_frm.refresh();
});
});
diff --git a/frappe/website/doctype/blog_post/blog_post.json b/frappe/website/doctype/blog_post/blog_post.json
new file mode 100644
index 0000000000..22b4cc68cd
--- /dev/null
+++ b/frappe/website/doctype/blog_post/blog_post.json
@@ -0,0 +1,144 @@
+{
+ "allow_attach": 1,
+ "allow_import": 1,
+ "creation": "2013-03-28 10:35:30.000000",
+ "docstatus": 0,
+ "doctype": "DocType",
+ "fields": [
+ {
+ "fieldname": "title",
+ "fieldtype": "Data",
+ "label": "Title",
+ "permlevel": 0,
+ "reqd": 1
+ },
+ {
+ "fieldname": "published_on",
+ "fieldtype": "Date",
+ "label": "Published On",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "published",
+ "fieldtype": "Check",
+ "label": "Published",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "column_break_3",
+ "fieldtype": "Column Break",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "blogger",
+ "fieldtype": "Link",
+ "in_list_view": 1,
+ "label": "Blogger",
+ "options": "Blogger",
+ "permlevel": 0,
+ "reqd": 1
+ },
+ {
+ "fieldname": "blog_category",
+ "fieldtype": "Link",
+ "in_list_view": 1,
+ "label": "Blog Category",
+ "options": "Blog Category",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "parent_website_route",
+ "fieldtype": "Link",
+ "hidden": 1,
+ "label": "Parent Website Route",
+ "options": "Website Route",
+ "permlevel": 0,
+ "read_only": 1
+ },
+ {
+ "fieldname": "section_break_5",
+ "fieldtype": "Section Break",
+ "permlevel": 0
+ },
+ {
+ "description": "Description for listing page, in plain text, only a couple of lines. (max 140 characters)",
+ "fieldname": "blog_intro",
+ "fieldtype": "Small Text",
+ "in_list_view": 1,
+ "label": "Blog Intro",
+ "permlevel": 0,
+ "reqd": 0
+ },
+ {
+ "fieldname": "content",
+ "fieldtype": "Text Editor",
+ "label": "Content",
+ "permlevel": 0,
+ "reqd": 1
+ },
+ {
+ "fieldname": "page_name",
+ "fieldtype": "Data",
+ "hidden": 1,
+ "label": "Page Name",
+ "permlevel": 0,
+ "read_only": 1
+ },
+ {
+ "fieldname": "email_sent",
+ "fieldtype": "Check",
+ "hidden": 1,
+ "label": "Email Sent",
+ "permlevel": 0
+ }
+ ],
+ "icon": "icon-quote-left",
+ "idx": 1,
+ "max_attachments": 5,
+ "modified": "2014-02-20 12:55:07.000000",
+ "modified_by": "Administrator",
+ "module": "Website",
+ "name": "Blog Post",
+ "owner": "Administrator",
+ "permissions": [
+ {
+ "cancel": 0,
+ "create": 1,
+ "delete": 0,
+ "email": 1,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "restrict": 1,
+ "role": "Website Manager",
+ "submit": 0,
+ "write": 1
+ },
+ {
+ "cancel": 0,
+ "create": 1,
+ "delete": 0,
+ "email": 1,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Blogger",
+ "submit": 0,
+ "write": 1
+ },
+ {
+ "cancel": 0,
+ "delete": 0,
+ "email": 1,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Guest",
+ "submit": 0,
+ "write": 0
+ }
+ ]
+}
\ No newline at end of file
diff --git a/frappe/website/doctype/blog_post/blog_post.py b/frappe/website/doctype/blog_post/blog_post.py
index 09b09aad52..aaaa551b83 100644
--- a/frappe/website/doctype/blog_post/blog_post.py
+++ b/frappe/website/doctype/blog_post/blog_post.py
@@ -10,32 +10,30 @@ from frappe.website.render import clear_cache
from frappe import _
from frappe.utils import today
-class DocType(WebsiteGenerator):
- def __init__(self, d, dl):
- self.doc, self.doclist = d, dl
- self.save_versions = True
+class BlogPost(WebsiteGenerator):
+ save_versions = True
def get_page_title(self):
- return self.doc.title
+ return self.title
def validate(self):
- if not self.doc.blog_intro:
- self.doc.blog_intro = self.doc.content[:140]
- re.sub("\<[^>]*\>", "", self.doc.blog_intro)
+ if not self.blog_intro:
+ self.blog_intro = self.content[:140]
+ re.sub("\<[^>]*\>", "", self.blog_intro)
- if self.doc.blog_intro:
- self.doc.blog_intro = self.doc.blog_intro[:140]
+ if self.blog_intro:
+ self.blog_intro = self.blog_intro[:140]
- if self.doc.published and not self.doc.published_on:
- self.doc.published_on = today()
+ if self.published and not self.published_on:
+ self.published_on = today()
- self.doc.parent_website_route = frappe.db.get_value("Website Route",
- {"ref_doctype": "Blog Category", "docname": self.doc.blog_category})
+ self.parent_website_route = frappe.db.get_value("Website Route",
+ {"ref_doctype": "Blog Category", "docname": self.blog_category})
# update posts
frappe.db.sql("""update tabBlogger set posts=(select count(*) from `tabBlog Post`
where ifnull(blogger,'')=tabBlogger.name)
- where name=%s""", (self.doc.blogger,))
+ where name=%s""", (self.blogger,))
def on_update(self):
diff --git a/frappe/website/doctype/blog_post/blog_post.txt b/frappe/website/doctype/blog_post/blog_post.txt
deleted file mode 100644
index 84be241b19..0000000000
--- a/frappe/website/doctype/blog_post/blog_post.txt
+++ /dev/null
@@ -1,149 +0,0 @@
-[
- {
- "creation": "2013-03-28 10:35:30",
- "docstatus": 0,
- "modified": "2014-02-20 12:55:07",
- "modified_by": "Administrator",
- "owner": "Administrator"
- },
- {
- "allow_attach": 1,
- "allow_import": 1,
- "doctype": "DocType",
- "icon": "icon-quote-left",
- "max_attachments": 5,
- "module": "Website",
- "name": "__common__"
- },
- {
- "doctype": "DocField",
- "name": "__common__",
- "parent": "Blog Post",
- "parentfield": "fields",
- "parenttype": "DocType",
- "permlevel": 0
- },
- {
- "cancel": 0,
- "delete": 0,
- "doctype": "DocPerm",
- "email": 1,
- "name": "__common__",
- "parent": "Blog Post",
- "parentfield": "permissions",
- "parenttype": "DocType",
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "submit": 0
- },
- {
- "doctype": "DocType",
- "name": "Blog Post"
- },
- {
- "doctype": "DocField",
- "fieldname": "title",
- "fieldtype": "Data",
- "label": "Title",
- "reqd": 1
- },
- {
- "doctype": "DocField",
- "fieldname": "published_on",
- "fieldtype": "Date",
- "label": "Published On"
- },
- {
- "doctype": "DocField",
- "fieldname": "published",
- "fieldtype": "Check",
- "label": "Published"
- },
- {
- "doctype": "DocField",
- "fieldname": "column_break_3",
- "fieldtype": "Column Break"
- },
- {
- "doctype": "DocField",
- "fieldname": "blogger",
- "fieldtype": "Link",
- "in_list_view": 1,
- "label": "Blogger",
- "options": "Blogger",
- "reqd": 1
- },
- {
- "doctype": "DocField",
- "fieldname": "blog_category",
- "fieldtype": "Link",
- "in_list_view": 1,
- "label": "Blog Category",
- "options": "Blog Category"
- },
- {
- "doctype": "DocField",
- "fieldname": "parent_website_route",
- "fieldtype": "Link",
- "hidden": 1,
- "label": "Parent Website Route",
- "options": "Website Route",
- "read_only": 1
- },
- {
- "doctype": "DocField",
- "fieldname": "section_break_5",
- "fieldtype": "Section Break"
- },
- {
- "description": "Description for listing page, in plain text, only a couple of lines. (max 140 characters)",
- "doctype": "DocField",
- "fieldname": "blog_intro",
- "fieldtype": "Small Text",
- "in_list_view": 1,
- "label": "Blog Intro",
- "reqd": 0
- },
- {
- "doctype": "DocField",
- "fieldname": "content",
- "fieldtype": "Text Editor",
- "label": "Content",
- "reqd": 1
- },
- {
- "doctype": "DocField",
- "fieldname": "page_name",
- "fieldtype": "Data",
- "hidden": 1,
- "label": "Page Name",
- "read_only": 1
- },
- {
- "doctype": "DocField",
- "fieldname": "email_sent",
- "fieldtype": "Check",
- "hidden": 1,
- "label": "Email Sent"
- },
- {
- "create": 1,
- "doctype": "DocPerm",
- "restrict": 1,
- "role": "Website Manager",
- "write": 1
- },
- {
- "create": 1,
- "doctype": "DocPerm",
- "role": "Blogger",
- "write": 1
- },
- {
- "doctype": "DocPerm",
- "role": "Guest",
- "write": 0
- }
-]
\ No newline at end of file
diff --git a/frappe/website/doctype/blog_post/test_blog_post.py b/frappe/website/doctype/blog_post/test_blog_post.py
index ac42ccb289..15b615f5de 100644
--- a/frappe/website/doctype/blog_post/test_blog_post.py
+++ b/frappe/website/doctype/blog_post/test_blog_post.py
@@ -3,31 +3,12 @@
"""Use blog post test to test permission restriction logic"""
-test_records = [
- [{
- "doctype": "Blog Post",
- "title":"_Test Blog Post",
- "blog_category": "_Test Blog Category",
- "blogger": "_Test Blogger",
- "blog_intro": "Test Blog Intro",
- "content": "Test Blog Content"
- }],
- [{
- "doctype": "Blog Post",
- "title":"_Test Blog Post 1",
- "blog_category": "_Test Blog Category 1",
- "blogger": "_Test Blogger",
- "blog_intro": "Test Blog Intro",
- "content": "Test Blog Content"
- }]
-
-]
-
import frappe
import frappe.defaults
import unittest
from frappe.core.page.user_properties.user_properties import add, remove, get_properties, clear_restrictions
+test_records = frappe.get_test_records('Blog Post')
test_dependencies = ["User"]
class TestBlogPost(unittest.TestCase):
@@ -39,11 +20,11 @@ class TestBlogPost(unittest.TestCase):
frappe.clear_cache(doctype="Blog Post")
- user = frappe.bean("User", "test1@example.com")
- user.get_controller().add_roles("Website Manager")
+ user = frappe.get_doc("User", "test1@example.com")
+ user.add_roles("Website Manager")
- user = frappe.bean("User", "test2@example.com")
- user.get_controller().add_roles("Blogger")
+ user = frappe.get_doc("User", "test2@example.com")
+ user.add_roles("Blogger")
frappe.set_user("test1@example.com")
@@ -53,18 +34,18 @@ class TestBlogPost(unittest.TestCase):
clear_restrictions("Blog Post")
def test_basic_permission(self):
- post = frappe.bean("Blog Post", "_test-blog-post")
- self.assertTrue(post.has_read_perm())
+ post = frappe.get_doc("Blog Post", "_test-blog-post")
+ self.assertTrue(post.has_permission("read"))
- def test_restriction_in_bean(self):
+ def test_restriction_in_doc(self):
frappe.defaults.add_default("Blog Category", "_Test Blog Category 1", "test1@example.com",
"Restriction")
- post = frappe.bean("Blog Post", "_test-blog-post")
- self.assertFalse(post.has_read_perm())
+ post = frappe.get_doc("Blog Post", "_test-blog-post")
+ self.assertFalse(post.has_permission("read"))
- post1 = frappe.bean("Blog Post", "_test-blog-post-1")
- self.assertTrue(post1.has_read_perm())
+ post1 = frappe.get_doc("Blog Post", "_test-blog-post-1")
+ self.assertTrue(post1.has_permission("read"))
def test_restriction_in_report(self):
frappe.defaults.add_default("Blog Category", "_Test Blog Category 1", "test1@example.com",
@@ -87,16 +68,16 @@ class TestBlogPost(unittest.TestCase):
and ifnull(permlevel,0)=0""")
frappe.clear_cache(doctype="Blog Post")
- def test_owner_match_bean(self):
+ def test_owner_match_doc(self):
self.add_restricted_on_blogger()
frappe.set_user("test2@example.com")
- post = frappe.bean("Blog Post", "_test-blog-post")
- self.assertTrue(post.has_read_perm())
+ post = frappe.get_doc("Blog Post", "_test-blog-post")
+ self.assertTrue(post.has_permission("read"))
- post1 = frappe.bean("Blog Post", "_test-blog-post-1")
- self.assertFalse(post1.has_read_perm())
+ post1 = frappe.get_doc("Blog Post", "_test-blog-post-1")
+ self.assertFalse(post1.has_permission("read"))
def test_owner_match_report(self):
frappe.db.sql("""update tabDocPerm set `restricted`=1 where parent='Blog Post'
@@ -130,12 +111,12 @@ class TestBlogPost(unittest.TestCase):
frappe.set_user("test2@example.com")
# user can only access restricted blog post
- bean = frappe.bean("Blog Post", "_test-blog-post")
- self.assertTrue(bean.has_read_perm())
+ doc = frappe.get_doc("Blog Post", "_test-blog-post")
+ self.assertTrue(doc.has_permission("read"))
# and not this one
- bean = frappe.bean("Blog Post", "_test-blog-post-1")
- self.assertFalse(bean.has_read_perm())
+ doc = frappe.get_doc("Blog Post", "_test-blog-post-1")
+ self.assertFalse(doc.has_permission("read"))
def test_not_allowed_to_remove_self(self):
self.add_restriction_to_user2()
@@ -151,22 +132,21 @@ class TestBlogPost(unittest.TestCase):
self.add_restricted_on_blogger()
frappe.set_user("test2@example.com")
- bean = frappe.bean("Blog Post", "_test-blog-post-1")
- self.assertFalse(bean.has_read_perm())
+ doc = frappe.get_doc("Blog Post", "_test-blog-post-1")
+ self.assertFalse(doc.has_permission("read"))
frappe.set_user("test1@example.com")
add("test2@example.com", "Blog Post", "_test-blog-post-1")
frappe.set_user("test2@example.com")
- bean = frappe.bean("Blog Post", "_test-blog-post-1")
+ doc = frappe.get_doc("Blog Post", "_test-blog-post-1")
- self.assertTrue(bean.has_read_perm())
+ self.assertTrue(doc.has_permission("read"))
def test_set_only_once(self):
- blog_post = frappe.get_doctype("Blog Post")
+ blog_post = frappe.get_meta("Blog Post")
blog_post.get_field("title").set_only_once = 1
- bean = frappe.bean("Blog Post", "_test-blog-post-1")
- bean.doc.title = "New"
- self.assertRaises(frappe.CannotChangeConstantError, bean.save)
- blog_post.get_field("title").set_only_once = 0
-
+ doc = frappe.get_doc("Blog Post", "_test-blog-post-1")
+ doc.title = "New"
+ self.assertRaises(frappe.CannotChangeConstantError, doc.save)
+ blog_post.get_field("title").set_only_once = 0
\ No newline at end of file
diff --git a/frappe/website/doctype/blog_post/test_records.json b/frappe/website/doctype/blog_post/test_records.json
new file mode 100644
index 0000000000..72282adcb2
--- /dev/null
+++ b/frappe/website/doctype/blog_post/test_records.json
@@ -0,0 +1,18 @@
+[
+ {
+ "blog_category": "_Test Blog Category",
+ "blog_intro": "Test Blog Intro",
+ "blogger": "_Test Blogger",
+ "content": "Test Blog Content",
+ "doctype": "Blog Post",
+ "title": "_Test Blog Post"
+ },
+ {
+ "blog_category": "_Test Blog Category 1",
+ "blog_intro": "Test Blog Intro",
+ "blogger": "_Test Blogger",
+ "content": "Test Blog Content",
+ "doctype": "Blog Post",
+ "title": "_Test Blog Post 1"
+ }
+]
\ No newline at end of file
diff --git a/frappe/website/doctype/blog_settings/blog_settings.json b/frappe/website/doctype/blog_settings/blog_settings.json
new file mode 100644
index 0000000000..963791679d
--- /dev/null
+++ b/frappe/website/doctype/blog_settings/blog_settings.json
@@ -0,0 +1,45 @@
+{
+ "creation": "2013-03-11 17:48:16.000000",
+ "description": "Blog Settings",
+ "docstatus": 0,
+ "doctype": "DocType",
+ "fields": [
+ {
+ "fieldname": "blog_title",
+ "fieldtype": "Data",
+ "label": "Blog Title",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "blog_introduction",
+ "fieldtype": "Small Text",
+ "label": "Blog Introduction",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "writers_introduction",
+ "fieldtype": "Small Text",
+ "label": "Writers Introduction",
+ "permlevel": 0
+ }
+ ],
+ "icon": "icon-cog",
+ "idx": 1,
+ "issingle": 1,
+ "modified": "2013-12-20 19:22:56.000000",
+ "modified_by": "Administrator",
+ "module": "Website",
+ "name": "Blog Settings",
+ "owner": "Administrator",
+ "permissions": [
+ {
+ "create": 1,
+ "email": 1,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "role": "Website Manager",
+ "write": 1
+ }
+ ]
+}
\ No newline at end of file
diff --git a/frappe/website/doctype/blog_settings/blog_settings.py b/frappe/website/doctype/blog_settings/blog_settings.py
index 2c03816c3c..19a2525ad8 100644
--- a/frappe/website/doctype/blog_settings/blog_settings.py
+++ b/frappe/website/doctype/blog_settings/blog_settings.py
@@ -6,9 +6,9 @@
from __future__ import unicode_literals
import frappe
-class DocType:
- def __init__(self, d, dl):
- self.doc, self.doclist = d, dl
+from frappe.model.document import Document
+
+class BlogSettings(Document):
def on_update(self):
from frappe.website.render import clear_cache
diff --git a/frappe/website/doctype/blog_settings/blog_settings.txt b/frappe/website/doctype/blog_settings/blog_settings.txt
deleted file mode 100644
index 8581e7982d..0000000000
--- a/frappe/website/doctype/blog_settings/blog_settings.txt
+++ /dev/null
@@ -1,64 +0,0 @@
-[
- {
- "creation": "2013-03-11 17:48:16",
- "docstatus": 0,
- "modified": "2013-12-20 19:22:56",
- "modified_by": "Administrator",
- "owner": "Administrator"
- },
- {
- "description": "Blog Settings",
- "doctype": "DocType",
- "icon": "icon-cog",
- "issingle": 1,
- "module": "Website",
- "name": "__common__"
- },
- {
- "doctype": "DocField",
- "name": "__common__",
- "parent": "Blog Settings",
- "parentfield": "fields",
- "parenttype": "DocType",
- "permlevel": 0
- },
- {
- "create": 1,
- "doctype": "DocPerm",
- "email": 1,
- "name": "__common__",
- "parent": "Blog Settings",
- "parentfield": "permissions",
- "parenttype": "DocType",
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "role": "Website Manager",
- "write": 1
- },
- {
- "doctype": "DocType",
- "name": "Blog Settings"
- },
- {
- "doctype": "DocField",
- "fieldname": "blog_title",
- "fieldtype": "Data",
- "label": "Blog Title"
- },
- {
- "doctype": "DocField",
- "fieldname": "blog_introduction",
- "fieldtype": "Small Text",
- "label": "Blog Introduction"
- },
- {
- "doctype": "DocField",
- "fieldname": "writers_introduction",
- "fieldtype": "Small Text",
- "label": "Writers Introduction"
- },
- {
- "doctype": "DocPerm"
- }
-]
\ No newline at end of file
diff --git a/frappe/website/doctype/blogger/blogger.json b/frappe/website/doctype/blogger/blogger.json
new file mode 100644
index 0000000000..1cec8d7bd5
--- /dev/null
+++ b/frappe/website/doctype/blogger/blogger.json
@@ -0,0 +1,89 @@
+{
+ "allow_attach": 1,
+ "allow_import": 1,
+ "autoname": "field:short_name",
+ "creation": "2013-03-25 16:00:51.000000",
+ "description": "User ID of a Blogger",
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "Master",
+ "fields": [
+ {
+ "fieldname": "disabled",
+ "fieldtype": "Check",
+ "label": "Disabled",
+ "permlevel": 0
+ },
+ {
+ "description": "Will be used in url (usually first name).",
+ "fieldname": "short_name",
+ "fieldtype": "Data",
+ "label": "Short Name",
+ "permlevel": 0,
+ "reqd": 1
+ },
+ {
+ "fieldname": "full_name",
+ "fieldtype": "Data",
+ "in_list_view": 1,
+ "label": "Full Name",
+ "permlevel": 0,
+ "reqd": 1
+ },
+ {
+ "fieldname": "user",
+ "fieldtype": "Link",
+ "label": "User",
+ "options": "User",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "bio",
+ "fieldtype": "Small Text",
+ "label": "Bio",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "avatar",
+ "fieldtype": "Select",
+ "label": "Avatar",
+ "options": "attach_files:",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "posts",
+ "fieldtype": "Int",
+ "in_list_view": 1,
+ "label": "Posts",
+ "permlevel": 0,
+ "read_only": 1
+ }
+ ],
+ "icon": "icon-user",
+ "idx": 1,
+ "max_attachments": 1,
+ "modified": "2013-12-20 19:23:58.000000",
+ "modified_by": "Administrator",
+ "module": "Website",
+ "name": "Blogger",
+ "owner": "Administrator",
+ "permissions": [
+ {
+ "create": 1,
+ "email": 1,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "role": "Website Manager",
+ "write": 1
+ },
+ {
+ "email": 1,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "role": "Blogger",
+ "write": 1
+ }
+ ]
+}
\ No newline at end of file
diff --git a/frappe/website/doctype/blogger/blogger.py b/frappe/website/doctype/blogger/blogger.py
index 3b71838336..4acc91408c 100644
--- a/frappe/website/doctype/blogger/blogger.py
+++ b/frappe/website/doctype/blogger/blogger.py
@@ -7,9 +7,9 @@ from __future__ import unicode_literals
import frappe
from frappe import _
-class DocType:
- def __init__(self, d, dl):
- self.doc, self.doclist = d, dl
+from frappe.model.document import Document
+
+class Blogger(Document):
def on_update(self):
"if user is set, then update all older blogs"
@@ -17,9 +17,9 @@ class DocType:
from frappe.website.doctype.blog_post.blog_post import clear_blog_cache
clear_blog_cache()
- if self.doc.user:
+ if self.user:
for blog in frappe.db.sql_list("""select name from `tabBlog Post` where owner=%s
- and ifnull(blogger,'')=''""", self.doc.user):
- b = frappe.bean("Blog Post", blog)
- b.doc.blogger = self.doc.name
+ and ifnull(blogger,'')=''""", self.user):
+ b = frappe.get_doc("Blog Post", blog)
+ b.blogger = self.name
b.save()
\ No newline at end of file
diff --git a/frappe/website/doctype/blogger/blogger.txt b/frappe/website/doctype/blogger/blogger.txt
deleted file mode 100644
index 3d7f343ea2..0000000000
--- a/frappe/website/doctype/blogger/blogger.txt
+++ /dev/null
@@ -1,104 +0,0 @@
-[
- {
- "creation": "2013-03-25 16:00:51",
- "docstatus": 0,
- "modified": "2013-12-20 19:23:58",
- "modified_by": "Administrator",
- "owner": "Administrator"
- },
- {
- "allow_attach": 1,
- "allow_import": 1,
- "autoname": "field:short_name",
- "description": "User ID of a Blogger",
- "doctype": "DocType",
- "document_type": "Master",
- "icon": "icon-user",
- "max_attachments": 1,
- "module": "Website",
- "name": "__common__"
- },
- {
- "doctype": "DocField",
- "name": "__common__",
- "parent": "Blogger",
- "parentfield": "fields",
- "parenttype": "DocType",
- "permlevel": 0
- },
- {
- "doctype": "DocPerm",
- "email": 1,
- "name": "__common__",
- "parent": "Blogger",
- "parentfield": "permissions",
- "parenttype": "DocType",
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "write": 1
- },
- {
- "doctype": "DocType",
- "name": "Blogger"
- },
- {
- "doctype": "DocField",
- "fieldname": "disabled",
- "fieldtype": "Check",
- "label": "Disabled"
- },
- {
- "description": "Will be used in url (usually first name).",
- "doctype": "DocField",
- "fieldname": "short_name",
- "fieldtype": "Data",
- "label": "Short Name",
- "reqd": 1
- },
- {
- "doctype": "DocField",
- "fieldname": "full_name",
- "fieldtype": "Data",
- "in_list_view": 1,
- "label": "Full Name",
- "reqd": 1
- },
- {
- "doctype": "DocField",
- "fieldname": "user",
- "fieldtype": "Link",
- "label": "User",
- "options": "User"
- },
- {
- "doctype": "DocField",
- "fieldname": "bio",
- "fieldtype": "Small Text",
- "label": "Bio"
- },
- {
- "doctype": "DocField",
- "fieldname": "avatar",
- "fieldtype": "Select",
- "label": "Avatar",
- "options": "attach_files:"
- },
- {
- "doctype": "DocField",
- "fieldname": "posts",
- "fieldtype": "Int",
- "in_list_view": 1,
- "label": "Posts",
- "read_only": 1
- },
- {
- "create": 1,
- "doctype": "DocPerm",
- "role": "Website Manager"
- },
- {
- "doctype": "DocPerm",
- "role": "Blogger"
- }
-]
\ No newline at end of file
diff --git a/frappe/website/doctype/blogger/test_blogger.py b/frappe/website/doctype/blogger/test_blogger.py
index 15b31b34c7..db7feb4970 100644
--- a/frappe/website/doctype/blogger/test_blogger.py
+++ b/frappe/website/doctype/blogger/test_blogger.py
@@ -1,16 +1,6 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt
-test_records = [
- [{
- "doctype": "Blogger",
- "short_name": "_Test Blogger",
- "full_name": "_Test Blogger"
- }],
- [{
- "doctype": "Blogger",
- "short_name": "_Test Blogger 1",
- "full_name": "_Test Blogger 1"
- }]
-
-]
\ No newline at end of file
+
+import frappe
+test_records = frappe.get_test_records('Blogger')
\ No newline at end of file
diff --git a/frappe/website/doctype/blogger/test_records.json b/frappe/website/doctype/blogger/test_records.json
new file mode 100644
index 0000000000..ecaaaa161e
--- /dev/null
+++ b/frappe/website/doctype/blogger/test_records.json
@@ -0,0 +1,12 @@
+[
+ {
+ "doctype": "Blogger",
+ "full_name": "_Test Blogger",
+ "short_name": "_Test Blogger"
+ },
+ {
+ "doctype": "Blogger",
+ "full_name": "_Test Blogger 1",
+ "short_name": "_Test Blogger 1"
+ }
+]
\ No newline at end of file
diff --git a/frappe/website/doctype/company_history/company_history.json b/frappe/website/doctype/company_history/company_history.json
new file mode 100644
index 0000000000..08cfe8eb9e
--- /dev/null
+++ b/frappe/website/doctype/company_history/company_history.json
@@ -0,0 +1,30 @@
+{
+ "creation": "2013-02-22 01:28:08.000000",
+ "docstatus": 0,
+ "doctype": "DocType",
+ "fields": [
+ {
+ "fieldname": "year",
+ "fieldtype": "Data",
+ "in_list_view": 1,
+ "label": "Year",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "highlight",
+ "fieldtype": "Text",
+ "in_list_view": 1,
+ "label": "Highlight",
+ "permlevel": 0,
+ "print_width": "300px",
+ "width": "300px"
+ }
+ ],
+ "idx": 1,
+ "istable": 1,
+ "modified": "2013-12-20 19:23:01.000000",
+ "modified_by": "Administrator",
+ "module": "Website",
+ "name": "Company History",
+ "owner": "Administrator"
+}
\ No newline at end of file
diff --git a/frappe/website/doctype/company_history/company_history.py b/frappe/website/doctype/company_history/company_history.py
index cb42e2eea2..83af48808c 100644
--- a/frappe/website/doctype/company_history/company_history.py
+++ b/frappe/website/doctype/company_history/company_history.py
@@ -6,6 +6,7 @@
from __future__ import unicode_literals
import frappe
-class DocType:
- def __init__(self, d, dl):
- self.doc, self.doclist = d, dl
\ No newline at end of file
+from frappe.model.document import Document
+
+class CompanyHistory(Document):
+ pass
\ No newline at end of file
diff --git a/frappe/website/doctype/company_history/company_history.txt b/frappe/website/doctype/company_history/company_history.txt
deleted file mode 100644
index e605049a48..0000000000
--- a/frappe/website/doctype/company_history/company_history.txt
+++ /dev/null
@@ -1,42 +0,0 @@
-[
- {
- "creation": "2013-02-22 01:28:08",
- "docstatus": 0,
- "modified": "2013-12-20 19:23:01",
- "modified_by": "Administrator",
- "owner": "Administrator"
- },
- {
- "doctype": "DocType",
- "istable": 1,
- "module": "Website",
- "name": "__common__"
- },
- {
- "doctype": "DocField",
- "in_list_view": 1,
- "name": "__common__",
- "parent": "Company History",
- "parentfield": "fields",
- "parenttype": "DocType",
- "permlevel": 0
- },
- {
- "doctype": "DocType",
- "name": "Company History"
- },
- {
- "doctype": "DocField",
- "fieldname": "year",
- "fieldtype": "Data",
- "label": "Year"
- },
- {
- "doctype": "DocField",
- "fieldname": "highlight",
- "fieldtype": "Text",
- "label": "Highlight",
- "print_width": "300px",
- "width": "300px"
- }
-]
\ No newline at end of file
diff --git a/frappe/website/doctype/contact_us_settings/contact_us_settings.json b/frappe/website/doctype/contact_us_settings/contact_us_settings.json
new file mode 100644
index 0000000000..1479112631
--- /dev/null
+++ b/frappe/website/doctype/contact_us_settings/contact_us_settings.json
@@ -0,0 +1,118 @@
+{
+ "creation": "2013-02-21 20:12:42.000000",
+ "description": "Settings for Contact Us Page",
+ "docstatus": 0,
+ "doctype": "DocType",
+ "fields": [
+ {
+ "fieldname": "help",
+ "fieldtype": "HTML",
+ "label": "Help",
+ "options": "
Link for Contact Page is \"/contact\"
",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "introduction_section",
+ "fieldtype": "Section Break",
+ "label": "Introduction",
+ "permlevel": 0
+ },
+ {
+ "description": "Send enquiries to this email address",
+ "fieldname": "forward_to_email",
+ "fieldtype": "Data",
+ "label": "Forward To Email Address",
+ "permlevel": 0
+ },
+ {
+ "description": "Default: \"Contact Us\"",
+ "fieldname": "heading",
+ "fieldtype": "Data",
+ "label": "Heading",
+ "permlevel": 0
+ },
+ {
+ "description": "Introductory information for the Contact Us Page",
+ "fieldname": "introduction",
+ "fieldtype": "Text Editor",
+ "label": "Introduction",
+ "permlevel": 0
+ },
+ {
+ "description": "Contact options, like \"Sales Query, Support Query\" etc each on a new line or separated by commas.",
+ "fieldname": "query_options",
+ "fieldtype": "Small Text",
+ "label": "Query Options",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "address",
+ "fieldtype": "Section Break",
+ "label": "Address",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "address_title",
+ "fieldtype": "Data",
+ "label": "Address Title",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "address_line1",
+ "fieldtype": "Data",
+ "label": "Address Line 1",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "address_line2",
+ "fieldtype": "Data",
+ "label": "Address Line 2",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "city",
+ "fieldtype": "Data",
+ "label": "City",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "state",
+ "fieldtype": "Data",
+ "label": "State",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "pincode",
+ "fieldtype": "Data",
+ "label": "Pincode",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "country",
+ "fieldtype": "Data",
+ "label": "Country",
+ "permlevel": 0
+ }
+ ],
+ "icon": "icon-cog",
+ "idx": 1,
+ "issingle": 1,
+ "modified": "2014-02-28 11:32:25.000000",
+ "modified_by": "Administrator",
+ "module": "Website",
+ "name": "Contact Us Settings",
+ "owner": "Administrator",
+ "permissions": [
+ {
+ "create": 1,
+ "email": 1,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 0,
+ "role": "Website Manager",
+ "submit": 0,
+ "write": 1
+ }
+ ]
+}
\ No newline at end of file
diff --git a/frappe/website/doctype/contact_us_settings/contact_us_settings.py b/frappe/website/doctype/contact_us_settings/contact_us_settings.py
index 12162c1799..c3185832ba 100644
--- a/frappe/website/doctype/contact_us_settings/contact_us_settings.py
+++ b/frappe/website/doctype/contact_us_settings/contact_us_settings.py
@@ -6,9 +6,9 @@
from __future__ import unicode_literals
import frappe
-class DocType:
- def __init__(self, d, dl):
- self.doc, self.doclist = d, dl
+from frappe.model.document import Document
+
+class ContactUsSettings(Document):
def on_update(self):
from frappe.website.render import clear_cache
diff --git a/frappe/website/doctype/contact_us_settings/contact_us_settings.txt b/frappe/website/doctype/contact_us_settings/contact_us_settings.txt
deleted file mode 100644
index cadce62a63..0000000000
--- a/frappe/website/doctype/contact_us_settings/contact_us_settings.txt
+++ /dev/null
@@ -1,137 +0,0 @@
-[
- {
- "creation": "2013-02-21 20:12:42",
- "docstatus": 0,
- "modified": "2014-02-28 11:32:25",
- "modified_by": "Administrator",
- "owner": "Administrator"
- },
- {
- "description": "Settings for Contact Us Page",
- "doctype": "DocType",
- "icon": "icon-cog",
- "issingle": 1,
- "module": "Website",
- "name": "__common__"
- },
- {
- "doctype": "DocField",
- "name": "__common__",
- "parent": "Contact Us Settings",
- "parentfield": "fields",
- "parenttype": "DocType",
- "permlevel": 0
- },
- {
- "create": 1,
- "doctype": "DocPerm",
- "email": 1,
- "name": "__common__",
- "parent": "Contact Us Settings",
- "parentfield": "permissions",
- "parenttype": "DocType",
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 0,
- "role": "Website Manager",
- "submit": 0,
- "write": 1
- },
- {
- "doctype": "DocType",
- "name": "Contact Us Settings"
- },
- {
- "doctype": "DocField",
- "fieldname": "help",
- "fieldtype": "HTML",
- "label": "Help",
- "options": "
Link for Contact Page is \"/contact\"
"
- },
- {
- "doctype": "DocField",
- "fieldname": "introduction_section",
- "fieldtype": "Section Break",
- "label": "Introduction"
- },
- {
- "description": "Send enquiries to this email address",
- "doctype": "DocField",
- "fieldname": "forward_to_email",
- "fieldtype": "Data",
- "label": "Forward To Email Address"
- },
- {
- "description": "Default: \"Contact Us\"",
- "doctype": "DocField",
- "fieldname": "heading",
- "fieldtype": "Data",
- "label": "Heading"
- },
- {
- "description": "Introductory information for the Contact Us Page",
- "doctype": "DocField",
- "fieldname": "introduction",
- "fieldtype": "Text Editor",
- "label": "Introduction"
- },
- {
- "description": "Contact options, like \"Sales Query, Support Query\" etc each on a new line or separated by commas.",
- "doctype": "DocField",
- "fieldname": "query_options",
- "fieldtype": "Small Text",
- "label": "Query Options"
- },
- {
- "doctype": "DocField",
- "fieldname": "address",
- "fieldtype": "Section Break",
- "label": "Address"
- },
- {
- "doctype": "DocField",
- "fieldname": "address_title",
- "fieldtype": "Data",
- "label": "Address Title"
- },
- {
- "doctype": "DocField",
- "fieldname": "address_line1",
- "fieldtype": "Data",
- "label": "Address Line 1"
- },
- {
- "doctype": "DocField",
- "fieldname": "address_line2",
- "fieldtype": "Data",
- "label": "Address Line 2"
- },
- {
- "doctype": "DocField",
- "fieldname": "city",
- "fieldtype": "Data",
- "label": "City"
- },
- {
- "doctype": "DocField",
- "fieldname": "state",
- "fieldtype": "Data",
- "label": "State"
- },
- {
- "doctype": "DocField",
- "fieldname": "pincode",
- "fieldtype": "Data",
- "label": "Pincode"
- },
- {
- "doctype": "DocField",
- "fieldname": "country",
- "fieldtype": "Data",
- "label": "Country"
- },
- {
- "doctype": "DocPerm"
- }
-]
\ No newline at end of file
diff --git a/frappe/website/doctype/post/post.json b/frappe/website/doctype/post/post.json
new file mode 100644
index 0000000000..ffbc54ecf3
--- /dev/null
+++ b/frappe/website/doctype/post/post.json
@@ -0,0 +1,128 @@
+{
+ "autoname": "P.#######",
+ "creation": "2014-01-07 14:00:04.000000",
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "Transaction",
+ "fields": [
+ {
+ "fieldname": "title",
+ "fieldtype": "Data",
+ "label": "Title",
+ "permlevel": 0,
+ "reqd": 0
+ },
+ {
+ "fieldname": "content",
+ "fieldtype": "Text",
+ "in_list_view": 1,
+ "label": "Content",
+ "permlevel": 0,
+ "reqd": 1
+ },
+ {
+ "fieldname": "picture_url",
+ "fieldtype": "Attach",
+ "label": "Picture URL",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "website_group",
+ "fieldtype": "Link",
+ "in_list_view": 1,
+ "label": "Website Group",
+ "options": "Website Group",
+ "permlevel": 0,
+ "reqd": 1,
+ "search_index": 1
+ },
+ {
+ "fieldname": "is_event",
+ "fieldtype": "Check",
+ "label": "Is Event",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "event_datetime",
+ "fieldtype": "Datetime",
+ "label": "Event Datetime",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "is_task",
+ "fieldtype": "Check",
+ "label": "Is Task",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "assigned_to",
+ "fieldtype": "Link",
+ "label": "Assigned To",
+ "options": "User",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "assigned_to_fullname",
+ "fieldtype": "Data",
+ "label": "Assigned To Fullname",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "status",
+ "fieldtype": "Select",
+ "label": "Status",
+ "options": "\nOpen\nClosed",
+ "permlevel": 0,
+ "reqd": 0
+ },
+ {
+ "fieldname": "parent_post",
+ "fieldtype": "Link",
+ "in_list_view": 1,
+ "label": "Parent Post",
+ "options": "Post",
+ "permlevel": 0,
+ "search_index": 1
+ },
+ {
+ "fieldname": "unsubscribe",
+ "fieldtype": "Check",
+ "label": "Unsubscribe",
+ "permlevel": 0
+ },
+ {
+ "default": "0",
+ "fieldname": "upvotes",
+ "fieldtype": "Int",
+ "label": "Upvotes",
+ "permlevel": 0
+ },
+ {
+ "default": "0",
+ "fieldname": "replies",
+ "fieldtype": "Int",
+ "label": "Replies",
+ "permlevel": 0
+ }
+ ],
+ "icon": "icon-comment",
+ "idx": 1,
+ "modified": "2014-03-03 14:53:19.000000",
+ "modified_by": "Administrator",
+ "module": "Website",
+ "name": "Post",
+ "owner": "Administrator",
+ "permissions": [
+ {
+ "cancel": 0,
+ "create": 1,
+ "delete": 1,
+ "export": 1,
+ "permlevel": 0,
+ "read": 1,
+ "report": 1,
+ "role": "System Manager",
+ "write": 1
+ }
+ ]
+}
\ No newline at end of file
diff --git a/frappe/website/doctype/post/post.py b/frappe/website/doctype/post/post.py
index cc83b76e2a..c3e51e8324 100644
--- a/frappe/website/doctype/post/post.py
+++ b/frappe/website/doctype/post/post.py
@@ -10,56 +10,56 @@ from frappe.utils import get_fullname
from frappe.utils.email_lib.bulk import send
from frappe.utils.email_lib import sendmail
-class DocType:
- def __init__(self, d, dl):
- self.doc, self.doclist = d, dl
+from frappe.model.document import Document
+
+class Post(Document):
def validate(self):
- if not self.doc.parent_post and not self.doc.title:
+ if not self.parent_post and not self.title:
frappe.throw("Please enter title!")
- self.assigned_to = frappe.db.get_value(self.doc.doctype, self.doc.name, "assigned_to")
- if self.doc.is_task:
- if not self.doc.status:
- self.doc.status = "Open"
- if self.doc.assigned_to:
- if not self.doc.assigned_to_fullname:
- self.doc.assigned_to_fullname = get_fullname(self.doc.assigned_to)
+ self.assigned_to = frappe.db.get_value(self.doctype, self.name, "assigned_to")
+ if self.is_task:
+ if not self.status:
+ self.status = "Open"
+ if self.assigned_to:
+ if not self.assigned_to_fullname:
+ self.assigned_to_fullname = get_fullname(self.assigned_to)
else:
- self.doc.assigned_to_fullname = None
+ self.assigned_to_fullname = None
else:
- self.doc.assigned_to = self.doc.assigned_to_fullname = self.doc.status = None
+ self.assigned_to = self.assigned_to_fullname = self.status = None
- if self.doc.is_event:
- if not self.doc.event_datetime:
+ if self.is_event:
+ if not self.event_datetime:
frappe.throw("Please specify Event's Date and Time")
else:
- self.doc.event_datetime = None
+ self.event_datetime = None
def on_update(self):
from frappe.templates.website_group.post import clear_post_cache
from frappe.templates.generators.website_group import clear_cache
- clear_cache(website_group=self.doc.website_group)
- clear_post_cache(self.doc.parent_post or self.doc.name)
+ clear_cache(website_group=self.website_group)
+ clear_post_cache(self.parent_post or self.name)
- if self.doc.assigned_to and self.doc.assigned_to != self.assigned_to \
- and frappe.session.user != self.doc.assigned_to:
+ if self.assigned_to and self.assigned_to != self.assigned_to \
+ and frappe.session.user != self.assigned_to:
# send assignment email
- sendmail(recipients=[self.doc.assigned_to],
- subject="You have been assigned this Task by {}".format(get_fullname(self.doc.modified_by)),
- msg=self.get_reply_email_message(self.doc.name, get_fullname(self.doc.owner)))
+ sendmail(recipients=[self.assigned_to],
+ subject="You have been assigned this Task by {}".format(get_fullname(self.modified_by)),
+ msg=self.get_reply_email_message(self.name, get_fullname(self.owner)))
def send_email_on_reply(self):
- owner_fullname = get_fullname(self.doc.owner)
+ owner_fullname = get_fullname(self.owner)
- parent_post = frappe.bean("Post", self.doc.parent_post).doc
+ parent_post = frappe.get_doc("Post", self.parent_post)
- message = self.get_reply_email_message(self.doc.name, owner_fullname)
+ message = self.get_reply_email_message(self.name, owner_fullname)
# send email to the owner of the post, if he/she is different
- if parent_post.owner != self.doc.owner:
+ if parent_post.owner != self.owner:
send(recipients=[parent_post.owner],
subject="{someone} replied to your post".format(someone=owner_fullname),
message=message,
@@ -69,12 +69,12 @@ class DocType:
email_field='owner',
# for tracking sent status
- ref_doctype=self.doc.doctype, ref_docname=self.doc.name)
+ ref_doctype=self.doctype, ref_docname=self.name)
# send email to members who part of the conversation
participants = frappe.db.sql("""select owner, name from `tabPost`
where parent_post=%s and owner not in (%s, %s) order by creation asc""",
- (self.doc.parent_post, parent_post.owner, self.doc.owner), as_dict=True)
+ (self.parent_post, parent_post.owner, self.owner), as_dict=True)
send(recipients=[p.owner for p in participants],
subject="{someone} replied to a post by {other}".format(someone=owner_fullname,
@@ -86,13 +86,13 @@ class DocType:
email_field='owner',
# for tracking sent status
- ref_doctype=self.doc.doctype, ref_docname=self.doc.name)
+ ref_doctype=self.doctype, ref_docname=self.name)
def get_reply_email_message(self, post_name, owner_fullname=None):
- message = self.doc.content
- if self.doc.picture_url:
+ message = self.content
+ if self.picture_url:
message += """

"""\
- .format(url=self.doc.picture_url)
+ .format(url=self.picture_url)
message += "
By {fullname}
".format(fullname=owner_fullname)
message += "
Click here to view the post
".format(fullname=owner_fullname,
post_name=post_name)
diff --git a/frappe/website/doctype/post/post.txt b/frappe/website/doctype/post/post.txt
deleted file mode 100644
index a9970af463..0000000000
--- a/frappe/website/doctype/post/post.txt
+++ /dev/null
@@ -1,147 +0,0 @@
-[
- {
- "creation": "2014-01-07 14:00:04",
- "docstatus": 0,
- "modified": "2014-03-03 14:53:19",
- "modified_by": "Administrator",
- "owner": "Administrator"
- },
- {
- "autoname": "P.#######",
- "doctype": "DocType",
- "document_type": "Transaction",
- "icon": "icon-comment",
- "module": "Website",
- "name": "__common__"
- },
- {
- "doctype": "DocField",
- "name": "__common__",
- "parent": "Post",
- "parentfield": "fields",
- "parenttype": "DocType",
- "permlevel": 0
- },
- {
- "cancel": 0,
- "create": 1,
- "delete": 1,
- "doctype": "DocPerm",
- "export": 1,
- "name": "__common__",
- "parent": "Post",
- "parentfield": "permissions",
- "parenttype": "DocType",
- "permlevel": 0,
- "read": 1,
- "report": 1,
- "role": "System Manager",
- "write": 1
- },
- {
- "doctype": "DocType",
- "name": "Post"
- },
- {
- "doctype": "DocField",
- "fieldname": "title",
- "fieldtype": "Data",
- "label": "Title",
- "reqd": 0
- },
- {
- "doctype": "DocField",
- "fieldname": "content",
- "fieldtype": "Text",
- "in_list_view": 1,
- "label": "Content",
- "reqd": 1
- },
- {
- "doctype": "DocField",
- "fieldname": "picture_url",
- "fieldtype": "Attach",
- "label": "Picture URL"
- },
- {
- "doctype": "DocField",
- "fieldname": "website_group",
- "fieldtype": "Link",
- "in_list_view": 1,
- "label": "Website Group",
- "options": "Website Group",
- "reqd": 1,
- "search_index": 1
- },
- {
- "doctype": "DocField",
- "fieldname": "is_event",
- "fieldtype": "Check",
- "label": "Is Event"
- },
- {
- "doctype": "DocField",
- "fieldname": "event_datetime",
- "fieldtype": "Datetime",
- "label": "Event Datetime"
- },
- {
- "doctype": "DocField",
- "fieldname": "is_task",
- "fieldtype": "Check",
- "label": "Is Task"
- },
- {
- "doctype": "DocField",
- "fieldname": "assigned_to",
- "fieldtype": "Link",
- "label": "Assigned To",
- "options": "User"
- },
- {
- "doctype": "DocField",
- "fieldname": "assigned_to_fullname",
- "fieldtype": "Data",
- "label": "Assigned To Fullname"
- },
- {
- "doctype": "DocField",
- "fieldname": "status",
- "fieldtype": "Select",
- "label": "Status",
- "options": "\nOpen\nClosed",
- "reqd": 0
- },
- {
- "doctype": "DocField",
- "fieldname": "parent_post",
- "fieldtype": "Link",
- "in_list_view": 1,
- "label": "Parent Post",
- "options": "Post",
- "search_index": 1
- },
- {
- "doctype": "DocField",
- "fieldname": "unsubscribe",
- "fieldtype": "Check",
- "label": "Unsubscribe"
- },
- {
- "default": "0",
- "doctype": "DocField",
- "fieldname": "upvotes",
- "fieldtype": "Int",
- "label": "Upvotes"
- },
- {
- "default": "0",
- "doctype": "DocField",
- "fieldname": "replies",
- "fieldtype": "Int",
- "label": "Replies"
- },
- {
- "doctype": "DocPerm"
- }
-]
\ No newline at end of file
diff --git a/frappe/website/doctype/style_settings/style_settings.json b/frappe/website/doctype/style_settings/style_settings.json
new file mode 100644
index 0000000000..9b08275502
--- /dev/null
+++ b/frappe/website/doctype/style_settings/style_settings.json
@@ -0,0 +1,187 @@
+{
+ "allow_attach": 1,
+ "creation": "2013-03-25 16:01:33.000000",
+ "description": "Set your background color, font and image (tiled)",
+ "docstatus": 0,
+ "doctype": "DocType",
+ "fields": [
+ {
+ "fieldname": "color",
+ "fieldtype": "Section Break",
+ "label": "Color",
+ "permlevel": 0
+ },
+ {
+ "description": "If image is selected, color will be ignored (attach first)",
+ "fieldname": "background_image",
+ "fieldtype": "Select",
+ "label": "Background Image",
+ "options": "attach_files:",
+ "permlevel": 0
+ },
+ {
+ "description": "Solid background color (default light gray)",
+ "fieldname": "background_color",
+ "fieldtype": "Data",
+ "label": "Background Color",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "page_background",
+ "fieldtype": "Data",
+ "label": "Page Background",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "page_border",
+ "fieldtype": "Check",
+ "label": "Page Border",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "page_headings",
+ "fieldtype": "Data",
+ "label": "Page Headings",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "page_text",
+ "fieldtype": "Data",
+ "label": "Page Text",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "page_links",
+ "fieldtype": "Data",
+ "label": "Page Links",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "cb0",
+ "fieldtype": "Column Break",
+ "label": "Top Bar",
+ "permlevel": 0,
+ "print_width": "50%",
+ "width": "50%"
+ },
+ {
+ "fieldname": "top_bar_background",
+ "fieldtype": "Data",
+ "label": "Top Bar Background",
+ "permlevel": 0
+ },
+ {
+ "description": "000 is black, fff is white",
+ "fieldname": "top_bar_foreground",
+ "fieldtype": "Data",
+ "label": "Top Bar Text",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "fonts",
+ "fieldtype": "Section Break",
+ "label": "Fonts",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "heading_font",
+ "fieldtype": "Select",
+ "label": "Font (Heading)",
+ "options": "\nHelvetica Neue\nLucida Grande\nVerdana\nArial\nGeorgia\nTahoma\nLato\nOpen Sans",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "font",
+ "fieldtype": "Select",
+ "label": "Font (Text)",
+ "options": "\nHelvetica Neue\nLucida Grande\nVerdana\nArial\nGeorgia\nTahoma",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "font_size",
+ "fieldtype": "Select",
+ "label": "Font Size (Text)",
+ "options": "\n12px\n13px\n14px\n15px\n16px\n17px\n18px",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "heading_text_as",
+ "fieldtype": "Select",
+ "label": "Heading Text As",
+ "options": "\nUPPERCASE\nTitle Case\nlowercase",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "column_break_13",
+ "fieldtype": "Column Break",
+ "permlevel": 0
+ },
+ {
+ "description": "Add the name of
Google Web Font e.g. \"Open Sans\"",
+ "fieldname": "google_web_font_for_heading",
+ "fieldtype": "Data",
+ "label": "Google Web Font (Heading)",
+ "permlevel": 0
+ },
+ {
+ "description": "Add the name of
Google Web Font e.g. \"Open Sans\"",
+ "fieldname": "google_web_font_for_text",
+ "fieldtype": "Data",
+ "label": "Google Web Font (Text)",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "css",
+ "fieldtype": "Section Break",
+ "label": "CSS",
+ "permlevel": 0
+ },
+ {
+ "description": "add your own CSS (careful!)",
+ "fieldname": "add_css",
+ "fieldtype": "Code",
+ "label": "Add CSS",
+ "permlevel": 0
+ },
+ {
+ "description": "Auto generated",
+ "fieldname": "custom_css",
+ "fieldtype": "Code",
+ "label": "Custom CSS",
+ "permlevel": 0,
+ "read_only": 1
+ }
+ ],
+ "icon": "icon-cog",
+ "idx": 1,
+ "issingle": 1,
+ "max_attachments": 1,
+ "modified": "2013-12-20 19:22:48.000000",
+ "modified_by": "Administrator",
+ "module": "Website",
+ "name": "Style Settings",
+ "owner": "Administrator",
+ "permissions": [
+ {
+ "create": 1,
+ "email": 1,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 0,
+ "role": "Website Manager",
+ "submit": 0,
+ "write": 1
+ },
+ {
+ "amend": 0,
+ "cancel": 0,
+ "create": 0,
+ "permlevel": 1,
+ "read": 1,
+ "report": 0,
+ "role": "Website Manager",
+ "submit": 0
+ }
+ ]
+}
\ No newline at end of file
diff --git a/frappe/website/doctype/style_settings/style_settings.py b/frappe/website/doctype/style_settings/style_settings.py
index c66e4779d0..8eeff8e484 100644
--- a/frappe/website/doctype/style_settings/style_settings.py
+++ b/frappe/website/doctype/style_settings/style_settings.py
@@ -7,22 +7,22 @@ import frappe
from frappe.utils import cint, cstr
from frappe import _
-class DocType:
- def __init__(self, d, dl):
- self.doc, self.doclist = d, dl
+from frappe.model.document import Document
+
+class StyleSettings(Document):
def validate(self):
"""make custom css"""
self.validate_colors()
def validate_colors(self):
- if (self.doc.page_background or self.doc.page_text) and \
- self.doc.page_background==self.doc.page_text:
+ if (self.page_background or self.page_text) and \
+ self.page_background==self.page_text:
frappe.msgprint(_("Page text and background is same color. Please change."),
raise_exception=1)
- if (self.doc.top_bar_background or self.doc.top_bar_foreground) and \
- self.doc.top_bar_background==self.doc.top_bar_foreground:
+ if (self.top_bar_background or self.top_bar_foreground) and \
+ self.top_bar_background==self.top_bar_foreground:
frappe.msgprint(_("Top Bar text and background is same color. Please change."),
raise_exception=1)
diff --git a/frappe/website/doctype/style_settings/style_settings.txt b/frappe/website/doctype/style_settings/style_settings.txt
deleted file mode 100644
index 3582672e71..0000000000
--- a/frappe/website/doctype/style_settings/style_settings.txt
+++ /dev/null
@@ -1,203 +0,0 @@
-[
- {
- "creation": "2013-03-25 16:01:33",
- "docstatus": 0,
- "modified": "2013-12-20 19:22:48",
- "modified_by": "Administrator",
- "owner": "Administrator"
- },
- {
- "allow_attach": 1,
- "description": "Set your background color, font and image (tiled)",
- "doctype": "DocType",
- "icon": "icon-cog",
- "issingle": 1,
- "max_attachments": 1,
- "module": "Website",
- "name": "__common__"
- },
- {
- "doctype": "DocField",
- "name": "__common__",
- "parent": "Style Settings",
- "parentfield": "fields",
- "parenttype": "DocType",
- "permlevel": 0
- },
- {
- "doctype": "DocPerm",
- "name": "__common__",
- "parent": "Style Settings",
- "parentfield": "permissions",
- "parenttype": "DocType",
- "read": 1,
- "report": 0,
- "role": "Website Manager",
- "submit": 0
- },
- {
- "doctype": "DocType",
- "name": "Style Settings"
- },
- {
- "doctype": "DocField",
- "fieldname": "color",
- "fieldtype": "Section Break",
- "label": "Color"
- },
- {
- "description": "If image is selected, color will be ignored (attach first)",
- "doctype": "DocField",
- "fieldname": "background_image",
- "fieldtype": "Select",
- "label": "Background Image",
- "options": "attach_files:"
- },
- {
- "description": "Solid background color (default light gray)",
- "doctype": "DocField",
- "fieldname": "background_color",
- "fieldtype": "Data",
- "label": "Background Color"
- },
- {
- "doctype": "DocField",
- "fieldname": "page_background",
- "fieldtype": "Data",
- "label": "Page Background"
- },
- {
- "doctype": "DocField",
- "fieldname": "page_border",
- "fieldtype": "Check",
- "label": "Page Border"
- },
- {
- "doctype": "DocField",
- "fieldname": "page_headings",
- "fieldtype": "Data",
- "label": "Page Headings"
- },
- {
- "doctype": "DocField",
- "fieldname": "page_text",
- "fieldtype": "Data",
- "label": "Page Text"
- },
- {
- "doctype": "DocField",
- "fieldname": "page_links",
- "fieldtype": "Data",
- "label": "Page Links"
- },
- {
- "doctype": "DocField",
- "fieldname": "cb0",
- "fieldtype": "Column Break",
- "label": "Top Bar",
- "print_width": "50%",
- "width": "50%"
- },
- {
- "doctype": "DocField",
- "fieldname": "top_bar_background",
- "fieldtype": "Data",
- "label": "Top Bar Background"
- },
- {
- "description": "000 is black, fff is white",
- "doctype": "DocField",
- "fieldname": "top_bar_foreground",
- "fieldtype": "Data",
- "label": "Top Bar Text"
- },
- {
- "doctype": "DocField",
- "fieldname": "fonts",
- "fieldtype": "Section Break",
- "label": "Fonts"
- },
- {
- "doctype": "DocField",
- "fieldname": "heading_font",
- "fieldtype": "Select",
- "label": "Font (Heading)",
- "options": "\nHelvetica Neue\nLucida Grande\nVerdana\nArial\nGeorgia\nTahoma\nLato\nOpen Sans"
- },
- {
- "doctype": "DocField",
- "fieldname": "font",
- "fieldtype": "Select",
- "label": "Font (Text)",
- "options": "\nHelvetica Neue\nLucida Grande\nVerdana\nArial\nGeorgia\nTahoma"
- },
- {
- "doctype": "DocField",
- "fieldname": "font_size",
- "fieldtype": "Select",
- "label": "Font Size (Text)",
- "options": "\n12px\n13px\n14px\n15px\n16px\n17px\n18px"
- },
- {
- "doctype": "DocField",
- "fieldname": "heading_text_as",
- "fieldtype": "Select",
- "label": "Heading Text As",
- "options": "\nUPPERCASE\nTitle Case\nlowercase"
- },
- {
- "doctype": "DocField",
- "fieldname": "column_break_13",
- "fieldtype": "Column Break"
- },
- {
- "description": "Add the name of
Google Web Font e.g. \"Open Sans\"",
- "doctype": "DocField",
- "fieldname": "google_web_font_for_heading",
- "fieldtype": "Data",
- "label": "Google Web Font (Heading)"
- },
- {
- "description": "Add the name of
Google Web Font e.g. \"Open Sans\"",
- "doctype": "DocField",
- "fieldname": "google_web_font_for_text",
- "fieldtype": "Data",
- "label": "Google Web Font (Text)"
- },
- {
- "doctype": "DocField",
- "fieldname": "css",
- "fieldtype": "Section Break",
- "label": "CSS"
- },
- {
- "description": "add your own CSS (careful!)",
- "doctype": "DocField",
- "fieldname": "add_css",
- "fieldtype": "Code",
- "label": "Add CSS"
- },
- {
- "description": "Auto generated",
- "doctype": "DocField",
- "fieldname": "custom_css",
- "fieldtype": "Code",
- "label": "Custom CSS",
- "read_only": 1
- },
- {
- "create": 1,
- "doctype": "DocPerm",
- "email": 1,
- "permlevel": 0,
- "print": 1,
- "write": 1
- },
- {
- "amend": 0,
- "cancel": 0,
- "create": 0,
- "doctype": "DocPerm",
- "permlevel": 1
- }
-]
\ No newline at end of file
diff --git a/frappe/website/doctype/top_bar_item/top_bar_item.json b/frappe/website/doctype/top_bar_item/top_bar_item.json
new file mode 100644
index 0000000000..db960600bd
--- /dev/null
+++ b/frappe/website/doctype/top_bar_item/top_bar_item.json
@@ -0,0 +1,50 @@
+{
+ "creation": "2013-02-22 01:28:08.000000",
+ "docstatus": 0,
+ "doctype": "DocType",
+ "fields": [
+ {
+ "fieldname": "label",
+ "fieldtype": "Data",
+ "in_list_view": 1,
+ "label": "Label",
+ "permlevel": 0,
+ "print_width": "120px",
+ "width": "120px"
+ },
+ {
+ "description": "If you set this, this Item will come in a drop-down under the selected parent.",
+ "fieldname": "parent_label",
+ "fieldtype": "Select",
+ "in_list_view": 1,
+ "label": "Parent Label",
+ "permlevel": 0
+ },
+ {
+ "description": "Link to the page you want to open",
+ "fieldname": "url",
+ "fieldtype": "Data",
+ "in_list_view": 1,
+ "label": "URL",
+ "permlevel": 0,
+ "print_width": "200px",
+ "width": "200px"
+ },
+ {
+ "description": "Select target = \"_blank\" to open in a new page.",
+ "fieldname": "target",
+ "fieldtype": "Select",
+ "in_list_view": 1,
+ "label": "Target",
+ "options": "\ntarget = \"_blank\"",
+ "permlevel": 0
+ }
+ ],
+ "idx": 1,
+ "istable": 1,
+ "modified": "2013-12-20 19:21:53.000000",
+ "modified_by": "Administrator",
+ "module": "Website",
+ "name": "Top Bar Item",
+ "owner": "Administrator"
+}
\ No newline at end of file
diff --git a/frappe/website/doctype/top_bar_item/top_bar_item.py b/frappe/website/doctype/top_bar_item/top_bar_item.py
index a48f49f2a7..5e8cd7c469 100644
--- a/frappe/website/doctype/top_bar_item/top_bar_item.py
+++ b/frappe/website/doctype/top_bar_item/top_bar_item.py
@@ -4,6 +4,7 @@
from __future__ import unicode_literals
import frappe
-class DocType:
- def __init__(self, d, dl):
- self.doc, self.doclist = d, dl
\ No newline at end of file
+from frappe.model.document import Document
+
+class TopBarItem(Document):
+ pass
\ No newline at end of file
diff --git a/frappe/website/doctype/top_bar_item/top_bar_item.txt b/frappe/website/doctype/top_bar_item/top_bar_item.txt
deleted file mode 100644
index e5ee3aeaca..0000000000
--- a/frappe/website/doctype/top_bar_item/top_bar_item.txt
+++ /dev/null
@@ -1,60 +0,0 @@
-[
- {
- "creation": "2013-02-22 01:28:08",
- "docstatus": 0,
- "modified": "2013-12-20 19:21:53",
- "modified_by": "Administrator",
- "owner": "Administrator"
- },
- {
- "doctype": "DocType",
- "istable": 1,
- "module": "Website",
- "name": "__common__"
- },
- {
- "doctype": "DocField",
- "in_list_view": 1,
- "name": "__common__",
- "parent": "Top Bar Item",
- "parentfield": "fields",
- "parenttype": "DocType",
- "permlevel": 0
- },
- {
- "doctype": "DocType",
- "name": "Top Bar Item"
- },
- {
- "doctype": "DocField",
- "fieldname": "label",
- "fieldtype": "Data",
- "label": "Label",
- "print_width": "120px",
- "width": "120px"
- },
- {
- "description": "If you set this, this Item will come in a drop-down under the selected parent.",
- "doctype": "DocField",
- "fieldname": "parent_label",
- "fieldtype": "Select",
- "label": "Parent Label"
- },
- {
- "description": "Link to the page you want to open",
- "doctype": "DocField",
- "fieldname": "url",
- "fieldtype": "Data",
- "label": "URL",
- "print_width": "200px",
- "width": "200px"
- },
- {
- "description": "Select target = \"_blank\" to open in a new page.",
- "doctype": "DocField",
- "fieldname": "target",
- "fieldtype": "Select",
- "label": "Target",
- "options": "\ntarget = \"_blank\""
- }
-]
\ No newline at end of file
diff --git a/frappe/website/doctype/user_vote/user_vote.json b/frappe/website/doctype/user_vote/user_vote.json
new file mode 100644
index 0000000000..31ab141701
--- /dev/null
+++ b/frappe/website/doctype/user_vote/user_vote.json
@@ -0,0 +1,43 @@
+{
+ "autoname": "_VOTE.#######",
+ "creation": "2014-01-17 16:26:21.000000",
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "Transaction",
+ "fields": [
+ {
+ "fieldname": "ref_doctype",
+ "fieldtype": "Link",
+ "label": "Ref DocType",
+ "options": "DocType",
+ "permlevel": 0,
+ "search_index": 0
+ },
+ {
+ "fieldname": "ref_name",
+ "fieldtype": "Data",
+ "label": "Ref Name",
+ "permlevel": 0,
+ "search_index": 0
+ }
+ ],
+ "idx": 1,
+ "modified": "2014-01-21 15:45:30.000000",
+ "modified_by": "Administrator",
+ "module": "Website",
+ "name": "User Vote",
+ "owner": "Administrator",
+ "permissions": [
+ {
+ "cancel": 0,
+ "create": 1,
+ "delete": 1,
+ "export": 1,
+ "permlevel": 0,
+ "read": 1,
+ "report": 1,
+ "role": "System Manager",
+ "write": 1
+ }
+ ]
+}
\ No newline at end of file
diff --git a/frappe/website/doctype/user_vote/user_vote.py b/frappe/website/doctype/user_vote/user_vote.py
index 79b8334305..b0a333534e 100644
--- a/frappe/website/doctype/user_vote/user_vote.py
+++ b/frappe/website/doctype/user_vote/user_vote.py
@@ -5,15 +5,15 @@ from __future__ import unicode_literals
import frappe
from frappe.website.permissions import get_access
-class DocType:
- def __init__(self, d, dl):
- self.doc, self.doclist = d, dl
+from frappe.model.document import Document
+
+class UserVote(Document):
def validate(self):
# if new
- if self.doc.fields.get("__islocal"):
- if frappe.db.get_value("User Vote", {"ref_doctype": self.doc.ref_doctype,
- "ref_name": self.doc.ref_name, "owner": frappe.session.user}):
+ if self.get("__islocal"):
+ if frappe.db.get_value("User Vote", {"ref_doctype": self.ref_doctype,
+ "ref_name": self.ref_name, "owner": frappe.session.user}):
raise frappe.DuplicateEntryError
@@ -25,8 +25,8 @@ class DocType:
def update_ref_count(self, cnt=0):
count = frappe.db.sql("""select count(*) from `tabUser Vote` where ref_doctype=%s and ref_name=%s""",
- (self.doc.ref_doctype, self.doc.ref_name))[0][0]
- frappe.db.set_value(self.doc.ref_doctype, self.doc.ref_name, "upvotes", count + cnt)
+ (self.ref_doctype, self.ref_name))[0][0]
+ frappe.db.set_value(self.ref_doctype, self.ref_name, "upvotes", count + cnt)
def on_doctype_update():
frappe.db.add_index("User Vote", ["ref_doctype", "ref_name"])
@@ -42,7 +42,7 @@ def set_vote(ref_doctype, ref_name):
raise frappe.PermissionError
try:
- user_vote = frappe.bean({
+ user_vote = frappe.get_doc({
"doctype": "User Vote",
"ref_doctype": ref_doctype,
"ref_name": ref_name
diff --git a/frappe/website/doctype/user_vote/user_vote.txt b/frappe/website/doctype/user_vote/user_vote.txt
deleted file mode 100644
index 86bbc7bc02..0000000000
--- a/frappe/website/doctype/user_vote/user_vote.txt
+++ /dev/null
@@ -1,61 +0,0 @@
-[
- {
- "creation": "2014-01-17 16:26:21",
- "docstatus": 0,
- "modified": "2014-01-21 15:45:30",
- "modified_by": "Administrator",
- "owner": "Administrator"
- },
- {
- "autoname": "_VOTE.#######",
- "doctype": "DocType",
- "document_type": "Transaction",
- "module": "Website",
- "name": "__common__"
- },
- {
- "doctype": "DocField",
- "name": "__common__",
- "parent": "User Vote",
- "parentfield": "fields",
- "parenttype": "DocType",
- "permlevel": 0,
- "search_index": 0
- },
- {
- "cancel": 0,
- "create": 1,
- "delete": 1,
- "doctype": "DocPerm",
- "export": 1,
- "name": "__common__",
- "parent": "User Vote",
- "parentfield": "permissions",
- "parenttype": "DocType",
- "permlevel": 0,
- "read": 1,
- "report": 1,
- "role": "System Manager",
- "write": 1
- },
- {
- "doctype": "DocType",
- "name": "User Vote"
- },
- {
- "doctype": "DocField",
- "fieldname": "ref_doctype",
- "fieldtype": "Link",
- "label": "Ref DocType",
- "options": "DocType"
- },
- {
- "doctype": "DocField",
- "fieldname": "ref_name",
- "fieldtype": "Data",
- "label": "Ref Name"
- },
- {
- "doctype": "DocPerm"
- }
-]
\ No newline at end of file
diff --git a/frappe/website/doctype/web_page/test_records.json b/frappe/website/doctype/web_page/test_records.json
new file mode 100644
index 0000000000..dcbd51c6c8
--- /dev/null
+++ b/frappe/website/doctype/web_page/test_records.json
@@ -0,0 +1,35 @@
+[
+ {
+ "doctype": "Web Page",
+ "main_section": "Test Content 1",
+ "published": 1,
+ "title": "Test Web Page 1"
+ },
+ {
+ "doctype": "Web Page",
+ "main_section": "Test Content 2",
+ "parent_website_route": "test-web-page-1",
+ "published": 1,
+ "title": "Test Web Page 2"
+ },
+ {
+ "doctype": "Web Page",
+ "main_section": "Test Content 3",
+ "parent_website_route": "test-web-page-1",
+ "published": 1,
+ "title": "Test Web Page 3"
+ },
+ {
+ "doctype": "Web Page",
+ "main_section": "Test Content 4",
+ "published": 1,
+ "title": "Test Web Page 4"
+ },
+ {
+ "doctype": "Web Page",
+ "main_section": "Test Content 5",
+ "parent_website_route": "test-web-page-1",
+ "published": 1,
+ "title": "Test Web Page 5"
+ }
+]
\ No newline at end of file
diff --git a/frappe/website/doctype/web_page/test_web_page.py b/frappe/website/doctype/web_page/test_web_page.py
index aeec26a454..234255e6fa 100644
--- a/frappe/website/doctype/web_page/test_web_page.py
+++ b/frappe/website/doctype/web_page/test_web_page.py
@@ -2,41 +2,7 @@ from __future__ import unicode_literals
import unittest
import frappe
-test_records = [
- [{
- "doctype": "Web Page",
- "title": "Test Web Page 1",
- "main_section": "Test Content 1",
- "published": 1
- }],
- [{
- "doctype": "Web Page",
- "title": "Test Web Page 2",
- "main_section": "Test Content 2",
- "published": 1,
- "parent_website_route": "test-web-page-1"
- }],
- [{
- "doctype": "Web Page",
- "title": "Test Web Page 3",
- "main_section": "Test Content 3",
- "published": 1,
- "parent_website_route": "test-web-page-1"
- }],
- [{
- "doctype": "Web Page",
- "title": "Test Web Page 4",
- "main_section": "Test Content 4",
- "published": 1,
- }],
- [{
- "doctype": "Web Page",
- "title": "Test Web Page 5",
- "main_section": "Test Content 5",
- "published": 1,
- "parent_website_route": "test-web-page-1"
- }],
-]
+test_records = frappe.get_test_records('Web Page')
class TestWebPage(unittest.TestCase):
def test_check_sitemap(self):
@@ -60,15 +26,15 @@ class TestWebPage(unittest.TestCase):
{"ref_doctype":"Web Page", "docname": "test-web-page-5"}, 'idx'), 2)
def test_check_rename(self):
- web_page = frappe.bean("Web Page", "test-web-page-1")
- web_page.doc.parent_website_route = "test-web-page-4"
+ web_page = frappe.get_doc("Web Page", "test-web-page-1")
+ web_page.parent_website_route = "test-web-page-4"
web_page.save()
self.assertEquals(frappe.db.get_value("Website Route",
{"ref_doctype":"Web Page", "docname": "test-web-page-2"}),
"test-web-page-4/test-web-page-1/test-web-page-2")
- web_page.doc.parent_website_route = ""
+ web_page.parent_website_route = ""
web_page.save()
self.assertEquals(frappe.db.get_value("Website Route",
@@ -76,8 +42,8 @@ class TestWebPage(unittest.TestCase):
"test-web-page-1/test-web-page-2")
def test_check_move(self):
- web_page = frappe.bean("Web Page", "test-web-page-3")
- web_page.doc.parent_website_route = "test-web-page-4"
+ web_page = frappe.get_doc("Web Page", "test-web-page-3")
+ web_page.parent_website_route = "test-web-page-4"
web_page.save()
self.assertEquals(frappe.db.get_value("Website Route",
@@ -89,9 +55,6 @@ class TestWebPage(unittest.TestCase):
self.assertEquals(frappe.db.get_value("Website Route",
{"ref_doctype":"Web Page", "docname": "test-web-page-5"}, 'idx'), 1)
- web_page = frappe.bean("Web Page", "test-web-page-3")
- web_page.doc.parent_website_route = "test-web-page-1"
- web_page.save()
-
-
-
\ No newline at end of file
+ web_page = frappe.get_doc("Web Page", "test-web-page-3")
+ web_page.parent_website_route = "test-web-page-1"
+ web_page.save()
\ No newline at end of file
diff --git a/frappe/website/doctype/web_page/web_page.json b/frappe/website/doctype/web_page/web_page.json
new file mode 100644
index 0000000000..02f5dc7e84
--- /dev/null
+++ b/frappe/website/doctype/web_page/web_page.json
@@ -0,0 +1,166 @@
+{
+ "allow_attach": 1,
+ "creation": "2013-03-28 10:35:30.000000",
+ "description": "Page to show on the website\n",
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "Transaction",
+ "fields": [
+ {
+ "fieldname": "section_title",
+ "fieldtype": "Section Break",
+ "label": "Title",
+ "permlevel": 0
+ },
+ {
+ "description": "Title / headline of your page",
+ "fieldname": "title",
+ "fieldtype": "Data",
+ "label": "Title",
+ "permlevel": 0,
+ "reqd": 1
+ },
+ {
+ "description": "Page url name (auto-generated)",
+ "fieldname": "page_name",
+ "fieldtype": "Data",
+ "in_list_view": 1,
+ "label": "Page Name",
+ "permlevel": 0,
+ "read_only": 0
+ },
+ {
+ "fieldname": "parent_website_route",
+ "fieldtype": "Link",
+ "label": "Parent Website Page",
+ "options": "Website Route",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "published",
+ "fieldtype": "Check",
+ "label": "Published",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "cb1",
+ "fieldtype": "Column Break",
+ "permlevel": 0,
+ "width": "50%"
+ },
+ {
+ "description": "Description for page header.",
+ "fieldname": "description",
+ "fieldtype": "Small Text",
+ "label": "Description",
+ "permlevel": 0
+ },
+ {
+ "description": "Page content",
+ "fieldname": "sb1",
+ "fieldtype": "Section Break",
+ "label": "Content",
+ "permlevel": 0
+ },
+ {
+ "description": "Begin this page with a slideshow of images",
+ "fieldname": "slideshow",
+ "fieldtype": "Link",
+ "label": "Slideshow",
+ "options": "Website Slideshow",
+ "permlevel": 0
+ },
+ {
+ "description": "Content in markdown format that appears on the main side of your page",
+ "fieldname": "main_section",
+ "fieldtype": "Text Editor",
+ "label": "Main Section",
+ "permlevel": 0
+ },
+ {
+ "depends_on": "eval:!doc.__islocal",
+ "description": "Link to other pages in the side bar and next section",
+ "fieldname": "sb2",
+ "fieldtype": "Section Break",
+ "label": "More",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "enable_comments",
+ "fieldtype": "Check",
+ "label": "Enable Comments",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "text_align",
+ "fieldtype": "Select",
+ "label": "Text Align",
+ "options": "Left\nCenter\nRight",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "custom_javascript",
+ "fieldtype": "Section Break",
+ "label": "Custom Javascript",
+ "permlevel": 0
+ },
+ {
+ "description": "Add code as <script>",
+ "fieldname": "insert_code",
+ "fieldtype": "Check",
+ "label": "Insert Code",
+ "permlevel": 0
+ },
+ {
+ "depends_on": "insert_code",
+ "fieldname": "javascript",
+ "fieldtype": "Code",
+ "label": "Javascript",
+ "options": "Javascript",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "custom_css",
+ "fieldtype": "Section Break",
+ "label": "Custom CSS",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "insert_style",
+ "fieldtype": "Check",
+ "label": "Insert Style",
+ "permlevel": 0
+ },
+ {
+ "depends_on": "insert_style",
+ "fieldname": "css",
+ "fieldtype": "Code",
+ "label": "CSS",
+ "options": "CSS",
+ "permlevel": 0
+ }
+ ],
+ "icon": "icon-file-alt",
+ "idx": 1,
+ "max_attachments": 20,
+ "modified": "2014-02-28 14:24:14.000000",
+ "modified_by": "Administrator",
+ "module": "Website",
+ "name": "Web Page",
+ "owner": "Administrator",
+ "permissions": [
+ {
+ "cancel": 0,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Website Manager",
+ "submit": 0,
+ "write": 1
+ }
+ ]
+}
\ No newline at end of file
diff --git a/frappe/website/doctype/web_page/web_page.py b/frappe/website/doctype/web_page/web_page.py
index 550605e67a..7ec632b776 100644
--- a/frappe/website/doctype/web_page/web_page.py
+++ b/frappe/website/doctype/web_page/web_page.py
@@ -7,7 +7,5 @@ from frappe.website.website_generator import WebsiteGenerator
from frappe.website.utils import cleanup_page_name
from frappe.utils import cint
-class DocType(WebsiteGenerator):
- def __init__(self, doc, doclist):
- self.doc, self.doclist = doc, doclist
- self.save_versions = True
\ No newline at end of file
+class WebPage(WebsiteGenerator):
+ save_versions = True
diff --git a/frappe/website/doctype/web_page/web_page.txt b/frappe/website/doctype/web_page/web_page.txt
deleted file mode 100644
index 774e2ddccb..0000000000
--- a/frappe/website/doctype/web_page/web_page.txt
+++ /dev/null
@@ -1,185 +0,0 @@
-[
- {
- "creation": "2013-03-28 10:35:30",
- "docstatus": 0,
- "modified": "2014-02-28 14:24:14",
- "modified_by": "Administrator",
- "owner": "Administrator"
- },
- {
- "allow_attach": 1,
- "description": "Page to show on the website\n",
- "doctype": "DocType",
- "document_type": "Transaction",
- "icon": "icon-file-alt",
- "max_attachments": 20,
- "module": "Website",
- "name": "__common__"
- },
- {
- "doctype": "DocField",
- "name": "__common__",
- "parent": "Web Page",
- "parentfield": "fields",
- "parenttype": "DocType",
- "permlevel": 0
- },
- {
- "cancel": 0,
- "create": 1,
- "delete": 1,
- "doctype": "DocPerm",
- "email": 1,
- "name": "__common__",
- "parent": "Web Page",
- "parentfield": "permissions",
- "parenttype": "DocType",
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Website Manager",
- "submit": 0,
- "write": 1
- },
- {
- "doctype": "DocType",
- "name": "Web Page"
- },
- {
- "doctype": "DocField",
- "fieldname": "section_title",
- "fieldtype": "Section Break",
- "label": "Title"
- },
- {
- "description": "Title / headline of your page",
- "doctype": "DocField",
- "fieldname": "title",
- "fieldtype": "Data",
- "label": "Title",
- "reqd": 1
- },
- {
- "description": "Page url name (auto-generated)",
- "doctype": "DocField",
- "fieldname": "page_name",
- "fieldtype": "Data",
- "in_list_view": 1,
- "label": "Page Name",
- "read_only": 0
- },
- {
- "doctype": "DocField",
- "fieldname": "parent_website_route",
- "fieldtype": "Link",
- "label": "Parent Website Page",
- "options": "Website Route"
- },
- {
- "doctype": "DocField",
- "fieldname": "published",
- "fieldtype": "Check",
- "label": "Published"
- },
- {
- "doctype": "DocField",
- "fieldname": "cb1",
- "fieldtype": "Column Break",
- "width": "50%"
- },
- {
- "description": "Description for page header.",
- "doctype": "DocField",
- "fieldname": "description",
- "fieldtype": "Small Text",
- "label": "Description"
- },
- {
- "description": "Page content",
- "doctype": "DocField",
- "fieldname": "sb1",
- "fieldtype": "Section Break",
- "label": "Content"
- },
- {
- "description": "Begin this page with a slideshow of images",
- "doctype": "DocField",
- "fieldname": "slideshow",
- "fieldtype": "Link",
- "label": "Slideshow",
- "options": "Website Slideshow"
- },
- {
- "description": "Content in markdown format that appears on the main side of your page",
- "doctype": "DocField",
- "fieldname": "main_section",
- "fieldtype": "Text Editor",
- "label": "Main Section"
- },
- {
- "depends_on": "eval:!doc.__islocal",
- "description": "Link to other pages in the side bar and next section",
- "doctype": "DocField",
- "fieldname": "sb2",
- "fieldtype": "Section Break",
- "label": "More"
- },
- {
- "doctype": "DocField",
- "fieldname": "enable_comments",
- "fieldtype": "Check",
- "label": "Enable Comments"
- },
- {
- "doctype": "DocField",
- "fieldname": "text_align",
- "fieldtype": "Select",
- "label": "Text Align",
- "options": "Left\nCenter\nRight"
- },
- {
- "doctype": "DocField",
- "fieldname": "custom_javascript",
- "fieldtype": "Section Break",
- "label": "Custom Javascript"
- },
- {
- "description": "Add code as <script>",
- "doctype": "DocField",
- "fieldname": "insert_code",
- "fieldtype": "Check",
- "label": "Insert Code"
- },
- {
- "depends_on": "insert_code",
- "doctype": "DocField",
- "fieldname": "javascript",
- "fieldtype": "Code",
- "label": "Javascript",
- "options": "Javascript"
- },
- {
- "doctype": "DocField",
- "fieldname": "custom_css",
- "fieldtype": "Section Break",
- "label": "Custom CSS"
- },
- {
- "doctype": "DocField",
- "fieldname": "insert_style",
- "fieldtype": "Check",
- "label": "Insert Style"
- },
- {
- "depends_on": "insert_style",
- "doctype": "DocField",
- "fieldname": "css",
- "fieldtype": "Code",
- "label": "CSS",
- "options": "CSS"
- },
- {
- "doctype": "DocPerm"
- }
-]
\ No newline at end of file
diff --git a/frappe/website/doctype/website_group/website_group.json b/frappe/website/doctype/website_group/website_group.json
new file mode 100644
index 0000000000..3433dfab38
--- /dev/null
+++ b/frappe/website/doctype/website_group/website_group.json
@@ -0,0 +1,123 @@
+{
+ "creation": "2014-01-29 15:57:42.000000",
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "Master",
+ "fields": [
+ {
+ "fieldname": "name_and_description",
+ "fieldtype": "Section Break",
+ "label": "Name and Description",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "group_name",
+ "fieldtype": "Data",
+ "label": "Group Name",
+ "permlevel": 0,
+ "reqd": 1
+ },
+ {
+ "fieldname": "group_title",
+ "fieldtype": "Data",
+ "label": "Group Title",
+ "no_copy": 0,
+ "permlevel": 0,
+ "reqd": 1
+ },
+ {
+ "fieldname": "group_type",
+ "fieldtype": "Select",
+ "label": "Group Type",
+ "options": "Forum\nTasks\nEvents",
+ "permlevel": 0,
+ "reqd": 1
+ },
+ {
+ "description": "Display in the sidebar of this Website Route node",
+ "fieldname": "parent_website_route",
+ "fieldtype": "Link",
+ "in_list_view": 0,
+ "label": "Parent Website Page",
+ "options": "Website Route",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "column_break_6",
+ "fieldtype": "Column Break",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "group_description",
+ "fieldtype": "Text",
+ "label": "Group Description",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "page_name",
+ "fieldtype": "Data",
+ "in_list_view": 1,
+ "label": "Page Name",
+ "no_copy": 1,
+ "permlevel": 0,
+ "reqd": 0
+ },
+ {
+ "fieldname": "details",
+ "fieldtype": "Section Break",
+ "label": "Details",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "public_read",
+ "fieldtype": "Check",
+ "label": "Anyone Can Read",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "public_write",
+ "fieldtype": "Check",
+ "label": "Anyone Can Write",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "column_break_12",
+ "fieldtype": "Column Break",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "upvotes",
+ "fieldtype": "Int",
+ "label": "Upvotes",
+ "permlevel": 0,
+ "read_only": 1
+ },
+ {
+ "fieldname": "replies",
+ "fieldtype": "Int",
+ "label": "Replies",
+ "permlevel": 0,
+ "read_only": 1
+ }
+ ],
+ "icon": "icon-group",
+ "idx": 1,
+ "modified": "2014-03-04 09:36:30.000000",
+ "modified_by": "Administrator",
+ "module": "Website",
+ "name": "Website Group",
+ "owner": "Administrator",
+ "permissions": [
+ {
+ "cancel": 0,
+ "create": 1,
+ "delete": 1,
+ "export": 1,
+ "permlevel": 0,
+ "read": 1,
+ "report": 1,
+ "role": "Website Manager",
+ "write": 1
+ }
+ ]
+}
\ No newline at end of file
diff --git a/frappe/website/doctype/website_group/website_group.py b/frappe/website/doctype/website_group/website_group.py
index 3068d3984f..c1ef08dd63 100644
--- a/frappe/website/doctype/website_group/website_group.py
+++ b/frappe/website/doctype/website_group/website_group.py
@@ -5,18 +5,16 @@ from __future__ import unicode_literals
import frappe
from frappe.website.website_generator import WebsiteGenerator
from frappe.templates.generators.website_group import clear_cache
-from frappe.model.doc import make_autoname
+from frappe.model.naming import make_autoname
-class DocType(WebsiteGenerator):
- def __init__(self, d, dl):
- self.doc, self.doclist = d, dl
+class WebsiteGroup(WebsiteGenerator):
def get_page_title(self):
- return self.doc.group_title
+ return self.group_title
def on_update(self):
WebsiteGenerator.on_update(self)
- clear_cache(website_group=self.doc.name)
+ clear_cache(website_group=self.name)
def after_insert(self):
- clear_cache(path=self.doc.parent_website_route)
+ clear_cache(path=self.parent_website_route)
diff --git a/frappe/website/doctype/website_group/website_group.txt b/frappe/website/doctype/website_group/website_group.txt
deleted file mode 100644
index 65e4942638..0000000000
--- a/frappe/website/doctype/website_group/website_group.txt
+++ /dev/null
@@ -1,142 +0,0 @@
-[
- {
- "creation": "2014-01-29 15:57:42",
- "docstatus": 0,
- "modified": "2014-03-04 09:36:30",
- "modified_by": "Administrator",
- "owner": "Administrator"
- },
- {
- "doctype": "DocType",
- "document_type": "Master",
- "icon": "icon-group",
- "module": "Website",
- "name": "__common__"
- },
- {
- "doctype": "DocField",
- "name": "__common__",
- "parent": "Website Group",
- "parentfield": "fields",
- "parenttype": "DocType",
- "permlevel": 0
- },
- {
- "cancel": 0,
- "create": 1,
- "delete": 1,
- "doctype": "DocPerm",
- "export": 1,
- "name": "__common__",
- "parent": "Website Group",
- "parentfield": "permissions",
- "parenttype": "DocType",
- "permlevel": 0,
- "read": 1,
- "report": 1,
- "role": "Website Manager",
- "write": 1
- },
- {
- "doctype": "DocType",
- "name": "Website Group"
- },
- {
- "doctype": "DocField",
- "fieldname": "name_and_description",
- "fieldtype": "Section Break",
- "label": "Name and Description"
- },
- {
- "doctype": "DocField",
- "fieldname": "group_name",
- "fieldtype": "Data",
- "label": "Group Name",
- "reqd": 1
- },
- {
- "doctype": "DocField",
- "fieldname": "group_title",
- "fieldtype": "Data",
- "label": "Group Title",
- "no_copy": 0,
- "reqd": 1
- },
- {
- "doctype": "DocField",
- "fieldname": "group_type",
- "fieldtype": "Select",
- "label": "Group Type",
- "options": "Forum\nTasks\nEvents",
- "reqd": 1
- },
- {
- "description": "Display in the sidebar of this Website Route node",
- "doctype": "DocField",
- "fieldname": "parent_website_route",
- "fieldtype": "Link",
- "in_list_view": 0,
- "label": "Parent Website Page",
- "options": "Website Route"
- },
- {
- "doctype": "DocField",
- "fieldname": "column_break_6",
- "fieldtype": "Column Break"
- },
- {
- "doctype": "DocField",
- "fieldname": "group_description",
- "fieldtype": "Text",
- "label": "Group Description"
- },
- {
- "doctype": "DocField",
- "fieldname": "page_name",
- "fieldtype": "Data",
- "in_list_view": 1,
- "label": "Page Name",
- "no_copy": 1,
- "reqd": 0
- },
- {
- "doctype": "DocField",
- "fieldname": "details",
- "fieldtype": "Section Break",
- "label": "Details"
- },
- {
- "doctype": "DocField",
- "fieldname": "public_read",
- "fieldtype": "Check",
- "label": "Anyone Can Read"
- },
- {
- "doctype": "DocField",
- "fieldname": "public_write",
- "fieldtype": "Check",
- "label": "Anyone Can Write"
- },
- {
- "doctype": "DocField",
- "fieldname": "column_break_12",
- "fieldtype": "Column Break"
- },
- {
- "doctype": "DocField",
- "fieldname": "upvotes",
- "fieldtype": "Int",
- "label": "Upvotes",
- "read_only": 1
- },
- {
- "doctype": "DocField",
- "fieldname": "replies",
- "fieldtype": "Int",
- "label": "Replies",
- "read_only": 1
- },
- {
- "doctype": "DocPerm"
- }
-]
\ No newline at end of file
diff --git a/frappe/website/doctype/website_route/website_route.json b/frappe/website/doctype/website_route/website_route.json
new file mode 100644
index 0000000000..ee3c43c462
--- /dev/null
+++ b/frappe/website/doctype/website_route/website_route.json
@@ -0,0 +1,132 @@
+{
+ "allow_rename": 1,
+ "autoname": "field:page_name",
+ "creation": "2013-11-18 15:38:40.000000",
+ "docstatus": 0,
+ "doctype": "DocType",
+ "fields": [
+ {
+ "fieldname": "page_or_generator",
+ "fieldtype": "Select",
+ "label": "Page or Generator",
+ "options": "Page\nGenerator",
+ "permlevel": 0,
+ "read_only": 1
+ },
+ {
+ "fieldname": "page_name",
+ "fieldtype": "Data",
+ "label": "Page Name",
+ "permlevel": 0,
+ "read_only": 1,
+ "reqd": 1
+ },
+ {
+ "fieldname": "page_title",
+ "fieldtype": "Data",
+ "label": "Page Title",
+ "permlevel": 0,
+ "read_only": 1
+ },
+ {
+ "fieldname": "ref_doctype",
+ "fieldtype": "Link",
+ "label": "Ref DocType",
+ "options": "DocType",
+ "permlevel": 0,
+ "reqd": 0
+ },
+ {
+ "fieldname": "docname",
+ "fieldtype": "Data",
+ "label": "Docname",
+ "permlevel": 0,
+ "read_only": 1
+ },
+ {
+ "fieldname": "lastmod",
+ "fieldtype": "Data",
+ "label": "Lastmod",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "website_template",
+ "fieldtype": "Link",
+ "label": "Website Template",
+ "options": "Website Template",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "parent_website_route",
+ "fieldtype": "Link",
+ "in_list_view": 1,
+ "label": "Parent Website Sitemap",
+ "options": "Website Route",
+ "permlevel": 0,
+ "search_index": 1
+ },
+ {
+ "fieldname": "lft",
+ "fieldtype": "Int",
+ "hidden": 1,
+ "label": "lft",
+ "permlevel": 0,
+ "read_only": 1,
+ "search_index": 1
+ },
+ {
+ "fieldname": "rgt",
+ "fieldtype": "Int",
+ "hidden": 1,
+ "in_list_view": 0,
+ "label": "rgt",
+ "permlevel": 0,
+ "read_only": 1,
+ "search_index": 1
+ },
+ {
+ "fieldname": "old_parent",
+ "fieldtype": "Data",
+ "hidden": 1,
+ "label": "Old Parent",
+ "permlevel": 0,
+ "read_only": 1
+ },
+ {
+ "fieldname": "public_read",
+ "fieldtype": "Check",
+ "label": "Anyone Can Read",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "public_write",
+ "fieldtype": "Check",
+ "label": "Anyone Can Write",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "static_file_timestamp",
+ "fieldtype": "Data",
+ "label": "Static File Timestamp",
+ "permlevel": 0
+ }
+ ],
+ "idx": 1,
+ "modified": "2014-02-24 12:46:59.000000",
+ "modified_by": "Administrator",
+ "module": "Website",
+ "name": "Website Route",
+ "owner": "Administrator",
+ "permissions": [
+ {
+ "cancel": 0,
+ "create": 0,
+ "delete": 1,
+ "permlevel": 0,
+ "read": 1,
+ "report": 1,
+ "role": "Website Manager",
+ "write": 1
+ }
+ ]
+}
\ No newline at end of file
diff --git a/frappe/website/doctype/website_route/website_route.py b/frappe/website/doctype/website_route/website_route.py
index 1498898565..79818db01f 100644
--- a/frappe/website/doctype/website_route/website_route.py
+++ b/frappe/website/doctype/website_route/website_route.py
@@ -5,85 +5,83 @@ from __future__ import unicode_literals
import frappe
from frappe import _
from frappe.utils import cint
-from frappe.utils.nestedset import DocTypeNestedSet
+from frappe.utils.nestedset import NestedSet
sitemap_fields = ("page_name", "ref_doctype", "docname", "page_or_generator", "idx",
"lastmod", "parent_website_route", "public_read", "public_write", "page_title")
-class DocType(DocTypeNestedSet):
- def __init__(self, d, dl):
- self.doc, self.doclist = d, dl
- self.nsm_parent_field = "parent_website_route"
+class WebsiteRoute(NestedSet):
+ nsm_parent_field = "parent_website_route"
def autoname(self):
- self.doc.name = self.get_url()
+ self.name = self.get_url()
def get_url(self):
- url = self.doc.page_name
- if self.doc.parent_website_route:
- url = self.doc.parent_website_route + "/" + url
+ url = self.page_name
+ if self.parent_website_route:
+ url = self.parent_website_route + "/" + url
return url
def validate(self):
- if self.get_url() != self.doc.name:
+ if self.get_url() != self.name:
self.rename()
self.check_if_page_name_is_unique()
self.make_private_if_parent_is_private()
- if not self.doc.is_new():
+ if not self.is_new():
self.renumber_if_moved()
self.set_idx()
def renumber_if_moved(self):
- current_parent = frappe.db.get_value("Website Route", self.doc.name, "parent_website_route")
- if current_parent and current_parent != self.doc.parent_website_route:
+ current_parent = frappe.db.get_value("Website Route", self.name, "parent_website_route")
+ if current_parent and current_parent != self.parent_website_route:
# move-up
# sitemap
frappe.db.sql("""update `tabWebsite Route` set idx=idx-1
- where parent_website_route=%s and idx>%s""", (current_parent, self.doc.idx))
+ where parent_website_route=%s and idx>%s""", (current_parent, self.idx))
# source table
frappe.db.sql("""update `tab{0}` set idx=idx-1
- where parent_website_route=%s and idx>%s""".format(self.doc.ref_doctype),
- (current_parent, self.doc.idx))
- self.doc.idx = None
+ where parent_website_route=%s and idx>%s""".format(self.ref_doctype),
+ (current_parent, self.idx))
+ self.idx = None
def on_update(self):
if not frappe.flags.in_rebuild_config:
- DocTypeNestedSet.on_update(self)
+ NestedSet.on_update(self)
self.clear_cache()
def set_idx(self):
- if self.doc.parent_website_route:
- if self.doc.idx == None:
+ if self.parent_website_route:
+ if self.idx == None:
self.set_idx_as_last()
else:
self.validate_previous_idx_exists()
def set_idx_as_last(self):
# new, append
- self.doc.idx = int(frappe.db.sql("""select ifnull(max(ifnull(idx, -1)), -1)
+ self.idx = int(frappe.db.sql("""select ifnull(max(ifnull(idx, -1)), -1)
from `tabWebsite Route`
where ifnull(parent_website_route, '')=%s and name!=%s""",
- (self.doc.parent_website_route or '',
- self.doc.name))[0][0]) + 1
+ (self.parent_website_route or '',
+ self.name))[0][0]) + 1
def validate_previous_idx_exists(self):
- self.doc.idx = cint(self.doc.idx)
+ self.idx = cint(self.idx)
previous_idx = frappe.db.sql("""select max(idx)
from `tab{}` where ifnull(parent_website_route, '')=%s
- and ifnull(idx, -1) < %s""".format(self.doc.ref_doctype),
- (self.doc.parent_website_route, self.doc.idx))[0][0]
+ and ifnull(idx, -1) < %s""".format(self.ref_doctype),
+ (self.parent_website_route, self.idx))[0][0]
- if previous_idx and previous_idx != self.doc.idx - 1:
+ if previous_idx and previous_idx != self.idx - 1:
frappe.throw("{}: {}, {}".format(
- _("Sitemap Ordering Error. Index missing"), self.doc.name, self.doc.idx-1))
+ _("Sitemap Ordering Error. Index missing"), self.name, self.idx-1))
def rename(self):
- self.old_name = self.doc.name
- self.doc.name = self.get_url()
+ self.old_name = self.name
+ self.name = self.get_url()
frappe.db.sql("""update `tabWebsite Route` set name=%s where name=%s""",
- (self.doc.name, self.old_name))
+ (self.name, self.old_name))
self.rename_links()
self.rename_descendants()
self.clear_cache(self.old_name)
@@ -93,80 +91,80 @@ class DocType(DocTypeNestedSet):
fieldname='parent_website_route' and options='Website Route'"""):
for name in frappe.db.sql_list("""select name from `tab{}`
where parent_website_route=%s""".format(doctype), self.old_name):
- frappe.db.set_value(doctype, name, "parent_website_route", self.doc.name)
+ frappe.db.set_value(doctype, name, "parent_website_route", self.name)
def rename_descendants(self):
# rename children
for name in frappe.db.sql_list("""select name from `tabWebsite Route`
- where parent_website_route=%s""", self.doc.name):
- child = frappe.bean("Website Route", name)
- child.doc.parent_website_route = self.doc.name
+ where parent_website_route=%s""", self.name):
+ child = frappe.get_doc("Website Route", name)
+ child.parent_website_route = self.name
child.save()
def check_if_page_name_is_unique(self):
exists = False
- if self.doc.page_or_generator == "Page":
+ if self.page_or_generator == "Page":
# for a page, name and website sitemap config form a unique key
exists = frappe.db.sql("""select name from `tabWebsite Route`
- where name=%s and website_template!=%s""", (self.doc.name, self.doc.website_template))
+ where name=%s and website_template!=%s""", (self.name, self.website_template))
else:
# for a generator, name, ref_doctype and docname make a unique key
exists = frappe.db.sql("""select name from `tabWebsite Route`
where name=%s and (ifnull(ref_doctype, '')!=%s or ifnull(docname, '')!=%s)""",
- (self.doc.name, self.doc.ref_doctype, self.doc.docname))
+ (self.name, self.ref_doctype, self.docname))
if exists:
frappe.throw("{}: {}. {}.".format(_("A Website Page already exists with the Page Name"),
- self.doc.name, _("Please change it to continue")))
+ self.name, _("Please change it to continue")))
def make_private_if_parent_is_private(self):
- if self.doc.parent_website_route:
- parent_pubic_read = frappe.db.get_value("Website Route", self.doc.parent_website_route,
+ if self.parent_website_route:
+ parent_pubic_read = frappe.db.get_value("Website Route", self.parent_website_route,
"public_read")
if not parent_pubic_read:
- self.doc.public_read = self.doc.public_write = 0
+ self.public_read = self.public_write = 0
def on_trash(self):
# remove website sitemap permissions
to_remove = frappe.db.sql_list("""select name from `tabWebsite Route Permission`
- where website_route=%s""", (self.doc.name,))
+ where website_route=%s""", (self.name,))
frappe.delete_doc("Website Route Permission", to_remove, ignore_permissions=True)
self.clear_cache()
def clear_cache(self, name=None):
from frappe.website.render import clear_cache
- clear_cache(name or self.doc.name)
- if self.doc.parent_website_route:
- clear_cache(self.doc.parent_website_route)
+ clear_cache(name or self.name)
+ if self.parent_website_route:
+ clear_cache(self.parent_website_route)
def add_to_sitemap(options):
- bean = frappe.new_bean("Website Route")
+ website_route = frappe.new_doc("Website Route")
for key in sitemap_fields:
- bean.doc.fields[key] = options.get(key)
- if not bean.doc.page_name:
- bean.doc.page_name = options.get("link_name")
- bean.doc.website_template = options.get("link_name")
+ website_route.set(key, options.get(key))
+ if not website_route.page_name:
+ website_route.page_name = options.get("link_name")
+ website_route.website_template = options.get("link_name")
- bean.insert(ignore_permissions=True)
+ website_route.insert(ignore_permissions=True)
- return bean.doc.idx
+ return website_route.idx
def update_sitemap(website_route, options):
- bean = frappe.bean("Website Route", website_route)
+ website_route = frappe.get_doc("Website Route", website_route)
for key in sitemap_fields:
- bean.doc.fields[key] = options.get(key)
+ website_route.set(key, options.get(key))
- if not bean.doc.page_name:
+ if not website_route.page_name:
# for pages
- bean.doc.page_name = options.get("link_name")
+ website_route.page_name = options.get("link_name")
- bean.doc.website_template = options.get("link_name")
- bean.save(ignore_permissions=True)
+ website_route.website_template = options.get("link_name")
+ website_route.save(ignore_permissions=True)
- return bean.doc.idx
+ return website_route.idx
def remove_sitemap(page_name=None, ref_doctype=None, docname=None):
if page_name:
diff --git a/frappe/website/doctype/website_route/website_route.txt b/frappe/website/doctype/website_route/website_route.txt
deleted file mode 100644
index 65f3f4e9e1..0000000000
--- a/frappe/website/doctype/website_route/website_route.txt
+++ /dev/null
@@ -1,151 +0,0 @@
-[
- {
- "creation": "2013-11-18 15:38:40",
- "docstatus": 0,
- "modified": "2014-02-24 12:46:59",
- "modified_by": "Administrator",
- "owner": "Administrator"
- },
- {
- "allow_rename": 1,
- "autoname": "field:page_name",
- "doctype": "DocType",
- "module": "Website",
- "name": "__common__"
- },
- {
- "doctype": "DocField",
- "name": "__common__",
- "parent": "Website Route",
- "parentfield": "fields",
- "parenttype": "DocType",
- "permlevel": 0
- },
- {
- "cancel": 0,
- "create": 0,
- "delete": 1,
- "doctype": "DocPerm",
- "name": "__common__",
- "parent": "Website Route",
- "parentfield": "permissions",
- "parenttype": "DocType",
- "permlevel": 0,
- "read": 1,
- "report": 1,
- "role": "Website Manager",
- "write": 1
- },
- {
- "doctype": "DocType",
- "name": "Website Route"
- },
- {
- "doctype": "DocField",
- "fieldname": "page_or_generator",
- "fieldtype": "Select",
- "label": "Page or Generator",
- "options": "Page\nGenerator",
- "read_only": 1
- },
- {
- "doctype": "DocField",
- "fieldname": "page_name",
- "fieldtype": "Data",
- "label": "Page Name",
- "read_only": 1,
- "reqd": 1
- },
- {
- "doctype": "DocField",
- "fieldname": "page_title",
- "fieldtype": "Data",
- "label": "Page Title",
- "read_only": 1
- },
- {
- "doctype": "DocField",
- "fieldname": "ref_doctype",
- "fieldtype": "Link",
- "label": "Ref DocType",
- "options": "DocType",
- "reqd": 0
- },
- {
- "doctype": "DocField",
- "fieldname": "docname",
- "fieldtype": "Data",
- "label": "Docname",
- "read_only": 1
- },
- {
- "doctype": "DocField",
- "fieldname": "lastmod",
- "fieldtype": "Data",
- "label": "Lastmod"
- },
- {
- "doctype": "DocField",
- "fieldname": "website_template",
- "fieldtype": "Link",
- "label": "Website Template",
- "options": "Website Template"
- },
- {
- "doctype": "DocField",
- "fieldname": "parent_website_route",
- "fieldtype": "Link",
- "in_list_view": 1,
- "label": "Parent Website Sitemap",
- "options": "Website Route",
- "search_index": 1
- },
- {
- "doctype": "DocField",
- "fieldname": "lft",
- "fieldtype": "Int",
- "hidden": 1,
- "label": "lft",
- "read_only": 1,
- "search_index": 1
- },
- {
- "doctype": "DocField",
- "fieldname": "rgt",
- "fieldtype": "Int",
- "hidden": 1,
- "in_list_view": 0,
- "label": "rgt",
- "read_only": 1,
- "search_index": 1
- },
- {
- "doctype": "DocField",
- "fieldname": "old_parent",
- "fieldtype": "Data",
- "hidden": 1,
- "label": "Old Parent",
- "read_only": 1
- },
- {
- "doctype": "DocField",
- "fieldname": "public_read",
- "fieldtype": "Check",
- "label": "Anyone Can Read"
- },
- {
- "doctype": "DocField",
- "fieldname": "public_write",
- "fieldtype": "Check",
- "label": "Anyone Can Write"
- },
- {
- "doctype": "DocField",
- "fieldname": "static_file_timestamp",
- "fieldtype": "Data",
- "label": "Static File Timestamp"
- },
- {
- "doctype": "DocPerm"
- }
-]
\ No newline at end of file
diff --git a/frappe/website/doctype/website_route_permission/website_route_permission.json b/frappe/website/doctype/website_route_permission/website_route_permission.json
new file mode 100644
index 0000000000..fe72366385
--- /dev/null
+++ b/frappe/website/doctype/website_route_permission/website_route_permission.json
@@ -0,0 +1,70 @@
+{
+ "autoname": "WSP.######",
+ "creation": "2014-01-29 17:56:29.000000",
+ "docstatus": 0,
+ "doctype": "DocType",
+ "fields": [
+ {
+ "fieldname": "website_route",
+ "fieldtype": "Link",
+ "in_list_view": 1,
+ "label": "Website Route",
+ "options": "Website Route",
+ "permlevel": 0,
+ "reqd": 1,
+ "search_index": 1
+ },
+ {
+ "fieldname": "user",
+ "fieldtype": "Link",
+ "in_list_view": 1,
+ "label": "User",
+ "options": "User",
+ "permlevel": 0,
+ "reqd": 1,
+ "search_index": 1
+ },
+ {
+ "fieldname": "read",
+ "fieldtype": "Check",
+ "in_list_view": 1,
+ "label": "Read",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "write",
+ "fieldtype": "Check",
+ "in_list_view": 1,
+ "label": "Write",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "admin",
+ "fieldtype": "Check",
+ "in_list_view": 1,
+ "label": "Admin",
+ "permlevel": 0
+ }
+ ],
+ "icon": "icon-shield",
+ "idx": 1,
+ "modified": "2014-02-24 13:17:18.000000",
+ "modified_by": "Administrator",
+ "module": "Website",
+ "name": "Website Route Permission",
+ "owner": "Administrator",
+ "permissions": [
+ {
+ "cancel": 0,
+ "create": 1,
+ "delete": 0,
+ "export": 1,
+ "import": 0,
+ "permlevel": 0,
+ "read": 1,
+ "report": 1,
+ "role": "Website Manager",
+ "write": 1
+ }
+ ]
+}
\ No newline at end of file
diff --git a/frappe/website/doctype/website_route_permission/website_route_permission.py b/frappe/website/doctype/website_route_permission/website_route_permission.py
index 3a840cd7df..6986189ecf 100644
--- a/frappe/website/doctype/website_route_permission/website_route_permission.py
+++ b/frappe/website/doctype/website_route_permission/website_route_permission.py
@@ -6,11 +6,11 @@ import frappe
from frappe.website.permissions import remove_empty_permissions, clear_permissions
-class DocType:
- def __init__(self, d, dl):
- self.doc, self.doclist = d, dl
+from frappe.model.document import Document
+
+class WebsiteRoutePermission(Document):
def on_update(self):
remove_empty_permissions()
- clear_permissions(self.doc.user)
+ clear_permissions(self.user)
\ No newline at end of file
diff --git a/frappe/website/doctype/website_route_permission/website_route_permission.txt b/frappe/website/doctype/website_route_permission/website_route_permission.txt
deleted file mode 100644
index ee5e3390b7..0000000000
--- a/frappe/website/doctype/website_route_permission/website_route_permission.txt
+++ /dev/null
@@ -1,85 +0,0 @@
-[
- {
- "creation": "2014-01-29 17:56:29",
- "docstatus": 0,
- "modified": "2014-02-24 13:17:18",
- "modified_by": "Administrator",
- "owner": "Administrator"
- },
- {
- "autoname": "WSP.######",
- "doctype": "DocType",
- "icon": "icon-shield",
- "module": "Website",
- "name": "__common__"
- },
- {
- "doctype": "DocField",
- "in_list_view": 1,
- "name": "__common__",
- "parent": "Website Route Permission",
- "parentfield": "fields",
- "parenttype": "DocType",
- "permlevel": 0
- },
- {
- "cancel": 0,
- "create": 1,
- "delete": 0,
- "doctype": "DocPerm",
- "export": 1,
- "import": 0,
- "name": "__common__",
- "parent": "Website Route Permission",
- "parentfield": "permissions",
- "parenttype": "DocType",
- "permlevel": 0,
- "read": 1,
- "report": 1,
- "role": "Website Manager",
- "write": 1
- },
- {
- "doctype": "DocType",
- "name": "Website Route Permission"
- },
- {
- "doctype": "DocField",
- "fieldname": "website_route",
- "fieldtype": "Link",
- "label": "Website Route",
- "options": "Website Route",
- "reqd": 1,
- "search_index": 1
- },
- {
- "doctype": "DocField",
- "fieldname": "user",
- "fieldtype": "Link",
- "label": "User",
- "options": "User",
- "reqd": 1,
- "search_index": 1
- },
- {
- "doctype": "DocField",
- "fieldname": "read",
- "fieldtype": "Check",
- "label": "Read"
- },
- {
- "doctype": "DocField",
- "fieldname": "write",
- "fieldtype": "Check",
- "label": "Write"
- },
- {
- "doctype": "DocField",
- "fieldname": "admin",
- "fieldtype": "Check",
- "label": "Admin"
- },
- {
- "doctype": "DocPerm"
- }
-]
\ No newline at end of file
diff --git a/frappe/website/doctype/website_script/website_script.json b/frappe/website/doctype/website_script/website_script.json
new file mode 100644
index 0000000000..68cffc71dd
--- /dev/null
+++ b/frappe/website/doctype/website_script/website_script.json
@@ -0,0 +1,35 @@
+{
+ "creation": "2012-12-27 11:51:24.000000",
+ "description": "Script to attach to all web pages.",
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "Other",
+ "fields": [
+ {
+ "fieldname": "javascript",
+ "fieldtype": "Code",
+ "label": "Javascript",
+ "options": "Javascript",
+ "permlevel": 0
+ }
+ ],
+ "icon": "icon-code",
+ "idx": 1,
+ "issingle": 1,
+ "modified": "2013-12-20 19:21:54.000000",
+ "modified_by": "Administrator",
+ "module": "Website",
+ "name": "Website Script",
+ "owner": "Administrator",
+ "permissions": [
+ {
+ "create": 1,
+ "email": 1,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "role": "Website Manager",
+ "write": 1
+ }
+ ]
+}
\ No newline at end of file
diff --git a/frappe/website/doctype/website_script/website_script.py b/frappe/website/doctype/website_script/website_script.py
index 2fdabfe4c1..a50b91d9b9 100644
--- a/frappe/website/doctype/website_script/website_script.py
+++ b/frappe/website/doctype/website_script/website_script.py
@@ -6,9 +6,9 @@
from __future__ import unicode_literals
import frappe
-class DocType:
- def __init__(self, d, dl):
- self.doc, self.doclist = d, dl
+from frappe.model.document import Document
+
+class WebsiteScript(Document):
def on_update(self):
"""clear cache"""
diff --git a/frappe/website/doctype/website_script/website_script.txt b/frappe/website/doctype/website_script/website_script.txt
deleted file mode 100644
index ce016d020c..0000000000
--- a/frappe/website/doctype/website_script/website_script.txt
+++ /dev/null
@@ -1,54 +0,0 @@
-[
- {
- "creation": "2012-12-27 11:51:24",
- "docstatus": 0,
- "modified": "2013-12-20 19:21:54",
- "modified_by": "Administrator",
- "owner": "Administrator"
- },
- {
- "description": "Script to attach to all web pages.",
- "doctype": "DocType",
- "document_type": "Other",
- "icon": "icon-code",
- "issingle": 1,
- "module": "Website",
- "name": "__common__"
- },
- {
- "doctype": "DocField",
- "fieldname": "javascript",
- "fieldtype": "Code",
- "label": "Javascript",
- "name": "__common__",
- "options": "Javascript",
- "parent": "Website Script",
- "parentfield": "fields",
- "parenttype": "DocType",
- "permlevel": 0
- },
- {
- "create": 1,
- "doctype": "DocPerm",
- "email": 1,
- "name": "__common__",
- "parent": "Website Script",
- "parentfield": "permissions",
- "parenttype": "DocType",
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "role": "Website Manager",
- "write": 1
- },
- {
- "doctype": "DocType",
- "name": "Website Script"
- },
- {
- "doctype": "DocField"
- },
- {
- "doctype": "DocPerm"
- }
-]
\ No newline at end of file
diff --git a/frappe/website/doctype/website_settings/website_settings.js b/frappe/website/doctype/website_settings/website_settings.js
index 4db6bd9e05..aecc9615a1 100644
--- a/frappe/website/doctype/website_settings/website_settings.js
+++ b/frappe/website/doctype/website_settings/website_settings.js
@@ -31,7 +31,7 @@ $.extend(cur_frm.cscript, {
},
label: function(doc, cdt, cdn) {
- var item = frappe.model.get_doc(cdt, cdn);
+ var item = frappe.get_doc(cdt, cdn);
if(item.parentfield === "top_bar_items") {
this.set_parent_label_options();
}
@@ -56,7 +56,7 @@ $.extend(cur_frm.cscript, {
// get labels of parent items
get_parent_options: function(table_field) {
- var items = getchildren('Top Bar Item', cur_frm.doc.name, table_field);
+ var items = cur_frm.doc[table_field] || [];
var main_items = [''];
for(var i in items) {
var d = items[i];
diff --git a/frappe/website/doctype/website_settings/website_settings.json b/frappe/website/doctype/website_settings/website_settings.json
new file mode 100644
index 0000000000..effd71d009
--- /dev/null
+++ b/frappe/website/doctype/website_settings/website_settings.json
@@ -0,0 +1,251 @@
+{
+ "allow_attach": 1,
+ "creation": "2013-04-30 12:58:46.000000",
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "Other",
+ "fields": [
+ {
+ "fieldname": "sb0",
+ "fieldtype": "Section Break",
+ "label": "Landing Page",
+ "permlevel": 0
+ },
+ {
+ "description": "Link that is the website home page. Standard Links (index, login, products, blog, about, contact)",
+ "fieldname": "home_page",
+ "fieldtype": "Link",
+ "label": "Home Page",
+ "options": "Website Route",
+ "permlevel": 0,
+ "reqd": 0
+ },
+ {
+ "description": "The name of your company / website as you want to appear on browser title bar. All pages will have this as the prefix to the title.",
+ "fieldname": "title_prefix",
+ "fieldtype": "Data",
+ "label": "Title Prefix",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "cb4",
+ "fieldtype": "Column Break",
+ "permlevel": 0
+ },
+ {
+ "description": "If checked, the Home page will be the default Item Group for the website.",
+ "fieldname": "home_page_is_products",
+ "fieldtype": "Check",
+ "label": "Home Page is Products",
+ "permlevel": 0
+ },
+ {
+ "description": "Add a banner to the site. (small banners are usually good)",
+ "fieldname": "banner",
+ "fieldtype": "Section Break",
+ "label": "Banner",
+ "permlevel": 0
+ },
+ {
+ "description": "Select an image of approx width 150px with a transparent background for best results.",
+ "fieldname": "banner_image",
+ "fieldtype": "Select",
+ "label": "Banner Image",
+ "options": "attach_files:",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "set_banner_from_image",
+ "fieldtype": "Button",
+ "label": "Set Banner from Image",
+ "permlevel": 0
+ },
+ {
+ "description": "Banner is above the Top Menu Bar.",
+ "fieldname": "banner_html",
+ "fieldtype": "Small Text",
+ "label": "Banner HTML",
+ "permlevel": 0
+ },
+ {
+ "description": "Menu items in the Top Bar. For setting the color of the Top Bar, go to
Style Settings",
+ "fieldname": "top_bar",
+ "fieldtype": "Section Break",
+ "label": "Top Bar",
+ "permlevel": 0
+ },
+ {
+ "description": "Brand is what appears on the top-right of the toolbar. If it is an image, make sure it\nhas a transparent background and use the <img /> tag. Keep size as 200px x 30px",
+ "fieldname": "brand_html",
+ "fieldtype": "Small Text",
+ "label": "Brand HTML",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "top_bar_items",
+ "fieldtype": "Table",
+ "label": "Top Bar Items",
+ "options": "Top Bar Item",
+ "permlevel": 0
+ },
+ {
+ "description": "Sidebar Links for Home Page only",
+ "fieldname": "sidebar",
+ "fieldtype": "Section Break",
+ "label": "Sidebar",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "sidebar_items",
+ "fieldtype": "Table",
+ "label": "Sidebar Items",
+ "options": "Top Bar Item",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "footer",
+ "fieldtype": "Section Break",
+ "label": "Footer",
+ "permlevel": 0
+ },
+ {
+ "description": "Address and other legal information you may want to put in the footer.",
+ "fieldname": "address",
+ "fieldtype": "Text Editor",
+ "label": "Address",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "copyright",
+ "fieldtype": "Data",
+ "label": "Copyright",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "footer_items",
+ "fieldtype": "Table",
+ "label": "Footer Items",
+ "options": "Top Bar Item",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "integrations",
+ "fieldtype": "Section Break",
+ "label": "Integrations",
+ "permlevel": 0
+ },
+ {
+ "description": "Add Google Analytics ID: eg. UA-89XXX57-1. Please search help on Google Analytics for more information.",
+ "fieldname": "google_analytics_id",
+ "fieldtype": "Data",
+ "label": "Google Analytics ID",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "column_break_17",
+ "fieldtype": "Column Break",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "google_plus_one",
+ "fieldtype": "Check",
+ "label": "Google Plus One",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "facebook_share",
+ "fieldtype": "Check",
+ "label": "Facebook Share",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "linked_in_share",
+ "fieldtype": "Check",
+ "label": "Linked In Share",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "twitter_share",
+ "fieldtype": "Check",
+ "label": "Twitter Share",
+ "permlevel": 0
+ },
+ {
+ "description": "Tweet will be shared via your user account (if specified)",
+ "fieldname": "twitter_share_via",
+ "fieldtype": "Data",
+ "label": "Twitter Share via",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "misc_section",
+ "fieldtype": "Section Break",
+ "label": "Misc",
+ "permlevel": 0
+ },
+ {
+ "description": "An icon file with .ico extension. Should be 16 x 16 px. Generated using a favicon generator. [
favicon-generator.org]",
+ "fieldname": "favicon",
+ "fieldtype": "Select",
+ "label": "FavIcon",
+ "options": "attach_files:",
+ "permlevel": 0
+ },
+ {
+ "description": "Sub-domain provided by erpnext.com",
+ "fieldname": "subdomain",
+ "fieldtype": "Text",
+ "label": "Subdomain",
+ "permlevel": 0,
+ "read_only": 1,
+ "reqd": 0
+ },
+ {
+ "fieldname": "column_break_28",
+ "fieldtype": "Column Break",
+ "permlevel": 0
+ },
+ {
+ "description": "Disable Customer Signup link in Login page",
+ "fieldname": "disable_signup",
+ "fieldtype": "Check",
+ "label": "Disable Signup",
+ "permlevel": 0
+ }
+ ],
+ "icon": "icon-cog",
+ "idx": 1,
+ "issingle": 1,
+ "max_attachments": 10,
+ "modified": "2014-02-26 11:39:10.000000",
+ "modified_by": "Administrator",
+ "module": "Website",
+ "name": "Website Settings",
+ "owner": "Administrator",
+ "permissions": [
+ {
+ "cancel": 0,
+ "create": 1,
+ "delete": 0,
+ "email": 1,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 0,
+ "role": "Website Manager",
+ "submit": 0,
+ "write": 1
+ },
+ {
+ "amend": 0,
+ "cancel": 0,
+ "create": 0,
+ "delete": 0,
+ "permlevel": 1,
+ "read": 1,
+ "report": 0,
+ "role": "All",
+ "submit": 0
+ }
+ ]
+}
\ No newline at end of file
diff --git a/frappe/website/doctype/website_settings/website_settings.py b/frappe/website/doctype/website_settings/website_settings.py
index 81b59ea6c7..e1af4cc518 100644
--- a/frappe/website/doctype/website_settings/website_settings.py
+++ b/frappe/website/doctype/website_settings/website_settings.py
@@ -8,23 +8,22 @@ from frappe.utils import get_request_site_address, encode
from frappe.model.controller import DocListController
from urllib import quote
-class DocType(DocListController):
+class WebsiteSettings(DocListController):
def validate(self):
self.validate_top_bar_items()
self.validate_footer_items()
self.validate_home_page()
def validate_home_page(self):
- if self.doc.home_page and \
- not frappe.db.get_value("Website Route", {"name": self.doc.home_page}):
+ if self.home_page and \
+ not frappe.db.get_value("Website Route", {"name": self.home_page}):
frappe.throw(_("Invalid Home Page") + " (Standard pages - index, login, products, blog, about, contact)")
def validate_top_bar_items(self):
"""validate url in top bar items"""
- for top_bar_item in self.doclist.get({"parentfield": "top_bar_items"}):
+ for top_bar_item in self.get("top_bar_items"):
if top_bar_item.parent_label:
- parent_label_item = self.doclist.get({"parentfield": "top_bar_items",
- "label": top_bar_item.parent_label})
+ parent_label_item = self.get("top_bar_items", {"label": top_bar_item.parent_label})
if not parent_label_item:
# invalid item
@@ -38,7 +37,7 @@ class DocType(DocListController):
def validate_footer_items(self):
"""clear parent label in footer"""
- for footer_item in self.doclist.get({"parentfield": "footer_items"}):
+ for footer_item in self.get("footer_items"):
footer_item.parent_label = None
def on_update(self):
@@ -80,12 +79,12 @@ def get_website_settings():
]
})
- settings = frappe.doc("Website Settings", "Website Settings")
+ settings = frappe.get_doc("Website Settings", "Website Settings")
for k in ["banner_html", "brand_html", "copyright", "twitter_share_via",
"favicon", "facebook_share", "google_plus_one", "twitter_share", "linked_in_share",
"disable_signup"]:
- if k in settings.fields:
- context[k] = settings.fields.get(k)
+ if hasattr(settings, k):
+ context[k] = settings.get(k)
if not context.get("favicon"):
context["favicon"] = "/assets/frappe/images/favicon.ico"
diff --git a/frappe/website/doctype/website_settings/website_settings.txt b/frappe/website/doctype/website_settings/website_settings.txt
deleted file mode 100644
index 50975bc243..0000000000
--- a/frappe/website/doctype/website_settings/website_settings.txt
+++ /dev/null
@@ -1,266 +0,0 @@
-[
- {
- "creation": "2013-04-30 12:58:46",
- "docstatus": 0,
- "modified": "2014-02-26 11:39:10",
- "modified_by": "Administrator",
- "owner": "Administrator"
- },
- {
- "allow_attach": 1,
- "doctype": "DocType",
- "document_type": "Other",
- "icon": "icon-cog",
- "issingle": 1,
- "max_attachments": 10,
- "module": "Website",
- "name": "__common__"
- },
- {
- "doctype": "DocField",
- "name": "__common__",
- "parent": "Website Settings",
- "parentfield": "fields",
- "parenttype": "DocType",
- "permlevel": 0
- },
- {
- "cancel": 0,
- "delete": 0,
- "doctype": "DocPerm",
- "name": "__common__",
- "parent": "Website Settings",
- "parentfield": "permissions",
- "parenttype": "DocType",
- "read": 1,
- "report": 0,
- "submit": 0
- },
- {
- "doctype": "DocType",
- "name": "Website Settings"
- },
- {
- "doctype": "DocField",
- "fieldname": "sb0",
- "fieldtype": "Section Break",
- "label": "Landing Page"
- },
- {
- "description": "Link that is the website home page. Standard Links (index, login, products, blog, about, contact)",
- "doctype": "DocField",
- "fieldname": "home_page",
- "fieldtype": "Link",
- "label": "Home Page",
- "options": "Website Route",
- "reqd": 0
- },
- {
- "description": "The name of your company / website as you want to appear on browser title bar. All pages will have this as the prefix to the title.",
- "doctype": "DocField",
- "fieldname": "title_prefix",
- "fieldtype": "Data",
- "label": "Title Prefix"
- },
- {
- "doctype": "DocField",
- "fieldname": "cb4",
- "fieldtype": "Column Break"
- },
- {
- "description": "If checked, the Home page will be the default Item Group for the website.",
- "doctype": "DocField",
- "fieldname": "home_page_is_products",
- "fieldtype": "Check",
- "label": "Home Page is Products"
- },
- {
- "description": "Add a banner to the site. (small banners are usually good)",
- "doctype": "DocField",
- "fieldname": "banner",
- "fieldtype": "Section Break",
- "label": "Banner"
- },
- {
- "description": "Select an image of approx width 150px with a transparent background for best results.",
- "doctype": "DocField",
- "fieldname": "banner_image",
- "fieldtype": "Select",
- "label": "Banner Image",
- "options": "attach_files:"
- },
- {
- "doctype": "DocField",
- "fieldname": "set_banner_from_image",
- "fieldtype": "Button",
- "label": "Set Banner from Image"
- },
- {
- "description": "Banner is above the Top Menu Bar.",
- "doctype": "DocField",
- "fieldname": "banner_html",
- "fieldtype": "Small Text",
- "label": "Banner HTML"
- },
- {
- "description": "Menu items in the Top Bar. For setting the color of the Top Bar, go to
Style Settings",
- "doctype": "DocField",
- "fieldname": "top_bar",
- "fieldtype": "Section Break",
- "label": "Top Bar"
- },
- {
- "description": "Brand is what appears on the top-right of the toolbar. If it is an image, make sure it\nhas a transparent background and use the <img /> tag. Keep size as 200px x 30px",
- "doctype": "DocField",
- "fieldname": "brand_html",
- "fieldtype": "Small Text",
- "label": "Brand HTML"
- },
- {
- "doctype": "DocField",
- "fieldname": "top_bar_items",
- "fieldtype": "Table",
- "label": "Top Bar Items",
- "options": "Top Bar Item"
- },
- {
- "description": "Sidebar Links for Home Page only",
- "doctype": "DocField",
- "fieldname": "sidebar",
- "fieldtype": "Section Break",
- "label": "Sidebar"
- },
- {
- "doctype": "DocField",
- "fieldname": "sidebar_items",
- "fieldtype": "Table",
- "label": "Sidebar Items",
- "options": "Top Bar Item"
- },
- {
- "doctype": "DocField",
- "fieldname": "footer",
- "fieldtype": "Section Break",
- "label": "Footer"
- },
- {
- "description": "Address and other legal information you may want to put in the footer.",
- "doctype": "DocField",
- "fieldname": "address",
- "fieldtype": "Text Editor",
- "label": "Address"
- },
- {
- "doctype": "DocField",
- "fieldname": "copyright",
- "fieldtype": "Data",
- "label": "Copyright"
- },
- {
- "doctype": "DocField",
- "fieldname": "footer_items",
- "fieldtype": "Table",
- "label": "Footer Items",
- "options": "Top Bar Item"
- },
- {
- "doctype": "DocField",
- "fieldname": "integrations",
- "fieldtype": "Section Break",
- "label": "Integrations"
- },
- {
- "description": "Add Google Analytics ID: eg. UA-89XXX57-1. Please search help on Google Analytics for more information.",
- "doctype": "DocField",
- "fieldname": "google_analytics_id",
- "fieldtype": "Data",
- "label": "Google Analytics ID"
- },
- {
- "doctype": "DocField",
- "fieldname": "column_break_17",
- "fieldtype": "Column Break"
- },
- {
- "doctype": "DocField",
- "fieldname": "google_plus_one",
- "fieldtype": "Check",
- "label": "Google Plus One"
- },
- {
- "doctype": "DocField",
- "fieldname": "facebook_share",
- "fieldtype": "Check",
- "label": "Facebook Share"
- },
- {
- "doctype": "DocField",
- "fieldname": "linked_in_share",
- "fieldtype": "Check",
- "label": "Linked In Share"
- },
- {
- "doctype": "DocField",
- "fieldname": "twitter_share",
- "fieldtype": "Check",
- "label": "Twitter Share"
- },
- {
- "description": "Tweet will be shared via your user account (if specified)",
- "doctype": "DocField",
- "fieldname": "twitter_share_via",
- "fieldtype": "Data",
- "label": "Twitter Share via"
- },
- {
- "doctype": "DocField",
- "fieldname": "misc_section",
- "fieldtype": "Section Break",
- "label": "Misc"
- },
- {
- "description": "An icon file with .ico extension. Should be 16 x 16 px. Generated using a favicon generator. [
favicon-generator.org]",
- "doctype": "DocField",
- "fieldname": "favicon",
- "fieldtype": "Select",
- "label": "FavIcon",
- "options": "attach_files:"
- },
- {
- "description": "Sub-domain provided by erpnext.com",
- "doctype": "DocField",
- "fieldname": "subdomain",
- "fieldtype": "Text",
- "label": "Subdomain",
- "read_only": 1,
- "reqd": 0
- },
- {
- "doctype": "DocField",
- "fieldname": "column_break_28",
- "fieldtype": "Column Break"
- },
- {
- "description": "Disable Customer Signup link in Login page",
- "doctype": "DocField",
- "fieldname": "disable_signup",
- "fieldtype": "Check",
- "label": "Disable Signup"
- },
- {
- "create": 1,
- "doctype": "DocPerm",
- "email": 1,
- "permlevel": 0,
- "print": 1,
- "role": "Website Manager",
- "write": 1
- },
- {
- "amend": 0,
- "create": 0,
- "doctype": "DocPerm",
- "permlevel": 1,
- "role": "All"
- }
-]
\ No newline at end of file
diff --git a/frappe/website/doctype/website_slideshow/website_slideshow.json b/frappe/website/doctype/website_slideshow/website_slideshow.json
new file mode 100644
index 0000000000..823b51454a
--- /dev/null
+++ b/frappe/website/doctype/website_slideshow/website_slideshow.json
@@ -0,0 +1,66 @@
+{
+ "allow_attach": 1,
+ "autoname": "field:slideshow_name",
+ "creation": "2013-03-07 15:53:15.000000",
+ "description": "Slideshow like display for the website",
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "Transaction",
+ "fields": [
+ {
+ "fieldname": "slideshow_name",
+ "fieldtype": "Data",
+ "label": "Slideshow Name",
+ "permlevel": 0,
+ "read_only": 0,
+ "reqd": 1
+ },
+ {
+ "depends_on": "eval:!doc.__islocal",
+ "description": "Note: For best results, images must be of the same size and width must be greater than height.",
+ "fieldname": "sb0",
+ "fieldtype": "Section Break",
+ "label": "Slideshow Items",
+ "permlevel": 0
+ },
+ {
+ "depends_on": "eval:!doc.__islocal",
+ "fieldname": "slideshow_items",
+ "fieldtype": "Table",
+ "label": "Slideshow Items",
+ "options": "Website Slideshow Item",
+ "permlevel": 0
+ },
+ {
+ "depends_on": "eval:!doc.__islocal",
+ "description": "This goes above the slideshow.",
+ "fieldname": "header",
+ "fieldtype": "Text Editor",
+ "label": "Header",
+ "permlevel": 0
+ }
+ ],
+ "icon": "icon-play",
+ "idx": 1,
+ "max_attachments": 10,
+ "modified": "2014-01-20 17:49:35.000000",
+ "modified_by": "Administrator",
+ "module": "Website",
+ "name": "Website Slideshow",
+ "owner": "Administrator",
+ "permissions": [
+ {
+ "cancel": 0,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Website Manager",
+ "submit": 0,
+ "write": 1
+ }
+ ]
+}
\ No newline at end of file
diff --git a/frappe/website/doctype/website_slideshow/website_slideshow.py b/frappe/website/doctype/website_slideshow/website_slideshow.py
index 8f1e859add..d0a3d3ab99 100644
--- a/frappe/website/doctype/website_slideshow/website_slideshow.py
+++ b/frappe/website/doctype/website_slideshow/website_slideshow.py
@@ -6,19 +6,22 @@
from __future__ import unicode_literals
import frappe
-class DocType:
- def __init__(self, d, dl):
- self.doc, self.doclist = d, dl
-
+from frappe.model.document import Document
+
+class WebsiteSlideshow(Document):
+
def on_update(self):
# a slide show can be in use and any change in it should get reflected
from frappe.website.render import clear_cache
clear_cache()
-
-def get_slideshow(bean):
- slideshow = frappe.bean("Website Slideshow", bean.doc.slideshow)
-
+
+def get_slideshow(doc):
+ if not doc.slideshow:
+ return {}
+
+ slideshow = frappe.get_doc("Website Slideshow", doc.slideshow)
+
return {
- "slides": slideshow.doclist.get({"doctype":"Website Slideshow Item"}),
- "slideshow_header": slideshow.doc.header or ""
+ "slides": slideshow.get({"doctype":"Website Slideshow Item"}),
+ "slideshow_header": slideshow.header or ""
}
diff --git a/frappe/website/doctype/website_slideshow/website_slideshow.txt b/frappe/website/doctype/website_slideshow/website_slideshow.txt
deleted file mode 100644
index ee6a074148..0000000000
--- a/frappe/website/doctype/website_slideshow/website_slideshow.txt
+++ /dev/null
@@ -1,85 +0,0 @@
-[
- {
- "creation": "2013-03-07 15:53:15",
- "docstatus": 0,
- "modified": "2014-01-20 17:49:35",
- "modified_by": "Administrator",
- "owner": "Administrator"
- },
- {
- "allow_attach": 1,
- "autoname": "field:slideshow_name",
- "description": "Slideshow like display for the website",
- "doctype": "DocType",
- "document_type": "Transaction",
- "icon": "icon-play",
- "max_attachments": 10,
- "module": "Website",
- "name": "__common__"
- },
- {
- "doctype": "DocField",
- "name": "__common__",
- "parent": "Website Slideshow",
- "parentfield": "fields",
- "parenttype": "DocType",
- "permlevel": 0
- },
- {
- "cancel": 0,
- "create": 1,
- "delete": 1,
- "doctype": "DocPerm",
- "email": 1,
- "name": "__common__",
- "parent": "Website Slideshow",
- "parentfield": "permissions",
- "parenttype": "DocType",
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Website Manager",
- "submit": 0,
- "write": 1
- },
- {
- "doctype": "DocType",
- "name": "Website Slideshow"
- },
- {
- "doctype": "DocField",
- "fieldname": "slideshow_name",
- "fieldtype": "Data",
- "label": "Slideshow Name",
- "read_only": 0,
- "reqd": 1
- },
- {
- "depends_on": "eval:!doc.__islocal",
- "description": "Note: For best results, images must be of the same size and width must be greater than height.",
- "doctype": "DocField",
- "fieldname": "sb0",
- "fieldtype": "Section Break",
- "label": "Slideshow Items"
- },
- {
- "depends_on": "eval:!doc.__islocal",
- "doctype": "DocField",
- "fieldname": "slideshow_items",
- "fieldtype": "Table",
- "label": "Slideshow Items",
- "options": "Website Slideshow Item"
- },
- {
- "depends_on": "eval:!doc.__islocal",
- "description": "This goes above the slideshow.",
- "doctype": "DocField",
- "fieldname": "header",
- "fieldtype": "Text Editor",
- "label": "Header"
- },
- {
- "doctype": "DocPerm"
- }
-]
\ No newline at end of file
diff --git a/frappe/website/doctype/website_slideshow_item/website_slideshow_item.json b/frappe/website/doctype/website_slideshow_item/website_slideshow_item.json
new file mode 100644
index 0000000000..95a9236161
--- /dev/null
+++ b/frappe/website/doctype/website_slideshow_item/website_slideshow_item.json
@@ -0,0 +1,42 @@
+{
+ "allow_attach": 0,
+ "creation": "2013-03-07 12:26:33.000000",
+ "docstatus": 0,
+ "doctype": "DocType",
+ "fields": [
+ {
+ "fieldname": "image",
+ "fieldtype": "Select",
+ "in_list_view": 1,
+ "label": "Image",
+ "options": "attach_files:",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "heading",
+ "fieldtype": "Data",
+ "in_list_view": 1,
+ "label": "Heading",
+ "permlevel": 0,
+ "print_width": "200px",
+ "width": "200px"
+ },
+ {
+ "fieldname": "description",
+ "fieldtype": "Text",
+ "in_list_view": 1,
+ "label": "Description",
+ "permlevel": 0,
+ "print_width": "200px",
+ "width": "200px"
+ }
+ ],
+ "idx": 1,
+ "istable": 1,
+ "max_attachments": 10,
+ "modified": "2013-12-20 19:21:55.000000",
+ "modified_by": "Administrator",
+ "module": "Website",
+ "name": "Website Slideshow Item",
+ "owner": "Administrator"
+}
\ No newline at end of file
diff --git a/frappe/website/doctype/website_slideshow_item/website_slideshow_item.py b/frappe/website/doctype/website_slideshow_item/website_slideshow_item.py
index cb42e2eea2..d782525f4b 100644
--- a/frappe/website/doctype/website_slideshow_item/website_slideshow_item.py
+++ b/frappe/website/doctype/website_slideshow_item/website_slideshow_item.py
@@ -6,6 +6,7 @@
from __future__ import unicode_literals
import frappe
-class DocType:
- def __init__(self, d, dl):
- self.doc, self.doclist = d, dl
\ No newline at end of file
+from frappe.model.document import Document
+
+class WebsiteSlideshowItem(Document):
+ pass
\ No newline at end of file
diff --git a/frappe/website/doctype/website_slideshow_item/website_slideshow_item.txt b/frappe/website/doctype/website_slideshow_item/website_slideshow_item.txt
deleted file mode 100644
index f549c36a1d..0000000000
--- a/frappe/website/doctype/website_slideshow_item/website_slideshow_item.txt
+++ /dev/null
@@ -1,53 +0,0 @@
-[
- {
- "creation": "2013-03-07 12:26:33",
- "docstatus": 0,
- "modified": "2013-12-20 19:21:55",
- "modified_by": "Administrator",
- "owner": "Administrator"
- },
- {
- "allow_attach": 0,
- "doctype": "DocType",
- "istable": 1,
- "max_attachments": 10,
- "module": "Website",
- "name": "__common__"
- },
- {
- "doctype": "DocField",
- "in_list_view": 1,
- "name": "__common__",
- "parent": "Website Slideshow Item",
- "parentfield": "fields",
- "parenttype": "DocType",
- "permlevel": 0
- },
- {
- "doctype": "DocType",
- "name": "Website Slideshow Item"
- },
- {
- "doctype": "DocField",
- "fieldname": "image",
- "fieldtype": "Select",
- "label": "Image",
- "options": "attach_files:"
- },
- {
- "doctype": "DocField",
- "fieldname": "heading",
- "fieldtype": "Data",
- "label": "Heading",
- "print_width": "200px",
- "width": "200px"
- },
- {
- "doctype": "DocField",
- "fieldname": "description",
- "fieldtype": "Text",
- "label": "Description",
- "print_width": "200px",
- "width": "200px"
- }
-]
\ No newline at end of file
diff --git a/frappe/website/doctype/website_template/website_template.json b/frappe/website/doctype/website_template/website_template.json
new file mode 100644
index 0000000000..5461131bc1
--- /dev/null
+++ b/frappe/website/doctype/website_template/website_template.json
@@ -0,0 +1,130 @@
+{
+ "autoname": "field:link_name",
+ "creation": "2013-11-18 15:35:00.000000",
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "System",
+ "fields": [
+ {
+ "fieldname": "page_or_generator",
+ "fieldtype": "Select",
+ "label": "Page or Generator",
+ "options": "Page\nGenerator",
+ "permlevel": 0,
+ "read_only": 1
+ },
+ {
+ "fieldname": "ref_doctype",
+ "fieldtype": "Link",
+ "label": "Ref DocType",
+ "options": "DocType",
+ "permlevel": 0,
+ "read_only": 1
+ },
+ {
+ "fieldname": "link_name",
+ "fieldtype": "Data",
+ "label": "Link Name",
+ "permlevel": 0,
+ "read_only": 1
+ },
+ {
+ "fieldname": "page_title",
+ "fieldtype": "Data",
+ "label": "Page Title",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "base_template_path",
+ "fieldtype": "Data",
+ "label": "Base Template Path",
+ "permlevel": 0,
+ "read_only": 1
+ },
+ {
+ "fieldname": "template_path",
+ "fieldtype": "Data",
+ "label": "Template Path",
+ "permlevel": 0,
+ "read_only": 1
+ },
+ {
+ "fieldname": "controller",
+ "fieldtype": "Data",
+ "label": "Controller",
+ "permlevel": 0,
+ "read_only": 1
+ },
+ {
+ "fieldname": "lastmod",
+ "fieldtype": "Data",
+ "label": "Lastmod",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "no_cache",
+ "fieldtype": "Check",
+ "label": "No Cache",
+ "permlevel": 0,
+ "read_only": 1
+ },
+ {
+ "fieldname": "no_sitemap",
+ "fieldtype": "Check",
+ "label": "No Sitemap",
+ "permlevel": 0,
+ "read_only": 1
+ },
+ {
+ "fieldname": "no_sidebar",
+ "fieldtype": "Check",
+ "label": "No Sidebar",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "page_name_field",
+ "fieldtype": "Data",
+ "label": "Page Name Field",
+ "permlevel": 0,
+ "read_only": 1
+ },
+ {
+ "fieldname": "condition_field",
+ "fieldtype": "Data",
+ "label": "Condition Field",
+ "permlevel": 0,
+ "read_only": 1
+ },
+ {
+ "fieldname": "sort_by",
+ "fieldtype": "Data",
+ "label": "Sort By",
+ "permlevel": 0
+ },
+ {
+ "fieldname": "sort_order",
+ "fieldtype": "Data",
+ "label": "Sort Order",
+ "permlevel": 0
+ }
+ ],
+ "idx": 1,
+ "modified": "2014-02-24 12:47:44.000000",
+ "modified_by": "Administrator",
+ "module": "Website",
+ "name": "Website Template",
+ "owner": "Administrator",
+ "permissions": [
+ {
+ "cancel": 0,
+ "create": 0,
+ "delete": 1,
+ "export": 0,
+ "permlevel": 0,
+ "read": 1,
+ "report": 1,
+ "role": "System Manager",
+ "write": 0
+ }
+ ]
+}
\ No newline at end of file
diff --git a/frappe/website/doctype/website_template/website_template.py b/frappe/website/doctype/website_template/website_template.py
index c9a8f2af94..2f0357a23a 100644
--- a/frappe/website/doctype/website_template/website_template.py
+++ b/frappe/website/doctype/website_template/website_template.py
@@ -11,18 +11,18 @@ from frappe import _
from frappe.website.doctype.website_route.website_route import add_to_sitemap, update_sitemap, cleanup_sitemap
from frappe.utils.nestedset import rebuild_tree
-class DocType:
- def __init__(self, d, dl):
- self.doc, self.doclist = d, dl
+from frappe.model.document import Document
+
+class WebsiteTemplate(Document):
def after_insert(self):
- if self.doc.page_or_generator == "Page":
+ if self.page_or_generator == "Page":
website_route = frappe.db.get_value("Website Route",
- {"website_template": self.doc.name, "page_or_generator": "Page"})
+ {"website_template": self.name, "page_or_generator": "Page"})
- opts = self.doc.fields.copy()
+ opts = self.as_dict()
opts.update({"public_read": 1})
-
+
if website_route:
update_sitemap(website_route, opts)
else:
@@ -30,20 +30,20 @@ class DocType:
else:
condition = ""
- if self.doc.condition_field:
- condition = " where ifnull(%s, 0)=1" % self.doc.condition_field
+ if self.condition_field:
+ condition = " where ifnull(%s, 0)=1" % self.condition_field
for name in frappe.db.sql_list("""select name from `tab{doctype}`
{condition} order by idx asc, {sort_field} {sort_order}""".format(
- doctype = self.doc.ref_doctype,
+ doctype = self.ref_doctype,
condition = condition,
- sort_field = self.doc.sort_field or "name",
- sort_order = self.doc.sort_order or "asc"
+ sort_field = getattr(self, "sort_field", "name"),
+ sort_order = getattr(self, "sort_order", "asc")
)):
- bean = frappe.bean(self.doc.ref_doctype, name)
+ doc = frappe.get_doc(self.ref_doctype, name)
# regenerate route
- bean.run_method("on_update")
+ doc.run_method("on_update")
def rebuild_website_template():
# TODO
@@ -127,7 +127,7 @@ def add_website_template(page_or_generator, app, path, fname, app_path):
# found by earlier app, override
frappe.db.sql("""delete from `tabWebsite Template` where name=%s""", (wsc.link_name,))
- frappe.bean(wsc).insert()
+ frappe.get_doc(wsc).insert()
return name
diff --git a/frappe/website/doctype/website_template/website_template.txt b/frappe/website/doctype/website_template/website_template.txt
deleted file mode 100644
index f7f9d545d5..0000000000
--- a/frappe/website/doctype/website_template/website_template.txt
+++ /dev/null
@@ -1,149 +0,0 @@
-[
- {
- "creation": "2013-11-18 15:35:00",
- "docstatus": 0,
- "modified": "2014-02-24 12:47:44",
- "modified_by": "Administrator",
- "owner": "Administrator"
- },
- {
- "autoname": "field:link_name",
- "doctype": "DocType",
- "document_type": "System",
- "module": "Website",
- "name": "__common__"
- },
- {
- "doctype": "DocField",
- "name": "__common__",
- "parent": "Website Template",
- "parentfield": "fields",
- "parenttype": "DocType",
- "permlevel": 0
- },
- {
- "cancel": 0,
- "create": 0,
- "delete": 1,
- "doctype": "DocPerm",
- "export": 0,
- "name": "__common__",
- "parent": "Website Template",
- "parentfield": "permissions",
- "parenttype": "DocType",
- "permlevel": 0,
- "read": 1,
- "report": 1,
- "role": "System Manager",
- "write": 0
- },
- {
- "doctype": "DocType",
- "name": "Website Template"
- },
- {
- "doctype": "DocField",
- "fieldname": "page_or_generator",
- "fieldtype": "Select",
- "label": "Page or Generator",
- "options": "Page\nGenerator",
- "read_only": 1
- },
- {
- "doctype": "DocField",
- "fieldname": "ref_doctype",
- "fieldtype": "Link",
- "label": "Ref DocType",
- "options": "DocType",
- "read_only": 1
- },
- {
- "doctype": "DocField",
- "fieldname": "link_name",
- "fieldtype": "Data",
- "label": "Link Name",
- "read_only": 1
- },
- {
- "doctype": "DocField",
- "fieldname": "page_title",
- "fieldtype": "Data",
- "label": "Page Title"
- },
- {
- "doctype": "DocField",
- "fieldname": "base_template_path",
- "fieldtype": "Data",
- "label": "Base Template Path",
- "read_only": 1
- },
- {
- "doctype": "DocField",
- "fieldname": "template_path",
- "fieldtype": "Data",
- "label": "Template Path",
- "read_only": 1
- },
- {
- "doctype": "DocField",
- "fieldname": "controller",
- "fieldtype": "Data",
- "label": "Controller",
- "read_only": 1
- },
- {
- "doctype": "DocField",
- "fieldname": "lastmod",
- "fieldtype": "Data",
- "label": "Lastmod"
- },
- {
- "doctype": "DocField",
- "fieldname": "no_cache",
- "fieldtype": "Check",
- "label": "No Cache",
- "read_only": 1
- },
- {
- "doctype": "DocField",
- "fieldname": "no_sitemap",
- "fieldtype": "Check",
- "label": "No Sitemap",
- "read_only": 1
- },
- {
- "doctype": "DocField",
- "fieldname": "no_sidebar",
- "fieldtype": "Check",
- "label": "No Sidebar"
- },
- {
- "doctype": "DocField",
- "fieldname": "page_name_field",
- "fieldtype": "Data",
- "label": "Page Name Field",
- "read_only": 1
- },
- {
- "doctype": "DocField",
- "fieldname": "condition_field",
- "fieldtype": "Data",
- "label": "Condition Field",
- "read_only": 1
- },
- {
- "doctype": "DocField",
- "fieldname": "sort_by",
- "fieldtype": "Data",
- "label": "Sort By"
- },
- {
- "doctype": "DocField",
- "fieldname": "sort_order",
- "fieldtype": "Data",
- "label": "Sort Order"
- },
- {
- "doctype": "DocPerm"
- }
-]
\ No newline at end of file
diff --git a/frappe/website/page/sitemap_browser/sitemap_browser.json b/frappe/website/page/sitemap_browser/sitemap_browser.json
new file mode 100644
index 0000000000..4cbbdf9bb6
--- /dev/null
+++ b/frappe/website/page/sitemap_browser/sitemap_browser.json
@@ -0,0 +1,23 @@
+{
+ "creation": "2014-02-18 10:47:22.000000",
+ "docstatus": 0,
+ "doctype": "Page",
+ "icon": "icon-sitemap",
+ "idx": 1,
+ "modified": "2014-02-18 10:47:22.000000",
+ "modified_by": "Administrator",
+ "module": "Website",
+ "name": "sitemap-browser",
+ "owner": "Administrator",
+ "page_name": "sitemap-browser",
+ "roles": [
+ {
+ "role": "Website Manager"
+ },
+ {
+ "role": "System Manager"
+ }
+ ],
+ "standard": "Yes",
+ "title": "Sitemap Browser"
+}
\ No newline at end of file
diff --git a/frappe/website/page/sitemap_browser/sitemap_browser.py b/frappe/website/page/sitemap_browser/sitemap_browser.py
index 9538f9e1b2..66aabafbda 100644
--- a/frappe/website/page/sitemap_browser/sitemap_browser.py
+++ b/frappe/website/page/sitemap_browser/sitemap_browser.py
@@ -24,10 +24,10 @@ def move(name, up_or_down):
if not frappe.has_permission("Website Route"):
raise frappe.PermissionError
- sitemap = frappe.doc("Website Route", name)
+ sitemap = frappe.get_doc("Website Route", name)
if up_or_down=="up":
if sitemap.idx > 0:
- prev = frappe.doc("Website Route", {
+ prev = frappe.get_doc("Website Route", {
"parent_website_route": sitemap.parent_website_route,
"idx": sitemap.idx - 1
})
@@ -40,7 +40,7 @@ def move(name, up_or_down):
ret = "ok"
else:
- nexts = frappe.doc("Website Route", {
+ nexts = frappe.get_doc("Website Route", {
"parent_website_route": sitemap.parent_website_route,
"idx": sitemap.idx + 1
})
@@ -60,13 +60,13 @@ def update_parent(name, new_parent):
if not frappe.has_permission("Website Route"):
raise frappe.PermissionError
- sitemap = frappe.doc("Website Route", name)
+ sitemap = frappe.get_doc("Website Route", name)
if sitemap.ref_doctype:
- generator = frappe.bean(sitemap.ref_doctype, sitemap.docname)
- if not generator.meta.has_field("parent_website_route"):
+ generator = frappe.get_doc(sitemap.ref_doctype, sitemap.docname)
+ if not generator.meta.get_field("parent_website_route"):
frappe.throw("Does not allow moving.")
- generator.doc.parent_website_route = new_parent
+ generator.parent_website_route = new_parent
generator.save()
else:
frappe.msgprint("Template Pages cannot be moved.")
diff --git a/frappe/website/page/sitemap_browser/sitemap_browser.txt b/frappe/website/page/sitemap_browser/sitemap_browser.txt
deleted file mode 100644
index 00d46e2f2a..0000000000
--- a/frappe/website/page/sitemap_browser/sitemap_browser.txt
+++ /dev/null
@@ -1,37 +0,0 @@
-[
- {
- "creation": "2014-02-18 10:47:22",
- "docstatus": 0,
- "modified": "2014-02-18 10:47:22",
- "modified_by": "Administrator",
- "owner": "Administrator"
- },
- {
- "doctype": "Page",
- "icon": "icon-sitemap",
- "module": "Website",
- "name": "__common__",
- "page_name": "sitemap-browser",
- "standard": "Yes",
- "title": "Sitemap Browser"
- },
- {
- "doctype": "Page Role",
- "name": "__common__",
- "parent": "sitemap-browser",
- "parentfield": "roles",
- "parenttype": "Page"
- },
- {
- "doctype": "Page",
- "name": "sitemap-browser"
- },
- {
- "doctype": "Page Role",
- "role": "Website Manager"
- },
- {
- "doctype": "Page Role",
- "role": "System Manager"
- }
-]
\ No newline at end of file
diff --git a/frappe/website/render.py b/frappe/website/render.py
index 8f2aa75648..9329edd131 100644
--- a/frappe/website/render.py
+++ b/frappe/website/render.py
@@ -111,8 +111,10 @@ def set_content_type(response, data, path):
response.headers["Content-Type"] = "text/html; charset: utf-8"
- if "." in path and not path.endswith(".html"):
+ if "." in path:
content_type, encoding = mimetypes.guess_type(path)
+ if not content_type:
+ raise frappe.UnsupportedMediaType("Cannot determine content type of {}".format(path))
response.headers["Content-Type"] = content_type.encode("utf-8")
return data
diff --git a/frappe/website/sitemap.py b/frappe/website/sitemap.py
index f401dfedc8..b4fbb58407 100644
--- a/frappe/website/sitemap.py
+++ b/frappe/website/sitemap.py
@@ -17,63 +17,67 @@ def get_sitemap_options(path):
sitemap_options = build_sitemap_options(path)
if can_cache(sitemap_options.no_cache):
frappe.cache().set_value(cache_key, sitemap_options)
-
+
return frappe._dict(sitemap_options)
-
+
def build_sitemap_options(path):
- sitemap_options = frappe._dict(frappe.doc("Website Route", path).fields)
+ sitemap_options = frappe._dict(frappe.get_doc("Website Route", path).as_dict())
home_page = get_home_page()
-
- sitemap_config = frappe.doc("Website Template",
- sitemap_options.get("website_template")).fields
-
+
+ sitemap_config = frappe.get_doc("Website Template",
+ sitemap_options.get("website_template")).as_dict()
+
# get sitemap config fields too
- for fieldname in ("base_template_path", "template_path", "controller",
+ for fieldname in ("base_template_path", "template_path", "controller",
"no_cache", "no_sitemap", "page_name_field", "condition_field"):
sitemap_options[fieldname] = sitemap_config.get(fieldname)
-
+
sitemap_options.doctype = sitemap_options.ref_doctype
sitemap_options.title = sitemap_options.page_title
sitemap_options.pathname = sitemap_options.name
-
+
# establish hierarchy
sitemap_options.parents = frappe.db.sql("""select name, page_title from `tabWebsite Route`
where lft < %s and rgt > %s order by lft asc""", (sitemap_options.lft, sitemap_options.rgt), as_dict=True)
if not sitemap_options.no_sidebar:
- set_sidebar_items(sitemap_options, sitemap_options.pathname, home_page)
+ sitemap_options.children = get_route_children(sitemap_options.pathname, home_page)
if not sitemap_options.children:
- set_sidebar_items(sitemap_options, sitemap_options.parent_website_route, home_page)
+ sitemap_options.children = get_route_children(sitemap_options.parent_website_route, home_page)
# determine templates to be used
if not sitemap_options.base_template_path:
app_base = frappe.get_hooks("base_template")
sitemap_options.base_template_path = app_base[0] if app_base else "templates/base.html"
-
+
return sitemap_options
-def set_sidebar_items(sitemap_options, pathname, home_page):
+def get_route_children(pathname, home_page=None):
+ if not home_page:
+ home_page = get_home_page()
+
if pathname==home_page or not pathname:
- sitemap_options.children = frappe.db.sql("""select url as name, label as page_title,
+ children = frappe.db.sql("""select url as name, label as page_title,
1 as public_read from `tabTop Bar Item` where parentfield='sidebar_items' order by idx""",
as_dict=True)
- else:
- sitemap_options.children = frappe.db.sql("""select * from `tabWebsite Route`
- where ifnull(parent_website_route,'')=%s
- and public_read=1
+ else:
+ children = frappe.db.sql("""select * from `tabWebsite Route`
+ where ifnull(parent_website_route,'')=%s
+ and public_read=1
order by idx, page_title asc""", pathname, as_dict=True)
-
- if sitemap_options.children:
+
+ if children:
# if children are from generator and sort order is specified, then get that condition
- website_template = frappe.doc("Website Template", sitemap_options.children[0].website_template)
+ website_template = frappe.get_doc("Website Template", children[0].website_template)
if website_template.sort_by!="name":
- sitemap_options.children = frappe.db.sql("""select t1.* from
+ children = frappe.db.sql("""select t1.* from
`tabWebsite Route` t1, `tab{ref_doctype}` t2
- where ifnull(t1.parent_website_route,'')=%s
- and t1.public_read=1
+ where ifnull(t1.parent_website_route,'')=%s
+ and t1.public_read=1
and t1.docname = t2.name
- order by t2.{sort_by} {sort_order}""".format(**website_template.fields),
+ order by t2.{sort_by} {sort_order}""".format(**website_template.as_dict()),
pathname, as_dict=True)
-
- sitemap_options.children = [frappe.doc("Website Route", pathname).fields] + sitemap_options.children
-
+
+ children = [frappe.get_doc("Website Route", pathname)] + children
+
+ return children
diff --git a/frappe/website/statics.py b/frappe/website/statics.py
index f467fe18f6..b7c1748153 100644
--- a/frappe/website/statics.py
+++ b/frappe/website/statics.py
@@ -7,6 +7,7 @@ import frappe, os, time
from frappe import _
from frappe.utils import cint
from markdown2 import markdown
+from frappe.website.sitemap import get_route_children
def sync_statics():
s = sync()
@@ -23,33 +24,33 @@ class sync(object):
self.sync_for_app(app)
self.cleanup()
-
+
if self.updated:
print str(self.updated) + " files updated"
-
+
def sync_for_app(self, app):
self.statics_path = frappe.get_app_path(app, "templates", "statics")
if os.path.exists(self.statics_path):
for basepath, folders, files in os.walk(self.statics_path):
self.sync_folder(basepath, folders, files)
-
+
def sync_folder(self, basepath, folders, files):
folder_route = os.path.relpath(basepath, self.statics_path)
self.get_index_txt(basepath, files)
self.sync_index_page(basepath, files)
-
- if not frappe.db.exists("Website Route", folder_route) and basepath!=self.statics_path:
+
+ if not frappe.db.exists("Website Route", folder_route) and basepath!=self.statics_path:
# not synced either by generator or by index.html
return
-
+
if self.index:
self.sync_using_given_index(basepath, folders, files)
-
+
else:
self.sync_alphabetically(basepath, folders, files)
-
-
+
+
def get_index_txt(self, basepath, files):
self.index = []
if "index.txt" in files:
@@ -62,7 +63,7 @@ class sync(object):
if fname in files:
self.sync_file(fname, os.path.join(basepath, fname), None)
return
-
+
def sync_using_given_index(self, basepath, folders, files):
for i, page_name in enumerate(self.index):
if page_name in folders:
@@ -88,22 +89,22 @@ class sync(object):
page_name = fname.rsplit(".", 1)[0]
if not (page_name=="index" and basepath!=self.statics_path):
self.sync_file(fname, os.path.join(basepath, fname), None)
-
+
def sync_file(self, fname, fpath, priority):
route = os.path.relpath(fpath, self.statics_path).rsplit(".", 1)[0]
if fname.rsplit(".", 1)[0]=="index" and os.path.dirname(fpath) != self.statics_path:
route = os.path.dirname(route)
-
+
if route in self.synced:
return
-
+
parent_website_route = os.path.dirname(route)
page_name = os.path.basename(route)
-
- route_details = frappe.db.get_value("Website Route", route,
+
+ route_details = frappe.db.get_value("Website Route", route,
["name", "idx", "static_file_timestamp", "docname"], as_dict=True)
-
+
if route_details:
self.update_web_page(route_details, fpath, priority, parent_website_route)
else:
@@ -111,72 +112,72 @@ class sync(object):
self.insert_web_page(route, fpath, page_name, priority, parent_website_route)
def insert_web_page(self, route, fpath, page_name, priority, parent_website_route):
- page = frappe.bean({
+ page = frappe.get_doc({
"doctype":"Web Page",
"idx": priority,
"page_name": page_name,
"published": 1,
"parent_website_route": parent_website_route
})
-
- page.doc.fields.update(get_static_content(fpath, page_name))
+
+ page.update(get_static_content(fpath, page_name, route))
try:
page.insert()
except NameError:
# page exists, if deleted static, delete it and try again
- old_route = frappe.doc("Website Route", {"ref_doctype":"Web Page",
- "docname": page.doc.name})
- if old_route.static_file_timestamp and not os.path.exists(os.path.join(self.statics_path,
+ old_route = frappe.get_doc("Website Route", {"ref_doctype":"Web Page",
+ "docname": page.name})
+ if old_route.static_file_timestamp and not os.path.exists(os.path.join(self.statics_path,
old_route.name)):
-
- frappe.delete_doc("Web Page", page.doc.name)
+
+ frappe.delete_doc("Web Page", page.name)
page.insert() # retry
-
-
+
+
# update timestamp
- route_bean = frappe.bean("Website Route", {"ref_doctype": "Web Page",
- "docname": page.doc.name})
- route_bean.doc.static_file_timestamp = cint(os.path.getmtime(fpath))
- route_bean.save()
+ route_doc = frappe.get_doc("Website Route", {"ref_doctype": "Web Page",
+ "docname": page.name})
+ route_doc.static_file_timestamp = cint(os.path.getmtime(fpath))
+ route_doc.save()
self.updated += 1
- print route_bean.doc.name + " inserted"
+ print route_doc.name + " inserted"
self.synced.append(route)
-
- def update_web_page(self, route_details, fpath, priority, parent_website_route):
+
+ def update_web_page(self, route_details, fpath, priority, parent_website_route):
if str(cint(os.path.getmtime(fpath)))!= route_details.static_file_timestamp \
or (cint(route_details.idx) != cint(priority) and (priority is not None)):
- page = frappe.bean("Web Page", route_details.docname)
- page.doc.fields.update(get_static_content(fpath, route_details.docname))
- page.doc.idx = priority
+ page = frappe.get_doc("Web Page", route_details.docname)
+ page.update(get_static_content(fpath, route_details.docname, route_details.name))
+ page.idx = priority
page.save()
- route_bean = frappe.bean("Website Route", route_details.name)
- route_bean.doc.static_file_timestamp = cint(os.path.getmtime(fpath))
- route_bean.save()
+ route_doc = frappe.get_doc("Website Route", route_details.name)
+ route_doc.static_file_timestamp = cint(os.path.getmtime(fpath))
+ route_doc.save()
- print route_bean.doc.name + " updated"
+ print route_doc.name + " updated"
self.updated += 1
-
+
self.synced.append(route_details.name)
def cleanup(self):
if self.synced:
- frappe.delete_doc("Web Page", frappe.db.sql_list("""select docname
+ frappe.delete_doc("Web Page", frappe.db.sql_list("""select docname
from `tabWebsite Route`
- where ifnull(static_file_timestamp,'')!='' and name not in ({})
- order by (rgt-lft) asc""".format(', '.join(["%s"]*len(self.synced))),
+ where ifnull(static_file_timestamp,'')!='' and name not in ({})
+ order by (rgt-lft) asc""".format(', '.join(["%s"]*len(self.synced))),
tuple(self.synced)))
else:
- frappe.delete_doc("Web Page", frappe.db.sql_list("""select docname
+ frappe.delete_doc("Web Page", frappe.db.sql_list("""select docname
from `tabWebsite Route`
- where ifnull(static_file_timestamp,'')!=''
+ where ifnull(static_file_timestamp,'')!=''
order by (rgt-lft) asc"""))
-def get_static_content(fpath, docname):
+def get_static_content(fpath, docname, route):
d = frappe._dict({})
with open(fpath, "r") as contentfile:
content = unicode(contentfile.read(), 'utf-8')
@@ -190,8 +191,14 @@ def get_static_content(fpath, docname):
d.title = first_line[2:]
content = "\n".join(lines[1:])
+ if "{index}" in content:
+ children = get_route_children(route)
+ html = frappe.get_template("templates/includes/static_index.html").render({
+ "items":children})
+ content = content.replace("{index}", html)
+
content = markdown(content)
-
+
d.main_section = unicode(content.encode("utf-8"), 'utf-8')
if not d.title:
d.title = docname.replace("-", " ").replace("_", " ").title()
@@ -201,8 +208,8 @@ def get_static_content(fpath, docname):
if os.path.exists(fpath):
with open(fpath, "r") as f:
d["css" if extn=="css" else "javascript"] = f.read()
-
+
d.insert_style = 1 if d.css else 0
d.insert_code = 1 if d.javascript else 0
-
+
return d
diff --git a/frappe/website/template.py b/frappe/website/template.py
index 1e6ca86630..f9a3dd42c1 100644
--- a/frappe/website/template.py
+++ b/frappe/website/template.py
@@ -14,44 +14,44 @@ def render_blocks(context):
"""returns a dict of block name and its rendered content"""
out = {}
-
+
env = frappe.get_jenv()
-
+
def _render_blocks(template_path):
source = frappe.local.jloader.get_source(frappe.local.jenv, template_path)[0]
for referenced_template_path in meta.find_referenced_templates(env.parse(source)):
if referenced_template_path:
_render_blocks(referenced_template_path)
-
+
template = frappe.get_template(template_path)
for block, render in template.blocks.items():
out[block] = scrub_relative_urls(concat(render(template.new_context(context))))
-
+
_render_blocks(context["template_path"])
# default blocks if not found
if "title" not in out and out.get("header"):
out["title"] = out["header"]
-
+
if "title" not in out:
out["title"] = context.get("title")
-
+
if "header" not in out and out.get("title"):
out["header"] = out["title"]
if not out["header"].startswith("
" + out["header"] + ""
-
+
if "breadcrumbs" not in out:
out["breadcrumbs"] = scrub_relative_urls(
frappe.get_template("templates/includes/breadcrumbs.html").render(context))
-
- if "sidebar" not in out:
+
+ if "sidebar" not in out and not context.get("no_sidebar"):
out["sidebar"] = scrub_relative_urls(
frappe.get_template("templates/includes/sidebar.html").render(context))
-
+
out["title"] = strip_html(out.get("title") or "")
-
+
# remove style and script tags from blocks
out["style"] = re.sub("?style[^<>]*>", "", out.get("style") or "")
out["script"] = re.sub("?script[^<>]*>", "", out.get("script") or "")
diff --git a/frappe/website/website_generator.py b/frappe/website/website_generator.py
index 403d8cc973..b93c9616a8 100644
--- a/frappe/website/website_generator.py
+++ b/frappe/website/website_generator.py
@@ -4,82 +4,92 @@
from __future__ import unicode_literals
import frappe
from frappe.model.controller import DocListController
+from frappe.model.naming import append_number_if_name_exists
from frappe.website.utils import cleanup_page_name
from frappe.utils import now
from frappe.website.doctype.website_route.website_route import add_to_sitemap, update_sitemap, remove_sitemap
-def call_website_generator(bean, method, *args, **kwargs):
- getattr(WebsiteGenerator(bean.doc, bean.doclist), method)(*args, **kwargs)
-
class WebsiteGenerator(DocListController):
def autoname(self):
- self.doc.name = self.get_page_name()
- self.doc.append_number_if_name_exists()
+ self.setup_generator()
+ if not self.website_template: return
+
+ self.name = self.get_page_name()
+ append_number_if_name_exists(self)
def set_page_name(self):
"""set page name based on parent page_name and title"""
page_name = cleanup_page_name(self.get_page_title())
- if self.doc.is_new():
- self.doc.fields[self.website_template.page_name_field] = page_name
+ if self.is_new():
+ self.set(self.website_template.page_name_field, page_name)
else:
- frappe.db.set(self.doc, self.website_template.page_name_field, page_name)
-
+ frappe.db.set(self, self.website_template.page_name_field, page_name)
+
return page_name
def get_parent_website_route(self):
- return self.doc.parent_website_route
+ return self.parent_website_route
def setup_generator(self):
if not hasattr(self, "website_template"):
- self.website_template = frappe.db.get_values("Website Template",
- {"ref_doctype": self.doc.doctype}, "*")[0]
+ website_template = frappe.db.get_values("Website Template",
+ {"ref_doctype": self.doctype}, "*")
+ if website_template:
+ self.website_template = website_template[0]
+ else:
+ self.website_template = None
def on_update(self):
self.update_sitemap()
if getattr(self, "save_versions", False):
- frappe.add_version(self.doclist)
-
+ frappe.add_version(self)
+
def after_rename(self, olddn, newdn, merge):
+ self.setup_generator()
+ if not self.website_template: return
+
frappe.db.sql("""update `tabWebsite Route`
- set docname=%s where ref_doctype=%s and docname=%s""", (newdn, self.doc.doctype, olddn))
-
+ set docname=%s where ref_doctype=%s and docname=%s""", (newdn, self.doctype, olddn))
+
if merge:
- self.setup_generator()
- remove_sitemap(ref_doctype=self.doc.doctype, docname=olddn)
-
+ remove_sitemap(ref_doctype=self.doctype, docname=olddn)
+
def on_trash(self):
self.setup_generator()
- remove_sitemap(ref_doctype=self.doc.doctype, docname=self.doc.name)
-
+ if not self.website_template: return
+
+ remove_sitemap(ref_doctype=self.doctype, docname=self.name)
+
def update_sitemap(self):
self.setup_generator()
-
+ if not self.website_template: return
+
if self.website_template.condition_field and \
- not self.doc.fields.get(self.website_template.condition_field):
+ not self.get(self.website_template.condition_field):
# condition field failed, remove and return!
- remove_sitemap(ref_doctype=self.doc.doctype, docname=self.doc.name)
+ remove_sitemap(ref_doctype=self.doctype, docname=self.name)
return
-
+
self.add_or_update_sitemap()
-
+
def add_or_update_sitemap(self):
page_name = self.get_page_name()
-
- existing_site_map = frappe.db.get_value("Website Route", {"ref_doctype": self.doc.doctype,
- "docname": self.doc.name})
-
- if self.doc.modified:
- lastmod = frappe.utils.get_datetime(self.doc.modified).strftime("%Y-%m-%d")
+
+ existing_site_map = frappe.db.get_value("Website Route", {"ref_doctype": self.doctype,
+ "docname": self.name})
+
+ if self.modified:
+ lastmod = frappe.utils.get_datetime(self.modified).strftime("%Y-%m-%d")
else:
lastmod = now()
-
+
opts = frappe._dict({
"page_or_generator": "Generator",
- "ref_doctype":self.doc.doctype,
- "idx": self.doc.idx,
- "docname": self.doc.name,
+ "ref_doctype":self.doctype,
+ "idx": self.idx,
+ "docname": self.name,
"page_name": page_name,
"link_name": self.website_template.name,
"lastmod": lastmod,
@@ -89,35 +99,34 @@ class WebsiteGenerator(DocListController):
})
self.update_permissions(opts)
-
+
if existing_site_map:
idx = update_sitemap(existing_site_map, opts)
else:
idx = add_to_sitemap(opts)
- if idx!=None and self.doc.idx != idx:
- frappe.db.set(self.doc, "idx", idx)
-
+ if idx!=None and self.idx != idx:
+ frappe.db.set(self, "idx", idx)
+
def update_permissions(self, opts):
if self.meta.get_field("public_read"):
- opts.public_read = self.doc.public_read
- opts.public_write = self.doc.public_write
+ opts.public_read = self.public_read
+ opts.public_write = self.public_write
else:
opts.public_read = 1
-
+
def get_page_name(self):
page_name = self._get_page_name()
if not page_name:
page_name = self.set_page_name()
-
+
return self._get_page_name()
-
+
def _get_page_name(self):
- self.setup_generator()
- if self.meta.has_field(self.website_template.page_name_field):
- return self.doc.fields.get(self.website_template.page_name_field)
+ if self.meta.get_field(self.website_template.page_name_field):
+ return self.get(self.website_template.page_name_field)
else:
return cleanup_page_name(self.get_page_title())
-
+
def get_page_title(self):
- return self.doc.title or (self.doc.name.replace("-", " ").replace("_", " ").title())
+ return self.get("title") or (self.name.replace("-", " ").replace("_", " ").title())
diff --git a/frappe/widgets/calendar.py b/frappe/widgets/calendar.py
index 4bc7ef4848..8cc8c27a3c 100644
--- a/frappe/widgets/calendar.py
+++ b/frappe/widgets/calendar.py
@@ -11,8 +11,8 @@ import json
def update_event(args, field_map):
args = frappe._dict(json.loads(args))
field_map = frappe._dict(json.loads(field_map))
- w = frappe.bean(args.doctype, args.name)
- w.doc.fields[field_map.start] = args[field_map.start]
- w.doc.fields[field_map.end] = args[field_map.end]
+ w = frappe.get_doc(args.doctype, args.name)
+ w.set(field_map.start, args[field_map.start])
+ w.set(field_map.end, args[field_map.end])
w.save()
diff --git a/frappe/widgets/event.py b/frappe/widgets/event.py
index 5239846ef4..68c2f2ebb6 100644
--- a/frappe/widgets/event.py
+++ b/frappe/widgets/event.py
@@ -7,9 +7,7 @@ from __future__ import unicode_literals
import frappe
@frappe.whitelist()
-def get_cal_events(m_st, m_end):
- import frappe.model.doc
-
+def get_cal_events(m_st, m_end):
# load owned events
res1 = frappe.db.sql("""select name from `tabEvent`
WHERE ifnull(event_date,'2000-01-01') between %s and %s and owner = %s
@@ -39,7 +37,7 @@ def get_cal_events(m_st, m_end):
doclist, rl = [], []
for r in res1 + res2 + res3 + res4:
if not r in rl:
- doclist += frappe.model.doc.get('Event', r[0])
+ doclist += frappe.get_doc('Event', r[0])
rl.append(r)
return doclist
diff --git a/frappe/widgets/form/assign_to.py b/frappe/widgets/form/assign_to.py
index 51f60e0fae..3617649bc2 100644
--- a/frappe/widgets/form/assign_to.py
+++ b/frappe/widgets/form/assign_to.py
@@ -34,7 +34,7 @@ def add(args=None):
else:
from frappe.utils import nowdate
- d = frappe.bean({
+ d = frappe.get_doc({
"doctype":"ToDo",
"owner": args['assign_to'],
"reference_type": args['doctype'],
@@ -44,11 +44,10 @@ def add(args=None):
"status": "Open",
"date": args.get('date', nowdate()),
"assigned_by": args.get('assigned_by', frappe.user.name),
- }).insert(ignore_permissions=True).doc
+ }).insert(ignore_permissions=True)
# set assigned_to if field exists
- from frappe.model.meta import has_field
- if has_field(args['doctype'], "assigned_to"):
+ if frappe.get_meta(args['doctype']).get_field("assigned_to"):
frappe.db.set_value(args['doctype'], args['name'], "assigned_to", args['assign_to'])
try:
@@ -64,31 +63,21 @@ def add(args=None):
# notify
if not args.get("no_notification"):
notify_assignment(d.assigned_by, d.owner, d.reference_type, d.reference_name, action='ASSIGN', description=args.get("description"), notify=args.get('notify'))
-
- # update feeed
- try:
- from erpnext.home import make_feed
- from frappe.utils import get_fullname
- make_feed('Assignment', d.reference_type, d.reference_name, frappe.session['user'],
- '[%s] Assigned to %s' % (d.priority, get_fullname(d.owner)), '#C78F58')
- except ImportError, e:
- pass
-
+
return get(args)
@frappe.whitelist()
def remove(doctype, name, assign_to):
"""remove from todo"""
- todo = frappe.bean("ToDo", {"reference_type":doctype, "reference_name":name, "owner":assign_to, "status":"Open"})
- todo.doc.status = "Closed"
+ todo = frappe.get_doc("ToDo", {"reference_type":doctype, "reference_name":name, "owner":assign_to, "status":"Open"})
+ todo.status = "Closed"
todo.save(ignore_permissions=True)
# clear assigned_to if field exists
- from frappe.model.meta import has_field
- if has_field(doctype, "assigned_to"):
+ if frappe.get_meta(doctype).get_field("assigned_to"):
frappe.db.set_value(doctype, name, "assigned_to", None)
- notify_assignment(todo.doc.assigned_by, todo.doc.owner, todo.doc.reference_type, todo.doc.reference_name)
+ notify_assignment(todo.assigned_by, todo.owner, todo.reference_type, todo.reference_name)
return get({"doctype": doctype, "name": name})
diff --git a/frappe/widgets/form/load.py b/frappe/widgets/form/load.py
index 672d9f6206..2e26d43ad2 100644
--- a/frappe/widgets/form/load.py
+++ b/frappe/widgets/form/load.py
@@ -3,8 +3,10 @@
from __future__ import unicode_literals
import frappe, json
-import frappe.model.doc
import frappe.utils
+import frappe.defaults
+import frappe.widgets.form.meta
+from frappe.utils.file_manager import get_file_url
@frappe.whitelist()
def getdoc(doctype, name, user=None):
@@ -13,8 +15,6 @@ def getdoc(doctype, name, user=None):
Requries "doctype", "name" as form variables.
Will also call the "onload" method on the document.
"""
-
- import frappe
if not (doctype and name):
raise Exception, 'doctype and name required!'
@@ -26,14 +26,12 @@ def getdoc(doctype, name, user=None):
return []
try:
- bean = frappe.bean(doctype, name)
- bean.run_method("onload")
+ doc = frappe.get_doc(doctype, name)
+ doc.run_method("onload")
- if not bean.has_read_perm():
+ if not doc.has_permission("read"):
raise frappe.PermissionError
- doclist = bean.doclist
-
# add file list
get_docinfo(doctype, name)
@@ -42,35 +40,39 @@ def getdoc(doctype, name, user=None):
frappe.msgprint('Did not load.')
raise
- if bean and not name.startswith('_'):
+ if doc and not name.startswith('_'):
frappe.user.update_recent(doctype, name)
- frappe.response['docs'] = doclist
+ frappe.response.docs.append(doc)
@frappe.whitelist()
def getdoctype(doctype, with_parent=False, cached_timestamp=None):
"""load doctype"""
- import frappe.model.doctype
- import frappe.model.meta
-
- doclist = []
+ docs = []
# with parent (called from report builder)
if with_parent:
parent_dt = frappe.model.meta.get_parent_dt(doctype)
if parent_dt:
- doclist = frappe.model.doctype.get(parent_dt, processed=True)
+ docs = get_meta_bundle(parent_dt)
frappe.response['parent_dt'] = parent_dt
- if not doclist:
- doclist = frappe.model.doctype.get(doctype, processed=True)
+ if not docs:
+ docs = get_meta_bundle(doctype)
- frappe.response['restrictions'] = get_restrictions(doclist)
+ frappe.response['restrictions'] = get_restrictions(docs[0])
- if cached_timestamp and doclist[0].modified==cached_timestamp:
+ if cached_timestamp and docs[0].modified==cached_timestamp:
return "use_cache"
- frappe.response['docs'] = doclist
+ frappe.response.docs.extend(docs)
+
+def get_meta_bundle(doctype):
+ bundle = [frappe.widgets.form.meta.get_meta(doctype)]
+ for df in bundle[0].fields:
+ if df.fieldtype=="Table":
+ bundle.append(frappe.widgets.form.meta.get_meta(df.options))
+ return bundle
def get_docinfo(doctype, name):
frappe.response["docinfo"] = {
@@ -87,11 +89,15 @@ def get_restrictions(meta):
return out
def add_attachments(dt, dn):
- attachments = {}
+ attachments = []
for f in frappe.db.sql("""select name, file_name, file_url from
`tabFile Data` where attached_to_name=%s and attached_to_doctype=%s""",
(dn, dt), as_dict=True):
- attachments[f.file_url or f.file_name] = f.name
+ attachments.append({
+ 'name': f.name,
+ 'file_url': f.file_url,
+ 'file_name': f.file_name
+ })
return attachments
@@ -121,4 +127,4 @@ def get_badge_info(doctypes, filters):
for doctype in doctypes:
out[doctype] = frappe.db.get_value(doctype, filters, "count(*)")
- return out
\ No newline at end of file
+ return out
diff --git a/frappe/widgets/form/meta.py b/frappe/widgets/form/meta.py
new file mode 100644
index 0000000000..63f0601864
--- /dev/null
+++ b/frappe/widgets/form/meta.py
@@ -0,0 +1,157 @@
+# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
+# MIT License. See license.txt
+
+# metadata
+
+from __future__ import unicode_literals
+import frappe, os
+from frappe.utils import cstr, cint
+from frappe.model.meta import Meta
+from frappe.modules import scrub, get_module_path
+from frappe.model.workflow import get_workflow_name
+
+######
+
+def get_meta(doctype, cached=True):
+ if cached:
+ meta = frappe.cache().get_value("form_meta:" + doctype, lambda: FormMeta(doctype))
+ else:
+ meta = FormMeta(doctype)
+
+ if frappe.local.lang != 'en':
+ meta.set("__messages", frappe.get_lang_dict("doctype", doctype))
+
+ return meta
+
+class FormMeta(Meta):
+ def __init__(self, doctype):
+ super(FormMeta, self).__init__(doctype)
+ self.load_assets()
+
+ def load_assets(self):
+ self.expand_selects()
+ self.add_search_fields()
+
+ if not self.istable:
+ self.add_linked_with()
+ self.add_code()
+ self.load_print_formats()
+ self.load_workflows()
+
+ def as_dict(self):
+ d = super(FormMeta, self).as_dict()
+ for k in ("__js", "__css", "__list_js", "__calendar_js", "__map_js", "__linked_with", "__messages"):
+ d[k] = self.get(k)
+
+ for i, df in enumerate(d.get("fields")):
+ for k in ("link_doctype", "search_fields"):
+ df[k] = self.get("fields")[i].get(k)
+
+ return d
+
+ def add_code(self):
+ path = os.path.join(get_module_path(self.module), 'doctype', scrub(self.name))
+ def _get_path(fname):
+ return os.path.join(path, scrub(fname))
+
+ self._add_code(_get_path(self.name + '.js'), '__js')
+ self._add_code(_get_path(self.name + '.css'), "__css")
+ self._add_code(_get_path(self.name + '_list.js'), '__list_js')
+ self._add_code(_get_path(self.name + '_calendar.js'), '__calendar_js')
+ self._add_code(_get_path(self.name + '_map.js'), '__map_js')
+
+ self.add_custom_script()
+ self.add_code_via_hook("doctype_js", "__js")
+
+ def _add_code(self, path, fieldname):
+ js = frappe.read_file(path)
+ if js:
+ self.set(fieldname, (self.get(fieldname) or "") + "\n\n" + render_jinja(js))
+
+ def add_code_via_hook(self, hook, fieldname):
+ hook = "{}:{}".format(hook, self.name)
+ for app_name in frappe.get_installed_apps():
+ for file in frappe.get_hooks(hook, app_name=app_name):
+ path = frappe.get_app_path(app_name, *file.strip("/").split("/"))
+ self._add_code(path, fieldname)
+
+ def add_custom_script(self):
+ """embed all require files"""
+ # custom script
+ custom = frappe.db.get_value("Custom Script", {"dt": self.name,
+ "script_type": "Client"}, "script") or ""
+
+ self.set("__js", (self.get('__js') or '') + "\n\n" + custom)
+
+ def render_jinja(content):
+ if "{% include" in content:
+ content = frappe.get_jenv().from_string(content).render()
+ return content
+
+ def expand_selects(self):
+ for df in self.get("fields", {"fieldtype": "Select"}):
+ if df.options and df.options.startswith("link:"):
+ df.link_doctype = df.options.split("\n")[0][5:]
+ df.options = '\n'.join([''] + [o.name for o in frappe.db.sql("""select
+ name from `tab%s` where docstatus<2 order by name asc""" % df.link_doctype, as_dict=1)])
+
+ def add_search_fields(self):
+ """add search fields found in the doctypes indicated by link fields' options"""
+ for df in self.get("fields", {"fieldtype": "Link", "options":["!=", "[Select]"]}):
+ if df.options:
+ search_fields = frappe.get_meta(df.options).search_fields
+ if search_fields:
+ df.search_fields = map(lambda sf: sf.strip(), search_fields.split(","))
+
+ def add_linked_with(self):
+ """add list of doctypes this doctype is 'linked' with"""
+ links = frappe.db.sql("""select parent, fieldname from tabDocField
+ where (fieldtype="Link" and options=%s)
+ or (fieldtype="Select" and options=%s)""", (self.name, "link:"+ self.name))
+ links += frappe.db.sql("""select dt as parent, fieldname from `tabCustom Field`
+ where (fieldtype="Link" and options=%s)
+ or (fieldtype="Select" and options=%s)""", (self.name, "link:"+ self.name))
+
+ links = dict(links)
+
+ if not links:
+ return {}
+
+ ret = {}
+
+ for dt in links:
+ ret[dt] = { "fieldname": links[dt] }
+
+ for grand_parent, options in frappe.db.sql("""select parent, options from tabDocField
+ where fieldtype="Table"
+ and options in (select name from tabDocType
+ where istable=1 and name in (%s))""" % ", ".join(["%s"] * len(links)) ,tuple(links)):
+
+ ret[grand_parent] = {"child_doctype": options, "fieldname": links[options] }
+ if options in ret:
+ del ret[options]
+
+ self.set("__linked_with", ret)
+
+ def load_print_formats(self):
+ frappe.response.docs.extend(frappe.db.sql("""select * FROM `tabPrint Format`
+ WHERE doc_type=%s AND docstatus<2""", (self.name,), as_dict=1, update={"doctype":"Print Format"}))
+
+ def load_workflows(self):
+ # get active workflow
+ workflow_name = get_workflow_name(self.name)
+
+ if workflow_name and frappe.db.exists("Workflow", workflow_name):
+ workflow = frappe.get_doc("Workflow", workflow_name)
+ frappe.response.docs.append(workflow)
+
+ for d in workflow.get("workflow_document_states"):
+ frappe.response.docs.append(frappe.get_doc("Workflow State", d.state))
+
+
+def render_jinja(content):
+ if "{% include" in content:
+ content = frappe.get_jenv().from_string(content).render()
+ return content
+
+
\ No newline at end of file
diff --git a/frappe/widgets/form/run_method.py b/frappe/widgets/form/run_method.py
index 8f84c3aa53..eb8919ddef 100644
--- a/frappe/widgets/form/run_method.py
+++ b/frappe/widgets/form/run_method.py
@@ -2,6 +2,7 @@
# MIT License. See license.txt
from __future__ import unicode_literals
+import json
import frappe
from frappe import _
@@ -10,47 +11,43 @@ def runserverobj():
"""
Run server objects
"""
- import frappe.model.code
- from frappe.model.bean import Bean
from frappe.utils import cint
wrapper = None
method = frappe.form_dict.get('method')
- arg = frappe.form_dict.get('args', frappe.form_dict.get("arg"))
dt = frappe.form_dict.get('doctype')
dn = frappe.form_dict.get('docname')
- frappe.response["docs"] = []
-
if dt: # not called from a doctype (from a page)
if not dn: dn = dt # single
- so = frappe.model.code.get_obj(dt, dn)
+ doc = frappe.get_doc(dt, dn)
else:
- bean = Bean()
- bean.from_compressed(frappe.form_dict.get('docs'), dn)
- if not bean.has_read_perm():
- frappe.msgprint(_("No Permission"), raise_exception = True)
- so = bean.make_controller()
- bean.check_if_latest(method="runserverobj")
+ doc = frappe.get_doc(json.loads(frappe.form_dict.get('docs')))
+ doc.check_if_latest()
- check_guest_access(so.doc)
+ if not doc.has_permission("read"):
+ frappe.msgprint(_("No Permission"), raise_exception = True)
- if so:
- r = frappe.model.code.run_server_obj(so, method, arg)
+ if doc:
+ try:
+ args = frappe.form_dict.get('args', frappe.form_dict.get("arg"))
+ args = json.loads(args)
+ except ValueError:
+ r = doc.run_method(method, args)
+ except TypeError:
+ r = doc.run_method(method)
+ else:
+ r = doc.run_method(method, **args)
+
if r:
#build output as csv
if cint(frappe.form_dict.get('as_csv')):
- make_csv_output(r, so.doc.doctype)
+ make_csv_output(r, doc.doctype)
else:
frappe.response['message'] = r
- frappe.response['docs'] += so.doclist
-
-def check_guest_access(doc):
- if frappe.session['user']=='Guest' and not frappe.db.sql("select name from tabDocPerm where role='Guest' and parent=%s and ifnull(`read`,0)=1", doc.doctype):
- frappe.msgprint("Guest not allowed to call this object")
- raise Exception
+ frappe.response.docs.append(doc)
def make_csv_output(res, dt):
"""send method response as downloadable CSV file"""
diff --git a/frappe/widgets/form/save.py b/frappe/widgets/form/save.py
index d8430b5c1a..7d7eba846d 100644
--- a/frappe/widgets/form/save.py
+++ b/frappe/widgets/form/save.py
@@ -2,27 +2,25 @@
# MIT License. See license.txt
from __future__ import unicode_literals
-import frappe
+import frappe, json
@frappe.whitelist()
def savedocs():
"""save / submit / update doclist"""
try:
- wrapper = frappe.bean()
- wrapper.from_compressed(frappe.form_dict.docs, frappe.form_dict.docname)
+ doc = frappe.get_doc(json.loads(frappe.form_dict.doc))
# action
- action = frappe.form_dict.action
- if action=='Update': action='update_after_submit'
+ doc.docstatus = {"Save":0, "Submit": 1, "Update": 1, "Cancel": 2}[frappe.form_dict.action]
try:
- getattr(wrapper, action.lower())()
+ doc.save()
except NameError, e:
frappe.msgprint(frappe._("Name Exists"))
raise
# update recent documents
- frappe.user.update_recent(wrapper.doc.doctype, wrapper.doc.name)
- send_updated_docs(wrapper)
+ frappe.user.update_recent(doc.doctype, doc.name)
+ send_updated_docs(doc)
except Exception, e:
frappe.msgprint(frappe._('Did not save'))
@@ -33,20 +31,21 @@ def savedocs():
def cancel(doctype=None, name=None):
"""cancel a doclist"""
try:
- wrapper = frappe.bean(doctype, name)
- wrapper.cancel()
- send_updated_docs(wrapper)
+ doc = frappe.get_doc(doctype, name)
+ doc.cancel()
+ send_updated_docs(doc)
except Exception, e:
frappe.errprint(frappe.utils.get_traceback())
frappe.msgprint(frappe._("Did not cancel"))
raise
-def send_updated_docs(wrapper):
+def send_updated_docs(doc):
from load import get_docinfo
- get_docinfo(wrapper.doc.doctype, wrapper.doc.name)
+ get_docinfo(doc.doctype, doc.name)
- frappe.response['main_doc_name'] = wrapper.doc.name
- frappe.response['doctype'] = wrapper.doc.doctype
- frappe.response['docname'] = wrapper.doc.name
- frappe.response['docs'] = wrapper.doclist
\ No newline at end of file
+ d = doc.as_dict()
+ if hasattr(doc, 'localname'):
+ d["localname"] = doc.localname
+
+ frappe.response.docs.append(d)
diff --git a/frappe/widgets/form/utils.py b/frappe/widgets/form/utils.py
index de71e4cf30..d8bc2f1847 100644
--- a/frappe/widgets/form/utils.py
+++ b/frappe/widgets/form/utils.py
@@ -1,8 +1,9 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
-# MIT License. See license.txt
+# MIT License. See license.txt
from __future__ import unicode_literals
import frappe, json
+import frappe.widgets.form.meta
from frappe import _
@@ -34,46 +35,44 @@ def validate_link():
"""validate link when updated by user"""
import frappe
import frappe.utils
-
+
value, options, fetch = frappe.form_dict.get('value'), frappe.form_dict.get('options'), frappe.form_dict.get('fetch')
# no options, don't validate
if not options or options=='null' or options=='undefined':
frappe.response['message'] = 'Ok'
return
-
+
if frappe.db.sql("select name from `tab%s` where name=%s" % (options, '%s'), (value,)):
-
+
# get fetch values
if fetch:
frappe.response['fetch_values'] = [frappe.utils.parse_val(c) \
for c in frappe.db.sql("select %s from `tab%s` where name=%s" \
% (fetch, options, '%s'), (value,))[0]]
-
+
frappe.response['message'] = 'Ok'
@frappe.whitelist()
def add_comment(doclist):
"""allow any logged user to post a comment"""
doclist = json.loads(doclist)
-
+
doclist[0]["__islocal"] = 1
- doclistobj = frappe.bean(doclist)
+ doclistobj = frappe.get_doc(doclist)
doclistobj.ignore_permissions = True
doclistobj.save()
-
- return [d.fields for d in doclist]
- return save(doclist)
+ return doclistobj.as_dict()
@frappe.whitelist()
def get_next(doctype, name, prev):
import frappe.widgets.reportview
-
+
prev = int(prev)
field = "`tab%s`.name" % doctype
res = frappe.widgets.reportview.execute(doctype,
- fields = [field],
+ fields = [field],
filters = [[doctype, "name", "<" if prev else ">", name]],
order_by = field + " " + ("desc" if prev else "asc"),
limit_start=0, limit_page_length=1, as_list=True)
@@ -87,33 +86,31 @@ def get_next(doctype, name, prev):
@frappe.whitelist()
def get_linked_docs(doctype, name, metadata_loaded=None):
if not metadata_loaded: metadata_loaded = []
- meta = frappe.get_doctype(doctype, True)
- linkinfo = meta[0].get("__linked_with")
+ meta = frappe.widgets.form.meta.get_meta(doctype)
+ linkinfo = meta.get("__linked_with")
results = {}
for dt, link in linkinfo.items():
link["doctype"] = dt
- linkmeta = frappe.get_doctype(dt, True)
- if not linkmeta[0].get("issingle"):
- fields = [d.fieldname for d in linkmeta.get({"parent":dt, "in_list_view":1,
+ linkmeta = frappe.widgets.form.meta.get_meta(dt)
+ if not linkmeta.get("issingle"):
+ fields = [d.fieldname for d in linkmeta.get("fields", {"in_list_view":1,
"fieldtype": ["not in", ["Image", "HTML", "Button", "Table"]]})] \
+ ["name", "modified", "docstatus"]
fields = ["`tab{dt}`.`{fn}`".format(dt=dt, fn=sf.strip()) for sf in fields if sf]
if link.get("child_doctype"):
- ret = frappe.get_list(doctype=dt, fields=fields,
+ ret = frappe.get_list(doctype=dt, fields=fields,
filters=[[link.get('child_doctype'), link.get("fieldname"), '=', name]])
-
+
else:
- ret = frappe.get_list(doctype=dt, fields=fields,
+ ret = frappe.get_list(doctype=dt, fields=fields,
filters=[[dt, link.get("fieldname"), '=', name]])
-
- if ret:
+
+ if ret:
results[dt] = ret
-
+
if not dt in metadata_loaded:
- if not "docs" in frappe.local.response:
- frappe.local.response.docs = []
- frappe.local.response.docs += linkmeta
-
- return results
\ No newline at end of file
+ frappe.local.response.docs.append(linkmeta)
+
+ return results
diff --git a/frappe/widgets/moduleview.py b/frappe/widgets/moduleview.py
index 41da851126..572f08163a 100644
--- a/frappe/widgets/moduleview.py
+++ b/frappe/widgets/moduleview.py
@@ -173,4 +173,4 @@ def get_report_list(module, is_standard="No"):
and docstatus in (0, NULL)
and ifnull(is_standard, "No")=%s
and ifnull(disabled,0) != 1
- order by name""", (module, is_standard), as_dict=True)
\ No newline at end of file
+ order by name""", (module, is_standard), as_dict=True)
diff --git a/frappe/widgets/page.py b/frappe/widgets/page.py
index 953771544c..d586339146 100644
--- a/frappe/widgets/page.py
+++ b/frappe/widgets/page.py
@@ -3,22 +3,20 @@
from __future__ import unicode_literals
import frappe
-import frappe.model.doc
-import frappe.model.code
@frappe.whitelist()
def get(name):
"""
Return the :term:`doclist` of the `Page` specified by `name`
"""
- page = frappe.bean("Page", name)
- if has_permission(page.doclist):
- page.run_method("get_from_files")
- return page.doclist
+ page = frappe.get_doc('Page', name)
+ if has_permission(page):
+ page.load_assets()
+ return page
else:
frappe.response['403'] = 1
raise frappe.PermissionError, 'No read permission for Page %s' % \
- (page.doclist[0].title or name,)
+ (page.title or name)
@frappe.whitelist(allow_guest=True)
def getpage():
@@ -26,24 +24,19 @@ def getpage():
Load the page from `frappe.form` and send it via `frappe.response`
"""
page = frappe.form_dict.get('name')
- doclist = get(page)
+ doc = get(page)
- if has_permission(doclist):
- # load translations
- if frappe.lang != "en":
- frappe.response["__messages"] = frappe.get_lang_dict("page", page)
+ # load translations
+ if frappe.lang != "en":
+ frappe.response["__messages"] = frappe.get_lang_dict("page", page)
- frappe.response['docs'] = doclist
- else:
- frappe.response['403'] = 1
- raise frappe.PermissionError, 'No read permission for Page %s' % \
- (doclist[0].title or page, )
-
-def has_permission(page_doclist):
+ frappe.response.docs.append(doc)
+
+def has_permission(page):
if frappe.user.name == "Administrator" or "System Manager" in frappe.user.get_roles():
return True
- page_roles = [d.role for d in page_doclist if d.fields.get("doctype")=="Page Role"]
+ page_roles = [d.role for d in page.get("roles")]
if page_roles:
if frappe.session.user == "Guest" and "Guest" not in page_roles:
return False
@@ -51,7 +44,7 @@ def has_permission(page_doclist):
# check if roles match
return False
- if not frappe.has_permission("Page", ptype="read", refdoc=page_doclist[0].name):
+ if not frappe.has_permission("Page", ptype="read", doc=page):
# check if there are any restrictions
return False
else:
diff --git a/frappe/widgets/query_report.py b/frappe/widgets/query_report.py
index 384c6979f1..d6e5d2f7f3 100644
--- a/frappe/widgets/query_report.py
+++ b/frappe/widgets/query_report.py
@@ -13,15 +13,15 @@ from frappe.utils import flt, cint
import frappe.widgets.reportview
def get_report_doc(report_name):
- bean = frappe.bean("Report", report_name)
- if not bean.has_read_perm():
+ doc = frappe.get_doc("Report", report_name)
+ if not doc.has_permission("read"):
raise frappe.PermissionError("You don't have access to: {report}".format(report=report_name))
- if not frappe.has_permission(bean.doc.ref_doctype, "report"):
+ if not frappe.has_permission(doc.ref_doctype, "report"):
raise frappe.PermissionError("You don't have access to get a report on: {doctype}".format(
- doctype=bean.doc.ref_doctype))
+ doctype=doc.ref_doctype))
- return bean.doc
+ return doc
@frappe.whitelist()
def get_script(report_name):
diff --git a/frappe/widgets/reportview.py b/frappe/widgets/reportview.py
index a2a193cb20..e0b189b6c4 100644
--- a/frappe/widgets/reportview.py
+++ b/frappe/widgets/reportview.py
@@ -52,8 +52,7 @@ def compress(data):
@frappe.whitelist()
def save_report():
"""save report"""
- from frappe.model.doc import Document
-
+
data = frappe.local.form_dict
if frappe.db.exists('Report', data['name']):
d = Document('Report', data['name'])
@@ -64,7 +63,7 @@ def save_report():
d.report_type = "Report Builder"
d.json = data['json']
- frappe.bean([d]).save()
+ frappe.get_doc(d).save()
frappe.msgprint("%s saved." % d.name)
return d.name
@@ -119,14 +118,13 @@ def get_labels(columns):
def delete_items():
"""delete selected items"""
import json
- from frappe.model.code import get_obj
-
+
il = json.loads(frappe.form_dict.get('items'))
doctype = frappe.form_dict.get('doctype')
for d in il:
try:
- dt_obj = get_obj(doctype, d)
+ dt_obj = frappe.get_doc(doctype, d)
if hasattr(dt_obj, 'on_trash'):
dt_obj.on_trash()
frappe.delete_doc(doctype, d)
diff --git a/frappe/widgets/search.py b/frappe/widgets/search.py
index f740e2a6a3..53c794c13d 100644
--- a/frappe/widgets/search.py
+++ b/frappe/widgets/search.py
@@ -22,7 +22,7 @@ def search_widget(doctype, txt, query=None, searchfield="name", start=0,
import json
filters = json.loads(filters)
- meta = frappe.get_doctype(doctype)
+ meta = frappe.get_meta(doctype)
standard_queries = frappe.get_hooks().standard_queries or []
if standard_queries:
@@ -57,9 +57,9 @@ def search_widget(doctype, txt, query=None, searchfield="name", start=0,
# build from doctype
if txt:
filters.append([doctype, searchfield or "name", "like", txt + "%"])
- if meta.get({"parent":doctype, "fieldname":"enabled", "fieldtype":"Check"}):
+ if meta.get("fields", {"fieldname":"enabled", "fieldtype":"Check"}):
filters.append([doctype, "enabled", "=", 1])
- if meta.get({"parent":doctype, "fieldname":"disabled", "fieldtype":"Check"}):
+ if meta.get("fields", {"fieldname":"disabled", "fieldtype":"Check"}):
filters.append([doctype, "disabled", "!=", 1])
frappe.response["values"] = frappe.widgets.reportview.execute(doctype,
@@ -68,12 +68,12 @@ def search_widget(doctype, txt, query=None, searchfield="name", start=0,
def get_std_fields_list(meta, key):
# get additional search fields
- sflist = meta[0].search_fields and meta[0].search_fields.split(",") or []
+ sflist = meta.search_fields and meta.search_fields.split(",") or []
sflist = ['name'] + sflist
if not key in sflist:
sflist = sflist + [key]
- return ['`tab%s`.`%s`' % (meta[0].name, f.strip()) for f in sflist]
+ return ['`tab%s`.`%s`' % (meta.name, f.strip()) for f in sflist]
def build_for_autosuggest(res):
results = []