file_sync.py 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. #
  2. # Copyright (c) 2006-2019, RT-Thread Development Team
  3. #
  4. # SPDX-License-Identifier: MIT License
  5. #
  6. # Change Logs:
  7. # Date Author Notes
  8. # 2019-07-15 SummerGift first version
  9. #
  10. import os
  11. import hashlib
  12. import binascii
  13. def get_file_hash(file_path):
  14. myhash = hashlib.md5()
  15. f = open(file_path, 'rb')
  16. while True:
  17. b = f.read(8096)
  18. if not b:
  19. break
  20. myhash.update(b)
  21. f.close()
  22. return str(myhash.hexdigest())
  23. def big_small_end_convert(data):
  24. tmp0 = data[:2]
  25. tmp1 = data[2:4]
  26. tmp2 = data[4:6]
  27. tmp3 = data[6:8]
  28. value = tmp3 + tmp2 + tmp1 + tmp0
  29. return value
  30. def get_file_crc32(file_path):
  31. try:
  32. with open(file_path, "rb") as infile:
  33. ucrc = binascii.crc32(infile.read())
  34. if ucrc > 0:
  35. uoutint = ucrc
  36. else:
  37. uoutint = ~ ucrc ^ 0xffffffff
  38. return '%x' % (uoutint)
  39. except:
  40. print("crc calc error.\r\n")
  41. return ''
  42. print("error")
  43. def _get_file_crc32(file_path):
  44. import binascii
  45. def mycrc32(szString, dwCrc32):
  46. m_pdwCrc32Table = [0 for x in range(0, 256)]
  47. dwPolynomial = 0xEDB88320
  48. dwCrc = 0
  49. dwCrc32 = dwCrc32 ^ 0xFFFFFFFF
  50. for i in range(0, 255):
  51. dwCrc = i
  52. for j in [8, 7, 6, 5, 4, 3, 2, 1]:
  53. if dwCrc & 1:
  54. dwCrc = (dwCrc >> 1) ^ dwPolynomial
  55. else:
  56. dwCrc >>= 1
  57. m_pdwCrc32Table[i] = dwCrc
  58. for i in szString:
  59. b = ord(i)
  60. dwCrc32 = ((dwCrc32) >> 8) ^ m_pdwCrc32Table[(b) ^ ((dwCrc32) & 0x000000FF)]
  61. dwCrc32 = dwCrc32 ^ 0xFFFFFFFF
  62. return dwCrc32
  63. with open(file_path, "rb") as infile:
  64. file_crc_value = 0xFFFFFFFF
  65. while True:
  66. ucrc = infile.read(500)
  67. if len(ucrc) == 0:
  68. break
  69. ucrc = binascii.b2a_base64(ucrc)
  70. file_crc_value = mycrc32(ucrc.decode(), file_crc_value)
  71. return ('%x' % (file_crc_value))
  72. def get_pc_dir_info(path, rtt_version):
  73. result = []
  74. for root, dirs, files in os.walk(path, topdown=False):
  75. for name in files:
  76. file_info = {}
  77. file_key = os.path.join(root, name)[len(path) + 1:].replace('\\', '/')
  78. file_info['name'] = file_key
  79. if rtt_version:
  80. big_small = get_file_crc32(os.path.join(root, name)).upper()
  81. else:
  82. big_small = _get_file_crc32(os.path.join(root, name)).upper()
  83. if len(big_small) == 8:
  84. convert_value = big_small_end_convert(big_small).upper()
  85. else:
  86. convert_value = "Invalid"
  87. file_info['md5'] = convert_value
  88. result.append(file_info)
  89. for name in dirs:
  90. file_info = {}
  91. file_key = os.path.join(root, name)[len(path) + 1:].replace('\\', '/')
  92. file_info['name'] = file_key
  93. file_info['md5'] = 'dir'
  94. result.append(file_info)
  95. return result
  96. def get_sync_info(pc_info, dev_info):
  97. sync_info = {}
  98. delete_list = []
  99. sync_list = []
  100. temp = {}
  101. # print("pcinfo:%s"%pc_info)
  102. # print("dev_info:%s"%dev_info)
  103. for filename, md5 in pc_info.items():
  104. if filename in dev_info.keys(): # If the file exists on both the PC and device side
  105. if md5 == 'dir':
  106. continue
  107. else:
  108. if md5 == dev_info[filename]:
  109. continue
  110. else:
  111. sync_list.append(filename)
  112. else:
  113. if md5 == 'dir':
  114. continue
  115. else:
  116. sync_list.append(filename)
  117. for filename, md5 in dev_info.items():
  118. if filename in pc_info.keys(): # If the file exists on both the PC and device side
  119. continue
  120. else:
  121. delete_list.append(filename)
  122. sync_info['delete'] = delete_list
  123. sync_info['sync'] = sync_list
  124. # print(sync_info)
  125. return sync_info
  126. def file_sync_info(local_path, info_pathname, rtt_version):
  127. pc_file_info = {}
  128. dev_file_info = {}
  129. pc_info = get_pc_dir_info(local_path, rtt_version)
  130. for item in pc_info:
  131. pc_file_info[item["name"]] = item["md5"]
  132. with open(info_pathname, 'r') as f:
  133. dev_file_info = f.read()
  134. return get_sync_info(pc_file_info, eval(dev_file_info)), pc_file_info