Example #1
0
 def _as_ics(self, citymeo=False):
     if not self.initialized:
         self._lazy_init()
     cal = iCalendar()
     cal.add('prodid', '-//PonyConf.io//PonyConf//FR')
     cal.add('version', '2.0')
     cal.add('x-wr-calname', self.conference.name)
     cal.add('x-wr-timezone', settings.TIME_ZONE)
     cal.add('calscale', 'GREGORIAN')
     talks = self.talks
     if citymeo and talks.exists():
         talks = talks.filter(start_date__gte=now()-timedelta(minutes=5))
         if talks.exists():
             limit = talks.first().start_date.replace(hour=23, minute=59, second=59)
             talks = talks.filter(start_date__lte=limit)
     for talk in talks:
         event = iEvent()
         event.add('dtstart', talk.start_date)
         if not talk.end_date:
             continue
         event.add('dtend', talk.end_date)
         event.add('dtstamp', talk.updated)
         event.add('summary', talk.title)
         if talk.room:
             event.add('location', talk.room)
         event.add('status', 'CONFIRMED' if talk.accepted else 'TENTATIVE')
         if not citymeo:
             event.add('description', talk.description)
         event.add('uid', '%s/%s' % (self.site.domain, talk.id))
         cal.add_component(event)
     return cal.to_ical()
Example #2
0
 def _as_ics(self, citymeo=False):
     if not self.initialized:
         self._lazy_init()
     cal = iCalendar()
     cal.add('prodid', '-//PonyConf.io//PonyConf//FR')
     cal.add('version', '2.0')
     cal.add('x-wr-calname', self.conference.name)
     cal.add('x-wr-timezone', settings.TIME_ZONE)
     cal.add('calscale', 'GREGORIAN')
     talks = self.talks
     if citymeo and talks.exists():
         talks = talks.filter(start_date__gte=now() - timedelta(minutes=5))
         if talks.exists():
             limit = talks.first().start_date.replace(hour=23,
                                                      minute=59,
                                                      second=59)
             talks = talks.filter(start_date__lte=limit)
     for talk in talks:
         event = iEvent()
         event.add('dtstart', talk.start_date)
         if not talk.end_date:
             continue
         event.add('dtend', talk.end_date)
         event.add('dtstamp', talk.updated)
         event.add('summary', talk.title)
         if talk.room:
             event.add('location', talk.room)
         event.add('status', 'CONFIRMED' if talk.accepted else 'TENTATIVE')
         if not citymeo:
             event.add('description', talk.description)
         event.add('uid', '%s/%s' % (self.site.domain, talk.id))
         cal.add_component(event)
     return cal.to_ical()
Example #3
0
def change():
    """ Change (create) or delete an event by POST request """
    calendar = Config.calendar()
    changes = request.get_json()
    for uid in changes["deleted"]:
        try:
            calendar.event_by_uid(uid).delete()
        except caldav.lib.error.NotFoundError:
            # the event haven't been in the calendar, maybe was just created and deleted
            pass

    for schedule in changes["created"]:
        c = iCalendar()
        c.add('prodid', '-//Schedule shift//csirt.cz//')
        c.add('version', '2.0')
        event = iEvent()
        event.add('uid', schedule["id"])
        event.add('summary', schedule["calendarId"] + " " + schedule["title"])
        # event.add('dtstart', parse(schedule["start"]["_date"]).astimezone().date()+timedelta(1))

        # print(schedule)
        # import ipdb; ipdb.set_trace()

        event.add('dtstart', parse(schedule["start-ics"]))
        event.add('dtend', parse(schedule["end-ics"]))
        # event.add('dtstart', parse(schedule["start"]["_date"]))
        # event.add('dtend', parse(schedule["end"]["_date"]))
        c.add_component(event)
        calendar.add_event(c.to_ical().decode("utf-8"))

    return "Saved"
def wrap_into_vcalendar(*vevents, **kw):
    calendar = iCalendar()
    calendar.add('prodid', "-//Plone/NONSGML Calendaring//EN")
    calendar.add('version', '2.0')
    title = kw.get('title')
    if title:
        title = unicode(title, 'utf-8')
        calendar.add('x-wr-calname', title)
    for vevent in vevents:
        calendar.add_component(vevent)
    return calendar.as_string()
def wrap_into_vcalendar(*vevents, **kw):
    calendar = iCalendar()
    calendar.add('prodid',  "-//Plone/NONSGML Calendaring//EN")
    calendar.add('version', '2.0')
    title = kw.get('title')
    if title:
        title = unicode(title, 'utf-8')
        calendar.add('x-wr-calname', title)
    for vevent in vevents:
        calendar.add_component(vevent)
    return calendar.as_string()
Example #6
0
def _generate_rsvp(status, account, event):
    # It seems that Google Calendar requires us to copy a number of fields
    # in the RVSP reply. I suppose it's for reconciling the reply with the
    # invite. - karim
    cal = iCalendar()
    cal.add('PRODID', '-//Nylas sync engine//nylas.com//')
    cal.add('METHOD', 'REPLY')
    cal.add('VERSION', '2.0')
    cal.add('CALSCALE', 'GREGORIAN')

    icalevent = icalendar.Event()
    icalevent['uid'] = event.uid

    # For ahem, 'historic reasons', we're saving the owner field
    # as "Organizer <*****@*****.**>".
    organizer_name, organizer_email = event.owner.split('<')
    organizer_email = organizer_email[:-1]

    icalevent['sequence'] = event.sequence_number
    icalevent['X-MICROSOFT-CDO-APPT-SEQUENCE'] = icalevent['sequence']

    if event.status == 'confirmed':
        icalevent['status'] = 'CONFIRMED'

    icalevent['dtstamp'] = serialize_datetime(datetime.utcnow())

    if event.start is not None:
        icalevent['dtstart'] = serialize_datetime(event.start)

    if event.end is not None:
        icalevent['dtend'] = serialize_datetime(event.end)

    if event.description is not None:
        icalevent['description'] = event.description

    if event.location is not None:
        icalevent['location'] = event.location

    if event.title is not None:
        icalevent['summary'] = event.title

    attendee = icalendar.vCalAddress(u'MAILTO:{}'.format(
        account.email_address))
    attendee.params['cn'] = account.name
    attendee.params['partstat'] = status
    icalevent.add('attendee', attendee, encode=0)
    cal.add_component(icalevent)

    ret = {}
    ret["cal"] = cal
    ret["organizer_email"] = organizer_email

    return ret
Example #7
0
def _generate_rsvp(status, account, event):
    # It seems that Google Calendar requires us to copy a number of fields
    # in the RVSP reply. I suppose it's for reconciling the reply with the
    # invite. - karim
    cal = iCalendar()
    cal.add('PRODID', '-//Nylas sync engine//nylas.com//')
    cal.add('METHOD', 'REPLY')
    cal.add('VERSION', '2.0')
    cal.add('CALSCALE', 'GREGORIAN')

    icalevent = icalendar.Event()
    icalevent['uid'] = event.uid

    # For ahem, 'historic reasons', we're saving the owner field
    # as "Organizer <*****@*****.**>".
    organizer_name, organizer_email = event.owner.split('<')
    organizer_email = organizer_email[:-1]

    icalevent['sequence'] = event.sequence_number
    icalevent['X-MICROSOFT-CDO-APPT-SEQUENCE'] = icalevent['sequence']

    if event.status == 'confirmed':
        icalevent['status'] = 'CONFIRMED'

    icalevent['dtstamp'] = serialize_datetime(datetime.utcnow())

    if event.start is not None:
        icalevent['dtstart'] = serialize_datetime(event.start)

    if event.end is not None:
        icalevent['dtend'] = serialize_datetime(event.end)

    if event.description is not None:
        icalevent['description'] = event.description

    if event.location is not None:
        icalevent['location'] = event.location

    if event.title is not None:
        icalevent['summary'] = event.title

    attendee = icalendar.vCalAddress(u'MAILTO:{}'.format(
        account.email_address))
    attendee.params['cn'] = account.name
    attendee.params['partstat'] = status
    icalevent.add('attendee', attendee, encode=0)
    cal.add_component(icalevent)

    ret = {}
    ret["cal"] = cal
    ret["organizer_email"] = organizer_email

    return ret
Example #8
0
def export(request, events, year=None):
    cal = iCalendar()
    site = Site.objects.get_current()

    cal.add('prodid', '-//%s Events Calendar//%s//' % (site.name, site.domain))
    cal.add('version', '2.0')

    site_token = site.domain.split('.')
    site_token.reverse()
    site_token = '.'.join(site_token)

    for event in events:
        show = event.show

        description = ""
        if show.info.headliner:
            description += "Headliner: %s\n" % show.info.headliner
        elif show.info.headliner_text:
            description += "Headliner: %s\n" % show.info.headliner_text
        if show.info.openers_text:
            description += "Openers: %s\n" % show.info.openers_text
        if show.info.venue:
            description += "Venue: %s\n" % show.info.venue
        else:
            description += "Venue: %s\n" % show.info.venue_text
        if show.info.description:
            description += "Description: %s\n" % show.info.description

        ical_event = iEvent()
        ical_event.add('summary', show.info.get_title())
        ical_event.add('description', description)
        ical_event.add('location', show.info.venue)
        ical_event.add('dtstart', show.date.start)
        ical_event.add('dtend', show.date.end and show.date.end
                       or show.date.start)
        ical_event.add('dtstamp', show.date.end and show.date.end
                       or show.date.start)
        ical_event['uid'] = '%d.event.events.%s' % (show.id, site_token)

        cal.add_component(ical_event)

    response = HttpResponse(cal.to_ical(), content_type="text/calendar")
    # title or headliner
    if year:
        response[
            'Content-Disposition'] = 'attachment; filename=%ss-calendar-%s.ics' % (
                slugify(request.user.profile), year)
    else:
        response[
            'Content-Disposition'] = 'attachment; filename=%s.ics' % slugify(
                events[0])
    return response
Example #9
0
def _generate_rsvp(status, account, event):
    # It seems that Google Calendar requires us to copy a number of fields
    # in the RVSP reply. I suppose it's for reconciling the reply with the
    # invite. - karim
    cal = iCalendar()
    cal.add("PRODID", "-//Nylas sync engine//nylas.com//")
    cal.add("METHOD", "REPLY")
    cal.add("VERSION", "2.0")
    cal.add("CALSCALE", "GREGORIAN")

    icalevent = icalendar.Event()
    icalevent["uid"] = event.uid

    if event.organizer_email is not None:
        icalevent["organizer"] = event.organizer_email

    icalevent["sequence"] = event.sequence_number
    icalevent["X-MICROSOFT-CDO-APPT-SEQUENCE"] = icalevent["sequence"]

    if event.status == "confirmed":
        icalevent["status"] = "CONFIRMED"

    icalevent["dtstamp"] = serialize_datetime(datetime.utcnow())

    if event.start is not None:
        icalevent["dtstart"] = serialize_datetime(event.start)

    if event.end is not None:
        icalevent["dtend"] = serialize_datetime(event.end)

    if event.description is not None:
        icalevent["description"] = event.description

    if event.location is not None:
        icalevent["location"] = event.location

    if event.title is not None:
        icalevent["summary"] = event.title

    attendee = icalendar.vCalAddress(u"MAILTO:{}".format(
        account.email_address))
    attendee.params["cn"] = account.name
    attendee.params["partstat"] = status
    icalevent.add("attendee", attendee, encode=0)
    cal.add_component(icalevent)

    ret = {}
    ret["cal"] = cal

    return ret
Example #10
0
def icalendar(request):
    from icalendar import Calendar as iCalendar
    from icalendar import Event
    from datetime import datetime, date
    from icalendar import UTC  # timezone

    cal = iCalendar()
    cal.add("prodid", "-//FWC Kung Fu Calendar //m.fwckungfu.com")
    cal.add("version", "2.4")
    cal.add("x-wr-calname", "FWC Kung Fu Calendar")

    yyyy = datetime.today().year
    # filter_ = dict(start_date__year=yyyy, start_date__gte=datetime.today())
    filter_ = dict()
    all_datestrings = set()
    for entry in Calendar.objects.filter(**filter_).order_by("start_date"):
        event = Event()
        # print entry.start_date, entry.event
        event.add("summary", entry.event)
        st = entry.start_date
        event.add("dtstart", date(st.year, st.month, st.day))
        all_datestrings.add(st.strftime("%Y%m%d"))
        # event.add('dtstart', datetime(st.year, st.month, st.day, 0, 0, 0, tzinfo=UTC))
        et = entry.end_date
        event.add("dtend", date(et.year, et.month, et.day))
        all_datestrings.add(et.strftime("%Y%m%d"))
        # event.add('dtend', datetime(et.year, et.month, et.day,0,0,0,tzinfo=UTC))
        # event.add('dtend', 'TZID=UTC;VALUE=DATE:' + et.strftime('%Y%m%d')) # DOESNOT WORK!

        event.add("dtstamp", datetime(st.year, st.month, st.day, 0, 0, 0, tzinfo=UTC))
        event["uid"] = "fwccalendar2.4-%s" % entry.id
        cal.add_component(event)

    as_string = cal.as_string()
    for datestring in all_datestrings:

        as_string = as_string.replace(":%s" % datestring, ";TZID=UTC;VALUE=DATE:%s" % datestring)

    as_string = as_string.replace("\r", "")
    response = HttpResponse(as_string, mimetype="text/calendar")
    response["Content-Disposition"] = 'attachment; filename="%s"' % "calendar.ics"
    return response
Example #11
0
def to_icalendar(events):
    """ Converts events to .ics format
    :param events = Iterable(cal.schema.Event)
    :return bytes
    """
    summary = "Calendar for Columbia University made by ADI (adicu.com)"
    cal = iCalendar(dtstart=vDatetime(datetime.now()),
                    summary=summary)

    for e in events:
        # for every event, create an event object
        organizer = vCalAddress("MAILTO:''")
        organizer.params['cn'] = e.user.name
        vevent = iEvent(summary=e.name, organizer=organizer,
                        location=vText(e.location), dtstart=vDatetime(e.start),
                        description=e.url)

        cal.add_component(vevent)

    return cal.to_ical()
Example #12
0
    def __call__(self, *args, **kwargs):
        self.args = args
        self.kwargs = kwargs

        cal = icalendar.iCalendar()
        cal.add('prodid', '-// django-scheduler //')
        cal.add('version', '2.0')

        for item in self.items():
            event = icalendar.Event()

            for vkey, key in EVENT_ITEMS:
                value = getattr(self, 'item_' + key)(item)
                if value:
                    event.add(vkey, value)

            cal.add_component(event)

        response = HttpResponse(cal.to_ical())
        response['Content-Type'] = 'text/calendar'

        return response
Example #13
0
    def __call__(self, *args, **kwargs):
        self.args = args
        self.kwargs = kwargs

        cal = icalendar.iCalendar()
        cal.add('prodid', '-// django-scheduler //')
        cal.add('version', '2.0')

        for item in self.items():
            event = icalendar.Event()

            for vkey, key in EVENT_ITEMS:
                value = getattr(self, 'item_' + key)(item)
                if value:
                    event.add(vkey, value)

            cal.add_component(event)

        response = HttpResponse(cal.to_ical())
        response['Content-Type'] = 'text/calendar'

        return response
Example #14
0
#!/usr/bin/env python3

from icalendar import Calendar as iCalendar, Event
import datetime
import pytz
import requests
import os

# f = open('importio.json', 'rb')
# json = json.loads(f.read().decode())

MOVEAVEIRO_API_ENDPOINT = 'https://api.import.io/store/connector/3efbeeba-cf14-4fdb-af8f-7c6ba6d27f0c/_query?input=webpage/url:https%3A%2F%2Fdocs.google.com%2Fspreadsheets%2Fd%2F12epuwHtZbmF3xpFZydbLVw19xR_c-EDyX2tfzpZTtRo%2Fpubhtml&&_apikey=f2f3cb66f1b6401ebbf5c2a1ba04fdbfb1f94626e5a682059588ee5e282ccb73102540273ee25426ded781d8c39315ddf137df6023b26bcbff811978815bd0e13686a986642c06c408cd4da678cd7aec'
json = requests.get(MOVEAVEIRO_API_ENDPOINT).json()
json = json['results']
ical = iCalendar()

''' Separate results by path '''
paths = {'1': [], '2': [], '3.1': [], '3.2': [], '4': [], '5': []}
for result in json:
    if 'path' in result:
        for k in [k for k in result.keys() if k.startswith("union_")]:
            result[k[6:]] = result[k]
            del result[k]

            paths[result['path']].append(result)

            event = Event()

            # Note
            # http://www.ietf.org/rfc/rfc2445.txt
            # http://icalendar.readthedocs.io
Example #15
0
def generate_icalendar_invite(event, invite_type='request'):
    # Generates an iCalendar invite from an event.
    assert invite_type in ['request', 'cancel']

    cal = iCalendar()
    cal.add('PRODID', '-//Nylas sync engine//nylas.com//')

    if invite_type in ['request', 'update']:
        cal.add('METHOD', 'REQUEST')
    elif invite_type == 'cancel':
        cal.add('METHOD', 'CANCEL')

    cal.add('VERSION', '2.0')
    cal.add('CALSCALE', 'GREGORIAN')

    icalendar_event = icalendar.Event()

    account = event.namespace.account
    organizer = icalendar.vCalAddress("MAILTO:{}".format(
        account.email_address))
    if account.name is not None:
        organizer.params['CN'] = account.name

    icalendar_event['organizer'] = organizer
    icalendar_event['sequence'] = str(event.sequence_number)
    icalendar_event['X-MICROSOFT-CDO-APPT-SEQUENCE'] = icalendar_event[
        'sequence']

    if invite_type == 'cancel':
        icalendar_event['status'] = 'CANCELLED'
    else:
        icalendar_event['status'] = 'CONFIRMED'

    icalendar_event['uid'] = "{}@nylas.com".format(event.public_id)
    icalendar_event['description'] = event.description or ''
    icalendar_event['summary'] = event.title or ''
    icalendar_event['last-modified'] = serialize_datetime(event.updated_at)
    icalendar_event['dtstamp'] = icalendar_event['last-modified']
    icalendar_event['created'] = serialize_datetime(event.created_at)
    icalendar_event['dtstart'] = serialize_datetime(event.start)
    icalendar_event['dtend'] = serialize_datetime(event.end)
    icalendar_event['transp'] = 'OPAQUE' if event.busy else 'TRANSPARENT'
    icalendar_event['location'] = event.location or ''

    attendees = []
    for participant in event.participants:
        email = participant.get('email', None)

        # FIXME @karim: handle the case where a participant has no address.
        # We may have to patch the iCalendar module for this.
        assert email is not None and email != ""

        attendee = icalendar.vCalAddress("MAILTO:{}".format(email))
        name = participant.get('name', None)
        if name is not None:
            attendee.params['CN'] = name

        attendee.params['RSVP'] = 'TRUE'
        attendee.params['ROLE'] = 'REQ-PARTICIPANT'
        attendee.params['CUTYPE'] = 'INDIVIDUAL'

        status = participant.get('status', 'noreply')
        attendee.params['PARTSTAT'] = INVERTED_STATUS_MAP.get(status)
        attendees.append(attendee)

    if attendees != []:
        icalendar_event.add('ATTENDEE', attendees)

    cal.add_component(icalendar_event)
    return cal
Example #16
0
    def get(self, request):
        items = Event.objects.filter(status='ACTIVE')

        academies = []
        ids = request.GET.get('academy', '')
        slugs = request.GET.get('academy_slug', '')

        ids = ids.split(",") if ids else []
        slugs = slugs.split(",") if slugs else []

        if ids:
            items = Event.objects.filter(academy__id__in=ids,
                                         status='ACTIVE').order_by('id')

        elif slugs:
            items = Event.objects.filter(academy__slug__in=slugs,
                                         status='ACTIVE').order_by('id')

        else:
            items = []

        if not ids and not slugs:
            raise ValidationException(
                "You need to specify at least one academy or academy_slug (comma separated) in the querystring"
            )

        if (Academy.objects.filter(id__in=ids).count() != len(ids) or
                Academy.objects.filter(slug__in=slugs).count() != len(slugs)):
            raise ValidationException("Some academy not exist")

        upcoming = request.GET.get('upcoming')
        if upcoming == 'true':
            now = timezone.now()
            items = items.filter(starting_at__gte=now)

        academies_repr = ical_academies_repr(ids=ids, slugs=slugs)

        calendar = iCalendar()
        calendar.add('prodid',
                     f'-//BreatheCode//Academy Events{academies_repr}//EN')
        calendar.add('X-WR-CALNAME', f'Academy - Events')
        calendar.add('X-WR-CALDESC', '')
        calendar.add('REFRESH-INTERVAL', 'PT15M')

        calendar.add('version', '2.0')

        for item in items:
            event = iEvent()

            if item.title:
                event.add('summary', item.title)

            if item.description:
                event.add('description', item.description)

            event.add('uid', f'breathecode_event_{item.id}')
            event.add('dtstart', item.starting_at)
            event.add('dtend', item.ending_at)
            event.add('dtstamp', item.created_at)

            if item.author and item.author.email:
                organizer = vCalAddress(f'MAILTO:{item.author.email}')

                if item.author.first_name and item.author.last_name:
                    organizer.params['cn'] = vText(f'{item.author.first_name} '
                                                   f'{item.author.last_name}')
                elif item.author.first_name:
                    organizer.params['cn'] = vText(item.author.first_name)
                elif item.author.last_name:
                    organizer.params['cn'] = vText(item.author.last_name)

                organizer.params['role'] = vText('OWNER')
                event['organizer'] = organizer

            if item.venue and (item.venue.country or item.venue.state or
                               item.venue.city or item.venue.street_address):
                value = ''

                if item.venue.street_address:
                    value = f'{value}{item.venue.street_address}, '

                if item.venue.city:
                    value = f'{value}{item.venue.city}, '

                if item.venue.state:
                    value = f'{value}{item.venue.state}, '

                if item.venue.country:
                    value = f'{value}{item.venue.country}'

                value = re.sub(', $', '', value)
                event['location'] = vText(value)

            calendar.add_component(event)

        calendar_text = calendar.to_ical()

        response = HttpResponse(calendar_text, content_type='text/calendar')
        response['Content-Disposition'] = 'attachment; filename="calendar.ics"'
        return response
Example #17
0
    def get(self, request):
        items = Cohort.objects.all()

        ids = request.GET.get('academy', '')
        slugs = request.GET.get('academy_slug', '')

        ids = ids.split(",") if ids else []
        slugs = slugs.split(",") if slugs else []

        if ids:
            items = Cohort.objects.filter(academy__id__in=ids).order_by('id')

        elif slugs:
            items = Cohort.objects.filter(
                academy__slug__in=slugs).order_by('id')

        else:
            items = []

        if not ids and not slugs:
            raise ValidationException(
                "You need to specify at least one academy or academy_slug (comma separated) in the querystring"
            )

        if (Academy.objects.filter(id__in=ids).count() != len(ids) or
                Academy.objects.filter(slug__in=slugs).count() != len(slugs)):
            raise ValidationException("Some academy not exist")

        items = items.exclude(stage='DELETED')

        upcoming = request.GET.get('upcoming')
        if upcoming == 'true':
            now = timezone.now()
            items = items.filter(kickoff_date__gte=now)

        academies_repr = ical_academies_repr(ids=ids, slugs=slugs)

        calendar = iCalendar()
        calendar.add('prodid',
                     f'-//BreatheCode//Academy Cohorts{academies_repr}//EN')
        calendar.add('X-WR-CALNAME', f'Academy - Cohorts')
        calendar.add('X-WR-CALDESC', '')
        calendar.add('REFRESH-INTERVAL', 'PT15M')

        calendar.add('version', '2.0')

        for item in items:
            event = iEvent()

            event.add('summary', item.name)
            event.add('uid', f'breathecode_cohort_{item.id}')
            event.add('dtstart', item.kickoff_date)

            if item.ending_date:
                event.add('dtend', item.ending_date)

            event.add('dtstamp', item.created_at)

            teacher = CohortUser.objects.filter(role='TEACHER',
                                                cohort__id=item.id).first()

            if teacher:
                organizer = vCalAddress(f'MAILTO:{teacher.user.email}')

                if teacher.user.first_name and teacher.user.last_name:
                    organizer.params['cn'] = vText(
                        f'{teacher.user.first_name} '
                        f'{teacher.user.last_name}')
                elif teacher.user.first_name:
                    organizer.params['cn'] = vText(teacher.user.first_name)
                elif teacher.user.last_name:
                    organizer.params['cn'] = vText(teacher.user.last_name)

                organizer.params['role'] = vText('OWNER')
                event['organizer'] = organizer

            location = item.academy.name

            if item.academy.website_url:
                location = f'{location} ({item.academy.website_url})'
            event['location'] = vText(item.academy.name)

            calendar.add_component(event)

        calendar_text = calendar.to_ical()

        response = HttpResponse(calendar_text, content_type='text/calendar')
        response['Content-Disposition'] = 'attachment; filename="calendar.ics"'
        return response
Example #18
0
def generate_icalendar_invite(event, invite_type='request'):
    # Generates an iCalendar invite from an event.
    assert invite_type in ['request', 'cancel']

    cal = iCalendar()
    cal.add('PRODID', '-//Nylas sync engine//nylas.com//')

    if invite_type in ['request', 'update']:
        cal.add('METHOD', 'REQUEST')
    elif invite_type == 'cancel':
        cal.add('METHOD', 'CANCEL')

    cal.add('VERSION', '2.0')
    cal.add('CALSCALE', 'GREGORIAN')

    icalendar_event = icalendar.Event()

    account = event.namespace.account
    organizer = icalendar.vCalAddress(u"MAILTO:{}".format(
        account.email_address))
    if account.name is not None:
        organizer.params['CN'] = account.name

    icalendar_event['organizer'] = organizer
    icalendar_event['sequence'] = str(event.sequence_number)
    icalendar_event['X-MICROSOFT-CDO-APPT-SEQUENCE'] = \
        icalendar_event['sequence']

    if invite_type == 'cancel':
        icalendar_event['status'] = 'CANCELLED'
    else:
        icalendar_event['status'] = 'CONFIRMED'

    icalendar_event['uid'] = u"{}@nylas.com".format(event.public_id)
    icalendar_event['description'] = event.description or ''
    icalendar_event['summary'] = event.title or ''
    icalendar_event['last-modified'] = serialize_datetime(event.updated_at)
    icalendar_event['dtstamp'] = icalendar_event['last-modified']
    icalendar_event['created'] = serialize_datetime(event.created_at)
    icalendar_event['dtstart'] = serialize_datetime(event.start)
    icalendar_event['dtend'] = serialize_datetime(event.end)
    icalendar_event['transp'] = 'OPAQUE' if event.busy else 'TRANSPARENT'
    icalendar_event['location'] = event.location or ''

    attendees = []
    for participant in event.participants:
        email = participant.get('email', None)

        # FIXME @karim: handle the case where a participant has no address.
        # We may have to patch the iCalendar module for this.
        assert email is not None and email != ""

        attendee = icalendar.vCalAddress(u"MAILTO:{}".format(email))
        name = participant.get('name', None)
        if name is not None:
            attendee.params['CN'] = name

        attendee.params['RSVP'] = 'TRUE'
        attendee.params['ROLE'] = 'REQ-PARTICIPANT'
        attendee.params['CUTYPE'] = 'INDIVIDUAL'

        status = participant.get('status', 'noreply')
        attendee.params['PARTSTAT'] = INVERTED_STATUS_MAP.get(status)
        attendees.append(attendee)

    if attendees != []:
        icalendar_event.add('ATTENDEE', attendees)

    cal.add_component(icalendar_event)
    return cal
Example #19
0
def generate_icalendar_invite(event, invite_type="request"):
    # Generates an iCalendar invite from an event.
    assert invite_type in ["request", "cancel"]

    cal = iCalendar()
    cal.add("PRODID", "-//Nylas sync engine//nylas.com//")

    if invite_type in ["request", "update"]:
        cal.add("METHOD", "REQUEST")
    elif invite_type == "cancel":
        cal.add("METHOD", "CANCEL")

    cal.add("VERSION", "2.0")
    cal.add("CALSCALE", "GREGORIAN")

    icalendar_event = icalendar.Event()

    account = event.namespace.account
    organizer = icalendar.vCalAddress(u"MAILTO:{}".format(
        account.email_address))
    if account.name is not None and account.name != "":
        organizer.params["CN"] = account.name

    icalendar_event["organizer"] = organizer
    icalendar_event["sequence"] = str(event.sequence_number)
    icalendar_event["X-MICROSOFT-CDO-APPT-SEQUENCE"] = icalendar_event[
        "sequence"]

    if invite_type == "cancel":
        icalendar_event["status"] = "CANCELLED"
    else:
        icalendar_event["status"] = "CONFIRMED"

    icalendar_event["uid"] = u"{}@nylas.com".format(event.public_id)
    icalendar_event["description"] = event.description or ""
    icalendar_event["summary"] = event.title or ""
    icalendar_event["last-modified"] = serialize_datetime(event.updated_at)
    icalendar_event["dtstamp"] = icalendar_event["last-modified"]
    icalendar_event["created"] = serialize_datetime(event.created_at)
    icalendar_event["dtstart"] = serialize_datetime(event.start)
    icalendar_event["dtend"] = serialize_datetime(event.end)
    icalendar_event["transp"] = "OPAQUE" if event.busy else "TRANSPARENT"
    icalendar_event["location"] = event.location or ""

    attendees = []
    for participant in event.participants:
        email = participant.get("email", None)

        # FIXME @karim: handle the case where a participant has no address.
        # We may have to patch the iCalendar module for this.
        assert email is not None and email != ""

        attendee = icalendar.vCalAddress(u"MAILTO:{}".format(email))
        name = participant.get("name", None)
        if name is not None:
            attendee.params["CN"] = name

        attendee.params["RSVP"] = "TRUE"
        attendee.params["ROLE"] = "REQ-PARTICIPANT"
        attendee.params["CUTYPE"] = "INDIVIDUAL"

        status = participant.get("status", "noreply")
        attendee.params["PARTSTAT"] = INVERTED_STATUS_MAP.get(status)
        attendees.append(attendee)

    if attendees != []:
        icalendar_event.add("ATTENDEE", attendees)

    cal.add_component(icalendar_event)
    return cal
Example #20
0
    def get(self, request):
        items = Cohort.objects.all()

        ids = request.GET.get('academy', '')
        slugs = request.GET.get('academy_slug', '')

        ids = ids.split(",") if ids else []
        slugs = slugs.split(",") if slugs else []

        if ids:
            items = Cohort.objects.filter(academy__id__in=ids).order_by('id')

        elif slugs:
            items = Cohort.objects.filter(
                academy__slug__in=slugs).order_by('id')

        else:
            items = []

        if not ids and not slugs:
            raise ValidationException(
                "You need to specify at least one academy or academy_slug (comma separated) in the querystring"
            )

        if (Academy.objects.filter(id__in=ids).count() != len(ids) or
                Academy.objects.filter(slug__in=slugs).count() != len(slugs)):
            raise ValidationException("Some academy not exist")

        items = items.exclude(stage='DELETED')

        upcoming = request.GET.get('upcoming')
        if upcoming == 'true':
            now = timezone.now()
            items = items.filter(kickoff_date__gte=now)

        academies_repr = ical_academies_repr(ids=ids, slugs=slugs)
        key = server_id()

        calendar = iCalendar()
        calendar.add(
            'prodid',
            f'-//BreatheCode//Academy Cohorts{academies_repr} {key}//EN')
        calendar.add('X-WR-CALNAME', f'Academy - Cohorts')
        calendar.add('X-WR-CALDESC', '')
        calendar.add('REFRESH-INTERVAL;VALUE=DURATION', 'PT15M')

        url = os.getenv('API_URL')
        if url:
            url = re.sub(r'/$', '', url) + '/v1/events/ical/cohorts'
            if ids or slugs:
                url = url + '?'

                if ids:
                    url = url + 'academy=' + ','.join(ids)

                if ids and slugs:
                    url = url + '&'

                if slugs:
                    url = url + 'academy_slug=' + ','.join(slugs)

            calendar.add('url', url)

        calendar.add('version', '2.0')

        for item in items:
            event = iEvent()
            event_first_day = iEvent()
            event_last_day = iEvent()
            has_last_day = False

            event.add('summary', item.name)
            event.add('uid', f'breathecode_cohort_{item.id}_{key}')
            event.add('dtstart', item.kickoff_date)

            timeslots = CohortTimeSlot.objects.filter(cohort__id=item.id)
            first_timeslot = timeslots.order_by('starting_at').first()

            if first_timeslot:
                event_first_day.add('summary', f'{item.name} - First day')
                event_first_day.add(
                    'uid', f'breathecode_cohort_{item.id}_first_{key}')
                event_first_day.add('dtstart', first_timeslot.starting_at)
                event_first_day.add('dtend', first_timeslot.ending_at)
                event_first_day.add('dtstamp', first_timeslot.created_at)

            if item.ending_date:
                event.add('dtend', item.ending_date)
                timeslots_datetime = []

                for timeslot in timeslots:
                    starting_at = timeslot.starting_at
                    ending_at = timeslot.ending_at
                    diff = ending_at - starting_at

                    if timeslot.recurrent:
                        ending_at = fix_datetime_weekday(item.ending_date,
                                                         ending_at,
                                                         prev=True)
                        starting_at = ending_at - diff

                    timeslots_datetime.append((starting_at, ending_at))

                last_timeslot = None

                if timeslots_datetime:
                    timeslots_datetime.sort(key=lambda x: x[1], reverse=True)
                    last_timeslot = timeslots_datetime[0]
                    has_last_day = True

                    event_last_day.add('summary', f'{item.name} - Last day')
                    event_last_day.add(
                        'uid', f'breathecode_cohort_{item.id}_last_{key}')
                    event_last_day.add('dtstart', last_timeslot[0])
                    event_last_day.add('dtend', last_timeslot[1])
                    event_last_day.add('dtstamp', item.created_at)

            event.add('dtstamp', item.created_at)

            teacher = CohortUser.objects.filter(role='TEACHER',
                                                cohort__id=item.id).first()

            if teacher:
                organizer = vCalAddress(f'MAILTO:{teacher.user.email}')

                if teacher.user.first_name and teacher.user.last_name:
                    organizer.params['cn'] = vText(
                        f'{teacher.user.first_name} '
                        f'{teacher.user.last_name}')
                elif teacher.user.first_name:
                    organizer.params['cn'] = vText(teacher.user.first_name)
                elif teacher.user.last_name:
                    organizer.params['cn'] = vText(teacher.user.last_name)

                organizer.params['role'] = vText('OWNER')
                event['organizer'] = organizer

                if first_timeslot:
                    event_first_day['organizer'] = organizer

                if has_last_day:
                    event_last_day['organizer'] = organizer

            location = item.academy.name

            if item.academy.website_url:
                location = f'{location} ({item.academy.website_url})'

            event['location'] = vText(item.academy.name)

            if first_timeslot:
                event_first_day['location'] = vText(item.academy.name)

            if has_last_day:
                event_last_day['location'] = vText(item.academy.name)

            if first_timeslot:
                calendar.add_component(event_first_day)
            calendar.add_component(event)

            if has_last_day:
                calendar.add_component(event_last_day)

        calendar_text = calendar.to_ical()

        response = HttpResponse(calendar_text, content_type='text/calendar')
        response['Content-Disposition'] = 'attachment; filename="calendar.ics"'
        return response
Example #21
0
    def get(self, request, user_id):
        items = Cohort.objects.all()

        if not User.objects.filter(id=user_id).count():
            raise ValidationException("Student not exist",
                                      404,
                                      slug='student-not-exist')

        cohort_ids = (CohortUser.objects.filter(user_id=user_id).values_list(
            'cohort_id', flat=True).exclude(cohort__stage='DELETED'))

        items = CohortTimeSlot.objects.filter(
            cohort__id__in=cohort_ids).order_by('id')
        items = items

        upcoming = request.GET.get('upcoming')
        if upcoming == 'true':
            now = timezone.now()
            items = items.filter(cohort__kickoff_date__gte=now)

        key = server_id()

        calendar = iCalendar()
        calendar.add(
            'prodid',
            f'-//BreatheCode//Student Schedule ({user_id}) {key}//EN')
        calendar.add('X-WR-CALNAME', f'Academy - Schedule')
        calendar.add('X-WR-CALDESC', '')
        calendar.add('REFRESH-INTERVAL;VALUE=DURATION', 'PT15M')

        url = os.getenv('API_URL')
        if url:
            url = re.sub(r'/$', '',
                         url) + '/v1/events/ical/student/' + str(user_id)
            calendar.add('url', url)

        calendar.add('version', '2.0')

        for item in items:
            event = iEvent()

            event.add('summary', item.cohort.name)
            event.add('uid', f'breathecode_cohort_time_slot_{item.id}_{key}')

            event.add('dtstart', item.starting_at)
            event.add('dtstamp', item.starting_at)

            until_date = item.cohort.ending_date

            if not until_date:
                until_date = timezone.make_aware(
                    datetime(year=2100,
                             month=12,
                             day=31,
                             hour=12,
                             minute=00,
                             second=00))

            if item.recurrent:
                event.add('rrule', {
                    'freq': item.recurrency_type,
                    'until': until_date
                })

            event.add('dtend', item.ending_at)

            teacher = CohortUser.objects.filter(
                role='TEACHER', cohort__id=item.cohort.id).first()

            if teacher:
                organizer = vCalAddress(f'MAILTO:{teacher.user.email}')

                if teacher.user.first_name and teacher.user.last_name:
                    organizer.params['cn'] = vText(
                        f'{teacher.user.first_name} '
                        f'{teacher.user.last_name}')
                elif teacher.user.first_name:
                    organizer.params['cn'] = vText(teacher.user.first_name)
                elif teacher.user.last_name:
                    organizer.params['cn'] = vText(teacher.user.last_name)

                organizer.params['role'] = vText('OWNER')
                event['organizer'] = organizer

            location = item.cohort.academy.name

            if item.cohort.academy.website_url:
                location = f'{location} ({item.cohort.academy.website_url})'
            event['location'] = vText(item.cohort.academy.name)

            calendar.add_component(event)

        calendar_text = calendar.to_ical()

        response = HttpResponse(calendar_text, content_type='text/calendar')
        response['Content-Disposition'] = 'attachment; filename="calendar.ics"'
        return response