You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Lark/hashdb.py

121 lines
3.5 KiB
Python

'''
hashdb.py
'''
import collections
import dataclasses
import hashlib
import sqlite3
import uuid
import sqlalchemy
import sqlalchemy.ext.declarative
import sqlalchemy.orm
# TODO: l o g g i n g
HASH_CHUNK_SIZE = 10485760 # 10mb
_db_session_maker = sqlalchemy.orm.sessionmaker()
ImageData = collections.namedtuple('ImageData', 'UUID, sha1sum, filename, release_group')
ReleaseGroupData = collections.namedtuple('ReleaseGroupData', 'UUID, name, platform')
DatData = collections.namedtuple('DatData', 'UUID, name, website, version, image_list')
def _uuidgen():
return str(uuid.uuid4())
_SQLBase = sqlalchemy.ext.declarative.declarative_base()
class Platform(_SQLBase):
__tablename__ = 'platforms'
id = sqlalchemy.Column(sqlalchemy.Integer, sqlalchemy.Sequence('platform_id_sequence'),
primary_key=True)
uuid = sqlalchemy.Column(sqlalchemy.String, nullable=False, default=_uuidgen)
fullname = sqlalchemy.Column(sqlalchemy.String, nullable=False)
shortcode = sqlalchemy.Column(sqlalchemy.String, unique=True, nullable=False)
def __repr__(self):
return 'id: %s, uuid: %s, fullname: %s, shortcode: %s' % (self.id, self.uuid,
self.fullname, self.shortcode)
# TODO: This should go in the eventual romdb class.
def get_file_sha1sum(filename):
sha1sum = hashlib.sha1()
with open(filename, 'rb') as file_contents:
while True:
chunk = file_contents.read(HASH_CHUNK_SIZE)
if not chunk:
break
sha1sum.update(chunk)
return sha1sum.hexdigest()
class MetadataDB:
def __init__(self, db_path):
'''
If db file does not exist, create it and create necessary tables.
Either way, create a connection object.
'''
# TODO: This process needs real error handling.
# TODO: Add DAT import/credit support.
self._engine = sqlalchemy.create_engine('sqlite:///%s' % db_path)
_SQLBase.metadata.create_all(self._engine)
_db_session_maker.configure(bind=self._engine)
# TODO: Using One Big Session may have unintended consequences in other, less linear
# applications. For now, it works.
self._session = _db_session_maker()
def add_image(self, image_data):
pass
def update_image(self, image_data):
pass
def remove_image(self, image_data):
pass
def add_release_group(self, release_group_data):
pass
def update_release_group(self, release_group_data):
pass
def remove_release_group(self, release_group_data):
pass
def add_platform(self, platform):
''' Add a platform shortcode to the database. '''
self._session.add(platform)
self._session.commit()
def update_platform(self, platform):
pass
def remove_platform(self, platform):
'''Remove a specific platform from the database. '''
self._session.delete(platform)
self._session.commit()
def search_platforms(self, inclusive=True, **constraints):
'''Search for platforms, given the parameters. '''
query = self._session.query(Platform)
for key, value in constraints.items():
query = query.filter(getattr(Platform, key).ilike('%%%s%%' % value))
platform_list = []
for platform in query:
platform_list.append(platform)
return platform_list
def add_dat(self, dat_data):
pass
def update_dat(self, dat_data):
pass
def remove_dat(self, dat_data):
pass