import tables, random, os, times, json, asyncfile, asyncdispatch, parseutils import nimhafas import cache_types, types randomize() proc toAlphaId (n: int): string = let chars = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" var tmp = n var digitValue: int = 1 var digit: int = 0 while tmp > 0: digitValue *= chars.len digit = tmp mod digitValue let char = int(digit * chars.len / digitValue) result = $(chars[char]) & result tmp -= digit proc fromAlphaId (s: string): int = let chars = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" for char in s: result *= chars.len result += chars.skipUntil(char) proc getFreeAlphaId (): string = result = toAlphaId(int32(rand(high(int32)))) while fileExists(getEnv("CACHE_PATH") & "/" & $result & ".json"): result = toAlphaId(int32(rand(high(int32)))) proc cacheExists* (id: string ): bool = return fileExists(getEnv("CACHE_PATH") & "/" & $id & ".json") proc getCacheObject* (reqId: string): CacheObject = if not cacheExists(reqId): raise newException(notFoundException, "REQUEST_NOT_FOUND") return parseFile(getEnv("CACHE_PATH") & "/" & $reqId & ".json").to(CacheObject) proc saveJourneys* (params: JourneysParams, journeysResponse: JourneysResponse): Future[CacheObject] {.async.} = let reqId = getFreeAlphaId() let lastUpdated = getTime().toUnix() var journeys = initTable[string, Journey]() var maxId = -1 for journey in journeysResponse.journeys: inc(maxId) journeys[$maxId] = journey var cacheObj = CacheObject( version: 1, reqId: reqId, minId: 0, maxId: maxId, earlierRef: journeysResponse.earlierRef, laterRef: journeysResponse.laterRef, lastUpdated: lastUpdated, params: params, journeys: journeys ) var file = openAsync(getEnv("CACHE_PATH") & "/" & $reqId & ".json", fmReadWrite) await file.write($(%* cacheObj)) return cacheObj proc updateJourneys* (reqId: string, mode: moreJourneysMode, journeysResponse: JourneysResponse): Future[CacheObject] {.async.} = var cacheObj = getCacheObject(reqId) if mode == earlier: cacheObj.minId -= journeysResponse.journeys.len var cnt = cacheObj.minId for journey in journeysResponse.journeys: cacheObj.journeys[$cnt] = journey inc(cnt) else: for journey in journeysResponse.journeys: inc(cacheObj.maxId) cacheObj.journeys[$cacheObj.maxId] = journey cacheObj.lastUpdated = getTime().toUnix() if mode != later: cacheObj.earlierRef = journeysResponse.earlierRef else: cacheObj.laterRef = journeysResponse.laterRef var file = openAsync(getEnv("CACHE_PATH") & "/" & $reqId & ".json", fmReadWrite) await file.write($(%* cacheObj)) return cacheObj proc updateJourney* (reqId: string, journeyId: string, journey: Journey): Future[CacheObject] {.async.} = var cacheObj = getCacheObject(reqId) cacheObj.lastUpdated = getTime().toUnix() cacheObj.journeys[journeyId] = journey var file = openAsync(getEnv("CACHE_PATH") & "/" & $reqId & ".json", fmReadWrite) await file.write($(%* cacheObj)) return cacheObj