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的官网就不用提供了吧。

下面贴出代码:

#-*- 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_name(a/s/p)
# 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,大家多多指正。如有需要的可以直接拿去对应的改改基本上也是可以用的。

时间: 2024-08-05 21:13:31

Python基础学习:svn导出差异文件脚本的相关文章

python基础学习shutil高级的文件,目录,压缩包处理模块

shutil高级的文件,目录,压缩包处理模块import shutil 复制shutil.copyfileobj(f1,f2) #从一个文件对接复制到另一个文件对象,需要先打开文件shutil.copyfile() #拷贝文件shutil.copystat() #只拷贝文件状态信息 包括 modebits,atime,mtime,flagsshutil.copymode() #值拷贝权限.内容和组,用户均不改变shutil.copy() #拷贝文件和权限shutil.copy2() #同时拷贝文

python基础学习07(核心编程第二版)部分

# -*- coding: utf-8 -*- # ==================== #File: python #Author: python #Date: 2014 #==================== __author__ = 'Administrator' #file与input output #文件对象 #简单说来,就是写入和读取的方式 #file(),open()2个操作都是一样的,一般推荐open() #语法 # open(name[, mode[, bufferin

python基础学习05(核心编程第二版)部分

# -*- coding: utf-8 -*- # ==================== #File: python #Author: python #Date: 2014 #==================== __author__ = 'Administrator' #dict{键:值} #哈希 #注:字典是无顺序的,所以你懂的 #创建与赋值 dict1={} dict2={'name':'apply','avg':24,'sex':'man'} print dict1,dict2

Python基础学习(九)

Python 多线程 多线程类似于同时执行多个不同程序,多线程运行有如下优点: 使用线程可以把占据长时间的程序中的任务放到后台去处理. 用户界面可以更加吸引人,这样比如用户点击了一个按钮去触发某些事件的处理,可以弹出一个进度条来显示处理的进度 程序的运行速度可能加快 在一些等待的任务实现上如用户输入.文件读写和网络收发数据等,线程就比较有用了.在这种情况下我们可以释放一些珍贵的资源如内存占用等等. 线程在执行过程中与进程还是有区别的.每个独立的线程有一个程序运行的入口.顺序执行序列和程序的出口.

Python基础学习(十)

Python I/O模型 同步IO和异步IO,阻塞IO和非阻塞IO分别是什么,到底有什么区别?不同的人在不同的上下文下给出的答案是不同的.所以先限定一下本文的上下文. 概念说明 在进行解释之前,首先要说明几个概念: 用户空间和内核空间 进程切换 进程的阻塞 文件描述符 缓存 I/O 用户空间与内核空间 现在操作系统都是采用虚拟存储器,那么对32位操作系统而言,它的寻址空间(虚拟存储空间)为4G(2的32次方).操作系统的核心是内核,独立于普通的应用程序,可以访问受保护的内存空间,也有访问底层硬件

python基础学习11(核心编程第二版)部分

# -*- coding: utf-8 -*- # ==================== #File: python #Author: python #Date: 2014 #==================== __author__ = 'Administrator' #执行环境 #可调用对象 """ 许多的python 对象都是我们所说的可调用的,即是任何能通过函数操作符“()”来调用的对象.要调用可调用对象, 函数操作符得紧跟在可调用对象之后.Python 有4

Python基础学习 总结篇

Python基础学习总结 先附上所有的章节: Python学习(一)安装.环境配置及IDE推荐 Python学习(二)Python 简介 Python学习(三)流程控制 Python学习(四)数据结构(概要) Python学习(四)数据结构 —— int float Python学习(四)数据结构 —— str Python学习(四)数据结构 —— bool Python学习(四)数据结构 —— list tuple range Python学习(四)数据结构 —— set frozenset

python基础学习日志day5-各模块文章导航

python基础学习日志day5---模块使用 http://www.cnblogs.com/lixiang1013/p/6832475.html python基础学习日志day5---time和datetime模块 http://www.cnblogs.com/lixiang1013/p/6848245.html python基础学习日志day5---random模块http://www.cnblogs.com/lixiang1013/p/6849162.html python基础学习日志da

Python 基础学习 网络小爬虫

<span style="font-size:18px;"># # 百度贴吧图片网络小爬虫 # import re import urllib def getHtml(url): page = urllib.urlopen(url) html = page.read() return html def getImg(html): reg = r'src="(.+?\.jpg)" pic_ext' imgre = re.compile(reg) imgli