Source code for tagit.model.attributes

"""Extended, optional image attributes.

Part of the tagit module.
A copy of the license is provided with the project.
Author: Matthias Baumgartner, 2016

"""
# STANDARD IMPORTS
import magic

# INNER-MODULE IMPORTS
from ..basics import fst

# CONSTANTS
IMAGE_ATTRIBUTES = ['image', 'mime', 'orientation', 'width', 'height', 'exposure', 'focal_length', 'focal_length_35', 'aperture', 'iso', 'flash']

# EXPORTS
__all__ = ('Attributes_SQLite', 'IMAGE_ATTRIBUTES')

## CODE ##

[docs]class Attributes(object): pass
[docs]class Attributes_SQLite(Attributes): def __init__(self, meta_adapter, conn): self.conn = conn self.meta_adapter = meta_adapter
[docs] def set(self, db_id, path): """Get attributes from EXIF and write them into the database.""" metrics = self.meta_adapter.get_metrics(path) width, height, orientation = self.meta_adapter.get_dimensions(path) metrics.update({'width': width, 'height': height, 'orientation': orientation}) metrics.update({'mime': magic.from_file(path, mime=True)}) if 'exposure' in metrics: metrics['exposure'] = 1.0 / metrics['exposure'] query = "INSERT OR REPLACE INTO attribute (" query += 'image, ' query += ', '.join(metrics.keys()) query += ') VALUES (' query += '?, ' query += ', '.join('?' * len(metrics)) query += ')' self.conn.execute(query, [db_id] + metrics.values())
def get(self, image, attribute): if attribute not in IMAGE_ATTRIBUTES: raise Exception('Invalid attribute') query = "SELECT {0} FROM attribute JOIN image on attribute.image = image.id WHERE image.path = ?".format(attribute) # FIXME: Dangerous SQL! metrics = self.conn.execute(query, (image, )).fetchall() if len(metrics) > 0: value = fst(metrics[0]) if value is None or value == 0: return None return value return None # Getters # FIXME: There's surely an easier way via DB abstraction... def orientation(self, image): return self.get(image, 'orientation') def mime(self, image): return self.get(image, 'mime') def width(self, image): return self.get(image, 'width') def height(self, image): return self.get(image, 'height') def exposure(self, image): return self.get(image, 'exposure') def focal_length(self, image): return self.get(image, 'focal_length') def focal_length_35(self, image): return self.get(image, 'focal_length_35') def aperture(self, image): return self.get(image, 'aperture') def iso(self, image): return self.get(image, 'iso') def flash(self, image): return self.get(image, 'flash')
[docs] def query(self, attributes=None, ranges=None): """ """ joins, conds, binds = [], [], [] if attributes is None or ranges is None or len(attributes) == 0: return joins, conds, binds assert len(attributes) == len(ranges) joins.append('attribute ON image.id = attribute.image') for attr, (lo, hi) in zip(attributes, ranges): if attr not in IMAGE_ATTRIBUTES: raise Exception('Invalid attribute') conds.append('attribute.{0} >= ?'.format(attr)) conds.append('attribute.{0} <= ?'.format(attr)) binds.append(lo) binds.append(hi) return joins, conds, binds ## EOF ##