Source code for airframe.flickr

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright 2013 Virantha Ekanayake All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import argparse
import sys, os
import logging

import yaml
import flickrapi
import urllib


[docs]class Photo(object): def __init__(self, photo_element): """Construct a photo object out of the XML response from Flickr""" attrs = { 'farm': 'farmid', 'server':'serverid','id':'photoid','secret':'secret'} for flickr_attr, py_attr in attrs.items(): setattr(self, py_attr, photo_element.get(flickr_attr)) def _construct_flickr_url(self): url = "http://farm%s.staticflickr.com/%s/%s_%s_b.jpg" % (self.farmid,self.serverid, self.photoid, self.secret) return url
[docs] def download_photo(self, dirname, cache=False, tgt_filename=None): if not os.path.exists(dirname): os.makedirs(dirname) tgt = os.path.join(dirname, "%s.jpg" % self.photoid) if cache: if os.path.isfile(tgt): return tgt urllib.urlretrieve(self._construct_flickr_url(), tgt) return tgt
[docs]class Flickr(object): def __init__(self): self.set_keys(*self.read_keys()) self.get_auth2()
[docs] def read_keys(self): """ Read the flickr API key and secret from a local file """ with open("flickr_api.yaml") as f: api = yaml.load(f) return (api["key"], api["secret"])
[docs] def set_keys(self, key, secret): self.api_key = key self.api_secret = secret
[docs] def get_auth2(self): print("Authenticating to Flickr") self.flickr = flickrapi.FlickrAPI(self.api_key, self.api_secret) (token,frob) = self.flickr.get_token_part_one(perms='read') if not token: raw_input("Press ENTER after you authorized this program") self.flickr.get_token_part_two((token,frob)) print("Authentication succeeded")
[docs] def get_tagged(self, tags, count, download_dir="photos"): """ Get photos with the given list of tags """ print ("connecting to flickr, and getting %d photos with tags %s" % (count, tags)) x = self.flickr.photos_search(api_key = self.api_key, user_id="me", tags=','.join(tags), per_page=count) photos = self._extract_photos_from_xml(x) photo_filenames = self._sync_photos(photos, download_dir) print("Found %d photos" % len(photos)) return photo_filenames
def _sync_photos(self, photos, download_dir="photos", clean_up=False): """ Connect to flickr, and for each photo in the list, download. Then, if delete photos that are present locally that weren't present in the list of photos. :returns: List of filenames downloaded """ photo_filenames = [] photo_count = len(photos) for i,photo in enumerate(photos): print("[%d/%d] Downloading %s from flickr" % (i,photo_count,photo.photoid)) filename = photo.download_photo(download_dir, cache=True) photo_filenames.append(filename) # Now, go through and clean up directory if required if clean_up: photo_file_list = ["%s.jpg" % (x.photoid) for x in photos] for fn in os.listdir(download_dir): full_fn = os.path.join(download_dir, fn) if os.path.isfile(full_fn): if not fn in photo_file_list: print ("Flickr sync: Deleting file %s" % fn) os.remove(full_fn) return photo_filenames def _extract_photos_from_xml(self, xml): photos = [] for i in xml.iter(): if i.tag == 'rsp': # the response header. stat member should be 'ok' if i.get('stat') == 'ok': continue else: # error, so just break break if i.tag == 'photo': photos.append(Photo(i)) return photos
[docs] def get_recent(self,count, download_dir="photos"): """ get the most recent photos """ print ("connecting to flickr, and getting most recent %d photos" % count) x = self.flickr.people_getphotos(api_key = self.api_key, user_id="me",per_page=count) #x = self.flickr.photos_search(api_key=self.api_key,"me") photos = self._extract_photos_from_xml(x) photo_filenames = self._sync_photos(photos, download_dir) return photo_filenames
[docs]def main(): #logging.basicConfig(level=logging.DEBUG, format='%(message)s') script = Flickr() key,secret = script.read_keys() script.set_keys(key,secret) script.get_auth2() script.get_recent(10)
if __name__ == '__main__': main()