def run (self) : required = ('crumb', 'photo_id', 'owner_id', 'latitude', 'longitude') if not self.ensure_args(required) : return # # Context # geo_context = self.request.get('geo_context') if geo_context : geo_context = int(geo_context) if not geo_context in (0, 1, 2) : self.api_error(3, 'Not a valid geo context') return else : geo_context = 0 # # # if not self.ensure_crumb('method=suggest') : return owner_nsid = self.request.get('owner_id') photo_id = long(self.request.get('photo_id')) # # Blocked? # if Blocked.is_user_blocked(self.user.nsid, owner_nsid) : self.api_error(3, 'You do not have permission to suggest a location for this photo.') return # # Opted out # if Membership.has_user_opted_out(owner_nsid) : self.api_error(4, 'You do not have permission to suggest a location for this photo.') return # # Already suggested? # This query will probably need to be less blunt # if Suggestion.has_pending_suggestions(photo_id, self.user.nsid) : self.api_error(999, 'Already suggested') return lat = float(self.request.get('latitude')) lon = float(self.request.get('longitude')) acc = int(self.request.get('accuracy')) woeid = self.request.get('woeid') if woeid != '' : woeid = int(woeid) # # grab the photo # method = 'flickr.photos.getInfo' args = { 'photo_id' : photo_id, } rsp = self.proxy_api_call(method, args) # # Recordify! # owner_nsid = self.request.get('owner_id') args = { 'photo_id' : photo_id, 'owner_id' : owner_nsid, 'latitude' : lat, 'longitude' : lon, 'accuracy' : acc, 'woeid' : woeid, 'suggestor_id' : self.user.nsid, 'suggestor_name' : self.user.username, 'context' : geo_context, } s = Suggestion.create(args) if not s : msg = "failed to add suggestion for %s" % str(args) self.log(msg, 'warning') self.api_error(2, 'There was a problem recording your suggestion.') return # # Notifications? # review_link = "%s/review/%s" % (self.request.host_url, photo_id) settings = Settings.get_settings_for_user(owner_nsid) if settings and settings.email_notifications : to_addr = settings.email_address subject = 'You have a new suggestion for one of your photos!' body = """Greetings from the Suggestify project! Flickr user %s has suggested a location for your photo "%s". To approve or reject this suggestion, follow the link below: %s (If you're tired of getting these email messages you can always disable email notifications by going to: %s/settings/notifications) Cheers, """ % (self.user.username, rsp['photo']['title']['_content'], review_link, self.request.host_url) Email.send(to=to_addr, subject=subject, body=body) # # Post comment to the photo on Flickr? # send_comment = False if config.config['notifications_flickr_comments'] and settings.comment_notifications : send_comment = True if self.user.perms != 2: send_comment = False self.log('not setting a comment; insufficient perms', 'info') if send_comment: # Do not display the lat,lon in the commment since they # are public for anyone to see. Only display WOE ID and name, # if we can find them. is_at = "" if woeid : method = 'flickr.places.getInfo' args = {'woe_id' : woeid} rsp = self.proxy_api_call(method, args) if rsp and rsp['stat'] == 'ok' and rsp.has_key('place') : # note the trailing space at the end is_at = """I think it was taken somewhere around: <a href="http://www.flickr.com/places/%s">%s</a>. """ % (woeid, rsp['place']['name']) # build the comment comment = """I've suggested a location for this photo over at the <a href="http://suggestify.appspot.com">Suggestify</a> project. %sYou can see the exact location and approve or reject this suggestion by following this link: <a href="%s">%s</a> If you do approve the suggestion then your photo will be automagically geotagged! (You can also <a href="http://suggestify.appspot.com/settings">configure Suggestify</a> to stop these notifications from being added to your photos or to prevent any of your photos from being "suggestified" at all in the future.) """ % (is_at, review_link, review_link) # post the comment method = 'flickr.photos.comments.addComment' args = { 'photo_id' : photo_id, 'comment_text' : comment, 'auth_token' : self.user.token, } rsp = self.api_call(method, args) # what is the right way to notify the user that # suggestion was recorded by the comment was not? if rsp and rsp['stat'] == 'ok': comment_id = rsp['comment']['id'] s.comment_id = comment_id s.put() else : msg = 'Failed to post review comment: ' if rsp : msg += rsp['message'] self.log(msg, 'warning') # # OKAY! # self.api_ok() return
def run (self) : required = ('crumb', 'photo_id', 'owner_id', 'latitude', 'longitude') if not self.ensure_args(required) : return # # Context # geo_context = self.request.get('geo_context') if geo_context : geo_context = int(geo_context) if not geo_context in (0, 1, 2) : self.api_error(3, 'Not a valid geo context') return else : geo_context = 0 # # # if not self.ensure_crumb('method=suggest') : return owner_nsid = self.request.get('owner_id') photo_id = long(self.request.get('photo_id')) # # Blocked? # if Blocked.is_user_blocked(self.user.nsid, owner_nsid) : self.api_error(3, 'You do not have permission to suggest a location for this photo.') return # # Opted out # if Membership.has_user_opted_out(owner_nsid) : self.api_error(4, 'You do not have permission to suggest a location for this photo.') return # # Already suggested? # This query will probably need to be less blunt # if Suggestion.has_pending_suggestions(photo_id, self.user.nsid) : self.api_error(999, 'Already suggested') return lat = float(self.request.get('latitude')) lon = float(self.request.get('longitude')) acc = int(self.request.get('accuracy')) woeid = self.request.get('woeid') if woeid != '' : woeid = int(woeid) # # grab the photo # method = 'flickr.photos.getInfo' args = { 'photo_id' : photo_id, } rsp = self.proxy_api_call(method, args) # # Recordify! # owner_nsid = self.request.get('owner_id') args = { 'photo_id' : photo_id, 'owner_id' : owner_nsid, 'latitude' : lat, 'longitude' : lon, 'accuracy' : acc, 'woeid' : woeid, 'suggestor_id' : self.user.nsid, 'suggestor_name' : self.user.username, 'context' : geo_context, } s = Suggestion.create(args) if not s : msg = "failed to add suggestion for %s" % str(args) self.log(msg, 'warning') self.api_error(2, 'There was a problem recording your suggestion.') return # # Notifications? # review_link = "%s/review/%s" % (self.request.host_url, photo_id) settings = Settings.get_settings_for_user(owner_nsid) if settings and settings.email_notifications : to_addr = settings.email_address subject = 'You have a new suggestion for one of your photos!' body = """Greetings from the Suggestify project! Flickr user %s has suggested a location for your photo "%s". To approve or reject this suggestion, follow the link below: %s (If you're tired of getting these email messages you can always disable email notifications by going to: %s/settings/notifications) Cheers, """ % (self.user.username, rsp['photo']['title']['_content'], review_link, self.request.host_url) Email.send(to=to_addr, subject=subject, body=body) # # Post comment to the photo on Flickr? # if config.config['notifications_flickr_comments'] and settings.comment_notifications : # Do not display the lat,lon in the commment since they # are public for anyone to see. Only display WOE ID and name, # if we can find them. is_at = "" if woeid : method = 'flickr.places.getInfo' args = {'woe_id' : woeid} rsp = self.proxy_api_call(method, args) if rsp and rsp['stat'] == 'ok' and rsp.has_key('place') : # note the trailing space at the end is_at = """I think it was taken somewhere around: <a href="http://www.flickr.com/places/%s">%s</a>. """ % (woeid, rsp['place']['name']) # build the comment comment = """I've suggested a location for this photo over at the <a href="http://suggestify.appspot.com">Suggestify</a> project. %sYou can see the exact location and approve or reject this suggestion by following this link: <a href="%s">%s</a> If you do approve the suggestion then your photo will be automagically geotagged! (You can also <a href="http://suggestify.appspot.com/settings">configure Suggestify</a> to stop these notifications from being added to your photos or to prevent any of your photos from being "suggestified" at all in the future.) """ % (is_at, review_link, review_link) # post the comment method = 'flickr.photos.comments.addComment' args = { 'photo_id' : photo_id, 'comment_text' : comment, 'auth_token' : self.user.token, } rsp = self.api_call(method, args) # what is the right way to notify the user that # suggestion was recorded by the comment was not? if rsp and rsp['stat'] : comment_id = rsp['comment']['id'] s.comment_id = comment_id s.put() else : msg = 'Failed to post review comment: ' if rsp : msg += rsp['message'] self.log(msg, 'warning') # # OKAY! # self.api_ok() return
def post(self, uuid): is_api = True if not self.ensure_config(uuid): self.error('invalid_config', is_api) return if not self.check_logged_in(self.min_perms): self.do_flickr_auth(self.min_perms) return if not self.validate_crumb(self.user, 'method=approve', self.request.get('crumb')): self.error('invalid_perms', is_api) return False # # args/sig validation # req_args = ('photo_id', 'lat', 'lon', 'acc', 'context', '_s') sig_args = ['photo_id', 'lat', 'lon', 'acc', 'context', 'woeid'] if not self.ensure_required_args(req_args): self.error('missing_args', is_api) return if not self.ensure_valid_args(req_args): self.error('invalid_args', is_api) return if not self.ensure_robot_sig(sig_args, self.request.get('_s')): self.error('invalid_sig') return args = { 'photo_id': suggestion.photo_id, 'auth_token': self.user.token, 'check_response': 1, } rsp = self.api_call('flickr.photos.getInfo', args) if not rsp: self.error('invalid_photo') return if rsp['photo'].has_key('location'): Suggestion.reject_all_pending_suggestions_for_photo( suggestion.photo_id) self.error('already_geotagged') return mock = self.generate_mock_suggestion() if not mock: self.error('invalid suggestion') return suggestion = Suggestion.create(mock) # # this is all copy/pasted out of API/Approve <-- it should probably # go in a "library" but the whole thing gets wrapped up in boring # object/globals/self nonsense and the fact that there aren't any # in Suggestion.py # args = { 'photo_id': suggestion.photo_id, 'lat': suggestion.latitude, 'lon': suggestion.longitude, 'accuracy': suggestion.accuracy, 'auth_token': self.user.token, } geo_context = self.request.get('geo_context') if geo_context and int(geo_context) != 0: args['context'] = geo_context rsp = self.api_call('flickr.photos.geo.setLocation', args) if not rsp: self.error('Failed to set location: Flickr API call failed', is_api) return if rsp['stat'] != 'ok': self.error( 'Failed to set location: %s (%s)' % (rsp['message'], rsp['code']), is_api) return geoperms = int(self.request.get('geo_perms')) default = self.default_geoperms() if geoperms != default: method = 'flickr.photos.geo.setPerms' args = { 'photo_id': suggestion.photo_id, 'auth_token': self.user.token, 'is_public': 0, 'is_contact': 0, 'is_family': 0, 'is_friend': 0 } if geoperms == 1: args['is_public'] = 1 elif geoperms == 2: args['is_contact'] = 1 elif geoperms == 3: args['is_friend'] = 1 args['is_family'] = 1 elif geoperms == 4: args['is_friend'] = 1 elif geoperms == 5: args['is_family'] = 1 else: pass rsp = self.api_call('flickr.photos.geo.setPerms', args) if rsp['stat'] != 'ok': msg = 'Failed to set location: %s (%s)' % (rsp['message'], rsp['code']) self.log(msg, 'warning') pass if geoperms == 1 and suggestion.suggestor_nsid != self.user.nsid: suggested_by = suggestion.suggestor_nsid suggestor = User.get_user_by_nsid(suggestion.suggestor_nsid) if suggestor and suggestor.path_alias: suggested_by = suggestor.path_alias tags = "geo:suggestedby=%s" % suggested_by args = { 'photo_id': suggestion.photo_id, 'tags': tags, 'auth_token': self.user.token, 'check_response': 1, } rsp = self.api_call('flickr.photos.addTags', args) # sudo make me a preference if self.user.nsid == 'brooklyn museum': suggested_date = suggestion.date_create suggestor_name = suggestor.username suggestor_url = 'http://www.flickr.com/photos/%s' % suggestor.nsid if suggestor.path_alias != '': suggestor_url = 'http://www.flickr.com/photos/%s' % suggestor.path_alias # Note: don't lookup/display the place name for the WOE ID # until it's possible to do corrections on approval. comment = """On %s, <a href="%s">%s</a> suggested where this photo was taken, and they were right! """ % (suggested_date, suggestor_url, suggestor_name) method = 'flickr.photos.comments.addComment' comments_args = { 'photo_id': photo_id, 'comment_text': comment, 'auth_token': self.user.token, } rsp = self.api_call(method, args) # Suggestion.approve_suggestion(suggestion) Suggestion.reject_all_pending_suggestions_for_photo( suggestion.photo_id) # photo_owner = self.user.nsid if self.user.path_alias: photo_owner = self.user.path_alias photo_url = "http://www.flickr.com/photos/%s/%s" % ( photo_owner, suggestion.photo_id) return self.ok({'photo_url': photo_url})
def post (self, uuid) : is_api = True if not self.ensure_config(uuid) : self.error('invalid_config', is_api) return if not self.check_logged_in(self.min_perms) : self.do_flickr_auth(self.min_perms) return if not self.validate_crumb(self.user, 'method=approve', self.request.get('crumb')) : self.error('invalid_perms', is_api) return False # # args/sig validation # req_args = ('photo_id', 'lat', 'lon', 'acc', 'context', '_s') sig_args = ['photo_id', 'lat', 'lon', 'acc', 'context', 'woeid'] if not self.ensure_required_args(req_args) : self.error('missing_args', is_api) return if not self.ensure_valid_args(req_args) : self.error('invalid_args', is_api) return if not self.ensure_robot_sig(sig_args, self.request.get('_s')) : self.error('invalid_sig') return args = { 'photo_id' : suggestion.photo_id, 'auth_token' : self.user.token, 'check_response' : 1, } rsp = self.api_call('flickr.photos.getInfo', args) if not rsp : self.error('invalid_photo') return if rsp['photo'].has_key('location') : Suggestion.reject_all_pending_suggestions_for_photo(suggestion.photo_id) self.error('already_geotagged') return mock = self.generate_mock_suggestion() if not mock : self.error('invalid suggestion') return suggestion = Suggestion.create(mock) # # this is all copy/pasted out of API/Approve <-- it should probably # go in a "library" but the whole thing gets wrapped up in boring # object/globals/self nonsense and the fact that there aren't any # in Suggestion.py # args = {'photo_id' : suggestion.photo_id, 'lat' : suggestion.latitude, 'lon' : suggestion.longitude, 'accuracy' : suggestion.accuracy, 'auth_token' : self.user.token, } geo_context = self.request.get('geo_context') if geo_context and int(geo_context) != 0 : args['context'] = geo_context rsp = self.api_call('flickr.photos.geo.setLocation', args) if not rsp : self.error('Failed to set location: Flickr API call failed', is_api) return if rsp['stat'] != 'ok' : self.error('Failed to set location: %s (%s)' % (rsp['message'], rsp['code']), is_api) return geoperms = int(self.request.get('geo_perms')) default = self.default_geoperms() if geoperms != default : method = 'flickr.photos.geo.setPerms' args = { 'photo_id' : suggestion.photo_id, 'auth_token' : self.user.token, 'is_public' : 0, 'is_contact' : 0, 'is_family' : 0, 'is_friend' : 0 } if geoperms == 1 : args['is_public'] = 1 elif geoperms == 2 : args['is_contact'] = 1 elif geoperms == 3 : args['is_friend'] = 1 args['is_family'] = 1 elif geoperms == 4 : args['is_friend'] = 1 elif geoperms == 5 : args['is_family'] = 1 else : pass rsp = self.api_call('flickr.photos.geo.setPerms', args) if rsp['stat'] != 'ok' : msg = 'Failed to set location: %s (%s)' % (rsp['message'], rsp['code']) self.log(msg, 'warning') pass if geoperms == 1 and suggestion.suggestor_nsid != self.user.nsid : suggested_by = suggestion.suggestor_nsid suggestor = User.get_user_by_nsid(suggestion.suggestor_nsid) if suggestor and suggestor.path_alias : suggested_by = suggestor.path_alias tags = "geo:suggestedby=%s" % suggested_by args = { 'photo_id' : suggestion.photo_id, 'tags' : tags, 'auth_token' : self.user.token, 'check_response' : 1, } rsp = self.api_call('flickr.photos.addTags', args) # sudo make me a preference if self.user.nsid == 'brooklyn museum' : suggested_date = suggestion.date_create suggestor_name = suggestor.username suggestor_url = 'http://www.flickr.com/photos/%s' % suggestor.nsid if suggestor.path_alias != '' : suggestor_url = 'http://www.flickr.com/photos/%s' % suggestor.path_alias # Note: don't lookup/display the place name for the WOE ID # until it's possible to do corrections on approval. comment = """On %s, <a href="%s">%s</a> suggested where this photo was taken, and they were right! """ % (suggested_date, suggestor_url, suggestor_name) method = 'flickr.photos.comments.addComment' comments_args = { 'photo_id' : photo_id, 'comment_text' : comment, 'auth_token' : self.user.token, } rsp = self.api_call(method, args) # Suggestion.approve_suggestion(suggestion) Suggestion.reject_all_pending_suggestions_for_photo(suggestion.photo_id) # photo_owner = self.user.nsid if self.user.path_alias : photo_owner = self.user.path_alias photo_url = "http://www.flickr.com/photos/%s/%s" % (photo_owner, suggestion.photo_id) return self.ok({'photo_url' : photo_url})