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对html代码进行escape编码的方法
May 04 Python
Python二分法搜索算法实例分析
May 11 Python
python复制文件的方法实例详解
May 22 Python
如何准确判断请求是搜索引擎爬虫(蜘蛛)发出的请求
Oct 13 Python
浅谈使用Python内置函数getattr实现分发模式
Jan 22 Python
tensorflow实现逻辑回归模型
Sep 08 Python
浅谈python str.format与制表符\t关于中文对齐的细节问题
Jan 14 Python
python中 * 的用法详解
Jul 10 Python
Django  ORM 练习题及答案
Jul 19 Python
python getpass实现密文实例详解
Sep 24 Python
Python创建临时文件和文件夹
Aug 05 Python
Python内置数据类型中的集合详解
Mar 18 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错误提示failed to open stream: HTTP request failed!的完美解决方法
2011/06/06 PHP
百度工程师讲PHP函数的实现原理及性能分析(二)
2015/05/13 PHP
php中文语义分析实现方法示例
2019/09/28 PHP
Alliance vs Liquid BO3 第二场2.13
2021/03/10 DOTA
基于jquery创建的一个图片、视频缓冲的效果样式插件
2012/08/28 Javascript
Extjs4 GridPanel的主要配置参数详细介绍
2013/04/18 Javascript
javascript中call和apply方法浅谈
2013/09/27 Javascript
最精简的JavaScript实现鼠标拖动效果的方法
2015/05/11 Javascript
jQuery+HTML5美女瀑布流布局实现方法
2015/09/21 Javascript
JSON+Jquery省市区三级联动
2016/01/13 Javascript
JavaScript中style.left与offsetLeft的使用及区别详解
2016/06/08 Javascript
原生js仿jquery animate动画效果
2016/07/13 Javascript
判断颜色是否合法的正则表达式(详解)
2017/05/03 Javascript
vue事件修饰符和按键修饰符用法总结
2017/07/25 Javascript
webpack学习笔记之优化缓存、合并、懒加载
2017/08/24 Javascript
基于vue,vue-router, vuex及addRoutes进行权限控制问题
2018/05/02 Javascript
javascript中UMD规范的代码推演
2018/08/29 Javascript
layui 动态设置checbox 选中状态的例子
2019/09/02 Javascript
Vue.js中的高级面试题及答案
2020/01/13 Javascript
JS实现横向轮播图(初级版)
2020/06/24 Javascript
Openlayers实现测量功能
2020/09/25 Javascript
antd form表单数据回显操作
2020/11/02 Javascript
python中sys.argv参数用法实例分析
2015/05/20 Python
Python排序搜索基本算法之冒泡排序实例分析
2017/12/09 Python
python3.x上post发送json数据
2018/03/04 Python
Python爬虫实现抓取京东店铺信息及下载图片功能示例
2018/08/07 Python
Python版名片管理系统
2018/11/30 Python
python装饰器代替set get方法实例
2019/12/19 Python
python调用HEG工具批量处理MODIS数据的方法及注意事项
2020/02/18 Python
斯巴达比赛商店:Spartan Race
2019/01/08 全球购物
美国时尚大码女装购物网站:Avenue
2019/05/24 全球购物
澳洲CFL商城:CHEMIST FOR LESS(中文)
2021/02/28 全球购物
诚信教育主题班会
2015/08/13 职场文书
个人工作总结怎么写?
2019/04/09 职场文书
Python生成九宫格图片的示例代码
2021/04/14 Python
Python实现将多张图片合成MP4视频并加入背景音乐
2022/04/28 Python