def publish_composite_model(cursor, model, parent_model, publisher, message): """Publishes the ``model`` and return its ident_hash.""" if not isinstance(model, CompositeDocument): raise ValueError("This function only publishes CompositeDocument " "objects. '{}' was given.".format(type(model))) if issequence(publisher) and len(publisher) > 1: raise ValueError("Only one publisher is allowed. '{}' " "were given: {}".format(len(publisher), publisher)) module_ident, ident_hash = _insert_metadata(cursor, model, publisher, message) for resource in model.resources: _insert_resource_file(cursor, module_ident, resource) html = str(cnxepub.DocumentContentFormatter(model)) fileid, _ = _insert_file(cursor, io.BytesIO(html.encode('utf-8')), 'text/html') file_arg = { 'module_ident': module_ident, 'parent_ident_hash': parent_model.ident_hash, 'fileid': fileid, } cursor.execute( """\ INSERT INTO collated_file_associations (context, item, fileid) VALUES ((SELECT module_ident FROM modules WHERE ident_hash(uuid, major_version, minor_version) = %(parent_ident_hash)s), %(module_ident)s, %(fileid)s)""", file_arg) model.id, model.metadata['version'] = split_ident_hash(ident_hash) model.set_uri('cnx-archive', ident_hash) return ident_hash
def publish_model(cursor, model, publisher, message): """Publishes the ``model`` and return its ident_hash.""" publishers = publisher if isinstance(publishers, list) and len(publishers) > 1: raise ValueError("Only one publisher is allowed. '{}' " "were given: {}".format(len(publishers), publishers)) module_ident, ident_hash = _insert_metadata(cursor, model, publisher, message) for resource in getattr(model, 'resources', []): _insert_resource_file(cursor, module_ident, resource) if isinstance(model, Document): html = str(cnxepub.DocumentContentFormatter(model)).encode('utf-8') sha1 = hashlib.new('sha1', html).hexdigest() cursor.execute("SELECT fileid FROM files WHERE sha1 = %s", (sha1, )) try: fileid = cursor.fetchone()[0] except TypeError: file_args = { 'media_type': 'text/html', 'data': psycopg2.Binary(html), } cursor.execute( """\ insert into files (file, media_type) VALUES (%(data)s, %(media_type)s) returning fileid""", file_args) fileid = cursor.fetchone()[0] args = { 'module_ident': module_ident, 'filename': 'index.cnxml.html', 'fileid': fileid, } cursor.execute( """\ INSERT INTO module_files (module_ident, fileid, filename) VALUES (%(module_ident)s, %(fileid)s, %(filename)s)""", args) elif isinstance(model, Binder): tree = cnxepub.model_to_tree(model) tree = _insert_tree(cursor, tree) return ident_hash
def publish_collated_document(cursor, model, parent_model): """Publish a given `module`'s collated content in the context of the `parent_model`. Note, the model's content is expected to already have the collated content. This will just persist that content to the archive. """ html = str(cnxepub.DocumentContentFormatter(model)).encode('utf-8') sha1 = hashlib.new('sha1', html).hexdigest() cursor.execute("SELECT fileid FROM files WHERE sha1 = %s", (sha1, )) try: fileid = cursor.fetchone()[0] except TypeError: file_args = { 'media_type': 'text/html', 'data': psycopg2.Binary(html), } cursor.execute( """\ INSERT INTO files (file, media_type) VALUES (%(data)s, %(media_type)s) RETURNING fileid""", file_args) fileid = cursor.fetchone()[0] args = { 'module_ident_hash': model.ident_hash, 'parent_ident_hash': parent_model.ident_hash, 'fileid': fileid, } stmt = """\ INSERT INTO collated_file_associations (context, item, fileid) VALUES ((SELECT module_ident FROM modules WHERE ident_hash(uuid, major_version, minor_version) = %(parent_ident_hash)s), (SELECT module_ident FROM modules WHERE ident_hash(uuid, major_version, minor_version) = %(module_ident_hash)s), %(fileid)s)""" cursor.execute(stmt, args)
def derive_resources(request, document): from .models import ArchiveConnectionError, Resource settings = request.registry.settings archive_url = settings['archive.url'] path = urlparse.unquote(request.route_path('get-resource', hash='{}')) resources = {} for r in document.references: if r.uri.startswith('/resources'): if not resources.get(r.uri): url = urlparse.urljoin(archive_url, r.uri) try: response = requests.get(url) except requests.exceptions.ConnectionError as exc: raise ArchiveConnectionError(exc.message) if response.status_code >= 400: continue content_type = response.headers['content-type'] resources[r.uri] = Resource(content_type, io.BytesIO(response.content)) yield resources[r.uri] r.bind(resources[r.uri], path) html = cnxepub.DocumentContentFormatter(document) document.metadata['content'] = str(html)