def upload(): opts, args = getoptions( description = 'Upload iCal .ics files to Google Calendar', config_file = 'gcaluploader.cnf', config_vars = [ 'config_file', 'username', 'password', 'calendar_id', 'quiet', 'dry_run', 'fail_dir', 'reminder_minutes', 'force_reminder', 'enable_vcal_import_workaround_hack', 'start_uid', 'select_uids', 'preserve_uids', 'coalesce_events', 'truncate_exdates', 'max_exdates', 'accept_neverending_recurrences', 'accept_empty_summary', ], ) if not args: print 'No files!' return 1 if opts['quiet']: global log log = noop uploader = icalutil.google.uploader( username = opts['username'], password = opts['password'], calendar_id = opts['calendar_id'], dry_run = opts['dry_run'], fail_dir = opts['fail_dir'], ) eventcallbacks = {} eventcallbacks['beforelogin'] = beforelogin eventcallbacks['beforeinsert'] = beforeinsert eventcallbacks['afterinsert'] = afterinsert eventcallbacks['eventexception'] = eventexception eventcallbacks['eventfailed'] = eventfailed for filename in args: f = open(filename) try: log('Reading %s ...' % filename) ical = vobject.readComponents(f).next() components = [c for c in ical.components()] nevents = len([c for c in components if c.name == vobject.icalendar.VEvent.name]) log('Sorting %d events by descending date ...' % nevents) tz = gettz(components) deco = [(componentdt(c, tz), c) for c in components] deco.sort() components = [pair[1] for pair in deco] components.reverse() # Descending dtstart ical = icalutil.createcalendar(components) components = None deco = None finally: f.close() uploadmemo = { 'inserts': 0, 'end': nevents, 'fails': {}, 'filters': {}, 'transforms': {}, } eventcallbacks['beforeinsertarg'] = uploadmemo eventcallbacks['afterinsertarg'] = uploadmemo eventcallbacks['eventfailedarg'] = uploadmemo filteropts = copy.copy(opts) filteropts['memo'] = uploadmemo filtered = icalutil.filtercomponents(ical, filterevent, filteropts) reportuids(filtered, opts['select_uids'], uploadmemo['filters'], 'Filtered') nevents = len([c for c in ical.components() if c.name == vobject.icalendar.VEvent.name]) uploadmemo['end'] = nevents failed = [] start = int(time.time()) try: failed = uploader.uploadcalendar( ical = ical, filteropts = { 'filter': filterentry, 'opts': { 'reminder_minutes': opts['reminder_minutes'], 'force_reminder': opts['force_reminder'], }, }, eventcallbacks = eventcallbacks, ) except gdata.service.CaptchaRequired: domain = opts['username'].split('@', 1)[1] if domain == 'gmail.com': path = 'accounts' else: path = 'a/%s' % domain # Google Apps log('https://www.google.com/%s/UnlockCaptcha' % path) raise finally: reportuids(filtered, opts['select_uids'], uploadmemo['filters'], 'Filtered') reportuids(filtered, None, uploadmemo['transforms'], 'Transformed') for uid in [vevent.getChildValue('uid') for vevent in failed]: log('Failed UID: %s (%s)' % (uid, uploadmemo['fails'][uid])) log('Inserted %d event(s)' % uploadmemo['inserts']) log('Elapsed time: %d second(s)' % (int(time.time()) - start)) return 0
def filtersplit(): opts, args = getoptions( description = 'Split a single iCal file into multiple smaller files', config_file = 'gcalfiltersplit.cnf', config_vars = [ 'config_file', 'quiet', 'dry_run', 'max_filesize', 'enable_vcal_import_workaround_hack', 'start_uid', 'select_uids', 'preserve_uids', 'coalesce_events', 'truncate_exdates', 'max_exdates', 'accept_neverending_recurrences', 'accept_empty_summary', ], ) if not args: print 'No files!' return 1 if opts['quiet']: global log log = noop for filename in args: f = open(filename) try: log('Reading %s ...' % filename) ical = vobject.readComponents(f).next() components = [c for c in ical.components()] nevents = len([c for c in components if c.name == vobject.icalendar.VEvent.name]) log('Sorting %d events by descending date ...' % nevents) tz = gettz(components) deco = [(componentdt(c, tz), c) for c in components] deco.sort() components = [pair[1] for pair in deco] components.reverse() # Descending dtstart ical = icalutil.createcalendar(components) components = None deco = None finally: f.close() splitmemo = { 'filters': {}, 'transforms': {}, } filteropts = copy.copy(opts) filteropts['memo'] = splitmemo filtered = icalutil.filtercomponents(ical, filterevent, filteropts) reportuids(filtered, opts['select_uids'], splitmemo['filters'], 'Filtered') newnevents = len([c for c in ical.components() if c.name == vobject.icalendar.VEvent.name]) if not newnevents: log('No events!') return 0 # Reduce filesize by filtered events oldfilesize = os.path.getsize(filename) * newnevents / nevents # Guess number of events in each sub-calendarfile splitevents = nevents * opts['max_filesize'] / oldfilesize start = int(time.time()) arg = { 'filename': filename, 'splits': 0, 'dry_run': opts['dry_run'], 'splitmemo': splitmemo, } try: icalutil.splitcal(ical, events_per_calendar = splitevents, splitcallback = splitcb, splitcallbackarg = arg, ) finally: log('Elapsed time: %d second(s)' % (int(time.time()) - start)) return 0