由于是刚接触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的官网就不用提供了吧。
使用方法:
在windows下dos里切换到脚本存放目录,然后使用脚本内给的用法进行脚本导出。导出的文件夹是相对脚本存放路径来的。
下面贴出代码:
#-*- 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(a | s | p)
# site_version: 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,大家多多指正。如有需要的可以直接拿去对应的改改基本上也是可以用的。
转载于:https://blog.51cto.com/chenpipi/1604039