Как стать автором
Обновить

Простой самодельный бэкап данных 2 (Python + DropBox)

Время на прочтение5 мин
Количество просмотров1.6K
Новая версия скрипта для бэкапа (оригинал). Или другая версия…

Логика работы с файлами-списками не поменялась. Поменялся только параметр скрипта — теперь это имя архива без расширения, скрипт сам добавит .tar.gz.

Новое:
  • Создание архива переместилось из внешнего архиватора внутрь скрипта. Создаётся tar.gz архив.
  • Все пути теперь системо-зависимы, т.е. скрипт должен работать на линуксах тоже

Кроме приятного нового, повились неприятный минус — скрипт стал жрать кучу памяти.

Сделать сжатый архив с помощью модуля tarfile не вышло. Архив создаётся и сжимается, но внтури архива пути почему-то съезжают.

Т.е. нужно создать архив d:\dropbox\my dropbox\backup\backup.tar.gz, он там появляется. Но если открыть этот gz архив, tar архив будет глубоко внутри по пути dropbox\my dropbox\backup\backup.tar. Т.е. полный путь до данных получается такой: d:\dropbox\my dropbox\backup\backup.tar.gz\dropbox\my dropbox\backup\backup.tar\.... В принципе с этим можно жить, но некрасиво…

Поэтому сделал по-другому — сначала создаётся tar архив без сжатия со всеми файлами, затем он сжимается. Вот в этом месте функции, сжимающей архив, он, архив, передаётся целиком, т.е. весь файл весом несколько сот Мб засасывается в память.

Надо бы ещё покопать в эту сторону и найти лучшее решение…

Copy Source | Copy HTML
  1. import sys
  2. import os
  3. import os.path
  4. import tarfile
  5. import time
  6. import gzip
  7.  
  8. if __name__ == "__main__":
  9.     if (len(sys.argv) < 2):
  10.         print("Usage: backup.py <output archive filename>")
  11.         print("E.g.: \"backup.py d:\\dropbox\\my dropbox\\backup\"")
  12.         exit(1)
  13.  
  14.     RootFoldersFile = "tobackup.lst"
  15.     IgnoreFoldersFile = "ignore.lst"
  16.     ExtraFile = "extra.lst"
  17.     OutputArchive = sys.argv[1]
  18.     OutputArchiveTar = OutputArchive + ".tar"
  19.     OutputArchiveTarGz = OutputArchive + ".tar.gz"
  20.  
  21.     # Only mandatory file is RootFoldersFile, check that it exists
  22.     if (not os.path.isfile(RootFoldersFile)):
  23.         print("%s doesn't exist" % RootFoldersFile)
  24.         exit(1)
  25.  
  26.     # Read root folders from file
  27.     rootFolders = [i.strip() for i in open(RootFoldersFile, "r").readlines()]
  28.  
  29.     # Read list of folders that need to be igonred (if specified)
  30.     ignoreList = []
  31.     if (os.path.isfile(IgnoreFoldersFile)):
  32.         ignoreList = [i.strip().lower() for i in open(IgnoreFoldersFile, "r").readlines()]
  33.  
  34.     # Delete old archive if exists
  35.     if (os.path.isfile(OutputArchiveTar)):
  36.         os.unlink(OutputArchiveTar)
  37.  
  38.     if (os.path.isfile(OutputArchiveTarGz)):
  39.         os.unlink(OutputArchiveTarGz)
  40.  
  41.     filesCount =  0
  42.  
  43.     # Open output archive for writing (we'll gzip it later)
  44.     try:
  45.         tar = tarfile.open(OutputArchiveTar, "w")
  46.     except IOError as err:
  47.         print(err)
  48.         exit(1)
  49.  
  50.     lastTime = time.time()
  51.     for rootFolder in rootFolders:
  52.         for root, dirs, files in os.walk(rootFolder):
  53.             for file in files:
  54.                 tar.add(os.path.join(root, file))
  55.                 filesCount += 1
  56.  
  57.                 # Show number of processed files each second
  58.                 if (time.time() - lastTime >= 1):
  59.                     print("%d files..." % (filesCount))
  60.                     lastTime = time.time()
  61.  
  62.             # Skip ignored folders
  63.             for dir in dirs:
  64.                 if (dir.lower() in ignoreList or (os.path.join(root, dir).lower() in ignoreList)):
  65.                     dirs.remove(dir)
  66.  
  67.     # Add some files from extra files list
  68.     if (os.path.isfile(ExtraFile)):
  69.         for file in [i.strip() for i in open(ExtraFile, "r").readlines()]:
  70.             tar.add(file)
  71.  
  72.     tar.close()
  73.  
  74.     print("Compressing...")
  75.  
  76.     # Gzip output archive
  77.     try:
  78.         gz = gzip.open(OutputArchiveTarGz, "wb")
  79.     except IOError as err:
  80.         print(err)
  81.         exit(1)
  82.  
  83.     gz.write(open(OutputArchiveTar, "rb").read())
  84.     gz.close()
  85.  
  86.     os.unlink(OutputArchiveTar)
  87.  
  88.     print("Output: %s, %d file(s), %d bytes" % (OutputArchiveTarGz, filesCount, os.path.getsize(OutputArchiveTarGz)))
  89.     print("Done")
Теги:
Хабы:
Всего голосов 5: ↑4 и ↓1+3
Комментарии3

Публикации

Истории

Ближайшие события

Антиконференция X5 Future Night
Дата30 мая
Время11:00 – 23:00
Место
Онлайн
OTUS CONF: GameDev
Дата30 мая
Время19:00 – 20:30
Место
Онлайн
Конференция «IT IS CONF 2024»
Дата20 июня
Время09:00 – 19:00
Место
Екатеринбург
Summer Merge
Дата28 – 30 июня
Время11:00
Место
Ульяновская область