Style changes, argument parser
This commit is contained in:
+59
-24
@@ -1,26 +1,45 @@
|
|||||||
|
import argparse
|
||||||
import datetime
|
import datetime
|
||||||
import sys
|
|
||||||
import time
|
import time
|
||||||
import xml.etree.ElementTree as ET
|
import xml.etree.ElementTree as ET
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
|
|
||||||
# Prepare and send the propfind request return xml string
|
# we only need one session for the whole script
|
||||||
|
session = requests.Session()
|
||||||
|
|
||||||
|
|
||||||
def propfind(path, auth):
|
def propfind(path, auth):
|
||||||
|
"""
|
||||||
|
Get a file's Last Modified timestamp and FileID via a PROPFIND request
|
||||||
|
:param path: The path of the file in question
|
||||||
|
:param auth: Auth data for the HTTP request (e.g. a requests.auth.HTTPBasicAuth object)
|
||||||
|
:return: The properties in XML format
|
||||||
|
"""
|
||||||
headers = {"Depth": "1"}
|
headers = {"Depth": "1"}
|
||||||
# This body returns only the timelastmodified and the fileid variable
|
# This body returns only the timelastmodified and the fileid variable
|
||||||
data = "<d:propfind xmlns:d=\"DAV:\" xmlns:oc=\"http://owncloud.org/ns\" xmlns:nc=\"http://nextcloud.org/ns\">" + "<d:prop>" + "<d:getlastmodified />" + "<oc:fileid />" + "</d:prop>" + "</d:propfind>"
|
requested_data = \
|
||||||
req = r = requests.Request("PROPFIND", path, headers=headers, auth=auth, data=data)
|
"""
|
||||||
|
<d:propfind xmlns:d=\"DAV:\" xmlns:oc=\"http://owncloud.org/ns\" xmlns:nc=\"http://nextcloud.org/ns\">
|
||||||
|
<d:prop>
|
||||||
|
<d:getlastmodified />
|
||||||
|
<oc:fileid />
|
||||||
|
</d:prop>
|
||||||
|
</d:propfind>
|
||||||
|
"""
|
||||||
|
req = requests.Request("PROPFIND", path, headers=headers, auth=auth, data=requested_data)
|
||||||
prepped = req.prepare()
|
prepped = req.prepare()
|
||||||
|
resp = session.send(prepped)
|
||||||
s = requests.Session()
|
|
||||||
resp = s.send(prepped)
|
|
||||||
return resp.text
|
return resp.text
|
||||||
|
|
||||||
|
|
||||||
# Function iterates through the given xml which contains all files and folders in the provided path
|
|
||||||
def search_folder(requestreturn):
|
def search_folder(requestreturn):
|
||||||
|
"""
|
||||||
|
Iterates through a folder's properties XML and returns
|
||||||
|
:param requestreturn:
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
# List to collect path of folders stored in path
|
# List to collect path of folders stored in path
|
||||||
innerfolders = []
|
innerfolders = []
|
||||||
# List to collect path of files with wrong timestamp
|
# List to collect path of files with wrong timestamp
|
||||||
@@ -53,11 +72,16 @@ def search_folder(requestreturn):
|
|||||||
if lastmodified < 631148400:
|
if lastmodified < 631148400:
|
||||||
for fileid in p.findall('.//{http://owncloud.org/ns}fileid'):
|
for fileid in p.findall('.//{http://owncloud.org/ns}fileid'):
|
||||||
linkswrongtime.append(fileid.text)
|
linkswrongtime.append(fileid.text)
|
||||||
return [innerfolders, linkswrongtime]
|
return (innerfolders, linkswrongtime)
|
||||||
|
|
||||||
|
|
||||||
# This function returns the fileid of the version of a given fileid with the most current timestamp or None if there are no versions with a timestamp younger than 01.01.1990
|
|
||||||
def version_check(xmlfile):
|
def version_check(xmlfile):
|
||||||
|
"""
|
||||||
|
This function returns the fileid of the version of a given fileid with the most current timestamp or None if
|
||||||
|
there are no versions with a timestamp younger than 01.01.1990
|
||||||
|
:param xmlfile: An XML file with Last Modified timestamps and FileIDs as returned by propfind()
|
||||||
|
:return: The FileID of the most recent version or None if no valid version exists
|
||||||
|
"""
|
||||||
tree = ET.ElementTree(ET.fromstring(xmlfile))
|
tree = ET.ElementTree(ET.fromstring(xmlfile))
|
||||||
# Name of files are stored as a string. But we can check the timestamp of the file only after we can check the name,
|
# Name of files are stored as a string. But we can check the timestamp of the file only after we can check the name,
|
||||||
# so it needs to be stored temporary in case the timestamp is the most current
|
# so it needs to be stored temporary in case the timestamp is the most current
|
||||||
@@ -91,14 +115,23 @@ def version_check(xmlfile):
|
|||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
# Enter username and password to enter nextcloud via webdav
|
# get all necessary data from the command line
|
||||||
user = sys.argv[1]
|
argparser = argparse.ArgumentParser(description="Fix broken dates in Nextcloud folders.")
|
||||||
passw = sys.argv[2]
|
argparser.add_argument("server", help="The base URL of the Nextcloud server.")
|
||||||
auth = requests.auth.HTTPBasicAuth(user, passw)
|
argparser.add_argument("username", help="The user to log in as.")
|
||||||
|
argparser.add_argument("password", help="The password for accessing Nextcloud. Hint: Use an App Token!")
|
||||||
|
argparser.add_argument(
|
||||||
|
"-p", "--path",
|
||||||
|
default="/",
|
||||||
|
help="The path to search, relative to the user's root. Default: /",
|
||||||
|
dest="search_path"
|
||||||
|
)
|
||||||
|
arguments = argparser.parse_args()
|
||||||
|
# Prepare HTTP Basic Authentication
|
||||||
|
auth = requests.auth.HTTPBasicAuth(arguments.username, arguments.password)
|
||||||
# Prepare the path we want to use
|
# Prepare the path we want to use
|
||||||
prefix_path = "https://kingsx.cs.uni-saarland.de"
|
mainpath = "/remote.php/dav/files/" + arguments.username + arguments.search_path
|
||||||
mainpath = "/remote.php/dav/files/" + user + "/Testrequests/"
|
# List of all folders we need to enter
|
||||||
# List of all folderpaths we need to enter
|
|
||||||
folders = [mainpath]
|
folders = [mainpath]
|
||||||
# List of all fileids with wrong time
|
# List of all fileids with wrong time
|
||||||
wrongtime = []
|
wrongtime = []
|
||||||
@@ -106,16 +139,18 @@ if __name__ == "__main__":
|
|||||||
# Iterate through all folders and check for wrong timestamps
|
# Iterate through all folders and check for wrong timestamps
|
||||||
while folders:
|
while folders:
|
||||||
path_suffix = folders.pop(0)
|
path_suffix = folders.pop(0)
|
||||||
path = prefix_path + str(path_suffix)
|
path = arguments.server + str(path_suffix)
|
||||||
r = propfind(path, auth)
|
r = propfind(path, auth)
|
||||||
res = search_folder(r)
|
new_folders, new_wrongtime = search_folder(r)
|
||||||
# Append all found folders and files with wrong timestamps to global list
|
# Append all found folders and files with wrong timestamps to global list
|
||||||
folders = folders + res[0]
|
folders += new_folders
|
||||||
wrongtime = wrongtime + res[1]
|
wrongtime += new_wrongtime
|
||||||
# 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
|
||||||
while wrongtime:
|
while wrongtime:
|
||||||
fileid = wrongtime.pop(0)
|
fileid = wrongtime.pop(0)
|
||||||
version_suffix = "/remote.php/dav/versions/" + user + "/versions/" + fileid
|
version_suffix = "/remote.php/dav/versions/" + arguments.username + "/versions/" + fileid
|
||||||
version_path = prefix_path + version_suffix
|
version_path = arguments.server + version_suffix
|
||||||
versions = propfind(version_path, auth)
|
versions = propfind(version_path, auth)
|
||||||
print(version_check(versions))
|
mrv = version_check(versions)
|
||||||
|
print(fileid, end=": ")
|
||||||
|
print(mrv)
|
||||||
|
|||||||
Reference in New Issue
Block a user