Exemple #1
0
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