ftp.py 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396
  1. # -*- coding:utf-8 -*-
  2. import time
  3. import sys
  4. import os
  5. import socket
  6. from ftplib import FTP_TLS
  7. #from ftplib import FTP
  8. import re # 正则表达式;
  9. import shutil
  10. class MyFTP:
  11. def __init__(self, host, port=21):
  12. self.host = host
  13. self.port = port
  14. self.ftp = FTP_TLS()
  15. #self.ftp = FTP()
  16. self.ftp.encoding = 'utf-8'
  17. self.log_file = open("log.txt", "a")
  18. self.file_list = []
  19. self.dir_list = []
  20. self.cur_dir = ''
  21. def login(self, username, password):
  22. try:
  23. timeout = 60
  24. socket.setdefaulttimeout(timeout)
  25. # 0主动模式 1 #被动模式
  26. self.ftp.set_pasv(True)
  27. # 打开调试级别2,显示详细信息
  28. # self.ftp.set_debuglevel(2)
  29. self.debug_print(u'try to connect %s' % self.host)
  30. self.ftp.connect(self.host, self.port)
  31. self.debug_print(u'connect success %s' % self.host)
  32. self.debug_print(u'try to login %s' % self.host)
  33. self.ftp.login(username, password)
  34. self.ftp.prot_p()
  35. self.debug_print(u'login success %s' % self.host)
  36. self.debug_print(self.ftp.welcome)
  37. except Exception as err:
  38. self.deal_error(u"FTP connect or login faild , error desc = %s" % err)
  39. pass
  40. def is_same_size(self, local_file, remote_file):
  41. try:
  42. remote_file_size = self.ftp.size(remote_file)
  43. except Exception as err:
  44. self.debug_print("is_same_size() error descript:%s" % err)
  45. remote_file_size = -1
  46. try:
  47. local_file_size = os.path.getsize(local_file)
  48. except Exception as err:
  49. self.debug_print("is_same_size() error descript:%s" % err)
  50. local_file_size = -1
  51. self.debug_print('local_file_size:%d , remote_file_size:%d' % (local_file_size, remote_file_size))
  52. if remote_file_size == local_file_size:
  53. return 1
  54. else:
  55. return 0
  56. def download_file(self, local_file, remote_file):
  57. """从ftp下载文件
  58. 参数:
  59. local_file: 本地文件
  60. remote_file: 远程文件
  61. """
  62. self.debug_print("download_file()---> local_path = %s ,remote_path = %s" % (local_file, remote_file))
  63. if self.is_same_size(local_file, remote_file):
  64. self.debug_print(u'%s same file size, no need to download' % local_file)
  65. return
  66. else:
  67. try:
  68. self.debug_print(u'>>>>>>>>>>>>download file %s ... ...' % local_file)
  69. buf_size = 1024
  70. file_handler = open(local_file, 'wb')
  71. self.ftp.retrbinary('RETR %s' % remote_file, file_handler.write, buf_size)
  72. file_handler.close()
  73. except Exception as err:
  74. self.debug_print(u'error downloading file with exception = %s ' % err)
  75. return
  76. def download_file_tree(self, local_path, remote_path):
  77. """从远程目录下载多个文件到本地目录
  78. 参数:
  79. local_path: 本地路径
  80. remote_path: 远程路径
  81. """
  82. print("download_file_tree()---> local_path = %s ,remote_path = %s" % (local_path, remote_path))
  83. try:
  84. self.ftp.cwd(remote_path)
  85. except Exception as err:
  86. self.debug_print(
  87. u'remote directory %s does not exist, continue...' % remote_path + u" ,the specific error description is %s" % err)
  88. return
  89. if not os.path.isdir(local_path):
  90. self.debug_print(u'local directory %s does not exsit, create local directory first' % local_path)
  91. os.makedirs(local_path)
  92. self.debug_print(u'switch to directory %s' % self.ftp.pwd())
  93. self.file_list = []
  94. # 方法回调
  95. self.ftp.dir(self.get_file_list)
  96. remote_names = self.file_list
  97. self.debug_print(u'remote directory list: %s' % remote_names)
  98. for item in remote_names:
  99. file_type = item[0]
  100. file_name = item[1]
  101. local = os.path.join(local_path, file_name)
  102. if file_type == 'd':
  103. print(u"download_file_tree()---> download directory: %s" % file_name)
  104. self.download_file_tree(local, file_name)
  105. elif file_type == '-':
  106. print(u"download_file()---> download file: %s" % file_name)
  107. self.download_file(local, file_name)
  108. self.ftp.cwd("..")
  109. self.debug_print(u'return to upper level directory %s' % self.ftp.pwd())
  110. return True
  111. def upload_file(self, local_file, remote_file):
  112. """从本地上传文件到ftp
  113. 参数:
  114. local_path: 本地文件
  115. remote_path: 远程文件
  116. """
  117. if not os.path.isfile(local_file):
  118. self.debug_print('%s does not exist' % local_file)
  119. return
  120. if self.is_same_size(local_file, remote_file):
  121. self.debug_print(u'skip equivalent files: %s' % local_file)
  122. return
  123. buf_size = 1024
  124. file_handler = open(local_file, 'rb')
  125. self.ftp.storbinary('STOR %s' % remote_file, file_handler, buf_size)
  126. file_handler.close()
  127. self.debug_print('upload: %s' % local_file + "success")
  128. def upload_file_tree(self, local_path, remote_path):
  129. """从本地上传目录下多个文件到ftp
  130. 参数:
  131. local_path: 本地路径
  132. remote_path: 远程路径
  133. """
  134. if not os.path.isdir(local_path):
  135. self.debug_print('local directory %s does not exsit' % local_path)
  136. return
  137. """
  138. 创建服务器目录
  139. """
  140. try:
  141. self.ftp.cwd(remote_path) # 切换工作路径
  142. except Exception as e:
  143. base_dir, part_path = self.ftp.pwd(), remote_path.split('/')
  144. print e, base_dir, part_path
  145. for p in part_path[1:]:
  146. print "Subdirectory", p
  147. base_dir = base_dir + p + '/' # 拼接子目录
  148. try:
  149. self.ftp.cwd(base_dir) # 切换到子目录, 不存在则异常
  150. except Exception as e:
  151. print('INFO:', e)
  152. self.ftp.mkd(base_dir) # 不存在创建当前子目录
  153. self.ftp.cwd(remote_path)
  154. self.debug_print('switch to remote directory: %s' % self.ftp.pwd())
  155. local_name_list = os.listdir(local_path)
  156. self.debug_print('local directory list: %s' % local_name_list)
  157. # self.debug_print('判断是否有服务器目录: %s' % os.path.isdir())
  158. for local_name in local_name_list:
  159. src = os.path.join(local_path, local_name)
  160. print("src directory==========" + src)
  161. if os.path.isdir(src):
  162. try:
  163. self.ftp.mkd(local_name)
  164. except Exception as err:
  165. self.debug_print("folder has exist %s , error descript:%s" % (local_name, err))
  166. self.debug_print("upload_file_tree()---> upload dir: %s" % local_name)
  167. self.debug_print("upload_file_tree()---> upload src dir: %s" % src)
  168. self.upload_file_tree(src, local_name)
  169. else:
  170. self.debug_print("upload_file_tree()---> upload file: %s" % local_name)
  171. self.upload_file(src, local_name)
  172. self.ftp.cwd("..")
  173. def close(self):
  174. """ 退出ftp
  175. """
  176. self.debug_print("close()---> FTP exit")
  177. self.ftp.quit()
  178. self.log_file.close()
  179. def debug_print(self, s):
  180. """ 打印日志
  181. """
  182. self.write_log(s)
  183. def deal_error(self, e):
  184. """ 处理错误异常
  185. 参数:
  186. e:异常
  187. """
  188. log_str = u'an error occurred : %s' % e
  189. self.write_log(log_str)
  190. sys.exit()
  191. def write_log(self, log_str):
  192. """ 记录日志
  193. 参数:
  194. log_str:日志
  195. """
  196. time_now = time.localtime()
  197. date_now = time.strftime('%Y-%m-%d', time_now)
  198. format_log_str = "%s ---> %s \n " % (date_now, log_str)
  199. print(format_log_str)
  200. self.log_file.write(format_log_str)
  201. def get_file_list(self, line):
  202. """ 获取文件列表
  203. 参数:
  204. line:
  205. """
  206. file_arr = self.get_file_name(line)
  207. # 去除 . 和 ..
  208. if file_arr[1] not in ['.', '..']:
  209. self.file_list.append(file_arr)
  210. def get_file_name(self, line):
  211. """ 获取文件名
  212. 参数:
  213. line:
  214. """
  215. pos = line.rfind(':')
  216. while (line[pos] != ' '):
  217. pos += 1
  218. while (line[pos] == ' '):
  219. pos += 1
  220. file_arr = [line[0], line[pos:]]
  221. return file_arr
  222. def get_dirs(self):
  223. self.get_dir()
  224. self.dir_list = []
  225. self.ftp.dir(self.callback_get_dirs)
  226. return self.dir_list
  227. def callback_get_dirs(self, line):
  228. # 正则表达式;
  229. # 字串:drwxrwxrwx 1 user group 0 Dec 28 18:35 V8-T851T01-LF1V024-CTS
  230. # 以时间冒号为分隔符;
  231. p = re.compile(r"(.*):(\d+) (.*)", re.DOTALL)
  232. mo = p.search(line)
  233. if mo is not None:
  234. ftpdir = mo.group(3)
  235. if ftpdir != '.' and ftpdir != '..':
  236. self.dir_list.append(self.cur_dir + '/' + ftpdir)
  237. else:
  238. print "Normal matching failed", line
  239. def get_files(self, path):
  240. filelist = self.ftp.nlst(path)
  241. for file in filelist:
  242. self.file_list.append(path + '/' + file)
  243. return self.file_list
  244. def set_dir(self, path):
  245. print("set dir", self.ftp.cwd(path))
  246. def get_dir(self):
  247. self.cur_dir = self.ftp.pwd()
  248. print("get dir", self.cur_dir)
  249. return self.cur_dir
  250. FTPHOST = '10.118.1.85'
  251. FTPUSER = 'jianfeng1.wang'
  252. FTPPWD = 'Moka@233668#'
  253. FTPDIR41 = u'/ProjectSoftware/TEST/TV/Regional_Customers/RT2841_MOKA/cts-auth/22Q1/approved/'
  254. FTPDIR51 = u'/ProjectSoftware/TEST/TV/Regional_Customers/RT2851_MOKA/cts-auth/22Q1/approved/'
  255. LOCALDIR41 = r'F:\22Q1-CTS\41'
  256. LOCALDIR51 = r'F:\22Q1-CTS\51'
  257. # 下载指定ftp路径内的所有的prop文件
  258. def download_prop(ftp_dir, local_dir):
  259. ftp = MyFTP(FTPHOST)
  260. print ftp.login(FTPUSER, FTPPWD)
  261. print ftp.set_dir(ftp_dir)
  262. print ftp.get_dirs()
  263. if os.path.exists(local_dir):
  264. shutil.rmtree(local_dir)
  265. if not os.path.exists(local_dir):
  266. os.makedirs(local_dir)
  267. ftp.file_list = []
  268. for path in ftp.dir_list:
  269. ftp.get_files(path)
  270. for i in range(ftp.file_list.__len__() - 1, -1, -1):
  271. path = ftp.file_list[i]
  272. (filepath, filename) = os.path.split(path)
  273. if filename != 'build.prop':
  274. ftp.file_list.remove(path)
  275. file_list = []
  276. for i in range(0, ftp.file_list.__len__()):
  277. path = ftp.file_list[i]
  278. (filepath, filename) = os.path.split(path)
  279. file_list.append(local_dir + '\\' + str(i) + filename)
  280. ftp.download_file(local_dir + '\\' + str(i) + filename, path)
  281. return file_list
  282. # 解析指定的prop文件;
  283. def parse_prop(path, find_objs):
  284. brand = ''
  285. prop_list = []
  286. if os.path.exists(path) is False:
  287. return
  288. with open(path, 'r') as f:
  289. content = f.read()
  290. for obj in find_objs:
  291. res = r"\n%s=(.*)\n" % obj
  292. print "expression:", res
  293. p = re.compile(res)
  294. mo = p.search(content)
  295. if mo is not None:
  296. prop = mo.group()
  297. if prop.find("test-keys"):
  298. prop = prop.replace("test-keys", "release-keys")
  299. prop = prop.strip('\n')
  300. prop_list.append(prop)
  301. if obj == 'ro.product.brand':
  302. brand = prop.replace(obj + '=', '')
  303. print "prop_list=", prop_list
  304. (filepath, filename) = os.path.split(path)
  305. if prop_list.__len__() > 0:
  306. prop_file = "%s\\%s.prop" % (filepath, brand.lower())
  307. if os.path.exists(prop_file):
  308. os.remove(prop_file)
  309. print "prop file:", prop_file
  310. with open(prop_file, 'ab+') as f:
  311. for prop in prop_list:
  312. f.writelines(prop + '\n')
  313. # 移除原文件;
  314. os.remove(path)
  315. return content.split('\n') # 将待匹配字符串保存在数组中
  316. if __name__ == "__main__":
  317. file_list = download_prop(FTPDIR41, LOCALDIR41)
  318. for file in file_list:
  319. parse_prop(file, ['ro.product.model',
  320. 'ro.product.brand',
  321. 'ro.product.name',
  322. 'ro.build.flavor',
  323. 'ro.build.date',
  324. 'ro.build.fingerprint',
  325. 'ro.build.date.utc',
  326. 'ro.build.description',
  327. 'ro.build.version.incremental']
  328. )
  329. file_list = download_prop(FTPDIR51, LOCALDIR51)
  330. for file in file_list:
  331. parse_prop(file, ['ro.product.model',
  332. 'ro.product.brand',
  333. 'ro.product.name',
  334. 'ro.build.flavor',
  335. 'ro.build.date',
  336. 'ro.build.fingerprint',
  337. 'ro.build.date.utc',
  338. 'ro.build.description',
  339. 'ro.build.version.incremental']
  340. )
  341. print "FTP-OK"