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,如需转载请自行联系原作者
相关文章
|
1月前
|
存储 Java 数据处理
(numpy)Python做数据处理必备框架!(一):认识numpy;从概念层面开始学习ndarray数组:形状、数组转置、数值范围、矩阵...
Numpy是什么? numpy是Python中科学计算的基础包。 它是一个Python库,提供多维数组对象、各种派生对象(例如掩码数组和矩阵)以及用于对数组进行快速操作的各种方法,包括数学、逻辑、形状操作、排序、选择、I/0 、离散傅里叶变换、基本线性代数、基本统计运算、随机模拟等等。 Numpy能做什么? numpy的部分功能如下: ndarray,一个具有矢量算术运算和复杂广播能力的快速且节省空间的多维数组 用于对整组数据进行快速运算的标准数学函数(无需编写循环)。 用于读写磁盘数据的工具以及用于操作内存映射文件的工具。 线性代数、随机数生成以及傅里叶变换功能。 用于集成由C、C++
301 0
|
1月前
|
存储 JavaScript Java
(Python基础)新时代语言!一起学习Python吧!(四):dict字典和set类型;切片类型、列表生成式;map和reduce迭代器;filter过滤函数、sorted排序函数;lambda函数
dict字典 Python内置了字典:dict的支持,dict全称dictionary,在其他语言中也称为map,使用键-值(key-value)存储,具有极快的查找速度。 我们可以通过声明JS对象一样的方式声明dict
169 1
|
1月前
|
算法 Java Docker
(Python基础)新时代语言!一起学习Python吧!(三):IF条件判断和match匹配;Python中的循环:for...in、while循环;循环操作关键字;Python函数使用方法
IF 条件判断 使用if语句,对条件进行判断 true则执行代码块缩进语句 false则不执行代码块缩进语句,如果有else 或 elif 则进入相应的规则中执行
259 1
|
2月前
|
数据可视化 Linux iOS开发
Python脚本转EXE文件实战指南:从原理到操作全解析
本教程详解如何将Python脚本打包为EXE文件,涵盖PyInstaller、auto-py-to-exe和cx_Freeze三种工具,包含实战案例与常见问题解决方案,助你轻松发布独立运行的Python程序。
984 2
|
1月前
|
存储 Java 索引
(Python基础)新时代语言!一起学习Python吧!(二):字符编码由来;Python字符串、字符串格式化;list集合和tuple元组区别
字符编码 我们要清楚,计算机最开始的表达都是由二进制而来 我们要想通过二进制来表示我们熟知的字符看看以下的变化 例如: 1 的二进制编码为 0000 0001 我们通过A这个字符,让其在计算机内部存储(现如今,A 字符在地址通常表示为65) 现在拿A举例: 在计算机内部 A字符,它本身表示为 65这个数,在计算机底层会转为二进制码 也意味着A字符在底层表示为 1000001 通过这样的字符表示进行转换,逐步发展为拥有127个字符的编码存储到计算机中,这个编码表也被称为ASCII编码。 但随时代变迁,ASCII编码逐渐暴露短板,全球有上百种语言,光是ASCII编码并不能够满足需求
145 4
|
1月前
|
监控 机器人 编译器
如何将python代码打包成exe文件---PyInstaller打包之神
PyInstaller可将Python程序打包为独立可执行文件,无需用户安装Python环境。它自动分析代码依赖,整合解释器、库及资源,支持一键生成exe,方便分发。使用pip安装后,通过简单命令即可完成打包,适合各类项目部署。
|
2月前
|
JavaScript Java 大数据
基于python的网络课程在线学习交流系统
本研究聚焦网络课程在线学习交流系统,从社会、技术、教育三方面探讨其发展背景与意义。系统借助Java、Spring Boot、MySQL、Vue等技术实现,融合云计算、大数据与人工智能,推动教育公平与教学模式创新,具有重要理论价值与实践意义。
|
2月前
|
数据采集 机器学习/深度学习 人工智能
Python:现代编程的首选语言
Python:现代编程的首选语言
284 102
|
2月前
|
数据采集 机器学习/深度学习 算法框架/工具
Python:现代编程的瑞士军刀
Python:现代编程的瑞士军刀
308 104

推荐镜像

更多