diff --git a/frappe/boot.py b/frappe/boot.py index ba3c353fcf..c7827ccb71 100644 --- a/frappe/boot.py +++ b/frappe/boot.py @@ -11,7 +11,7 @@ import frappe.defaults import frappe.desk.desk_page from frappe.utils import get_gravatar, get_url from frappe.desk.form.load import get_meta_bundle -from frappe.change_log import get_versions +from frappe.utils.change_log import get_versions def get_bootinfo(): """build and return boot info""" diff --git a/frappe/change_log/__init__.py b/frappe/change_log/__init__.py index aac9b17d3c..e69de29bb2 100644 --- a/frappe/change_log/__init__.py +++ b/frappe/change_log/__init__.py @@ -1,96 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors -# MIT License. See license.txt - -from __future__ import unicode_literals -import os -import json -from semantic_version import Version -import frappe -from frappe.utils import cstr - -def get_change_log(user=None): - if not user: user = frappe.session.user - - last_known_versions = frappe._dict(json.loads(frappe.db.get_value("User", user, "last_known_versions") or "{}")) - current_versions = get_versions() - - if not last_known_versions: - update_last_known_versions() - return [] - - change_log = [] - for app, opts in current_versions.items(): - from_version = last_known_versions.get(app, {}).get("version") or "0.0.1" - to_version = opts["version"] - - if from_version != to_version: - app_change_log = get_change_log_for_app(app, from_version=from_version, to_version=to_version) - - if app_change_log: - change_log.append({ - "title": opts["title"], - "description": opts["description"], - "version": to_version, - "change_log": app_change_log - }) - - return change_log - -def get_change_log_for_app(app, from_version, to_version): - change_log_folder = os.path.join(frappe.get_app_path(app), "change_log") - if not os.path.exists(change_log_folder): - return - - from_version = Version(from_version) - to_version = Version(to_version) - # remove pre-release part - to_version.prerelease = None - - major_version_folders = ["v{0}".format(i) for i in xrange(from_version.major, to_version.major + 1)] - app_change_log = [] - - for folder in os.listdir(change_log_folder): - if folder in major_version_folders: - for file in os.listdir(os.path.join(change_log_folder, folder)): - version = Version(os.path.splitext(file)[0][1:].replace("_", ".")) - - if from_version < version <= to_version: - file_path = os.path.join(change_log_folder, folder, file) - content = frappe.read_file(file_path) - app_change_log.append([version, content]) - - app_change_log = sorted(app_change_log, key=lambda d: d[0], reverse=True) - - # convert version to string and send - return [[cstr(d[0]), d[1]] for d in app_change_log] - -@frappe.whitelist() -def update_last_known_versions(): - frappe.db.set_value("User", frappe.session.user, "last_known_versions", json.dumps(get_versions()), update_modified=False) - -@frappe.whitelist() -def get_versions(): - """Get versions of all installed apps. - - Example: - - { - "frappe": { - "title": "Frappe Framework", - "version": "5.0.0" - } - }""" - versions = {} - for app in frappe.get_installed_apps(sort=True): - versions[app] = { - "title": frappe.get_hooks("app_title", app_name=app), - "description": frappe.get_hooks("app_description", app_name=app) - } - try: - versions[app]["version"] = frappe.get_attr(app + ".__version__") - except AttributeError: - versions[app]["version"] = '0.0.1' - - return versions - - diff --git a/frappe/change_log/v5/v5_0_0.md b/frappe/change_log/v5/v5_0_0.md deleted file mode 100644 index ef5b12edc2..0000000000 --- a/frappe/change_log/v5/v5_0_0.md +++ /dev/null @@ -1,13 +0,0 @@ -### Version 5 - -Please see https://frappe.io/version-5 - -Changes include: - -1. New Visual Design -1. Custom DocTypes -1. Email Accounts -1. Email Replies and Notifications -1. Print Format Builder -1. Document Sharing - diff --git a/frappe/public/js/frappe/change_log.html b/frappe/public/js/frappe/change_log.html index 69337adcbd..c05aadfe27 100644 --- a/frappe/public/js/frappe/change_log.html +++ b/frappe/public/js/frappe/change_log.html @@ -1,17 +1,16 @@ -{% for (var i=0, l=change_log.length; i < l; i++) { var app_info = change_log[0]; %} +{% for (var i=0, l=change_log.length; i < l; i++) { + var app_info = change_log[i]; %} {% if (i > 0) { %}
{% } %}
-

{%= app_info.title %} - {%= __("updated to {0}", [app_info.version]) %} - {% if (app_info.title != app_info.description) { %} -
- {%= app_info.description %} - {% } %} +

+ {{ app_info.title }} + {{ __("updated to {0}", [app_info.version]) }}

- {% for (var x=0, y=app_info.change_log.length; x < y; x++) { var version_info = app_info.change_log[i]; %} -
-

{%= __("New in version {0}", [version_info[0]]) %}

-

{%= frappe.markdown(version_info[1]) %}

- {% } %} + {% for (var x=0, y=app_info.change_log.length; x < y; x++) { + var version_info = app_info.change_log[x]; + if(version_info) { %} +

{{ frappe.markdown(version_info[1]) }}

+ {% } + } %}
{% } %} diff --git a/frappe/public/js/frappe/desk.js b/frappe/public/js/frappe/desk.js index 96755ae8cd..007efdfd45 100644 --- a/frappe/public/js/frappe/desk.js +++ b/frappe/public/js/frappe/desk.js @@ -293,7 +293,7 @@ frappe.Application = Class.extend({ d.keep_open = true; d.custom_onhide = function() { frappe.call({ - "method": "frappe.change_log.update_last_known_versions" + "method": "frappe.utils.change_log.update_last_known_versions" }); }; } diff --git a/frappe/sessions.py b/frappe/sessions.py index 41baa0d4f2..04818dd05a 100644 --- a/frappe/sessions.py +++ b/frappe/sessions.py @@ -15,7 +15,7 @@ from frappe.utils import cint, cstr import frappe.model.meta import frappe.defaults import frappe.translate -import frappe.change_log +from frappe.utils.change_log import get_change_log import redis from urllib import unquote @@ -114,7 +114,7 @@ def get(): # check only when clear cache is done, and don't cache this if frappe.local.request: - bootinfo["change_log"] = frappe.change_log.get_change_log() + bootinfo["change_log"] = get_change_log() bootinfo["metadata_version"] = frappe.cache().get_value("metadata_version") if not bootinfo["metadata_version"]: @@ -124,7 +124,6 @@ def get(): frappe.get_attr(hook)(bootinfo=bootinfo) bootinfo["lang"] = frappe.translate.get_user_lang() - return bootinfo class Session: diff --git a/frappe/templates/pages/desk.py b/frappe/templates/pages/desk.py index ef295d017a..c8d262ca75 100644 --- a/frappe/templates/pages/desk.py +++ b/frappe/templates/pages/desk.py @@ -21,6 +21,8 @@ def get_context(context): boot = frappe.sessions.get() boot_json = frappe.as_json(boot) + frappe.db.commit() + # remove script tags from boot boot_json = re.sub("\[^<]*\", "", boot_json) diff --git a/frappe/utils/change_log.py b/frappe/utils/change_log.py new file mode 100644 index 0000000000..5e53bb708f --- /dev/null +++ b/frappe/utils/change_log.py @@ -0,0 +1,105 @@ +# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors +# MIT License. See license.txt + +from __future__ import unicode_literals +import os +import json +from semantic_version import Version +import frappe +from frappe.utils import cstr + +def get_change_log(user=None): + if not user: user = frappe.session.user + + last_known_versions = frappe._dict(json.loads(frappe.db.get_value("User", + user, "last_known_versions") or "{}")) + current_versions = get_versions() + + if not last_known_versions: + update_last_known_versions() + return [] + + change_log = [] + def set_in_change_log(app, opts, change_log): + from_version = last_known_versions.get(app, {}).get("version") or "0.0.1" + to_version = opts["version"] + + if from_version != to_version: + app_change_log = get_change_log_for_app(app, from_version=from_version, to_version=to_version) + + if app_change_log: + change_log.append({ + "title": opts["title"], + "description": opts["description"], + "version": to_version, + "change_log": app_change_log + }) + + for app, opts in current_versions.items(): + if app != "frappe": + set_in_change_log(app, opts, change_log) + + if "frappe" in current_versions: + set_in_change_log("frappe", current_versions["frappe"], change_log) + + return change_log + +def get_change_log_for_app(app, from_version, to_version): + change_log_folder = os.path.join(frappe.get_app_path(app), "change_log") + if not os.path.exists(change_log_folder): + return + + from_version = Version(from_version) + to_version = Version(to_version) + # remove pre-release part + to_version.prerelease = None + + major_version_folders = ["v{0}".format(i) for i in xrange(from_version.major, to_version.major + 1)] + app_change_log = [] + + for folder in os.listdir(change_log_folder): + if folder in major_version_folders: + for file in os.listdir(os.path.join(change_log_folder, folder)): + version = Version(os.path.splitext(file)[0][1:].replace("_", ".")) + + if from_version < version <= to_version: + file_path = os.path.join(change_log_folder, folder, file) + content = frappe.read_file(file_path) + app_change_log.append([version, content]) + + app_change_log = sorted(app_change_log, key=lambda d: d[0], reverse=True) + + # convert version to string and send + return [[cstr(d[0]), d[1]] for d in app_change_log] + +@frappe.whitelist() +def update_last_known_versions(): + frappe.db.set_value("User", frappe.session.user, "last_known_versions", + json.dumps(get_versions()), update_modified=False) + +@frappe.whitelist() +def get_versions(): + """Get versions of all installed apps. + + Example: + + { + "frappe": { + "title": "Frappe Framework", + "version": "5.0.0" + } + }""" + versions = {} + for app in frappe.get_installed_apps(sort=True): + versions[app] = { + "title": frappe.get_hooks("app_title", app_name=app)[0], + "description": frappe.get_hooks("app_description", app_name=app)[0] + } + try: + versions[app]["version"] = frappe.get_attr(app + ".__version__") + except AttributeError: + versions[app]["version"] = '0.0.1' + + return versions + +