diff options
author | Randy Ramos <rramos1295@gmail.com> | 2017-09-06 17:46:19 -0400 |
---|---|---|
committer | Lukas Fleischer <lfleischer@calcurse.org> | 2017-09-08 22:35:36 +0200 |
commit | 1e1d61585ded01891de74f01b88fc03c8ab89bb2 (patch) | |
tree | 638551a4818f773fcc16b8df142d9121d7c4b96f /contrib | |
parent | 2d1e6e394d14b21525d981546108bb8f0ba44f98 (diff) | |
download | calcurse-1e1d61585ded01891de74f01b88fc03c8ab89bb2.tar.gz calcurse-1e1d61585ded01891de74f01b88fc03c8ab89bb2.zip |
Refactor calcurse-caldav to use httplib2
This will allow much more flexibility and less code duplication when
adding OAuth2 support. OAuth2 support will require this library as it is
a dependency of oauth2client. The documentation was updated to reflect
the new dependency.
Signed-off-by: Randy Ramos <rramos1295@gmail.com>
Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
Diffstat (limited to 'contrib')
-rw-r--r-- | contrib/caldav/README | 4 | ||||
-rwxr-xr-x | contrib/caldav/calcurse-caldav.py | 42 |
2 files changed, 17 insertions, 29 deletions
diff --git a/contrib/caldav/README b/contrib/caldav/README index 008b3fe..93baf37 100644 --- a/contrib/caldav/README +++ b/contrib/caldav/README @@ -18,7 +18,9 @@ Usage calcurse-caldav requires an up-to-date version of calcurse and a configuration file located at ~/.calcurse/caldav/config. An example configuration file can be -found under contrib/caldav/config.sample in the calcurse source tree. +found under contrib/caldav/config.sample in the calcurse source tree. You will +also need to install *httplib2* for Python 3 using *pip* (e.g. `pip3 install +--user httplib2`) or your distribution's package manager. If you run calcurse-caldav for the first time, you need to provide the --init argument. You can choose between the following initialization modes: diff --git a/contrib/caldav/calcurse-caldav.py b/contrib/caldav/calcurse-caldav.py index f98ee9d..3725068 100755 --- a/contrib/caldav/calcurse-caldav.py +++ b/contrib/caldav/calcurse-caldav.py @@ -3,10 +3,9 @@ import argparse import base64 import configparser -import http.client +import httplib2 import os import re -import ssl import subprocess import sys import textwrap @@ -113,18 +112,14 @@ def remote_query(conn, cmd, path, additional_headers, body): if isinstance(body, str): body = body.encode('utf-8') - conn.request(cmd, path, headers=headers, body=body) - - resp = conn.getresponse() + resp, body = conn.request(path, cmd, body=body, headers=headers) + body = body.decode('utf-8') if not resp: return (None, None) - headers = resp.getheaders() - body = resp.read().decode('utf-8') - if debug: - print("< Headers: " + repr(headers)) + print("< Headers: " + repr(resp)) for line in body.splitlines(): print("< " + line) print() @@ -134,7 +129,7 @@ def remote_query(conn, cmd, path, additional_headers, body): "while trying to access {}.").format(hostname, resp.status, resp.reason, path)) - return (headers, body) + return (resp, body) def get_etags(conn, hrefs=[]): @@ -155,7 +150,7 @@ def get_etags(conn, hrefs=[]): '<D:prop><D:getetag /></D:prop>' '<C:filter><C:comp-filter name="VCALENDAR" /></C:filter>' '</C:calendar-query>') - headers, body = remote_query(conn, "REPORT", path, headers, body) + headers, body = remote_query(conn, "REPORT", absolute_uri, headers, body) if not headers: return {} root = etree.fromstring(body) @@ -230,13 +225,13 @@ def save_syncdb(fn, syncdb): def push_object(conn, objhash): href = path + objhash + ".ics" body = calcurse_export(objhash) - headers, body = remote_query(conn, "PUT", href, {}, body) + headers, body = remote_query(conn, "PUT", hostname_uri + href, {}, body) if not headers: return None etag = None - headerdict = dict((key.lower(), value) for key, value in headers) + headerdict = dict(headers) if 'etag' in headerdict: etag = headerdict['etag'] while not etag: @@ -266,7 +261,7 @@ def push_objects(objhashes, conn, syncdb, etagdict): def remove_remote_object(conn, etag, href): headers = {'If-Match': '"' + etag + '"'} - remote_query(conn, "DELETE", href, headers, None) + remote_query(conn, "DELETE", hostname_uri + href, headers, None) def remove_remote_objects(objhashes, conn, syncdb, etagdict): @@ -313,7 +308,7 @@ def pull_objects(hrefs_missing, hrefs_modified, conn, syncdb, etagdict): for href in (hrefs_missing | hrefs_modified): body += '<D:href>{}</D:href>'.format(href) body += '</C:calendar-multiget>' - headers, body = remote_query(conn, "REPORT", path, {}, body) + headers, body = remote_query(conn, "REPORT", absolute_uri, {}, body) root = etree.fromstring(body) @@ -433,6 +428,8 @@ except FileNotFoundError as e: hostname = config.get('General', 'HostName') path = '/' + config.get('General', 'Path').strip('/') + '/' +hostname_uri = 'https://' + hostname +absolute_uri = hostname_uri + path if config.has_option('General', 'InsecureSSL'): insecure_ssl = config.getboolean('General', 'InsecureSSL') @@ -499,18 +496,9 @@ try: # Connect to the server via HTTPs. if verbose: print('Connecting to ' + hostname + '...') + conn = httplib2.Http() if insecure_ssl: - try: - context = ssl._create_unverified_context() - conn = http.client.HTTPSConnection(hostname, context=context) - except AttributeError: - # Python versions prior to 3.4.3 do not support - # ssl._create_unverified_context(). However, these versions do not - # seem to verify certificates by default so we can simply fall back - # to http.client.HTTPSConnection(). - conn = http.client.HTTPSConnection(hostname) - else: - conn = http.client.HTTPSConnection(hostname) + conn.disable_ssl_certificate_validation = True if init: # In initialization mode, start with an empty synchronization database. @@ -563,8 +551,6 @@ try: # Write the synchronization database. save_syncdb(syncdbfn, syncdb) - # Close the HTTPs connection. - conn.close() finally: # Remove lock file. os.remove(lockfn) |