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.
 
 
 
 
 
 

170 lines
4.9 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. import os
  8. import conf
  9. def sync_all(force=0):
  10. modules = []
  11. modules += sync_core_doctypes(force)
  12. modules += sync_modules(force)
  13. try:
  14. webnotes.conn.begin()
  15. webnotes.conn.sql("DELETE FROM __CacheItem")
  16. webnotes.conn.commit()
  17. except Exception, e:
  18. if e[0]!=1146: raise e
  19. return modules
  20. def sync_core_doctypes(force=0):
  21. # doctypes
  22. return walk_and_sync(os.path.join(os.path.dirname(os.path.abspath(conf.__file__)), 'lib'), force)
  23. def sync_modules(force=0):
  24. return walk_and_sync(os.path.join(os.path.dirname(os.path.abspath(conf.__file__)), 'app'), force)
  25. def walk_and_sync(start_path, force=0):
  26. """walk and sync all doctypes and pages"""
  27. from webnotes.modules import reload_doc
  28. modules = []
  29. document_type = ['page', 'workflow', 'module_def', 'workflow_state', 'workflow_action']
  30. for path, folders, files in os.walk(start_path):
  31. if os.path.basename(os.path.dirname(path)) in (['doctype'] + document_type):
  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 document_type:
  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.modules.utils import peval_doclist
  53. doclist = peval_doclist(f.read())
  54. modified = doclist[0]['modified']
  55. if not doclist:
  56. raise Exception('ModelWrapper could not be evaluated')
  57. db_modified = str(webnotes.conn.get_value(doclist[0].get('doctype'),
  58. doclist[0].get('name'), 'modified'))
  59. if modified == db_modified and not force:
  60. return
  61. webnotes.conn.begin()
  62. delete_doctype_docfields(doclist)
  63. save_doctype_docfields(doclist)
  64. save_perms_if_none_exist(doclist)
  65. webnotes.conn.sql("""UPDATE `tab{doctype}`
  66. SET modified=%s WHERE name=%s""".format(doctype=doclist[0]['doctype']),
  67. (modified, doclist[0]['name']))
  68. webnotes.conn.commit()
  69. print module_name, '|', docname
  70. #raise Exception
  71. return doclist[0].get('name')
  72. def get_file_path(module_name, docname):
  73. if not (module_name and docname):
  74. raise Exception('No Module Name or DocName specified')
  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. if isinstance(modules, basestring): modules = [modules]
  117. for module_name in modules:
  118. module = __import__(module_name)
  119. if hasattr(module, 'install_docs'):
  120. webnotes.conn.begin()
  121. for data in module.install_docs:
  122. if data.get('name'):
  123. if not webnotes.conn.exists(data['doctype'], data.get('name')):
  124. create_doc(data)
  125. elif not webnotes.conn.exists(data):
  126. create_doc(data)
  127. webnotes.conn.commit()
  128. if hasattr(module, 'module_init'):
  129. module.module_init()
  130. def create_doc(data):
  131. from webnotes.model.doc import Document
  132. d = Document(data['doctype'])
  133. d.fields.update(data)
  134. d.save()
  135. print 'Created %(doctype)s %(name)s' % d.fields