25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

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