diff --git a/Backup.py b/Backup.py index ff57850..763d2f8 100644 --- a/Backup.py +++ b/Backup.py @@ -1,5 +1,6 @@ import io import os +from datetime import datetime import re import tempfile import mgzip as gzip @@ -7,7 +8,7 @@ import tarfile import sqlite3 import pathlib -import crypt +from crypt import * class Backup: @@ -27,21 +28,36 @@ class Backup: uri = os.path.join(path, f) if os.path.isfile(uri): size = os.path.getsize(uri) + m_date = datetime.fromtimestamp(os.path.getmtime(uri)) + c_date = datetime.fromtimestamp(os.path.getctime(uri)) print(f + " : ", human_size(size)) if size > tarball_size: - crypt_name = self.bdd.add([{'name': f, 'path': path, 'size': size}], compress_mode="gz") - enc = crypt(compress(uri), self.key) - save(enc, os.path.join(self.save_location, crypt_name)) + crypt_name = self.bdd.add([{'name': f, + 'path': path, + 'size': size, + 'm_date': m_date, + 'c_date': c_date}], + compress_mode="gz") + if crypt_name is not None: + print("proceed") + enc = crypt(compress(uri), self.key) + save(enc, os.path.join(self.save_location, crypt_name)) else: - files.append({'name': f, 'path': path, 'size': size}) + files.append({'name': f, + 'path': path, + 'size': size, + 'm_date': m_date, + 'c_date': c_date}) elif os.path.isdir(uri): self.recurse(uri) if len(files) > 0: - print("End", path, ":", files) + print("End", path, ":", [file['name'] for file in files]) crypt_name = self.bdd.add(files, compress_mode="tar.gz") - tarball = tar(files) - enc = crypt(compress(tarball), self.key) - save(enc, os.path.join(self.save_location, crypt_name)) + if crypt_name is not None: + print("proceed") + tarball = tar(files) + enc = crypt(compress(tarball), self.key) + save(enc, os.path.join(self.save_location, crypt_name)) def tar(files): @@ -90,13 +106,13 @@ def uncompress(file): def crypt(file, key): encrypted_file = tempfile.SpooledTemporaryFile() - crypt.encrypt_file(key, file, encrypted_file) + encrypt_file(key, file, encrypted_file) return encrypted_file def uncrypt(file, key): decrypted_file = tempfile.SpooledTemporaryFile() - crypt.decrypt_file(key, file, decrypted_file) + decrypt_file(key, file, decrypted_file) return decrypted_file @@ -133,6 +149,8 @@ class DataBase: name TEXT, path TEXT, size TEXT, + m_date DATE, + c_date DATE, crypt_id INTEGER, CONSTRAINT files_crypt_FK FOREIGN KEY (crypt_id) REFERENCES crypt(id) ) @@ -145,6 +163,8 @@ class DataBase: ) """) + self.conn.row_factory = dict_factory + self.conn.commit() def get_crypt_id(self, list_file): @@ -154,36 +174,50 @@ class DataBase: cursor.execute("""SELECT crypt_id FROM files WHERE name=? AND path=?""", (file['name'], file['path'])) try: - crypt_id_list.append(cursor.fetchone()[0]) + crypt_id_list.append(cursor.fetchone()['crypt_id']) except TypeError: pass - if len(crypt_id_list) > 0: - return most_frequent(crypt_id_list) - else: - return None + if len(crypt_id_list) > 0: + return most_frequent(crypt_id_list) + else: + return None def exist(self, file): cursor = self.conn.cursor() - cursor.execute("""SELECT EXISTS (SELECT 1 FROM files WHERE name=? AND path=?)""", + cursor.execute("""SELECT EXISTS (SELECT 1 FROM files WHERE name=? AND path=?) as exist""", (file['name'], file['path'])) - return cursor.fetchone()[0] + return cursor.fetchone()['exist'] + + def modified(self, file): + cursor = self.conn.cursor() + cursor.execute("""SELECT name, path, size, m_date, c_date FROM files WHERE name=? AND path=?""", + (file['name'], file['path'])) + bdd_file = cursor.fetchone() + for key in ['m_date', 'c_date']: + bdd_file[key] = datetime.strptime(bdd_file[key], "%Y-%m-%d %H:%M:%S.%f") + bdd_file['size'] = int(bdd_file['size']) + if file != bdd_file: + return True + else: + return False def add(self, list_file, compress_mode=None): cursor = self.conn.cursor() crypt_id = self.get_crypt_id(list_file) if crypt_id is None: - cursor.execute("""SELECT IFNULL(max(id) + 1, 0) FROM crypt""") - crypt_id = cursor.fetchone()[0] - cursor.execute("""SELECT IFNULL(max(id) + 1, 0) FROM files""") - files_id = cursor.fetchone()[0] + cursor.execute("""SELECT IFNULL(max(id) + 1, 0) as crypt_id FROM crypt""") + crypt_id = cursor.fetchone()['crypt_id'] for file in list_file: if self.exist(file): - cursor.execute("""UPDATE files SET size=?, crypt_id=? WHERE name=? AND path=?""", - (file['size'], crypt_id, file['name'], file['path'])) + if self.modified(file): + cursor.execute("""UPDATE files SET size=?, m_date=?, c_date=?, crypt_id=? + WHERE name=? AND path=?""", + (file['size'], file['m_date'], file['c_date'], crypt_id, file['name'], file['path'])) + else: + return None else: - cursor.execute("""INSERT INTO files VALUES(?, ?, ?, ?, ?)""", - (files_id, file['name'], file['path'], file['size'], crypt_id)) - files_id += 1 + cursor.execute("""INSERT INTO files (name, path, size, m_date, c_date, crypt_id) + VALUES(?, ?, ?, ?, ?, ?)""", (file['name'], file['path'], file['size'], file['m_date'], file['c_date'], crypt_id)) cursor.execute("""INSERT OR IGNORE INTO crypt VALUES(?, ?)""", (crypt_id, compress_mode)) self.conn.commit() @@ -207,4 +241,11 @@ def parse_size(size): def most_frequent(list): - return max(set(list), key = list.count) + return max(set(list), key=list.count) + + +def dict_factory(cursor, row): + d = {} + for idx, col in enumerate(cursor.description): + d[col[0]] = row[idx] + return d