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实现图书超期提醒
Aug 02 Python
Python实现去除列表中重复元素的方法小结【4种方法】
Apr 27 Python
Python采集代理ip并判断是否可用和定时更新的方法
May 07 Python
快速解决pandas.read_csv()乱码的问题
Jun 15 Python
用Python将一个列表分割成小列表的实例讲解
Jul 02 Python
Python3实现从排序数组中删除重复项算法分析
Apr 03 Python
Python Flask框架扩展操作示例
May 03 Python
使用Python实现跳帧截取视频帧
May 31 Python
ubuntu上安装python的实例方法
Sep 30 Python
python 初始化一个定长的数组实例
Dec 02 Python
OpenCV4.1.0+VS2017环境配置的方法步骤
Jul 09 Python
Python2与Python3关于字符串编码处理的差别总结
Sep 07 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目录操作实例代码
2014/02/21 PHP
Smarty中的注释和截断功能介绍
2015/04/09 PHP
PHP快速排序quicksort实例详解
2016/09/28 PHP
Laravel给生产环境添加监听事件(SQL日志监听)
2017/06/19 PHP
javascript 获取所有id中包含某关键字的控件的实现代码
2010/11/25 Javascript
用js读、写、删除Cookie代码分享及详细注释说明
2014/06/05 Javascript
IE8中动态创建script标签onload无效的解决方法
2014/12/22 Javascript
JS实现同时搜索百度和必应的方法
2015/01/27 Javascript
用js编写的简单的计算器代码程序
2015/08/04 Javascript
jQuery Validate初步体验(二)
2015/12/12 Javascript
jQuery模拟窗口抖动效果
2017/03/15 Javascript
ExtJs的Ext.Ajax.request实现waitMsg等待提示效果
2017/06/14 Javascript
微信小程序组件之srcoll-view的详解
2017/10/19 Javascript
JavaScript内置对象math,global功能与用法实例分析
2019/06/10 Javascript
Vue ​v-model相关知识总结
2021/01/28 Vue.js
[53:36]Liquid vs VP Supermajor决赛 BO 第三场 6.10
2018/07/05 DOTA
举例讲解Django中数据模型访问外键值的方法
2015/07/21 Python
Python实现的Excel文件读写类
2015/07/30 Python
Python rstrip()方法实例详解
2018/11/11 Python
python实现画五角星和螺旋线的示例
2019/01/20 Python
python实现浪漫的烟花秀
2019/01/30 Python
Django REST framework 如何实现内置访问频率控制
2019/07/23 Python
python2使用bs4爬取腾讯社招过程解析
2019/08/14 Python
pymysql模块的操作实例
2019/12/17 Python
python开发实例之Python的Twisted框架中Deferred对象的详细用法与实例
2020/03/19 Python
Pandas对每个分组应用apply函数的实现
2020/12/13 Python
html5+svg学习指南之SVG基础知识
2014/12/17 HTML / CSS
药物学专业学生的自我评价
2013/10/27 职场文书
高中军训第一天感言
2014/03/06 职场文书
护士工作失误检讨书
2014/09/14 职场文书
2015年全国助残日活动方案
2015/05/04 职场文书
2016高考冲刺决心书
2015/09/23 职场文书
公证书
2019/04/17 职场文书
导游词之宁夏贺兰山岩画
2019/11/08 职场文书
Golang之sync.Pool使用详解
2021/05/06 Golang
MongoDB日志切割的三种方式总结
2021/09/15 MongoDB