예제 #1
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
예제 #2
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
            dateTakenGranularity = configdict.get('date_taken_granularity', '0')
            dateTaken = datePosted = ''
            if configdict.get('override_dates', '0') == '1':
                #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)
                stats=os.stat(image)
                dateTaken = time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime(stats.st_mtime))
            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' or exiftags == {}:
                    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.error(sys.exc_info())
        return None
예제 #3
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):
            return None

        try:
            logging.debug("Getting EXIF for %s", image)
            f = open(image, 'rb')
            exiftags = exifread.process_file(f)
            f.close()
            #print exiftags
            #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()

            image_date = None
            image_yyyy = None
            image_yyyy_mm = None
            if 'Image DateTime' in exiftags:
                image_date = exiftags['Image DateTime'].printable
                # print image_date
                date_field = re.search('^(\d{4}):(\d{2}):(\d{2})', image_date)
                if date_field:
                    image_yyyy = date_field.group(1)
                    image_yyyy_mm = "%s-%s" % (date_field.group(1), date_field.group(2),)
		    print image_yyyy
		    print image_yyyy_mm
		
            if configdict.get('full_folder_tags', 'false').startswith('true'):
                realTags = os.path.dirname(folderTag).split(os.sep)
                # Remove empty tags
                realTags = filter(None, realTags)
                # Assumes date is the first field, and add YYYY as tag
                datefield = realTags[0]
                realTags.append(datefield[0:4])
                #
                realTags = (' '.join('"' + item + '"' for item in  realTags))

            picTags = realTags
            #picTags = '#' + folderTag.replace(' ','#') + ' ' + realTags # Do not make a tag of the image path

            if exiftags == {}:
                logging.debug('NO_EXIF_HEADER for %s', image)
            else:
                # 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)
                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.error(sys.exc_info())
        return None
예제 #4
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):
            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'[/\\_.]', ' ', folderTag).strip()
            picTags = '#' + realTags.replace(' ','#')

            # with the full_folder_tags option, the tag for the file is directly its
            # relative path. We use quotes to make it only one tag on Flickr.
            if configdict.get('full_folder_tags', 'false').startswith('true'):
                realTags = '"#' + folderTag + '"' 
                picTags = realTags

            if exiftags == {}:
                logging.debug('NO_EXIF_HEADER for %s', image)
            else:
                # 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)
                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.error(sys.exc_info())
        return None
예제 #5
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):
            return None

        try:
            logging.debug("Getting EXIF for %s", image)
            f = open(image, "rb")
            exiftags = exifread.process_file(f)
            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.replace(" ", "#") + " " + realTags

            if exiftags == {}:
                logging.debug("NO_EXIF_HEADER for %s", image)
            else:
                # 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)
                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.error(sys.exc_info())
        return None
예제 #6
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):
            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.replace(' ', '#') + ' ' + realTags

            if exiftags == {}:
                logging.debug('NO_EXIF_HEADER for %s', image)
            else:
                # 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)
                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.error(sys.exc_info())
        return None