Python实现SVN的目录周期性备份实例


Posted in Python onJuly 17, 2015

本文实例讲述了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程序设计有所帮助。

Python 相关文章推荐
使用python实现baidu hi自动登录的代码
Feb 10 Python
Django与遗留的数据库整合的方法指南
Jul 24 Python
python抓取并保存html页面时乱码问题的解决方法
Jul 01 Python
在Django中URL正则表达式匹配的方法
Dec 20 Python
Python异步操作MySQL示例【使用aiomysql】
May 16 Python
Python通过VGG16模型实现图像风格转换操作详解
Jan 16 Python
python 异步async库的使用说明
May 04 Python
Django封装交互接口代码
Jul 12 Python
用Python自动清理系统垃圾的实现
Jan 18 Python
python3定位并识别图片验证码实现自动登录功能
Jan 29 Python
10张动图学会python循环与递归问题
Feb 06 Python
python爬取股票最新数据并用excel绘制树状图的示例
Mar 01 Python
Python的Django框架中设置日期和字段可选的方法
Jul 17 #Python
Python的Django框架下管理站点的基本方法
Jul 17 #Python
Django中更新多个对象数据与删除对象的方法
Jul 17 #Python
Django框架中数据的连锁查询和限制返回数据的方法
Jul 17 #Python
Django中对数据查询结果进行排序的方法
Jul 17 #Python
在Python的Django框架中获取单个对象数据的简单方法
Jul 17 #Python
Python的Django框架中的数据过滤功能
Jul 17 #Python
You might like
PHP及Zend Engine的线程安全模型分析
2011/11/10 PHP
示例详解Laravel的注册重构
2016/08/14 PHP
php删除txt文件指定行及按行读取txt文档数据的方法
2017/01/30 PHP
thinkphp3.2实现跨控制器调用其他模块的方法
2017/03/14 PHP
PHP面向对象五大原则之里氏替换原则(LSP)详解
2018/04/08 PHP
jquery提取元素里的纯文本不包含span等里的内容
2013/09/30 Javascript
当达到输入长度时表单自动切换焦点
2014/04/06 Javascript
jQuery实现带幻灯的tab滑动切换风格菜单代码
2015/08/27 Javascript
JavaScript 判断一个对象{}是否为空对象的简单方法
2016/10/09 Javascript
JavaScript prototype属性详解
2016/10/25 Javascript
bootstrap 下拉多选框进行多选传值问题代码分析
2017/02/14 Javascript
angularJS深拷贝详解
2017/03/23 Javascript
深入理解react-router@4.0 使用和源码解析
2017/05/23 Javascript
nodejs简单实现TCP服务器端和客户端的聊天功能示例
2018/01/04 NodeJs
python 解压pkl文件的方法
2018/10/25 Python
python实现写数字文件名的递增保存文件方法
2018/10/25 Python
filter使用python3代码进行迭代元素的实例详解
2020/12/03 Python
python使用Windows的wmic命令监控文件运行状况,如有异常发送邮件报警
2021/01/30 Python
佳能法国商店:Canon法国
2019/02/14 全球购物
Oakley西班牙官方商店:太阳眼镜和男女运动服
2019/04/26 全球购物
VC++笔试题
2014/10/13 面试题
linux面试题参考答案(9)
2016/01/29 面试题
护理工作感言
2014/01/16 职场文书
简历的自我评价
2014/02/03 职场文书
2014年情人节活动方案
2014/02/16 职场文书
一句话工作感言
2014/03/01 职场文书
旅行社优秀创业计划书
2014/08/16 职场文书
2015年度团总支工作总结
2015/04/23 职场文书
2015年物业管理员工工作总结
2015/10/15 职场文书
实习报告范文之电话客服岗位
2019/07/26 职场文书
小学秋季运动会加油口号及加油稿
2019/08/19 职场文书
手把手教你制定暑期学习计划,让你度过充实的暑假
2019/08/22 职场文书
用Python爬取某乎手机APP数据
2021/06/15 Python
Python使用海龟绘图实现贪吃蛇游戏
2021/06/18 Python
mysql 联合索引生效的条件及索引失效的条件
2021/11/20 MySQL
Springboot-cli 开发脚手架,权限认证,附demo演示
2022/04/28 Java/Android