Skip to content

Instantly share code, notes, and snippets.

@hugosenari
Created April 6, 2022 12:52
Show Gist options
  • Save hugosenari/4da28401d32f72194a20653cc4608351 to your computer and use it in GitHub Desktop.
Save hugosenari/4da28401d32f72194a20653cc4608351 to your computer and use it in GitHub Desktop.
command line memoization
# import a lot of things because I'm to lazy (or dumb) to think about what imports
import std/[
algorithm,
asyncdispatch,
asyncfile,
asyncnet,
asyncstreams,
base64,
browsers,
distros,
enumerate,
enumutils,
htmlparser,
httpclient,
json,
jsonutils,
math,
md5,
mimetypes,
oids,
options,
os,
osproc,
parsecfg,
parsecsv,
parsesql,
parsexml,
posix,
posix_utils,
random,
re,
sequtils,
sets,
setutils,
sha1,
streams,
strformat,
strutils,
sugar,
tables,
terminal,
threadpool,
times,
uri,
with,
]
## SHELL HELPERS
proc arg(n: int; default: string = ""): string =
result = default
if paramCount() >= n:
result = n.paramStr
proc arg(n: int; default: JsonNode): string =
var defaultVal = default.getStr $default
arg n, defaultVal
proc env(name: string; default: string = ""): string =
getEnv name, default
proc env(name: JsonNode; default: string = ""): string =
getEnv name.getStr($name), default
proc env(name: JsonNode; default: JsonNode): string =
getEnv name.getStr($name), default.getStr($default)
let
args = commandLineParams().mapIt it.quoteShell
PRJ_ROOT = env "PRJ_ROOT"
proc cd(dir: string): void =
setCurrentDir dir
proc cmd(cmdName: string; arguments: seq[string] = @[]; dir: string = "."): void =
quit(execShellCmd fmt"""cd {dir}; {cmdName} {arguments.join " "} """)
proc cmd(cmdName: string; dir: string = "."): void =
quit(execShellCmd fmt"""cd {dir}; {cmdName}""")
## JSON HELPERS
type JsonPath = distinct seq[string]
proc jpath(path: string; sep: char = '/'): JsonPath =
JsonPath path.split(sep)
proc get(path: JsonPath; obj: JsonNode; default: JsonNode = newJNull()): JsonNode =
result = obj
for trace in cast[seq[string]](path):
result = result.getOrDefault trace
if result.isNil:
result = default
proc `[]`(obj: JsonNode; path: JsonPath): JsonNode =
path.get obj
proc set(path: JsonPath; obj: JsonNode; val: JsonNode): void =
var
lastObj = obj
traces = cast[seq[string]](path)
tracesLen = traces.len
for (n, trace) in enumerate(1, traces):
var nextObj = lastObj.getOrDefault(trace)
if n == tracesLen:
lastObj[trace] = val
break
if nextObj.isNil or nextObj.kind != JObject:
nextObj = newJObject()
lastObj[trace] = nextObj
lastObj = nextObj
proc `[]=`(obj: JsonNode; path: JsonPath; val: JsonNode): void =
path.set obj, val
proc `[]=`(obj: JsonNode; path: JsonPath; val: string): void =
path.set obj, %* val
proc `[]=`(obj: JsonNode; path: JsonPath; val: enum): void =
path.set obj, %* val
proc `[]=`(obj: JsonNode; path: JsonPath; val: SomeInteger): void =
path.set obj, %* val
proc `[]=`(obj: JsonNode; path: JsonPath; val: SomeFloat): void =
path.set obj, %* val
proc `[]=`(obj: JsonNode; path: JsonPath; val: bool): void =
path.set obj, %* val
include dumbness.nim
let
params = args[1 .. ^1].join " "
key = $params.secureHash
tmpDir = getTempDir() / "memoize"
tmpFile = tmpDir / fmt"{key}.json"
# cmd fmt"find {tmpDir} -type f -cmin '+60' -delete"
if not dirExists tmpDir:
createDir tmpDir
if not fileExists tmpFile:
writeFile tmpFile, """{"ttl": 0}"""
let cache = parseJson readFile tmpFile
if cache["ttl"].getInt < now().toTime.toUnix:
let
(output,
exitCode) = execCmdEx params
interval = parseInt arg 1
expiresAt = now() + interval.seconds
cache["code"] = %* exitCode
cache["out" ] = %* output.strip(chars={'\n'})
cache["ttl" ] = %* expiresAt.toTime.toUnix
writeFile tmpFile, cache.pretty
echo getStr cache["out" ]
quit getInt cache["code"]
@hugosenari
Copy link
Author

Example:
call curl with 20 seconds cache

memoize 20 curl 'https://fourtonfish.com/hellosalut/?mode=auto'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment