def fetch_from_flickr(self, keyword, api_key, api_secret, number_links=50): """ Fetch images from Flikr """ from flickrapi import FlickrAPI # we import flikcr API only if needed # calculate number of pages: if number_links < 200: items_per_page = number_links else: items_per_page = 200 # max 200 for flikr pages_nbr = int(ceil(number_links / items_per_page)) links = [] # get links from the first page: print("Carwling Flickr Search...") flickr = FlickrAPI(api_key, api_secret) response = flickr.photos_search(api_key=api_key, text=keyword, per_page=items_per_page, media='photos', sort='relevance') images = [im for im in list(response.iter()) if im.tag == 'photo'] for photo in images: photo_url = "https://farm{0}.staticflickr.com/{1}/{2}_{3}.jpg".format( photo.get('farm'), photo.get('server'), photo.get('id'), photo.get('secret')) links.append(photo_url) print(" >> ", len(links), " links extracted...", end="") # get next pages: for _ in range(1, pages_nbr): response = flickr.photos_search(api_key=api_key, text=keyword, per_page=items_per_page, media='photos', sort='relevance') images = [im for im in list(response.iter()) if im.tag == 'photo'] for photo in images: link = "https://farm{0}.staticflickr.com/{1}/{2}_{3}.jpg".format( photo.get('farm'), photo.get('server'), photo.get('id'), photo.get('secret')) links.append(link) print("\r >> ", len(links), " links extracted...", end="") # store and reduce the number of images if too much: return links
def fetch_from_flickr(self, keyword, api_key, api_secret, number_links=50): """ Fetch images from Flikr """ from flickrapi import FlickrAPI # we import flikcr API only if needed # calculate number of pages: if number_links < 200: items_per_page = number_links else: items_per_page = 200 # max 200 for flikr pages_nbr = int(ceil(number_links / items_per_page)) links = [] # get links from the first page: print("Carwling Flickr Search...") flickr = FlickrAPI(api_key, api_secret) response = flickr.photos_search(api_key=api_key, text=keyword, per_page=items_per_page, media='photos', sort='relevance') images = [im for im in list(response.iter()) if im.tag == 'photo'] for photo in images: photo_url = "https://farm{0}.staticflickr.com/{1}/{2}_{3}.jpg". format( photo.get('farm'), photo.get('server'), photo.get('id'), photo.get('secret')) links.append(photo_url) print(" >> ", len(links), " links extracted...", end="") # get next pages: for i in range(1, pages_nbr): response = flickr.photos_search(api_key=api_key, text=keyword, per_page=items_per_page, media='photos', page = i + 1, sort='relevance') images = [im for im in list(response.iter()) if im.tag == 'photo'] for photo in images: link = "https://farm{0}.staticflickr.com/{1}/{2}_{3}.jpg". format( photo.get('farm'), photo.get('server'), photo.get('id'), photo.get('secret')) links.append(link) print("\r >> ", len(links), " links extracted...", end="") # store and reduce the number of images if too much: return links
class FwiktrFlickrRetriever(FwiktrServiceManager): transformList = [FwiktrFlickrFuckItSelectionTransform(), FwiktrFlickrFullANDSelectionTransform()] def __init__(self): self._pic_info = [] FwiktrServiceManager.__init__(self) self.name = "Flickr" def _SetupService(self): self._fapi = FlickrAPI(self._GetOption('flickr_api_key'), self._GetOption('flickr_api_secret')) def GetPictureXML(self): return flickr_info_xml def GetPictureData(self): return {'picture_title':cgi.escape(self._pic_info['title']), 'picture_info':self._GetPictureSpecificData()} def _GetPictureSpecificData(self): return flickr_info_xml % {'flickr_server':self._pic_info['server'], 'flickr_farm':self._pic_info['farm'], 'flickr_photo_id':self._pic_info['id'], 'flickr_secret':self._pic_info['secret'], 'flickr_owner_id':self._pic_info['owner']} def GetNewPicture(self, tag_list): try: if len(tag_list) > 20: culler = FwiktrFlickrTagCullTransform() tag_list = culler.RunTransform(tag_list) tag_string = ','.join(tag_list) if(tag_string == ""): return False pic = FwiktrFlickrFullANDSelectionTransform() rsp = self._fapi.photos_search(api_key=self._GetOption('flickr_api_key'),tags=tag_string,tag_mode='all') self._fapi.testFailure(rsp) print rsp.photos[0]['total'] if(int(rsp.photos[0]['total']) == 0): pic = FwiktrFlickrFuckItSelectionTransform() rsp = self._fapi.photos_search(api_key=self._GetOption('flickr_api_key'),tags=tag_string,tag_mode='any') print rsp.photos[0]['total'] self._fapi.testFailure(rsp) if(int(rsp.photos[0]['total']) == 0): return False rand_index = random.randint(0, min(int(rsp.photos[0]['perpage']), int(rsp.photos[0]['total']))) self._pic_info = rsp.photos[0].photo[rand_index] pic.RunTransform({'total':rsp.photos[0]['total'],'picked':rand_index}) return True except: return False
successfulQuery = True return response if __name__ == "__main__": flickr_api_key = config.flickrAPIKey flickr_per_page = str(config.maxPhotosPerPage) flickrAPI = FlickrAPI(config.flickrAPIKey, config.flickrSecret) response = flickrAPI.photos_search( api_key=flickr_api_key, sort='interestingness-desc', ispublic='1', media='photos', per_page=flickr_per_page, page='1', text='love', extras = config.photo_extras, min_upload_date='1300822535', max_upload_date='1300882535') count = 0 for photo in response[0]: image = photo.attrib print (extract_url(image)) if(is_valid_photo(image)): count = count + 1 print (count)
class Offlickr: def __init__( self, key, secret, httplib=None, dryrun=False, verbose=False, ): """Instantiates an Offlickr object An API key is needed, as well as an API secret""" self.__flickrAPIKey = key self.__flickrSecret = secret self.__httplib = httplib # Get authentication token # note we must explicitly select the xmlnode parser to be compatible with FlickrAPI 1.2 self.fapi = FlickrAPI(self.__flickrAPIKey, self.__flickrSecret, format='xmlnode') (token, frob) = self.fapi.get_token_part_one() if not token: raw_input('Press ENTER after you authorized this program') self.fapi.get_token_part_two((token, frob)) self.token = token test_login = self.fapi.test_login() uid = test_login.user[0]['id'] self.flickrUserId = uid self.dryrun = dryrun self.verbose = verbose def __testFailure(self, rsp): """Returns whether the previous call was successful""" if rsp['stat'] == 'fail': print 'Error!' return True else: return False def getPhotoList(self, dateLo, dateHi): """Returns a list of photo given a time frame""" n = 0 flickr_max = 500 photos = [] print 'Retrieving list of photos' while True: if self.verbose: print 'Requesting a page...' n = n + 1 rsp = self.fapi.photos_search( api_key=self.__flickrAPIKey, auth_token=self.token, user_id=self.flickrUserId, per_page=str(flickr_max), page=str(n), min_upload_date=dateLo, max_upload_date=dateHi, ) if self.__testFailure(rsp): return None if rsp.photos[0]['total'] == '0': return None photos += rsp.photos[0].photo if self.verbose: print ' %d photos so far' % len(photos) if len(photos) >= int(rsp.photos[0]['total']): break return photos def getGeotaggedPhotoList(self, dateLo, dateHi): """Returns a list of photo given a time frame""" n = 0 flickr_max = 500 photos = [] print 'Retrieving list of photos' while True: if self.verbose: print 'Requesting a page...' n = n + 1 rsp = \ self.fapi.photos_getWithGeoData(api_key=self.__flickrAPIKey, auth_token=self.token, user_id=self.flickrUserId, per_page=str(flickr_max), page=str(n)) if self.__testFailure(rsp): return None if rsp.photos[0]['total'] == '0': return None photos += rsp.photos[0].photo if self.verbose: print ' %d photos so far' % len(photos) if len(photos) >= int(rsp.photos[0]['total']): break return photos def getPhotoLocation(self, pid): """Returns a string containing location of a photo (in XML)""" rsp = \ self.fapi.photos_geo_getLocation(api_key=self.__flickrAPIKey, auth_token=self.token, photo_id=pid) if self.__testFailure(rsp): return None doc = libxml2.parseDoc(rsp.xml) info = doc.xpathEval('/rsp/photo')[0].serialize() doc.freeDoc() return info def getPhotoLocationPermission(self, pid): """Returns a string containing location permision for a photo (in XML)""" rsp = \ self.fapi.photos_geo_getPerms(api_key=self.__flickrAPIKey, auth_token=self.token, photo_id=pid) if self.__testFailure(rsp): return None doc = libxml2.parseDoc(rsp.xml) info = doc.xpathEval('/rsp/perms')[0].serialize() doc.freeDoc() return info def getPhotosetList(self): """Returns a list of photosets for a user""" rsp = self.fapi.photosets_getList(api_key=self.__flickrAPIKey, auth_token=self.token, user_id=self.flickrUserId) if self.__testFailure(rsp): return None return rsp.photosets[0].photoset def getPhotosetInfo(self, pid, method): """Returns a string containing information about a photoset (in XML)""" rsp = method(api_key=self.__flickrAPIKey, auth_token=self.token, photoset_id=pid) if self.__testFailure(rsp): return None doc = libxml2.parseDoc(rsp.xml) info = doc.xpathEval('/rsp/photoset')[0].serialize() doc.freeDoc() return info def getPhotoMetadata(self, pid): """Returns an array containing containing the photo metadata (as a string), and the format of the photo""" if self.verbose: print 'Requesting metadata for photo %s' % pid rsp = self.fapi.photos_getInfo(api_key=self.__flickrAPIKey, auth_token=self.token, photo_id=pid) if self.__testFailure(rsp): return None doc = libxml2.parseDoc(rsp.xml) metadata = doc.xpathEval('/rsp/photo')[0].serialize() doc.freeDoc() return [metadata, rsp.photo[0]['originalformat']] def getPhotoComments(self, pid): """Returns an XML string containing the photo comments""" if self.verbose: print 'Requesting comments for photo %s' % pid rsp = \ self.fapi.photos_comments_getList(api_key=self.__flickrAPIKey, auth_token=self.token, photo_id=pid) if self.__testFailure(rsp): return None doc = libxml2.parseDoc(rsp.xml) comments = doc.xpathEval('/rsp/comments')[0].serialize() doc.freeDoc() return comments def getPhotoSizes(self, pid): """Returns a string with is a list of available sizes for a photo""" rsp = self.fapi.photos_getSizes(api_key=self.__flickrAPIKey, auth_token=self.token, photo_id=pid) if self.__testFailure(rsp): return None return rsp def getOriginalPhoto(self, pid): """Returns a URL which is the original photo, if it exists""" source = None rsp = self.getPhotoSizes(pid) if rsp == None: return None for s in rsp.sizes[0].size: if s['label'] == 'Original': source = s['source'] for s in rsp.sizes[0].size: if s['label'] == 'Video Original': source = s['source'] return [source, s['label'] == 'Video Original'] def __downloadReportHook( self, count, blockSize, totalSize, ): if not self.__verbose: return p = ((100 * count) * blockSize) / totalSize if p > 100: p = 100 print '\r %3d %%' % p, sys.stdout.flush() def downloadURL( self, url, target, filename, verbose=False, ): """Saves a photo in a file""" if self.dryrun: return self.__verbose = verbose tmpfile = '%s/%s.TMP' % (target, filename) if self.__httplib == 'wget': cmd = 'wget -q -t 0 -T 120 -w 10 -c -O %s %s' % (tmpfile, url) os.system(cmd) else: urllib.urlretrieve(url, tmpfile, reporthook=self.__downloadReportHook) os.rename(tmpfile, '%s/%s' % (target, filename))
class iesPicture(): def __init__(self, pageNum=50): self.flickr = FlickrAPI(FLICKRKEY.encode('utf-8'), FLICKRSECRET, format='parsed-json') if not self.flickr.token_valid(): self.flickr.get_request_token(oauth_callback="oob") verifier = str( input( "Get verifier code from {} and enter it here.\n: ".format( self.flickr.auth_url(perms="write")))) self.flickr.get_access_token(verifier) self.LCD = lcd1602.LCD16021() def choosePrintPicture(self, pageNum=50): photos = self.flickr.photos_search(user_id=MYID, per_page=pageNum) urltitledict = {} for i in range(pageNum): photoData = photos['photos']['photo'][i] farmId = photoData['farm'] severId = photoData['server'] picId = photoData['id'] idSecreat = photoData['secret'] title = photoData["title"] url = "https://farm{0}.staticflickr.com/{1}/{2}_{3}.jpg".format( farmId, severId, picId, idSecreat) urltitledict[url] = title dlURL, title = random.choice(list(urltitledict.items())) print(dlURL) self.LCD.lcd_string("Title", 0x80) self.LCD.lcd_string(title, 0xC0) self.downloadPicture(dlURL, "./Image/downloadpic.jpg") self.pictureConvert("./Image/downloadpic.jpg") def downloadPicture(self, url, filename): r = requests.get(url, stream=True) if r.status_code == 200: with open(filename, 'wb') as f: r.raw.decode_content = True shutil.copyfileobj(r.raw, f) def pictureConvert(self, name): root, ext = os.path.splitext(name) newext = ".png" args = ['convert', name, root + newext] res = subprocess.check_call(args) print(res) def uploadPhoto(self, path_to_photo, title=None): """ Upload the photo file to flickr. arguments: api: FlickrAPI object. path_to_photo: Path to photo file. title: photo file's name if None. returns: uploaded photo ID if success, else None. """ # res is instance of xml.etree.ElementTree.Element. # This element has something like "<rsp><photoid>1234</photoid></rsp>". """ if not api.token_valid(): api.get_request_token(oauth_callback="oob") verifier = str(input("Get verifier code from {} and enter it here.\n: ".format(api.auth_url(perms="write")))) api.get_access_token(verifier) """ try: res = self.flickr.upload( filename=path_to_photo, title=os.path.basename(path_to_photo) if not title else title, is_private=True) except json.decoder.JSONDecodeError: return None if res.get("stat") != "ok": return None # Get the uploaded photo's ID. return res
class TransFlickr: extras = "original_format,date_upload,last_update" def __init__(self, browserName): self.fapi = FlickrAPI(flickrAPIKey, flickrSecret) self.user_id = "" # proceed with auth # TODO use auth.checkToken function if available, # and wait after opening browser. print "Authorizing with flickr..." log.info("authorizing with flickr...") try: self.authtoken = self.fapi.getToken(browser=browserName) except: print ("Can't retrieve token from browser %s" % browserName) print ("\tIf you're behind a proxy server," " first set http_proxy environment variable.") print "\tPlease close all your browser windows, and try again" log.error(format_exc()) log.error("can't retrieve token from browser %s", browserName) sys.exit(-1) if self.authtoken == None: print "Unable to authorize (reason unknown)" log.error('not able to authorize; exiting') sys.exit(-1) #Add some authorization checks here(?) print "Authorization complete." log.info('authorization complete') def uploadfile(self, filepath, taglist, bufData, mode): #Set public 4(always), 1(public). Public overwrites f&f. public = mode&1 #Set friends and family 4(always), 2(family), 1(friends). friends = mode>>3 & 1 family = mode>>4 & 1 #E.g. 745 - 4:No f&f, but 5:public #E.g. 754 - 5:friends, but not public #E.g. 774 - 7:f&f, but not public log.info("uploading file %s", filepath) log.info(" data length: %s", len(bufData)) log.info(" taglist: %s", taglist) log.info(" permissions: family %s, friends %s, public %s", family, friends, public) filename = os.path.splitext(os.path.basename(filepath))[0] rsp = self.fapi.upload(filename=filepath, jpegData=bufData, title=filename, tags=taglist, is_public=public and "1" or "0", is_friend=friends and "1" or "0", is_family=family and "1" or "0") if rsp is None: log.error("response None from attempt to write file %s", filepath) log.error("will attempt recovery...") recent_rsp = None trytimes = 2 while(trytimes): log.info("sleeping for 3 seconds...") time.sleep(3) trytimes -= 1 # Keep on trying to retrieve the recently uploaded photo, till we # actually get the information, or the function throws an exception. while(recent_rsp is None or not recent_rsp): recent_rsp = self.fapi.photos_recentlyUpdated( auth_token=self.authtoken, min_date='1', per_page='1') pic = recent_rsp.photos[0].photo[0] log.info('we are looking for %s', filename) log.info('most recently updated pic is %s', pic['title']) if filename == pic['title']: id = pic['id'] log.info("file %s uploaded with photoid %s", filepath, id) return id log.error("giving up; upload of %s appears to have failed", filepath) return None else: id = rsp.photoid[0].elementText log.info("file %s uploaded with photoid %s", filepath, id) return id def put2Set(self, set_id, photo_id): log.info("uploading photo %s to set id %s", photo_id, set_id) rsp = self.fapi.photosets_addPhoto(auth_token=self.authtoken, photoset_id=set_id, photo_id=photo_id) if rsp: log.info("photo uploaded to set") else: log.error(rsp.errormsg) def createSet(self, path, photo_id): log.info("creating set %s with primary photo %s", path, photo_id) path, title = os.path.split(path) rsp = self.fapi.photosets_create(auth_token=self.authtoken, title=title, primary_photo_id=photo_id) if rsp: log.info("created set %s", title) return rsp.photoset[0]['id'] else: log.error(rsp.errormsg) def deleteSet(self, set_id): log.info("deleting set %s", set_id) if str(set_id)=="0": log.info("ignoring attempt to delete set wtih set_id 0 (a locally " "created set that has not yet acquired an id via uploading") return rsp = self.fapi.photosets_delete(auth_token=self.authtoken, photoset_id=set_id) if rsp: log.info("deleted set %s", set_id) else: log.error(rsp.errormsg) def getPhotoInfo(self, photoId): log.debug("id: %s", photoId) rsp = self.fapi.photos_getInfo(auth_token=self.authtoken, photo_id=photoId) if not rsp: log.error("can't retrieve information about photo %s; got error %s", photoId, rsp.errormsg) return None #XXX: should see if there's some other 'format' option we can fall back to. try: format = rsp.photo[0]['originalformat'] except KeyError: format = 'jpg' perm_public = rsp.photo[0].visibility[0]['ispublic'] perm_family = rsp.photo[0].visibility[0]['isfamily'] perm_friend = rsp.photo[0].visibility[0]['isfriend'] if perm_public == '1': mode = 0755 else: b_cnt = 4 if perm_family == '1': b_cnt += 2 if perm_friend == '1': b_cnt += 1 mode = "07" + str(b_cnt) + "4" mode = int(mode) if hasattr(rsp.photo[0],'permissions'): permcomment = rsp.photo[0].permissions[0]['permcomment'] permaddmeta = rsp.photo[0].permissions[0]['permaddmeta'] else: permcomment = permaddmeta = [None] commMeta = '%s%s' % (permcomment,permaddmeta) # Required for chmod. desc = rsp.photo[0].description[0].elementText title = rsp.photo[0].title[0].elementText if hasattr(rsp.photo[0].tags[0], "tag"): taglist = [ a.elementText for a in rsp.photo[0].tags[0].tag ] else: taglist = [] license = rsp.photo[0]['license'] owner = rsp.photo[0].owner[0]['username'] ownerNSID = rsp.photo[0].owner[0]['nsid'] url = rsp.photo[0].urls[0].url[0].elementText posted = rsp.photo[0].dates[0]['posted'] lastupdate = rsp.photo[0].dates[0]['lastupdate'] return (format, mode, commMeta, desc, title, taglist, license, owner, ownerNSID, url, int(posted), int(lastupdate)) def setPerm(self, photoId, mode, comm_meta="33"): log.debug("id: %s, mode: %s, comm_meta=%s", photoId, mode, comm_meta) public = mode&1 #Set public 4(always), 1(public). Public overwrites f&f #Set friends and family 4(always), 2(family), 1(friends) friends = mode>>3 & 1 family = mode>>4 & 1 if len(comm_meta)<2: # This wd patch string index out of range bug, caused # because some photos may not have comm_meta value set. comm_meta="33" rsp = self.fapi.photos_setPerms(auth_token=self.authtoken, is_public=str(public), is_friend=str(friends), is_family=str(family), perm_comment=comm_meta[0], perm_addmeta=comm_meta[1], photo_id=photoId) if not rsp: log.error("couldn't set permission for photo %s; got error %s", photoId, rsp.errormsg) return False log.info("permissions have been set for photo %s", photoId) return True def setTags(self, photoId, tags): log.debug("id: %s, tags: %s", photoId, tags) templist = [ '"%s"'%(a,) for a in string.split(tags, ',')] + ['flickrfs'] tagstring = ' '.join(templist) rsp = self.fapi.photos_setTags(auth_token=self.authtoken, photo_id=photoId, tags=tagstring) if not rsp: log.error("couldn't set tags for %s; got error %s", photoId, rsp.errormsg) return False return True def setMeta(self, photoId, title, desc): log.debug("id: %s, title: %s, desc: %s", photoId, title, desc) rsp = self.fapi.photos_setMeta(auth_token=self.authtoken, photo_id=photoId, title=title, description=desc) if not rsp: log.error("couldn't set meta info for photo %s; got error", photoId, rsp.errormsg) return False return True def getLicenses(self): log.debug("started") rsp = self.fapi.photos_licenses_getInfo() if not rsp: log.error("couldn't retrieve licenses; got error %s", rsp.errormsg) return None licenseDict = {} for l in rsp.licenses[0].license: licenseDict[l['id']] = l['name'] keys = licenseDict.keys() keys.sort() sortedLicenseList = [] for k in keys: # Add tuple of license key, and license value. sortedLicenseList.append((k, licenseDict[k])) return sortedLicenseList def setLicense(self, photoId, license): log.debug("id: %s, license: %s", photoId, license) rsp = self.fapi.photos_licenses_setLicense(auth_token=self.authtoken, photo_id=photoId, license_id=license) if not rsp: log.error("couldn't set license info for photo %s; got error %s", photoId, rsp.errormsg) return False return True def getPhoto(self, photoId): log.debug("id: %s", photoId) rsp = self.fapi.photos_getSizes(auth_token=self.authtoken, photo_id=photoId) if not rsp: log.error("error while trying to retrieve size information" " for photo %s", photoId) return None buf = "" for a in rsp.sizes[0].size: if a['label']=='Original': try: f = urllib2.urlopen(a['source']) buf = f.read() except: log.error("exception in getPhoto") log.error(format_exc()) return "" if not buf: f = urllib2.urlopen(rsp.sizes[0].size[-1]['source']) buf = f.read() return buf def removePhotofromSet(self, photoId, photosetId): log.debug("id: %s, setid: %s", photoId, photosetId) rsp = self.fapi.photosets_removePhoto(auth_token=self.authtoken, photo_id=photoId, photoset_id=photosetId) if rsp: log.info("photo %s removed from set %s", photoId, photosetId) else: log.error(rsp.errormsg) def getBandwidthInfo(self): log.debug("retrieving bandwidth information") rsp = self.fapi.people_getUploadStatus(auth_token=self.authtoken) if not rsp: log.error("can't retrieve bandwidth information; got error %s", rsp.errormsg) return (None,None) bw = rsp.user[0].bandwidth[0] log.debug("max bandwidth: %s, bandwidth used: %s", bw['max'], bw['used']) return (bw['max'], bw['used']) def getUserId(self): log.debug("entered") rsp = self.fapi.auth_checkToken(api_key=flickrAPIKey, auth_token=self.authtoken) if not rsp: log.error("unable to get userid; got error %s", rsp.errormsg) return None usr = rsp.auth[0].user[0] log.info("got NSID %s", usr['nsid']) #Set self.user_id to this value self.user_id = usr['nsid'] return usr['nsid'] def getPhotosetList(self): log.debug("entered") if self.user_id is "": self.getUserId() #This will set the value of self.user_id rsp = self.fapi.photosets_getList(auth_token=self.authtoken, user_id=self.user_id) if not rsp: log.error("error getting photoset list; got error %s", rsp.errormsg) return [] if not hasattr(rsp.photosets[0], "photoset"): log.info("no sets found for userid %s", self.user_id) return [] else: log.info("%s sets found for userid %s", len(rsp.photosets[0].photoset), self.user_id) return rsp.photosets[0].photoset def parseInfoFromPhoto(self, photo, perms=None): info = {} info['id'] = photo['id'] info['title'] = photo['title'].replace('/', '_') # Some pics don't contain originalformat attribute, so set it to jpg by default. try: info['format'] = photo['originalformat'] except KeyError: info['format'] = 'jpg' try: info['dupload'] = photo['dateupload'] except KeyError: info['dupload'] = '0' try: info['dupdate'] = photo['lastupdate'] except KeyError: info['dupdate'] = '0' info['perms'] = perms return info def parseInfoFromFullInfo(self, id, fullInfo): info = {} info['id'] = id info['title'] = fullInfo[4] info['format'] = fullInfo[0] info['dupload'] = fullInfo[10] info['dupdate'] = fullInfo[11] info['mode'] = fullInfo[1] return info def getPhotosFromPhotoset(self, photoset_id): log.debug("set id: %s", photoset_id) photosPermsMap = {} # I'm not utilizing the value part of this dictionary. Its arbitrarily # set to i. for i in range(0,3): page = 1 while True: rsp = self.fapi.photosets_getPhotos(auth_token=self.authtoken, photoset_id=photoset_id, extras=self.extras, page=str(page), privacy_filter=str(i)) if not rsp: break if not hasattr(rsp.photoset[0], 'photo'): log.error("photoset %s doesn't have attribute photo", rsp.photoset[0]['id']) break for p in rsp.photoset[0].photo: photosPermsMap[p] = str(i) page += 1 if page > int(rsp.photoset[0]['pages']): break if photosPermsMap: break return photosPermsMap def getPhotoStream(self, user_id): log.debug("userid: %s", user_id) retList = [] pageNo = 1 maxPage = 1 while pageNo<=maxPage: log.info("retreiving page number %s of %s", pageNo, maxPage) rsp = self.fapi.photos_search(auth_token=self.authtoken, user_id=user_id, per_page="500", page=str(pageNo), extras=self.extras) if not rsp: log.error("can't retrive photos from your stream; got error %s", rsp.errormsg) return retList if not hasattr(rsp.photos[0], 'photo'): log.error("photos.search response doesn't have attribute photos; " "returning list acquired so far") return retList for a in rsp.photos[0].photo: retList.append(a) maxPage = int(rsp.photos[0]['pages']) pageNo = pageNo + 1 return retList def getTaggedPhotos(self, tags, user_id=None): log.debug("tags: %s user_id: %s", tags, user_id) kw = kwdict(auth_token=self.authtoken, tags=tags, tag_mode="all", extras=self.extras, per_page="500") if user_id is not None: kw = kwdict(user_id=user_id, **kw) rsp = self.fapi.photos_search(**kw) log.debug("search for photos with tags %s has been" " successfully finished" % tags) if not rsp: log.error("couldn't search for the photos; got error %s", rsp.errormsg) return if not hasattr(rsp.photos[0], 'photo'): return [] return rsp.photos[0].photo
# timeskip = 172800 #two days timeskip = 86400 #one day jan_1_2016 = 1451606400 jan_1_2006 = 1136073600 oct_09_2008 = 1223510400 time_start = oct_09_2008 time_end = time_start + timeskip output_dir = '/tigress/dchouren/thesis/resources/paths' while time_end < jan_1_2016: print(time_start) f = flickr.photos_search( bbox='-74.052544, 40.525070, -73.740685, 40.889249', min_upload_date=time_start, max_upload_date=time_end) num_pages = int(f[0].get('pages')) print(num_pages) infos = [] #store a list of what was downloaded # ipdb.set_trace() write_count = 0 for page in range(0, num_pages): # print(i) f = flickr.photos_search( page=page, extras='geo', media='photos',
def importFromFlickr(): if g.user is None: return jsonify(result = False, error = "You need to be logged in to import from Flickr") if not g.user.flickr_auth: return jsonify(result = False, error = "Your account has not been authenticated with Flickr") try: # Yes yes, a massive try block, the horror! But almost every single line in here throws an error from FlickrAPI photoID = request.form.get('photoID') api_key = os.environ['PARAM1'] api_secret = os.environ['PARAM2'] flickr = FlickrAPI(api_key, api_secret, store_token = False) # Get original photo's URL sizes = flickr.photos_getSizes(photo_id = photoID).find('sizes')[-1] photo_url = sizes.attrib['source'] img_width = int(sizes.attrib['width']) # necessary to correctly scale notes img_height = int(sizes.attrib['height']) # Pull a blob of most of the photo's metadata photo_info = flickr.photos_getInfo(photo_id = photoID).find('photo') # Check if the person importing this photo actually owns it flickr_screen_name = photo_info.find('owner').attrib['username'] if flickr_screen_name.lower() != g.user.name.lower(): return jsonify(result = False, error = 'You dog! You don\'t own this photo! %s does. For shame.' % flickr_screen_name) # Pull photo's title, desc, timestamps from metadata blob flickr_owner_id = photo_info.find('owner').attrib['nsid'] # used to retrieve views title = photo_info.find('title').text desc = photo_info.find('description').text time_taken = photo_info.find('dates').attrib['taken'] # '2013-06-22 11:16:32' ... wtf? time_posted = photo_info.find('dates').attrib['posted'] # '1372279163' # flickr notes are in a 0..500px coordinate space, where 500 maps to max(img_width, img_height) # brickr notes are normalized to a 0..100 % coordinate space, regardless of image aspect ratio (because I'm smarter) # flickr notes don't have timestamp info scale_w = 500 if img_width >= img_height else (500 / img_height * img_width) scale_h = 500 if img_width < img_height else (500 / img_width * img_height) notes = [] for note in photo_info.find('notes'): notes.append({ 'user_id': note.attrib['author'], 'screen_name': note.attrib['authorname'], 'text': note.text, 'x': int(note.attrib['x']) / scale_w * 100, 'y': int(note.attrib['y']) / scale_h * 100, 'w': int(note.attrib['w']) / scale_w * 100, 'h': int(note.attrib['h']) / scale_h * 100 }) # Photo tags are easy tags = [] for tag in photo_info.find('tags'): if tag.attrib['machine_tag'] != '1': # Ignore ugly automatically created inivisible-to-users tags tags.append(tag.attrib['raw']) # Import comments - needs its own Flickr API call comments = [] if int(photo_info.find('comments').text) > 0: comment_rsp = flickr.photos_comments_getList(photo_id = photoID).find('comments') for comment in comment_rsp: comments.append({ 'user_id': comment.attrib.get('author'), 'screen_name': comment.attrib.get('authorname'), 'timestamp': comment.attrib.get('datecreate'), 'iconfarm': comment.attrib.get('iconfarm'), 'iconserver': comment.attrib.get('iconserver'), 'text': comment.text }) # Import Favorites. These come in at most 50 per request. Another dedicated Flickr API call favorites = [] favorite_rsp = flickr.photos_getFavorites(photo_id = photoID, per_page = '50').find('photo') for fav in favorite_rsp: favorites.append({ 'user_id': fav.attrib.get('nsid'), 'screen_name': fav.attrib.get('username'), 'timestamp': fav.attrib.get('favedate'), 'iconfarm': comment.attrib.get('iconfarm'), 'iconserver': comment.attrib.get('iconserver') }) fav_page_count = int(favorite_rsp.attrib['pages']) if fav_page_count > 1: for i in range(2, fav_page_count + 1): favorite_rsp = flickr.photos_getFavorites(photo_id = photoID, page = str(i), per_page = '50').find('photo') for fav in favorite_rsp: favorites.append({ 'user_id': fav.attrib['nsid'], 'screen_name': fav.attrib.get('username'), 'timestamp': fav.attrib.get('favedate'), 'iconfarm': comment.attrib.get('iconfarm'), 'iconserver': comment.attrib.get('iconserver') }) # View count # There's no direct flickr API to get a photo's view count (weird) # But we can add 'views' to the list of extra info returned by photo.search... (weird) # Can't search by photo ID (not weird), but can search by min & max upload time... set those to the photo's upload time, and we find the exact photo... (lucky) views = flickr.photos_search(user_id = flickr_owner_id, min_upload_date = time_posted, max_upload_date = time_posted, extras = 'views') views = views.find('photos')[0].attrib['views'] except Exception as e: return jsonify(result = False, error = "F**k me. Flickr Import went horribly awry. Send this message to Remi:\n\nPhoto: %s - %s" % (photoID, e.__repr__())) try: # So, we've pulled absolutely everything about this one photo out of Flickr. # Now dump it all into Brickr. You're welcome. photo = Photo(photo_url, g.user, title, desc) file_object = urllib2.urlopen(photo_url) # Download photo from Flickr fp = StringIO(file_object.read()) if not photo.save_file(fp): return jsonify(result = False, error = "Well shit. So, everything exported FROM Flickr just fine. But we failed to save the exported photo file. Send this message to Remi:\n\nPhoto: %s - Flickr Export - %s" % (photoID, photo_url)) # Flickr buddy icon URL: # http://farm{icon-farm}.staticflickr.com/{icon-server}/buddyicons/{nsid}.jpg # http://farm4.staticflickr.com/3692/buddyicons/[email protected] photo.views = views db.session.add(photo) db.session.commit() # Shit, should do everything in one commit, but we need a photo ID before adding things to the photo... for c in comments: user = User.get_user_or_placeholder(c['screen_name'], c['user_id']) comment = Comment(user, photo, c['text'], datetime.date.fromtimestamp(float(c['timestamp']))) db.session.add(comment) for n in notes: user = User.get_user_or_placeholder(n['screen_name'], n['user_id']) note = Note(user, photo, n['text'], n['x'], n['y'], n['w'], n['h']) db.session.add(note) for t in tags: tag = Tag.get_or_create(t) photo.tags.extend([tag]) db.session.add(tag) for f in favorites: user = User.get_user_or_placeholder(f['screen_name'], f['user_id']) fav = Favorite(user, photo) db.session.add(fav) db.session.commit() return jsonify(result = True, url = url_for('photos.photo', user_url = g.user.url, photoID = photo.id)) except Exception as e: return jsonify(result = False, error = "Well shit. So, everything exported FROM flickr just fine. But dumping it INTO Brickr is apparently too much to ask. Send this message to Remi:\n\nPhoto: %s - Brickr Import - %s" % (photoID, e.__repr__()))
class Fwiktr: def __init__(self): self.ftp_socket = ftplib.FTP('30helensagree.com') self.ftp_socket.login('thirtyhelens', 'ZHXK7tzL') self.ftp_socket.cwd('30helensagree.com') self.SetupFlickr() self.SetupTwitter() def SetupFlickr(self): # make a new FlickrAPI instance self.fapi = FlickrAPI(flickrAPIKey, flickrAPISecret) def SetupTwitter(self): self.tapi = twitter.Api() def RunPOSTagger(self): twitter_messages = self.tapi.GetPublicTimeline() for message in twitter_messages: try: cmd = 'echo "' + message.text + '" | treetagger/cmd/tree-tagger-english > ./twitter_message_output.txt' os.system(cmd) self.pos_file = open('twitter_message_output.txt', 'r') tokens = [] self.parse_string = "" for line in self.pos_file: current_line = [] self.parse_string += line + "<BR>" for value in tokenize.whitespace(line): current_line.append(value) tokens.append(current_line) filename = uuid.uuid4() self.output_file = open(str(filename)+".html", 'w') self.output_file.write(file_header % (message.text)) self.output_file.write(message.text + "<BR>") self.RetreiveFlickrURLs(tokens) self.output_file.write(file_footer) self.output_file.close() self.output_file = open(str(filename)+".html", 'r') self.ftp_socket.storlines("STOR "+str(filename)+".html", self.output_file) self.output_file.close() self.pos_file.close() time.sleep(30) except UnicodeEncodeError: print "Twitter Message not ascii, skipping" except AttributeError: print "Weird XML error. I wish it'd stop doing that" def CullAndFormatTagList(self, tagList): #Start by culling everything that's not a noun tags_culled = ""; for tag_tuple in tagList: if tag_tuple[1] == "NP" or tag_tuple[1] == "NN" or tag_tuple[1] == "NNS": tags_culled += tag_tuple[0] + "," return tags_culled def RetreiveFlickrURLs(self, tagList): tag_string = self.CullAndFormatTagList(tagList) rsp = self.fapi.photos_search(api_key=flickrAPIKey,tags=tag_string) if(rsp.photos[0]['total'] == 0): return rand_index = random.randint(0, min(int(rsp.photos[0]['perpage']), int(rsp.photos[0]['total']))) i = 0 urls = "<UL>" for a in rsp.photos[0].photo: photo_url = "http://farm%s.static.flickr.com/%s/%s_%s.jpg" % (a['farm'], a['server'], a['id'], a['secret']) flickr_url = "http://www.flickr.com/photos/%s/%s" % (a['owner'], a['id']) urls += "<LI><A HREF='"+photo_url+"'>"+photo_url+"</A> - <A HREF='"+ flickr_url+"'>"+flickr_url+"</A></LI>" if i == rand_index: self.output_file.write("<A HREF='"+flickr_url+"'><IMG SRC='"+photo_url+"' border=0></A>") i = i + 1 urls += "</UL>" self.output_file.write("<HR>") self.output_file.write(self.parse_string) self.output_file.write("<HR>") self.output_file.write("Tag String for Flickr Search: " + tag_string) self.output_file.write("<HR>") self.output_file.write("Using photo " + str(rand_index) + " of " + rsp.photos[0]['total'] + "<BR>") self.output_file.write("Selection method: RANDOM CHOICE<BR>") self.output_file.write(urls)
class Importer(object): def __init__(self): self.flickr = FlickrAPI(FLICKR_KEY) def get_photosets(self, username, filename=None): filename = filename or username+'.json' if os.path.exists(filename): print "Looks like we already have information about your photos." if raw_input("Refresh? (y/n): ").lower().startswith('n'): return deserialize(open(filename).read()) print "Downloading information about your photos." if '@' in username: response = self.flickr.people_findByEmail(find_email=username) else: response = self.flickr.people_findByUsername(username=username) nsid = response[0].get('nsid') response = self.flickr.photosets_getList(user_id=nsid) photosets = [] photo_ids = [] for ps in response[0]: photoset = {'id': ps.get('id'), 'title': ps[0].text, 'description': ps[1].text, 'photos':[]} photos_response = self.flickr.photosets_getPhotos(photoset_id=photoset['id'], extras='url_o') for pxml in photos_response[0]: photo = {'id':pxml.get('id'), 'title':pxml.get('title')} photoset['photos'].append(photo) photo_ids.append(photo['id']) print photoset['title'],'-',len(photoset['photos']),'photos' photosets.append(photoset) # get photos not in photosets photos_response = self.flickr.photos_search(user_id=nsid, per_page=500) photoset = {'id':'stream', 'title':'Flickr Stream', 'description':'Photos from my flickr stream', 'photos':[]} for pxml in response[0]: photo = {'id':pxml.get('id'), 'title':pxml.get('title')} if photo['id'] not in photo_ids: photoset['photos'].append(photo) photo_ids.append(photo['id']) if photoset['photos']: print photoset['title'],'-',len(photoset['photos']),'photos' photosets.append(photoset) f = open(filename, "w") f.write(serialize(photosets)) f.close() return photosets def download_images(self, photosets, directory): print "Downloading your photos" if not os.path.exists(directory): os.mkdir(directory) default = None for photoset in photosets: dirpath = os.path.join(directory, photoset['id']+' - '+photoset['title']) if not os.path.exists(dirpath): os.mkdir(dirpath) for photo in photoset['photos']: filename = os.path.join(dirpath, photo['id']+'.jpg') if os.path.exists(filename): if default is None: print "Photo", photo['id'], "has already been downloaded." default = raw_input("Download again? (y/n/Y/N) (capital to not ask again): ") if default == 'n': default = None continue elif default == 'N': continue elif default == 'y': default = None f = open(filename, 'w') if not photo.get('url'): try: sizes_response = self.flickr.photos_getSizes(photo_id=photo['id']) except: print "Failed to download photo:", photo['id'], '... sorry!' else: photo['url'] = sizes_response[0][-1].get('source') if photo.get('url'): print "Downloading", photo['title'], 'from', photo['url'] remote = urllib2.urlopen(photo['url']) f.write(remote.read()) f.close() remote.close() def upload_images(self, photosets, directory): client = DivvyshotClient() for photoset in photosets: event_data = client.create_event(name=photoset['title'], description=photoset['description']) event_path = '/api/v2/json/event/%s/photo/' % event_data['url_slug'] for photo in photoset['photos']: print "Uploading", photo['title'] filename = os.path.join(directory, photoset['id']+' - '+photoset['title'], photo['id']+'.jpg') if not os.path.exists(filename): print "Looks like photo",photo['id'],'did not get downloaded.' continue photo_data = client.create_photo(event_data['url_slug'], filename) photo_data = client.update_photo(photo_data['url_slug'], name=photo['title']) print "Finished uploading", photo_data['name'] os.remove(filename) def do_import(self): username = raw_input("Your flickr username/email: ") # Step 1: grab the list of photos from flickr photosets = self.get_photosets(username) # Step 2: download the images from flickr self.download_images(photosets, username) self.upload_images(photosets, username)
class Offlickr: def __init__(self, key, secret, uid, httplib=None, browser="lynx", verbose=False): """Instantiates an Offlickr object An API key is needed, as well as an API secret and a user id. A browser can be specified to be used for authorizing the program to access the user account.""" self.__flickrAPIKey = key self.__flickrSecret = secret self.__httplib = httplib # Get authentication token self.fapi = FlickrAPI(self.__flickrAPIKey, self.__flickrSecret) self.token = self.fapi.getToken(browser=browser) self.flickrUserId = uid self.verbose = verbose def __testFailure(self, rsp): """Returns whether the previous call was successful""" if rsp['stat'] == "fail": print "Error!" return True else: return False def getPhotoList(self, dateLo, dateHi): """Returns a list of photo given a time frame""" n = 0 flickr_max = 500 photos = [] print "Retrieving list of photos" while True: if self.verbose: print "Requesting a page..." n = n + 1 rsp = self.fapi.photos_search( api_key=self.__flickrAPIKey, auth_token=self.token, user_id=self.flickrUserId, per_page=str(flickr_max), # Max allowed by Flickr page=str(n), min_upload_date=dateLo, max_upload_date=dateHi) if self.__testFailure(rsp): return None if rsp.photos[0]['total'] == '0': return None photos += rsp.photos[0].photo if self.verbose: print " %d photos so far" % len(photos) if len(photos) >= int(rsp.photos[0]['total']): break return photos def getPhotosetList(self): """Returns a list of photosets for a user""" rsp = self.fapi.photosets_getList(api_key=self.__flickrAPIKey, auth_token=self.token, user_id=self.flickrUserId) if self.__testFailure(rsp): return None return rsp.photosets[0].photoset def getPhotosetInfo(self, pid, method): """Returns a string containing information about a photoset (in XML)""" rsp = method(api_key=self.__flickrAPIKey, auth_token=self.token, photoset_id=pid) if self.__testFailure(rsp): return None doc = libxml2.parseDoc(rsp.xml) info = str(doc.xpathEval("/rsp/photoset")[0]) doc.freeDoc() return info def getPhotoMetadata(self, pid): """Returns an array containing containing the photo metadata (as a string), and the format of the photo""" if self.verbose: print "Requesting metadata for photo %s" % pid rsp = self.fapi.photos_getInfo(api_key=self.__flickrAPIKey, auth_token=self.token, photo_id=pid) if self.__testFailure(rsp): return None doc = libxml2.parseDoc(rsp.xml) metadata = doc.xpathEval("/rsp/photo")[0].serialize() doc.freeDoc() return [metadata, rsp.photo[0]['originalformat']] def getPhotoComments(self, pid): """Returns an XML string containing the photo comments""" if self.verbose: print "Requesting comments for photo %s" % pid rsp = self.fapi.photos_comments_getList(api_key=self.__flickrAPIKey, auth_token=self.token, photo_id=pid) if self.__testFailure(rsp): return None doc = libxml2.parseDoc(rsp.xml) comments = doc.xpathEval("/rsp/comments")[0].serialize() doc.freeDoc() return comments def getPhotoSizes(self, pid): """Returns a string with is a list of available sizes for a photo""" rsp = self.fapi.photos_getSizes(api_key=self.__flickrAPIKey, auth_token=self.token, photo_id=pid) if self.__testFailure(rsp): return None return rsp def getOriginalPhoto(self, pid): """Returns a URL which is the original photo, if it exists""" source = None rsp = self.getPhotoSizes(pid) if rsp == None: return None for s in rsp.sizes[0].size: if s['label'] == 'Original': source = s['source'] return source def __downloadReportHook(self, count, blockSize, totalSize): if self.__verbose == False: return p = 100 * count * blockSize / totalSize if (p > 100): p = 100 print "\r %3d %%" % p, sys.stdout.flush() def downloadURL(self, url, target, filename, verbose=False): """Saves a photo in a file""" self.__verbose = verbose tmpfile = "%s/%s.TMP" % (target, filename) if self.__httplib == 'wget': cmd = 'wget -q -t 0 -T 120 -w 10 -c -O %s %s' % (tmpfile, url) os.system(cmd) else: urllib.urlretrieve(url, tmpfile, reporthook=self.__downloadReportHook) os.rename(tmpfile, "%s/%s" % (target, filename))
flickr = FlickrAPI('ecbe2e529de5b65c68fb66470c587423') n = 0 pagenr = 1 ids = [] maxDate = int(time.time()) tempMaxDate = maxDate totalPics = 0 newestDate = datetime.fromtimestamp(0) try: while True: while n < 4000: try: result = flickr.photos_search(bbox="2.570801,49.475263,6.437988,51.512161", max_upload_date=maxDate, per_page=250, extras="geo,date_upload", page=pagenr) pagenr = pagenr + 1 photos = result.find('photos').findall('photo') if photos: for photo in photos: photoid = int(photo.attrib['id']) if photoid not in ids: ids.append(photoid) #output.write("%s %s\n" %(photo.attrib['longitude'], photo.attrib['latitude'])) dateupload = int(photo.attrib['dateupload']) if dateupload<tempMaxDate: tempMaxDate = dateupload utcdate = datetime.utcfromtimestamp(dateupload) if utcdate > newestDate: