Skip to content

Commit

Permalink
Added caching with periodic refresh
Browse files Browse the repository at this point in the history
  • Loading branch information
iinsertNameHere committed Jul 19, 2024
1 parent e328316 commit db35dce
Show file tree
Hide file tree
Showing 4 changed files with 139 additions and 48 deletions.
5 changes: 4 additions & 1 deletion src/catnap.nim
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import "catnaplib/platform/fetch"
import "catnaplib/drawing/render"
from "catnaplib/global/definitions" import CONFIGPATH, DISTROSPATH, Config, STATNAMES, CACHEPATH
from "catnaplib/global/definitions" import CONFIGPATH, DISTROSPATH, Config, STATNAMES, CACHEPATH, TEMPPATH
import "catnaplib/global/config"
import "catnaplib/terminal/logging"
import parsetoml
Expand Down Expand Up @@ -305,6 +305,9 @@ if paramCount() > 0:
if not dirExists(CACHEPATH):
createDir(CACHEPATH)

if not dirExists(TEMPPATH):
createDir(TEMPPATH)

# Getting config
var cfg = LoadConfig(cfgPath, dstPath)

Expand Down
9 changes: 7 additions & 2 deletions src/catnaplib/global/definitions.nim
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,13 @@ proc getCachePath*(): string =
else:
result = "/tmp/catnap"

let CACHEPATH* = getCachePath()
let CACHEPATH* = getCachePath()
let TEMPPATH* = "/tmp/catnap"

proc toCachePath*(p: string): string =
# Converts a path [p] into a cahce path
return joinPath(CACHEPATH, p)

proc toTmpPath*(p: string): string =
# Converts a path [p] into a temp path
return joinPath(CACHEPATH, p)
return joinPath(TEMPPATH, p)
54 changes: 54 additions & 0 deletions src/catnaplib/platform/caching.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import times
import os
import strformat
import strutils

const datetimeFormat = "YYYY-MM-dd HH:mm:ss"
let INFINITEDURATION* = initDuration(
nanoseconds = 4294967295,
microseconds = 4294967295,
milliseconds = 4294967295,
seconds = 4294967295,
minutes = 4294967295,
hours = 4294967295,
days = 4294967295,
weeks = 4294967295)

proc writeCache*(filename: string, content: string, dur: Duration) =
if fileExists(filename): removeFile(filename)

var expiration: string
if dur == INFINITEDURATION:
expiration = "NEVER"
else:
expiration = $(now() + dur).format(datetimeFormat)

var filecontent = &"[CONTENT]\n{content}\n[EXPIRATION]\n{expiration}"
writeFile(filename, filecontent)

proc readCache*(filename: string, default: string = ""): string =
if not fileExists(filename): return default

var filecontent = readFile(filename).strip()
let lines = filecontent.split('\n')

var content: seq[string]
var expiration: DateTime = now()
var partindex = 0
for line in lines:
if line == "[CONTENT]" and partindex == 0:
partindex += 1
continue
elif line == "[EXPIRATION]" and partindex == 1:
partindex += 1
continue

if partindex == 1:
content.add(line)
elif partindex == 2:
if line == "NEVER": expiration = (now() + 1.hours)
else: expiration = parse(line, datetimeFormat)
break

if now() >= expiration: return default
return content.join("\n")
119 changes: 74 additions & 45 deletions src/catnaplib/platform/probe.nim
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,48 @@ import math
import strutils
import parsecfg
import posix_utils
import times
import tables
import osproc
import re
from unicode import toLower
from "../global/definitions" import DistroId, PKGMANAGERS, PKGCOUNTCOMMANDS, toTmpPath
from "../global/definitions" import DistroId, PKGMANAGERS, PKGCOUNTCOMMANDS, toCachePath, toTmpPath
import "../terminal/logging"
import "caching"
import algorithm

proc getDistro*(): string =
let cacheFile = "distroname".toCachePath
result = readCache(cacheFile)
if result != "": return

when defined(linux):
# Returns the name of the running linux distro
result = "/etc/os-release".loadConfig.getSectionValue("", "PRETTY_NAME") & " " & uname().machine
elif defined(macos):
result = "MacOS X" & " " & uname().machine

writeCache(cacheFile, result, INFINITEDURATION)

proc getDistroId*(): DistroId =
# Returns the DistroId of the running linux distro
let cacheFile = "distroid".toCachePath
let raw = readCache(cacheFile)
if raw != "":
let raw_vals = raw.split(':')
if raw_vals.len == 2:
result.id = raw_vals[0]
result.like = raw_vals[1]


if fileExists("/boot/issue.txt"): # Check if raspbian else get distroid from /etc/os-release
result.id = "raspbian"
result.like = "debian"
else:
result.id = "/etc/os-release".loadConfig.getSectionValue("", "ID").toLower()
result.like = "/etc/os-release".loadConfig.getSectionValue("", "ID_LIKE").toLower()

writeCache(cacheFile, &"{result.id}|{result.like}", INFINITEDURATION)

proc getUptime*(): string =
# Returns the system uptime as a string (DAYS, HOURS, MINUTES)

Expand Down Expand Up @@ -178,7 +196,7 @@ proc getMounts*(): seq[string] =
result.add(mount)

proc getDisk*(mount: string): string =
# Returns disk space usage
# Returns diskinfo for the mounting point
proc getTotalDiskSpace(mountingPoint: cstring): cfloat {.importc, varargs, header: "getDisk.h".}
proc getUsedDiskSpace(mountingPoint: cstring): cfloat {.importc, varargs, header: "getDisk.h".}

Expand All @@ -189,7 +207,12 @@ proc getDisk*(mount: string): string =
result = &"{used} / {total} GB ({percentage}%)"

proc getCpu*(): string =
# Returns CPU model
# Returns the cpu name
let cacheFile = "cpu".toCachePath
result = readCache(cacheFile)
if result != "":
return

let rawLines = readFile("/proc/cpuinfo").split("\n")

var key_name = "model name"
Expand All @@ -206,9 +229,10 @@ proc getCpu*(): string =
if key == key_name:
result = val
break

writeCache(cacheFile, result, initDuration(days=1))

proc getPkgManager(distroId: DistroId): string =
# Returns main package manager of distro
for key in PKGMANAGERS.keys:
if distroId.id == key:
return PKGMANAGERS[key]
Expand All @@ -217,72 +241,77 @@ proc getPkgManager(distroId: DistroId): string =
if distroId.like == key:
return PKGMANAGERS[key]

return "unknown"
return "Unknown"

proc getPackages*(distroId: DistroId = getDistroId()): string =
# Return install package count of the main package manager of the distro
# Returns the installed package count
let cacheFile = "packages".toCachePath

result = readCache(cacheFile)
if result != "":
return

let pkgManager = getPkgManager(distroId)
if pkgManager == "unknown":
return "unknown"
if pkgManager == "Unknown":
return "Unknown"

var foundPkgCmd = false
for key in PKGCOUNTCOMMANDS.keys:
if pkgManager == key:
foundPkgCmd = true
break
if not foundPkgCmd:
return "unknown"
return "Unknown"

let tmpFile = "pkgcount.txt".toTmpPath

if not fileExists(tmpFile):
let cmd: string = PKGCOUNTCOMMANDS[pkgManager] & " > " & tmpFile
if execCmd(cmd) != 0:
logError("Failed to fetch pkg count!")
let tmpFile = "packages.txt".toTmpPath
let cmd: string = PKGCOUNTCOMMANDS[pkgManager] & " > " & tmpFile
if execCmd(cmd) != 0:
logError("Failed to fetch pkg count!")

let count = readFile(tmpFile).strip()
return count & " [" & pkgManager & "]"
result = count & " [" & pkgManager & "]"
writeCache(cacheFile, result, initDuration(hours=2))

proc getGpu*(): string =
# Returns the VGA line of lspci output
# Returns the gpu name
let cacheFile = "gpu".toCachePath

result = readCache(cacheFile)
if result != "":
return

let tmpFile = "lspci.txt".toTmpPath
let gpuFile = "gpu.txt".toTmpPath

if fileExists(gpuFile):
return readFile(gpuFile)

if not fileExists(tmpFile):
if execCmd("lspci > " & tmpFile) != 0:
logError("Failed to fetch GPU!")
if execCmd("lspci > " & tmpFile) != 0:
logError("Failed to fetch GPU!")

var vga = ""
var vga = "Unknown"
let lspci = readFile(tmpFile)
for line in lspci.split('\n'):
if line.split(' ')[1] == "VGA":
vga = line
break

if vga == "":
writeFile(gpuFile, "Unknown")
return "Unknown"

let vga_parts = vga.split(":")

if vga_parts.len < 2:
writeFile(gpuFile, "Unknown")
return "Unknown"

let gpu = vga_parts[vga_parts.len - 1].split("(")[0]
writeFile(gpuFile, gpu.strip())
return gpu.strip()
if vga_parts.len >= 2 or vga != "Unknown":
result = vga_parts[vga_parts.len - 1].split("(")[0].strip()
else:
result = "Unknown"

writeCache(cacheFile, result, initDuration(days=1))

proc getWeather*(): string =
# Returns current weather
let cacheFile = "weather".toCachePath

result = readCache(cacheFile)
if result != "":
return

let tmpFile = "weather.txt".toTmpPath
if fileExists(tmpFile):
# Returns the weather and discards the annoying newline.
result = readFile(tmpFile).strip()
else:
if execCmd("curl -s wttr.in/?format=3 > " & tmpFile) != 0:
logError("Failed to fetch weather!")
# Returns the weather and discards the annoying newline.
result = readFile(tmpFile).strip()
if execCmd("curl -s wttr.in/?format=3 > " & tmpFile) != 0:
logError("Failed to fetch weather!")

result = readFile(tmpFile).strip()
writeCache(cacheFile, result, initDuration(minutes=30))

0 comments on commit db35dce

Please sign in to comment.