2025-05-17 09:02:52 -05:00
|
|
|
#[Copyright 2025 ITwrx.
|
|
|
|
This file is part of Forget-Me-Not.
|
|
|
|
Forget-Me-Not is released under the GNU Affero General Public License 3.0.
|
|
|
|
See COPYING or <https://www.gnu.org/licenses/> for details.]#
|
|
|
|
|
2025-05-15 08:01:35 -05:00
|
|
|
import std/[times, strutils, re, uri, paths, random, strtabs]
|
|
|
|
|
|
|
|
#universal
|
|
|
|
const APP_PATH* = "/var/www/forget-me-not-gs"
|
2025-05-18 10:52:58 -05:00
|
|
|
const ASSETS_PATH* = "/var/www/forget-me-not-gs/assets"
|
2025-05-15 08:01:35 -05:00
|
|
|
const APP_NAME* = "Forget-Me-Not"
|
2025-05-18 10:52:58 -05:00
|
|
|
#set to 'dev' or 'prod'. changes how cookies are created and possibly paths, if using two environments. Maybe other stuff i'm forgetting.
|
2025-05-15 08:01:35 -05:00
|
|
|
const APP_MODE* = "dev"
|
|
|
|
#dev
|
2025-05-18 10:52:58 -05:00
|
|
|
#using paths config'd in /etc/hosts for local dev.
|
2025-05-15 08:01:35 -05:00
|
|
|
const APP_URL* = "http://fmn-gs"
|
|
|
|
const ASSETS_URL* = "http://assets.fmn-gs"
|
|
|
|
#prod
|
2025-05-18 10:52:58 -05:00
|
|
|
#const APP_URL* = "https://my-fmn-url.com"
|
|
|
|
#const ASSETS_URL* = "https://assets.my-fmn-url.com"
|
2025-05-15 08:01:35 -05:00
|
|
|
|
|
|
|
var frStrTab* = newStringTable()
|
|
|
|
|
2025-05-18 10:52:58 -05:00
|
|
|
#TODO: implement logging or remove logging code. Remove SSM code not used in FMN.
|
2025-05-17 09:02:52 -05:00
|
|
|
|
2025-05-15 08:01:35 -05:00
|
|
|
#Guildensterns logger is conflicting with my, evidently incorrect, usage of the std lib logger so i'll just write some lines to a file for now.
|
|
|
|
#var logger* = newFileLogger("errors.log")
|
|
|
|
|
|
|
|
let dt = now()
|
|
|
|
let nowDT* = dt.format("M-d-YYYY h:mm:ss tt")
|
|
|
|
|
|
|
|
proc writeLogLine*(errorMsg: string) =
|
|
|
|
{.gcsafe.}:
|
|
|
|
let logFile = open("errors.log", fmAppend)
|
|
|
|
defer: logFile.close()
|
|
|
|
logFile.writeLine(errorMsg)
|
|
|
|
|
|
|
|
template location*(slug: string): untyped =
|
|
|
|
"location: " & APP_URL & slug
|
|
|
|
|
|
|
|
template locationBack*(): string =
|
|
|
|
"location: " & http.headers.getOrDefault("referer")
|
|
|
|
|
|
|
|
template locationOrigin*(origin: string): untyped =
|
|
|
|
"location: " & origin
|
|
|
|
|
|
|
|
proc filenameToSentence*(filename: string): string =
|
|
|
|
#remove file extension.
|
|
|
|
let filePath = Path filename
|
|
|
|
let filePathEnum = splitFile(filePath)
|
|
|
|
var name = filePathEnum[1].string
|
|
|
|
#replace dashes and underscores with spaces.
|
|
|
|
name = name.replace(re"_", " ")
|
|
|
|
name = name.replace(re"-", " ")
|
|
|
|
#strip numbers.
|
|
|
|
name = name.replace(re"[0-9]", "")
|
|
|
|
return name
|
|
|
|
|
|
|
|
proc titleToSlug*(title: string): string =
|
|
|
|
#replace one or more spaces with dash
|
|
|
|
var dataString = title.replace(re" +", "-")
|
|
|
|
#replace anything that is not a letter, number or underscore with nothing.
|
|
|
|
dataString = dataString.replace(re"[^a-zA-Z0-9-]", "")
|
|
|
|
#convert to all lowercase.
|
|
|
|
dataString = dataString.toLowerAscii()
|
|
|
|
return dataString
|
|
|
|
|
|
|
|
proc getIdFromURI*(uri: string): int =
|
|
|
|
#let parsedUri = parseUri(uri)
|
|
|
|
let pathSeq = parseUri(uri).path.split('/')
|
|
|
|
result = strutils.parseInt(pathSeq[2])
|
|
|
|
|
|
|
|
proc parseIntIf*(input: string): int =
|
|
|
|
if input.len > 0:
|
|
|
|
return parseInt(input)
|
|
|
|
else:
|
|
|
|
return 0
|
|
|
|
|
|
|
|
proc parseFloatIf*(input: string): float =
|
|
|
|
if input.len > 0:
|
|
|
|
return parseFloat(input)
|
|
|
|
else:
|
|
|
|
return 0.0
|
|
|
|
|
|
|
|
#not cryptographically secure.
|
|
|
|
proc rndStr20*(): string =
|
|
|
|
for _ in 0..20:
|
|
|
|
add(result, char(rand(int('A') .. int('z'))))
|
|
|
|
|
|
|
|
proc boolToInt*(myBool: bool): int =
|
|
|
|
if myBool == true:
|
|
|
|
return 1
|
|
|
|
else:
|
|
|
|
return 0
|
|
|
|
|