Created
September 24, 2013 13:54
-
-
Save martinburger/6685108 to your computer and use it in GitHub Desktop.
Fixes DAViCal "event-only" calendars for iOS 7 by inserting now required property 'urn:ietf:params:xml:ns:caldav:supported-calendar-component-set' with value '<comp name="VEVENT" xmlns="urn:ietf:params:xml:ns:caldav"/>'.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
import sys | |
import psycopg2 | |
# http://www.postgresql.org/docs/current/static/libpq-connect.html#LIBPQ-CONNSTRING | |
CONNECTION_STRING = None | |
PROPERTY_NAME = 'urn:ietf:params:xml:ns:caldav:supported-calendar-component-set' | |
PROPERTY_VALUE = '<comp name="VEVENT" xmlns="urn:ietf:params:xml:ns:caldav"/>' | |
# http://stackoverflow.com/a/3041990/66981 | |
def query_yes_no(question, default="yes"): | |
"""Ask a yes/no question via raw_input() and return their answer. | |
"question" is a string that is presented to the user. | |
"default" is the presumed answer if the user just hits <Enter>. | |
It must be "yes" (the default), "no" or None (meaning | |
an answer is required of the user). | |
The "answer" return value is one of "yes" or "no". | |
""" | |
valid = {"yes":True, "y":True, "ye":True, | |
"no":False, "n":False} | |
if default == None: | |
prompt = " [y/n] " | |
elif default == "yes": | |
prompt = " [Y/n] " | |
elif default == "no": | |
prompt = " [y/N] " | |
else: | |
raise ValueError("invalid default answer: '%s'" % default) | |
while True: | |
sys.stdout.write(question + prompt) | |
choice = raw_input().lower() | |
if default is not None and choice == '': | |
return valid[default] | |
elif choice in valid: | |
return valid[choice] | |
else: | |
sys.stdout.write("Please respond with 'yes' or 'no' "\ | |
"(or 'y' or 'n').\n") | |
# [(1001, '/jdoe/home/'), ...] | |
def getCalendars(conn): | |
calendars = [] | |
with conn.cursor() as cur: | |
cur.execute("SELECT user_no, dav_name FROM collection WHERE is_calendar=TRUE ORDER BY user_no") | |
for record in cur: | |
calendars.append(record) | |
return calendars | |
def getCalendarname(conn, dav_name): | |
with conn.cursor() as cur: | |
cur.execute("SELECT dav_displayname FROM collection WHERE dav_name = %s", (dav_name,)) | |
calendar_name = cur.fetchone()[0] | |
return calendar_name | |
def getUsername(conn, user_no): | |
with conn.cursor() as cur: | |
cur.execute("SELECT fullname FROM usr WHERE user_no = %s", (user_no,)) | |
user_name = cur.fetchone()[0] | |
return user_name | |
def getPropValue(conn, dav_name): | |
with conn.cursor() as cur: | |
cur.execute("SELECT property_value FROM property WHERE property_name = %s AND dav_name = %s", (PROPERTY_NAME, dav_name)) | |
property_value = cur.fetchone() | |
if property_value is not None: | |
return property_value[0] | |
return None | |
def setPropValue(conn, dav_name, user_no): | |
with conn.cursor() as cur: | |
cur.execute("INSERT INTO property (dav_name, property_name, property_value, changed_by) VALUES (%s, %s, %s, %s)", (dav_name, PROPERTY_NAME, PROPERTY_VALUE, user_no)) | |
def handleCalendar(conn, user_no, dav_name): | |
user_name = getUsername(conn, user_no) | |
print "Handling calendar '%s' (%s) of user '%s' (%s)." % (getCalendarname(conn, dav_name), dav_name, user_name, user_no) | |
property_value = getPropValue(conn, dav_name) | |
if property_value is None: | |
print "\tProperty '%s' not yet set." % (PROPERTY_NAME) | |
if query_yes_no("\tShould that porperty be set to '%s'?" % (PROPERTY_VALUE), "no"): | |
setPropValue(conn, dav_name, user_no) | |
property_value = getPropValue(conn, dav_name) | |
print "\tProperty '%s' set to (no commit, yet):\n\t\t%s" % (PROPERTY_NAME, property_value.strip()) | |
else: | |
print "\tProperty '%s' already set to:\n\t\t%s" % (PROPERTY_NAME, property_value.strip()) | |
def main(argv): | |
if CONNECTION_STRING is None: | |
raise Exception("Please set constant CONNECTION_STRING in this script!") | |
conn = psycopg2.connect(CONNECTION_STRING) | |
print "Connected to database via connection: %s" % (conn.dsn) | |
try: | |
for user_no, dav_name in getCalendars(conn): | |
handleCalendar(conn, user_no, dav_name) | |
print "Doing commit on connection: %s" % (conn.dsn) | |
conn.commit() | |
except: | |
print "Unexpected error:", sys.exc_info()[0] | |
print "Doing rollback on connection: %s" % (conn.dsn) | |
conn.rollback() | |
raise | |
finally: | |
print "Closing connection: %s" % (conn.dsn) | |
conn.close() | |
if __name__ == "__main__": | |
main(sys.argv[1:]) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Bonjour,
J'ai les erreurs suivantes lorsque je lance le path ?
root# ./patch-davical.py
Connected to database via connection: dbname=davical port=5432 user=davical_dba
Unexpected error: <type 'exceptions.AttributeError'>
Doing rollback on connection: dbname=davical port=5432 user=davical_dba
Closing connection: dbname=davical port=5432 user=davical_dba
Traceback (most recent call last):
File "./patch-davical.py", line 131, in
main(sys.argv[1:])
File "./patch-davical.py", line 112, in main
for user_no, dav_name in getCalendars(conn):
File "./patch-davical.py", line 51, in getCalendars
with conn.cursor() as cur:
AttributeError: exit
Merci pour votre aide,
Courou