Beispiel #1
0
    def post(self):

        if not self.check_logged_in(self.min_perms):
            self.do_flickr_auth(self.min_perms)
            return

        if not self.validate_crumb(self.user, 'optin',
                                   self.request.get('crumb')):
            self.assign('error', 'bad_crumb')
            self.display('deny.html')
            return

        if not Membership.has_user_opted_out(self.user.nsid):
            self.assign('done', 1)
            self.display('allow.html')
            return

        if not self.request.get('confirm'):
            self.assign('error', 'no_confirm')
            self.display('allow.html')
            return

        Membership.opt_in(self.user.nsid)

        self.assign('done', 1)
        self.display('allow.html')
Beispiel #2
0
    def post(self):

        if not self.check_logged_in(self.min_perms):
            self.do_flickr_auth()
            return

        if not self.validate_crumb(self.user, 'optout',
                                   self.request.get('crumb')):
            self.assign('error', 'bad_crumb')
            self.display('deny.html')
            return

        if Membership.has_user_opted_out(self.user.nsid):
            self.assign('done', 1)
            self.display('deny.html')
            return

        if not self.request.get('confirm'):
            self.assign('error', 'no_confirm')
            self.display('deny.html')
            return

        Membership.opt_out(self.user.nsid)

        Suggestion.reject_all_pending_suggestions_for_owner(self.user.nsid)

        self.assign('done', 1)
        self.display('deny.html')
Beispiel #3
0
  def post (self) :
    
    if not self.check_logged_in(self.min_perms) :
      self.do_flickr_auth()
      return

    if not self.validate_crumb(self.user, 'optout', self.request.get('crumb')) :
      self.assign('error', 'bad_crumb');
      self.display('deny.html')
      return

    if Membership.has_user_opted_out(self.user.nsid) :
      self.assign('done', 1)
      self.display('deny.html')
      return
    
    if not self.request.get('confirm') :
      self.assign('error', 'no_confirm')
      self.display('deny.html')
      return

    Membership.opt_out(self.user.nsid)
    
    Suggestion.reject_all_pending_suggestions_for_owner(self.user.nsid)
    
    self.assign('done', 1)
    self.display('deny.html')
Beispiel #4
0
  def post (self) :

    if not self.check_logged_in(self.min_perms) :
      self.do_flickr_auth(self.min_perms)
      return

    if not self.validate_crumb(self.user, 'optin', self.request.get('crumb')) :
      self.assign('error', 'bad_crumb');
      self.display('deny.html')
      return

    if not Membership.has_user_opted_out(self.user.nsid) :
      self.assign('done', 1)
      self.display('allow.html')
      return
    
    if not self.request.get('confirm') :
      self.assign('error', 'no_confirm')
      self.display('allow.html')
      return

    Membership.opt_in(self.user.nsid)

    self.assign('done', 1)
    self.display('allow.html')    
Beispiel #5
0
  def check_logged_in (self, min_perms=None) :

    if not FlickrApp.check_logged_in(self, min_perms) :
      return False

    membership = Membership.retrieve(self.user.nsid)

    if not membership :
      membership = Membership.create(self.user.nsid)

    self.membership = membership
    self.has_opted_out = membership.opted_out

    return True
Beispiel #6
0
    def check_logged_in(self, min_perms=None):

        if not FlickrApp.check_logged_in(self, min_perms):
            return False

        membership = Membership.retrieve(self.user.nsid)

        if not membership:
            membership = Membership.create(self.user.nsid)

        self.membership = membership
        self.has_opted_out = membership.opted_out

        return True
Beispiel #7
0
  def get (self):

    if self.check_logged_in(self.min_perms) :
      pending = Suggestion.pending_suggestions_for_user(self.user.nsid)
      self.assign('pending_suggestions', pending.count())      
      self.assign('has_opted_out', Membership.has_user_opted_out(self.user.nsid))

    self.display('main.html')
Beispiel #8
0
  def get (self) :

    if not self.check_logged_in(self.min_perms) :
      self.do_flickr_auth(self.min_perms)
      return

    crumb = self.generate_crumb(self.user, "optin")
    self.assign("optin_crumb", crumb)

    self.assign('has_opted_out', Membership.has_user_opted_out(self.user.nsid))
    self.display("allow.html")
Beispiel #9
0
    def get(self):

        if not self.check_logged_in(self.min_perms):
            self.do_flickr_auth(self.min_perms)
            return

        crumb = self.generate_crumb(self.user, "optin")
        self.assign("optin_crumb", crumb)

        self.assign('has_opted_out',
                    Membership.has_user_opted_out(self.user.nsid))
        self.display("allow.html")
Beispiel #10
0
    def get(self, page=None):

        if not page:
            page = 1

        page = int(page)
        per_page = 10

        offset = (page - 1) * per_page

        res = dbFlickrUser.all().order("-created")
        count = res.count()

        users = res.fetch(per_page, offset)

        perms = dict([(v, k) for (k, v) in self.perms_map.iteritems()])

        for u in users:
            u.settings = Settings.get_settings_for_user(u.nsid)
            u.opted_out = Membership.has_user_opted_out(u.nsid)

            u.created_ymd = u.created.date
            u.perms_str = perms[u.perms]

            u.count_suggested_for = Suggestion.count_suggestions_for_user(
                u.nsid)

            u.count_suggested_by = Suggestion.count_suggestions_by_user(u.nsid)
            u.count_suggested_by_approved = Suggestion.count_suggestions_by_user(
                u.nsid, 2)
            u.count_suggested_by_rejected = Suggestion.count_suggestions_by_user(
                u.nsid, 3)

        pages = math.ceil(float(count) / float(per_page))

        if pages > page:
            self.assign("next", page + 1)

        if page > 1:
            self.assign("prev", page - 1)

        self.assign("count", count)
        self.assign("pages", pages)
        self.assign("page", page)
        self.assign("per_page", per_page)
        self.assign("offset", offset)

        self.assign("users", users)
        self.display("admin_users.html")
        return
Beispiel #11
0
    def get (self, page=None) :

        if not page :
            page = 1

        page = int(page)
        per_page = 10

        offset = (page - 1) * per_page
        
        res = dbFlickrUser.all().order("-created")
        count = res.count()
        
        users = res.fetch(per_page, offset)

        perms = dict([(v, k) for (k, v) in self.perms_map.iteritems()])
        
        for u in users :
            u.settings = Settings.get_settings_for_user(u.nsid)
            u.opted_out = Membership.has_user_opted_out(u.nsid)

            u.created_ymd = u.created.date
            u.perms_str = perms[ u.perms ]
            
            u.count_suggested_for = Suggestion.count_suggestions_for_user(u.nsid)
            
            u.count_suggested_by = Suggestion.count_suggestions_by_user(u.nsid)
            u.count_suggested_by_approved = Suggestion.count_suggestions_by_user(u.nsid, 2)
            u.count_suggested_by_rejected = Suggestion.count_suggestions_by_user(u.nsid, 3)            
            
        pages = math.ceil(float(count) / float(per_page))
        
        if pages > page :
            self.assign("next", page + 1)

        if page > 1 : 
            self.assign("prev", page - 1)
        
        self.assign("count", count)
        self.assign("pages", pages)        
        self.assign("page", page)
        self.assign("per_page", per_page)
        self.assign("offset", offset)
        
        self.assign("users", users)
        self.display("admin_users.html")
        return
Beispiel #12
0
  def get (self, context, filter) :

    min_perms = self.min_perms

    if self.request.get('perms') == 'write' :
      min_perms = 'write'
  
    if not self.check_logged_in(min_perms) :
      self.do_flickr_auth(min_perms)
      return

    # this is who I am ...

    if not context and self.request.get('user') :
      context = 'user'
      filter = self.request.get('user')
      
    self.assign('context', context)
    
    # Default, choose a user
    
    if not context :
      self.display('chooser.html')
      return

    # ok, what are we trying to do...

    other_user = None
    other_username = None
      
    if context == 'user' :

      other_username = filter
  
    elif context == 'photo' :

      # magic referer glue, mostly for the Brooklyn Museum
      
      headers = self.request.headers

      if headers.has_key('Referer') :
        
        u = urlparse.urlparse(headers['Referer'])

        m = re.match(r'(?:www\.)?flickr\.com', u[1])
        
        if not m :
          self.error(404)
          return

        m = re.match(r'/photos/(?:[^/]+)/(\d+)', u[2])
        
        if m :
          filter = m.groups()[0]
        else :
          self.error(404)          
          return
      
      # end of magic glue
      
      method = 'flickr.photos.getInfo'

      args = {
        'photo_id' : filter,
        'auth_token' : self.user.token,
        }

      ttl = 60 * 60
      
      rsp = self.proxy_api_call(method, args, ttl)
      
      if not rsp or not rsp.has_key('photo') :
        self.assign('error', 'no_photo')
      elif rsp['photo'].has_key('location') :
        self.assign('error', 'already_geotagged')
      else :
        
        # this is kind of dumb in the end...
        
        spr = {
          'id': rsp['photo']['id'],
          'owner' : rsp['photo']['owner']['nsid'],
          'secret' : rsp['photo']['secret'],
          'server' : rsp['photo']['server'],
          'farm' : rsp['photo']['farm'],
          'title' : rsp['photo']['title']['_content'],
          'tags' : '',
          'datetaken' : rsp['photo']['dates']['taken'],
          'ownername' : rsp['photo']['owner']['username'],
          }

        if rsp['photo'].has_key('tags') :
          tags = map( lambda t: t['_content'], rsp['photo']['tags']['tag'])
          spr['tags'] = ' '.join(tags)
        
        json = simplejson.dumps({ 'photo' : [spr] })
        self.assign("photo_json", json)
          
        other_username = rsp['photo']['owner']['username']

        self.assign("usernsid", rsp['photo']['owner']['nsid'])
        
    elif context == 'random' :
      noidea_crumb = self.generate_crumb(self.user, 'method=noidea')
      self.assign('noidea_crumb', noidea_crumb);
    else :
      self.assign('error', 'unknown_context')

    # do some sanity checking on the user

    self.assign("username", other_username)
    
    if other_username :
      other_user = User.get_user_by_username(other_username)
      
      if other_user :
      
        if Blocked.is_user_blocked(self.user.nsid, other_user.nsid) :
          self.assign('blocked', 1)
          
        elif Membership.has_user_opted_out(other_user.nsid) :
          self.assign('optedout', 1)

        else :

          pass
        
        self.assign("other_user", other_user)
        
        #
        
    # crumbs
      
    crumb = self.generate_crumb(self.user, 'method=suggest')
    self.assign('suggest_crumb', crumb)

    # go!
    
    self.display('chooser.html')
    return
Beispiel #13
0
    def run (self) :

        if self.request.get('page') != '' :
            page = self.request.get('page')

        page = 1

        if self.request.get('page') :
            page = self.request.get('page')
            
        per_page = max(int(random.random() * 100), 25)
    
        sort = ['date-posted-asc',
                'date-posted-desc',
                'date-taken-asc',
                'date-taken-desc',
                'interestingness-desc',
                'interestingness-asc',
                'relevance']
            
        random.shuffle(sort)
        random.shuffle(sort)
            
        contacts = ['ff', 'all']
        random.shuffle(contacts)

        prop = random.random()
        format = "%Y-%m-%d"
        stime = time.mktime(time.strptime('1970-01-01', format))
        etime = time.time()
        
        ptime = stime + prop * (etime - stime)
    
        date_taken  = time.strftime(format, time.localtime(ptime))

        method = 'flickr.photos.search'
        
        args = {
            'auth_token' : self.user.token,
            'user_id' : self.user.nsid,
            'contacts' : contacts[0],
            'has_geo' : 0,
            'per_page' : per_page,
            'page' : page,
            'sort' : sort[0],
            'max_taken_date' : "%s 00:00:00" % date_taken,
            'extras' : 'owner_name,date_taken,tags'
            }

        ttl = 60 * 10

        rsp = self.proxy_api_call(method, args, ttl)

        # wrong and dirty, please to fix
        self.format = 'json'
            
        if not rsp or rsp['stat'] != 'ok' :
            self.api_error(1, 'API call failed')
            return
        
        if rsp['photos']['total'] == 0 :
            self.api_error(2, 'Retry, no photos for query');
            return

        # these always time out on localhost...
        
        if self.request.host.startswith("localhost") :
            self.api_ok({'photos' : rsp['photos']})
            return
    
        skip_photos = []
        unknown_photos = []    
        filtered = []
        
        blocked_by = {}
        opted_out = {}

        # please to memcache all of this...
            
        gql = "SELECT * FROM dbSuggestion WHERE suggestor_nsid = :1"
        res = db.GqlQuery(gql, self.user.nsid)
        
        for ph in res.fetch(res.count()) :
            skip_photos.append(ph.photo_id)

        gql = "SELECT * FROM dbGamesRandom WHERE suggestor_nsid = :1"
        res = db.GqlQuery(gql, self.user.nsid)
    
        for ph in res.fetch(res.count()) :
            unknown_photos.append(ph.photo_id)
            
        for ph in rsp['photos']['photo'] :

            id = long(ph['id'])
            
            if id in skip_photos :
                continue

            if id in unknown_photos :
                continue

            # has the photo owner opted out

            photo_owner = ph['owner']
        
            if not opted_out.has_key(photo_owner) :
                has_opted_out = Membership.has_user_opted_out(photo_owner)
                opted_out[photo_owner] = has_opted_out

            if opted_out[photo_owner] :
                continue

            # has the photo owner blocked this user
        
            if not blocked_by.has_key(photo_owner) :
                is_blocked = Blocked.is_user_blocked(self.user.nsid, photo_owner)
                blocked_by[photo_owner] = is_blocked

            if blocked_by[photo_owner] :
                continue
        
            filtered.append(ph)

        if len(filtered) == 0 :
            self.api_error(3, 'Retry, no photos post filter');   
            return
        
        rsp['photos']['photo'] = filtered

        self.api_ok({'photos' : rsp['photos']})
        return
Beispiel #14
0
    def get(self, context, filter):

        min_perms = self.min_perms

        if self.request.get('perms') == 'write':
            min_perms = 'write'

        if not self.check_logged_in(min_perms):
            self.do_flickr_auth(min_perms)
            return

        # this is who I am ...

        if not context and self.request.get('user'):
            context = 'user'
            filter = self.request.get('user')

        self.assign('context', context)

        # Default, choose a user

        if not context:
            self.display('chooser.html')
            return

        # ok, what are we trying to do...

        other_user = None
        other_username = None

        if context == 'user':

            other_username = filter

        elif context == 'photo':

            # magic referer glue, mostly for the Brooklyn Museum

            headers = self.request.headers

            if headers.has_key('Referer'):

                u = urlparse.urlparse(headers['Referer'])

                m = re.match(r'(?:www\.)?flickr\.com', u[1])

                if not m:
                    self.error(404)
                    return

                m = re.match(r'/photos/(?:[^/]+)/(\d+)', u[2])

                if m:
                    filter = m.groups()[0]
                else:
                    self.error(404)
                    return

            # end of magic glue

            method = 'flickr.photos.getInfo'

            args = {
                'photo_id': filter,
                'auth_token': self.user.token,
            }

            ttl = 60 * 60

            rsp = self.proxy_api_call(method, args, ttl)

            if not rsp or not rsp.has_key('photo'):
                self.assign('error', 'no_photo')
            elif rsp['photo'].has_key('location'):
                self.assign('error', 'already_geotagged')
            else:

                # this is kind of dumb in the end...

                spr = {
                    'id': rsp['photo']['id'],
                    'owner': rsp['photo']['owner']['nsid'],
                    'secret': rsp['photo']['secret'],
                    'server': rsp['photo']['server'],
                    'farm': rsp['photo']['farm'],
                    'title': rsp['photo']['title']['_content'],
                    'tags': '',
                    'datetaken': rsp['photo']['dates']['taken'],
                    'ownername': rsp['photo']['owner']['username'],
                }

                if rsp['photo'].has_key('tags'):
                    tags = map(lambda t: t['_content'],
                               rsp['photo']['tags']['tag'])
                    spr['tags'] = ' '.join(tags)

                json = simplejson.dumps({'photo': [spr]})
                self.assign("photo_json", json)

                other_username = rsp['photo']['owner']['username']

                self.assign("usernsid", rsp['photo']['owner']['nsid'])

        elif context == 'random':
            noidea_crumb = self.generate_crumb(self.user, 'method=noidea')
            self.assign('noidea_crumb', noidea_crumb)
        else:
            self.assign('error', 'unknown_context')

        # do some sanity checking on the user

        self.assign("username", other_username)

        if other_username:
            other_user = User.get_user_by_username(other_username)

            if other_user:

                if Blocked.is_user_blocked(self.user.nsid, other_user.nsid):
                    self.assign('blocked', 1)

                elif Membership.has_user_opted_out(other_user.nsid):
                    self.assign('optedout', 1)

                else:

                    pass

                self.assign("other_user", other_user)

                #

        # crumbs

        crumb = self.generate_crumb(self.user, 'method=suggest')
        self.assign('suggest_crumb', crumb)

        # go!

        self.display('chooser.html')
        return
Beispiel #15
0
    def run(self):

        if self.request.get('page') != '':
            page = self.request.get('page')

        page = 1

        if self.request.get('page'):
            page = self.request.get('page')

        per_page = max(int(random.random() * 100), 25)

        sort = [
            'date-posted-asc', 'date-posted-desc', 'date-taken-asc',
            'date-taken-desc', 'interestingness-desc', 'interestingness-asc',
            'relevance'
        ]

        random.shuffle(sort)
        random.shuffle(sort)

        contacts = ['ff', 'all']
        random.shuffle(contacts)

        prop = random.random()
        format = "%Y-%m-%d"
        stime = time.mktime(time.strptime('1970-01-01', format))
        etime = time.time()

        ptime = stime + prop * (etime - stime)

        date_taken = time.strftime(format, time.localtime(ptime))

        method = 'flickr.photos.search'

        args = {
            'auth_token': self.user.token,
            'user_id': self.user.nsid,
            'contacts': contacts[0],
            'has_geo': 0,
            'per_page': per_page,
            'page': page,
            'sort': sort[0],
            'max_taken_date': "%s 00:00:00" % date_taken,
            'extras': 'owner_name,date_taken,tags'
        }

        ttl = 60 * 10

        rsp = self.proxy_api_call(method, args, ttl)

        # wrong and dirty, please to fix
        self.format = 'json'

        if not rsp or rsp['stat'] != 'ok':
            self.api_error(1, 'API call failed')
            return

        if rsp['photos']['total'] == 0:
            self.api_error(2, 'Retry, no photos for query')
            return

        # these always time out on localhost...

        if self.request.host.startswith("localhost"):
            self.api_ok({'photos': rsp['photos']})
            return

        skip_photos = []
        unknown_photos = []
        filtered = []

        blocked_by = {}
        opted_out = {}

        # please to memcache all of this...

        gql = "SELECT * FROM dbSuggestion WHERE suggestor_nsid = :1"
        res = db.GqlQuery(gql, self.user.nsid)

        for ph in res.fetch(res.count()):
            skip_photos.append(ph.photo_id)

        gql = "SELECT * FROM dbGamesRandom WHERE suggestor_nsid = :1"
        res = db.GqlQuery(gql, self.user.nsid)

        for ph in res.fetch(res.count()):
            unknown_photos.append(ph.photo_id)

        for ph in rsp['photos']['photo']:

            id = long(ph['id'])

            if id in skip_photos:
                continue

            if id in unknown_photos:
                continue

            # has the photo owner opted out

            photo_owner = ph['owner']

            if not opted_out.has_key(photo_owner):
                has_opted_out = Membership.has_user_opted_out(photo_owner)
                opted_out[photo_owner] = has_opted_out

            if opted_out[photo_owner]:
                continue

            # has the photo owner blocked this user

            if not blocked_by.has_key(photo_owner):
                is_blocked = Blocked.is_user_blocked(self.user.nsid,
                                                     photo_owner)
                blocked_by[photo_owner] = is_blocked

            if blocked_by[photo_owner]:
                continue

            filtered.append(ph)

        if len(filtered) == 0:
            self.api_error(3, 'Retry, no photos post filter')
            return

        rsp['photos']['photo'] = filtered

        self.api_ok({'photos': rsp['photos']})
        return
Beispiel #16
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
Beispiel #17
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