aboutsummaryrefslogtreecommitdiff
path: root/src/cache.gleam
blob: 17fc1682ab85328f44e0d5089be8b74b6f75f8f8 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
import gleam/bit_array
import gleam/dict.{type Dict}
import gleam/int
import gleam/list
import gleam/result
import gleam/string
import image
import simplifile
import wisp

pub type CachedImage {
  CachedImage(base64: String, info: image.ImageInformation)
}

pub type ThemeCache =
  Dict(String, Dict(Int, CachedImage))

pub fn load_themes() {
  let themes = case simplifile.read_directory("./themes") {
    Ok(files) -> files
    Error(_) -> {
      wisp.log_error("Error reading themes directory")

      []
    }
  }

  themes
  |> list.map(fn(theme) { #(theme, load_theme(theme)) })
  |> dict.from_list
}

fn load_theme(theme) -> Dict(Int, CachedImage) {
  let theme_directory = "./themes/" <> theme
  let files = case simplifile.read_directory(theme_directory) {
    Ok(files) -> files
    Error(_) -> {
      wisp.log_error("Error reading theme directory " <> theme_directory)

      []
    }
  }

  files
  |> list.filter_map(fn(file) {
    use digit <- result.try(parse_digit_filename(file))
    use cached_image <- result.try(load_cached_image(
      theme_directory <> "/" <> file,
    ))

    Ok(#(digit, cached_image))
  })
  |> dict.from_list
}

fn parse_digit_filename(file) {
  case string.split(file, ".") {
    [digit, _extension] ->
      case int.parse(digit) {
        Ok(parsed_digit) if parsed_digit >= 0 && parsed_digit <= 9 ->
          Ok(parsed_digit)
        _ -> Error(Nil)
      }
    _ -> Error(Nil)
  }
}

fn load_cached_image(path) {
  case simplifile.read_bits(from: path) {
    Ok(image_data) ->
      case image.get_image_information(image_data) {
        Ok(info) ->
          Ok(CachedImage(
            base64: bit_array.base64_encode(image_data, False),
            info: info,
          ))
        Error(_) -> {
          wisp.log_error("Error getting image information for " <> path)

          Error(Nil)
        }
      }
    Error(_) -> {
      wisp.log_error("Error reading image file " <> path)

      Error(Nil)
    }
  }
}

pub fn get_image(cache, theme, digit) -> Result(CachedImage, Nil) {
  dict.get(cache, theme)
  |> result.then(fn(theme_images) { dict.get(theme_images, digit) })
}