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天前
|
JSON JavaScript 数据格式
python遍历目录文件_结合vue获取所有的html文件并且展示
python遍历目录文件_结合vue获取所有的html文件并且展示
4 0
|
1天前
|
运维 Shell Python
Shell和Python学习教程总结
Shell和Python学习教程总结
|
2天前
|
Python
Python从入门到精通:深入学习面向对象编程——2.1.2继承、封装和多态的概念
Python从入门到精通:深入学习面向对象编程——2.1.2继承、封装和多态的概念
|
2天前
|
开发框架 前端开发 数据库
Python从入门到精通:3.3.2 深入学习Python库和框架:Web开发框架的探索与实践
Python从入门到精通:3.3.2 深入学习Python库和框架:Web开发框架的探索与实践
|
2天前
|
数据采集 数据可视化 数据处理
Python从入门到精通的文章3.3.1 深入学习Python库和框架:数据处理与可视化的利器
Python从入门到精通的文章3.3.1 深入学习Python库和框架:数据处理与可视化的利器
|
2天前
|
存储 网络协议 关系型数据库
Python从入门到精通:2.3.2数据库操作与网络编程——学习socket编程,实现简单的TCP/UDP通信
Python从入门到精通:2.3.2数据库操作与网络编程——学习socket编程,实现简单的TCP/UDP通信
|
7天前
|
存储 Python
用Python实现批量下载文件——代理ip排除万难
用Python实现批量下载文件——代理ip排除万难
|
7天前
|
JSON 关系型数据库 数据库
《Python 简易速速上手小册》第6章:Python 文件和数据持久化(2024 最新版)
《Python 简易速速上手小册》第6章:Python 文件和数据持久化(2024 最新版)
35 0
|
15天前
|
安全 Java 数据处理
Python网络编程基础(Socket编程)多线程/多进程服务器编程
【4月更文挑战第11天】在网络编程中,随着客户端数量的增加,服务器的处理能力成为了一个重要的考量因素。为了处理多个客户端的并发请求,我们通常需要采用多线程或多进程的方式。在本章中,我们将探讨多线程/多进程服务器编程的概念,并通过一个多线程服务器的示例来演示其实现。