def get_icalendar_event(self): domain = Site.objects.get_current().domain rv = icalEvent() rv.add('uid', u'%d@%s' % (self.id, domain)) rv.add('summary', unicode(self.name)) rv.add('dtstart', vDatetime(self.startDate).to_ical(), encode=0) rv.add('dtstamp', vDatetime(self.created_at).to_ical(), encode=0) rv.add('url', urllib.quote((u'http://%s/wiki/%s' % (domain, unicode(self.wikiPage))).encode('utf-8')) ) if self.teaser: rv.add('description', unicode(self.teaser)) if self.endDate: rv.add('dtend', vDatetime(self.endDate).to_ical(), encode=0) if self.who: rv.add('organizer', unicode(self.who)) elif self.created_by_id and User.objects.filter(id=self.created_by_id): rv.add('organizer', unicode(self.created_by)) if self.location: rv.add('location', u'Metalab ' + unicode(self.location)) elif self.where: rv.add('location', u'Metalab ' + unicode(self.where)) if self.category: rv.add('categories', unicode(self.category)) return rv
def format_as_ical(events: List[dict]) -> bytes: """ Format existing schedule to iCalendar :returns: ics file """ # inictialize calendar cal = Calendar() cal.add("prodid", "-//ue-schedule/UE Schedule//PL") cal.add("version", "2.0") # add event components for day in events: for event in day["events"]: ev = CalEvent() ev.add("summary", f"{event.name} - {event.type}") if event.location: ev.add("location", event.location) if event.teacher: ev.add("description", event.teacher) ev.add("dtstart", vDatetime(event.start)) ev.add("dtend", vDatetime(event.end)) cal.add_component(ev) return cal.to_ical()
def test_prop_vDatetime(self): from ..prop import vDatetime dt = datetime(2001, 1, 1, 12, 30, 0) self.assertEqual(vDatetime(dt).to_ical(), b'20010101T123000') self.assertEqual(vDatetime.from_ical('20000101T120000'), datetime(2000, 1, 1, 12, 0)) dutc = pytz.utc.localize(datetime(2001, 1, 1, 12, 30, 0)) self.assertEqual(vDatetime(dutc).to_ical(), b'20010101T123000Z') dutc = pytz.utc.localize(datetime(1899, 1, 1, 12, 30, 0)) self.assertEqual(vDatetime(dutc).to_ical(), b'18990101T123000Z') self.assertEqual(vDatetime.from_ical('20010101T000000'), datetime(2001, 1, 1, 0, 0)) self.assertRaises(ValueError, vDatetime.from_ical, '20010101T000000A') utc = vDatetime.from_ical('20010101T000000Z') self.assertEqual(vDatetime(utc).to_ical(), b'20010101T000000Z') # 1 minute before transition to DST dat = vDatetime.from_ical('20120311T015959', 'America/Denver') self.assertEqual(dat.strftime('%Y%m%d%H%M%S %z'), '20120311015959 -0700') # After transition to DST dat = vDatetime.from_ical('20120311T030000', 'America/Denver') self.assertEqual(dat.strftime('%Y%m%d%H%M%S %z'), '20120311030000 -0600') dat = vDatetime.from_ical('20101010T000000', 'Europe/Vienna') self.assertEqual(vDatetime(dat).to_ical(), b'20101010T000000')
def _expand_rrule_component(incomp, start, end, existing): rs = rruleset_from_comp(incomp) for field in ['RRULE', 'EXRULE', 'UNTIL', 'RDATE', 'EXDATE']: if field in incomp: del incomp[field] # Work our magic for ts in rs.between(start, end): utcts = asutc(ts) try: outcomp = existing.pop(utcts) outcomp['DTSTART'] = vDatetime(asutc(outcomp['DTSTART'].dt)) except KeyError: outcomp = incomp.copy() outcomp['DTSTART'] = vDatetime(utcts) outcomp['RECURRENCE-ID'] = vDatetime(utcts) yield outcomp
def uid(self, host_name='example.com', unique=''): """ Generates a unique id consisting of: datetime-uniquevalue@host. Like: [email protected] """ from icalendar.prop import vText, vDatetime unique = unique or self.rnd_string() return vText('%s-%s@%s' % (vDatetime(datetime.today()).to_ical(), unique, host_name))
def uid(self, host_name='example.com', unique=''): """Generates a unique id consisting of: datetime-uniquevalue@host. Like: [email protected] """ host_name = to_unicode(host_name) unique = unique or self.rnd_string() today = to_unicode(vDatetime(datetime.today()).to_ical()) return vText('%s-%s@%s' % (today, unique, host_name))
def uid(self, host_name='example.com', unique=''): """ Generates a unique id consisting of: datetime-uniquevalue@host. Like: [email protected] """ from icalendar.prop import vText, vDatetime unique = unique or self.rnd_string() return vText( '%s-%s@%s' % (vDatetime(datetime.today()).to_ical(), unique, host_name))
def add(request): def submit_form(form): return render_to_response("add.html", {"form": form}, context_instance=RequestContext(request)) if request.method == "GET": if not request.user.is_authenticated(): pass # Ask the user if the want to sign on data = {} if "url" in request.GET: data.update({"url": request.GET["url"]}) day = datetime.today() if "day" in request.GET: if request.GET["day"] != "": day = request.GET["day"] # Javascript hands you Tue May 20 1990 data.update({"date": day}) else: data.update({"date": day.strftime("%a %b %d %Y")}) else: data.update({"date": day.strftime("%a %b %d %Y")}) start_time = datetime.today() start_time = start_time.strftime("%H:%M") if "start_time" in request.GET: if request.GET["start_time"] != "": start_time = request.GET["start_time"] data.update({"start_time": start_time}) if "end_time" in request.GET: end_time = request.GET["end_time"] if end_time != "null": data.update({"end_time": end_time}) data.update({"mail": "outlook"}) form = EventForm(data) return submit_form(form) # Form was returned with data if request.method == "POST": form = EventForm(request.POST) if not form.is_valid(): return submit_form(form) title = form.cleaned_data["title"] date = form.cleaned_data["date"] start_time = form.cleaned_data["start_time"] end_time = form.cleaned_data["end_time"] url = form.cleaned_data["url"] describe = form.cleaned_data["describe"] address = form.cleaned_data["address"] mail = form.cleaned_data["mail"] latitude = None longitude = None if address != u"": local = geocode(address) if local != None: if "address" in local: address = local["address"] if "latitude" in local and "longitude" in local: latitude = local["latitude"] longitude = local["longitude"] # If they move the pointer to be more specific override address """ if form.data['lati'] and form.data['lngi']: latitude = form.data['lati'] longitude = form.data['lngi'] """ event = EventModel( title=title, date=date, start_time=start_time, end_time=end_time, address=address, longitude=longitude, latitude=latitude, description=describe, url=url, ) # Save this event event.save() # Make sure you save the event before connecting it to a user if request.user.is_authenticated(): event.connect(request.user) # Ical or Outlook iCal file if mail == "outlook" or mail == "ical": # Create the iCal file cal = Calendar() cal.add("version", "2.0") cal.add("prodid", "-//Microsoft Corporation//Windows Calendar 1.0//EN") cal.add("method", "PUBLISH") event = Event() event.add("summary", describe) if start_time != None: dt = datetime.combine(date, start_time) else: dt = date event.add("dtstart", dt) event.add("dtstamp", dt) if end_time != None: de = datetime.combine(date, end_time) event.add("dtend", de) g = (latitude, latitude) event.add("geo", g) event.add("location", address) uid = date.isoformat() + "@wenzit.net" event.add("UID", uid) event.add("url", url) cal.add_component(event) f = open("schedule.ics", "wb") f.write(cal.as_string()) f.close() response = HttpResponse(cal.as_string(), mimetype="text/calendar") response["Content-Disposition"] = "attachment; filename=schedule.ics" return response # Send the event to google elif mail == "google": response = "http://www.google.com/calendar/event?action=TEMPLATE" response += "&text=" + urllib.quote_plus(title) if start_time != None: ds = datetime.combine(date, start_time) else: ds = date if end_time != None: de = datetime.combine(date, end_time) response += "&dates=" + vDatetime(ds).ical() + "/" + vDatetime(de).ical() else: response += "&dates=" + vDatetime(ds).ical() response += "&details=" + urllib.quote_plus(title) response += "&location=" + urllib.quote_plus(address) response += "&sprop=" + urllib.quote_plus(url) return HttpResponseRedirect(response) # Send the event to Yahoo if mail == "yahoo": response = "http://calendar.yahoo.com/?v=60" response += "&TITLE=" + urllib.quote_plus(title) ds = datetime.combine(date, start_time) if end_time: de = datetime.combine(date, end_time) dur = de - ds hrs, left = divmod(dur.seconds, 3600) mins, secs = divmod(left, 60) dur = "%02d%02d" % (hrs, mins) else: dur = "" response += "&ST=" + vDatetime(ds).ical() response += "&DUR=" + dur response += "&in_loc=" + urllib.quote_plus(address) response += "&DESC=" + urllib.quote_plus(title) response += "&URL=" + urllib.quote_plus(url) return HttpResponseRedirect(response)
def test_date_vcal2google(self): self.assertEqual( date_vcal2google( vDatetime(vDatetime.from_ical('20140828T120150')), 120), '2014-08-28T12:01:50+02:00')
] for task in launchpad.bugs.searchTasks(assignee=launchpad.me, status=STATUSES): print("Processing %s" % task.bug.id) (old, new, href, etag, todo) = utils.create_or_update_calendar_item(flags.url, "VTODO", task.self_link) todo["CLASS"] = "PUBLIC" todo["URL"] = task.web_link todo["SUMMARY"] = "%s: %s" % (task.target.name, task.bug.title) if task.is_complete: todo["STATUS"] = "COMPLETED" else: todo["STATUS"] = "NEEDS-ACTION" if task.date_created and False: todo["CREATED"] = vDatetime(task.date_created) if task.date_closed and False: todo["COMPLETED"] = vDatetime(task.date_closed) # TODO(jelmer): Set RELATED-TO (SIBLING) based on task.related_tasks # TODO(jelmer): Set COMMENT field based on task.messages todo["CATEGORIES"] = task.bug.tags todo["DESCRIPTION"] = task.bug.description if etag is None: print("Adding todo item for %r" % task.self_link) utils.add_member(flags.url, 'text/calendar', new.to_ical()) tasks_created_counter.inc()
def item_to_ics(item): """ Convert an etm item to an ical object and return a tuple (Success, object) """ doc_id = item.doc_id if not doc_id: return False, None itemtype = item.get('itemtype') if not itemtype: return False, None element = item_types.get(itemtype) if not element: return False, None summary = item['summary'] element.add('uid', doc_id) if 'z' in item: # pytz is required to get the proper tzid into datetimes tz = pytz.timezone(item['z']) else: tz = None if 's' in item: dt = item['s'] dz = dt.replace(tzinfo=tz) tzinfo = dz.tzinfo dt = dz dd = dz.date() else: dt = None tzinfo = None # tzname = None if 'r' in item: # repeating rlst = item['r'] for r in rlst: ritem = {} for k in ical_rrule_keys: if k in r: if k == 'f': ritem[ical_item[k]] = freq_item[r[k]] elif k == 'w': if type(r[k]) == list: ritem[ical_item[k]] = [x.upper() for x in r[k]] else: ritem[ical_item[k]] = r[k].upper() elif k == 'u': uz = parse_str(r[k], item['z']).replace(tzinfo=tzinfo) ritem[ical_item[k]] = uz else: ritem[ical_item[k]] = r[k] citem = CaselessDict(ritem) element.add('rrule', citem) if '+' in item: for pd in item['+']: element.add('rdate', pd) if '-' in item: for md in item['-']: element.add('exdate', md) element.add('summary', summary) if 'p' in item: element.add('priority', item['p']) if 'l' in item: element.add('location', item['l']) if 't' in item: element.add('categories', item['t']) if 'd' in item: element.add('description', item['d']) if 'm' in item: element.add('comment', item['m']) if 'w' in item: element.add('organizer', item['w']) if 'i' in item: for x in item['i']: element.add('attendee', "MAILTO:{0}".format(x)) if item['itemtype'] in ['-', '+', '%']: done, due, following = getDoneAndTwo(item) if 's' in item: element.add('dtstart', dt) if done: finz = done.replace(tzinfo=tzinfo) fint = vDatetime(finz) element.add('completed', fint) if due: duez = due.replace(tzinfo=tzinfo) dued = vDate(duez) element.add('due', dued) elif item['itemtype'] == '^': element.add('dtstart', dd) elif dt: try: element.add('dtstart', dt) except: logger.exception('exception adding dtstart: {0}'.format(dt)) if item['itemtype'] == '*': if 'e' in item and item['e']: ez = dz + item['e'] else: ez = dz try: element.add('dtend', ez) except: logger.exception('exception adding dtend: {0}, {1}'.format(ez, tz)) elif item['itemtype'] == '~': if 'e' in item and item['e']: element.add('comment', timedelta2Str(item['e']))
elif fromstr.count(' ') == 0: fromstr += dtend.strftime(' %b %Y') dtstart = datetime.datetime.strptime(fromstr, "%d %b %Y") duration = None else: if datestr.count(' ') == 1: datestr += time.strftime(' %Y') dtstart = datetime.datetime.strptime(datestr, "%d %b %Y") dtend = None duration = datetime.timedelta(1) props = { 'categories': opts.categories.split(','), 'dtstart': vDate(dtstart.date()), 'created': vDatetime(datetime.datetime.now()), 'class': 'PUBLIC', } if status is not None: props['status'] = status if location is not None: props['location'] = vText(location) if opts.event_url: props['url'] = vUri(opts.event_url) if description is not None: props['summary'] = vText(description) if dtend is not None: props['dtend'] = vDate(dtend.date()) if duration is not None: props['duration'] = vDuration(duration)
elif fromstr.count(' ') == 0: fromstr += dtend.strftime(' %b %Y') dtstart = datetime.datetime.strptime(fromstr, "%d %b %Y") duration = None else: if datestr.count(' ') == 1: datestr += time.strftime(' %Y') dtstart = datetime.datetime.strptime(datestr, "%d %b %Y") dtend = None duration = datetime.timedelta(1) props = { 'categories': opts.categories.split(','), 'dtstart': vDate(dtstart.date()), 'created': vDatetime(datetime.datetime.now()), 'class': 'PUBLIC', } if status is not None: props['status'] = status if location is not None: props['location'] = vText(location) if opts.url: props['url'] = vUri(opts.url) if description is not None: props['summary'] = vText(description) if dtend is not None: props['dtend'] = vDate(dtend.date()) if duration is not None: props['duration'] = vDuration(duration)
} for issue in gh.search_issues(query="assignee:jelmer"): (old, new, href, etag, todo) = utils.create_or_update_calendar_item(flags.url, "VTODO", issue.url) todo["CLASS"] = "PUBLIC" todo["DESCRIPTION"] = issue.body todo["URL"] = issue.html_url todo["SUMMARY"] = "%s: %s" % (issue.repository.name, issue.title) todo["X-GITHUB-URL"] = issue.url todo["STATUS"] = state_map[issue.state] if issue.milestone and issue.milestone.url: todo["X-MILESTONE"] = issue.milestone.url if issue.created_at: todo["CREATED"] = vDatetime(issue.created_at) if issue.closed_at: todo["COMPLETED"] = vDatetime(issue.closed_at) for label in issue.labels: todo["X-LABEL"] = label.name if etag is None: print("Adding todo item for %r" % issue.title) utils.add_member(flags.url, 'text/calendar', new.to_ical()) tasks_created_counter.inc() else: url = urllib.parse.urljoin(flags.url, href) if new != old: print("Updating todo item for %r" % issue.title) utils.put(url, 'text/calendar', new.to_ical(), if_match=[etag]) tasks_updated_counter.inc()
def item_to_ics(item): """ Convert an etm item to an ical object and return a tuple (Success, object) """ doc_id = item.doc_id if not doc_id: return False, None itemtype = item.get('itemtype') if not itemtype: return False, None element = item_types.get(itemtype) if not element: return False, None summary = item['summary'] element.add('uid', doc_id) if 'z' in item: # pytz is required to get the proper tzid into datetimes tz = pytz.timezone(item['z']) else: tz = None if 's' in item: dt = item['s'] dz = dt.replace(tzinfo=tz) tzinfo = dz.tzinfo dt = dz dd = dz.date() else: dt = None tzinfo = None # tzname = None if 'r' in item: # repeating rlst = item['r'] for r in rlst: ritem = {} for k in ical_rrule_keys: if k in r: if k == 'f': ritem[ical_item[k]] = freq_item[r[k]] elif k == 'w': if type(r[k]) == list: ritem[ical_item[k]] = [x.upper() for x in r[k]] else: ritem[ical_item[k]] = r[k].upper() elif k == 'u': uz = parse_str(r[k], item['z']).replace(tzinfo=tzinfo) ritem[ical_item[k]] = uz else: ritem[ical_item[k]] = r[k] citem = CaselessDict(ritem) element.add('rrule', citem) if '+' in item: for pd in item['+']: element.add('rdate', pd) if '-' in item: for md in item['-']: element.add('exdate', md) element.add('summary', summary) if 'p' in item: element.add('priority', item['p']) if 'l' in item: element.add('location', item['l']) if 't' in item: element.add('categories', item['t']) if 'd' in item: element.add('description', item['d']) if 'm' in item: element.add('comment', item['m']) if 'w' in item: element.add('organizer', item['w']) if 'i' in item: for x in item['i']: element.add('attendee', "MAILTO:{0}".format(x)) if item['itemtype'] in ['-', '+', '%']: done, due, following = getDoneAndTwo(item) if 's' in item: element.add('dtstart', dt) if done: finz = done.replace(tzinfo=tzinfo) fint = vDatetime(finz) element.add('completed', fint) if due: duez = due.replace(tzinfo=tzinfo) dued = vDate(duez) element.add('due', dued) elif item['itemtype'] == '^': element.add('dtstart', dd) elif dt: try: element.add('dtstart', dt) except: logger.exception('exception adding dtstart: {0}'.format(dt)) if item['itemtype'] == '*': if 'e' in item and item['e']: ez = dz + item['e'] else: ez = dz try: element.add('dtend', ez) except: logger.exception('exception adding dtend: {0}, {1}'.format(ez, tz)) elif item['itemtype'] == '~': if 'e' in item and item['e']: element.add('comment', timedelta2Str(item['e'])) return True, element
def add(request): def submit_form(form): return render_to_response('add.html', {'form': form}, context_instance=RequestContext(request)) if request.method == 'GET': if not request.user.is_authenticated(): pass # Ask the user if the want to sign on data = {} if 'url' in request.GET: data.update({'url': request.GET['url']}) day = datetime.today() if 'day' in request.GET: if request.GET['day'] != "": day = request.GET[ 'day'] # Javascript hands you Tue May 20 1990 data.update({'date': day}) else: data.update({'date': day.strftime('%a %b %d %Y')}) else: data.update({'date': day.strftime('%a %b %d %Y')}) start_time = datetime.today() start_time = start_time.strftime('%H:%M') if 'start_time' in request.GET: if request.GET['start_time'] != '': start_time = request.GET['start_time'] data.update({'start_time': start_time}) if 'end_time' in request.GET: end_time = request.GET['end_time'] if end_time != 'null': data.update({'end_time': end_time}) data.update({'mail': 'outlook'}) form = EventForm(data) return submit_form(form) # Form was returned with data if request.method == 'POST': form = EventForm(request.POST) if not form.is_valid(): return submit_form(form) title = form.cleaned_data['title'] date = form.cleaned_data['date'] start_time = form.cleaned_data['start_time'] end_time = form.cleaned_data['end_time'] url = form.cleaned_data['url'] describe = form.cleaned_data['describe'] address = form.cleaned_data['address'] mail = form.cleaned_data['mail'] latitude = None longitude = None if address != u'': local = geocode(address) if local != None: if 'address' in local: address = local['address'] if 'latitude' in local and 'longitude' in local: latitude = local['latitude'] longitude = local['longitude'] # If they move the pointer to be more specific override address """ if form.data['lati'] and form.data['lngi']: latitude = form.data['lati'] longitude = form.data['lngi'] """ event = EventModel(title=title, date=date, start_time=start_time, end_time=end_time, address=address, longitude=longitude, latitude=latitude, description=describe, url=url) # Save this event event.save() # Make sure you save the event before connecting it to a user if request.user.is_authenticated(): event.connect(request.user) # Ical or Outlook iCal file if mail == 'outlook' or mail == 'ical': # Create the iCal file cal = Calendar() cal.add('version', '2.0') cal.add('prodid', '-//Microsoft Corporation//Windows Calendar 1.0//EN') cal.add('method', 'PUBLISH') event = Event() event.add('summary', describe) if start_time != None: dt = datetime.combine(date, start_time) else: dt = date event.add('dtstart', dt) event.add('dtstamp', dt) if end_time != None: de = datetime.combine(date, end_time) event.add('dtend', de) g = (latitude, latitude) event.add('geo', g) event.add('location', address) uid = date.isoformat() + '@wenzit.net' event.add('UID', uid) event.add('url', url) cal.add_component(event) f = open('schedule.ics', 'wb') f.write(cal.as_string()) f.close() response = HttpResponse(cal.as_string(), mimetype='text/calendar') response[ 'Content-Disposition'] = 'attachment; filename=schedule.ics' return response # Send the event to google elif mail == 'google': response = "http://www.google.com/calendar/event?action=TEMPLATE" response += "&text=" + urllib.quote_plus(title) if start_time != None: ds = datetime.combine(date, start_time) else: ds = date if end_time != None: de = datetime.combine(date, end_time) response += "&dates=" + vDatetime(ds).ical()+ \ '/'+vDatetime(de).ical() else: response += "&dates=" + vDatetime(ds).ical() response += "&details=" + urllib.quote_plus(title) response += "&location=" + urllib.quote_plus(address) response += "&sprop=" + urllib.quote_plus(url) return HttpResponseRedirect(response) # Send the event to Yahoo if mail == 'yahoo': response = 'http://calendar.yahoo.com/?v=60' response += '&TITLE=' + urllib.quote_plus(title) ds = datetime.combine(date, start_time) if end_time: de = datetime.combine(date, end_time) dur = de - ds hrs, left = divmod(dur.seconds, 3600) mins, secs = divmod(left, 60) dur = '%02d%02d' % (hrs, mins) else: dur = '' response += '&ST=' + vDatetime(ds).ical() response += '&DUR=' + dur response += '&in_loc=' + urllib.quote_plus(address) response += '&DESC=' + urllib.quote_plus(title) response += '&URL=' + urllib.quote_plus(url) return HttpResponseRedirect(response)