|
|
|
@ -4,7 +4,6 @@ metadata.py
|
|
|
|
Everything needed to interact with the metadata database; namely SQL ORM objects, a context
|
|
|
|
Everything needed to interact with the metadata database; namely SQL ORM objects, a context
|
|
|
|
generator for the actual database, and a handful of convenience functions.
|
|
|
|
generator for the actual database, and a handful of convenience functions.
|
|
|
|
'''
|
|
|
|
'''
|
|
|
|
# TODO: Rename file to metadata.py
|
|
|
|
|
|
|
|
import contextlib
|
|
|
|
import contextlib
|
|
|
|
import collections
|
|
|
|
import collections
|
|
|
|
import hashlib
|
|
|
|
import hashlib
|
|
|
|
@ -28,8 +27,7 @@ def _uuidgen():
|
|
|
|
|
|
|
|
|
|
|
|
_SQLBase = sqlalchemy.ext.declarative.declarative_base()
|
|
|
|
_SQLBase = sqlalchemy.ext.declarative.declarative_base()
|
|
|
|
|
|
|
|
|
|
|
|
# TODO: Rename Image concept to "Release".
|
|
|
|
class Release(_SQLBase):
|
|
|
|
class Image(_SQLBase):
|
|
|
|
|
|
|
|
'''SQLAlchemy ORM class for ROM image metadata.'''
|
|
|
|
'''SQLAlchemy ORM class for ROM image metadata.'''
|
|
|
|
# TODO: Split filenames into more meaningful metadata.
|
|
|
|
# TODO: Split filenames into more meaningful metadata.
|
|
|
|
__tablename__ = 'images'
|
|
|
|
__tablename__ = 'images'
|
|
|
|
@ -41,7 +39,7 @@ class Image(_SQLBase):
|
|
|
|
release_group_id = sqlalchemy.Column(sqlalchemy.Integer,
|
|
|
|
release_group_id = sqlalchemy.Column(sqlalchemy.Integer,
|
|
|
|
sqlalchemy.ForeignKey('release_groups.id'))
|
|
|
|
sqlalchemy.ForeignKey('release_groups.id'))
|
|
|
|
|
|
|
|
|
|
|
|
release_group = sqlalchemy.orm.relationship('ReleaseGroup', back_populates='images')
|
|
|
|
release_group = sqlalchemy.orm.relationship('ReleaseGroup', back_populates='releases')
|
|
|
|
|
|
|
|
|
|
|
|
def __repr__(self):
|
|
|
|
def __repr__(self):
|
|
|
|
return 'ROM Image: id: %s, uuid: %s, sha1sum: %s, filename: %s, release-group: %s' % (
|
|
|
|
return 'ROM Image: id: %s, uuid: %s, sha1sum: %s, filename: %s, release-group: %s' % (
|
|
|
|
@ -57,7 +55,7 @@ class ReleaseGroup(_SQLBase):
|
|
|
|
platform_id = sqlalchemy.Column(sqlalchemy.Integer, sqlalchemy.ForeignKey('platforms.id'))
|
|
|
|
platform_id = sqlalchemy.Column(sqlalchemy.Integer, sqlalchemy.ForeignKey('platforms.id'))
|
|
|
|
|
|
|
|
|
|
|
|
platform = sqlalchemy.orm.relationship('Platform', back_populates='release_groups')
|
|
|
|
platform = sqlalchemy.orm.relationship('Platform', back_populates='release_groups')
|
|
|
|
images = sqlalchemy.orm.relationship('Image', back_populates='release_group')
|
|
|
|
images = sqlalchemy.orm.relationship('Release', back_populates='release_group')
|
|
|
|
|
|
|
|
|
|
|
|
def __repr__(self):
|
|
|
|
def __repr__(self):
|
|
|
|
return 'Release Group: id: %s, uuid: %s, name: %s, platform:%s' % (self.id, self.uuid,
|
|
|
|
return 'Release Group: id: %s, uuid: %s, name: %s, platform:%s' % (self.id, self.uuid,
|
|
|
|
@ -80,19 +78,6 @@ class Platform(_SQLBase):
|
|
|
|
return 'Platform: id: %s, uuid: %s, fullname: %s, shortcode: %s' % (self.id, self.uuid,
|
|
|
|
return 'Platform: id: %s, uuid: %s, fullname: %s, shortcode: %s' % (self.id, self.uuid,
|
|
|
|
self.fullname, self.shortcode)
|
|
|
|
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()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def configure(db_path):
|
|
|
|
def configure(db_path):
|
|
|
|
'''
|
|
|
|
'''
|
|
|
|
Configure and initialize the database for the entire module.
|
|
|
|
Configure and initialize the database for the entire module.
|
|
|
|
@ -106,7 +91,6 @@ def configure(db_path):
|
|
|
|
_db_session_maker.configure(bind=_engine)
|
|
|
|
_db_session_maker.configure(bind=_engine)
|
|
|
|
|
|
|
|
|
|
|
|
# TODO: Passing the session object is a little clunky. Maybe there's a way to infer it somehow?
|
|
|
|
# TODO: Passing the session object is a little clunky. Maybe there's a way to infer it somehow?
|
|
|
|
# Maybe setting a _session class variable?
|
|
|
|
|
|
|
|
def search(session, table_object, **constraints):
|
|
|
|
def search(session, table_object, **constraints):
|
|
|
|
'''
|
|
|
|
'''
|
|
|
|
Search the database for entries matching the given constraints.
|
|
|
|
Search the database for entries matching the given constraints.
|
|
|
|
|