def _creatSet(photoSet, setName, existingSets): """ Creates or updates a set on flickr with the given photos. """ setName = setName.replace('\\', ' ') setName = setName.replace('/', ' ') setName = setName.strip() photos = [] #real photo objects for photo in photoSet: photos.append(flickr.Photo(id=photo)) fset = None unicodeSetName = setName.decode(sys.getfilesystemencoding()) #check if set with the name exists already generate = 'Generating' for existingSet in existingSets: if existingSet.title == unicodeSetName: fset = existingSet logging.debug('tags2set: Found existing set %s', setName) generate = 'Updating' break msg = "%s set %s with %d pictures" % (generate, setName, len(photoSet)) logging.debug(msg) print msg try: if (fset == None): logging.debug("tags2set: create set %s with photo %s", setName, photos[0]) fset = flickr.Photoset.create(photos[0], setName, SET_DESC) logging.debug('tags2set: created new set %s', setName) except Exception, ex: logging.error('tags2set: Cannot create set "%s"', setName) logging.error(str(ex)) logging.error(sys.exc_info()[0])
def uploadImage(self, image): """ Upload a single image. Returns the photoid, or None on failure. """ folderTag = image[len(IMAGE_DIR):] if self.uploaded.has_key(folderTag): stats = os.stat(image) logging.debug('The file %s already exists: mtime=%d, size=%d', image, stats.st_mtime, stats.st_size) data = self.uploaded[folderTag] if not isinstance(data, tuple): logging.error( 'Should not have non-tuple data but continuing in any case' ) self.uploaded[folderTag] = (data, stats.st_mtime, stats.st_size) return None else: photo_id = data[0] mtime = data[1] filesize = data[2] if mtime != stats.st_mtime or filesize != stats.st_size: logging.info('File has changed since previous time') logging.info('Removing %s from Flickr before updating', data[0]) photo = flickr.Photo(data[0]) try: photo.delete() del self.uploaded[folderTag] del self.uploaded[photo_id] except flickr.FlickrError: logging.info('File does not exist, adding') else: return None try: logging.debug("Getting EXIF for %s", image) f = open(image, 'rb') try: exiftags = exifread.process_file(f) except MemoryError: exiftags = {} f.close() #print exiftags[XPKEYWORDS] #print folderTag # make one tag equal to original file path with spaces replaced by # # and start it with # (for easier recognition) since space is # used as TAG separator by flickr # this is needed for later syncing flickr with folders # look for / \ _ . and replace them with SPACE to make real Tags realTags = re.sub(r'[/\\_.]', ' ', os.path.dirname(folderTag)).strip() if configdict.get('full_folder_tags', 'false').startswith('true'): realTags = os.path.dirname(folderTag).split(os.sep) realTags = (' '.join('"' + item + '"' for item in realTags)) picTags = '"#' + folderTag + '" ' + realTags #check if we need to override photo dates if configdict.get('override_dates', '0') == '1': dateTaken = datePosted = '' dateTakenGranularity = configdict.get('date_taken_granularity', '0') #fixed take date if configdict.get('date_taken_type', '0') == '2': datePosted = configdict.get('date_posted_fixed', '') #fixed post date if configdict.get('date_posted_type', '0') == '2': datePosted = configdict.get('date_posted_fixed', '') #Use year and month from config ini, then calculate end of month (note: Flickr does not accept future dates. You'll get current date maximum) if configdict.get('date_posted_granularity', '0') == '4': datePostedY = int( datetime.fromtimestamp(datePosted).strftime("%Y")) datePostedM = int( datetime.fromtimestamp(datePosted).strftime("%m")) datePostedD = calendar.monthrange( datePostedY, datePostedM)[1] datePosted = int( (datetime(datePostedY, datePostedM, datePostedD, 23, 59, 59) - datetime(1970, 1, 1)).total_seconds()) #Use year from config ini, then calculate end of year (note: Flickr does not accept future dates. You'll get current date maximum) if configdict.get('date_posted_granularity', '0') == '6': datePostedY = int( datetime.fromtimestamp(datePosted).strftime("%Y")) datePosted = int( (datetime(datePostedY, 12, 31, 23, 59, 59) - datetime(1970, 1, 1)).total_seconds()) #Convert timestamp to GMT zone dateZone = configdict.get('date_posted_utc', '0') if dateZone != '0': datePosted = datePosted - int(dateZone) * 3600 if exiftags == {}: logging.debug('NO_EXIF_HEADER for %s', image) else: if configdict.get('override_dates', '0') == '1': if 'EXIF DateTimeDigitized' in exiftags: dateExif = str(exiftags['EXIF DateTimeDigitized']) dateExif = dateExif[0:10].replace(':', '-') + dateExif[10:] dateUnix = int((datetime( int(dateExif[0:4]), int(dateExif[5:7]), int(dateExif[8:10]), int(dateExif[11:13]), int(dateExif[14:16]), int(dateExif[17:19])) - datetime(1970, 1, 1)).total_seconds()) if configdict.get('date_taken_type', '0') == '1': dateTaken = dateExif if configdict.get('date_posted_type', '0') == '1': datePosted = dateUnix #Use year and month from dateExif, then calculate end of month (note: Flickr does not accept future dates. You'll get current date maximum) if configdict.get('date_posted_granularity', '0') == '4': datePostedY = int( datetime.fromtimestamp( datePosted).strftime("%Y")) datePostedM = int( datetime.fromtimestamp( datePosted).strftime("%m")) datePostedD = calendar.monthrange( datePostedY, datePostedM)[1] datePosted = int( (datetime(datePostedY, datePostedM, datePostedD, 23, 59, 59) - datetime(1970, 1, 1)).total_seconds()) #Use year from dateExif, then calculate end of year (note: Flickr does not accept future dates. You'll get current date maximum) if configdict.get('date_posted_granularity', '0') == '6': datePostedY = int( datetime.fromtimestamp( datePosted).strftime("%Y")) datePosted = int(( datetime(datePostedY, 12, 31, 23, 59, 59) - datetime(1970, 1, 1)).total_seconds()) #Convert timestamp to GMT zone dateZone = configdict.get('date_posted_utc', '0') if dateZone != '0': datePosted = datePosted - int(dateZone) * 3600 # look for additional tags in EXIF to tag picture with if XPKEYWORDS in exiftags: printable = exiftags[XPKEYWORDS].printable if len(printable) > 4: exifstring = exifread.make_string(eval(printable)) picTags += exifstring.replace(';', ' ') picTags = picTags.strip() logging.info("Uploading image %s with tags %s", image, picTags) photo = ('photo', image, open(image, 'rb').read()) d = { api.token: str(self.token), api.perms: str(self.perms), "tags": str(picTags), "hidden": str(FLICKR["hidden"]), "is_public": str(FLICKR["is_public"]), "is_friend": str(FLICKR["is_friend"]), "is_family": str(FLICKR["is_family"]) } sig = signCall(d) d[api.sig] = sig d[api.key] = FLICKR[api.key] url = buildRequest(api.upload, d, (photo, )) res = getResponse(url) if isGood(res): logging.debug("successful.") photoid = str(res.photoid.text) self.logUpload(photoid, folderTag, image) if configdict.get('override_dates', '0') == '1': self.overrideDates(image, photoid, datePosted, dateTaken, dateTakenGranularity) return photoid else: print "problem.." reportError(res) except KeyboardInterrupt: logging.debug("Keyboard interrupt seen, abandon uploads") print "Stopping uploads..." self.abandonUploads = True return None except: logging.exception("Upload failed") return None