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

__init__.py 12 KiB

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