Python基础学习:svn导出差异文件脚本

由于是刚接触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里切换到脚本存放目录,然后使用脚本内给的用法进行脚本导出。导出的文件夹是相对脚本存放路径来的。

下面贴出代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
#-*- 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 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)
                         
            = 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 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,大家多多指正。如有需要的可以直接拿去对应的改改基本上也是可以用的。



本文转自Mr_陈 51CTO博客,原文链接:http://blog.51cto.com/chenpipi/1604039,如需转载请自行联系原作者
上一篇:聚焦2021云栖大会,边缘云专场畅谈技术应用创新


下一篇:短视频APP开发:短视频特效SDK功能火爆来袭!