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.
 
 
 
 
 
 

212 regels
6.0 KiB

  1. from __future__ import unicode_literals
  2. """
  3. Sync's doctype and docfields from txt files to database
  4. perms will get synced only if none exist
  5. """
  6. import webnotes
  7. def sync_all(force=0):
  8. modules = []
  9. modules += sync_core_doctypes(force)
  10. modules += sync_modules(force)
  11. try:
  12. webnotes.conn.begin()
  13. webnotes.conn.sql("DELETE FROM __CacheItem")
  14. webnotes.conn.commit()
  15. except Exception, e:
  16. if e[0]!=1146: raise e
  17. return modules
  18. def sync_core_doctypes(force=0):
  19. import os
  20. import core
  21. # doctypes
  22. return walk_and_sync(os.path.abspath(os.path.dirname(core.__file__)), force)
  23. def sync_modules(force=0):
  24. import conf
  25. return walk_and_sync(conf.modules_path, force)
  26. def walk_and_sync(start_path, force=0):
  27. """walk and sync all doctypes and pages"""
  28. import os
  29. from webnotes.modules import reload_doc
  30. modules = []
  31. for path, folders, files in os.walk(start_path):
  32. for f in files:
  33. if f.endswith(".txt"):
  34. # great grand-parent folder is module_name
  35. module_name = path.split(os.sep)[-3]
  36. if not module_name in modules:
  37. modules.append(module_name)
  38. # grand parent folder is doctype
  39. doctype = path.split(os.sep)[-2]
  40. # parent folder is the name
  41. name = path.split(os.sep)[-1]
  42. if doctype == 'doctype':
  43. sync(module_name, name, force)
  44. elif doctype in ['page']:#, 'search_criteria', 'Print Format', 'DocType Mapper']:
  45. if reload_doc(module_name, doctype, name):
  46. print module_name + ' | ' + doctype + ' | ' + name
  47. return modules
  48. # docname in small letters with underscores
  49. def sync(module_name, docname, force=0):
  50. """sync doctype from file if modified"""
  51. with open(get_file_path(module_name, docname), 'r') as f:
  52. from webnotes.model.utils import peval_doclist
  53. doclist = peval_doclist(f.read())
  54. modified = doclist[0]['modified']
  55. if not doclist:
  56. raise Exception('DocList could not be evaluated')
  57. if modified == str(webnotes.conn.get_value(doclist[0].get('doctype'),
  58. doclist[0].get('name'), 'modified')) and not force:
  59. return
  60. webnotes.conn.begin()
  61. delete_doctype_docfields(doclist)
  62. save_doctype_docfields(doclist)
  63. save_perms_if_none_exist(doclist)
  64. webnotes.conn.sql("""UPDATE `tab{doctype}`
  65. SET modified=%s WHERE name=%s""".format(doctype=doclist[0]['doctype']),
  66. (modified, doclist[0]['name']))
  67. webnotes.conn.commit()
  68. print module_name, '|', docname
  69. #raise Exception
  70. return doclist[0].get('name')
  71. def get_file_path(module_name, docname):
  72. if not (module_name and docname):
  73. raise Exception('No Module Name or DocName specified')
  74. import os
  75. module = __import__(module_name)
  76. module_init_path = os.path.abspath(module.__file__)
  77. module_path = os.sep.join(module_init_path.split(os.sep)[:-1])
  78. return os.sep.join([module_path, 'doctype', docname, docname + '.txt'])
  79. def delete_doctype_docfields(doclist):
  80. parent = doclist[0].get('name')
  81. if not parent: raise Exception('Could not determine parent')
  82. webnotes.conn.sql("DELETE FROM `tabDocType` WHERE name=%s", parent)
  83. webnotes.conn.sql("DELETE FROM `tabDocField` WHERE parent=%s", parent)
  84. def save_doctype_docfields(doclist):
  85. from webnotes.model.doc import Document
  86. from webnotes.model.code import get_obj
  87. parent_doc = Document(fielddata=doclist[0])
  88. parent_doc.save(1, check_links=0,
  89. ignore_fields=1)
  90. idx = 1
  91. for d in doclist:
  92. if d.get('doctype') != 'DocField': continue
  93. d['idx'] = idx
  94. Document(fielddata=d).save(1, check_links=0, ignore_fields=1)
  95. idx += 1
  96. update_schema(parent_doc.name)
  97. def update_schema(docname):
  98. from webnotes.model.db_schema import updatedb
  99. updatedb(docname)
  100. from webnotes.utils.cache import CacheItem
  101. CacheItem(docname).clear()
  102. def save_perms_if_none_exist(doclist):
  103. res = webnotes.conn.sql("""SELECT name FROM `tabDocPerm`
  104. WHERE parent=%s""", doclist[0].get('name'))
  105. if res and res[0][0]: return
  106. from webnotes.model.doc import Document
  107. for d in doclist:
  108. if d.get('doctype') != 'DocPerm': continue
  109. Document(fielddata=d).save(1, check_links=0, ignore_fields=1)
  110. def sync_install(force=1):
  111. # sync all doctypes
  112. modules = sync_all(force)
  113. # load install docs
  114. load_install_docs(modules)
  115. def load_install_docs(modules):
  116. import os
  117. if isinstance(modules, basestring): modules = [modules]
  118. for module_name in modules:
  119. module = __import__(module_name)
  120. if hasattr(module, 'install_docs'):
  121. webnotes.conn.begin()
  122. for data in module.install_docs:
  123. if data.get('name'):
  124. if not webnotes.conn.exists(data['doctype'], data.get('name')):
  125. create_doc(data)
  126. elif not webnotes.conn.exists(data):
  127. create_doc(data)
  128. webnotes.conn.commit()
  129. if hasattr(module, 'module_init'):
  130. module.module_init()
  131. def create_doc(data):
  132. from webnotes.model.doc import Document
  133. d = Document(data['doctype'])
  134. d.fields.update(data)
  135. d.save()
  136. print 'Created %(doctype)s %(name)s' % d.fields
  137. import unittest
  138. class TestSync(unittest.TestCase):
  139. def setUp(self):
  140. self.test_case = {
  141. 'module_name': 'selling',
  142. 'docname': 'sales_order'
  143. }
  144. webnotes.conn.begin()
  145. def tearDown(self):
  146. pass
  147. #from webnotes.utils import cstr
  148. #webnotes.conn.rollback()
  149. def test_sync(self):
  150. #old_doctype, old_docfields = self.query('Profile')
  151. #self.parent = sync(self.test_case.get('module_name'), self.test_case.get('docname'))
  152. #new_doctype, new_docfields = self.query(self.parent)
  153. #self.assertNotEqual(old_doctype, new_doctype)
  154. #self.assertNotEqual(old_docfields, new_docfields)
  155. #from webnotes.utils import cstr
  156. #print new_doctype[0]
  157. #print
  158. #print "\n".join((cstr(d) for d in new_docfields))
  159. #print "\n\n"
  160. pass
  161. def test_sync_all(self):
  162. sync_all()
  163. def query(self, parent):
  164. doctype = webnotes.conn.sql("SELECT name FROM `tabDocType` \
  165. WHERE name=%s", parent)
  166. docfields = webnotes.conn.sql("SELECT idx, fieldname, label, fieldtype FROM `tabDocField` \
  167. WHERE parent=%s order by idx", parent)
  168. #doctype = webnotes.conn.sql("SELECT * FROM `tabDocType` \
  169. # WHERE name=%s", parent)
  170. #docfields = webnotes.conn.sql("SELECT * FROM `tabDocField` \
  171. # WHERE parent=%s order by idx", parent)
  172. return doctype, docfields