# -*- coding: utf-8 -*-
"""Location database."""

import logging
import os

from sqlalchemy import (
    Column,
    MetaData,
    Table,
    create_engine,
)
from sqlalchemy.types import (
    DateTime,
    Float,
    String,
)
from xdg import BaseDirectory

logger = logging.getLogger(__name__)


class Database(object):

    """Generic database object.

    This class is subclassed to provide additional functionality specific to
    artifacts and/or documents.

    :param db_filename: Path to the sqlite database file
    :type db_filename: str

    """

    def __init__(self, db_filename):
        """Connect to database and create session object."""
        self.db_filename = db_filename
        self.engine = create_engine(
            'sqlite:///{}'.format(db_filename),
        )
        self.connection = None
        self.metadata = MetaData(bind=self.engine)

    def connect(self):
        """Create connection."""
        logger.debug('Connecting to SQLite database: %r', self.db_filename)
        self.connection = self.engine.connect()

    def disconnect(self):
        """Close connection."""
        assert not self.connection.closed
        logger.debug(
            'Disconnecting from SQLite database: %r', self.db_filename)
        self.connection.close()

    def __enter__(self):
        """Connect on entering context."""
        self.connect()
        return self

    def __exit__(self, exc_type, exc_value, traceback):
        """Disconnect on exiting context."""
        self.disconnect()

    def __getitem__(self, table_name):
        """Get table object in database.

        :param table_name: Name of the table
        :type table_name: str
        :return: Table object that can be used in queries
        :rtype: sqlalchemy.schema.Table

        """
        if not isinstance(table_name, basestring):
            raise TypeError('Unexpected table name: {}'.format(table_name))
        table = self.metadata.tables.get(table_name)
        if table is None:
            table = Table(table_name, self.metadata, autoload=True)
        return table


class LocationDB(Database):

    """Location database.

    Store location information from picture files into a sqlite database.

    """

    def __init__(self):
        """Create database if needed."""
        base_directory = BaseDirectory.save_data_path('pic2map')
        db_filename = os.path.join(base_directory, 'location.db')
        Database.__init__(self, db_filename)

        if not os.path.isfile(db_filename):
            logger.debug('Creating location database %r...', db_filename)

            location_table = Table(
                'location',
                self.metadata,
                Column('filename', String),
                Column('latitude', Float),
                Column('longitude', Float),
                Column('timestamp', DateTime),
            )
            location_table.create()

@@ -43,16 +43,32 @@
 se.%22%22%22%0A%0A
+import datetime%0A
 import l
@@ -2917,12 +2917,964 @@
 le.create()%0A
+%0A%0Adef transform_metadata_to_row(metadata):%0A    %22%22%22Transform GPS metadata in database rows.%0A%0A    :param metadata: GPS metadata as returned by exiftool%0A    :type metadata: dict(str)%0A    :returns: Database row%0A    :rtype: dict(str)%0A%0A    %22%22%22%0A    new_metadata = %7B%0A        'filename': metadata%5B'SourceFile'%5D,%0A        'latitude': metadata%5B'EXIF:GPSLatitude'%5D,%0A        'longitude': metadata%5B'EXIF:GPSLongitude'%5D,%0A    %7D%0A%0A    if metadata%5B'EXIF:GPSLatitudeRef'%5D == u'S':%0A        new_metadata%5B'latitude'%5D *= -1%0A    if metadata%5B'EXIF:GPSLongitudeRef'%5D == u'W':%0A        new_metadata%5B'longitude'%5D *= -1%0A%0A    if ('EXIF:GPSDateStamp' in metadata and%0A            'EXIF:GPSTimeStamp' in metadata):%0A        datetime_str = u'%7B%7D#%7B%7D'.format(%0A            metadata%5B'EXIF:GPSDateStamp'%5D,%0A            metadata%5B'EXIF:GPSTimeStamp'%5D,%0A        )%0A%0A        new_metadata%5B'datetime'%5D = datetime.datetime.strptime(%0A            datetime_str, u'%25Y:%25m:%25d#%25H:%25M:%25S')%0A%0A    return new_metadata%0A

Add metadata transformation function