def download_set(set_id, size_label=None, naming=None): """ Download the set with 'set_id' to the current directory. @param set_id: str, id of the photo set @param size_label: str|None, size to download (or None for largest available) @param naming: str|append, photo naming strategy """ suffix = " ({})".format(size_label) if size_label else "" pset = Flickr.Photoset(id=set_id) photos = pset.getPhotos() pagenum = 2 while True: try: page = pset.getPhotos(page=pagenum) photos.extend(page) pagenum += 1 except FlickrAPIError as ex: if ex.code == 1: break raise if not os.path.exists(pset.title): os.mkdir(pset.title) # Stores in a dictionary the photo titles already found and their count, # if the --naming argument was set to 'increment' duplicates = {} for photo in photos: if naming == 'append': fname = '{0}/{1}-{2}{3}.jpg'.format(pset.title, photo.title, photo.id, suffix) elif naming == 'replace': fname = '{0}/{1}{2}.jpg'.format(pset.title, photo.id, suffix) elif naming == 'increment': if duplicates.has_key(photo.title): extra = '(' + str(duplicates[photo.title]) + ')' duplicates[photo.title] += 1 else: extra = '' duplicates[photo.title] = 1 fname = '{0}/{1}{2}{3}.jpg'.format(pset.title, photo.title, suffix, extra) else: fname = '{0}/{1}{2}.jpg'.format(pset.title, photo.title, suffix) if os.path.exists(fname): # TODO: Ideally we should check for file size / md5 here # to handle failed downloads. print 'Skipping {0}, as it exists already'.format(fname) continue print 'Saving: {0}'.format(fname) photo.save(fname, size_label) # Set file times to when the photo was taken info = photo.getInfo() taken = parser.parse(info['taken']) taken_unix = time.mktime(taken.timetuple()) os.utime(fname, (taken_unix, taken_unix))
def order_photosets_by_taken_date(): logging.debug('Get photoset ids ordered by photo taken date desc.') sql = """select ps.id from f_photoset ps inner join f_photosetphoto psp on ps.id = psp.photosetId left join f_photosetnodate nd on ps.id = nd.id inner join f_photo p on psp.photoId = p.id group by ps.id, ps.title order by max(case when nd.id is not null then cast('1900-01-01' as datetime) else p.taken end) desc""" setids = get_int_list_from_database(sql) setids = [str(i) for i in setids] logging.debug('Retrieved %s photoset ids.' % len(setids)) flickr_api.Photoset().orderSets(photoset_ids=','.join(setids)) logging.debug('Ordering photos inside sets. Getting list of sets.') photosets = user.getPhotosets() for photoset in photosets: logging.debug('Getting photos of set %s and ordering them by taken date.' % photoset.title) sql = """select p.id from f_photo p inner join f_photosetphoto psp on p.id = psp.photoId where psp.photosetId = %s order by p.taken asc""" % photoset.id photoids = get_int_list_from_database(sql) photoids = [str(i) for i in photoids] photoset.reorderPhotos(photo_ids=','.join(photoids))
def download_set(set_id, get_filename, size_label=None): """ Download the set with 'set_id' to the current directory. @param set_id: str, id of the photo set @param get_filename: Function, function that creates a filename for the photo @param size_label: str|None, size to download (or None for largest available) """ pset = Flickr.Photoset(id=set_id) download_list(pset, pset.title, get_filename, size_label)
def download_set(set_id, get_filename, size_label=None, skip_download=False, save_json=False): """ Download the set with 'set_id' to the current directory. @param set_id: str, id of the photo set @param get_filename: Function, function that creates a filename for the photo @param size_label: str|None, size to download (or None for largest available) @param skip_download: bool, do not actually download the photo @param save_json: bool, save photo info as .json file """ pset = Flickr.Photoset(id=set_id) download_list(pset, pset.title, get_filename, size_label, skip_download, save_json)
def check_flickr(self): flickr.set_keys(api_key=settings.FLICKR_API_KEY, api_secret=settings.FLICKR_API_SECRET) # photos from photoset photoset = flickr.Photoset(id=settings.FLICKR_PHOTOSET_ID) photos_from_photoset = photoset.getPhotos(extras=['url_m', 'url_o'], media='photos') photos_from_photoset_to_save = [ Photo( title=photo.title, flickr_id=photo.id, url_m=photo.url_m, url_o=photo.url_o, ) for photo in photos_from_photoset ] # photos by tag #int20h photos_by_tag = flickr.Photo.search( tags=settings.FLICKR_PARSE_TAG, extras=['url_m', 'url_o'], media='photos', per_page=500, ) photos_by_tag_to_save = [ Photo( title=photo.title, flickr_id=photo.id, url_m=photo.url_m, url_o=photo.url_o, ) for photo in photos_by_tag ] # merge two unsaved lists into one all_photos_to_save = photos_by_tag_to_save + photos_from_photoset_to_save # save to db preventing duplicates # we will need to wait for Django 2.2 to use bulk_create ignore_conflicts all_photos_to_save_flickr_ids = {photo.flickr_id for photo in all_photos_to_save} photos_already_exists_flickr_ids = set( Photo.objects.filter( flickr_id__in=list(all_photos_to_save_flickr_ids) ).values_list( 'flickr_id', flat=True, ) ) # Note: we save flickr_id as integer in db new_photos_to_save = [ photo for photo in all_photos_to_save if int(photo.flickr_id) not in photos_already_exists_flickr_ids ] Photo.objects.bulk_create(new_photos_to_save) return f'added: {len(new_photos_to_save)} Photos'
def get_photos_by_option(option, term): if option == "s": # try "minimalism" print("Searching for photos with tag \"" + term + "\"") return flickr_api.Walker(flickr_api.Photo.search, tags=term) elif option == "u": # try "alexcurrie" print("Retrieving photos from user " + term) user = flickr_api.Person.findByUserName(term) return user.getPublicPhotos() elif option == "a": # try "72157669309212490" print("Retrieving photos from album with ID " + term) photoset = flickr_api.Photoset(id=term) return photoset.getPhotos()