You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

278 rivejä
8.0 KiB

  1. # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
  2. # License: See license.txt
  3. from __future__ import unicode_literals
  4. import frappe, json, os
  5. from frappe.utils import strip, cint
  6. from frappe.translate import (set_default_language, get_dict, send_translations)
  7. from frappe.geo.country_info import get_country_info
  8. from frappe.utils.file_manager import save_file
  9. from frappe.utils.password import update_password
  10. from werkzeug.useragents import UserAgent
  11. import install_fixtures
  12. from six import string_types
  13. @frappe.whitelist()
  14. def setup_complete(args):
  15. """Calls hooks for `setup_wizard_complete`, sets home page as `desktop`
  16. and clears cache. If wizard breaks, calls `setup_wizard_exception` hook"""
  17. if cint(frappe.db.get_single_value('System Settings', 'setup_complete')):
  18. # do not throw an exception if setup is already complete
  19. # let the user continue to desk
  20. return
  21. #frappe.throw(_('Setup already complete'))
  22. args = process_args(args)
  23. try:
  24. if args.language and args.language != "english":
  25. set_default_language(get_language_code(args.lang))
  26. frappe.clear_cache()
  27. # update system settings
  28. update_system_settings(args)
  29. update_user_name(args)
  30. for method in frappe.get_hooks("setup_wizard_complete"):
  31. frappe.get_attr(method)(args)
  32. disable_future_access()
  33. frappe.db.commit()
  34. frappe.clear_cache()
  35. except:
  36. frappe.db.rollback()
  37. if args:
  38. traceback = frappe.get_traceback()
  39. for hook in frappe.get_hooks("setup_wizard_exception"):
  40. frappe.get_attr(hook)(traceback, args)
  41. raise
  42. else:
  43. for hook in frappe.get_hooks("setup_wizard_success"):
  44. frappe.get_attr(hook)(args)
  45. install_fixtures.install()
  46. def update_system_settings(args):
  47. number_format = get_country_info(args.get("country")).get("number_format", "#,###.##")
  48. # replace these as float number formats, as they have 0 precision
  49. # and are currency number formats and not for floats
  50. if number_format=="#.###":
  51. number_format = "#.###,##"
  52. elif number_format=="#,###":
  53. number_format = "#,###.##"
  54. system_settings = frappe.get_doc("System Settings", "System Settings")
  55. system_settings.update({
  56. "country": args.get("country"),
  57. "language": get_language_code(args.get("language")),
  58. "time_zone": args.get("timezone"),
  59. "float_precision": 3,
  60. 'date_format': frappe.db.get_value("Country", args.get("country"), "date_format"),
  61. 'number_format': number_format,
  62. 'enable_scheduler': 1 if not frappe.flags.in_test else 0,
  63. 'backup_limit': 3 # Default for downloadable backups
  64. })
  65. system_settings.save()
  66. def update_user_name(args):
  67. first_name, last_name = args.get('full_name'), ''
  68. if ' ' in first_name:
  69. first_name, last_name = first_name.split(' ', 1)
  70. if args.get("email"):
  71. if frappe.db.exists('User', args.get('email')):
  72. # running again
  73. return
  74. args['name'] = args.get("email")
  75. _mute_emails, frappe.flags.mute_emails = frappe.flags.mute_emails, True
  76. doc = frappe.get_doc({
  77. "doctype":"User",
  78. "email": args.get("email"),
  79. "first_name": first_name,
  80. "last_name": last_name
  81. })
  82. doc.flags.no_welcome_mail = True
  83. doc.insert()
  84. frappe.flags.mute_emails = _mute_emails
  85. update_password(args.get("email"), args.get("password"))
  86. else:
  87. args.update({
  88. "name": frappe.session.user,
  89. "first_name": first_name,
  90. "last_name": last_name
  91. })
  92. frappe.db.sql("""update `tabUser` SET first_name=%(first_name)s,
  93. last_name=%(last_name)s WHERE name=%(name)s""", args)
  94. if args.get("attach_user"):
  95. attach_user = args.get("attach_user").split(",")
  96. if len(attach_user)==3:
  97. filename, filetype, content = attach_user
  98. fileurl = save_file(filename, content, "User", args.get("name"), decode=True).file_url
  99. frappe.db.set_value("User", args.get("name"), "user_image", fileurl)
  100. add_all_roles_to(args.get("name"))
  101. def process_args(args):
  102. if not args:
  103. args = frappe.local.form_dict
  104. if isinstance(args, string_types):
  105. args = json.loads(args)
  106. args = frappe._dict(args)
  107. # strip the whitespace
  108. for key, value in args.items():
  109. if isinstance(value, string_types):
  110. args[key] = strip(value)
  111. return args
  112. def add_all_roles_to(name):
  113. user = frappe.get_doc("User", name)
  114. for role in frappe.db.sql("""select name from tabRole"""):
  115. if role[0] not in ["Administrator", "Guest", "All", "Customer", "Supplier", "Partner", "Employee"]:
  116. d = user.append("roles")
  117. d.role = role[0]
  118. user.save()
  119. def disable_future_access():
  120. frappe.db.set_default('desktop:home_page', 'desktop')
  121. frappe.db.set_value('System Settings', 'System Settings', 'setup_complete', 1)
  122. if not frappe.flags.in_test:
  123. # remove all roles and add 'Administrator' to prevent future access
  124. page = frappe.get_doc('Page', 'setup-wizard')
  125. page.roles = []
  126. page.append('roles', {'role': 'Administrator'})
  127. page.flags.do_not_update_json = True
  128. page.flags.ignore_permissions = True
  129. page.save()
  130. @frappe.whitelist()
  131. def load_messages(language):
  132. """Load translation messages for given language from all `setup_wizard_requires`
  133. javascript files"""
  134. frappe.clear_cache()
  135. set_default_language(get_language_code(language))
  136. m = get_dict("page", "setup-wizard")
  137. for path in frappe.get_hooks("setup_wizard_requires"):
  138. # common folder `assets` served from `sites/`
  139. js_file_path = os.path.abspath(frappe.get_site_path("..", *path.strip("/").split("/")))
  140. m.update(get_dict("jsfile", js_file_path))
  141. m.update(get_dict("boot"))
  142. send_translations(m)
  143. return frappe.local.lang
  144. @frappe.whitelist()
  145. def load_languages():
  146. language_codes = frappe.db.sql('select language_code, language_name from tabLanguage order by name', as_dict=True)
  147. codes_to_names = {}
  148. for d in language_codes:
  149. codes_to_names[d.language_code] = d.language_name
  150. return {
  151. "default_language": frappe.db.get_value('Language', frappe.local.lang, 'language_name') or frappe.local.lang,
  152. "languages": sorted(frappe.db.sql_list('select language_name from tabLanguage order by name')),
  153. "codes_to_names": codes_to_names
  154. }
  155. @frappe.whitelist()
  156. def load_country():
  157. from frappe.sessions import get_geo_ip_country
  158. return get_geo_ip_country(frappe.local.request_ip) if frappe.local.request_ip else None
  159. @frappe.whitelist()
  160. def load_user_details():
  161. return {
  162. "full_name": frappe.cache().hget("full_name", "signup"),
  163. "email": frappe.cache().hget("email", "signup")
  164. }
  165. def prettify_args(args):
  166. # remove attachments
  167. for key, val in args.items():
  168. if isinstance(val, string_types) and "data:image" in val:
  169. filename = val.split("data:image", 1)[0].strip(", ")
  170. size = round((len(val) * 3 / 4) / 1048576.0, 2)
  171. args[key] = "Image Attached: '{0}' of size {1} MB".format(filename, size)
  172. pretty_args = []
  173. for key in sorted(args):
  174. pretty_args.append("{} = {}".format(key, args[key]))
  175. return pretty_args
  176. def email_setup_wizard_exception(traceback, args):
  177. if not frappe.local.conf.setup_wizard_exception_email:
  178. return
  179. pretty_args = prettify_args(args)
  180. if frappe.local.request:
  181. user_agent = UserAgent(frappe.local.request.headers.get('User-Agent', ''))
  182. else:
  183. user_agent = frappe._dict()
  184. message = """
  185. #### Basic Information
  186. - **Site:** {site}
  187. - **User:** {user}
  188. - **Browser:** {user_agent.platform} {user_agent.browser} version: {user_agent.version} language: {user_agent.language}
  189. - **Browser Languages**: `{accept_languages}`
  190. ---
  191. #### Traceback
  192. <pre>{traceback}</pre>
  193. ---
  194. #### Setup Wizard Arguments
  195. <pre>{args}</pre>
  196. ---
  197. #### Request Headers
  198. <pre>{headers}</pre>""".format(
  199. site=frappe.local.site,
  200. traceback=traceback,
  201. args="\n".join(pretty_args),
  202. user=frappe.session.user,
  203. user_agent=user_agent,
  204. headers=frappe.local.request.headers,
  205. accept_languages=", ".join(frappe.local.request.accept_languages.values()))
  206. frappe.sendmail(recipients=frappe.local.conf.setup_wizard_exception_email,
  207. sender=frappe.session.user,
  208. subject="Exception in Setup Wizard - {}".format(frappe.local.site),
  209. message=message,
  210. delayed=False)
  211. def get_language_code(lang):
  212. return frappe.db.get_value('Language', {'language_name':lang})
  213. def enable_twofactor_all_roles():
  214. all_role = frappe.get_doc('Role',{'role_name':'All'})
  215. all_role.two_factor_auth = True
  216. all_role.save(ignore_permissions=True)