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抓取豆瓣图片并自动保存示例学习
Jan 10 Python
Python构造函数及解构函数介绍
Feb 26 Python
Python2.x中文乱码问题解决方法
Jun 02 Python
python中pandas.DataFrame对行与列求和及添加新行与列示例
Mar 12 Python
Python内置模块turtle绘图详解
Dec 09 Python
78行Python代码实现现微信撤回消息功能
Jul 26 Python
对pytorch的函数中的group参数的作用介绍
Feb 18 Python
在PyTorch中使用标签平滑正则化的问题
Apr 03 Python
Django models文件模型变更错误解决
May 11 Python
python中np是做什么的
Jul 21 Python
用python制作个视频下载器
Feb 01 Python
据Python爬虫不靠谱预测可知今年双十一销售额将超过6000亿元
Nov 11 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日历[测试通过]
2008/03/27 PHP
php中数组首字符过滤功能代码
2012/07/31 PHP
浅谈PHP与C#的值类型指向区别的详解
2013/05/21 PHP
深入掌握include_once与require_once的区别
2013/06/17 PHP
PHP处理JSON字符串key缺少双引号的解决方法
2014/09/16 PHP
php使用parse_str实现查询字符串解析到变量中的方法
2017/02/17 PHP
ThinkPHP+EasyUI之ComboTree中的会计科目树形菜单实现方法
2017/06/09 PHP
jquery api参考 visualjquery 中国线路 速度快
2007/11/30 Javascript
jquery ajax 同步异步的执行示例代码
2010/06/23 Javascript
jquery trim() 功能源代码
2011/02/14 Javascript
javascript之典型高阶函数应用介绍
2013/01/10 Javascript
jquery获取一个元素下面相同子元素的个数代码
2014/07/31 Javascript
JavaScript开发人员的10个关键习惯小结
2014/12/05 Javascript
微信小程序 request接口的封装实例代码
2017/04/26 Javascript
vue.js中v-on:textInput无法执行事件问题的解决过程
2017/07/12 Javascript
js+html5实现页面可刷新的倒计时效果
2017/07/15 Javascript
如何利用Node.js与JSON搭建简单的动态服务器
2020/06/16 Javascript
[04:16]完美世界DOTA2联赛PWL S2 集锦第一期
2020/11/23 DOTA
pygame学习笔记(5):游戏精灵
2015/04/15 Python
Python 3.x 新特性及10大变化
2015/06/12 Python
基于matplotlib中ion()和ioff()的使用详解
2020/06/16 Python
Keras在训练期间可视化训练误差和测试误差实例
2020/06/16 Python
Python存储读取HDF5文件代码解析
2020/11/25 Python
css实例教程 一款纯css3实现的超炫动画背画特效
2014/11/05 HTML / CSS
HTML5中新标签和常用标签详解
2014/03/07 HTML / CSS
数学专业推荐信范文
2013/11/21 职场文书
幼儿园新学期寄语
2014/01/18 职场文书
自主招生自荐信指南
2014/02/04 职场文书
给老师的检讨书
2014/02/11 职场文书
教师节活动总结
2014/08/29 职场文书
判缓刑人员个人思想汇报
2014/10/10 职场文书
副总经理岗位职责范本
2015/04/08 职场文书
2015最新婚礼司仪主持词
2015/06/30 职场文书
董事长年会致辞
2015/07/29 职场文书
MySQL创建高性能索引的全步骤
2021/05/02 MySQL
MySQL和Oracle批量插入SQL的通用写法示例
2021/11/17 MySQL