diff --git a/webnotes/__init__.py b/webnotes/__init__.py index cc49b656f6..50419c9192 100644 --- a/webnotes/__init__.py +++ b/webnotes/__init__.py @@ -201,7 +201,7 @@ def throw(msg, exc=ValidationError): def create_folder(path): if not os.path.exists(path): os.makedirs(path) - + def connect(site=None, db_name=None): from db import Database if site: @@ -546,27 +546,36 @@ jenv = None def get_jenv(): global jenv if not jenv: - from jinja2 import Environment, ChoiceLoader, PackageLoader + from jinja2 import Environment, ChoiceLoader, PackageLoader, DebugUndefined + import webnotes.utils apps = get_installed_apps() apps.remove("webnotes") # webnotes will be loaded last, so app templates will get precedence jenv = Environment(loader = ChoiceLoader([PackageLoader(app, ".") \ - for app in apps + ["webnotes"]])) + for app in apps + ["webnotes"]]), undefined=DebugUndefined) set_filters(jenv) + jenv.globals.update({ + "webnotes": sys.modules[__name__], + "webnotes.utils": webnotes.utils + }) + return jenv def set_filters(jenv): - from webnotes.utils import global_date_format + from webnotes.utils import global_date_format, scrub_relative_url + from webnotes.webutils import get_hex_shade from markdown2 import markdown from json import dumps jenv.filters["global_date_format"] = global_date_format jenv.filters["markdown"] = markdown jenv.filters["json"] = dumps + jenv.filters["scrub_relative_url"] = scrub_relative_url + jenv.filters["get_hex_shade"] = get_hex_shade # load jenv_filters from hooks.txt for app in get_all_apps(True): diff --git a/webnotes/auth.py b/webnotes/auth.py index cffed6f9ea..900aa5b07d 100644 --- a/webnotes/auth.py +++ b/webnotes/auth.py @@ -107,7 +107,7 @@ class LoginManager: def set_user_info(self): info = webnotes.conn.get_value("Profile", self.user, - ["user_type", "first_name", "last_name"], as_dict=1) + ["user_type", "first_name", "last_name", "user_image"], as_dict=1) if info.user_type=="Website User": webnotes.local._response.set_cookie("system_user", "no") webnotes.local.response["message"] = "No App" @@ -116,9 +116,10 @@ class LoginManager: webnotes.local.response['message'] = 'Logged In' full_name = " ".join(filter(None, [info.first_name, info.last_name])) - webnotes.local.response["full_name"] = full_name - webnotes.local._response.set_cookie("full_name", full_name) - webnotes.local._response.set_cookie("user_id", self.user) + webnotes.response["full_name"] = full_name + webnotes._response.set_cookie("full_name", full_name) + webnotes._response.set_cookie("user_id", self.user) + webnotes._response.set_cookie("user_image", info.user_image or "") def make_session(self, resume=False): # start session diff --git a/webnotes/cli.py b/webnotes/cli.py index 026b47013a..abe4ae66f5 100755 --- a/webnotes/cli.py +++ b/webnotes/cli.py @@ -237,7 +237,8 @@ def use(): # install @cmd def install(db_name, root_login="root", root_password=None, source_sql=None, - admin_password = 'admin', verbose=True, force=False, site_config=None, reinstall=False): + admin_password = 'admin', verbose=True, force=False, site_config=None, reinstall=False): + print db_name, source_sql from webnotes.installer import install_db, install_app, make_site_dirs install_db(root_login=root_login, root_password=root_password, db_name=db_name, source_sql=source_sql, admin_password = admin_password, verbose=verbose, force=force, site_config=site_config, reinstall=reinstall) diff --git a/webnotes/core/doctype/communication/communication.py b/webnotes/core/doctype/communication/communication.py index 64199c4537..def068ba59 100644 --- a/webnotes/core/doctype/communication/communication.py +++ b/webnotes/core/doctype/communication/communication.py @@ -36,6 +36,15 @@ def make(doctype=None, name=None, content=None, subject=None, sent_or_received = if doctype and name and not webnotes.has_permission(doctype, "email", name): raise webnotes.PermissionError("You are not allowed to send emails related to: {doctype} {name}".format( doctype=doctype, name=name)) + + _send(doctype=doctype, name=name, content=content, subject=subject, sent_or_received=sent_or_received, + sender=sender, recipients=recipients, communication_medium=communication_medium, send_email=send_email, + print_html=print_html, attachments=attachments, send_me_a_copy=send_me_a_copy, set_lead=set_lead, + date=date) + +def _make(doctype=None, name=None, content=None, subject=None, sent_or_received = "Sent", + sender=None, recipients=None, communication_medium="Email", send_email=False, + print_html=None, attachments='[]', send_me_a_copy=False, set_lead=True, date=None): # add to Communication sent_via = None diff --git a/webnotes/core/doctype/page/page.py b/webnotes/core/doctype/page/page.py index 515f73fb03..c85bf22629 100644 --- a/webnotes/core/doctype/page/page.py +++ b/webnotes/core/doctype/page/page.py @@ -38,7 +38,6 @@ class DocType: make_module_and_roles(self.doclist, "Page Role") if not webnotes.flags.in_import and getattr(conf,'developer_mode', 0) and self.doc.standard=='Yes': - print "here" from webnotes.modules.export_file import export_to_files from webnotes.modules import get_module_path, scrub import os diff --git a/webnotes/core/doctype/profile/profile.py b/webnotes/core/doctype/profile/profile.py index 66fb92ebe8..e39cf97830 100644 --- a/webnotes/core/doctype/profile/profile.py +++ b/webnotes/core/doctype/profile/profile.py @@ -347,6 +347,57 @@ def reset_password(user): else: return "No such user (%s)" % user +@webnotes.whitelist(allow_guest=True) +def facebook_login(data): + data = json.loads(data) + + if not (data.get("id") and data.get("fb_access_token")): + raise webnotes.ValidationError + + user = data["email"] + + if not get_fb_userid(data.get("fb_access_token")): + # garbage + raise webnotes.ValidationError + + if not webnotes.conn.exists("Profile", user): + if data.get("birthday"): + b = data.get("birthday").split("/") + data["birthday"] = b[2] + "-" + b[0] + "-" + b[1] + + profile = webnotes.bean({ + "doctype":"Profile", + "first_name": data["first_name"], + "last_name": data["last_name"], + "email": data["email"], + "enabled": 1, + "new_password": webnotes.generate_hash(data["email"]), + "fb_username": data["username"], + "fb_userid": data["id"], + "fb_location": data.get("location", {}).get("name"), + "fb_hometown": data.get("hometown", {}).get("name"), + "fb_age_range": data.get("age_range") and "{min}-{max}".format(**data.get("age_range")), + "birth_date": data.get("birthday"), + "fb_bio": data.get("bio"), + "fb_education": data.get("education") and data.get("education")[-1].get("type"), + "user_type": "Website User" + }) + profile.ignore_permissions = True + profile.get_controller().no_welcome_mail = True + profile.insert() + + webnotes.local.login_manager.user = user + webnotes.local.login_manager.post_login() + +def get_fb_userid(fb_access_token): + import requests + response = requests.get("https://graph.facebook.com/me?access_token=" + fb_access_token) + if response.status_code==200: + print response.json() + return response.json().get("id") + else: + return webnotes.AuthenticationError + def profile_query(doctype, txt, searchfield, start, page_len, filters): from webnotes.widgets.reportview import get_match_cond return webnotes.conn.sql("""select name, concat_ws(' ', first_name, middle_name, last_name) diff --git a/webnotes/core/doctype/profile/profile.txt b/webnotes/core/doctype/profile/profile.txt index a37cbbc3ac..9e7af19117 100644 --- a/webnotes/core/doctype/profile/profile.txt +++ b/webnotes/core/doctype/profile/profile.txt @@ -2,7 +2,7 @@ { "creation": "2013-03-07 11:54:44", "docstatus": 0, - "modified": "2014-01-23 13:27:37", + "modified": "2014-01-29 16:52:01", "modified_by": "Administrator", "owner": "Administrator" }, @@ -132,15 +132,6 @@ "options": "Loading...", "permlevel": 0 }, - { - "doctype": "DocField", - "fieldname": "birth_date", - "fieldtype": "Date", - "label": "Birth Date", - "oldfieldname": "birth_date", - "oldfieldtype": "Date", - "permlevel": 0 - }, { "default": "System User", "doctype": "DocField", @@ -154,17 +145,6 @@ "read_only": 1, "reqd": 1 }, - { - "doctype": "DocField", - "fieldname": "gender", - "fieldtype": "Select", - "label": "Gender", - "oldfieldname": "gender", - "oldfieldtype": "Select", - "options": "\nMale\nFemale\nOther", - "permlevel": 0, - "search_index": 0 - }, { "doctype": "DocField", "fieldname": "change_password", @@ -234,6 +214,39 @@ "label": "Short Bio", "permlevel": 0 }, + { + "doctype": "DocField", + "fieldname": "gender", + "fieldtype": "Select", + "label": "Gender", + "oldfieldname": "gender", + "oldfieldtype": "Select", + "options": "\nMale\nFemale\nOther", + "permlevel": 0, + "search_index": 0 + }, + { + "doctype": "DocField", + "fieldname": "birth_date", + "fieldtype": "Date", + "label": "Birth Date", + "oldfieldname": "birth_date", + "oldfieldtype": "Date", + "permlevel": 0 + }, + { + "doctype": "DocField", + "fieldname": "location", + "fieldtype": "Data", + "label": "Location", + "permlevel": 0 + }, + { + "doctype": "DocField", + "fieldname": "column_break_22", + "fieldtype": "Column Break", + "permlevel": 0 + }, { "doctype": "DocField", "fieldname": "bio", @@ -439,6 +452,29 @@ "print_hide": 1, "read_only": 1 }, + { + "doctype": "DocField", + "fieldname": "facebook_authentication", + "fieldtype": "Section Break", + "label": "Facebook Authentication", + "permlevel": 0 + }, + { + "doctype": "DocField", + "fieldname": "fb_username", + "fieldtype": "Data", + "label": "Facebook Username", + "permlevel": 0, + "read_only": 1 + }, + { + "doctype": "DocField", + "fieldname": "fb_userid", + "fieldtype": "Data", + "label": "Facebook User ID", + "permlevel": 0, + "read_only": 1 + }, { "create": 1, "delete": 1, @@ -461,6 +497,19 @@ "role": "All", "write": 0 }, + { + "create": 0, + "delete": 0, + "doctype": "DocPerm", + "email": 1, + "permlevel": 0, + "print": 1, + "report": 1, + "restricted": 1, + "role": "All", + "submit": 0, + "write": 0 + }, { "amend": 0, "create": 0, diff --git a/webnotes/handler.py b/webnotes/handler.py index e3d24479d4..a9fd171baf 100755 --- a/webnotes/handler.py +++ b/webnotes/handler.py @@ -119,4 +119,3 @@ def get_attr(cmd): method = globals()[cmd] webnotes.log("method:" + cmd) return method - diff --git a/webnotes/hooks.txt b/webnotes/hooks.txt index de96d2d02e..377302f4fd 100644 --- a/webnotes/hooks.txt +++ b/webnotes/hooks.txt @@ -6,13 +6,24 @@ app_icon = icon-cog app_version = 4.0.0-wip app_color = #3498db +before_install = webnotes.utils.install.before_install after_install = webnotes.utils.install.after_install +# website app_include_js = assets/js/webnotes.min.js app_include_css = assets/webnotes/css/splash.css app_include_css = assets/css/webnotes.css web_include_js = assets/js/webnotes-web.min.js web_include_css = assets/css/webnotes-web.css +web_include_js = website_script.js +web_include_css = style_settings.css + +website_clear_cache = webnotes.templates.generators.website_group.clear_cache + +website_group_handler:Forum = webnotes.templates.website_group.forum +website_group_handler:Events = webnotes.templates.website_group.events +website_group_handler:Tasks = webnotes.templates.website_group.tasks + get_desktop_icons = webnotes.manage.get_desktop_icons notification_config = webnotes.core.notifications.get_notification_config @@ -26,7 +37,7 @@ on_session_creation = webnotes.auth.notify_administrator_login # permissions permission_query_conditions:Event = webnotes.core.doctype.event.event.get_permission_query_conditions -has_permission:Event = webnotes.core.doctype.event.event.has_permission +has_permission:Event = webnotes.core.doctype.event.event.has_permission permission_query_conditions:ToDo = webnotes.core.doctype.todo.todo.get_permission_query_conditions -has_permission:ToDo = webnotes.core.doctype.todo.todo.has_permission \ No newline at end of file +has_permission:ToDo = webnotes.core.doctype.todo.todo.has_permission \ No newline at end of file diff --git a/webnotes/model/bean.py b/webnotes/model/bean.py index 1482ceb53d..9798984ec3 100644 --- a/webnotes/model/bean.py +++ b/webnotes/model/bean.py @@ -241,6 +241,8 @@ class Bean: return webnotes.local.response + return out + def get_attr(self, method): self.make_controller() return getattr(self.controller, method, None) diff --git a/webnotes/model/delete_doc.py b/webnotes/model/delete_doc.py index 24002b34d7..ffe14516a1 100644 --- a/webnotes/model/delete_doc.py +++ b/webnotes/model/delete_doc.py @@ -9,10 +9,11 @@ import webnotes.defaults from webnotes.utils.file_manager import remove_all from webnotes import _ -def delete_doc(doctype=None, name=None, doclist = None, force=0, ignore_doctypes=[], for_reload=False, ignore_permissions=False): +def delete_doc(doctype=None, name=None, doclist = None, force=0, ignore_doctypes=None, for_reload=False, ignore_permissions=False): """ Deletes a doc(dt, dn) and validates if it is not submitted and not linked in a live record """ + if not ignore_doctypes: ignore_doctypes = [] # get from form if not doctype: diff --git a/webnotes/model/rename_doc.py b/webnotes/model/rename_doc.py index cd4c5f58b0..754735a24a 100644 --- a/webnotes/model/rename_doc.py +++ b/webnotes/model/rename_doc.py @@ -8,7 +8,7 @@ import webnotes.model.doctype from webnotes.model.doc import validate_name @webnotes.whitelist() -def rename_doc(doctype, old, new, force=False, merge=False): +def rename_doc(doctype, old, new, force=False, merge=False, ignore_permissions=False): """ Renames a doc(dt, old) to doc(dt, new) and updates all linked fields of type "Link" or "Select" with "link:" @@ -23,11 +23,9 @@ def rename_doc(doctype, old, new, force=False, merge=False): doclist = webnotes.model.doctype.get(doctype) # call before_rename - old_obj = webnotes.get_obj(doctype, old) - if hasattr(old_obj, 'before_rename'): - new = old_obj.before_rename(old, new, merge) or new + new = webnotes.bean(doctype, old).run_method("before_rename", old, new, merge) or new - new = validate_rename(doctype, new, doclist, merge, force) + new = validate_rename(doctype, new, doclist, merge, force, ignore_permissions) if not merge: rename_parent_and_child(doctype, old, new, doclist) @@ -45,9 +43,7 @@ def rename_doc(doctype, old, new, force=False, merge=False): webnotes.delete_doc(doctype, old) # call after_rename - new_obj = webnotes.get_obj(doctype, new) - if hasattr(new_obj, 'after_rename'): - new_obj.after_rename(old, new, merge) + webnotes.bean(doctype, new).run_method("after_rename", old, new, merge) # update restrictions webnotes.conn.sql("""update tabDefaultValue set defvalue=%s where parenttype='Restriction' @@ -71,7 +67,7 @@ def rename_parent_and_child(doctype, old, new, doclist): update_child_docs(old, new, doclist) -def validate_rename(doctype, new, doclist, merge, force): +def validate_rename(doctype, new, doclist, merge, force, ignore_permissions): exists = webnotes.conn.exists(doctype, new) if merge and not exists: @@ -80,7 +76,7 @@ def validate_rename(doctype, new, doclist, merge, force): if (not merge) and exists: webnotes.msgprint("%s: %s exists, select a new, new name." % (doctype, new), raise_exception=1) - if not webnotes.has_permission(doctype, "write"): + if not (ignore_permissions or webnotes.has_permission(doctype, "write")): webnotes.msgprint("You need write permission to rename", raise_exception=1) if not force and not doclist[0].allow_rename: diff --git a/webnotes/patches.txt b/webnotes/patches.txt index d8781cab77..1a64ee71fe 100644 --- a/webnotes/patches.txt +++ b/webnotes/patches.txt @@ -9,4 +9,5 @@ execute:webnotes.reload_doc('core', 'doctype', 'report') #2013-13-26 webnotes.patches.4_0.remove_index_sitemap webnotes.patches.4_0.add_delete_permission webnotes.patches.4_0.move_match_to_restricted -webnotes.patches.4_0.set_todo_checked_as_closed \ No newline at end of file +webnotes.patches.4_0.set_todo_checked_as_closed +webnotes.patches.4_0.website_sitemap_hierarchy \ No newline at end of file diff --git a/webnotes/patches/4_0/website_sitemap_hierarchy.py b/webnotes/patches/4_0/website_sitemap_hierarchy.py new file mode 100644 index 0000000000..4fdb32af09 --- /dev/null +++ b/webnotes/patches/4_0/website_sitemap_hierarchy.py @@ -0,0 +1,22 @@ +# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors +# MIT License. See license.txt + +from __future__ import unicode_literals + +import webnotes + +def execute(): + webnotes.reload_doc("website", "doctype", "website_sitemap") + webnotes.reload_doc("website", "doctype", "website_sitemap_permission") + webnotes.reload_doc("website", "doctype", "website_group") + webnotes.reload_doc("website", "doctype", "post") + webnotes.reload_doc("website", "doctype", "user_vote") + + webnotes.conn.sql("""update `tabWebsite Sitemap` ws set ref_doctype=(select wsc.ref_doctype + from `tabWebsite Sitemap Config` wsc where wsc.name=ws.website_sitemap_config) + where ifnull(page_or_generator, '')!='Page'""") + + home_page = webnotes.conn.get_value("Website Settings", "Website Settings", "home_page") + home_page = webnotes.conn.get_value("Website Sitemap", {"docname": home_page}) or home_page + webnotes.conn.set_value("Website Settings", "Website Settings", "home_page", + home_page) diff --git a/webnotes/public/build.json b/webnotes/public/build.json index ce627b9139..68a807e494 100644 --- a/webnotes/public/build.json +++ b/webnotes/public/build.json @@ -7,10 +7,17 @@ ], "js/webnotes-web.min.js": [ "public/js/lib/bootstrap.min.js", + "public/js/wn/provide.js", "public/js/wn/misc/number_format.js", "public/js/lib/nprogress.js", "public/js/wn/translate.js", - "website/js/website.js" + "public/js/wn/misc/pretty_date.js", + "website/js/website.js", + "website/js/website_group.js" + ], + "js/canvasResize.min.js": [ + "website/js/jquery.exif.js", + "website/js/jquery.canvasResize.js" ], "js/editor.min.js": [ "public/js/lib/jquery/jquery.hotkeys.js", diff --git a/webnotes/public/css/common.css b/webnotes/public/css/common.css index 422dd78245..d0bc1c77d3 100644 --- a/webnotes/public/css/common.css +++ b/webnotes/public/css/common.css @@ -316,6 +316,11 @@ div#freeze { max-height: 15px; } +.navbar-brand { + min-height: 20px; + height: auto; +} + .navbar #spinner { display: block; float: right; diff --git a/webnotes/templates/base.html b/webnotes/templates/base.html index b6b614324f..e61e5e4d47 100644 --- a/webnotes/templates/base.html +++ b/webnotes/templates/base.html @@ -6,37 +6,78 @@