def get_file(hash): """Return the contents of the file as a ``memoryview``.""" stmt = _get_sql('get-file.sql') args = dict(hash=hash) with db_connect() as db_conn: with db_conn.cursor() as cursor: cursor.execute(stmt, args) try: file, _ = cursor.fetchone() except TypeError: raise FileNotFound(hash) return memoryview(file[:])
def inject_resource(ident_hash, file, filename, media_type): """Injects the contents of ``file`` (a file-like object) into the database as ``filename`` with ``media_type`` in association with the content at ``ident_hash``. """ resource_hash = get_file_sha1(file) with db_connect() as db_conn: with db_conn.cursor() as cursor: s_ident_hash = split_ident_hash(ident_hash) module_ident = lookup_module_ident(*s_ident_hash) fileid, resource_hash = insert_file(file, media_type) upsert_module_file(module_ident, fileid, filename) return resource_hash
def get_type(ident_hash): """Return the database type for the given ``ident_hash`` As of now, this could either be a 'Module' or 'Collection'. """ id, version = get_id_n_version(ident_hash) stmt = _get_sql('get-type.sql') args = dict(id=id, version=version) with db_connect() as db_conn: with db_conn.cursor() as cursor: cursor.execute(stmt, args) type = cursor.fetchone()[0] return type
def verify_id_n_version(id, version): """Given an ``id`` and ``version``, verify the identified content exists. """ stmt = _get_sql('verify-id-and-version.sql') args = dict(id=id, version=version) with db_connect() as db_conn: with db_conn.cursor() as cursor: cursor.execute(stmt, args) try: valid = cursor.fetchone()[0] except TypeError: raise NotFound(join_ident_hash(id, version)) return True
def get_tree(ident_hash): """Return a tree structure of the Collection""" id, version = get_id_n_version(ident_hash) stmt = _get_sql('get-tree.sql') args = dict(id=id, version=version) with db_connect() as db_conn: with db_conn.cursor() as cursor: cursor.execute(stmt, args) try: tree = cursor.fetchone()[0] except TypeError: raise NotFound(ident_hash) return tree
def get_tree(ident_hash, baked=False): """Return a tree structure of the Collection""" id, version = get_id_n_version(ident_hash) stmt = _get_sql('get-tree.sql') args = dict(id=id, version=version, baked=baked) with db_connect() as db_conn: with db_conn.cursor() as cursor: cursor.execute(stmt, args) try: tree = cursor.fetchone()[0] except TypeError: raise NotFound(ident_hash) if tree is None: raise NotFound(ident_hash) return tree
def lookup_module_ident(id, version): """Return the ``module_ident`` for the given ``id`` & major and minor version as a tuple. """ with db_connect() as db_conn: with db_conn.cursor() as cursor: cursor.execute( "SELECT module_ident FROM modules " "WHERE uuid = %s " "AND CONCAT_WS('.', major_version, minor_version) = %s", (id, version)) try: mident = cursor.fetchone()[0] except (IndexError, TypeError): ident_hash = join_ident_hash(id, version) raise RuntimeError("Content at {} does not exist." .format(ident_hash)) return mident
def insert_file(file, media_type): """Upsert the ``file`` and ``media_type`` into the files table. Returns the ``fileid`` and ``sha1`` of the upserted file. """ resource_hash = get_file_sha1(file) with db_connect() as db_conn: with db_conn.cursor() as cursor: cursor.execute("SELECT fileid FROM files WHERE sha1 = %s", (resource_hash,)) try: fileid = cursor.fetchone()[0] except (IndexError, TypeError): cursor.execute("INSERT INTO files (file, media_type) " "VALUES (%s, %s)" "RETURNING fileid", (psycopg2.Binary(file.read()), media_type,)) fileid = cursor.fetchone()[0] return fileid, resource_hash
def lookup_module_ident(id, version): """Return the ``module_ident`` for the given ``id`` & major and minor version as a tuple. """ with db_connect() as db_conn: with db_conn.cursor() as cursor: cursor.execute( "SELECT module_ident FROM modules " "WHERE uuid = %s " "AND CONCAT_WS('.', major_version, minor_version) = %s", (id, version)) try: mident = cursor.fetchone()[0] except (IndexError, TypeError): ident_hash = join_ident_hash(id, version) raise RuntimeError( "Content at {} does not exist.".format(ident_hash)) return mident
def get_metadata(ident_hash): """Return the dictionary of metadata from the database. This data is keyed using the cnx-epub data structure. """ id, version = get_id_n_version(ident_hash) stmt = _get_sql('get-metadata.sql') args = dict(id=id, version=version) # FIXME The license_url and license_text metadata attributes need to # change to a License structure similar to what is used in cnx-authoring. with db_connect() as db_conn: with db_conn.cursor() as cursor: cursor.execute(stmt, args) try: metadata = cursor.fetchone()[0] except TypeError: raise NotFound(ident_hash) return metadata
def get_file_info(hash, context=None): """Returns information about the file, identified by ``hash``. If the `context` (an ident-hash) is supplied, the information returned will be specific to that context. """ if context is None: stmt = _get_sql('get-file-info.sql') args = dict(hash=hash) else: stmt = _get_sql('get-file-info-in-context.sql') id, version = get_id_n_version(context) args = dict(hash=hash, id=id, version=version) with db_connect() as db_conn: with db_conn.cursor() as cursor: cursor.execute(stmt, args) try: filename, media_type = cursor.fetchone() except TypeError: raise FileNotFound(hash) return filename, media_type
def insert_file(file, media_type): """Upsert the ``file`` and ``media_type`` into the files table. Returns the ``fileid`` and ``sha1`` of the upserted file. """ resource_hash = get_file_sha1(file) with db_connect() as db_conn: with db_conn.cursor() as cursor: cursor.execute("SELECT fileid FROM files WHERE sha1 = %s", (resource_hash, )) try: fileid = cursor.fetchone()[0] except (IndexError, TypeError): cursor.execute( "INSERT INTO files (file, media_type) " "VALUES (%s, %s)" "RETURNING fileid", ( psycopg2.Binary(file.read()), media_type, )) fileid = cursor.fetchone()[0] return fileid, resource_hash
def get_registered_files(ident_hash): """Returns a list SHA1 hashes for registered file entries identified by the given module ``ident_hash``. Note, it's possible for a module to reference a file without having a registered file entry for it. Note, all files are included, including the raw form of the content. """ id, version = get_id_n_version(ident_hash) stmt = _get_sql('get-registered-files-info.sql') args = dict(id=id, version=version) with db_connect() as db_conn: with db_conn.cursor() as cursor: cursor.execute(stmt, args) rows = cursor.fetchall() if rows is None: rows = [] hashes = list(set([sha1 for sha1, _, __ in rows])) return hashes
def upsert_module_file(module_ident, fileid, filename): """Upsert a file associated with ``fileid`` with ``filename`` as a module_files entry associated with content at ``module_ident``. """ with db_connect() as db_conn: with db_conn.cursor() as cursor: cursor.execute("SELECT true FROM module_files " "WHERE module_ident = %s " "AND filename = %s", (module_ident, filename,)) try: cursor.fetchone()[0] except (IndexError, TypeError): cursor.execute("INSERT INTO module_files " "(module_ident, fileid, filename) " "VALUES (%s, %s, %s)", (module_ident, fileid, filename,)) else: cursor.execute("UPDATE module_files " "SET (fileid) = (%s) " "WHERE module_ident = %s AND filename = %s", (fileid, module_ident, filename,))
def get_content(ident_hash, context=None): """Returns the content for the given ``ident_hash``. ``context`` is optionally ident-hash used to find the content within the context of a Collection. """ id, version = get_id_n_version(ident_hash) filename = 'index.cnxml.html' if context is not None: raise NotImplementedError('cooking has not yet been implemented') stmt = _get_sql('get-content.sql') args = dict(id=id, version=version, filename=filename) with db_connect() as db_conn: with db_conn.cursor() as cursor: cursor.execute(stmt, args) try: content, _ = cursor.fetchone() except TypeError: raise ContentNotFound(ident_hash, context, filename) return content[:]
def get_content(ident_hash, context=None): """Returns the content for the given ``ident_hash``. ``context`` is optionally ident-hash used to find the content within the context of a Collection ident_hash. """ id, version = get_id_n_version(ident_hash) filename = 'index.cnxml.html' if context is not None: stmt = _get_sql('get-baked-content.sql') args = dict(id=id, version=version, context=context) else: stmt = _get_sql('get-content.sql') args = dict(id=id, version=version, filename=filename) with db_connect() as db_conn: with db_conn.cursor() as cursor: cursor.execute(stmt, args) try: content, _ = cursor.fetchone() except TypeError: raise ContentNotFound(ident_hash, context, filename) return content[:]