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 相关文章推荐
以911新闻为例演示Python实现数据可视化的教程
Apr 23 Python
Python错误提示:[Errno 24] Too many open files的分析与解决
Feb 16 Python
利用pyinstaller打包exe文件的基本教程
May 02 Python
Python利用pandas处理Excel数据的应用详解
Jun 18 Python
pycharm编写spark程序,导入pyspark包的3中实现方法
Aug 02 Python
Python 使用matplotlib模块模拟掷骰子
Aug 08 Python
Python下应用opencv 实现人脸检测功能
Oct 24 Python
Python jieba库用法及实例解析
Nov 04 Python
python plotly画柱状图代码实例
Dec 13 Python
Django之form组件自动校验数据实现
Jan 14 Python
Python爬取某平台短视频的方法
Feb 08 Python
python基础之错误和异常处理
Oct 24 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数组排序函数合集 以及它们之间的联系分析
2013/06/27 PHP
mongo Table类文件 获取MongoCursor(游标)的实现方法分析
2013/07/01 PHP
PHP程序员学习使用Swoole的理由
2018/06/24 PHP
javascript中类的定义及其方式(《javascript高级程序设计》学习笔记)
2011/07/04 Javascript
JS隐藏参数post传值实例
2013/04/18 Javascript
JavaScript的事件绑定(方便不支持js的时候)
2013/10/01 Javascript
jQuery Ajax异步处理Json数据详解
2013/11/05 Javascript
使用JQUERY进行后台页面布局控制DIV实现左右式
2014/01/07 Javascript
jQuery不兼容input的change事件问题解决过程
2014/12/05 Javascript
详解JavaScript对Date对象的操作问题(生成一个倒数7天的数组)
2015/10/01 Javascript
iOS和Android用同一个二维码实现跳转下载链接的方法
2016/09/28 Javascript
Javascript之面向对象--方法
2016/12/02 Javascript
layer实现弹窗提交信息
2016/12/12 Javascript
js a标签点击事件
2017/03/30 Javascript
vue2.0 axios跨域并渲染的问题解决方法
2018/03/08 Javascript
微信小程序前端自定义分享的实现方法
2019/06/13 Javascript
浅谈python中的变量默认是什么类型
2016/09/11 Python
Python与人工神经网络:使用神经网络识别手写图像介绍
2017/12/19 Python
django数据库migrate失败的解决方法解析
2018/02/08 Python
python+opencv 读取文件夹下的所有图像并批量保存ROI的方法
2019/01/10 Python
Django 对象关系映射(ORM)源码详解
2019/08/06 Python
python tornado修改log输出方式
2019/11/18 Python
Python: 传递列表副本方式
2019/12/19 Python
python对指定字符串逆序的6种方法(小结)
2020/04/02 Python
Python实现初始化不同的变量类型为空值
2020/06/02 Python
注塑工厂厂长岗位职责
2013/12/02 职场文书
优秀辅导员事迹材料
2014/02/16 职场文书
班干部演讲稿
2014/04/24 职场文书
2015届大学生就业推荐表自我评价
2014/09/27 职场文书
离婚协议书该怎么写
2014/10/04 职场文书
史上最牛辞职信
2015/05/13 职场文书
红色革命电影观后感
2015/06/18 职场文书
读《工匠精神》有感:热爱工作,精益求精
2019/12/28 职场文书
Jupyter Notebook 如何修改字体和大小以及更改字体样式
2021/06/03 Python
使用Python+OpenCV进行卡类型及16位卡号数字的OCR功能
2021/08/30 Python
spring IOC容器的Bean管理XML自动装配过程
2022/05/30 Java/Android