calcurse-caldav: Fix issues reported by pylint
Add missing parameter to remote_query() and fix various style issues. Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
This commit is contained in:
parent
19f239e490
commit
cb85175524
@ -13,6 +13,7 @@ import sys
|
|||||||
import textwrap
|
import textwrap
|
||||||
import xml.etree.ElementTree as etree
|
import xml.etree.ElementTree as etree
|
||||||
|
|
||||||
|
|
||||||
def die(msg):
|
def die(msg):
|
||||||
newmsg = ""
|
newmsg = ""
|
||||||
for line in msg.splitlines():
|
for line in msg.splitlines():
|
||||||
@ -22,6 +23,7 @@ def die(msg):
|
|||||||
msg += 'error: ' + line + '\n'
|
msg += 'error: ' + line + '\n'
|
||||||
sys.exit(msg.rstrip('\n'))
|
sys.exit(msg.rstrip('\n'))
|
||||||
|
|
||||||
|
|
||||||
def die_atnode(msg, node):
|
def die_atnode(msg, node):
|
||||||
if debug:
|
if debug:
|
||||||
msg += '\n\n'
|
msg += '\n\n'
|
||||||
@ -29,6 +31,7 @@ def die_atnode(msg, node):
|
|||||||
msg += etree.tostring(node).decode('utf-8')
|
msg += etree.tostring(node).decode('utf-8')
|
||||||
die(msg)
|
die(msg)
|
||||||
|
|
||||||
|
|
||||||
def calcurse_wipe():
|
def calcurse_wipe():
|
||||||
if verbose:
|
if verbose:
|
||||||
print('Removing all local calcurse objects...')
|
print('Removing all local calcurse objects...')
|
||||||
@ -36,16 +39,19 @@ def calcurse_wipe():
|
|||||||
return
|
return
|
||||||
subprocess.call([calcurse, '-F', '--filter-hash=XXX'])
|
subprocess.call([calcurse, '-F', '--filter-hash=XXX'])
|
||||||
|
|
||||||
|
|
||||||
def calcurse_import(icaldata):
|
def calcurse_import(icaldata):
|
||||||
p = subprocess.Popen([calcurse, '-i', '-', '--list-imported', '-q'],
|
p = subprocess.Popen([calcurse, '-i', '-', '--list-imported', '-q'],
|
||||||
stdin=subprocess.PIPE, stdout=subprocess.PIPE)
|
stdin=subprocess.PIPE, stdout=subprocess.PIPE)
|
||||||
return p.communicate(icaldata.encode('utf-8'))[0].decode('utf-8').rstrip()
|
return p.communicate(icaldata.encode('utf-8'))[0].decode('utf-8').rstrip()
|
||||||
|
|
||||||
|
|
||||||
def calcurse_export(objhash):
|
def calcurse_export(objhash):
|
||||||
p = subprocess.Popen([calcurse, '-x', 'ical', '--export-uid',
|
p = subprocess.Popen([calcurse, '-x', 'ical', '--export-uid',
|
||||||
'--filter-hash=' + objhash], stdout=subprocess.PIPE)
|
'--filter-hash=' + objhash], stdout=subprocess.PIPE)
|
||||||
return p.communicate()[0].decode('utf-8').rstrip()
|
return p.communicate()[0].decode('utf-8').rstrip()
|
||||||
|
|
||||||
|
|
||||||
def calcurse_hashset():
|
def calcurse_hashset():
|
||||||
p = subprocess.Popen([calcurse, '-G'], stdout=subprocess.PIPE)
|
p = subprocess.Popen([calcurse, '-G'], stdout=subprocess.PIPE)
|
||||||
out = p.communicate()[0]
|
out = p.communicate()[0]
|
||||||
@ -59,16 +65,19 @@ def calcurse_hashset():
|
|||||||
hashes.add(sha1.hexdigest())
|
hashes.add(sha1.hexdigest())
|
||||||
return hashes
|
return hashes
|
||||||
|
|
||||||
|
|
||||||
def calcurse_remove(objhash):
|
def calcurse_remove(objhash):
|
||||||
subprocess.call([calcurse, '-F', '--filter-hash=!' + objhash])
|
subprocess.call([calcurse, '-F', '--filter-hash=!' + objhash])
|
||||||
|
|
||||||
|
|
||||||
def calcurse_version():
|
def calcurse_version():
|
||||||
p = subprocess.Popen([calcurse, '--version'], stdout=subprocess.PIPE)
|
p = subprocess.Popen([calcurse, '--version'], stdout=subprocess.PIPE)
|
||||||
m = re.match('calcurse ([0-9]+)\.([0-9]+)\.([0-9]+)(?:-([0-9]+)-)?',
|
m = re.match(r'calcurse ([0-9]+)\.([0-9]+)\.([0-9]+)(?:-([0-9]+)-)?',
|
||||||
p.communicate()[0].decode('utf-8'))
|
p.communicate()[0].decode('utf-8'))
|
||||||
if not m:
|
if not m:
|
||||||
return None
|
return None
|
||||||
return tuple(map(int, m.groups(0)))
|
return tuple([int(group) for group in m.groups(0)])
|
||||||
|
|
||||||
|
|
||||||
def get_auth_headers():
|
def get_auth_headers():
|
||||||
if not username or not password:
|
if not username or not password:
|
||||||
@ -78,7 +87,8 @@ def get_auth_headers():
|
|||||||
headers = {'Authorization': 'Basic %s' % user_password}
|
headers = {'Authorization': 'Basic %s' % user_password}
|
||||||
return headers
|
return headers
|
||||||
|
|
||||||
def remote_query(cmd, path, additional_headers, body):
|
|
||||||
|
def remote_query(conn, cmd, path, additional_headers, body):
|
||||||
headers = custom_headers.copy()
|
headers = custom_headers.copy()
|
||||||
headers.update(get_auth_headers())
|
headers.update(get_auth_headers())
|
||||||
if cmd == 'PUT':
|
if cmd == 'PUT':
|
||||||
@ -118,22 +128,24 @@ def remote_query(cmd, path, additional_headers, body):
|
|||||||
|
|
||||||
return (headers, body)
|
return (headers, body)
|
||||||
|
|
||||||
|
|
||||||
def get_hrefmap(conn, hrefs=[]):
|
def get_hrefmap(conn, hrefs=[]):
|
||||||
if len(hrefs) > 0:
|
if len(hrefs) > 0:
|
||||||
body = '<?xml version="1.0" encoding="utf-8" ?>' +\
|
body = ('<?xml version="1.0" encoding="utf-8" ?>'
|
||||||
'<C:calendar-multiget xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">' +\
|
'<C:calendar-multiget xmlns:D="DAV:" '
|
||||||
'<D:prop><D:getetag /></D:prop>'
|
' xmlns:C="urn:ietf:params:xml:ns:caldav">'
|
||||||
|
'<D:prop><D:getetag /></D:prop>')
|
||||||
for href in hrefs:
|
for href in hrefs:
|
||||||
body += '<D:href>{}</D:href>'.format(href)
|
body += '<D:href>{}</D:href>'.format(href)
|
||||||
body += '</C:calendar-multiget>'
|
body += '</C:calendar-multiget>'
|
||||||
else:
|
else:
|
||||||
body = '<?xml version="1.0" encoding="utf-8" ?>' +\
|
body = ('<?xml version="1.0" encoding="utf-8" ?>'
|
||||||
'<C:calendar-query xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">' +\
|
'<C:calendar-query xmlns:D="DAV:" '
|
||||||
'<D:prop><D:getetag /></D:prop><C:filter>' +\
|
' xmlns:C="urn:ietf:params:xml:ns:caldav">'
|
||||||
'<C:comp-filter name="VCALENDAR"></C:comp-filter>' +\
|
'<D:prop><D:getetag /></D:prop>'
|
||||||
'</C:filter></C:calendar-query>'
|
'<C:filter><C:comp-filter name="VCALENDAR" /></C:filter>'
|
||||||
|
'</C:calendar-query>')
|
||||||
headers, body = remote_query("REPORT", path, {}, body)
|
headers, body = remote_query(conn, "REPORT", path, {}, body)
|
||||||
if not headers:
|
if not headers:
|
||||||
return {}
|
return {}
|
||||||
root = etree.fromstring(body)
|
root = etree.fromstring(body)
|
||||||
@ -154,13 +166,15 @@ def get_hrefmap(conn, hrefs=[]):
|
|||||||
|
|
||||||
return hrefmap
|
return hrefmap
|
||||||
|
|
||||||
|
|
||||||
def remote_wipe(conn):
|
def remote_wipe(conn):
|
||||||
if verbose:
|
if verbose:
|
||||||
print('Removing all objects from the CalDAV server...')
|
print('Removing all objects from the CalDAV server...')
|
||||||
if dry_run:
|
if dry_run:
|
||||||
return
|
return
|
||||||
|
|
||||||
remote_query("DELETE", path, {}, None)
|
remote_query(conn, "DELETE", path, {}, None)
|
||||||
|
|
||||||
|
|
||||||
def get_syncdb(fn):
|
def get_syncdb(fn):
|
||||||
if not os.path.exists(fn):
|
if not os.path.exists(fn):
|
||||||
@ -177,6 +191,7 @@ def get_syncdb(fn):
|
|||||||
|
|
||||||
return syncdb
|
return syncdb
|
||||||
|
|
||||||
|
|
||||||
def save_syncdb(fn, syncdb):
|
def save_syncdb(fn, syncdb):
|
||||||
if verbose:
|
if verbose:
|
||||||
print('Saving synchronization database to ' + fn + '...')
|
print('Saving synchronization database to ' + fn + '...')
|
||||||
@ -187,10 +202,11 @@ def save_syncdb(fn, syncdb):
|
|||||||
for etag, objhash in syncdb.items():
|
for etag, objhash in syncdb.items():
|
||||||
print("%s %s" % (etag, objhash), file=f)
|
print("%s %s" % (etag, objhash), file=f)
|
||||||
|
|
||||||
|
|
||||||
def push_object(conn, objhash):
|
def push_object(conn, objhash):
|
||||||
href = path + objhash + ".ics"
|
href = path + objhash + ".ics"
|
||||||
body = calcurse_export(objhash)
|
body = calcurse_export(objhash)
|
||||||
headers, body = remote_query("PUT", href, {}, body)
|
headers, body = remote_query(conn, "PUT", href, {}, body)
|
||||||
|
|
||||||
if not headers:
|
if not headers:
|
||||||
return None
|
return None
|
||||||
@ -207,9 +223,11 @@ def push_object(conn, objhash):
|
|||||||
|
|
||||||
return etag
|
return etag
|
||||||
|
|
||||||
|
|
||||||
def remove_remote_object(conn, etag, href):
|
def remove_remote_object(conn, etag, href):
|
||||||
headers = {'If-Match': '"' + etag + '"'}
|
headers = {'If-Match': '"' + etag + '"'}
|
||||||
remote_query("DELETE", href, headers, None)
|
remote_query(conn, "DELETE", href, headers, None)
|
||||||
|
|
||||||
|
|
||||||
def push_objects(conn, syncdb, hrefmap):
|
def push_objects(conn, syncdb, hrefmap):
|
||||||
objhashes = calcurse_hashset()
|
objhashes = calcurse_hashset()
|
||||||
@ -237,7 +255,7 @@ def push_objects(conn, syncdb, hrefmap):
|
|||||||
deletags.append(key)
|
deletags.append(key)
|
||||||
|
|
||||||
for etag in deletags:
|
for etag in deletags:
|
||||||
if not etag in hrefmap:
|
if etag not in hrefmap:
|
||||||
continue
|
continue
|
||||||
href = hrefmap[etag]
|
href = hrefmap[etag]
|
||||||
|
|
||||||
@ -252,18 +270,20 @@ def push_objects(conn, syncdb, hrefmap):
|
|||||||
|
|
||||||
return (added, deleted)
|
return (added, deleted)
|
||||||
|
|
||||||
|
|
||||||
def pull_objects(conn, syncdb, hrefmap):
|
def pull_objects(conn, syncdb, hrefmap):
|
||||||
missing = set(hrefmap.keys()) - set(syncdb.keys())
|
missing = set(hrefmap.keys()) - set(syncdb.keys())
|
||||||
orphan = set(syncdb.keys()) - set(hrefmap.keys())
|
orphan = set(syncdb.keys()) - set(hrefmap.keys())
|
||||||
|
|
||||||
# Download and import new objects from the server.
|
# Download and import new objects from the server.
|
||||||
body = '<?xml version="1.0" encoding="utf-8" ?>' +\
|
body = ('<?xml version="1.0" encoding="utf-8" ?>'
|
||||||
'<C:calendar-multiget xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">' +\
|
'<C:calendar-multiget xmlns:D="DAV:" '
|
||||||
'<D:prop><D:getetag /><C:calendar-data /></D:prop>'
|
' xmlns:C="urn:ietf:params:xml:ns:caldav">'
|
||||||
|
'<D:prop><D:getetag /><C:calendar-data /></D:prop>')
|
||||||
for etag in missing:
|
for etag in missing:
|
||||||
body += '<D:href>%s</D:href>' % (hrefmap[etag])
|
body += '<D:href>%s</D:href>' % (hrefmap[etag])
|
||||||
body += '</C:calendar-multiget>'
|
body += '</C:calendar-multiget>'
|
||||||
headers, body = remote_query("REPORT", path, {}, body)
|
headers, body = remote_query(conn, "REPORT", path, {}, body)
|
||||||
|
|
||||||
root = etree.fromstring(body)
|
root = etree.fromstring(body)
|
||||||
|
|
||||||
@ -304,6 +324,7 @@ def pull_objects(conn, syncdb, hrefmap):
|
|||||||
|
|
||||||
return (added, deleted)
|
return (added, deleted)
|
||||||
|
|
||||||
|
|
||||||
# Initialize the XML namespace map.
|
# Initialize the XML namespace map.
|
||||||
nsmap = {"D": "DAV:", "C": "urn:ietf:params:xml:ns:caldav"}
|
nsmap = {"D": "DAV:", "C": "urn:ietf:params:xml:ns:caldav"}
|
||||||
|
|
||||||
@ -429,9 +450,9 @@ try:
|
|||||||
|
|
||||||
if init:
|
if init:
|
||||||
# In initialization mode, start with an empty synchronization database.
|
# In initialization mode, start with an empty synchronization database.
|
||||||
if (args.init == 'keep-remote'):
|
if args.init == 'keep-remote':
|
||||||
calcurse_wipe()
|
calcurse_wipe()
|
||||||
elif (args.init == 'keep-local'):
|
elif args.init == 'keep-local':
|
||||||
remote_wipe(conn)
|
remote_wipe(conn)
|
||||||
syncdb = {}
|
syncdb = {}
|
||||||
else:
|
else:
|
||||||
@ -441,9 +462,9 @@ try:
|
|||||||
if not syncdb:
|
if not syncdb:
|
||||||
die('Sync database not found or empty. Please initialize the ' +
|
die('Sync database not found or empty. Please initialize the ' +
|
||||||
'database first.\n\nSupported initialization modes are:\n' +
|
'database first.\n\nSupported initialization modes are:\n' +
|
||||||
' --init=keep-remote Remove all local calcurse items and import remote objects\n' +
|
' --init=keep-remote Remove all local calcurse items\n' +
|
||||||
' --init=keep-local Remove all remote objects and push local calcurse items\n' +
|
' --init=keep-local Remove all remote objects\n' +
|
||||||
' --init=two-way Copy local objects to the CalDAV server and vice versa')
|
' --init=two-way Copy local items to the server and vice versa')
|
||||||
|
|
||||||
# Query the server and build a dictionary that maps ETags to paths on the
|
# Query the server and build a dictionary that maps ETags to paths on the
|
||||||
# server.
|
# server.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user