Example #1
0
    def __init__(self, output_dir, search_dirs=None):
        self.output_dir = output_dir
        self.search_dirs = search_dirs

        if self.search_dirs is None:
            self.search_dirs = []

        self.zapi = ZooomrApi(API_KEY, SHARED_SECRET, 'write')
        self.meta_handler = MetaHandler()
Example #2
0
class ZooomrTouchr(object):

    def __init__(self, output_dir, search_dirs=None):
        self.output_dir = output_dir
        self.search_dirs = search_dirs

        if self.search_dirs is None:
            self.search_dirs = []

        self.zapi = ZooomrApi(API_KEY, SHARED_SECRET, 'write')
        self.meta_handler = MetaHandler()

    def find_local_photo(self, paths, metadata):

        if 'date_created' not in metadata:
            return []

        files_found = []
        for path in paths:
            date = metadata['date_created']
            date_str = '%d/%02d/%02d' % (date.year, date.month, date.day) 
            path = os.path.join(path, date_str)

            for dirpath, dirnames, filenames in os.walk(path):
                for filename in filenames:
                    filepath = os.path.join(dirpath, filename)
                    filedate = self.meta_handler.get_datetime_created(filepath)

                    if date == filedate:
                        logger.debug('found matching local photo: %s', filename)
                        files_found.append((dirpath, filename))

        ## sort images by modified date
        return sorted(files_found, cmp=self.cmp_file_mtime)

    def download_metadata(self, xml):
        metadata = {}

        photo_xml = xml.find('photo')
        metadata['id'] = photo_xml.get('id')

        for name in ['title', 'description']:
            metadata[name] = photo_xml.find(name).text
        
        metadata['license'] = LICENSES[int(photo_xml.get('license', 0))]

        timestamp = photo_xml.find('dates').get('posted')
        metadata['date_posted'] = datetime.datetime.utcfromtimestamp(float(timestamp))

        ##FIXME: What about other machine tags??
        metadata['tags'] = []
        for label in photo_xml.findall('tags/tag'):
            ## tags/keywords: rc="labels" rda="Penticton" rdi="penticton"
            if label.get('rc') == 'labels':
                metadata['tags'].append(label.get('rda'))

            ## rc="camera" rda="2011:08:29 00:26:14Z" rdi="createdate"
            elif label.get('rc') == 'camera':
                if label.get('rdi') == 'createdate':
                    date_str = label.get('rda')[:19]
                    metadata['date_created'] = datetime.datetime.strptime(
                        date_str,
                        "%Y:%m:%d %H:%M:%S"
                    )
                elif label.get('rdi') == 'datetime':
                    if 'date_created' not in metadata:
                        metadata['date_created'] = datetime.datetime.strptime(
                            label.get('rda')[:19].replace(' ', ':'),
                            "%Y:%m:%d:%H:%M:%S" 
                        )
                elif label.get('rdi') == 'imageheight':
                    metadata['height'] = int(label.get('rda'))
                elif label.get('rdi') == 'imagewidth':
                    metadata['width'] = int(label.get('rda'))

        ## extract visibility Zooomr settings
        for key in ['isfamily', 'isfriend', 'ispublic']:
            metadata[key] = photo_xml.find('visibility').get(key, 0)

        ##TODO: people & notes 

        urls = {}
        for url_xml in photo_xml.findall('urls/url'):
            urls[url_xml.get('type')] = url_xml.text

        ## get geo info
        metadata.update(
            self.zapi.get_geo_location(urls['photopage'])
        )

        return metadata 

    def download_photo(self, photo_id):
        try:
            resp = self.zapi.photos_getInfo(photo_id=photo_id)
        except ZooomrError as inst:
            logger.error(inst.strerror)
            return None

        photo_url = self.zapi.get_photo_url(resp.find('photo'), Size.ORIGINAL)
        filename = "%s.%s" % (
            resp.find('photo').get('id'), 
            resp.find('photo').get('originalformat')
        )
        path = os.path.join(self.output_dir, filename)
                
        metadata = self.download_metadata(resp)

        if not os.path.exists(path):
            logger.debug('start retrieving original photo')

            try:
                photo_data = urllib2.urlopen(photo_url, timeout=10)
                with open(path, 'wb') as photo_file:
                    photo_file.write(photo_data.read())
            except urllib2.URLError:
                logger.debug('cannot download image, search in local dir')
                ## search in local directory
                matching_files = self.find_local_photo(self.search_dirs, metadata)

                if len(matching_files) == 0:
                    logger.error(
                        'could not find or download file for ID #%s', 
                        resp.find('photo').get('id')
                    )
                else:
                    origin = os.path.join(matching_files[0][0], matching_files[0][1])
                    shutil.copy(origin, path)
                    shutil.copystat(origin, path)

        return filename, metadata

    @staticmethod
    def cmp_file_mtime(fa, fb):
        fa_date = os.path.getmtime(os.path.join(*fa))
        fb_date = os.path.getmtime(os.path.join(*fb))
        return cmp(fb_date, fa_date)