def post(self): if self.request.get('event_url'): event_id = urls.get_event_id_from_url(self.request.get('event_url')) if not event_id: self.add_error('Unrecognized Facebook event URL') else: self.add_error('Missing Facebook event URL') self.errors_are_fatal() event_errors = [] event_warnings = [] try: fb_event = self.fbl.get(fb_api.LookupEvent, event_id, allow_cache=False) except fb_api.NoFetchedDataException: event_errors.append('Unable to fetch event. Please adjust your event privacy settings, or log in.') return if 'cover_info' not in fb_event['info']: event_errors.append('The event needs a cover photo.') start_time = dates.parse_fb_start_time(fb_event) if start_time < datetime.datetime.now() - datetime.timedelta(days=1): event_errors.append('Your event appears to be in the past. You should fix the date.') if 'name' not in fb_event['info']: event_errors.append('The event needs a name.') if 'description' not in fb_event['info']: event_errors.append('The event needs a description.') if not fb_events.is_event_public(fb_event): event_errors.append('The event privacy settings are too restricted.') classified_event = event_classifier.classified_event_from_fb_event(fb_event) classified_event.classify() auto_add_result = event_auto_classifier.is_auto_add_event(classified_event) if not auto_add_result[0]: event_warnings.append("The event wouldn't be automatically added. There weren't enough strong keywords for the system to identify it.") auto_notadd_result = event_auto_classifier.is_auto_notadd_event(classified_event, auto_add_result=auto_add_result) if auto_notadd_result[0]: event_warnings.append('The event appears to be the "wrong" kind of dance event for DanceDeets. Are you sure it is a street dance event?') location_info = event_locations.LocationInfo(fb_event) if not location_info.geocode: event_errors.append('Your event has no location. Please select a particular address, city, state, or country for this event.') elif 'place' not in fb_event['info']: event_warnings.append('For best results, your event should select a location from one of the venues Facebook suggests. DanceDeets believes your event is in %s' % location_info.final_city) self.display['event_warnings'] = event_warnings self.display['event_errors'] = event_errors self.display['event'] = fb_event # Add Event if self.request.get('force_add') or not event_errors: self.user.add_message('Your event "%s" has been added.' % fb_event['info']['name']) add_entities.add_update_event(fb_event, self.fbl, creating_uid=self.user.fb_uid, creating_method=eventdata.CM_USER) self.render_page()
def classify_events(fbl, pe_list, fb_list): results = [] for pe, fb_event in zip(pe_list, fb_list): if fb_event and fb_event['empty']: fb_event = None # Get these past events out of the way, saved, then continue. # Next time through this mapreduce, we shouldn't need to process them. if pe.set_past_event(fb_event): pe.put() if not fb_event: continue # Don't process events we've already looked at, or don't need to look at. # This doesn't happen with the mapreduce that pre-filters them out, # but it does happen when we scrape users potential events and throw them all in here. if not pe.should_look_at or pe.looked_at: continue classified_event = event_classifier.classified_event_from_fb_event(fb_event) classified_event.classify() auto_add_result = event_auto_classifier.is_auto_add_event(classified_event) if auto_add_result[0]: logging.info("Found event %s, looking up location", pe.fb_event_id) location_info = event_locations.LocationInfo(fb_event) result = '+%s\n' % '\t'.join(unicode(x) for x in (pe.fb_event_id, True, location_info.final_city, location_info.final_city is not None, location_info.fb_address, fb_event['info'].get('name', ''))) try: logging.info('VTFI %s: Adding event %s, due to pe-invite-ids: %s', pe.fb_event_id, pe.fb_event_id, pe.get_invite_uids()) add_entities.add_update_event(fb_event, fbl, visible_to_fb_uids=pe.get_invite_uids(), creating_method=eventdata.CM_AUTO) pe2 = potential_events.PotentialEvent.get_by_key_name(pe.fb_event_id) pe2.looked_at = True pe2.auto_looked_at = True pe2.put() # TODO(lambert): handle un-add-able events differently results.append(result) mr.increment('auto-added-dance-events') except fb_api.NoFetchedDataException as e: logging.error("Error adding event %s, no fetched data: %s", pe.fb_event_id, e) except add_entities.AddEventException as e: logging.warning("Error adding event %s, no fetched data: %s", pe.fb_event_id, e) auto_notadd_result = event_auto_classifier.is_auto_notadd_event(classified_event, auto_add_result=auto_add_result) if auto_notadd_result[0]: pe2 = potential_events.PotentialEvent.get_by_key_name(pe.fb_event_id) pe2.looked_at = True pe2.auto_looked_at = True pe2.put() result = '-%s\n' % '\t'.join(unicode(x) for x in (pe.fb_event_id, fb_event['info'].get('name', ''))) results.append(result) mr.increment('auto-notadded-dance-events') return results
def really_classify_events(fbl, new_pe_list, new_fb_list, allow_posting=True): if not new_pe_list: new_pe_list = [None] * len(new_fb_list) logging.info('Filtering out already-added events and others, have %s remaining events to run the classifier on', len(new_fb_list)) fb_event_ids = [x['info']['id'] for x in new_fb_list] fb_attending_maybe_list = fbl.get_multi(fb_api.LookupEventAttendingMaybe, fb_event_ids, allow_fail=True) results = [] for pe, fb_event, fb_event_attending_maybe in zip(new_pe_list, new_fb_list, fb_attending_maybe_list): event_id = fb_event['info']['id'] logging.info('Is Good Event By Text: %s: Checking...', event_id) classified_event = event_classifier.get_classified_event(fb_event) auto_add_result = event_auto_classifier.is_auto_add_event(classified_event) logging.info('Is Good Event By Text: %s: %s', event_id, auto_add_result) good_event = False if auto_add_result and auto_add_result[0]: good_event = auto_add_result[0] method = eventdata.CM_AUTO elif fb_event_attending_maybe: logging.info('Is Good Event By Attendees: %s: Checking...', event_id) good_event = event_attendee_classifier.is_good_event_by_attendees( fbl, fb_event, fb_event_attending_maybe=fb_event_attending_maybe, classified_event=classified_event ) logging.info('Is Good Event By Attendees: %s: %s', event_id, good_event) method = eventdata.CM_AUTO_ATTENDEE if good_event: result = '+%s\n' % '\t'.join((event_id, fb_event['info'].get('name', ''))) try: invite_ids = pe.get_invite_uids() if pe else [] logging.info('VTFI %s: Adding event %s, due to pe-invite-ids: %s', event_id, event_id, invite_ids) e = add_entities.add_update_event( fb_event, fbl, visible_to_fb_uids=invite_ids, creating_method=method, allow_posting=allow_posting ) pe2 = potential_events.PotentialEvent.get_by_key_name(event_id) pe2.looked_at = True pe2.auto_looked_at = True pe2.put() # TODO(lambert): handle un-add-able events differently results.append(result) mr.increment('auto-added-dance-events') if e.start_time < datetime.datetime.now(): mr.increment('auto-added-dance-events-past') mr.increment('auto-added-dance-events-past-eventid-%s' % event_id) else: mr.increment('auto-added-dance-events-future') except fb_api.NoFetchedDataException as e: logging.error("Error adding event %s, no fetched data: %s", event_id, e) except add_entities.AddEventException as e: logging.warning("Error adding event %s, no fetched data: %s", event_id, e) return results
def basic_match(fb_event): e = event_classifier.get_classified_event(fb_event) if not full_run: print e.processed_text.get_tokenized_text() if positive_classifier: result = event_auto_classifier.is_auto_add_event(e) else: result = event_auto_classifier.is_auto_notadd_event(e) # classified as good, but not supposed to be in the good set of ids: if result[0] and fb_event['info']['id'] not in training_data.good_ids: # false positive print fb_event['info']['id'], result if not full_run: print fb_event['info']['id'], result return result[0]
def post(self): if self.request.get('event_url'): event_id = urls.get_event_id_from_url( self.request.get('event_url')) if not event_id: self.add_error('Unrecognized Facebook event URL') else: self.add_error('Missing Facebook event URL') self.errors_are_fatal() event_errors = [] event_warnings = [] try: fb_event = self.fbl.get(fb_api.LookupEvent, event_id, allow_cache=False) except fb_api.NoFetchedDataException: event_errors.append( 'Unable to fetch event. Please adjust your event privacy settings, or log in.' ) return if 'cover_info' not in fb_event['info']: event_errors.append('The event needs a cover photo.') start_time = dates.parse_fb_start_time(fb_event) if start_time < datetime.datetime.now() - datetime.timedelta(days=1): event_errors.append( 'Your event appears to be in the past. You should fix the date.' ) if 'name' not in fb_event['info']: event_errors.append('The event needs a name.') if 'description' not in fb_event['info']: event_errors.append('The event needs a description.') if not fb_events.is_public(fb_event): event_errors.append( 'The event privacy settings are too restricted.') classified_event = event_classifier.classified_event_from_fb_event( fb_event) classified_event.classify() auto_add_result = event_auto_classifier.is_auto_add_event( classified_event) if not auto_add_result[0]: event_warnings.append( "The event wouldn't be automatically added. There weren't enough strong keywords for the system to identify it." ) auto_notadd_result = event_auto_classifier.is_auto_notadd_event( classified_event, auto_add_result=auto_add_result) if auto_notadd_result[0]: event_warnings.append( 'The event appears to be the "wrong" kind of dance event for DanceDeets. Are you sure it is a street dance event?' ) location_info = event_locations.LocationInfo(fb_event) if not location_info.geocode: event_errors.append( 'Your event has no location. Please select a particular address, city, state, or country for this event.' ) elif 'place' not in fb_event['info']: event_warnings.append( 'For best results, your event should select a location from one of the venues Facebook suggests. DanceDeets believes your event is in %s' % location_info.final_city) self.display['event_warnings'] = event_warnings self.display['event_errors'] = event_errors self.display['event'] = fb_event # Add Event if self.request.get('force_add') or not event_errors: self.user.add_message('Your event "%s" has been added.' % fb_event['info']['name']) add_entities.add_update_event(fb_event, self.fbl, creating_uid=self.user.fb_uid, creating_method=eventdata.CM_USER) self.render_page()
def get(self): event_id = None if self.request.get('event_url'): event_id = urls.get_event_id_from_url(self.request.get('event_url')) elif self.request.get('event_id'): event_id = self.request.get('event_id') self.finish_preload() fb_event = get_fb_event(self.fbl, event_id) if not fb_event: logging.error('No fetched data for %s, showing error page', event_id) return self.show_barebones_page(event_id, "No fetched data") e = eventdata.DBEvent.get_by_id(event_id) if not fb_events.is_public_ish(fb_event): if e: fb_event = e.fb_event else: self.add_error('Cannot add secret/closed events to dancedeets!') self.errors_are_fatal() owner_location = None if 'owner' in fb_event['info']: owner_id = fb_event['info']['owner']['id'] location = self._get_location(owner_id, fb_api.LookupProfile, 'profile' ) or self._get_location(owner_id, fb_api.LookupThingPage, 'info') if location: owner_location = event_locations.city_for_fb_location(location) self.display['owner_location'] = owner_location display_event = search.DisplayEvent.get_by_id(event_id) # Don't insert object until we're ready to save it... if e and e.creating_fb_uid: #STR_ID_MIGRATE creating_user = self.fbl.get(fb_api.LookupProfile, str(e.creating_fb_uid)) if creating_user.get('empty'): logging.warning( 'Have creating-user %s...but it is not publicly visible, so treating as None: %s', e.creating_fb_uid, creating_user ) creating_user = None else: creating_user = None potential_event = potential_events.make_potential_event_without_source(event_id) classified_event = event_classifier.get_classified_event(fb_event, potential_event.language) self.display['classified_event'] = classified_event dance_words_str = ', '.join(list(classified_event.dance_matches())) if classified_event.is_dance_event(): event_words_str = ', '.join(list(classified_event.event_matches())) else: event_words_str = 'NONE' self.display['classifier_dance_words'] = dance_words_str self.display['classifier_event_words'] = event_words_str self.display['creating_user'] = creating_user self.display['potential_event'] = potential_event self.display['display_event'] = display_event add_result = event_auto_classifier.is_auto_add_event(classified_event) notadd_result = event_auto_classifier.is_auto_notadd_event(classified_event, auto_add_result=add_result) auto_classified = '' if add_result[0]: auto_classified += 'add: %s.\n' % add_result[1] if notadd_result[0]: auto_classified += 'notadd: %s.\n' % notadd_result[1] self.display['auto_classified_types'] = auto_classified styles = categories.find_styles(fb_event) event_types = styles + categories.find_event_types(fb_event) self.display['auto_categorized_types'] = ', '.join(x.public_name for x in event_types) location_info = event_locations.LocationInfo(fb_event, db_event=e, debug=True) self.display['location_info'] = location_info if location_info.fb_address: fb_geocode = gmaps_api.lookup_address(location_info.fb_address) self.display['fb_geocoded_address'] = formatting.format_geocode(fb_geocode) else: self.display['fb_geocoded_address'] = '' city_name = 'Unknown' if location_info.geocode: city = cities_db.get_nearby_city(location_info.geocode.latlng(), country=location_info.geocode.country()) if city: city_name = city.display_name() self.display['ranking_city_name'] = city_name fb_event_attending_maybe = get_fb_event(self.fbl, event_id, lookup_type=fb_api.LookupEventAttendingMaybe) matcher = event_attendee_classifier.get_matcher(self.fbl, fb_event, fb_event_attending_maybe) # print '\n'.join(matcher.results) sorted_matches = sorted(matcher.matches, key=lambda x: -len(x.overlap_ids)) matched_overlap_ids = sorted_matches[0].overlap_ids if matcher.matches else [] self.display['auto_add_attendee_ids'] = sorted(matched_overlap_ids) self.display['overlap_results'] = ['%s %s: %s' % (x.top_n, x.name, x.reason) for x in sorted_matches] self.display['overlap_attendee_ids'] = sorted(matcher.overlap_ids) if matcher.matches: attendee_ids_to_admin_hash_and_event_ids = sorted_matches[0].get_attendee_lookups() self.display['attendee_ids_to_admin_hash_and_event_ids'] = attendee_ids_to_admin_hash_and_event_ids self.display['event'] = e self.display['event_id'] = event_id self.display['fb_event'] = fb_event self.jinja_env.filters['highlight_keywords'] = event_classifier.highlight_keywords self.display['track_analytics'] = False self.render_template('admin_edit')
def get(self): event_id = None if self.request.get('event_url'): event_id = urls.get_event_id_from_url(self.request.get('event_url')) elif self.request.get('event_id'): event_id = self.request.get('event_id') self.fbl.request(fb_api.LookupEvent, event_id, allow_cache=False) # DISABLE_ATTENDING # self.fbl.request(fb_api.LookupEventAttending, event_id, allow_cache=False) self.finish_preload() try: fb_event = self.fbl.fetched_data(fb_api.LookupEvent, event_id) # DISABLE_ATTENDING fb_event_attending = None # fb_event_attending = fbl.fetched_data(fb_api.LookupEventAttending, event_id) except fb_api.NoFetchedDataException: return self.show_barebones_page(event_id, "No fetched data") if not fb_events.is_public_ish(fb_event): self.add_error('Cannot add secret/closed events to dancedeets!') self.errors_are_fatal() owner_location = None if 'owner' in fb_event['info']: owner_id = fb_event['info']['owner']['id'] location = self._get_location(owner_id, fb_api.LookupProfile, 'profile') or self._get_location(owner_id, fb_api.LookupThingFeed, 'info') if location: owner_location = event_locations.city_for_fb_location(location) self.display['owner_location'] = owner_location display_event = search.DisplayEvent.get_by_id(event_id) # Don't insert object until we're ready to save it... e = eventdata.DBEvent.get_by_id(event_id) if e and e.creating_fb_uid: creating_user = self.fbl.get(fb_api.LookupUser, e.creating_fb_uid) else: creating_user = None potential_event = potential_events.make_potential_event_without_source(event_id, fb_event, fb_event_attending) classified_event = event_classifier.get_classified_event(fb_event, potential_event.language) self.display['classified_event'] = classified_event if classified_event.is_dance_event(): dance_words_str = ', '.join(list(classified_event.dance_matches())) event_words_str = ', '.join(list(classified_event.event_matches())) else: dance_words_str = 'NONE' event_words_str = 'NONE' self.display['classifier_dance_words'] = dance_words_str self.display['classifier_event_words'] = event_words_str self.display['creating_user'] = creating_user self.display['potential_event'] = potential_event self.display['display_event'] = display_event add_result = event_auto_classifier.is_auto_add_event(classified_event) notadd_result = event_auto_classifier.is_auto_notadd_event(classified_event, auto_add_result=add_result) auto_classified = '' if add_result[0]: auto_classified += 'add: %s.\n' % add_result[1] if notadd_result[0]: auto_classified += 'notadd: %s.\n' % notadd_result[1] self.display['auto_classified_types'] = auto_classified styles = categories.find_styles(fb_event) + categories.find_event_types(fb_event) self.display['auto_categorized_types'] = ', '.join(x.public_name for x in styles) location_info = event_locations.LocationInfo(fb_event, db_event=e, debug=True) self.display['location_info'] = location_info fb_geocode = gmaps_api.lookup_address(location_info.fb_address) self.display['fb_geocoded_address'] = formatting.format_geocode(fb_geocode) self.display['event'] = e self.display['event_id'] = event_id self.display['fb_event'] = fb_event self.jinja_env.filters['highlight_keywords'] = event_classifier.highlight_keywords self.display['track_analytics'] = False self.render_template('admin_edit')
def is_good_event_by_text(fb_event, classified_event): return event_auto_classifier.is_auto_add_event(classified_event)[0]
def classify_events(fbl, pe_list, fb_list): results = [] for pe, fb_event in zip(pe_list, fb_list): if fb_event and fb_event['empty']: fb_event = None # Get these past events out of the way, saved, then continue. # Next time through this mapreduce, we shouldn't need to process them. if pe.set_past_event(fb_event): pe.put() if not fb_event: continue # Don't process events we've already looked at, or don't need to look at. # This doesn't happen with the mapreduce that pre-filters them out, # but it does happen when we scrape users potential events and throw them all in here. if not pe.should_look_at or pe.looked_at: continue classified_event = event_classifier.classified_event_from_fb_event( fb_event) classified_event.classify() auto_add_result = event_auto_classifier.is_auto_add_event( classified_event) if auto_add_result[0]: logging.info("Found event %s, looking up location", pe.fb_event_id) location_info = event_locations.LocationInfo(fb_event) result = '+%s\n' % '\t'.join( unicode(x) for x in (pe.fb_event_id, location_info.exact_from_event, location_info.final_city, location_info.final_city is not None, location_info.fb_address, fb_event['info'].get('name', ''))) try: add_entities.add_update_event( fb_event, fbl, visible_to_fb_uids=pe.get_invite_uids(), creating_method=eventdata.CM_AUTO) pe2 = potential_events.PotentialEvent.get_by_key_name( pe.fb_event_id) pe2.looked_at = True pe2.auto_looked_at = True pe2.put() # TODO(lambert): handle un-add-able events differently results.append(result) mr.increment('auto-added-dance-events') except fb_api.NoFetchedDataException as e: logging.error("Error adding event %s, no fetched data: %s", pe.fb_event_id, e) except add_entities.AddEventException as e: logging.warning("Error adding event %s, no fetched data: %s", pe.fb_event_id, e) auto_notadd_result = event_auto_classifier.is_auto_notadd_event( classified_event, auto_add_result=auto_add_result) if auto_notadd_result[0]: pe2 = potential_events.PotentialEvent.get_by_key_name( pe.fb_event_id) pe2.looked_at = True pe2.auto_looked_at = True pe2.put() result = '-%s\n' % '\t'.join( unicode(x) for x in (pe.fb_event_id, fb_event['info'].get('name', ''))) results.append(result) mr.increment('auto-notadded-dance-events') return results