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月前
|
PyTorch Linux 算法框架/工具
pytorch学习一:Anaconda下载、安装、配置环境变量。anaconda创建多版本python环境。安装 pytorch。
这篇文章是关于如何使用Anaconda进行Python环境管理,包括下载、安装、配置环境变量、创建多版本Python环境、安装PyTorch以及使用Jupyter Notebook的详细指南。
255 1
pytorch学习一:Anaconda下载、安装、配置环境变量。anaconda创建多版本python环境。安装 pytorch。
|
1月前
|
安全 Linux 数据安全/隐私保护
python知识点100篇系列(15)-加密python源代码为pyd文件
【10月更文挑战第5天】为了保护Python源码不被查看,可将其编译成二进制文件(Windows下为.pyd,Linux下为.so)。以Python3.8为例,通过Cython工具,先写好Python代码并加入`# cython: language_level=3`指令,安装easycython库后,使用`easycython *.py`命令编译源文件,最终生成.pyd文件供直接导入使用。
python知识点100篇系列(15)-加密python源代码为pyd文件
|
14天前
|
开发者 Python
Python中__init__.py文件的作用
`__init__.py`文件在Python包管理中扮演着重要角色,通过标识目录为包、初始化包、控制导入行为、支持递归包结构以及定义包的命名空间,`__init__.py`文件为组织和管理Python代码提供了强大支持。理解并正确使用 `__init__.py`文件,可以帮助开发者更好地组织代码,提高代码的可维护性和可读性。
16 2
|
30天前
|
Java Python
> python知识点100篇系列(19)-使用python下载文件的几种方式
【10月更文挑战第7天】本文介绍了使用Python下载文件的五种方法,包括使用requests、wget、线程池、urllib3和asyncio模块。每种方法适用于不同的场景,如单文件下载、多文件并发下载等,提供了丰富的选择。
|
30天前
|
数据安全/隐私保护 流计算 开发者
python知识点100篇系列(18)-解析m3u8文件的下载视频
【10月更文挑战第6天】m3u8是苹果公司推出的一种视频播放标准,采用UTF-8编码,主要用于记录视频的网络地址。HLS(Http Live Streaming)是苹果公司提出的一种基于HTTP的流媒体传输协议,通过m3u8索引文件按序访问ts文件,实现音视频播放。本文介绍了如何通过浏览器找到m3u8文件,解析m3u8文件获取ts文件地址,下载ts文件并解密(如有必要),最后使用ffmpeg合并ts文件为mp4文件。
|
1月前
|
机器学习/深度学习 人工智能 架构师
Python学习圣经:从0到1,精通Python使用
尼恩架构团队的大模型《LLM大模型学习圣经》是一个系统化的学习系列,初步规划包括以下内容: 1. **《Python学习圣经:从0到1精通Python,打好AI基础》** 2. **《LLM大模型学习圣经:从0到1吃透Transformer技术底座》**
Python学习圣经:从0到1,精通Python使用
|
1月前
|
机器学习/深度学习 缓存 PyTorch
pytorch学习一(扩展篇):miniconda下载、安装、配置环境变量。miniconda创建多版本python环境。整理常用命令(亲测ok)
这篇文章是关于如何下载、安装和配置Miniconda,以及如何使用Miniconda创建和管理Python环境的详细指南。
359 0
pytorch学习一(扩展篇):miniconda下载、安装、配置环境变量。miniconda创建多版本python环境。整理常用命令(亲测ok)
|
1月前
|
JSON 数据格式 Python
Python实用记录(十四):python统计某个单词在TXT/JSON文件中出现的次数
这篇文章介绍了一个Python脚本,用于统计TXT或JSON文件中特定单词的出现次数。它包含两个函数,分别处理文本和JSON文件,并通过命令行参数接收文件路径、目标单词和文件格式。文章还提供了代码逻辑的解释和示例用法。
42 0
Python实用记录(十四):python统计某个单词在TXT/JSON文件中出现的次数
|
1月前
|
机器学习/深度学习 人工智能 架构师
|
1月前
|
机器学习/深度学习 缓存 Linux
python环境学习:pip介绍,pip 和 conda的区别和联系。哪个更好使用?pip创建虚拟环境并解释venv模块,pip的常用命令,conda的常用命令。
本文介绍了Python的包管理工具pip和环境管理器conda的区别与联系。pip主要用于安装和管理Python包,而conda不仅管理Python包,还能管理其他语言的包,并提供强大的环境管理功能。文章还讨论了pip创建虚拟环境的方法,以及pip和conda的常用命令。作者推荐使用conda安装科学计算和数据分析包,而pip则用于安装无法通过conda获取的包。
67 0