def populate_birthdays_calendar(birthdays): """ Populate a birthdays calendar using birthday objects """ c = Calendar() c.scale = 'GREGORIAN' c.method = 'PUBLISH' c.creator = f'fb2cal v{__version__} ({__status__}) [{__website__}]' c.extra.append( ContentLine(name='X-WR-CALNAME', value='Facebook Birthdays (fb2cal)')) c.extra.append(ContentLine(name='X-PUBLISHED-TTL', value='PT12H')) c.extra.append( ContentLine(name='X-ORIGINAL-URL', value='/events/birthdays/')) cur_date = datetime.now() for birthday in birthdays: e = Event() e.uid = birthday.uid e.name = f"{birthday.name}'s Birthday" # Calculate the year as this year or next year based on if its past current month or not # Also pad day, month with leading zeros to 2dp year = cur_date.year if birthday.month >= cur_date.month else ( cur_date + relativedelta(years=1)).year month = '{:02d}'.format(birthday.month) day = '{:02d}'.format(birthday.day) e.begin = f'{year}-{month}-{day} 00:00:00' e.make_all_day() e.duration = timedelta(days=1) e.extra.append(ContentLine(name='RRULE', value='FREQ=YEARLY')) c.events.add(e) return c
def populate_birthdays_calendar(birthdays): """ Populate a birthdays calendar using birthday objects """ c = Calendar() c.scale = 'GREGORIAN' c.method = 'PUBLISH' c.creator = f'fb2cal v{__version__} ({__status__}) [{__website__}]' c.extra.append( ContentLine(name='X-WR-CALNAME', value='Facebook Birthdays (fb2cal)')) c.extra.append(ContentLine(name='X-PUBLISHED-TTL', value='PT12H')) c.extra.append( ContentLine(name='X-ORIGINAL-URL', value='/events/birthdays/')) cur_date = datetime.now() backburner = [] rearrange = False logger.info("Saving birthdays to local cache...") with open('birthdays.pkl', 'wb') as pkl_file: pickle.dump(birthdays, pkl_file) logger.info("Saved to cache (src/birthdays.pkl)") for birthday_i in range(0, len(birthdays)): birthday = birthdays[birthday_i] if (birthday.month == 2 and birthday.day == 29): rearrange = True backburner.append(birthday) del birthdays[birthday_i] birthday_i -= 1 continue if rearrange: if not (birthday.month == 2 and birthday.day == 28): birthdays.insert(birthday_i, backburner) rearrange = False birthday_i -= 1 continue e = Event() e.uid = birthday.uid e.name = f"{birthday.name}'s Birthday" # Calculate the year as this year or next year based on if its past current month or not # Also pad day, month with leading zeros to 2dp year = cur_date.year if birthday.month >= cur_date.month else ( cur_date + relativedelta(years=1)).year month = '{:02d}'.format(birthday.month) day = '{:02d}'.format(birthday.day) e.begin = f'{year}-{month}-{day} 00:00:00' e.make_all_day() e.duration = timedelta(days=1) e.extra.append(ContentLine(name='RRULE', value='FREQ=YEARLY')) c.events.add(e) return c
def generate(self): c = Calendar() c.scale = 'GREGORIAN' c.method = 'PUBLISH' c.creator = f'fb2cal v{__version__} ({__status__}) [{__website__}]' c.extra.append( ContentLine(name='X-WR-CALNAME', value='Facebook Birthdays (fb2cal)')) c.extra.append(ContentLine(name='X-PUBLISHED-TTL', value='PT12H')) c.extra.append( ContentLine(name='X-ORIGINAL-URL', value='/events/birthdays/')) cur_date = datetime.now() for facebook_user in self.facebook_users: # Don't add extra 's' if name already ends with 's' formatted_username = f"{facebook_user.name}'s" if facebook_user.name[ -1] != 's' else f"{facebook_user.name}'" formatted_username = f'{formatted_username} Birthday' # Set date components day = facebook_user.birthday_day month = facebook_user.birthday_month year = facebook_user.birthday_year # Feb 29 special case: # If event year is not a leap year, use Feb 28 as birthday date instead if facebook_user.birthday_month == 2 and facebook_user.birthday_day == 29 and not calendar.isleap( year): day = 28 # The birth year may not be visible due to privacy settings # In this case, calculate the year as this year or next year based on if its past current month or not if year is None: year = cur_date.year if facebook_user.birthday_month >= cur_date.month else ( cur_date + relativedelta(years=1)).year # Format date components as needed month = f'{month:02}' day = f'{day:02}' # Event meta data e = Event() e.uid = facebook_user.id e.name = formatted_username e.created = cur_date e.description = f'{facebook_user}\n{generate_facebook_profile_url_permalink(facebook_user)}' e.begin = f'{year}-{month}-{day} 00:00:00' e.make_all_day() e.duration = timedelta(days=1) e.extra.append(ContentLine(name='RRULE', value='FREQ=YEARLY')) c.events.add(e) self.birthday_calendar = c
def populate_birthdays_calendar(birthdays): """ Populate a birthdays calendar using birthday objects """ c = Calendar() c.scale = 'GREGORIAN' c.method = 'PUBLISH' c.creator = f'fb2cal v{__version__} ({__status__}) [{__website__}]' c.extra.append( ContentLine(name='X-WR-CALNAME', value='Facebook Birthdays (fb2cal)')) c.extra.append(ContentLine(name='X-PUBLISHED-TTL', value='PT12H')) c.extra.append( ContentLine(name='X-ORIGINAL-URL', value='/events/birthdays/')) cur_date = datetime.now() for birthday in birthdays: e = Event() e.uid = birthday.uid e.name = f"{birthday.name}'s Birthday" # Calculate the year as this year or next year based on if its past current month or not # Also pad day, month with leading zeros to 2dp year = cur_date.year if birthday.month >= cur_date.month else ( cur_date + relativedelta(years=1)).year month = '{:02d}'.format(birthday.month) day = '{:02d}'.format(birthday.day) try: e.begin = f'{year}-{month}-{day} 00:00:00' except ValueError as err: # Check if this is due to leap year. If so, move to Feb 28. if birthday.month == 2 and birthday.day == 29: day = '{:02d}'.format(birthday.day - 1) logger.warning( f"{birthday.name}'s birthday landed on a missing leap day. Moving 1 day earlier ({year}-{month}-{day}) instead." ) e.begin = f'{year}-{month}-{day} 00:00:00' else: raise err e.make_all_day() e.duration = timedelta(days=1) e.extra.append(ContentLine(name='RRULE', value='FREQ=YEARLY')) c.events.add(e) return c
def generate(self): c = Calendar() c.scale = 'GREGORIAN' c.method = 'PUBLISH' c.creator = f'fb2cal v{__version__} ({__status__}) [{__website__}]' c.extra.append( ContentLine(name='X-WR-CALNAME', value='Facebook Birthdays (fb2cal)')) c.extra.append(ContentLine(name='X-PUBLISHED-TTL', value='PT12H')) c.extra.append( ContentLine(name='X-ORIGINAL-URL', value='/events/birthdays/')) cur_date = datetime.now() for facebook_user in self.facebook_users: e = Event() e.uid = facebook_user.id e.created = cur_date # Don't add extra 's' if name already ends with 's' formatted_username = f"{facebook_user.name}'s" if facebook_user.name[ -1] != 's' else f"{facebook_user.name}'" e.name = f"{formatted_username} Birthday" # Calculate the year as this year or next year based on if its past current month or not # Also pad day, month with leading zeros to 2dp year = cur_date.year if facebook_user.birthday_month >= cur_date.month else ( cur_date + relativedelta(years=1)).year # Feb 29 special case: # If event year is not a leap year, use Feb 28 as birthday date instead if facebook_user.birthday_month == 2 and facebook_user.birthday_day == 29 and not calendar.isleap( year): facebook_user.birthday_day = 28 month = '{:02d}'.format(facebook_user.birthday_month) day = '{:02d}'.format(facebook_user.birthday_day) e.begin = f'{year}-{month}-{day} 00:00:00' e.make_all_day() e.duration = timedelta(days=1) e.extra.append(ContentLine(name='RRULE', value='FREQ=YEARLY')) c.events.add(e) self.birthday_calendar = c
def calendar_for_branch(branch): events = fetch_next_days_for_branch(branch) cal_events = [calendar_event_for_event(branch, e) for e in events] cal = Calendar(events=cal_events, creator="sfymca") cal.method = "PUBLISH" cal.scale = "GREGORIAN" lines = str(cal).split("\r\n") indicies = [i for i, s in enumerate(lines) if s.startswith("BEGIN:")] if len(indicies) > 1: second_index = indicies[1] lines.insert(second_index, f"X-WR-CALNAME:{branch.name} YMCA Pool") lines.insert(second_index + 1, "X-WR-TIMEZONE:America/Los_Angeles") return "\r\n".join(lines)
def ics_parser(bday_info_tuple, enable_date_swap): # Set calender info. c = Calendar() c.scale = 'GREGORIAN' c.method = 'PUBLISH' c.creator = 'Hardeep Singh Narang @hardeepnarang10' c._unused.append(ContentLine(name='X-WR-CALNAME', params={}, value='Facebook Birthdays Calendar (fb2ics)')) c._unused.append(ContentLine(name='X-PUBLISHED-TTL', params={}, value='PT12H')) c._unused.append(ContentLine(name='X-ORIGINAL-URL', params={}, value='/events/birthdays/')) # Get present date. present_date = datetime.now() # Process and add individual Events to the Calender object. for each_tuple in bday_info_tuple: # Calculate year for next birthday. # Add padding for day and month (2 digits - leading zero). tuple_date = each_tuple[2] year = present_date.year if int(tuple_date[0:tuple_date.index('/')]) >= present_date.month else (present_date + relativedelta(years=1)).year if enable_date_swap: day = '{:02d}'.format(int(tuple_date[0:tuple_date.index('/')])) month = '{:02d}'.format(int(tuple_date[tuple_date.index('/') + 1:])) else: month = '{:02d}'.format(int(tuple_date[0:tuple_date.index('/')])) day = '{:02d}'.format(int(tuple_date[tuple_date.index('/')+1:])) # Create Event object. e = Event() e.uid = each_tuple[0] e.name = f"{each_tuple[1]}'s Birthday!" e.description = "Facebook friend's birthday! Wish them well!" e.begin = f'{year}-{month}-{day} 00:00:00' e.make_all_day() e.duration = timedelta(days=1) e._unused.append(ContentLine(name='RRULE', params={}, value='FREQ=YEARLY')) c.events.add(e) return c
async def main(): s = spond.Spond(username=username, password=password) c = Calendar() c.method = 'PUBLISH' events = await s.getEvents() for event in events: e = Event() e.uid = event['id'] e.name = event['heading'] e.description = event['description'] e.begin = event['startTimestamp'] e.end = event['endTimestamp'] e.sequence = event['updated'] if 'cancelled' in event and event['cancelled']: e.status = 'Cancelled' if 'location' in event: e.location = "{}, {}".format(event['location']['feature'], event['location']['address']) c.events.add(e) with open(ics_file, 'w') as out_file: out_file.writelines(c) await s.clientsession.close()
def ProcessEventsintoICS(root, xpath, eventcount, namePrefix, synonymPrefix, locationPrefix): # if no prefix then just look for location if (namePrefix): # also add the eventor message location if available if (synonymPrefix): xpath += " | /EventList/Event[(starts-with(Name,'{0}')) or (starts-with(Name,'{1}'))]/HashTableEntry[(Key='Eventor_Message') and contains(Value,'{2}') ]/Value".format( namePrefix, synonymPrefix, locationPrefix) else: xpath += " | /EventList/Event[starts-with(Name,'{0}')]/HashTableEntry[(Key='Eventor_Message') and contains(Value, '{1}'}) ]/Value".format( namePrefix, locationPrefix) else: xpath += " | /EventList/Event/HashTableEntry[(Key='Eventor_Message') and contains(Value, '{0}') ]/Value".format( locationPrefix) eventids = root.xpath(xpath) locCount = len(eventids) - eventcount print("Found {0} locations".format(locCount)) # create a list of event locations eventdata = {} # for each event then add a location based on the eventid for eventid in eventids: if (eventid.tag == 'EventId'): eventdata[eventid.text] = "" lasteventid = eventid.text if (eventid.tag == "Value"): # default is no location location = "location unknown (not found in the eventor message)" # look for end of lines if "\n" in eventid.text: # split into lines looking for location eventormessagelines = eventid.text.split('\n') for line in eventormessagelines: if (line.startswith(locationPrefix)): location = line.replace(locationPrefix, "") break else: # look in the text for prefix if locationPrefix in eventid.text: location = eventid.text.replace(locationPrefix, "") eventdata[lasteventid] = location # now the locations are extracted properly add each location to an event in the calendar from ics import Calendar mainCal = None for key, value in eventdata.items(): # get the calendar from eventor icsURL = "https://eventor.orienteering.asn.au/Events/ICalendar/{0}".format( key) print("Reading ICS file for event id {0}".format(key)) c = Calendar(requests.get(icsURL).text) # create main calendar if it doesn't exist if mainCal is None: mainCal = c for event in c.events: event.location = value else: for event in c.events: event.location = value mainCal.events.add(event) # for the calendar to be used it must be published c.method = "PUBLISH" # TODO: add in X-WR-CALNAME e.g. "Sydney Summer Series Season 29 "Map Running Sydney" print("Writing combined {0} events".format(len(mainCal.events))) if (namePrefix): filename = namePrefix else: filename = "OrganisationEvents" with open('{0}.ics'.format(filename), 'w', newline='') as f: f.writelines(mainCal) print(str(mainCal))
def ical(request): # This should be a comma-separated list with values corresponding to # Committee's abbreviation_short field. abbreviations = request.GET.get( 'committee', '').split(',') if 'committee' in request.GET else [] committees = Committee.objects.filter( parliaments__parliament_num=CURRENT_PARLIAMENT_NUM) if len(abbreviations) > 0: committees = committees.filter(abbreviation_short__in=abbreviations) cal = Calendar() cal.creator = '-//Alþingi//NONSGML Fastanefndir Alþingis//IS' cal.scale = 'GREGORIAN' cal.method = 'PUBLISH' agendas = CommitteeAgenda.objects.select_related( 'committee').prefetch_related('committee_agenda_items').filter( parliament__parliament_num=CURRENT_PARLIAMENT_NUM, committee__in=committees).order_by('timing_start_planned') for agenda in agendas: # Short-hand. agenda_id = agenda.committee_agenda_xml_id description = 'Dagskrá:\n\n' for item in agenda.committee_agenda_items.select_related( 'issue__parliament'): description += '%d. %s\n' % (item.order, capfirst(item.name)) # Add URL of issue, if any. if item.issue is not None: description += '%s\n' % external_issue_url( item.issue.parliament.parliament_num, item.issue.issue_num) description += '\n' event = Event() event.uid = '*****@*****.**' % agenda_id event.name = capfirst(agenda.committee.name) event.description = description event.begin = agenda.timing_start_planned event.end = agenda.timing_end event.url = 'https://www.althingi.is/thingnefndir/dagskra-nefndarfunda/?nfaerslunr=%d' % agenda_id # Committee agendas are never planned at midnight (or damn well # hopefully not). So when a committee agenda is planned without a time # factor, or in other words, is timed at midnight, we'll assume that # the timing is actually not precisely determined and turn it into an # all-day event instead, using the timing text (determined below) to # elaborate instead. if event.begin.hour == 0 and event.begin.minute == 0 and event.begin.second == 0: event.make_all_day() if agenda.timing_text: # If agenda.timing_text is just a representation of what is # already known from the planned starting time, we'll want to # nullify it so that we don't clutter the name with it # unnecessarily. To do this, we have to re-construct the text that # is typically provided and compare it against agenda.timing_text. # If they match, we won't include it. If they don't match, then # what's provided in agenda.timing_text is presumably more # meaningful than simply a (badly) reformatted version of # agenda.timing_start_planned. timing = agenda.timing_start_planned day = timing.day month_name = ICELANDIC_MONTHS[timing.month] year = str(timing.year)[2:] time = timing.strftime('%-I:%M') am_pm = icelandic_am_pm(timing) # Known inconsistencies are whether there is a space in the # beginning, and whether there is one space or two between "kl." # and the time-of-day. We strip and replace to compensate. timing_text_test = '%d. %s %s, kl. %s %s' % (day, month_name, year, time, am_pm) if agenda.timing_text.strip().replace(' ', ' ') != timing_text_test: event.name += ' (%s)' % agenda.timing_text.strip() cal.events.add(event) ical_text = monkey_patch_ical( cal.__str__(), 'Fastanefndir Alþingis', 'Dagatal sem inniheldur boðaða fundi fastanefnda Alþingis ásamt dagskrá í lýsingu.', 'Reykjavik/Iceland', 'PT10M') if request.GET.get('plaintext', False): content_type = 'text/plain' else: content_type = 'text/calendar' return HttpResponse(ical_text, content_type='%s; charset=utf-8' % content_type)