Example #1
0
def fbevent_to_event(fbevent, allow_place_import=True, save=False):
    e = Event()
    e.name = fbevent.get_field('name', '').strip()
    e.description = fbevent.get_field('description', '').strip()
    e.dtstart = fbevent.get_dtstart()
    e.dtend = fbevent.get_dtend()
    e.url = fbevent.get_field('website', '').strip()   # fairly sure this isn't part of a Graph API Event

    place_fbpage_id = fbevent.get_venue_id()
    if place_fbpage_id:
        linked_places = Place.objects.filter(fb_id=place_fbpage_id)
        if len(linked_places) > 0:
            if len(linked_places) > 1:
                pass
                # TODO: need an admin warning generated about data cleanup
            e.place = linked_places[0]

    if not e.place:
        new_place = fbevent.get_place(allow_import=allow_place_import)
        if new_place:
            new_place.listed = False    # don't automatically list any place we're creating dynamically here

            if save:
                # see if inner Location needs saved
                if new_place.location_id is None and new_place.location is not None:
                    new_place.location.save()
                    # this statment is necessary for Django's stupid inner model handling
                    new_place.location = new_place.location
                new_place.save()
            e.place = new_place
        else:
            # worst case, we get a location string to use as a primitive
            e.place_primitive = fbevent.get_field('location', '')
    try:
        im_url = fbevent.get_picture_url(size='large')
        e.image = imagefile_from_url(im_url)
    except IOError:
        # TODO: log network error
        pass

    if save:
        e.save()
    return e
Example #2
0
    def process_entry(self, entry, default_tz_str=None, start_filter=None):
        '''
        Process a single iCal entry, adding a new event or updating a current
        one if it is synced to this entry.

        If a synced event does exist, all fields will be overwritten with
        the current values of the iCal entry. The one exception is place.
        The place field will not be overwritten because it would often
        result reintroducing a place_primitive for an Event whose place was
        manually set.
        '''
        try:
            uid = unicode(entry['uid'])
            guid = u'%s;%s' % (self.feed_instance.url, uid)

            # see if we've already processed this record. if so, we're done
            try:
                event = EventMeta.objects.get(key='ical_synced_event', value=guid).event
                new_tracker = None
            except EventMeta.DoesNotExist:
                event = Event()
                new_tracker = EventMeta(key='ical_synced_event', value=guid)

            place_primitive = entry.get('location', '').strip()
            candidate_places = self.feed_instance.candidate_places.all()

            # Location processing -- need a candidate place to get anywhere
            if len(candidate_places) > 0:
                if not place_primitive and len(candidate_places) == 1:
                    # if there's no location specified, and there's one candidate place, safe to assume that's it
                    # TODO: need an explicit go-to primary_place
                    event.place = candidate_places[0]
                elif place_primitive and event.place is None:
                    # TODO: we're super conservative about not overwriting Place here. Introduce field-specific sync meta to do this right.
                    # quick and dirty location parsing (grab all chunks that could be separate entities)

                    # start off with the whole string
                    all_fields = [place_primitive.strip().lower()]
                    # split by commassemicolons, or dashes
                    for delim in (',', ';', '-'):
                        all_fields.append([s.strip().lower() for s in place_primitive.split(delim)])
                    # if parenthesis, grab the inside and outside content
                    p_match = re.match(r'^(.+)\((.+)\)', place_primitive)
                    if p_match:
                        all_fields.append(p_match.group(1).strip().lower())
                        all_fields.append(p_match.group(2).strip().lower())

                    # now, see if any candidate place name or street address is in these fields
                    for candidate in candidate_places:
                        if candidate.name.lower() in all_fields or \
                            candidate.location and candidate.location.address in all_fields:
                            event.place = candidate

            if event.place is None:
                event.place_primitive = place_primitive

            event.name = entry.get('summary', '').strip()
            event.dtstart = process_time(entry['dtstart'], default_tz_str)
            event.dtend = process_time(entry['dtend'], default_tz_str)
            event.description = entry.get('description', '').strip()

            # fitler out evnets before the start filter
            if start_filter is not None and event.dtstart < start_filter:
                    return None

            event.save()

            if self.feed_instance.owner:
                Role.objects.get_or_create(role_type='owner',
                                            organization=self.feed_instance.owner,
                                            event=event)

            if new_tracker:
                new_tracker.event = event
                new_tracker.save()

            return event
        except KeyError:
            # TODO: log message?
            return None