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.
 
 
 
 
 
 

117 lines
3.4 KiB

  1. # Copyright (c) 2013, Web Notes Technologies Pvt. Ltd.
  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
  12. def run_all(patch_list=None):
  13. """run all pending patches"""
  14. if webnotes.conn.table_exists("__PatchLog"):
  15. executed = [p[0] for p in webnotes.conn.sql("""select patch from `__PatchLog`""")]
  16. else:
  17. executed = [p[0] for p in webnotes.conn.sql("""select patch from `tabPatch Log`""")]
  18. import patches.patch_list
  19. for patch in (patch_list or patches.patch_list.patch_list):
  20. if patch not in executed:
  21. if not run_single(patchmodule = patch):
  22. return log(patch + ': failed: STOPPED')
  23. def reload_doc(args):
  24. import webnotes.modules
  25. run_single(method = webnotes.modules.reload_doc, methodargs = args)
  26. def run_single(patchmodule=None, method=None, methodargs=None, force=False):
  27. import conf
  28. # don't write txt files
  29. conf.developer_mode = 0
  30. if force or method or not executed(patchmodule):
  31. return execute_patch(patchmodule, method, methodargs)
  32. else:
  33. return True
  34. def execute_patch(patchmodule, method=None, methodargs=None):
  35. """execute the patch"""
  36. success = False
  37. block_user(True)
  38. webnotes.conn.begin()
  39. try:
  40. log('Executing %s in %s' % (patchmodule or str(methodargs), webnotes.conn.cur_db_name))
  41. if patchmodule:
  42. if patchmodule.startswith("execute:"):
  43. exec patchmodule.split("execute:")[1] in globals()
  44. else:
  45. webnotes.get_method(patchmodule + ".execute")()
  46. update_patch_log(patchmodule)
  47. elif method:
  48. method(**methodargs)
  49. webnotes.conn.commit()
  50. success = True
  51. except Exception, e:
  52. webnotes.conn.rollback()
  53. global has_errors
  54. has_errors = True
  55. tb = webnotes.getTraceback()
  56. log(tb)
  57. import os
  58. if webnotes.request:
  59. add_to_patch_log(tb)
  60. block_user(False)
  61. if success:
  62. log('Success')
  63. return success
  64. def add_to_patch_log(tb):
  65. """add error log to patches/patch.log"""
  66. import conf, os
  67. with open(os.path.join(os.path.dirname(conf.__file__), 'app', 'patches','patch.log'),'a') as patchlog:
  68. patchlog.write('\n\n' + tb)
  69. def update_patch_log(patchmodule):
  70. """update patch_file in patch log"""
  71. if webnotes.conn.table_exists("__PatchLog"):
  72. webnotes.conn.sql("""INSERT INTO `__PatchLog` VALUES (%s, now())""", \
  73. patchmodule)
  74. else:
  75. webnotes.doc({"doctype": "Patch Log", "patch": patchmodule}).insert()
  76. def executed(patchmodule):
  77. """return True if is executed"""
  78. if webnotes.conn.table_exists("__PatchLog"):
  79. done = webnotes.conn.sql("""select patch from __PatchLog where patch=%s""", patchmodule)
  80. else:
  81. done = webnotes.conn.get_value("Patch Log", {"patch": patchmodule})
  82. if done:
  83. print "Patch %s executed in %s" % (patchmodule, webnotes.conn.cur_db_name)
  84. return done
  85. def block_user(block):
  86. """stop/start execution till patch is run"""
  87. webnotes.conn.begin()
  88. msg = "Patches are being executed in the system. Please try again in a few moments."
  89. webnotes.conn.set_global('__session_status', block and 'stop' or None)
  90. webnotes.conn.set_global('__session_status_message', block and msg or None)
  91. webnotes.conn.commit()
  92. def setup():
  93. webnotes.conn.sql("""CREATE TABLE IF NOT EXISTS `__PatchLog` (
  94. patch TEXT, applied_on DATETIME) engine=InnoDB""")
  95. log_list = []
  96. has_errors = False
  97. def log(msg):
  98. log_list.append(msg)