update.py 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. import os
  2. import sys
  3. import json
  4. import re
  5. import shutil
  6. def update():
  7. from Config import config
  8. config.parse()
  9. if getattr(sys, 'source_update_dir', False):
  10. if not os.path.isdir(sys.source_update_dir):
  11. os.makedirs(sys.source_update_dir)
  12. source_path = sys.source_update_dir.rstrip("/")
  13. else:
  14. source_path = os.getcwd().rstrip("/")
  15. if config.dist_type.startswith("bundle_linux"):
  16. runtime_path = os.path.normpath(os.path.dirname(sys.executable) + "/../..")
  17. else:
  18. runtime_path = os.path.dirname(sys.executable)
  19. updatesite_path = config.data_dir + "/" + config.updatesite
  20. sites_json = json.load(open(config.data_dir + "/sites.json"))
  21. updatesite_bad_files = sites_json.get(config.updatesite, {}).get("cache", {}).get("bad_files", {})
  22. print(
  23. "Update site path: %s, bad_files: %s, source path: %s, runtime path: %s, dist type: %s" %
  24. (updatesite_path, len(updatesite_bad_files), source_path, runtime_path, config.dist_type)
  25. )
  26. updatesite_content_json = json.load(open(updatesite_path + "/content.json"))
  27. inner_paths = list(updatesite_content_json.get("files", {}).keys())
  28. inner_paths += list(updatesite_content_json.get("files_optional", {}).keys())
  29. # Keep file only in ZeroNet directory
  30. inner_paths = [inner_path for inner_path in inner_paths if re.match("^(core|bundle)", inner_path)]
  31. # Checking plugins
  32. plugins_enabled = []
  33. plugins_disabled = []
  34. if os.path.isdir("%s/plugins" % source_path):
  35. for dir in os.listdir("%s/plugins" % source_path):
  36. if dir.startswith("disabled-"):
  37. plugins_disabled.append(dir.replace("disabled-", ""))
  38. else:
  39. plugins_enabled.append(dir)
  40. print("Plugins enabled:", plugins_enabled, "disabled:", plugins_disabled)
  41. update_paths = {}
  42. for inner_path in inner_paths:
  43. if ".." in inner_path:
  44. continue
  45. inner_path = inner_path.replace("\\", "/").strip("/") # Make sure we have unix path
  46. print(".", end=" ")
  47. if inner_path.startswith("core"):
  48. dest_path = source_path + "/" + re.sub("^core/", "", inner_path)
  49. elif inner_path.startswith(config.dist_type):
  50. dest_path = runtime_path + "/" + re.sub("^bundle[^/]+/", "", inner_path)
  51. else:
  52. continue
  53. if not dest_path:
  54. continue
  55. # Keep plugin disabled/enabled status
  56. match = re.match(re.escape(source_path) + "/plugins/([^/]+)", dest_path)
  57. if match:
  58. plugin_name = match.group(1).replace("disabled-", "")
  59. if plugin_name in plugins_enabled: # Plugin was enabled
  60. dest_path = dest_path.replace("plugins/disabled-" + plugin_name, "plugins/" + plugin_name)
  61. elif plugin_name in plugins_disabled: # Plugin was disabled
  62. dest_path = dest_path.replace("plugins/" + plugin_name, "plugins/disabled-" + plugin_name)
  63. print("P", end=" ")
  64. dest_dir = os.path.dirname(dest_path)
  65. if dest_dir and not os.path.isdir(dest_dir):
  66. os.makedirs(dest_dir)
  67. if dest_dir != dest_path.strip("/"):
  68. update_paths[updatesite_path + "/" + inner_path] = dest_path
  69. num_ok = 0
  70. num_rename = 0
  71. num_error = 0
  72. for path_from, path_to in update_paths.items():
  73. print("-", path_from, "->", path_to)
  74. if not os.path.isfile(path_from):
  75. print("Missing file")
  76. continue
  77. data = open(path_from, "rb").read()
  78. try:
  79. open(path_to, 'wb').write(data)
  80. num_ok += 1
  81. except Exception as err:
  82. try:
  83. print("Error writing: %s. Renaming old file as workaround..." % err)
  84. path_to_tmp = path_to + "-old"
  85. if os.path.isfile(path_to_tmp):
  86. os.unlink(path_to_tmp)
  87. os.rename(path_to, path_to_tmp)
  88. num_rename += 1
  89. open(path_to, 'wb').write(data)
  90. shutil.copymode(path_to_tmp, path_to) # Copy permissions
  91. print("Write done after rename!")
  92. num_ok += 1
  93. except Exception as err:
  94. print("Write error after rename: %s" % err)
  95. num_error += 1
  96. print("* Updated files: %s, renamed: %s, error: %s" % (num_ok, num_rename, num_error))
  97. if __name__ == "__main__":
  98. sys.path.insert(0, os.path.join(os.path.dirname(__file__), "src")) # Imports relative to src
  99. update()