Added first version for file comparing (much too slow, try parallelism next)
This commit is contained in:
+66
-5
@@ -1,5 +1,8 @@
|
|||||||
import argparse
|
import argparse
|
||||||
import datetime
|
import datetime
|
||||||
|
import filecmp
|
||||||
|
import os
|
||||||
|
import tempfile
|
||||||
import time
|
import time
|
||||||
import urllib.parse
|
import urllib.parse
|
||||||
import sys
|
import sys
|
||||||
@@ -7,7 +10,6 @@ import xml.etree.ElementTree as ET
|
|||||||
|
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
|
|
||||||
# some constants
|
# some constants
|
||||||
FILES_PATH_PREFIX = "/remote.php/dav/files/"
|
FILES_PATH_PREFIX = "/remote.php/dav/files/"
|
||||||
VERSIONS_PATH_PREFIX = "/remote.php/dav/versions/"
|
VERSIONS_PATH_PREFIX = "/remote.php/dav/versions/"
|
||||||
@@ -17,6 +19,7 @@ DATE_THRESHOLD = datetime.datetime(1990, 1, 1)
|
|||||||
SESSION = requests.Session()
|
SESSION = requests.Session()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def propfind(path, auth):
|
def propfind(path, auth):
|
||||||
"""
|
"""
|
||||||
Get a file's Last Modified timestamp and FileID via a PROPFIND request
|
Get a file's Last Modified timestamp and FileID via a PROPFIND request
|
||||||
@@ -86,6 +89,50 @@ def find_valid_version(versions):
|
|||||||
return most_recent
|
return most_recent
|
||||||
|
|
||||||
|
|
||||||
|
def download_file(path, auth):
|
||||||
|
"""
|
||||||
|
This function downloads one file and saves it on the local device.
|
||||||
|
:param path: The path to the file in question
|
||||||
|
:param auth: Auth data for the HTTP request (e.g. a requests.auth.HTTPBasicAuth object)
|
||||||
|
:return: The path of the created file
|
||||||
|
"""
|
||||||
|
r = requests.request(
|
||||||
|
method='get',
|
||||||
|
url=path,
|
||||||
|
auth=auth
|
||||||
|
)
|
||||||
|
|
||||||
|
_, filename = os.path.split(path)
|
||||||
|
if r.status_code == 200:
|
||||||
|
with open(filename, 'wb') as file:
|
||||||
|
file.write(r.content)
|
||||||
|
return filename
|
||||||
|
return ''
|
||||||
|
|
||||||
|
|
||||||
|
def content_equal(original_entry, fixed_version, auth):
|
||||||
|
"""
|
||||||
|
Compares the two file versions for replacement.
|
||||||
|
:param original_entry: Filename of the entry with wrong timestamp.
|
||||||
|
:param fixed_version: Filename of the version for comparison with the original.
|
||||||
|
:param auth: Auth data for the HTTP request (e.g. a requests.auth.HTTPBasicAuth object)
|
||||||
|
:return: True, if they are equal in Metadata anc content. False otherwise.
|
||||||
|
"""
|
||||||
|
original = download_file(original_entry, auth)
|
||||||
|
fixed = download_file(fixed_version, auth)
|
||||||
|
|
||||||
|
# shallow comparison
|
||||||
|
shallow = filecmp.cmp(original, fixed)
|
||||||
|
# deep comparison
|
||||||
|
deep = filecmp.cmp(original, fixed, shallow=False)
|
||||||
|
if deep != shallow:
|
||||||
|
print(deep)
|
||||||
|
os.remove(original)
|
||||||
|
os.remove(fixed)
|
||||||
|
return deep and shallow
|
||||||
|
|
||||||
|
|
||||||
|
#TODO: parallelisieren
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
# get all necessary data from the command line
|
# get all necessary data from the command line
|
||||||
argparser = argparse.ArgumentParser(description="Fix broken dates in Nextcloud folders.")
|
argparser = argparse.ArgumentParser(description="Fix broken dates in Nextcloud folders.")
|
||||||
@@ -108,6 +155,10 @@ if __name__ == "__main__":
|
|||||||
# List of all entries with wrong time
|
# List of all entries with wrong time
|
||||||
wrongtime = []
|
wrongtime = []
|
||||||
|
|
||||||
|
restore_coumt = 0
|
||||||
|
fixed_count = 0
|
||||||
|
touch_count = 0
|
||||||
|
|
||||||
# Iterate through all folders and check for wrong timestamps
|
# Iterate through all folders and check for wrong timestamps
|
||||||
while folders:
|
while folders:
|
||||||
url = arguments.server + folders.pop(0)
|
url = arguments.server + folders.pop(0)
|
||||||
@@ -123,10 +174,20 @@ if __name__ == "__main__":
|
|||||||
# Iterate through all fileids with wrong timestamps and check for versions with intact timestamp
|
# Iterate through all fileids with wrong timestamps and check for versions with intact timestamp
|
||||||
print()
|
print()
|
||||||
# NOTE: you can indent this into the loop above to fix things on-the-fly instead of all at once
|
# NOTE: you can indent this into the loop above to fix things on-the-fly instead of all at once
|
||||||
|
# TODO: indented for quicker access to examples
|
||||||
for entry in wrongtime:
|
for entry in wrongtime:
|
||||||
print(urllib.parse.unquote(entry["path"][len(FILES_PATH_PREFIX):]))
|
# print(urllib.parse.unquote(entry["path"][len(FILES_PATH_PREFIX):]))
|
||||||
fixed_version = find_valid_version(propfind(arguments.server + VERSIONS_PATH_PREFIX + arguments.username + "/versions/" + str(entry["file_id"]), auth))
|
fixed_version = find_valid_version(propfind(
|
||||||
|
arguments.server + VERSIONS_PATH_PREFIX + arguments.username + "/versions/" + str(entry["file_id"]),
|
||||||
|
auth))
|
||||||
if fixed_version:
|
if fixed_version:
|
||||||
print("Restore from {}".format(fixed_version))
|
fixed_count+=1
|
||||||
|
if fixed_version and content_equal(arguments.server + entry['path'], arguments.server + fixed_version['path'], auth):
|
||||||
|
# print("Restore from {}".format(fixed_version))
|
||||||
|
restore_coumt +=1
|
||||||
else:
|
else:
|
||||||
print("Touch file.")
|
touch_count +=1
|
||||||
|
# print("Touch file.")
|
||||||
|
|
||||||
|
print(restore_coumt)
|
||||||
|
print(touch_count)
|
||||||
Reference in New Issue
Block a user