您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 
 
 

535 行
14 KiB

  1. # Copyright (c) 2013, Web Notes Technologies Pvt. Ltd.
  2. # MIT License. See license.txt
  3. """
  4. globals attached to webnotes module
  5. + some utility functions that should probably be moved
  6. """
  7. from __future__ import unicode_literals
  8. from werkzeug.local import Local
  9. import os
  10. import json
  11. local = Local()
  12. class _dict(dict):
  13. """dict like object that exposes keys as attributes"""
  14. def __getattr__(self, key):
  15. return self.get(key)
  16. def __setattr__(self, key, value):
  17. self[key] = value
  18. def __getstate__(self):
  19. return self
  20. def __setstate__(self, d):
  21. self.update(d)
  22. def update(self, d):
  23. """update and return self -- the missing dict feature in python"""
  24. super(_dict, self).update(d)
  25. return self
  26. def copy(self):
  27. return _dict(super(_dict, self).copy())
  28. def __getattr__(self, key):
  29. return webnotes.local.get("key", None)
  30. def _(msg):
  31. """translate object in current lang, if exists"""
  32. from webnotes.translate import messages
  33. return messages.get(lang, {}).get(msg, msg)
  34. def set_user_lang(user, user_language=None):
  35. from webnotes.translate import get_lang_dict
  36. if not user_language:
  37. user_language = conn.get_value("Profile", user, "language")
  38. if user_language:
  39. lang_dict = get_lang_dict()
  40. if user_language in lang_dict:
  41. local.lang = lang_dict[user_language]
  42. def load_translations(module, doctype, name):
  43. from webnotes.translate import load_doc_messages
  44. load_doc_messages(module, doctype, name)
  45. # local-globals
  46. conn = local("conn")
  47. conf = local("conf")
  48. form = form_dict = local("form_dict")
  49. request = local("request")
  50. request_method = local("request_method")
  51. response = local("response")
  52. _response = local("_response")
  53. session = local("session")
  54. user = local("user")
  55. error_log = local("error_log")
  56. debug_log = local("debug_log")
  57. message_log = local("message_log")
  58. lang = local("lang")
  59. def init(site=None):
  60. local.error_log = []
  61. local.message_log = []
  62. local.debug_log = []
  63. local.response = _dict({})
  64. local.lang = "en"
  65. local.request_method = request.method if request else None
  66. local.conf = get_conf(site)
  67. _memc = None
  68. mute_emails = False
  69. mute_messages = False
  70. test_objects = {}
  71. print_messages = False
  72. in_import = False
  73. in_test = False
  74. rollback_on_exception = False
  75. # memcache
  76. def cache():
  77. global _memc
  78. if not _memc:
  79. from webnotes.memc import MClient
  80. _memc = MClient(['localhost:11211'])
  81. return _memc
  82. class DuplicateEntryError(Exception): pass
  83. class ValidationError(Exception): pass
  84. class AuthenticationError(Exception): pass
  85. class PermissionError(Exception): pass
  86. class OutgoingEmailError(ValidationError): pass
  87. class UnknownDomainError(Exception): pass
  88. class SessionStopped(Exception): pass
  89. class MappingMismatchError(ValidationError): pass
  90. class InvalidStatusError(ValidationError): pass
  91. class DoesNotExistError(ValidationError): pass
  92. class MandatoryError(ValidationError): pass
  93. def getTraceback():
  94. import utils
  95. return utils.getTraceback()
  96. def errprint(msg):
  97. from utils import cstr
  98. if not request:
  99. print cstr(msg)
  100. error_log.append(cstr(msg))
  101. def log(msg):
  102. if not request:
  103. import conf
  104. if getattr(conf, "logging", False):
  105. print repr(msg)
  106. from utils import cstr
  107. debug_log.append(cstr(msg))
  108. def msgprint(msg, small=0, raise_exception=0, as_table=False):
  109. def _raise_exception():
  110. if raise_exception:
  111. if rollback_on_exception:
  112. conn.rollback()
  113. import inspect
  114. if inspect.isclass(raise_exception) and issubclass(raise_exception, Exception):
  115. raise raise_exception, msg
  116. else:
  117. raise ValidationError, msg
  118. if mute_messages:
  119. _raise_exception()
  120. return
  121. from utils import cstr
  122. if as_table and type(msg) in (list, tuple):
  123. msg = '<table border="1px" style="border-collapse: collapse" cellpadding="2px">' + ''.join(['<tr>'+''.join(['<td>%s</td>' % c for c in r])+'</tr>' for r in msg]) + '</table>'
  124. if print_messages:
  125. print "Message: " + repr(msg)
  126. message_log.append((small and '__small:' or '')+cstr(msg or ''))
  127. _raise_exception()
  128. def throw(msg, exc=ValidationError):
  129. msgprint(msg, raise_exception=exc)
  130. def create_folder(path):
  131. import os
  132. try:
  133. os.makedirs(path)
  134. except OSError, e:
  135. if e.args[0]!=17:
  136. raise e
  137. def create_symlink(source_path, link_path):
  138. import os
  139. try:
  140. os.symlink(source_path, link_path)
  141. except OSError, e:
  142. if e.args[0]!=17:
  143. raise e
  144. def remove_file(path):
  145. import os
  146. try:
  147. os.remove(path)
  148. except OSError, e:
  149. if e.args[0]!=2:
  150. raise e
  151. def connect(db_name=None, password=None):
  152. import webnotes.db
  153. local.conn = webnotes.db.Database(user=db_name, password=password)
  154. local.session = _dict({'user':'Administrator'})
  155. local.response = _dict()
  156. local.form_dict = _dict()
  157. import webnotes.profile
  158. local.user = webnotes.profile.Profile('Administrator')
  159. def get_request_header(key, default=None):
  160. try:
  161. return request.headers.get(key, default)
  162. except Exception, e:
  163. return None
  164. logger = None
  165. def get_db_password(db_name):
  166. """get db password from conf"""
  167. import conf
  168. if hasattr(conf, 'get_db_password'):
  169. return conf.get_db_password(db_name)
  170. elif hasattr(conf, 'db_password'):
  171. return conf.db_password
  172. else:
  173. return db_name
  174. whitelisted = []
  175. guest_methods = []
  176. def whitelist(allow_guest=False, allow_roles=None):
  177. """
  178. decorator for whitelisting a function
  179. Note: if the function is allowed to be accessed by a guest user,
  180. it must explicitly be marked as allow_guest=True
  181. for specific roles, set allow_roles = ['Administrator'] etc.
  182. """
  183. def innerfn(fn):
  184. global whitelisted, guest_methods
  185. whitelisted.append(fn)
  186. if allow_guest:
  187. guest_methods.append(fn)
  188. if allow_roles:
  189. roles = get_roles()
  190. allowed = False
  191. for role in allow_roles:
  192. if role in roles:
  193. allowed = True
  194. break
  195. if not allowed:
  196. raise PermissionError, "Method not allowed"
  197. return fn
  198. return innerfn
  199. def clear_cache(user=None, doctype=None):
  200. """clear cache"""
  201. if doctype:
  202. from webnotes.model.doctype import clear_cache
  203. clear_cache(doctype)
  204. elif user:
  205. from webnotes.sessions import clear_cache
  206. clear_cache(user)
  207. else:
  208. from webnotes.sessions import clear_cache
  209. clear_cache()
  210. def get_roles(user=None, with_standard=True):
  211. """get roles of current user"""
  212. if not user:
  213. user = session.user
  214. if user=='Guest':
  215. return ['Guest']
  216. roles = [r[0] for r in conn.sql("""select role from tabUserRole
  217. where parent=%s and role!='All'""", user)] + ['All']
  218. # filter standard if required
  219. if not with_standard:
  220. roles = filter(lambda x: x not in ['All', 'Guest', 'Administrator'], roles)
  221. return roles
  222. def check_admin_or_system_manager():
  223. if ("System Manager" not in get_roles()) and \
  224. (session.user!="Administrator"):
  225. msgprint("Only Allowed for Role System Manager or Administrator", raise_exception=True)
  226. def has_permission(doctype, ptype="read", refdoc=None):
  227. """check if user has permission"""
  228. from webnotes.defaults import get_user_default_as_list
  229. if session.user=="Administrator":
  230. return True
  231. if conn.get_value("DocType", doctype, "istable"):
  232. return True
  233. if isinstance(refdoc, basestring):
  234. refdoc = doc(doctype, refdoc)
  235. perms = conn.sql("""select `name`, `match` from tabDocPerm p
  236. where p.parent = %s
  237. and ifnull(p.`%s`,0) = 1
  238. and ifnull(p.permlevel,0) = 0
  239. and (p.role="All" or p.role in (select `role` from tabUserRole where `parent`=%s))
  240. """ % ("%s", ptype, "%s"), (doctype, session.user), as_dict=1)
  241. if refdoc:
  242. match_failed = {}
  243. for p in perms:
  244. if p.match:
  245. if ":" in p.match:
  246. keys = p.match.split(":")
  247. else:
  248. keys = [p.match, p.match]
  249. if refdoc.fields.get(keys[0],"[No Value]") in get_user_default_as_list(keys[1]):
  250. return True
  251. else:
  252. match_failed[keys[0]] = refdoc.fields.get(keys[0],"[No Value]")
  253. else:
  254. # found a permission without a match
  255. return True
  256. # no valid permission found
  257. if match_failed:
  258. doctypelist = get_doctype(doctype)
  259. msg = _("Not allowed for: ")
  260. for key in match_failed:
  261. msg += "\n" + (doctypelist.get_field(key) and doctypelist.get_label(key) or key) \
  262. + " = " + (match_failed[key] or "None")
  263. msgprint(msg)
  264. return False
  265. else:
  266. return perms and True or False
  267. def generate_hash():
  268. """Generates random hash for session id"""
  269. import hashlib, time
  270. return hashlib.sha224(str(time.time())).hexdigest()
  271. def get_obj(dt = None, dn = None, doc=None, doclist=[], with_children = True):
  272. from webnotes.model.code import get_obj
  273. return get_obj(dt, dn, doc, doclist, with_children)
  274. def doc(doctype=None, name=None, fielddata=None):
  275. from webnotes.model.doc import Document
  276. return Document(doctype, name, fielddata)
  277. def new_doc(doctype, parent_doc=None, parentfield=None):
  278. from webnotes.model.create_new import get_new_doc
  279. return get_new_doc(doctype, parent_doc, parentfield)
  280. def new_bean(doctype):
  281. from webnotes.model.create_new import get_new_doc
  282. return bean([get_new_doc(doctype)])
  283. def doclist(lst=None):
  284. from webnotes.model.doclist import DocList
  285. return DocList(lst)
  286. def bean(doctype=None, name=None, copy=None):
  287. """return an instance of the object, wrapped as a Bean (webnotes.model.bean)"""
  288. from webnotes.model.bean import Bean
  289. if copy:
  290. return Bean(copy_doclist(copy))
  291. else:
  292. return Bean(doctype, name)
  293. def set_value(doctype, docname, fieldname, value):
  294. import webnotes.client
  295. return webnotes.client.set_value(doctype, docname, fieldname, value)
  296. def get_doclist(doctype, name=None):
  297. return bean(doctype, name).doclist
  298. def get_doctype(doctype, processed=False):
  299. import webnotes.model.doctype
  300. return webnotes.model.doctype.get(doctype, processed)
  301. def delete_doc(doctype=None, name=None, doclist = None, force=0, ignore_doctypes=None, for_reload=False, ignore_permissions=False):
  302. import webnotes.model.utils
  303. if not ignore_doctypes:
  304. ignore_doctypes = []
  305. if isinstance(name, list):
  306. for n in name:
  307. webnotes.model.utils.delete_doc(doctype, n, doclist, force, ignore_doctypes, for_reload, ignore_permissions)
  308. else:
  309. webnotes.model.utils.delete_doc(doctype, name, doclist, force, ignore_doctypes, for_reload, ignore_permissions)
  310. def clear_perms(doctype):
  311. conn.sql("""delete from tabDocPerm where parent=%s""", doctype)
  312. def reset_perms(doctype):
  313. clear_perms(doctype)
  314. reload_doc(conn.get_value("DocType", doctype, "module"), "DocType", doctype, force=True)
  315. def reload_doc(module, dt=None, dn=None, force=False):
  316. import webnotes.modules
  317. return webnotes.modules.reload_doc(module, dt, dn, force)
  318. def rename_doc(doctype, old, new, debug=0, force=False, merge=False):
  319. from webnotes.model.rename_doc import rename_doc
  320. rename_doc(doctype, old, new, force=force, merge=merge)
  321. def insert(doclist):
  322. import webnotes.model
  323. return webnotes.model.insert(doclist)
  324. def get_module(modulename):
  325. __import__(modulename)
  326. import sys
  327. return sys.modules[modulename]
  328. def get_method(method_string):
  329. modulename = '.'.join(method_string.split('.')[:-1])
  330. methodname = method_string.split('.')[-1]
  331. return getattr(get_module(modulename), methodname)
  332. def make_property_setter(args):
  333. args = _dict(args)
  334. bean([{
  335. 'doctype': "Property Setter",
  336. 'doctype_or_field': args.doctype_or_field or "DocField",
  337. 'doc_type': args.doctype,
  338. 'field_name': args.fieldname,
  339. 'property': args.property,
  340. 'value': args.value,
  341. 'property_type': args.property_type or "Data",
  342. '__islocal': 1
  343. }]).save()
  344. def get_application_home_page(user='Guest'):
  345. """get home page for user"""
  346. hpl = conn.sql("""select home_page
  347. from `tabDefault Home Page`
  348. where parent='Control Panel'
  349. and role in ('%s') order by idx asc limit 1""" % "', '".join(get_roles(user)))
  350. if hpl:
  351. return hpl[0][0]
  352. else:
  353. # no app
  354. try:
  355. from startup import application_home_page
  356. return application_home_page
  357. except ImportError:
  358. return "desktop"
  359. def copy_doclist(in_doclist):
  360. new_doclist = []
  361. parent_doc = None
  362. for i, d in enumerate(in_doclist):
  363. is_dict = False
  364. if isinstance(d, dict):
  365. is_dict = True
  366. values = _dict(d.copy())
  367. else:
  368. values = _dict(d.fields.copy())
  369. newd = new_doc(values.doctype, parent_doc=(None if i==0 else parent_doc), parentfield=values.parentfield)
  370. newd.fields.update(values)
  371. if i==0:
  372. parent_doc = newd
  373. new_doclist.append(newd.fields if is_dict else newd)
  374. return doclist(new_doclist)
  375. def compare(val1, condition, val2):
  376. import webnotes.utils
  377. return webnotes.utils.compare(val1, condition, val2)
  378. def repsond_as_web_page(title, html):
  379. global message, message_title, response
  380. message_title = title
  381. message = "<h3>" + title + "</h3>" + html
  382. response['type'] = 'page'
  383. response['page_name'] = 'message.html'
  384. def load_json(obj):
  385. if isinstance(obj, basestring):
  386. import json
  387. try:
  388. obj = json.loads(obj)
  389. except ValueError:
  390. pass
  391. return obj
  392. def build_match_conditions(doctype, fields=None, as_condition=True, match_filters=None):
  393. import webnotes.widgets.reportview
  394. return webnotes.widgets.reportview.build_match_conditions(doctype, fields, as_condition, match_filters)
  395. def get_list(doctype, filters=None, fields=None, docstatus=None,
  396. group_by=None, order_by=None, limit_start=0, limit_page_length=None,
  397. as_list=False, debug=False):
  398. import webnotes.widgets.reportview
  399. return webnotes.widgets.reportview.execute(doctype, filters=filters, fields=fields, docstatus=docstatus,
  400. group_by=group_by, order_by=order_by, limit_start=limit_start, limit_page_length=limit_page_length,
  401. as_list=as_list, debug=debug)
  402. _config = None
  403. def get_config():
  404. global _config
  405. if not _config:
  406. import webnotes.utils, json
  407. _config = _dict()
  408. def update_config(path):
  409. try:
  410. with open(path, "r") as configfile:
  411. this_config = json.loads(configfile.read())
  412. for key, val in this_config.items():
  413. if isinstance(val, dict):
  414. _config.setdefault(key, _dict()).update(val)
  415. else:
  416. _config[key] = val
  417. except IOError:
  418. pass
  419. update_config(webnotes.utils.get_path("lib", "config.json"))
  420. update_config(webnotes.utils.get_path("app", "config.json"))
  421. return _config
  422. def get_conf(site):
  423. import conf
  424. from webnotes.utils import get_storage_base_path
  425. conf = _dict(conf.__dict__)
  426. if conf.sites_dir and site:
  427. with open(os.path.join(get_storage_base_path(conf.sites_dir, site), 'site_config.json'), 'r') as f:
  428. site_config = json.load(f)
  429. site_config.update(conf.__dict__)
  430. return _dict(site_config)
  431. else:
  432. return conf