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.
 
 
 
 
 
 

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