def _iter_recent(self, progress_callback=None): """Get the recently updated photos.""" page, pages = 1, 1 while page <= pages: resp = self.proxy.photos_recentlyUpdated( page=page, min_date=self.last_update + 1, extras=', '.join(( 'date_upload', 'last_update', 'o_dims', 'original_format', 'url_o', ))) photos = resp.find('photos') if photos: for photo in photos.findall('photo'): yield photo.attrib elif photos is None: raise FlickrError('No photos in server response.') else: break pages = int(photos.get('pages')) if progress_callback: progress_callback('photos', (page, pages)) page = int(photos.get('page')) + 1
def get_proxy(key=API_KEY, secret=API_SECRET, wait_callback=None): """Get a web service proxy to Flickr.""" # Setup the API proxy. perms = 'write' proxy = flickrapi.FlickrAPI(key, secret, format='etree') try: # Authorize. auth_response = proxy.get_token_part_one(perms=perms) except ExpatError: # FlickrAPI chokes on non-XML responses. raise FlickrError('Non-XML response from Flickr') while True: try: if proxy.get_token_part_two(auth_response): break except FlickrError as e: # Wait for frob confirmation. frob_ok = filter(lambda x: x.startswith('Error: 108'), e) if frob_ok and wait_callback \ and not wait_callback(proxy, perms, *auth_response): continue raise return proxy
def parse_xmlnode(self, rest_xml): '''Parses a REST XML response from Flickr into an XMLNode object.''' rsp = XMLNode.parse(rest_xml, store_xml=True) if rsp['stat'] == 'ok': return rsp err = rsp.err[0] raise FlickrError(u'Error: %(code)s: %(msg)s' % err)
def parse_xmlnode(self, rest_xml): u'''Parses a REST XML response from Flickr into an XMLNode object.''' #$NON-NLS-1$ rsp = XMLNode.parse(rest_xml, store_xml=True) if rsp[u'stat'] == u'ok' or not self.fail_on_error: #$NON-NLS-2$ #$NON-NLS-1$ return rsp err = rsp.err[0] raise FlickrError(u'Error: %(code)s: %(msg)s' % err) #$NON-NLS-1$
def parse_etree(self, rest_xml): u'''Parses a REST XML response from Flickr into an ElementTree object.''' #$NON-NLS-1$ # Only import it here, to maintain Python 2.4 compatibility import xml.etree.ElementTree rsp = xml.etree.ElementTree.fromstring(rest_xml) if rsp.attrib[u'stat'] == u'ok' or not self.fail_on_error: #$NON-NLS-2$ #$NON-NLS-1$ return rsp err = rsp.find(u'err') #$NON-NLS-1$ raise FlickrError(u'Error: %s: %s' % ( #$NON-NLS-1$ err.attrib[u'code'], err.attrib[u'msg'])) #$NON-NLS-2$ #$NON-NLS-1$
def test_failure(cls, rsp, exception_on_error=True): u"""Exit app if the rsp XMLNode indicates failure.""" #$NON-NLS-1$ LOG.warn(u"FlickrAPI.test_failure has been deprecated and will be " #$NON-NLS-1$ u"removed in FlickrAPI version 1.2.") #$NON-NLS-1$ if rsp[u'stat'] != u"fail": #$NON-NLS-2$ #$NON-NLS-1$ return message = cls.get_printable_error(rsp) LOG.error(message) if exception_on_error: raise FlickrError(message)
def parse_etree(self, rest_xml): '''Parses a REST XML response from Flickr into an ElementTree object.''' try: import xml.etree.ElementTree as ElementTree except ImportError: # For Python 2.4 compatibility: try: import elementtree.ElementTree as ElementTree except ImportError: raise ImportError("You need to install " "ElementTree for using the etree format") rsp = ElementTree.fromstring(rest_xml) if rsp.attrib['stat'] == 'ok': return rsp err = rsp.find('err') raise FlickrError(u'Error: %(code)s: %(msg)s' % err.attrib)
def __extract_upload_response_format(self, kwargs): '''Returns the response format given in kwargs['format'], or the default format if there is no such key. If kwargs contains 'format', it is removed from kwargs. If the format isn't compatible with Flickr's upload response type, a FlickrError exception is raised. ''' # Figure out the response format format = kwargs.get('format', self.default_format) if format not in rest_parsers and format != 'rest': raise FlickrError('Format %s not supported for uploading ' 'photos' % format) # The format shouldn't be used in the request to Flickr. if 'format' in kwargs: del kwargs['format'] return format
def build_flickr_call(module, method, response_format="json", quiet=False, context=None): """ A builder to flickr api call. """ flickr = get_flickr_object() context = context or {} call = "%s.%s" % (module, method) command = getattr(flickr, call) # add context bases context['format'] = response_format context['user_id'] = settings.USER_ID try: return command(**context) except FlickrError as e: if not quiet: raise FlickrError(e.message)
def get_token_part_one(self, perms="read", auth_callback=None): """Get a token either from the cache, or make a new one from the frob. This first attempts to find a token in the user's token cache on disk. If that token is present and valid, it is returned by the method. If that fails (or if the token is no longer valid based on flickr.auth.checkToken) a new frob is acquired. If an auth_callback method has been specified it will be called. Otherwise the frob is validated by having the user log into flickr (with a browser). To get a proper token, follow these steps: - Store the result value of this method call - Give the user a way to signal the program that he/she has authorized it, for example show a button that can be pressed. - Wait for the user to signal the program that the authorization was performed, but only if there was no cached token. - Call flickrapi.get_token_part_two(...) and pass it the result value you stored. The newly minted token is then cached locally for the next run. perms "read", "write", or "delete" auth_callback method to be called if authorization is needed. When not passed, ``self.validate_frob(...)`` is called. You can call this method yourself from the callback method too. If authorization should be blocked, pass ``auth_callback=False``. The auth_callback method should take ``(frob, perms)`` as parameters. An example:: (token, frob) = flickr.get_token_part_one(perms='write') if not token: raw_input("Press ENTER after you authorized this program") flickr.get_token_part_two((token, frob)) Also take a look at ``authenticate_console(perms)``. """ # Check our auth_callback parameter for correctness before we # do anything authenticate = self.validate_frob if auth_callback is not None: if hasattr(auth_callback, '__call__'): # use the provided callback function authenticate = auth_callback elif auth_callback is False: authenticate = None else: # Any non-callable non-False value is invalid raise ValueError('Invalid value for auth_callback: %s' % auth_callback) # see if we have a saved token token = self.token_cache.token frob = None # see if it's valid if token: LOG.debug("Trying cached token '%s'" % token) try: rsp = self.auth_checkToken(auth_token=token, format='xmlnode') # see if we have enough permissions tokenPerms = rsp.auth[0].perms[0].text if tokenPerms == "read" and perms != "read": token = None elif tokenPerms == "write" and perms == "delete": token = None except FlickrError: LOG.debug("Cached token invalid") self.token_cache.forget() token = None # get a new token if we need one if not token: # If we can't authenticate, it's all over. if not authenticate: raise FlickrError('Authentication required but ' 'blocked using auth_callback=False') # get the frob LOG.debug("Getting frob for new token") rsp = self.auth_getFrob(auth_token=None, format='xmlnode') frob = rsp.frob[0].text authenticate(frob, perms) return (token, frob)