由于是刚接触python不久,所以很多都不是很熟练,只能是用到什么查点什么。所以如果有什么bug或者不严谨的语法或其他,希望各位看客指正。
鉴于公司的平台研发部门需求想直接把svn中的差异代码导出并打包自动上传到指定的服务器上,然后在从指定的服务器上进行一个发布更新。由于我们开发和发布服务器的环境很特殊,中间牵扯到很多网络代理。所以才这么麻烦。
要求如下:
1、自动导出指定版本之间的差异文件
2、根据给定的选项过滤出指定的文件夹以及文件;例如给定选项 a ,那就导出的文件中只保留admin的内容
3、自动打包这些内容并按照当前的时间命名
4、以FTP模式上传到指定的服务器
主要还是在windows下操作这些,实在想不出什么好的方法,于是网络搜索求助。网络真是个神奇的东西,当然我还是没有搜到任何结果。于是加了一些脚本的群,随机的找一个管理员问下有没有相关的脚本或思路。真是天无绝人之路。第一个请教的哥们就给了我一个回答。python可以搞定(当然给的指导肯定不止这些)。
于是当下又在学习python,顺便就用这个来实现(其实是不知道用什么来操作的)
在多次google、baidu之后。就写了以下的脚本,目前测试是能满足基本需求的:
python的环境需求:py32-pysvn, python-3.2
pysvn下载官网:http://pysvn.tigris.org/
python的官网就不用提供了吧。
下面贴出代码:
#-*- coding: utf-8 -*- #!/usr/bin/env python # ==================================================================== # # svnchanged_export.py # # Export Files in a revision Range # Usage: python SCRIPT_NAME.py -r beginRev:endRev [ --username user --password passwd ] svnurl site_version_name(a/s/p) # a [admin] s [static] p [platform] # # ==================================================================== import pysvn # http://pysvn.tigris.org/ import getopt, time, string, sys, shutil import os, urllib, tarfile, getpass import unicodedata from urllib.parse import urlparse from ftplib import FTP # Options by default date_folder=time.strftime(r"%Y%m%d%H%M%S", time.localtime()) site_version="p" #targetPath = "." # Current directory export_dir="xxxx" # Change into a folder you want to export, The store path relative to the script username = "" password = "" url = "" ftp_host="xxx.xxx.xxx.xxx" ftp_port=xxx ftp_user=‘xxxx‘ ftp_pass=‘xxxx‘ revision_min = pysvn.Revision( pysvn.opt_revision_kind.number, 0 ) revision_max = pysvn.Revision( pysvn.opt_revision_kind.head ) hasRevision = False current_dir = os.getcwd() os.chdir(r‘%s/%s‘ %(os.getcwd(),export_dir)) os.makedirs(r‘%s‘ %(date_folder)) os.chdir(‘../‘) targetPath=(r"%s\%s") % (export_dir,date_folder) try: optlist, args = getopt.getopt (sys.argv[1:], "r:u:p:", ["revision=", "username=", "password="]) if len(args) == 1 or len(args) == 2: url = args[0] if len(args) == 2: #targetPath = args[1] site_version = args[1] else: raise Exception ("Input URL [site_version]") for option, value in optlist: if option == "--username" or option == "-u": username = value elif option == "--password" or option == "-p": password = value elif option == "--revision" or option == "-r": revision = value if str.find(value, ":") >= 0: (revision_min0, revision_max0) = str.split(value, ":") revision_min = pysvn.Revision( pysvn.opt_revision_kind.number, int(revision_min0) ) if revision_max0 != "HEAD": revision_max = pysvn.Revision( pysvn.opt_revision_kind.number, int(revision_max0) ) hasRevision = True else: raise Exception ("Please Input revision range " + str(option)) else: raise Exception ("Unknown option " + str(option)) if hasRevision == False: raise Exception ("Please Input Revision Range -r min:max") #urlObject = urlparse(url) #if urlObject.scheme == ‘http‘ or urlObject.scheme == ‘https‘: # url = urlObject.scheme+"://"+urlObject.netloc+urllib.quote(urlObject.path.decode(sys.stdin.encoding).encode(‘utf8‘)) #else: #url = unicode(url, sys.stdin.encoding) #print (sys.stdin.encoding) # print(url) if not url.endswith("/"): url = url + "/" except getopt.error as reason: raise Exception("Usage: " + sys.argv[0] + ": " + str(reason)) f_list=[] f_list=os.listdir(targetPath) for f in f_list: f_path=os.path.join(targetPath, f) if os.path.isfile(f_path): os.remove(f_path) print (f_path+" removed.") else: shutil.rmtree(f_path) print (f_path+ " removed.") print (targetPath+" is already empty.") def get_login(realm,user,may_save): return True, username, password, False print ("SVN Path:"+url+‘ ‘+"Diff file path:"+targetPath) client = pysvn.Client() if username != "" and password != "": client.callback_get_login = get_login summary = client.diff_summarize(url, revision_min, url, revision_max) #print summary for changed in summary: #path, summarize_kind, node_kind, prop_changed #for key in changed.iterkeys(): # print key if pysvn.diff_summarize_kind.delete == changed[‘summarize_kind‘]: fullPath = targetPath+"/"+changed[‘path‘] if os.path.exists(fullPath): os.remove(fullPath) if pysvn.diff_summarize_kind.added == changed[‘summarize_kind‘] or pysvn.diff_summarize_kind.modified == changed[‘summarize_kind‘]: print (changed[‘summarize_kind‘], changed[‘path‘]) if changed[‘node_kind‘] == pysvn.node_kind.file: #uniPath = changed[‘path‘].decode(‘utf8‘).encode() file_text = client.cat(url+urllib.parse.quote(changed[‘path‘].encode(‘utf8‘)), revision_max) fullPath = targetPath+"/"+changed[‘path‘] dirPath = fullPath[0:fullPath.rfind("/")] if not os.path.exists(dirPath): os.makedirs(dirPath) f = open(fullPath,‘wb‘) f.write(file_text) f.close #f = open(fullPath,‘wb‘) #f.write(file_text) #f.close #f_tar="./"+os.path.basename(targetPath)+".tar" #if os.path.exists(f_tar): # os.remove(f_tar) # print (os.path.basename(f_tar)+" is removed.") #else: # print (os.path.basename(f_tar)+" is not exists.") # Folder filter regulation os.chdir((r"%s") % targetPath) p_list = a_list = s_list = os.listdir(os.getcwd()) p_outer_list = list(filter(lambda x:x != "website" and x != "framework", p_list)) a_outer_list = list(filter(lambda x:x != "website" and x != "framework" and x != "service", a_list)) s_outer_list = list(filter(lambda x:x != "website", s_list)) os.chdir((r"%s\website") % targetPath) p_inner_list = a_inner_list = s_inner_list = os.listdir(os.getcwd()) p_inner_list = list(filter(lambda x:x != "platform", p_inner_list)) a_inner_list = list(filter(lambda x:x != "admin" and x != "union", a_inner_list)) s_inner_list = list(filter(lambda x:x != "static", s_inner_list)) def inner_filter(list_op): for i in list_op: shutil.rmtree((r"%s\website\%s") % (targetPath,i)) os.chdir((r"%s") % t_path) print (os.listdir(os.getcwd())) def filter_site(site_op): if site_version == "p": for p_o in p_outer_list: shutil.rmtree((r"%s\%s") % (targetPath,p_o)) inner_filter(p_inner_list) elif site_version == "a": for a_o in a_outer_list: shutil.rmtree((r"%s\%s") % (targetPath,a_o)) inner_filter(a_inner_list) elif site_version == "s": for s_o in s_outer_list: shutil.rmtree((r"%s\%s") % (targetPath,s_o)) inner_filter(s_inner_list) else: raise Exception (("Unknown site_option: %s") % site_op) filter_site(site_version) print (("export file: %s_%s"+‘.tar‘) % (site_version,date_folder)) def make_tar(folder_to_tar,dst_folder): fold_name = os.path.basename(folder_to_tar) dst_name = "%s_%s.tar" %(site_version,fold_name) dst_path = os.path.join(dst_folder, dst_name) tar = tarfile.TarFile.open(dst_path, ‘w‘) tar.add(folder_to_tar, fold_name) tar.close() return dst_path dst_file = make_tar(targetPath,‘./‘) # print (dst_file) def upload_file(localfile): ftp=FTP() ftp.connect(ftp_host,ftp_port) ftp.login(ftp_user,ftp_pass) ftp.cwd(‘./‘) file=open(localfile,‘rb‘) ftp.storbinary(‘STOR %s‘ % os.path.basename(localfile),file) ftp.retrlines(‘LIST‘) file.close() ftp.close() ftp.quit upload_file(dst_file) print (‘File Upload Successful.‘)
代码就是如上这么多,中间肯定有很多语法的不严谨和bug,大家多多指正。如有需要的可以直接拿去对应的改改基本上也是可以用的。
本文出自 “Soul” 博客,请务必保留此出处http://chenpipi.blog.51cto.com/8563610/1604039
原文地址:http://chenpipi.blog.51cto.com/8563610/1604039