-#!/usr/bin/python
+#!/usr/bin/python3
#
#
# THE SOFTWARE.
import sys, os
-import urlparse
+import urllib.parse
import vobject
from cgi import parse_header
# Special case, if this is a HTTP url, return the data from it using
# the HTTP functions which attempt to play a bit nicer.
- parsedURL = urlparse.urlparse(url)
+ parsedURL = urllib.parse.urlparse(url)
if 'http' in parsedURL[0]: return getHTTPContent(url)
if stdin:
if not parsedURL[0]: url = 'file://' + os.path.abspath(url)
# If we've survived, use python's generic URL opening library to handle it
- import urllib2
+ import urllib.request, urllib.error, urllib.parse
try:
- res = urllib2.urlopen(url)
+ res = urllib.request.urlopen(url)
content = res.read()
ct = res.info().getplist()
res.close()
- except (urllib2.URLError, OSError), e:
+ except (urllib.error.URLError, OSError) as e:
sys.stderr.write('%s\n'%e)
sys.exit(1)
try:
import httplib2
except ImportError:
- import urllib2
+ import urllib.request, urllib.error, urllib.parse
if not url: return ('','')
- if not 'http' in urlparse.urlparse(url)[0]: return ('','')
+ if not 'http' in urllib.parse.urlparse(url)[0]: return ('','')
if 'httplib2' in sys.modules:
try: h = httplib2.Http('.httplib2-cache')
if h:
try:
req = h.request(url)
- except ValueError, e:
+ except ValueError as e:
sys.stderr.write('%s\n'%e)
sys.exit(1)
else:
try:
- req = urllib2.urlopen(url)
- except urllib2.URLError, e:
+ req = urllib.request.urlopen(url)
+ except urllib.error.URLError as e:
sys.stderr.write('%s\n'%e)
sys.exit(1)
else:
try:
out = open(outfile, 'w')
- except (IOError, OSError), e:
+ except (IOError, OSError) as e:
sys.stderr.write('%s\n'%e)
sys.exit(1)
(content, encoding) = getContent(url, options.stdin)
encoding = encoding or options.encoding or 'utf-8'
- cal = vobject.readOne(unicode(content, encoding))
+ cal = vobject.readOne(str(content, encoding))
cal = applyRules(cal, generateRules(ruleConfig), options.verbose)
writeOutput(cal, options.outfile)
def exitQuiet(exitstate=0):
'''When called as a CGI script, exit quietly if theres any errors'''
- print('Content-Type: text/calendar\n')
+ print('Content-Type: text/html\n')
sys.exit(exitstate)
to process facebook ical files'''
import cgi
import re
- #import cgitb; cgitb.enable()
+ import cgitb; cgitb.enable()
ruleConfig["facebook"] = True
form = cgi.FieldStorage()
if "uid" not in form or "key" not in form:
- exitQuiet()
+ print('Content-Type: text/calendar\n')
+ sys.exit(0)
try:
# UID should be numeric, if it's not we have someone playing games
uid = int(form['uid'].value)
# The user's key will be a 16 character string
key = form['key'].value
re.search('[&?]+', key) and exitQuiet()
- len(key) == 16 or exitQuiet()
# Historically facebook has been notoriously bad at setting timzeones
# in their stuff so this should be a user setting. If it is set in
url = 'http://www.facebook.com/ical/u.php?uid=%d&key=%s'%(uid,key)
(content, encoding) = getHTTPContent(url)
- cal = vobject.readOne(unicode(content, encoding))
+ cal = vobject.readOne(str(content, encoding))
cal = applyRules(cal, generateRules(ruleConfig), False)
- print('Content-Type: text/calendar; charset=%s\n'%encoding)
+ print(('Content-Type: text/calendar; charset=%s\n'%encoding))
writeOutput(cal)
def facebookOrganiser(cal):
'''Adds organiser details to the body of facebook calendars.'''
- if cal.contents.has_key(u'prodid'):
+ if 'prodid' in cal.contents:
if not "Facebook" in cal.prodid.value: return cal
+ if 'vevent_list' not in dir(cal):
+ return cal
+
for event in cal.vevent_list:
- if not event.contents.has_key(u'organizer'): continue
+ if 'organizer' not in event.contents: continue
try:
a = event.organizer.cn_paramlist
organizer = "Organised by: " + event.organizer.cn_param + " ("
def whatPrivacy(cal):
'''Marks events public so google calendar doesn't have a sad about them.'''
+ if 'vevent_list' not in dir(cal):
+ return cal
+
for event in cal.vevent_list:
- if event.contents.has_key(u'class'):
+ if 'class' in event.contents:
# Bit of a hack as class is a reserved word in python
- del event.contents[u'class']
+ del event.contents['class']
event.add('class').value = "PUBLIC"
return cal
if "facebook" in ruleConfig:
if ruleConfig["facebook"] == True: return cal
+ if 'vevent_list' not in dir(cal):
+ return cal
+
eventBlacklist = [x.lower() for x in [
"X-ALT-DESC",
"X-MICROSOFT-CDO-BUSYSTATUS",
for event in cal.vevent_list:
for blacklist in eventBlacklist:
- if event.contents.has_key(blacklist): del event.contents[blacklist]
+ if blacklist in event.contents: del event.contents[blacklist]
for blkl in mainBlacklist:
while blkl in cal.contents: del cal.contents[blkl]
if "facebook" in ruleConfig:
if ruleConfig["facebook"] == True: return cal
+ if 'vevent_list' not in dir(cal):
+ return cal
+
from datetime import datetime
from pytz import timezone
default = timezone(ruleConfig["defaultTZ"])
for event in cal.vevent_list:
- if not event.contents.has_key(u'exdate'): continue
+ if 'exdate' not in event.contents: continue
dates = event.exdate.value
- del event.contents[u'exdate']
+ del event.contents['exdate']
for date in dates:
if isinstance(date, datetime):
if date.tzinfo is None: date = date.replace(tzinfo = default)
date = date.astimezone(vobject.icalendar.utc)
- entry = event.add(u'exdate')
+ entry = event.add('exdate')
entry.value = [date]
return cal
'''Removing local timezones in favour of UTC. If the remote calendar specifies a timezone
then use it, otherwise assume it's in the user-specified or default values'''
+ if 'vevent_list' not in dir(cal):
+ return cal
+
from datetime import datetime
from pytz import timezone
"TZID"
]
+ if 'vevent_list' not in dir(cal):
+ return cal
+
for event in cal.vevent_list:
for attr in event.contents:
attr = getattr(event, attr)