⭐ Moe-Counter Compatible Website Hit Counter Written in Gleam mayu.due.moe
hit-counter svg moe
at main 83 lines 2.2 kB view raw
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}