ftp.py 13 KB

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