예제 #1
0
def create_epub(ident_hash, file, format='raw'):
    """Creates an epub from an ``ident_hash``, which is output to the given
    ``file`` (a file-like object).
    Returns None, writes to the given ``file``.

    """
    model = factory(ident_hash, baked=(format != 'raw'))
    if isinstance(model, cnxepub.Document):
        model = cnxepub.TranslucentBinder(nodes=[model])
    cnxepub.make_epub(model, file)
예제 #2
0
def tree_to_nodes(tree, context=None, metadata=None):
    """Assembles ``tree`` nodes into object models.
    If ``context`` is supplied, it will be used to contextualize
    the contents of the nodes. Metadata will pass non-node identifying
    values down to child nodes, if not overridden (license, timestamps, etc)
    """
    nodes = []
    for item in tree['contents']:
        if 'contents' in item:
            sub_nodes = tree_to_nodes(item, context=context, metadata=metadata)
            if metadata is None:
                metadata = {}
            else:
                metadata = metadata.copy()
                for key in ('title', 'id', 'shortid', 'cnx-archive-uri',
                            'cnx-archive-shortid'):
                    if key in metadata:
                        metadata.pop(key)

            for key in ('title', 'id', 'shortId'):
                if item.get(key):
                    metadata[key] = item[key]
                    if item[key] != 'subcol':
                        if key == 'id':
                            metadata['cnx-archive-uri'] = item[key]
                        elif key == 'shortId':
                            metadata['cnx-archive-shortid'] = item[key]

            titles = _title_overrides_from_tree(item)
            if item.get('id') is not None:
                tbinder = cnxepub.Binder(item.get('id'),
                                         sub_nodes,
                                         metadata=metadata,
                                         title_overrides=titles)
            else:
                tbinder = cnxepub.TranslucentBinder(sub_nodes,
                                                    metadata=metadata,
                                                    title_overrides=titles)
            nodes.append(tbinder)
        else:
            doc = document_factory(item['id'], context=context)
            for key in ('title', 'id', 'shortId'):
                if item.get(key):
                    doc.metadata[key] = item[key]
                    if key == 'id':
                        doc.metadata['cnx-archive-uri'] = item[key]
                    elif key == 'shortId':
                        doc.metadata['cnx-archive-shortid'] = item[key]
            nodes.append(doc)
    return nodes
예제 #3
0
    def setUp(self, cursor):
        super(RemoveBakedTestCase, self).setUp()
        binder = use_cases.setup_COMPLEX_BOOK_ONE_in_archive(self, cursor)
        cursor.connection.commit()
        publisher = 'ream'
        msg = 'part of collated publish'

        # Build some new metadata for the composite document.
        metadata = [
            x.metadata.copy() for x in cnxepub.flatten_to_documents(binder)
        ][0]
        del metadata['cnx-archive-uri']
        del metadata['version']
        metadata['created'] = None
        metadata['revised'] = None
        metadata['title'] = "Made up of other things"

        # Add some fake collation objects to the book.
        content = '<p>composite</p>'
        composite_doc = cnxepub.CompositeDocument(None, content, metadata)
        composite_section = cnxepub.TranslucentBinder(
            nodes=[composite_doc], metadata={'title': "Other things"})

        baked_doc_content = '<p>collated</p>'

        def cnxepub_collate(binder_model, ruleset=None, includes=None):
            binder_model[0][0].content = baked_doc_content
            binder_model.append(composite_section)
            return binder_model

        with mock.patch('cnxpublishing.bake.collate_models') as mock_collate:
            mock_collate.side_effect = cnxepub_collate
            from cnxpublishing.bake import bake
            fake_recipe_id = 1
            errors = bake(binder,
                          fake_recipe_id,
                          publisher,
                          msg,
                          cursor=cursor)

        self.ident_hash = binder.ident_hash
        self.composite_ident_hash = composite_doc.ident_hash
        self.baked_doc_sha1 = self._get_file_sha1(cursor, binder[0][0], binder)
        self.composite_doc_sha1 = self._get_file_sha1(cursor, composite_doc,
                                                      binder)
예제 #4
0
def tree_to_nodes(tree, context=None):
    """Assembles ``tree`` nodes into object models.
    If ``context`` is supplied, it will be used to contextualize
    the contents of the nodes.

    """
    nodes = []
    for item in tree['contents']:
        if 'contents' in item:
            sub_nodes = tree_to_nodes(item, context=context)
            titles = _title_overrides_from_tree(item)
            metadata = {}
            for key in ('title', 'id', 'shortId'):
                if item.get(key):
                    metadata[key] = item[key]
                    if item[key] != 'subcol':
                        if key == 'id':
                            metadata['cnx-archive-uri'] = item[key]
                        elif key == 'shortId':
                            metadata['cnx-archive-shortid'] = item[key]
            if item.get('id') is not None:
                tbinder = cnxepub.Binder(item.get('id'),
                                         sub_nodes,
                                         metadata=metadata,
                                         title_overrides=titles)
            else:
                tbinder = cnxepub.TranslucentBinder(sub_nodes,
                                                    metadata=metadata,
                                                    title_overrides=titles)
            nodes.append(tbinder)
        else:
            doc = document_factory(item['id'], context=context)
            for key in ('title', 'id', 'shortId'):
                if item.get(key):
                    doc.metadata[key] = item[key]
                    if key == 'id':
                        doc.metadata['cnx-archive-uri'] = item[key]
                    elif key == 'shortId':
                        doc.metadata['cnx-archive-shortid'] = item[key]
            nodes.append(doc)
    return nodes
예제 #5
0
 cnxepub.TranslucentBinder(
     metadata={u'title': u'Part One'},
     nodes=[
         cnxepub.TranslucentBinder(
             metadata={u'title': u'Chapter One'},
             title_overrides=['Document One'],
             nodes=[
                 cnxepub.Document(
                     id=u'2cf4d7d3@draft',
                     data=
                     u'<p class="para">If you finish the book, there will be cake.</p><img src="../resources/{}">'
                     .format(RESOURCE_ONE_FILENAME),
                     resources=[
                         cnxepub.Resource(
                             RESOURCE_ONE_FILENAME,
                             _read_file(RESOURCE_ONE_FILEPATH, 'rb'),
                             'image/png',
                             filename=RESOURCE_ONE_FILENAME)
                     ],
                     metadata={
                         u'title':
                         u'Document One of Infinity',
                         u'created':
                         u'2013/03/19 15:01:16 -0500',
                         u'revised':
                         u'2013/03/19 15:01:16 -0500',
                         u'keywords': [u'South Africa'],
                         u'subjects': [
                             u'Mathematics and Statistics',
                         ],
                         u'summary':
                         u"<span xmlns='http://www.w3.org/1999/xhtml'>descriptive text</span>",
                         u'language':
                         u'en',
                         u'license_text':
                         u'CC-By 4.0',
                         u'license_url':
                         u'http://creativecommons.org/licenses/by/4.0/',
                         u'authors': [{
                             u'id': u'marknewlyn',
                             u'name': u'Mark Horner',
                             u'type': u'cnx-id'
                         }, {
                             u'id': u'charrose',
                             u'name': u'Charmaine St. Rose',
                             u'type': u'cnx-id'
                         }, {
                             u'id': u'sarblyth',
                             u'name': u'Sarah Blyth',
                             u'type': u'cnx-id'
                         }],
                         u'copyright_holders': [{
                             u'id': u'ream',
                             u'name': u'Ream',
                             u'type': u'cnx-id'
                         }],
                         u'editors': [{
                             u'id': u'impicky',
                             u'name': u'I. M. Picky',
                             u'type': u'cnx-id'
                         }],
                         u'illustrators': [{
                             u'id': u'frahablar',
                             u'name': u'Francis Hablar',
                             u'type': u'cnx-id'
                         }],
                         u'publishers': [{
                             u'id': u'ream',
                             u'name': u'Ream',
                             u'type': u'cnx-id'
                         }, {
                             u'id': u'rings',
                             u'name': u'Rings',
                             u'type': u'cnx-id'
                         }],
                         u'translators': [{
                             u'id': u'frahablar',
                             u'name': u'Francis Hablar',
                             u'type': u'cnx-id'
                         }],
                         u'print_style':
                         u'*print style*',
                     }),
             ]),
     ]),
예제 #6
0
    def test(self, cursor):
        binder = use_cases.setup_COMPLEX_BOOK_ONE_in_archive(self, cursor)
        cursor.connection.commit()
        publisher = 'ream'
        msg = 'part of collated publish'

        # Build some new metadata for the composite document.
        metadata = [
            x.metadata.copy() for x in cnxepub.flatten_to_documents(binder)
        ][0]
        del metadata['cnx-archive-uri']
        del metadata['version']
        metadata['created'] = None
        metadata['revised'] = None
        metadata['title'] = "Made up of other things"

        # Add some fake collation objects to the book.
        content = '<p>composite</p>'
        composite_doc = cnxepub.CompositeDocument(None, content, metadata)
        composite_section = cnxepub.TranslucentBinder(
            nodes=[composite_doc], metadata={'title': "Other things"})

        baked_doc_content = '<p>collated</p>'

        def cnxepub_collate(binder_model, ruleset=None, includes=None):
            binder_model[0][0].content = baked_doc_content
            binder_model.append(composite_section)
            return binder_model

        fake_recipe_id = 1

        with mock.patch('cnxpublishing.bake.collate_models') as mock_collate:
            mock_collate.side_effect = cnxepub_collate
            errors = self.target(binder, fake_recipe_id, publisher, msg)

        # Ensure the output of the errors.
        self.assertEqual(errors, [])

        # Ensure the original tree is intact.
        cursor.execute("SELECT tree_to_json(%s, %s, FALSE)::json;", (
            binder.id,
            binder.metadata['version'],
        ))
        tree = cursor.fetchone()[0]
        self.assertNotIn(composite_doc.ident_hash,
                         cnxepub.flatten_tree_to_ident_hashes(tree))

        # Ensure the tree as been stamped.
        cursor.execute("SELECT tree_to_json(%s, %s, TRUE)::json;", (
            binder.id,
            binder.metadata['version'],
        ))
        baked_tree = cursor.fetchone()[0]
        self.assertIn(composite_doc.ident_hash,
                      cnxepub.flatten_tree_to_ident_hashes(baked_tree))

        # Ensure the changes to a document content were persisted.
        content_to_check = [
            (
                binder[0][0],
                baked_doc_content,
            ),
            (
                composite_doc,
                content,
            ),
        ]
        for doc, content in content_to_check:
            self.assertIn(content, self._get_baked_file(cursor, doc, binder))