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

camatcode / basenji / afc3f9268594a73283acb7ae1dcc2df893c76bc1

17 Jul 2025 02:46AM UTC coverage: 59.127% (+0.7%) from 58.437%
afc3f9268594a73283acb7ae1dcc2df893c76bc1

Pull #50

github

camatcode
feat: predictive cache pre-caches images for flawless page traversal
Pull Request #50: feat: predictive cache pre-caches images for flawless page traversal

42 of 48 new or added lines in 2 files covered. (87.5%)

2 existing lines in 1 file now uncovered.

975 of 1649 relevant lines covered (59.13%)

354.81 hits per line

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

82.61
/lib/basenji_web/controllers/api/comics_controller.ex
1
defmodule BasenjiWeb.ComicsController do
2
  @moduledoc false
3
  use BasenjiWeb, :controller
4

5
  alias Basenji.Comics
6
  alias Basenji.ImageProcessor
7
  alias BasenjiWeb.API.Utils
8
  alias BasenjiWeb.PredictiveCache
9

10
  def get_page(conn, params) do
11
    id = params["id"]
4✔
12
    page = params["page"]
4✔
13

NEW
14
    with {:ok, page_num} <- Utils.safe_to_int(page),
×
15
         {:ok, comic} <- Comics.get_comic(id) do
4✔
16
      PredictiveCache.get_comic_page_from_cache(comic, page_num)
4✔
17
    end
18
    |> case do
4✔
19
      {:ok, binary, mime} ->
20
        length = byte_size(binary)
4✔
21

22
        conn
23
        |> merge_resp_headers([{"access-control-allow-origin", "*"}])
24
        |> merge_resp_headers([{"content-type", mime}])
25
        |> merge_resp_headers([{"content-length", "#{length}"}])
4✔
26
        |> send_resp(200, binary)
4✔
27

28
      error ->
29
        Utils.bad_request_handler(conn, error)
×
30
    end
31
  end
32

33
  def get_preview(conn, params) do
34
    id = params["id"]
1✔
35

36
    get_comic_preview(id)
37
    |> case do
1✔
38
      {:ok, binary} ->
39
        length = byte_size(binary)
1✔
40

41
        conn
42
        |> merge_resp_headers([{"access-control-allow-origin", "*"}])
43
        |> merge_resp_headers([{"content-type", "image/jpeg"}])
44
        |> merge_resp_headers([{"content-length", "#{length}"}])
1✔
45
        |> send_resp(200, binary)
1✔
46

47
      error ->
48
        Utils.bad_request_handler(conn, error)
×
49
    end
50
  end
51

52
  defp get_comic_preview(id) do
53
    with {:ok, comic} <- Comics.get_comic(id) do
1✔
54
      if comic.image_preview do
1✔
55
        {:ok, comic.image_preview}
×
56
      else
57
        make_preview(comic)
1✔
58
      end
59
    end
60
  end
61

62
  defp make_preview(comic) do
63
    {:ok, bytes, _mime} = PredictiveCache.get_comic_page_from_cache(comic, 1)
1✔
64
    {:ok, preview_bytes} = ImageProcessor.get_image_preview(bytes, 600, 600)
1✔
65
    Comics.update_comic(comic, %{image_preview: preview_bytes})
1✔
66
    {:ok, preview_bytes}
67
  end
68
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