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.

patch_handler.py 3.5 KiB

13 jaren geleden
13 jaren geleden
13 jaren geleden
13 jaren geleden
13 jaren geleden
12 jaren geleden
13 jaren geleden
13 jaren geleden
13 jaren geleden
13 jaren geleden
13 jaren geleden
13 jaren geleden
13 jaren geleden
11 jaren geleden
13 jaren geleden
13 jaren geleden
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. # Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
  2. # MIT License. See license.txt
  3. from __future__ import unicode_literals
  4. """
  5. Execute Patch Files
  6. To run directly
  7. python lib/wnf.py patch patch1, patch2 etc
  8. python lib/wnf.py patch -f patch1, patch2 etc
  9. where patch1, patch2 is module name
  10. """
  11. import webnotes, os
  12. class PatchError(Exception): pass
  13. def run_all():
  14. """run all pending patches"""
  15. executed = [p[0] for p in webnotes.conn.sql("""select patch from `tabPatch Log`""")]
  16. for patch in get_all_patches():
  17. if patch and (patch not in executed):
  18. if not run_single(patchmodule = patch):
  19. log(patch + ': failed: STOPPED')
  20. raise PatchError(patch)
  21. def get_all_patches():
  22. patches = []
  23. for app in webnotes.get_installed_apps():
  24. patches.extend(webnotes.get_file_items(webnotes.get_pymodule_path(app, "patches.txt")))
  25. return patches
  26. def reload_doc(args):
  27. import webnotes.modules
  28. run_single(method = webnotes.modules.reload_doc, methodargs = args)
  29. def run_single(patchmodule=None, method=None, methodargs=None, force=False):
  30. from webnotes import conf
  31. # don't write txt files
  32. conf.developer_mode = 0
  33. if force or method or not executed(patchmodule):
  34. return execute_patch(patchmodule, method, methodargs)
  35. else:
  36. return True
  37. def execute_patch(patchmodule, method=None, methodargs=None):
  38. """execute the patch"""
  39. success = False
  40. block_user(True)
  41. webnotes.conn.begin()
  42. try:
  43. log('Executing %s in %s' % (patchmodule or str(methodargs), webnotes.conn.cur_db_name))
  44. if patchmodule:
  45. if patchmodule.startswith("execute:"):
  46. exec patchmodule.split("execute:")[1] in globals()
  47. else:
  48. webnotes.get_attr(patchmodule + ".execute")()
  49. update_patch_log(patchmodule)
  50. elif method:
  51. method(**methodargs)
  52. webnotes.conn.commit()
  53. success = True
  54. except Exception, e:
  55. webnotes.conn.rollback()
  56. tb = webnotes.get_traceback()
  57. log(tb)
  58. import os
  59. if webnotes.request:
  60. add_to_patch_log(tb)
  61. block_user(False)
  62. if success:
  63. log('Success')
  64. return success
  65. def add_to_patch_log(tb):
  66. """add error log to patches/patch.log"""
  67. import conf, os
  68. # TODO use get_site_base_path
  69. with open(os.path.join(os.path.dirname(conf.__file__), 'app', 'patches','patch.log'),'a') as patchlog:
  70. patchlog.write('\n\n' + tb)
  71. def update_patch_log(patchmodule):
  72. """update patch_file in patch log"""
  73. if webnotes.conn.table_exists("__PatchLog"):
  74. webnotes.conn.sql("""INSERT INTO `__PatchLog` VALUES (%s, now())""", \
  75. patchmodule)
  76. else:
  77. webnotes.doc({"doctype": "Patch Log", "patch": patchmodule}).insert()
  78. def executed(patchmodule):
  79. """return True if is executed"""
  80. if webnotes.conn.table_exists("__PatchLog"):
  81. done = webnotes.conn.sql("""select patch from __PatchLog where patch=%s""", patchmodule)
  82. else:
  83. done = webnotes.conn.get_value("Patch Log", {"patch": patchmodule})
  84. if done:
  85. print "Patch %s executed in %s" % (patchmodule, webnotes.conn.cur_db_name)
  86. return done
  87. def block_user(block):
  88. """stop/start execution till patch is run"""
  89. webnotes.conn.begin()
  90. msg = "Patches are being executed in the system. Please try again in a few moments."
  91. webnotes.conn.set_global('__session_status', block and 'stop' or None)
  92. webnotes.conn.set_global('__session_status_message', block and msg or None)
  93. webnotes.conn.commit()
  94. def setup():
  95. webnotes.conn.sql("""CREATE TABLE IF NOT EXISTS `__PatchLog` (
  96. patch TEXT, applied_on DATETIME) engine=InnoDB""")
  97. def log(msg):
  98. if getattr(webnotes.local, "patch_log_list", None) is None:
  99. webnotes.local.patch_log_list = []
  100. webnotes.local.patch_log_list.append(msg)