Python实现SVN的目录周期性备份实例
作者:优雅先生 发布时间:2021-07-19 16:13:22
标签:Python,SVN,备份
本文实例讲述了Python实现SVN的目录周期性备份方法。分享给大家供大家参考。具体如下:
起因:今天用SVN时,不小心把远程SVN服务器上的目录删掉了,然后在本地又手贱地还原了一下项目(eclipse中右键项目team => 还原),导致写了大半天的代码全部丢失,用多款数据恢复软件恢复也无果。一怒之下写了这个目录周期性备份小工具,每隔5秒备份源目录中的所有文件到目标目录(保留结构),保证目标目录中的文件只增不减。且每次只拷贝发生变化的文件(比较两个文件的MD5值)。
思考:虽然SVN也是一个版本管理软件,但在使用过程总觉得它的诸多操作挺别扭,相比而言Git更强大灵活。我自己理想中的版本控制软件至少应该考虑到一些让用户产生较强挫败的使用场景(也许大部分情况是因为用户误用,但如果误用情况也能考虑到,才能更体现软件的终极人文关怀嘛),比如删除远程服务器上的文件,我觉得应该设计成这样:即使用户删除了文件,文件还应该在一个缓冲区中呆1天(或几个小时,可以配置),然后由一个定时任务定时删除缓冲区中停留时间超过1天的文件。而不是立即物理删除。
TODO:
增加配置文件,做成命令行程序
md5_caculate.py:
# -*- coding: utf-8 -*-
#!/usr/bin/python
from hashlib import md5
import os
def calMD5(str):
m = md5()
m.update(str)
return m.hexdigest()
def calMD5ForFile(file):
statinfo = os.stat(file)
if int(statinfo.st_size) / (1024*1024) >= 1000:
# print("File size > 1000, move to big file...")
return calMD5ForBigFile(file)
m = md5()
f = open(file, 'rb')
m.update(f.read())
f.close()
return m.hexdigest()
def calMD5ForFolder(dir, MD5File):
outfile = open(MD5File,'w')
for root, subdirs, files in os.walk(dir):
for file in files:
filefullpath = os.path.join(root, file)
"""print filefullpath"""
filerelpath = os.path.relpath(filefullpath, dir)
md5 = calMD5ForFile(filefullpath)
outfile.write(filerelpath+' '+md5+"\n")
outfile.close()
def calMD5ForBigFile(file):
m = md5()
f = open(file, 'rb')
buffer = 8192 # why is 8192 | 8192 is fast than 2048
while 1:
chunk = f.read(buffer)
if not chunk : break
m.update(chunk)
f.close()
return m.hexdigest()
if __name__=="__main__":
print(calMD5ForFile("e:/test/target/a/b/rabbit.txt"))
file_util.py:
# -*- coding: utf-8 -*-
#!/usr/bin/python
import os,shutil
from md5_caculate import calMD5ForFile
# 拷贝源目录到目标目录
def copyDir(srcDir, dstDir):
if srcDir in dstDir: # 源目录包含在目标目录,则直接返回
return
if not os.path.isdir(srcDir):
print(srcDir, "路径指定的源目录不存在!")
return;
if not os.path.exists(dstDir): # 目标目录不存在时则创建
os.makedirs(dstDir)
for fileOrDirName in os.listdir(srcDir): # 源目录下的所有文件(包括文件和目录) TODO BUG:如果srcDir为一个空目录?
# fileOrDirPath = srcDir + "/" + fileOrDirName
fileOrDirPath = os.path.join(srcDir, fileOrDirName)
if os.path.isfile(fileOrDirPath): # 如果当前是一个子文件,则直接复制文件
copyFile(fileOrDirPath, dstDir)
if os.path.isdir(fileOrDirPath): # 如果当前是一个子目录,则递归复制目录
copyDir(fileOrDirPath, os.path.join(dstDir, fileOrDirName))
# 拷贝源文件到目标目录
def copyFile(srcFile, dstDir):
if not os.path.isfile(srcFile):
print(srcFile, "路径指定的源文件不存在!")
return
fileName = os.path.basename(srcFile)
dstFile = os.path.join(dstDir, fileName)
if os.path.isfile(dstFile): # 有同名的目标文件,则检查MD5值是否相同,如果不同才Copy
if calMD5ForFile(srcFile) != calMD5ForFile(dstFile):
try:
shutil.copy(srcFile, dstDir)
except PermissionError:
print("PermissionError occurs: ", srcFile)
else:
shutil.copy(srcFile, dstDir)
if __name__=="__main__":
copyDir("e:/test/src", "e:/test/target")
backuper.py:
# -*- coding: utf-8 -*-
#!/usr/bin/python
import os, time
from file_util import copyDir
# -------------------------------------------------------------
# 定时备份源目录到目标目录
# version = 1.0
# author = Will
# -------------------------------------------------------------
# 定时备份源目录到目标目录,sleepIntervalSeconds为备份时间间隔秒数
def backupDir(srcDir, dstDir, sleepIntervalSeconds):
if not os.path.isdir(srcDir):
print("请指定要备份源目录并确保目录存在!")
return;
while True:
print("备份:", srcDir, ",到:", dstDir)
copyDir(srcDir, dstDir)
print("开始休眠", sleepIntervalSeconds, "秒...")
time.sleep(sleepIntervalSeconds)
if __name__=="__main__":
backupDir("d:/Documents/workspace/workspace/griddle", "e:/backup/griddle", 20)
希望本文所述对大家的Python程序设计有所帮助。


猜你喜欢
- 一、关闭数据库[oracle@RHEL5]$sqlplus / as sysdba SQL>shutdown immediate; 二
- 前言最近无意间发现mysql的coalesce,又正好有时间,就把mysql中coalesce()的使用技巧总结下分享给大家,下面来一起看看
- 我想此时不妨使用字符串参数来帮助我们解决这种情况,利用字符串分割的方法将一个参数分割成数个参数来解决。下面我们看一个例子: 假设现在给你一个
- 用CSV格式来保存文件是个不错的主意,因为大部分程序设计语言和应用程序都能处理这种格式,所以交流起来非常方便。然而这种格式的存储效率不是很高
- Pandas中的resample,重新采样,是对原样本重新处理的一个方法,是一个对常规时间序列数据重新采样和频率转换的便捷的方法。方法的格式
- 本文实例为大家分享了python实现剪切功能的具体代码,供大家参考,具体内容如下#!/usr/bin/env python#coding:
- 目录题目描述:思路:代码:改良版采用递归数学方法题目描述:编写一个算法来确定一个数字是否“快乐”。 快乐的数字按照如下方式确定:从一个正整数
- 在ACCESS数据库中可以用MSSQL的形式定义操作字符串,也可以采用OLEDB的形式。MSSQL 形式string sqlText = @
- 目录简介环境要求:安装小试一下创建爬虫将请求头转为json格式使用简介feapder 是一款上手简单,功能强大的Python爬虫框架,使用方
- 前段时间自学了一段时间的Python,想着浓一点项目来练练手。看着大佬们一说就是爬了100W+的数据就非常的羡慕,不过对于我这种初学者来说,
- 之前上传图片都是直接将图片转化为io流传给服务器,没有用框架传图片。最近做项目,打算换个方法上传图片。Android发展到现在,Okhttp
- 前言此Julia非彼Julia,指的是对于某复数 &nb
- v1.0.0完成基础框架、初始功能背景:为了提高日常工作效率、学习界面工具开发,可以将一些常用的功能集成到一个小的测试工具中,供大家使用。一
- 人在学校,身不由己。总有一些奇奇怪怪的学习任务,需要我们刷够一定的时长去完成,但这很多都是不太令人感兴趣的文字或是视频,而这些课都有共同的特
- Hedger Wang 在国内 blog 上得到的方法:使用 try … finally 结构来使对象最终为 null ,以阻止内存泄露。其
- 官网下载就好, https://www.python.org/downloads/release/python-352/用installer
- Request.ServerVariables里Server_Name与Http_Host之间有什么区别呢?如果不仔细看,您应该看不出它们之
- (1)饼图(pie),即在一个圆圈内分成几块,显示不同数据系列的占比大小,这也是我们在日常数据的图形展示中最常用的图形之一。在python中
- 问题缘由:负责公司的开发平台研发工作,考虑的知识产权的保护工作,必须要考虑java的加密技术和js脚本的加密技术。在目前java加密很容易破
- 作为前端开发工程师,平时对于Dom的查找遍历和操作是家常便饭。对于优秀的前端来说,也肯定早已有了自己的一套方法来封装这些重复的操作。但是,现