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中使用xlrd、xlwt操作excel表格详解
Jan 29 Python
深入讲解Python中的迭代器和生成器
Oct 26 Python
Python 处理数据的实例详解
Aug 10 Python
python3.6.3转化为win-exe文件发布的方法
Oct 31 Python
Python实现 PS 图像调整中的亮度调整
Jun 28 Python
解决在pycharm运行代码,调用CMD窗口的命令运行显示乱码问题
Aug 23 Python
PYTHON绘制雷达图代码实例
Oct 15 Python
python实现感知机模型的示例
Sep 30 Python
Python实现手势识别
Oct 21 Python
理解深度学习之深度学习简介
Apr 14 Python
python 网络编程要点总结
Jun 18 Python
Python爬虫框架之Scrapy中Spider的用法
Jun 28 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正则表达式(regar expression)
2011/09/10 PHP
php实现在线生成条形码示例分享(条形码生成器)
2013/12/30 PHP
PHP设计模式之迭代器模式
2016/06/17 PHP
JavaScript使用prototype定义对象类型(转)[
2006/12/22 Javascript
SWFObject Flash js调用类
2008/07/08 Javascript
JavaScript之引用类型介绍
2012/08/10 Javascript
JavaScript中“+”的陷阱深刻理解
2012/12/04 Javascript
JavaScript SHA512&SHA256加密算法详解
2015/08/11 Javascript
基于jQuery通过jQuery.form.js插件实现异步上传
2015/12/13 Javascript
JavaScript正则表达式的分组匹配详解
2016/02/13 Javascript
Javascript中级语法快速入手
2016/07/30 Javascript
浅谈JQ中mouseover和mouseenter的区别
2016/09/13 Javascript
微信小程序 tabs选项卡效果的实现
2017/01/05 Javascript
JS中Safari浏览器中的Date
2017/07/17 Javascript
nodejs调取微信收货地址的方法
2017/12/20 NodeJs
[02:57]2014DOTA2国际邀请赛-观众采访
2014/07/19 DOTA
[00:30]明星选手化身超级英雄!2018DOTA2亚洲邀请赛全明星赛来临!
2018/04/06 DOTA
在Python的Django框架中创建和使用模版
2015/07/15 Python
创建pycharm的自定义python模板方法
2018/05/23 Python
Python实现的朴素贝叶斯算法经典示例【测试可用】
2018/06/13 Python
python3实现猜数字游戏
2020/12/07 Python
pytorch在fintune时将sequential中的层输出方法,以vgg为例
2019/08/20 Python
python实现画出e指数函数的图像
2019/11/21 Python
python getopt模块使用实例解析
2019/12/18 Python
Pytorch 实现计算分类器准确率(总分类及子分类)
2020/01/18 Python
美国高街时尚品牌:OASAP
2016/07/24 全球购物
采购部岗位职责
2013/11/24 职场文书
房地产广告策划方案
2014/05/15 职场文书
党员评议思想汇报
2014/10/08 职场文书
县人大领导班子四风对照检查材料思想汇报
2014/10/09 职场文书
银行客户经理岗位职责
2015/04/09 职场文书
硕士论文致谢范文
2015/05/14 职场文书
演讲比赛主持词
2015/06/29 职场文书
祝福语集锦:给满月宝宝的祝福语
2019/11/20 职场文书
实体类或对象序列化时,忽略为空属性的操作
2021/06/30 Java/Android
基于Pygame实现简单的贪吃蛇游戏
2021/12/06 Python