Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.
 
 
 
 
 
 

448 righe
12 KiB

  1. # Copyright (c) 2012 Web Notes Technologies Pvt Ltd (http://erpnext.com)
  2. #
  3. # MIT License (MIT)
  4. #
  5. # Permission is hereby granted, free of charge, to any person obtaining a
  6. # copy of this software and associated documentation files (the "Software"),
  7. # to deal in the Software without restriction, including without limitation
  8. # the rights to use, copy, modify, merge, publish, distribute, sublicense,
  9. # and/or sell copies of the Software, and to permit persons to whom the
  10. # Software is furnished to do so, subject to the following conditions:
  11. #
  12. # The above copyright notice and this permission notice shall be included in
  13. # all copies or substantial portions of the Software.
  14. #
  15. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
  16. # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  17. # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  18. # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
  19. # CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
  20. # OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  21. #
  22. """
  23. globals attached to webnotes module
  24. + some utility functions that should probably be moved
  25. """
  26. from __future__ import unicode_literals
  27. code_fields_dict = {
  28. 'Page':[('script', 'js'), ('content', 'html'), ('style', 'css'), ('static_content', 'html'), ('server_code', 'py')],
  29. 'DocType':[('server_code_core', 'py'), ('client_script_core', 'js')],
  30. 'Search Criteria':[('report_script', 'js'), ('server_script', 'py'), ('custom_query', 'sql')],
  31. 'Patch':[('patch_code', 'py')],
  32. 'Stylesheet':['stylesheet', 'css'],
  33. 'Page Template':['template', 'html'],
  34. 'Control Panel':[('startup_code', 'js'), ('startup_css', 'css')]
  35. }
  36. class _dict(dict):
  37. """dict like object that exposes keys as attributes"""
  38. def __getattr__(self, key):
  39. return self.get(key)
  40. def __setattr__(self, key, value):
  41. self[key] = value
  42. def __getstate__(self):
  43. return self
  44. def __setstate__(self, d):
  45. self.update(d)
  46. def update(self, d):
  47. """update and return self -- the missing dict feature in python"""
  48. super(_dict, self).update(d)
  49. return self
  50. def copy(self):
  51. return _dict(super(_dict, self).copy())
  52. def _(msg):
  53. """translate object in current lang, if exists"""
  54. from webnotes.translate import messages
  55. return messages.get(lang, {}).get(msg, msg)
  56. request = form_dict = _dict()
  57. conn = None
  58. _memc = None
  59. form = None
  60. session = None
  61. user = None
  62. incoming_cookies = {}
  63. add_cookies = {} # append these to outgoing request
  64. cookies = {}
  65. response = _dict({'message':'', 'exc':''})
  66. error_log = []
  67. debug_log = []
  68. message_log = []
  69. mute_emails = False
  70. test_objects = {}
  71. request_method = None
  72. print_messages = False
  73. user_lang = False
  74. lang = 'en'
  75. # memcache
  76. _toc = [
  77. "webnotes.auth",
  78. "webnotes.boot",
  79. "webnotes.client",
  80. "webnotes.db",
  81. "webnotes.model"
  82. ]
  83. def cache():
  84. global _memc
  85. if not _memc:
  86. from webnotes.memc import MClient
  87. _memc = MClient(['localhost:11211'])
  88. return _memc
  89. class DuplicateEntryError(Exception): pass
  90. class ValidationError(Exception): pass
  91. class AuthenticationError(Exception): pass
  92. class PermissionError(Exception): pass
  93. class OutgoingEmailError(ValidationError): pass
  94. class UnknownDomainError(Exception): pass
  95. class SessionStopped(Exception): pass
  96. class MappingMismatchError(ValidationError): pass
  97. class InvalidStatusError(ValidationError): pass
  98. class DoesNotExistError(ValidationError): pass
  99. def getTraceback():
  100. import utils
  101. return utils.getTraceback()
  102. def errprint(msg):
  103. from utils import cstr
  104. if not request_method:
  105. print cstr(msg)
  106. error_log.append(cstr(msg))
  107. def log(msg):
  108. if not request_method:
  109. import conf
  110. if getattr(conf, "logging", False):
  111. print repr(msg)
  112. from utils import cstr
  113. debug_log.append(cstr(msg))
  114. def msgprint(msg, small=0, raise_exception=0, as_table=False):
  115. from utils import cstr
  116. if as_table and type(msg) in (list, tuple):
  117. 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>'
  118. if print_messages:
  119. print "Message: " + repr(msg)
  120. message_log.append((small and '__small:' or '')+cstr(msg or ''))
  121. if raise_exception:
  122. import inspect
  123. if inspect.isclass(raise_exception) and issubclass(raise_exception, Exception):
  124. raise raise_exception, msg
  125. else:
  126. raise ValidationError, msg
  127. def create_folder(path):
  128. import os
  129. try:
  130. os.makedirs(path)
  131. except OSError, e:
  132. if e.args[0]!=17:
  133. raise e
  134. def create_symlink(source_path, link_path):
  135. import os
  136. try:
  137. os.symlink(source_path, link_path)
  138. except OSError, e:
  139. if e.args[0]!=17:
  140. raise e
  141. def remove_file(path):
  142. import os
  143. try:
  144. os.remove(path)
  145. except OSError, e:
  146. if e.args[0]!=2:
  147. raise e
  148. def connect(db_name=None, password=None):
  149. import webnotes.db
  150. global conn
  151. conn = webnotes.db.Database(user=db_name, password=password)
  152. global session
  153. session = _dict({'user':'Administrator'})
  154. import webnotes.profile
  155. global user
  156. user = webnotes.profile.Profile('Administrator')
  157. def get_env_vars(env_var):
  158. import os
  159. return os.environ.get(env_var,'None')
  160. remote_ip = get_env_vars('REMOTE_ADDR') #Required for login from python shell
  161. logger = None
  162. def get_db_password(db_name):
  163. """get db password from conf"""
  164. import conf
  165. if hasattr(conf, 'get_db_password'):
  166. return conf.get_db_password(db_name)
  167. elif hasattr(conf, 'db_password'):
  168. return conf.db_password
  169. else:
  170. return db_name
  171. whitelisted = []
  172. guest_methods = []
  173. def whitelist(allow_guest=False, allow_roles=None):
  174. """
  175. decorator for whitelisting a function
  176. Note: if the function is allowed to be accessed by a guest user,
  177. it must explicitly be marked as allow_guest=True
  178. for specific roles, set allow_roles = ['Administrator'] etc.
  179. """
  180. def innerfn(fn):
  181. global whitelisted, guest_methods
  182. whitelisted.append(fn)
  183. if allow_guest:
  184. guest_methods.append(fn)
  185. if allow_roles:
  186. roles = get_roles()
  187. allowed = False
  188. for role in allow_roles:
  189. if role in roles:
  190. allowed = True
  191. break
  192. if not allowed:
  193. raise PermissionError, "Method not allowed"
  194. return fn
  195. return innerfn
  196. def clear_cache(user=None, doctype=None):
  197. """clear cache"""
  198. if doctype:
  199. from webnotes.model.doctype import clear_cache
  200. clear_cache(doctype)
  201. elif user:
  202. from webnotes.sessions import clear_cache
  203. clear_cache(user)
  204. else:
  205. from webnotes.sessions import clear_cache
  206. clear_cache()
  207. def get_roles(user=None, with_standard=True):
  208. """get roles of current user"""
  209. if not user:
  210. user = session.user
  211. if user=='Guest':
  212. return ['Guest']
  213. roles = [r[0] for r in conn.sql("""select role from tabUserRole
  214. where parent=%s and role!='All'""", user)] + ['All']
  215. # filter standard if required
  216. if not with_standard:
  217. roles = filter(lambda x: x not in ['All', 'Guest', 'Administrator'], roles)
  218. return roles
  219. def has_permission(doctype, ptype="read", doc=None):
  220. """check if user has permission"""
  221. from webnotes.defaults import get_user_default_as_list
  222. if session.user=="Administrator":
  223. return True
  224. if conn.get_value("DocType", doctype, "istable"):
  225. return True
  226. perms = conn.sql("""select `name`, `match` from tabDocPerm p
  227. where p.parent = %s
  228. and ifnull(p.`%s`,0) = 1
  229. and ifnull(p.permlevel,0) = 0
  230. and (p.role="All" or p.role in (select `role` from tabUserRole where `parent`=%s))
  231. """ % ("%s", ptype, "%s"), (doctype, session.user), as_dict=1)
  232. if doc:
  233. match_failed = {}
  234. for p in perms:
  235. if p.match:
  236. if ":" in p.match:
  237. keys = p.match.split(":")
  238. else:
  239. keys = [p.match, p.match]
  240. if doc.fields.get(keys[0],"[No Value]") \
  241. in get_user_default_as_list(keys[1]):
  242. return True
  243. else:
  244. match_failed[keys[0]] = doc.fields.get(keys[0],"[No Value]")
  245. else:
  246. # found a permission without a match
  247. return True
  248. # no valid permission found
  249. if match_failed:
  250. doctypelist = get_doctype(doctype)
  251. msg = _("Not allowed for: ")
  252. for key in match_failed:
  253. msg += "\n" + (doctypelist.get_field(key) and doctypelist.get_label(key) or key) \
  254. + " = " + (match_failed[key] or "None")
  255. msgprint(msg)
  256. return False
  257. else:
  258. return perms and True or False
  259. def generate_hash():
  260. """Generates random hash for session id"""
  261. import hashlib, time
  262. return hashlib.sha224(str(time.time())).hexdigest()
  263. def get_obj(dt = None, dn = None, doc=None, doclist=[], with_children = True):
  264. from webnotes.model.code import get_obj
  265. return get_obj(dt, dn, doc, doclist, with_children)
  266. def doc(doctype=None, name=None, fielddata=None):
  267. from webnotes.model.doc import Document
  268. return Document(doctype, name, fielddata)
  269. def doclist(lst=None):
  270. from webnotes.model.doclist import DocList
  271. return DocList(lst)
  272. def bean(doctype=None, name=None, copy=None):
  273. """return an instance of the object, wrapped as a Bean (webnotes.model.bean)"""
  274. from webnotes.model.bean import Bean
  275. if copy:
  276. return Bean(copy_doclist(copy))
  277. else:
  278. return Bean(doctype, name)
  279. def get_doclist(doctype, name=None):
  280. return bean(doctype, name).doclist
  281. def get_doctype(doctype, processed=False):
  282. import webnotes.model.doctype
  283. return webnotes.model.doctype.get(doctype, processed)
  284. def delete_doc(doctype=None, name=None, doclist = None, force=0, ignore_doctypes=[], for_reload=False):
  285. import webnotes.model.utils
  286. webnotes.model.utils.delete_doc(doctype, name, doclist, force, ignore_doctypes, for_reload)
  287. def clear_perms(doctype):
  288. conn.sql("""delete from tabDocPerm where parent=%s""", doctype)
  289. def reset_perms(doctype):
  290. clear_perms(doctype)
  291. reload_doc(conn.get_value("DocType", doctype, "module"), "DocType", doctype)
  292. def reload_doc(module, dt=None, dn=None):
  293. import webnotes.modules
  294. return webnotes.modules.reload_doc(module, dt, dn)
  295. def rename_doc(doctype, old, new, debug=0, force=False):
  296. from webnotes.model.rename_doc import rename_doc
  297. rename_doc(doctype, old, new, force=force)
  298. def insert(doclist):
  299. import webnotes.model
  300. return webnotes.model.insert(doclist)
  301. def get_method(method_string):
  302. modulename = '.'.join(method_string.split('.')[:-1])
  303. methodname = method_string.split('.')[-1]
  304. __import__(modulename)
  305. import sys
  306. moduleobj = sys.modules[modulename]
  307. return getattr(moduleobj, methodname)
  308. def make_property_setter(args):
  309. args = _dict(args)
  310. bean([{
  311. 'doctype': "Property Setter",
  312. 'doctype_or_field': args.doctype_or_field or "DocField",
  313. 'doc_type': args.doctype,
  314. 'field_name': args.fieldname,
  315. 'property': args.property,
  316. 'value': args.value,
  317. 'property_type': args.property_type or "Data",
  318. '__islocal': 1
  319. }]).save()
  320. def get_application_home_page(user='Guest'):
  321. """get home page for user"""
  322. hpl = conn.sql("""select home_page
  323. from `tabDefault Home Page`
  324. where parent='Control Panel'
  325. and role in ('%s') order by idx asc limit 1""" % "', '".join(get_roles(user)))
  326. if hpl:
  327. return hpl[0][0]
  328. else:
  329. from startup import application_home_page
  330. return application_home_page
  331. def copy_doclist(in_doclist):
  332. new_doclist = []
  333. for d in in_doclist:
  334. if isinstance(d, dict):
  335. new_doclist.append(d.copy())
  336. else:
  337. new_doclist.append(doc(d.fields.copy()))
  338. return doclist(new_doclist)
  339. def map_doclist(from_to_list, from_docname, to_doclist=None):
  340. from_doctype, to_doctype = from_to_list[0][0], from_to_list[0][1]
  341. if to_doclist:
  342. to_doclist = bean(to_doclist).doclist
  343. else:
  344. to_doclist = bean({"doctype": to_doctype}).doclist
  345. mapper = get_obj("DocType Mapper", "-".join(from_to_list[0]))
  346. to_doclist = mapper.dt_map(from_doctype, to_doctype, from_docname, to_doclist[0], to_doclist, from_to_list)
  347. return to_doclist
  348. def compare(val1, condition, val2):
  349. import webnotes.utils
  350. return webnotes.utils.compare(val1, condition, val2)
  351. def repsond_as_web_page(title, html):
  352. global message, message_title, response
  353. message_title = title
  354. message = "<h3>" + title + "</h3>" + html
  355. response['type'] = 'page'
  356. response['page_name'] = 'message.html'
  357. _config = None
  358. def get_config():
  359. global _config
  360. if not _config:
  361. import webnotes.utils, json
  362. _config = _dict({"modules": {}, "web": _dict({"pages": {}, "generators": {}})})
  363. with open(webnotes.utils.get_path("lib", "config.json"), "r") as configf:
  364. framework_config = json.loads(configf.read())
  365. _config.modules.update(framework_config["modules"])
  366. _config.web.pages.update(framework_config["web"]["pages"])
  367. _config.web.generators.update(framework_config["web"]["generators"])
  368. with open(webnotes.utils.get_path("app", "config.json"), "r") as configf:
  369. app_config = json.loads(configf.read())
  370. _config.modules.update(app_config["modules"])
  371. _config.web.pages.update(app_config["web"]["pages"])
  372. _config.web.generators.update(app_config["web"]["generators"])
  373. return _config