• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

camatcode / basenji / 3c9c873f5bc38298e82a98cf802e5e59a2369b8d

27 Jul 2025 02:37PM UTC coverage: 81.818% (+0.1%) from 81.695%
3c9c873f5bc38298e82a98cf802e5e59a2369b8d

Pull #72

github

camatcode
perf: introduce telemetry wrapper
Pull Request #72: perf: introduce telemetry

38 of 45 new or added lines in 7 files covered. (84.44%)

21 existing lines in 3 files now uncovered.

1152 of 1408 relevant lines covered (81.82%)

510.53 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

91.89
/lib/basenji/reader/pdf_reader.ex
1
defmodule Basenji.Reader.PDFReader do
2
  @moduledoc false
3

4
  import Basenji.Reader
5

6
  def format, do: :pdf
2✔
7

8
  def file_extensions, do: ["pdf"]
818✔
9

10
  def get_magic_numbers, do: [%{offset: 0, magic: [0x25, 0x50, 0x44, 0x46, 0x2D]}]
816✔
11

12
  def close(_any), do: :ok
3✔
13

14
  def get_entries(pdf_file_path, _opts \\ []) do
15
    with {:ok, %{pages: pages}} <- get_metadata(pdf_file_path) do
819✔
16
      padding = String.length("#{pages}")
818✔
17

18
      file_entries =
818✔
19
        1..pages
20
        |> Enum.map(fn idx ->
21
          %{file_name: "#{String.pad_leading("#{idx}", padding, "0")}.jpg"}
3,272✔
22
        end)
23

24
      {:ok, %{entries: file_entries}}
25
    end
26
  end
27

28
  def get_entry_stream!(pdf_file_path, entry) do
29
    file_name = entry[:file_name]
60✔
30
    {page_num, _rest} = Integer.parse(file_name)
60✔
31

32
    create_resource(fn ->
60✔
33
      with {:ok, output} <- exec("pdftoppm", ["-f", "#{page_num}", "-singlefile", "-jpeg", "-q", pdf_file_path]) do
60✔
34
        [output |> :binary.bin_to_list()]
35
      end
36
    end)
37
  end
38

39
  def read(pdf_file_path, _opts \\ []) do
40
    with {:ok, %{entries: file_entries}} <- get_entries(pdf_file_path) do
817✔
41
      file_entries =
817✔
42
        file_entries
43
        |> Enum.map(fn entry ->
44
          entry
45
          |> Map.put(:stream_fun, fn -> get_entry_stream!(pdf_file_path, entry) end)
3,268✔
46
        end)
47

48
      {:ok, %{entries: file_entries}}
49
    end
50
  end
51

52
  def get_metadata(pdf_file_path) do
53
    with {:ok, output} <- exec("pdfinfo", ["-isodates", pdf_file_path]) do
819✔
54
      metadata =
818✔
55
        String.split(output, "\n")
56
        |> Map.new(fn line ->
57
          String.split(line, ":", parts: 2)
58
          |> case do
14,724✔
59
            [k, v] -> to_metadata(k, v)
14,724✔
UNCOV
60
            [v] -> to_metadata("unknown_#{System.monotonic_time()}", v)
×
61
          end
62
        end)
63

64
      {:ok, metadata}
65
    end
66
  end
67

68
  defp to_metadata(k, v) do
69
    k = k |> String.trim() |> ProperCase.snake_case() |> String.to_atom()
14,724✔
70
    v = convert_value(k, v |> String.trim())
14,724✔
71
    {k, v}
72
  end
73

74
  defp convert_value(:creation_date, v), do: DateTimeParser.parse!(v)
818✔
75
  defp convert_value(:mod_date, v), do: DateTimeParser.parse!(v)
818✔
76
  defp convert_value(:pages, v), do: String.to_integer(v)
818✔
77

78
  defp convert_value(:filesize, v) do
79
    {first, _rest} = Integer.parse(v)
818✔
80
    first
818✔
81
  end
82

83
  defp convert_value(:pagesize, v) do
84
    String.split(v, " ")
85
    |> Enum.reduce([], fn part, acc ->
86
      Integer.parse(part)
87
      |> case do
3,272✔
88
        {coord, _rest} -> [coord | acc]
1,636✔
89
        _ -> acc
1,636✔
90
      end
91
    end)
92
    |> case do
818✔
93
      [x, y] -> {x, y}
818✔
UNCOV
94
      _ -> v
×
95
    end
96
  end
97

UNCOV
98
  defp convert_value(_k, "yes"), do: true
×
99
  defp convert_value(_k, "no"), do: false
6,544✔
100
  defp convert_value(_k, "none"), do: nil
818✔
101
  defp convert_value(_k, v), do: v
3,272✔
102
end
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc