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小程序来统计测试脚本的关键字
Mar 12 Python
python对json的相关操作实例详解
Jan 04 Python
pandas 转换成行列表进行读取与Nan处理的方法
Oct 30 Python
解决Python下json.loads()中文字符出错的问题
Dec 19 Python
PyQt打开保存对话框的方法和使用详解
Feb 27 Python
python 利用pywifi模块实现连接网络破解wifi密码实时监控网络
Sep 16 Python
Python Selenium参数配置方法解析
Jan 19 Python
Python脚本如何在bilibili中查找弹幕发送者
Jun 04 Python
python3.x中安装web.py步骤方法
Jun 23 Python
增大python字体的方法步骤
Jul 05 Python
详解python UDP 编程
Aug 24 Python
Django 用户认证Auth组件的使用
Nov 30 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脚本的10个技巧(1)
2006/10/09 PHP
获得Google PR值的PHP代码
2007/01/28 PHP
使用PHP Socket 编程模拟Http post和get请求
2014/11/25 PHP
ThinkPHP开发框架函数详解:C方法
2015/08/14 PHP
PHP浮点数的一个常见问题
2016/03/10 PHP
PHP抓取及分析网页的方法详解
2016/04/26 PHP
thinkPHP简单实现多个子查询语句的方法
2016/12/05 PHP
老生常谈PHP面向对象之注册表模式
2017/05/26 PHP
Javascript 倒计时源代码.(时.分.秒) 详细注释版
2011/05/09 Javascript
使用jquery获取网页中图片高度的两种方法
2013/09/26 Javascript
模拟用户点击弹出新页面不会被浏览器拦截
2014/04/08 Javascript
jQuery中事件对象e的事件冒泡用法示例介绍
2014/04/25 Javascript
详细分析使用AngularJS编程中提交表单的方式
2015/06/19 Javascript
深入学习Bootstrap表单
2016/12/13 Javascript
AngularJs中Bootstrap3 datetimepicker使用实例
2016/12/13 Javascript
vue.js实现仿原生ios时间选择组件实例代码
2016/12/21 Javascript
Bootstrap jquery.twbsPagination.js动态页码分页实例代码
2017/02/20 Javascript
简单了解JavaScript arguement原理及作用
2020/05/28 Javascript
iview实现图片上传功能
2020/06/29 Javascript
python如何查看系统网络流量的信息
2016/09/12 Python
Jupyter中直接显示Matplotlib的图形方法
2018/05/24 Python
python组合无重复三位数的实例
2018/11/13 Python
python实现知乎高颜值图片爬取
2019/08/12 Python
pytorch 加载(.pth)格式的模型实例
2019/08/20 Python
解决Jupyter NoteBook输出的图表太小看不清问题
2020/04/16 Python
Servlet如何得到服务器的信息
2015/12/22 面试题
中专自我鉴定范文
2013/10/16 职场文书
创业计划书中要认真思考的问题
2013/12/28 职场文书
网上开店必备创业计划书
2014/01/26 职场文书
医药营销个人求职信范文
2014/02/07 职场文书
厂长岗位职责
2014/02/19 职场文书
送温暖献爱心活动总结
2014/07/08 职场文书
2015年销售工作总结范文
2015/03/30 职场文书
傅雷家书读书笔记
2015/06/29 职场文书
教你利用python实现企业微信发送消息
2021/05/23 Python
详解Vue项目的打包方式(生成dist文件)
2022/01/18 Vue.js