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.
 
 
 
 
 
 

210 lines
5.8 KiB

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