92 lines
2.4 KiB
Nim
92 lines
2.4 KiB
Nim
import asyncdispatch, times, strutils
|
|
import norm/sqlite
|
|
|
|
import types, api/profile
|
|
|
|
template safeAddColumn(field: typedesc): untyped =
|
|
try: field.addColumn
|
|
except DbError: discard
|
|
|
|
dbFromTypes("cache.db", "", "", "", [Profile, Video])
|
|
|
|
withDb:
|
|
Video.createTable(force=true)
|
|
try: Profile.createTable()
|
|
except DbError: discard
|
|
|
|
safeAddColumn Profile.lowername
|
|
safeAddColumn Profile.suspended
|
|
|
|
var profileCacheTime = initDuration(minutes=10)
|
|
|
|
proc isOutdated*(profile: Profile): bool =
|
|
getTime() - profile.updated > profileCacheTime
|
|
|
|
proc cache*(profile: var Profile) =
|
|
withDb:
|
|
try:
|
|
let p = Profile.getOne("lowername = ?", profile.lowername)
|
|
profile.id = p.id
|
|
profile.update()
|
|
except KeyError:
|
|
if profile.username.len > 0:
|
|
profile.insert()
|
|
|
|
proc hasCachedProfile*(username: string): Option[Profile] =
|
|
withDb:
|
|
try:
|
|
let p = Profile.getOne("lowername = ?", toLower(username))
|
|
doAssert not p.isOutdated
|
|
result = some p
|
|
except AssertionError, KeyError:
|
|
result = none Profile
|
|
|
|
proc getCachedProfile*(username, agent: string;
|
|
force=false): Future[Profile] {.async.} =
|
|
withDb:
|
|
try:
|
|
result.getOne("lowername = ?", toLower(username))
|
|
doAssert not result.isOutdated
|
|
except AssertionError, KeyError:
|
|
result = await getProfileFull(username, agent)
|
|
cache(result)
|
|
|
|
proc setProfileCacheTime*(minutes: int) =
|
|
profileCacheTime = initDuration(minutes=minutes)
|
|
|
|
proc cache*(video: var Video) =
|
|
withDb:
|
|
try:
|
|
let v = Video.getOne("videoId = ?", video.videoId)
|
|
video.id = v.id
|
|
video.update()
|
|
except KeyError:
|
|
if video.videoId.len > 0:
|
|
video.insert()
|
|
|
|
proc uncache*(id: int64) =
|
|
withDb:
|
|
try:
|
|
var video = Video.getOne("videoId = ?", $id)
|
|
video.delete()
|
|
except:
|
|
discard
|
|
|
|
proc getCachedVideo*(id: int64): Option[Video] =
|
|
withDb:
|
|
try:
|
|
return some Video.getOne("videoId = ?", $id)
|
|
except KeyError:
|
|
return none Video
|
|
|
|
proc cacheCleaner*() {.async.} =
|
|
while true:
|
|
await sleepAsync(profileCacheTime.inMilliseconds.int)
|
|
withDb:
|
|
let up = "updated<" & $toUnix(getTime() - profileCacheTime)
|
|
var profiles = Profile.getMany(10000, cond=up)
|
|
var videos = Video.getMany(10000, cond=up)
|
|
transaction:
|
|
for p in profiles.mitems: delete(p)
|
|
for v in videos.mitems: delete(v)
|