예제 #1
0
def test_append_items(outlines_doc):
    # Simple check that we can write new objects
    # without failing the object duplicate checks
    with outlines_doc.open_outline(strict=True) as outline:
        new_item = OutlineItem('Four')
        new_item.children.extend([OutlineItem('Four-A'), OutlineItem('Four-B')])
        outline.root.append(new_item)

    with outlines_doc.open_outline(strict=True):
        list(outline.root)
예제 #2
0
def test_new_item(resources, title, page_num, page_loc):
    doc = Pdf.open(resources / 'outlines.pdf')
    kwargs = dict.fromkeys(ALL_PAGE_LOCATION_KWARGS, 100)
    page_ref = doc.pages[page_num]

    new_item = OutlineItem(title, page_num, page_loc, **kwargs)
    with doc.open_outline() as outline:
        outline.root.append(new_item)
    if isinstance(page_loc, PageLocation):
        loc_str = page_loc.name
    else:
        loc_str = page_loc
    if loc_str == 'FitR':
        kwarg_len = 4
    elif loc_str == 'XYZ':
        kwarg_len = 3
    elif loc_str in ('FitH', 'FitV', 'FitBH', 'FitBV'):
        kwarg_len = 1
    else:
        kwarg_len = 0
    expected_dest = [page_ref, Name('/{0}'.format(loc_str))]
    expected_dest.extend(repeat(100, kwarg_len))
    assert new_item.destination == expected_dest
    new_obj = new_item.obj
    assert new_obj.Title == title
    assert new_obj.Dest == expected_dest
    assert new_obj.is_indirect is True
예제 #3
0
def test_new_item(resources, title, page_num, page_loc):
    # @given precludes use of outlines_doc fixture - causes hypothesis health check to
    # fail
    with Pdf.open(resources / 'outlines.pdf') as doc:
        kwargs = dict.fromkeys(ALL_PAGE_LOCATION_KWARGS, 100)
        page_ref = doc.pages[page_num]

        new_item = OutlineItem(title, page_num, page_loc, **kwargs)
        with doc.open_outline() as outline:
            outline.root.append(new_item)
        if isinstance(page_loc, PageLocation):
            loc_str = page_loc.name
        else:
            loc_str = page_loc
        if loc_str == 'FitR':
            kwarg_len = 4
        elif loc_str == 'XYZ':
            kwarg_len = 3
        elif loc_str in ('FitH', 'FitV', 'FitBH', 'FitBV'):
            kwarg_len = 1
        else:
            kwarg_len = 0
        expected_dest = [page_ref, Name(f'/{loc_str}')]
        expected_dest.extend(repeat(100, kwarg_len))
        assert new_item.destination == expected_dest
        new_obj = new_item.obj
        assert new_obj.Title == title
        assert new_obj.Dest == expected_dest
        assert new_obj.is_indirect is True
예제 #4
0
def test_outlineitem_str(resources):
    with Pdf.open(resources / 'outlines.pdf') as pdf:
        with pdf.open_outline() as outline:
            assert str(outline.root[0]) == '[+] One -> <Action>'
            assert str(outline.root[1]) == '[ ] Two -> <Action>'
            item = OutlineItem('Test', make_page_destination(pdf, 0))
            assert '[ ] Test -> 1' == str(item)
예제 #5
0
 def dict_to_outline_item(item):
     oi = OutlineItem(item['title'], item['page'] - 1)
     if 'children' in item:
         for child in item['children']:
             ci = dict_to_outline_item(child)
             oi.children.append(ci)
     return oi
예제 #6
0
 def append_subnodes(outline, nodes):
     for node in nodes:
         if "title" in node and "page" in node:
             print(node["title"], node["page"])
             outline.append(OutlineItem(node["title"], node["page"]))
         if "children" in node:
             append_subnodes(outline, node["children"])
예제 #7
0
def test_create_from_scratch(outlines_doc):
    # Simple check that we can discard the existing outline
    # and create a new one.
    del outlines_doc.Root.Outlines
    with outlines_doc.open_outline(strict=True) as outline:
        new_item = OutlineItem('One')
        new_item.children.extend([OutlineItem('One-A'), OutlineItem('One-B')])
        outline.root.append(new_item)

    with outlines_doc.open_outline(strict=True):
        list(outline.root)

    # Should also work while the outline is open
    with outlines_doc.open_outline(strict=True) as outline:
        del outlines_doc.Root.Outlines
        new_item = OutlineItem('One')
        outline.root.append(new_item)

    with outlines_doc.open_outline(strict=True):
        list(outline.root)
예제 #8
0
def test_outlineitem_str(outlines_doc):
    with outlines_doc.open_outline() as outline:
        assert str(outline.root[0]) == '[+] One -> <Action>'
        assert str(outline.root[1]) == '[ ] Two -> <Action>'

        outline.root[0].is_closed = False
        assert str(outline.root[0]) == '[-] One -> <Action>'

        item = OutlineItem('Test', make_page_destination(outlines_doc, 0))
        assert '[ ] Test -> 1' == str(item)

        assert str(outline) != ''
예제 #9
0
    def mergeFiles(self):

        # Only try to combine if files have been added to the list
        # Allow for a single pdf to be 'combined', in this case it will just remove security if there is any
        if self.ui.lstFiles.count():

            outfile = self.openSaveFileDialog()

            # Only merge the pdfs if there is an output filename
            if outfile:

                self.ui.statusbar.showMessage("Combining...")

                output = Pdf.new()

                page_count = 0

                try:

                    with output.open_outline() as outline:
                        # Combine PDFs
                        for i in range(0, self.ui.lstFiles.count()):

                            filename = self.ui.lstFiles.item(i).text()

                            with Pdf.open(filename) as pdf:

                                oi = OutlineItem(os.path.basename(filename),
                                                 page_count)
                                outline.root.append(oi)
                                page_count += len(pdf.pages)
                                output.pages.extend(pdf.pages)

                    # Save file
                    output.save(outfile)

                    # Clear files from list
                    self.clearFilesFromList()

                    # Update statusbar with success message
                    self.ui.statusbar.showMessage("Success. Saved file '%s'" %
                                                  (os.path.basename(outfile)))

                # If combining the PDFs fails
                except:

                    # Update the statusbar with an error message with the file that caused it to fail
                    self.ui.statusbar.showMessage("Error processing '%s'" %
                                                  (os.path.basename(filename)))
                    output.close()
예제 #10
0
def add_tree(parent_list: list[OutlineItem], tree: Tree[PaginatedAnchor],
             pages: list[Path]) -> int:
    page_number = -1
    if tree.value.pages:
        page_number = len(pages)
    pages.extend(tree.value.pages)
    children: list[OutlineItem] = []
    child_page_numbers = [
        add_tree(children, child_tree, pages) for child_tree in tree.children
    ]
    if page_number < 0:
        page_number = child_page_numbers[0]
    outline_item = OutlineItem(tree.value.text, page_number)
    outline_item.children.extend(children)
    parent_list.append(outline_item)
    return page_number
예제 #11
0
    def removeSecurityFromFiles(self):

        # Only try to combine if files have been added to the list
        # Allow for a single pdf to be 'combined', in this case it will just remove security if there is any
        if self.ui.lstFiles.count():

            self.ui.statusbar.showMessage("Removing security from PDFs...")

            try:

                for i in range(0, self.ui.lstFiles.count()):

                    output = Pdf.new()

                    page_count = 0

                    filename = self.ui.lstFiles.item(i).text()

                    outfile = filename.replace(".pdf", "-UNSECURED.pdf")

                    with output.open_outline() as outline:
                        with Pdf.open(filename) as pdf:

                            oi = OutlineItem(os.path.basename(filename),
                                             page_count)
                            outline.root.append(oi)
                            page_count += len(pdf.pages)
                            output.pages.extend(pdf.pages)

                    # Save the file
                    output.save(outfile)

                # Clear files from list
                self.clearFilesFromList()

                # Update statusbar with success message
                self.ui.statusbar.showMessage(
                    "Success. Removed security from %d pdfs" % (i + 1))

            except:

                # Update the statusbar with an error message with the file that caused it to fail
                self.ui.statusbar.showMessage("Error processing '%s'" %
                                              (os.path.basename(filename)))
                output.close()
예제 #12
0
def test_recursion_depth_zero(outlines_doc):
    # Only keeps root level
    with outlines_doc.open_outline(max_depth=0) as outline:
        # No more than the root level should be read
        for root_element in outline.root:
            assert len(root_element.children) == 0

        # Attach an item to the first root level element
        # that should be ignored when writing
        outline.root[0].children.append(OutlineItem('New', 0))

    root_obj = outlines_doc.Root.Outlines
    first_obj = root_obj.First
    second_obj = first_obj.Next
    third_obj = second_obj.Next
    for obj in [first_obj, second_obj, third_obj]:
        assert '/First' not in obj
        assert '/Last' not in obj
예제 #13
0
def test_duplicated_object(outlines_doc):
    # Fails on reoccurring element
    with pytest.raises(OutlineStructureError):
        with outlines_doc.open_outline(strict=True) as outline:
            # Copy and object reference from one node to another
            obj_b_ii = outline.root[0].children[1].children[0].obj
            outline.root[2].children[0].obj = obj_b_ii

    # Silently creates a copy of the outline node
    with outlines_doc.open_outline() as outline:
        # Append duplicate object reference to existing outline
        obj_b_ii = outline.root[0].children[1].children[0].obj
        outline.root[2].children.append(
            OutlineItem.from_dictionary_object(obj_b_ii))

    # Should not fail at this point anymore
    with outlines_doc.open_outline(strict=True) as outline:
        assert len(outline.root[2].children) == 3
        assert (outline.root[2].children[2].title ==
                outline.root[0].children[1].children[0].title)
예제 #14
0
def test_recursion_depth_one(outlines_doc):
    # Only keeps first level from root
    with outlines_doc.open_outline(max_depth=1) as outline:
        # Only children of first level should be present
        for root_element, first_level_count in zip(outline.root, (2, 0, 2)):
            assert len(root_element.children) == first_level_count
            for sub_element in root_element.children:
                assert len(sub_element.children) == 0

        # Attach an item to the first sub level element
        # that should be ignored when writing
        outline.root[0].children[1].children.append(OutlineItem('New', 0))

    root_obj = outlines_doc.Root.Outlines
    first_obj = root_obj.First
    first_obj_a = first_obj.First
    first_obj_b = first_obj_a.Next
    second_obj = first_obj.Next
    third_obj = second_obj.Next
    third_obj_a = third_obj.First
    third_obj_b = third_obj_a.Next
    for obj in [first_obj_a, first_obj_b, third_obj_a, third_obj_b]:
        assert '/First' not in obj
        assert '/Last' not in obj
예제 #15
0
def test_noop(outlines_doc):
    with outlines_doc.open_outline(strict=True):
        # Forget to attach it - should simply not modify.
        OutlineItem('New')
예제 #16
0
import pikepdf
from pikepdf import Pdf, OutlineItem

with Pdf.open('TampaFD_TemporalPDF-4.pdf') as pdf:
    with pdf.open_outline() as outline:
        new_action = pikepdf.Dictionary()
        new_action['/S'] = pikepdf.Name('/JavaScript')
        new_action['/JS'] = "app.alert(\"Hello from Robin\");"
        test_item = OutlineItem('Test Alert Robin', action=new_action)
        outline.root.append(test_item)
    pdf.save('output1.pdf')
예제 #17
0
def test_outline_destination_name_object_types():
    # See issues 258, 261
    obj = Dictionary(Title='foo', Dest=Name.Bar)
    item = OutlineItem.from_dictionary_object(obj)
    assert '.Root.Dests' in str(item)