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
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