aboutsummaryrefslogtreecommitdiff
path: root/src/cache.gleam
blob: 7e4ff21148906c9bd58fa92d52e5081de338cb28 (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
import gleam/bit_array
import gleam/dict.{type Dict}
import gleam/int
import gleam/list
import gleam/option.{type Option}
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() {
  list.fold(
    case simplifile.read_directory("./themes") {
      Ok(files) -> files
      Error(_) -> {
        wisp.log_error("Error reading themes directory")

        []
      }
    },
    dict.new(),
    fn(accumulated_themes, theme) {
      dict.insert(accumulated_themes, theme, load_theme(theme))
    },
  )
}

fn load_theme(theme) -> Dict(Int, CachedImage) {
  let theme_directory = "./themes/" <> theme

  case simplifile.read_directory(theme_directory) {
    Ok(files) ->
      list.fold(files, dict.new(), fn(accumulated_digits, file) {
        case parse_digit_filename(file) {
          Ok(digit) ->
            load_cached_image(theme_directory <> "/" <> file)
            |> result.map(dict.insert(accumulated_digits, digit, _))
            |> result.unwrap(accumulated_digits)
          Error(_) -> accumulated_digits
        }
      })
    Error(_) -> {
      wisp.log_error("Error reading theme directory " <> theme_directory)

      dict.new()
    }
  }
}

fn parse_digit_filename(file) {
  case string.split(file, ".") {
    [digit, _extension] -> int.parse(digit)
    _ -> 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) -> Option(CachedImage) {
  dict.get(cache, theme)
  |> result.then(fn(theme_images) { dict.get(theme_images, digit) })
  |> option.from_result
}