Esempio n. 1
0
    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
Esempio n. 2
0
    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
Esempio n. 3
0
    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})
Esempio n. 4
0
    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})