@@ -362,13 +362,13 @@ def latest(verbose=True, rebuild_website_config=True, quiet=False): | |||
# sync | |||
frappe.model.sync.sync_all(verbose=verbose) | |||
sync_fixtures() | |||
statics.sync().start() | |||
# build website config if any changes in templates etc. | |||
if rebuild_website_config: | |||
rebuild_config() | |||
statics.sync().start() | |||
sync_fixtures() | |||
frappe.translate.clear_cache() | |||
@@ -18,11 +18,11 @@ data_keys = frappe._dict({ | |||
@frappe.whitelist() | |||
def get_doctypes(): | |||
if "System Manager" in frappe.get_roles(): | |||
return [r[0] for r in frappe.db.sql("""select name from `tabDocType` | |||
return [r[0] for r in frappe.db.sql("""select name from `tabDocType` | |||
where allow_import = 1""")] | |||
else: | |||
return frappe.user._get("can_import") | |||
@frappe.whitelist() | |||
def get_doctype_options(): | |||
doctype = frappe.form_dict['doctype'] | |||
@@ -35,7 +35,7 @@ def import_file_by_path(path, ignore_links=False, overwrite=False, submit=False) | |||
from frappe.core.page.data_import_tool.importer import upload | |||
print "Importing " + path | |||
with open(path, "r") as infile: | |||
upload(rows = read_csv_content(infile), ignore_links=ignore_links, overwrite=overwrite, submit_after_import=submit) | |||
upload(rows = read_csv_content(infile.read()), ignore_links=ignore_links, overwrite=overwrite, submit_after_import=submit) | |||
def export_csv(doctype, path): | |||
from frappe.core.page.data_import_tool.exporter import get_template | |||
@@ -59,25 +59,30 @@ def export_json(doctype, name, path): | |||
def export_fixture(doctype, name, app): | |||
if frappe.session.user != "Administrator": | |||
raise frappe.PermissionError | |||
if not os.path.exists(frappe.get_app_path(app, "fixtures")): | |||
os.mkdir(frappe.get_app_path(app, "fixtures")) | |||
export_json(doctype, name, frappe.get_app_path(app, "fixtures", frappe.scrub(name) + ".json")) | |||
def import_doc(path, overwrite=False, ignore_links=False, ignore_insert=False, insert=False, submit=False): | |||
if os.path.isdir(path): | |||
files = [os.path.join(path, f) for f in os.listdir(path)] | |||
else: | |||
files = [path] | |||
def _import_doc(d): | |||
doc = frappe.get_doc(d) | |||
doc.ignore_links = ignore_links | |||
if insert: | |||
doc.set("__islocal", True) | |||
try: | |||
if doc.name and overwrite: | |||
if frappe.db.exists(doc.doctype, doc.name): | |||
frappe.delete_doc(doc.doctype, doc.name, force=True) | |||
doc.set("__islocal", True) | |||
doc.ignore_links = ignore_links | |||
doc.save() | |||
except NameError: | |||
if ignore_insert: | |||
@@ -85,7 +90,7 @@ def import_doc(path, overwrite=False, ignore_links=False, ignore_insert=False, i | |||
else: | |||
raise | |||
print "Imported: " + doc.doctype + " / " + doc.name | |||
for f in files: | |||
if f.endswith(".json"): | |||
with open(f, "r") as infile: | |||
@@ -97,5 +102,5 @@ def import_doc(path, overwrite=False, ignore_links=False, ignore_insert=False, i | |||
_import_doc(data) | |||
frappe.db.commit() | |||
if f.endswith(".csv"): | |||
import_file_by_path(f, ignore_links=True, overwrite=overwrite, submit=submit) | |||
import_file_by_path(f, ignore_links=ignore_links, overwrite=overwrite, submit=submit) | |||
frappe.db.commit() |
@@ -17,7 +17,7 @@ def upload(rows = None, submit_after_import=None, ignore_encoding_errors=False, | |||
frappe.flags.mute_emails = True | |||
# extra input params | |||
params = json.loads(frappe.form_dict.get("params") or '{}') | |||
if params.get("_submit"): | |||
submit_after_import = True | |||
if params.get("ignore_encoding_errors"): | |||
@@ -54,7 +54,7 @@ def upload(rows = None, submit_after_import=None, ignore_encoding_errors=False, | |||
def filter_empty_columns(columns): | |||
empty_cols = filter(lambda x: x in ("", None), columns) | |||
if empty_cols: | |||
if columns[-1*len(empty_cols):] == empty_cols: | |||
# filter empty columns if they exist at the end | |||
@@ -69,7 +69,7 @@ def upload(rows = None, submit_after_import=None, ignore_encoding_errors=False, | |||
doctype_row, row_idx = get_header_row_and_idx(data_keys.doctype) | |||
if row_idx == -1: # old style | |||
return | |||
dt = None | |||
for i, d in enumerate(doctype_row[1:]): | |||
if d not in ("~", "-"): | |||
@@ -97,7 +97,7 @@ def upload(rows = None, submit_after_import=None, ignore_encoding_errors=False, | |||
try: | |||
fieldname = column_idx_to_fieldname[dt][column_idx] | |||
fieldtype = column_idx_to_fieldtype[dt][column_idx] | |||
d[fieldname] = rows[idx][column_idx] | |||
if fieldtype in ("Int", "Check"): | |||
d[fieldname] = cint(d[fieldname]) | |||
@@ -105,7 +105,7 @@ def upload(rows = None, submit_after_import=None, ignore_encoding_errors=False, | |||
d[fieldname] = flt(d[fieldname]) | |||
except IndexError, e: | |||
pass | |||
# scrub quotes from name and modified | |||
if d.get("name") and d["name"].startswith('"'): | |||
d["name"] = d["name"][1:-1] | |||
@@ -125,13 +125,13 @@ def upload(rows = None, submit_after_import=None, ignore_encoding_errors=False, | |||
return doc | |||
else: | |||
d = frappe._dict(zip(columns, rows[start_idx][1:])) | |||
d['doctype'] = doctype | |||
return [d] | |||
doc = frappe._dict(zip(columns, rows[start_idx][1:])) | |||
doc['doctype'] = doctype | |||
return doc | |||
def main_doc_empty(row): | |||
return not (row and ((len(row) > 1 and row[1]) or (len(row) > 2 and row[2]))) | |||
# header | |||
if not rows: | |||
rows = read_csv_content_from_uploaded_file(ignore_encoding_errors) | |||
@@ -144,13 +144,13 @@ def upload(rows = None, submit_after_import=None, ignore_encoding_errors=False, | |||
doctype_parentfield = {} | |||
column_idx_to_fieldname = {} | |||
column_idx_to_fieldtype = {} | |||
if submit_after_import and not cint(frappe.db.get_value("DocType", | |||
if submit_after_import and not cint(frappe.db.get_value("DocType", | |||
doctype, "is_submittable")): | |||
submit_after_import = False | |||
parenttype = get_header_row(data_keys.parent_table) | |||
if len(parenttype) > 1: | |||
parenttype = parenttype[1] | |||
parentfield = get_parent_field(doctype, parenttype) | |||
@@ -159,15 +159,15 @@ def upload(rows = None, submit_after_import=None, ignore_encoding_errors=False, | |||
if not frappe.permissions.can_import(parenttype or doctype): | |||
frappe.flags.mute_emails = False | |||
return {"messages": [_("Not allowed to Import") + ": " + _(doctype)], "error": True} | |||
# allow limit rows to be uploaded | |||
check_data_length() | |||
make_column_map() | |||
frappe.db.begin() | |||
if overwrite==None: | |||
overwrite = params.get('overwrite') | |||
# delete child rows (if parenttype) | |||
if parenttype and overwrite: | |||
delete_child_rows(data, doctype) | |||
@@ -179,10 +179,10 @@ def upload(rows = None, submit_after_import=None, ignore_encoding_errors=False, | |||
# bypass empty rows | |||
if main_doc_empty(row): | |||
continue | |||
row_idx = i + start_row | |||
doc = None | |||
doc = get_doc(row_idx) | |||
try: | |||
frappe.local.message_log = [] | |||
@@ -192,7 +192,7 @@ def upload(rows = None, submit_after_import=None, ignore_encoding_errors=False, | |||
parent.save() | |||
ret.append('Inserted row for %s at #%s' % (getlink(parenttype, | |||
doc.parent), unicode(doc.idx))) | |||
else: | |||
if overwrite and frappe.db.exists(doctype, doc["name"]): | |||
original = frappe.get_doc(doctype, doc["name"]) | |||
@@ -210,36 +210,36 @@ def upload(rows = None, submit_after_import=None, ignore_encoding_errors=False, | |||
except Exception, e: | |||
error = True | |||
if doc: | |||
frappe.errprint(doc.as_dict()) | |||
frappe.errprint(doc if isinstance(doc, dict) else doc.as_dict()) | |||
err_msg = frappe.local.message_log and "<br>".join(frappe.local.message_log) or cstr(e) | |||
ret.append('Error for row (#%d) %s : %s' % (row_idx + 1, | |||
ret.append('Error for row (#%d) %s : %s' % (row_idx + 1, | |||
len(row)>1 and row[1] or "", err_msg)) | |||
frappe.errprint(frappe.get_traceback()) | |||
if error: | |||
frappe.db.rollback() | |||
frappe.db.rollback() | |||
else: | |||
frappe.db.commit() | |||
frappe.flags.mute_emails = False | |||
return {"messages": ret, "error": error} | |||
def get_parent_field(doctype, parenttype): | |||
parentfield = None | |||
# get parentfield | |||
if parenttype: | |||
for d in frappe.get_meta(parenttype).get_table_fields(): | |||
if d.options==doctype: | |||
parentfield = d.fieldname | |||
break | |||
if not parentfield: | |||
frappe.msgprint("Did not find parentfield for %s (%s)" % \ | |||
(parenttype, doctype)) | |||
raise Exception | |||
return parentfield | |||
def delete_child_rows(rows, doctype): | |||
@@ -19,7 +19,7 @@ def delete_doc(doctype=None, name=None, force=0, ignore_doctypes=None, for_reloa | |||
if not doctype: | |||
doctype = frappe.form_dict.get('dt') | |||
name = frappe.form_dict.get('dn') | |||
if not doctype: | |||
frappe.msgprint('Nothing to delete!', raise_exception =1) | |||
@@ -28,16 +28,20 @@ def delete_doc(doctype=None, name=None, force=0, ignore_doctypes=None, for_reloa | |||
return | |||
doc = frappe.get_doc(doctype, name) | |||
if not for_reload: | |||
check_permission_and_not_submitted(doc, ignore_permissions) | |||
doc.run_method("on_trash") | |||
# check if links exist | |||
if not force: | |||
check_if_doc_is_linked(doc) | |||
try: | |||
frappe.db.sql("delete from `tab%s` where name=%s" % (doctype, "%s"), (name,)) | |||
if doctype==name: | |||
frappe.db.sql("delete from `tabSingles` where doctype=%s", name) | |||
else: | |||
frappe.db.sql("delete from `tab%s` where name=%s" % (doctype, "%s"), (name,)) | |||
for t in doc.meta.get_table_fields(): | |||
if t.options not in ignore_doctypes: | |||
frappe.db.sql("delete from `tab%s` where parent = %s" % (t.options, '%s'), (name,)) | |||
@@ -45,15 +49,15 @@ def delete_doc(doctype=None, name=None, force=0, ignore_doctypes=None, for_reloa | |||
except Exception, e: | |||
if e.args[0]==1451: | |||
frappe.msgprint("Cannot delete %s '%s' as it is referenced in another record. You must delete the referred record first" % (doctype, name)) | |||
raise | |||
# delete attachments | |||
remove_all(doctype, name) | |||
# delete restrictions | |||
frappe.defaults.clear_default(parenttype="Restriction", key=doctype, value=name) | |||
return 'okay' | |||
def check_permission_and_not_submitted(doc, ignore_permissions=False): | |||
@@ -78,12 +82,12 @@ def check_if_doc_is_linked(doc, method="Delete"): | |||
for link_dt, link_field, issingle in link_fields: | |||
if not issingle: | |||
item = frappe.db.get_value(link_dt, {link_field:doc.name}, | |||
item = frappe.db.get_value(link_dt, {link_field:doc.name}, | |||
["name", "parent", "parenttype", "docstatus"], as_dict=True) | |||
if item and item.parent != doc.name and ((method=="Delete" and item.docstatus<2) or | |||
if item and item.parent != doc.name and ((method=="Delete" and item.docstatus<2) or | |||
(method=="Cancel" and item.docstatus==1)): | |||
frappe.msgprint(method + " " + _("Error") + ":"+\ | |||
("%s (%s) " % (doc.name, doc.doctype)) + _("is linked in") + (" %s (%s)") % | |||
("%s (%s) " % (doc.name, doc.doctype)) + _("is linked in") + (" %s (%s)") % | |||
(item.parent or item.name, item.parent and item.parenttype or link_dt), | |||
raise_exception=LinkExistsError) |
@@ -13,13 +13,13 @@ no_cache = 1 | |||
def get_context(context): | |||
group, view = guess_group_view(context) | |||
try: | |||
if not has_access(context.access, view): | |||
raise frappe.PermissionError | |||
return get_group_context(group, view, context) | |||
except frappe.DoesNotExistError: | |||
return { | |||
"content": '<div class="alert alert-danger full-page">' | |||
@@ -30,48 +30,48 @@ def get_context(context): | |||
"content": '<div class="alert alert-danger full-page">' | |||
'You are not permitted to view this page.</div>' | |||
} | |||
def get_group_context(group, view, context): | |||
cache_key = "website_group_context:{}:{}".format(group, view) | |||
views = get_views(context.doc.group_type) | |||
view = frappe._dict(views.get(view)) | |||
if can_cache(view.no_cache): | |||
group_context = frappe.cache().get_value(cache_key) | |||
if group_context: | |||
return group_context | |||
group_context = build_group_context(group, view, views, context) | |||
if can_cache(view.get("no_cache")): | |||
frappe.cache().set_value(cache_key, group_context) | |||
return group_context | |||
def build_group_context(group, view, views, context): | |||
title = "{} - {}".format(context.doc.group_title, view.get("label")) | |||
group_context = frappe._dict({ | |||
"group": context.doc.as_dict(), | |||
"group": context.doc, | |||
"view": view, | |||
"views": [v[1] for v in sorted(views.iteritems(), key=lambda (k, v): v.get("idx"))], | |||
"title": title, | |||
"pathname": context.pathname | |||
}) | |||
group_context.update(build_view_context(group_context)) | |||
return group_context | |||
def build_view_context(context): | |||
from frappe.templates.website_group.post import get_post_context | |||
if context.view.name in ("popular", "feed", "open", "closed", "upcoming", "past"): | |||
context.post_list_html = get_post_list_html(context.group.name, context.view.name) | |||
elif context.view.name == "edit": | |||
context.post = frappe.get_doc("Post", frappe.form_dict.name).as_dict() | |||
if context.post.assigned_to: | |||
context.user = frappe.get_doc("User", context.post.assigned_to) | |||
@@ -79,22 +79,22 @@ def build_view_context(context): | |||
context.users = frappe.db.sql("""select p.*, wsp.`read`, wsp.`write`, wsp.`admin` | |||
from `tabUser` p, `tabWebsite Route Permission` wsp | |||
where wsp.website_route=%s and wsp.user=p.name""", context.pathname, as_dict=True) | |||
elif context.view.name == "post": | |||
context.update(get_post_context(context)) | |||
return context | |||
def guess_group_view(context): | |||
group = context.docname | |||
view = frappe.form_dict.view or get_default_view(context.doc.group_type) | |||
return group, view | |||
def get_default_view(group_type): | |||
for view, opts in get_views(group_type).iteritems(): | |||
if opts.get("default"): | |||
return view | |||
def get_views(group_type=None): | |||
if group_type: | |||
group_views = frappe._dict(views[group_type]) | |||
@@ -102,22 +102,22 @@ def get_views(group_type=None): | |||
group_views = {} | |||
for group_type in views: | |||
group_views.update(views[group_type].copy()) | |||
group_views.update(common_views) | |||
if group_type == "Forum": | |||
group_views["post"]["upvote"] = True | |||
return group_views | |||
def has_access(access, view): | |||
def has_access(access, view): | |||
if view=="settings": | |||
return access.get("admin") | |||
elif view in ("add", "edit"): | |||
return access.get("write") | |||
else: | |||
return access.get("read") | |||
def clear_cache(path=None, website_group=None): | |||
from frappe.templates.website_group.post import clear_post_cache | |||
if path: | |||
@@ -127,7 +127,7 @@ def clear_cache(path=None, website_group=None): | |||
else: | |||
clear_post_cache() | |||
website_groups = frappe.db.sql_list("""select name from `tabWebsite Group`""") | |||
cache = frappe.cache() | |||
all_views = get_views() | |||
for group in website_groups: | |||
@@ -137,10 +137,10 @@ def clear_cache(path=None, website_group=None): | |||
def clear_event_cache(): | |||
for group in frappe.db.sql_list("""select name from `tabWebsite Group` where group_type='Event'"""): | |||
clear_unit_views(website_group=group) | |||
def clear_cache_on_doc_event(doc, method, *args, **kwargs): | |||
clear_cache(path=doc.website_route, website_group=doc.website_group) | |||
def get_pathname(group): | |||
return frappe.db.get_value("Website Route", {"ref_doctype": "Website Group", | |||
"docname": group}) | |||
@@ -237,4 +237,4 @@ common_views = { | |||
"hidden": True, | |||
"idx": 6 | |||
} | |||
} | |||
} |
@@ -12,7 +12,7 @@ def get_post_context(context): | |||
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.get_doc("User", post.owner) | |||
for fieldname in ("first_name", "last_name", "user_image", "location"): | |||
post.set(fieldname, user.get(fieldname)) | |||
return frappe.get_template("templates/includes/inline_post.html")\ | |||
.render({"post": post.as_dict(), "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,8 +64,8 @@ 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.get_doc("Website Group", group) | |||
group = frappe.get_doc("Website Group", group) | |||
post = frappe.get_doc({ | |||
"doctype":"Post", | |||
"title": (title or "").title(), | |||
@@ -73,7 +73,7 @@ def add_post(group, content, picture, picture_name, title=None, parent_post=None | |||
"website_group": group.name, | |||
"parent_post": parent_post or None | |||
}) | |||
if not parent_post: | |||
if group.group_type == "Tasks": | |||
post.is_task = 1 | |||
@@ -81,38 +81,38 @@ def add_post(group, content, picture, picture_name, title=None, parent_post=None | |||
elif group.group_type == "Events": | |||
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.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.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.owner: | |||
for fieldname in ("title", "content"): | |||
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.update({ | |||
"title": (title or "").title(), | |||
"content": content, | |||
@@ -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.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.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] |
@@ -1,5 +1,5 @@ | |||
# 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 | |||