Exemplo n.º 1
0
def test_name_equality():
    # Who needs transitivity?
    # While this is less than ideal ('/Foo' != b'/Foo') it allows for slightly
    # sloppy tests like if colorspace == '/Indexed' without requiring
    # Name('/Indexed') everywhere
    assert Name('/Foo') == '/Foo'
    assert Name('/Foo') == b'/Foo'
Exemplo n.º 2
0
    def _from_pil_image(cls, *, pdf, page, name, image):  # pragma: no cover
        """Insert a PIL image into a PDF (rudimentary)

        Args:
            pdf (pikepdf.Pdf): the PDF to attach the image to
            page (pikepdf.Object): the page to attach the image to
            name (str or pikepdf.Name): the name to set the image
            image (PIL.Image.Image): the image to insert
        """

        data = image.tobytes()

        imstream = Stream(pdf, data)
        imstream.Type = Name('/XObject')
        imstream.Subtype = Name('/Image')
        if image.mode == 'RGB':
            imstream.ColorSpace = Name('/DeviceRGB')
        elif image.mode in ('1', 'L'):
            imstream.ColorSpace = Name('/DeviceGray')
        imstream.BitsPerComponent = 1 if image.mode == '1' else 8
        imstream.Width = image.width
        imstream.Height = image.height

        page.Resources.XObject[name] = imstream

        return cls(imstream)
Exemplo n.º 3
0
def test_image_roundtrip(outdir, w, h, pixeldata, cs, bpc):
    pdf = Pdf.new()

    image_data = pixeldata * (w * h)

    image = Stream(pdf, image_data)
    image.Type = Name('/XObject')
    image.Subtype = Name('/Image')
    image.ColorSpace = Name(cs)
    image.BitsPerComponent = bpc
    image.Width = w
    image.Height = h

    xobj = {'/Im1': image}
    resources = {'/XObject': xobj}
    mediabox = [0, 0, 100, 100]
    stream = b'q 100 0 0 100 0 0 cm /Im1 Do Q'
    contents = Stream(pdf, stream)

    page_dict = {
        '/Type': Name('/Page'),
        '/MediaBox': mediabox,
        '/Contents': contents,
        '/Resources': resources,
    }
    page = pdf.make_indirect(page_dict)

    pdf.pages.append(page)
    outfile = outdir / f'test{w}{h}{cs[1:]}{bpc}.pdf'
    pdf.save(
        outfile, compress_streams=False, stream_decode_level=StreamDecodeLevel.none
    )

    with Pdf.open(outfile) as p2:
        pim = PdfImage(p2.pages[0].Resources.XObject['/Im1'])

        assert pim.bits_per_component == bpc
        assert pim.colorspace == cs
        assert pim.width == w
        assert pim.height == h
        if cs == '/DeviceRGB':
            assert pim.mode == 'RGB'
        elif cs == '/DeviceGray' and bpc == 8:
            assert pim.mode == 'L'
        elif cs == '/DeviceCMYK':
            assert pim.mode == 'CMYK'
        elif bpc == 1:
            assert pim.mode == '1'
        assert not pim.palette

        assert pim.filters == []
        assert pim.read_bytes() == pixeldata

        outstream = BytesIO()
        pim.extract_to(stream=outstream)
        outstream.seek(0)
        im = Image.open(outstream)
        assert pim.mode == im.mode
Exemplo n.º 4
0
def test_image_replace(congress, outdir):
    pdfimage = PdfImage(congress[0])
    pillowimage = pdfimage.as_pil_image()

    grayscale = pillowimage.convert('L')

    congress[0].write(zlib.compress(grayscale.tobytes()), Name("/FlateDecode"), Null())
    congress[0].ColorSpace = Name("/DeviceGray")
    pdf = congress[1]
    pdf.save(outdir / 'congress_gray.pdf')
Exemplo n.º 5
0
def test_image_replace(congress, outdir):
    pdfimage = PdfImage(congress[0])
    pillowimage = pdfimage.as_pil_image()

    grayscale = pillowimage.convert('L')
    grayscale = grayscale.resize((4, 4))  # So it is not obnoxious on error

    congress[0].write(zlib.compress(grayscale.tobytes()), filter=Name("/FlateDecode"))
    congress[0].ColorSpace = Name("/DeviceGray")
    pdf = congress[1]
    pdf.save(outdir / 'congress_gray.pdf')
Exemplo n.º 6
0
def test_lowlevel_replace_jpeg(congress, outdir):
    # This test will modify the PDF so needs its own image
    raw_bytes = congress[0].read_raw_bytes()

    im = Image.open(BytesIO(raw_bytes))
    grayscale = im.convert('L')

    congress[0].write(zlib.compress(grayscale.tobytes()), Name("/FlateDecode"), Null())
    congress[0].ColorSpace = Name('/DeviceGray')

    pdf = congress[1]
    pdf.save(outdir / 'congress_gray.pdf')
Exemplo n.º 7
0
def test_bytes():
    b = b'\x79\x78\x77\x76'
    qs = String(b)
    assert bytes(qs) == b

    s = 'é'
    qs = String(s)
    assert str(qs) == s

    assert Name('/xyz') == b'/xyz'
    with pytest.raises(TypeError, match='should be str'):
        Name(b'/bytes')
Exemplo n.º 8
0
def test_lowlevel_replace_jpeg(congress, outdir):
    # This test will modify the PDF so needs its own image
    raw_bytes = congress[0].read_raw_bytes()

    im = Image.open(BytesIO(raw_bytes))
    grayscale = im.convert('L')
    grayscale = grayscale.resize((4, 4))  # So it is not obnoxious on error

    congress[0].write(zlib.compress(grayscale.tobytes()[:10]),
                      filter=Name("/FlateDecode"))
    congress[0].ColorSpace = Name('/DeviceGray')

    pdf = congress[1]
    pdf.save(outdir / 'congress_gray.pdf')
Exemplo n.º 9
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
Exemplo n.º 10
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
Exemplo n.º 11
0
def test_page_destination(resources, page_num, page_loc, kwargs):
    # @given precludes use of outlines_doc fixture - causes hypothesis health check to
    # fail
    with Pdf.open(resources / 'outlines.pdf') as doc:
        page_ref = doc.pages[page_num]

        if page_loc == 'invalid':
            with pytest.raises(ValueError, match='unsupported page location'):
                make_page_destination(doc, page_num, page_loc, **kwargs)
            return

        dest = make_page_destination(doc, page_num, page_loc, **kwargs)
        if isinstance(page_loc, PageLocation):
            loc_str = page_loc.name
        else:
            loc_str = page_loc
        if loc_str == 'XYZ':
            args = 'left', 'top', 'zoom'
        elif loc_str == 'FitH':
            args = ('top', )
        elif loc_str == 'FitV':
            args = ('left', )
        elif loc_str == 'FitR':
            args = 'left', 'bottom', 'right', 'top'
        elif loc_str == 'FitBH':
            args = ('top', )
        elif loc_str == 'FitBV':
            args = ('left', )
        else:
            args = ()
        expected_dest = [page_ref, Name(f'/{loc_str}')]
        expected_dest.extend(kwargs.get(k, 0) for k in args)
        assert dest == expected_dest
Exemplo n.º 12
0
def make_page_destination(
    pdf: Pdf,
    page_num: int,
    page_location: Optional[Union[PageLocation, str]] = None,
    **kwargs,
) -> Array:
    """
    Creates a destination ``Array`` with reference to a Pdf document's page number.

    Arguments:
        pdf: PDF document object.
        page_num: Page number (zero-based).
        page_location: Optional page location, as a string or :enum:`PageLocation`.
        kwargs: Optional keyword arguments for the page location, e.g. ``top``.
    """
    res = [pdf.pages[page_num]]
    if page_location:
        if isinstance(page_location, PageLocation):
            loc_key = page_location
            loc_str = loc_key.name
        else:
            loc_str = page_location
            try:
                loc_key = PageLocation[loc_str]
            except KeyError:
                raise ValueError(
                    f"Invalid or unsupported page location type {loc_str}")
        res.append(Name(f'/{loc_str}'))
        dest_arg_names = PAGE_LOCATION_ARGS.get(loc_key)
        if dest_arg_names:
            res.extend(kwargs.get(k, 0) for k in dest_arg_names)
    else:
        res.append(Name.Fit)
    return Array(res)
Exemplo n.º 13
0
def _make_page_destination(
    pdf: Pdf,
    page_num: int,
    page_location: Optional[Union[PageLocation, str]] = None,
    **kwargs,
) -> Array:
    kwargs = {k: v for k, v in kwargs.items() if v is not None}

    res = [pdf.pages[page_num]]
    if page_location:
        if isinstance(page_location, PageLocation):
            loc_key = page_location
            loc_str = loc_key.name
        else:
            loc_str = page_location
            try:
                loc_key = PageLocation[loc_str]
            except KeyError:
                raise ValueError(
                    f"Invalid or unsupported page location type {loc_str}"
                ) from None
        res.append(Name(f'/{loc_str}'))
        dest_arg_names = PAGE_LOCATION_ARGS.get(loc_key)
        if dest_arg_names:
            res.extend(kwargs.get(k, 0) for k in dest_arg_names)
    else:
        res.append(Name.Fit)
    return Array(res)
Exemplo n.º 14
0
def test_page_destination(resources, page_num, page_loc, kwargs):
    doc = Pdf.open(resources / 'outlines.pdf')
    page_ref = doc.pages[page_num]
    dest = make_page_destination(doc, page_num, page_loc, **kwargs)
    if isinstance(page_loc, PageLocation):
        loc_str = page_loc.name
    else:
        loc_str = page_loc
    if loc_str == 'XYZ':
        args = 'left', 'top', 'zoom'
    elif loc_str == 'FitH':
        args = ('top', )
    elif loc_str == 'FitV':
        args = ('left', )
    elif loc_str == 'FitR':
        args = 'left', 'bottom', 'right', 'top'
    elif loc_str == 'FitBH':
        args = ('top', )
    elif loc_str == 'FitBV':
        args = ('left', )
    else:
        args = ()
    expected_dest = [page_ref, Name('/{0}'.format(loc_str))]
    expected_dest.extend(kwargs.get(k, 0) for k in args)
    assert dest == expected_dest
Exemplo n.º 15
0
def test_list_apis():
    a = pikepdf.Array([1, 2, 3])
    a[1] = None
    assert a[1] is None
    assert len(a) == 3
    del a[1]
    assert len(a) == 2
    a[-1] = Name('/Foo')
Exemplo n.º 16
0
def test_create_pdf(outdir):
    pdf = Pdf.new()

    font = pdf.make_indirect(
        Object.parse(b"""
            <<
                /Type /Font
                /Subtype /Type1
                /Name /F1
                /BaseFont /Helvetica
                /Encoding /WinAnsiEncoding
            >>"""))

    width, height = 100, 100
    image_data = b"\xff\x7f\x00" * (width * height)

    image = Stream(pdf, image_data)
    image.stream_dict = Object.parse(b"""
            <<
                /Type /XObject
                /Subtype /Image
                /ColorSpace /DeviceRGB
                /BitsPerComponent 8
                /Width 100
                /Height 100
            >>""")

    rfont = {'/F1': font}

    xobj = {'/Im1': image}

    resources = {
        '/Font': rfont,
        '/XObject': xobj
        }

    mediabox = [0, 0, 612, 792]

    stream = b"""
        BT /F1 24 Tf 72 720 Td (Hi there) Tj ET
        q 144 0 0 144 234 324 cm /Im1 Do Q
        """

    contents = Stream(pdf, stream)

    page_dict = {
        '/Type': Name('/Page'),
        '/MediaBox': mediabox,
        '/Contents': contents,
        '/Resources': resources
        }
    qpdf_page_dict = page_dict
    page = pdf.make_indirect(qpdf_page_dict)

    pdf.pages.append(page)
    pdf.save(outdir / 'hi.pdf')
Exemplo n.º 17
0
def test_list_apis():
    a = pikepdf.Array([1, 2, 3])
    a[1] = None
    assert a[1] is None
    assert len(a) == 3
    del a[1]
    assert len(a) == 2
    a[-1] = Name('/Foo')
    with pytest.raises(IndexError):
        a[-5555] = Name.Foo
Exemplo n.º 18
0
def test_bytes():
    b = b'\x79\x78\x77\x76'
    qs = String(b)
    assert bytes(qs) == b

    s = 'é'
    qs = String(s)
    assert str(qs) == s

    assert Name('/xyz') == b'/xyz'
Exemplo n.º 19
0
 def test_repr_scalar(self):
     scalars = [
         False, 666,
         Decimal('3.14'),
         String('scalar'),
         Name('/Bob'),
         Operator('Q')
     ]
     for s in scalars:
         assert eval(repr(s)) == s
Exemplo n.º 20
0
def test_list_apis():
    a = pikepdf.Array([1, 2, 3])
    a[1] = None
    assert a[1] is None
    assert len(a) == 3
    del a[1]
    assert len(a) == 2
    a[-1] = Name('/Foo')
    with pytest.raises(IndexError):
        a[-5555] = Name.Foo
    assert a == pikepdf.Array([1, Name.Foo])
    a.append(4)
    assert a == pikepdf.Array([1, Name.Foo, 4])
    a.extend([42, 666])
    assert a == pikepdf.Array([1, Name.Foo, 4, 42, 666])
Exemplo n.º 21
0
def set_pagelabels(doc, page_labels):
    arr = []
    for label in page_labels:
        pn = label['start'] - 1  # page index 1-based -> 0-based
        d = {}
        if 'style' in label and label['style'] != 'none':
            d['/S'] = Name('/' + label['style'])
        if 'prefix' in label:
            d['/P'] = label['prefix']
        if 'initial_count' in label:
            d['/St'] = label['initial_count']
        obj = Dictionary(d)
        arr.append(pn)
        arr.append(obj)
    obj = Dictionary({'/Nums': Array(arr)})
    doc.root[Name.PageLabels] = obj
Exemplo n.º 22
0
def test_list_apis():
    a = pikepdf.Array([1, 2, 3])
    a[1] = None
    assert a[1] is None
    assert len(a) == 3
    del a[1]
    assert len(a) == 2
    a[-1] = Name('/Foo')
    with pytest.raises(IndexError):
        a[-5555] = Name.Foo
    assert a == pikepdf.Array([1, Name.Foo])
    a.append(4)
    assert a == pikepdf.Array([1, Name.Foo, 4])
    a.extend([42, 666])
    assert a == pikepdf.Array([1, Name.Foo, 4, 42, 666])
    with pytest.raises(ValueError, match='object is not a dictionary'):
        del a.ImaginaryKey
    with pytest.raises(TypeError, match=r"items\(\) not available"):
        a.items()
Exemplo n.º 23
0
    def _remove_simple_filters(obj, filters):
        """Remove simple lossless compression where it appears.

        Args:
            obj (pikepdf.Stream): the compressed object
            filters (list of str): all files on the data
        """

        COMPLEX_FILTERS = {
            '/DCTDecode',
            '/JPXDecode',
            '/JBIG2Decode',
            '/CCITTFaxDecode',
        }

        idx = [n for n, item in enumerate(filters) if item in COMPLEX_FILTERS]
        if idx:
            if len(idx) > 1:
                raise NotImplementedError(
                    f"Object {obj.objgen} has compound complex filters: {filters}. "
                    "We cannot decompress this."
                )
            simple_filters = filters[: idx[0]]
            complex_filters = filters[idx[0] :]
        else:
            simple_filters = filters
            complex_filters = []

        if not simple_filters:
            return obj.read_raw_bytes(), complex_filters

        original_filters = obj.Filter
        try:
            obj.Filter = Array([Name(s) for s in simple_filters])
            data = obj.read_bytes(StreamDecodeLevel.specialized)
        finally:
            obj.Filter = original_filters

        return data, complex_filters
Exemplo n.º 24
0
 def test_contains(self):
     d = Dictionary({'/Monty': 'Python', '/Flying': 'Circus'})
     assert Name.Flying in d
     assert Name('/Monty') in d
     assert Name.Brian not in d
Exemplo n.º 25
0
 def test_name(self):
     self.check(Name.This, Name('/This'))
Exemplo n.º 26
0
 def test_unequal_but_similar(self):
     assert Name('/Foo') != String('/Foo')
Exemplo n.º 27
0
def test_empty_name():
    with pytest.raises(ValueError):
        Name('')
    with pytest.raises(ValueError):
        Name('/')
Exemplo n.º 28
0
def test_unslashed_name():
    with pytest.raises(ValueError, match='must begin with'):
        Name('Monty') not in []  # pylint: disable=expression-not-assigned
Exemplo n.º 29
0
def test_wrap_array():
    assert Name('/Foo').wrap_in_array() == Array([Name('/Foo')])
    assert Array([42]).wrap_in_array() == Array([42])
Exemplo n.º 30
0
def get_pdf():
	form = UserForm()
	if form.validate_on_submit():

		profile = {}
		profile["firstname"] = form.firstname.data
		profile["lastname"] = form.lastname.data
		profile["birthday"] = form.birthday.data.strftime("%d/%m/%Y")
		profile["address"] = form.address.data
		profile["city"] = form.city.data
		profile["zipcode"] = form.zipcode.data
		profile["reason"] = form.reason.data
		profile["delay"] = form.delay.data

		now, date, hour = get_date(profile["delay"])

		if profile["reason"] == "sport" and (19 <= now.hour or now.hour < 6):
			profile["reason"] = "animaux"
		elif profile["reason"] == "animaux" and (19 > now.hour or now.hour >= 6):
			profile["reason"] = "sport"
		if profile["reason"] == "achats_culte_culturel" and (19 <= now.hour or now.hour < 6):
			flash("Des achats pendant le couvre-feu ? T'es magique toi !")
			return redirect("/")

		fp = webdriver.FirefoxProfile()
		fp.set_preference("browser.download.folderList", 2)
		fp.set_preference("browser.download.dir", str(PureWindowsPath(ATTEST_PATH)) if platform.system() == "Windows" else ATTEST_PATH)
		fp.set_preference("browser.helperApps.neverAsk.saveToDisk", "application/pdf, attachment/pdf")
		fp.set_preference("browser.download.manager.showWhenStarting",False)
		fp.set_preference("browser.helperApps.neverAsk.openFile","application/pdf")
		fp.set_preference("browser.helperApps.alwaysAsk.force", False)
		fp.set_preference("browser.download.manager.useWindow", False)
		fp.set_preference("browser.download.manager.focusWhenStarting", False)
		fp.set_preference("browser.download.manager.alertOnEXEOpen", False)
		fp.set_preference("browser.download.manager.showAlertOnComplete", False)
		fp.set_preference("browser.download.manager.closeWhenDone", True)
		fp.set_preference("pdfjs.disabled", True)

		options = webdriver.firefox.options.Options()
		options.add_argument("--headless")
		
		try:
			driver = webdriver.Firefox(options=options, firefox_profile=fp)
		except Exception as e:
			app.logger.error("Error: %s" % str(e))
			flash("Woopsy, une erreur s'est produite...")
			return redirect("/")

		# get page	
		driver.get("https://media.interieur.gouv.fr/attestation-deplacement-derogatoire-covid-19/")
		html = driver.page_source
		soup = BeautifulSoup(html, features="lxml")

		# pass the update button
		wait = WebDriverWait(driver, DELAY)
		try:
			update_button = wait.until(EC.element_to_be_clickable((By.ID, 'reload-btn')))
			update_button = driver.find_element_by_id("reload-btn").click()
		except:
			pass

		files_nb = len(os.listdir(ATTEST_PATH))

		# fill form
		fill_form(driver, profile, now, date, hour)

		# wait file to get there
		i = 5
		while i:
			if len(os.listdir(ATTEST_PATH)) <= files_nb:
				i -= 1
				time.sleep(DELAY)
			else:
				break
			if i == 0:
				app.logger.error("Error: file not downloaded.")
				flash("Woopsy, une erreur s'est produite...")
				return redirect("/")

		# rename file to avoid duplicates between users
		try:
			filepath = max([os.path.join(ATTEST_PATH, f) for f in os.listdir(ATTEST_PATH)], key=os.path.getctime)
			filename = profile["lastname"] + "_" + profile["firstname"] + os.path.basename(filepath)
			new_filename = os.path.join(ATTEST_PATH, filename)
			shutil.move(filepath, new_filename)
		except Exception as e:
			app.logger.error("Error: %s" % str(e))
			flash("Woopsy, une erreur s'est produite...")
			return redirect("/")

		# make QRcode and edit PDF
		img = make_qr_code(profile, now, date, hour).convert('RGB').resize((590, 590))
		pdf_file = Pdf.open(new_filename, allow_overwriting_input=True)
		page = pdf_file.pages[1]
		page_image = list(page.images.keys())
		rawimage = page.images[page_image[0]]
		rawimage.write(zlib.compress(img.tobytes()), filter=Name("/FlateDecode"))
		rawimage.Width, rawimage.Height = 590, 590
		page.Resources.XObject[page_image[0]] = rawimage
		pdf_file.save(new_filename)

		# program file cleaner
		file_handle = open(new_filename, 'rb')

		# This *replaces* the `remove_file` + @after_this_request code above
		def stream_and_remove_file():
			yield from file_handle
			file_handle.close()
			os.remove(new_filename)

		return app.response_class(
			stream_and_remove_file(),
			mimetype='application/pdf',
			headers={'Content-Disposition': 'attachment', 'filename': filename}
		)
	return redirect("/")