⭐ Moe-Counter Compatible Website Hit Counter Written in Gleam
mayu.due.moe
hit-counter
svg
moe
1import gleam/bit_array
2import gleam/dict.{type Dict}
3import gleam/int
4import gleam/list
5import gleam/option.{type Option}
6import gleam/result
7import image
8import simplifile
9import wisp
10
11pub type CachedImage {
12 CachedImage(base64: String, info: image.ImageInformation)
13}
14
15pub type ThemeCache =
16 Dict(String, Dict(Int, CachedImage))
17
18pub fn load_themes() {
19 list.fold(
20 case simplifile.read_directory("./themes") {
21 Ok(files) -> files
22 Error(_) -> {
23 wisp.log_error("Error reading themes directory")
24
25 []
26 }
27 },
28 dict.new(),
29 fn(accumulated_themes, theme) {
30 dict.insert(
31 accumulated_themes,
32 theme,
33 list.range(0, 9)
34 |> list.fold(dict.new(), fn(accumulated_digits, digit) {
35 let path =
36 "./themes/"
37 <> theme
38 <> "/"
39 <> int.to_string(digit)
40 <> "."
41 <> case theme {
42 "gelbooru-h" | "moebooru-h" | "lain" | "garukura" -> "png"
43 _ -> "gif"
44 }
45
46 case simplifile.read_bits(from: path) {
47 Ok(image_data) -> {
48 case image.get_image_information(image_data) {
49 Ok(info) ->
50 dict.insert(
51 accumulated_digits,
52 digit,
53 CachedImage(
54 base64: bit_array.base64_encode(image_data, False),
55 info: info,
56 ),
57 )
58 Error(_) -> {
59 wisp.log_error(
60 "Error getting image information for " <> path,
61 )
62
63 accumulated_digits
64 }
65 }
66 }
67 Error(_) -> {
68 wisp.log_error("Error reading image file " <> path)
69
70 accumulated_digits
71 }
72 }
73 }),
74 )
75 },
76 )
77}
78
79pub fn get_image(cache, theme, digit) -> Option(CachedImage) {
80 dict.get(cache, theme)
81 |> result.then(fn(theme_images) { dict.get(theme_images, digit) })
82 |> option.from_result
83}