Skip to content

Instantly share code, notes, and snippets.

@martinburger
Created September 24, 2013 13:54
Show Gist options
  • Save martinburger/6685108 to your computer and use it in GitHub Desktop.
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"/>'.
#!/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):
print
handleCalendar(conn, user_no, dav_name)
print
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:])
@courou
Copy link

courou commented Jan 7, 2014

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment