131 lines
3.1 KiB
Nim
131 lines
3.1 KiB
Nim
import httpclient
|
|
import json
|
|
import strformat
|
|
import os
|
|
import uri
|
|
import chronicles
|
|
|
|
import types/gif_item
|
|
from statusgo_backend/gif import getRecentGifs, getFavoriteGifs, setFavoriteGifs, setRecentGifs
|
|
|
|
logScope:
|
|
topics = "gif"
|
|
|
|
const MAX_RECENT = 50
|
|
# set via `nim c` param `-d:TENOR_API_KEY:[api_key]`; should be set in CI/release builds
|
|
const TENOR_API_KEY {.strdefine.} = ""
|
|
let TENOR_API_KEY_ENV = $getEnv("TENOR_API_KEY")
|
|
|
|
let TENOR_API_KEY_RESOLVED =
|
|
if TENOR_API_KEY_ENV != "":
|
|
TENOR_API_KEY_ENV
|
|
else:
|
|
TENOR_API_KEY
|
|
|
|
const baseUrl = "https://g.tenor.com/v1/"
|
|
let defaultParams = fmt("&media_filter=minimal&limit=50&key={TENOR_API_KEY_RESOLVED}")
|
|
|
|
type
|
|
GifClient* = ref object
|
|
client: HttpClient
|
|
favorites: seq[GifItem]
|
|
recents: seq[GifItem]
|
|
favoritesLoaded: bool
|
|
recentsLoaded: bool
|
|
|
|
proc newGifClient*(): GifClient =
|
|
result = GifClient()
|
|
result.client = newHttpClient()
|
|
result.favorites = @[]
|
|
result.recents = @[]
|
|
|
|
proc getContentWithRetry(self: GifClient, path: string, maxRetry: int = 3): string =
|
|
var currentRetry = 0
|
|
while true:
|
|
try:
|
|
let content = self.client.getContent(fmt("{baseUrl}{path}{defaultParams}"))
|
|
return content
|
|
except Exception as e:
|
|
currentRetry += 1
|
|
error "could not query tenor API", msg=e.msg
|
|
|
|
if currentRetry >= maxRetry:
|
|
raise
|
|
|
|
sleep(100 * currentRetry)
|
|
|
|
proc tenorQuery(self: GifClient, path: string): seq[GifItem] =
|
|
try:
|
|
let content = self.getContentWithRetry(path)
|
|
let doc = content.parseJson()
|
|
|
|
var items: seq[GifItem] = @[]
|
|
for json in doc["results"]:
|
|
items.add(tenorToGifItem(json))
|
|
|
|
return items
|
|
except:
|
|
return @[]
|
|
|
|
proc search*(self: GifClient, query: string): seq[GifItem] =
|
|
return self.tenorQuery(fmt("search?q={encodeUrl(query)}"))
|
|
|
|
proc getTrendings*(self: GifClient): seq[GifItem] =
|
|
return self.tenorQuery("trending?")
|
|
|
|
proc getFavorites*(self: GifClient): seq[GifItem] =
|
|
if not self.favoritesLoaded:
|
|
self.favoritesLoaded = true
|
|
self.favorites = getFavoriteGifs()
|
|
|
|
return self.favorites
|
|
|
|
proc getRecents*(self: GifClient): seq[GifItem] =
|
|
if not self.recentsLoaded:
|
|
self.recentsLoaded = true
|
|
self.recents = getRecentGifs()
|
|
|
|
return self.recents
|
|
|
|
proc isFavorite*(self: GifClient, gifItem: GifItem): bool =
|
|
for favorite in self.getFavorites():
|
|
if favorite.id == gifItem.id:
|
|
return true
|
|
|
|
return false
|
|
|
|
proc toggleFavorite*(self: GifClient, gifItem: GifItem) =
|
|
var newFavorites: seq[GifItem] = @[]
|
|
var found = false
|
|
|
|
for favoriteGif in self.getFavorites():
|
|
if favoriteGif.id == gifItem.id:
|
|
found = true
|
|
continue
|
|
|
|
newFavorites.add(favoriteGif)
|
|
|
|
if not found:
|
|
newFavorites.add(gifItem)
|
|
|
|
self.favorites = newFavorites
|
|
setFavoriteGifs(newFavorites)
|
|
|
|
proc addToRecents*(self: GifClient, gifItem: GifItem) =
|
|
let recents = self.getRecents()
|
|
var newRecents: seq[GifItem] = @[gifItem]
|
|
var idx = 0
|
|
|
|
while idx < MAX_RECENT - 1:
|
|
if idx >= recents.len:
|
|
break
|
|
|
|
if recents[idx].id == gifItem.id:
|
|
idx += 1
|
|
continue
|
|
|
|
newRecents.add(recents[idx])
|
|
idx += 1
|
|
|
|
self.recents = newRecents
|
|
setRecentGifs(newRecents) |