seitime-frappe/frappe/desk/page/applications/applications.py
2017-09-04 16:05:57 +05:30

125 lines
3.8 KiB
Python

# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt
from __future__ import unicode_literals
import frappe
import frappe.utils
import frappe.installer
import frappe.sessions
import subprocess
import os
import json
from frappe import _
from distutils.spawn import find_executable
from frappe.utils.background_jobs import enqueue
from six.moves import reload_module
@frappe.whitelist()
def get_app_list():
"""Get list of all apps with properties, installed, category from hooks and
`frappe/data/app_listing/` if an entry exists"""
out = {}
installed = frappe.get_installed_apps()
for app in frappe.get_all_apps(True):
app_hooks = frappe.get_hooks(app_name=app)
if app not in installed and app_hooks.get('hide_in_installer'):
continue
out[app] = {}
for key in ("app_name", "app_title", "app_description", "app_icon",
"app_publisher", "app_version", "app_url", "app_color"):
val = app_hooks.get(key) or []
out[app][key] = val[0] if len(val) else ""
if app in installed:
out[app]["installed"] = 1
for app_from_list in get_app_listing().values():
if app_from_list.app_name in out:
out[app_from_list.app_name].update(app_from_list)
else:
if not frappe.conf.disallow_app_listing:
out[app_from_list.app_name] = app_from_list
return out
def get_app_listing():
"""Get apps listed in `frappe/data/app_listing/`"""
apps_listing_dir = os.path.join(os.path.dirname(frappe.__file__), 'data', 'app_listing')
out = {}
for app in os.listdir(apps_listing_dir):
if app.endswith(".json"):
with open(os.path.join(apps_listing_dir, app)) as f:
out[app[:-5]] = frappe._dict(json.load(f))
return out
@frappe.whitelist()
def install_app(name):
"""Install app, if app is not installed in local environment, install it via git url in
`frappe/data/app_listing/`"""
frappe.only_for("System Manager")
if name not in frappe.get_all_apps(True):
if not frappe.conf.disallow_app_listing:
get_app(name)
frappe.cache().delete_value(["app_hooks"])
# reload sys.path
import site
reload_module(site)
else:
# will only come via direct API
frappe.throw(_("Listing app not allowed"))
app_hooks = frappe.get_hooks(app_name=name)
if app_hooks.get('hide_in_installer'):
frappe.throw(_("You cannot install this app"))
enqueue('frappe.desk.page.applications.applications.start_install', name=name)
frappe.msgprint(_('Queued for install'))
def start_install(name):
frappe.publish_realtime("install_app_progress", {"status": _("Installing App {0}").format(name)},
user=frappe.session.user)
frappe.installer.install_app(name)
frappe.publish_realtime("install_app_progress", {"status": _("{0} Installed").format(name)},
user=frappe.session.user)
@frappe.whitelist()
def remove_app(name):
"""Remove installed app"""
frappe.only_for("System Manager")
if name in frappe.get_installed_apps():
enqueue('frappe.desk.page.applications.applications.start_remove', name=name)
frappe.msgprint(_('Queued for backup and removing {0}').format(frappe.bold(name)))
def start_remove(name):
frappe.installer.remove_app(app_name=name, yes=True)
frappe.publish_realtime('msgprint', _('App {0} removed').format(frappe.bold(name)))
def get_app(name):
"""Get app using git clone and install it in bench environment"""
app_listing = get_app_listing()
if name not in app_listing:
frappe.throw(_("Unknown app {0}").format(name))
raise frappe.ValidationError
frappe.publish_realtime("install_app_progress", {"status": _("Downloading App {0}").format(name)},
user=frappe.session.user)
args = [find_executable('bench'), 'get-app', name, app_listing[name]['repo_url']]
try:
subprocess.check_call(args, cwd=frappe.utils.get_bench_path(),
stderr=subprocess.STDOUT)
return "okay"
except subprocess.CalledProcessError as e:
frappe.msgprint("<b>" + " ".join(args) + "</b>")
frappe.msgprint(e.output)
return e.output