Skip to content

Commit

Permalink
switch to cfproxy - fixes #66
Browse files Browse the repository at this point in the history
  • Loading branch information
froehlichA committed Feb 27, 2022
1 parent 88acea9 commit cf2c9bb
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 21 deletions.
27 changes: 14 additions & 13 deletions src/api/cfclient.nim
@@ -1,37 +1,38 @@
## Provides functions for connecting to the unofficial curseforge api.
## Provides functions for connecting to the CF proxy [https://github.com/bmpm-mc/cfproxy].
##
## The unofficial API has capabilities like:
## The proxy connects to the official API internally, and has capabilities like:
## - Searching for a addon.
## - Retrieving an addon by their project id.
## - Retrieving the files of an given addon.
##
## Some docs for the unofficial API are available at https://gaz492.github.io/.
## Docs for the official API are available at https://docs.curseforge.com.
## Requests to the proxy stay the same, except the base URL is switched out.

import asyncdispatch, json, options, strutils
import uri except Url
import cfcore, http

const
## base url of the forgesvc endpoint
addonsBaseUrl = "https://addons-ecs.forgesvc.net/api/v2"
## base url of the cfproxy endpoint
addonsBaseUrl = "https://cfproxy.fly.dev"
## base url of the curse metadata api endpoint
## used for retrieving mods by their slug, which isn't possible with the curse api
addonsSlugBaseUrl = "https://curse.nikky.moe/graphql"

proc fetchAddonsByQuery*(query: string, category = CfAddonGameCategory.Mod): Future[seq[CfAddon]] {.async.} =
## retrieves all addons that match the given `query` search and `category`.
let encodedQuery = encodeUrl(query, usePlus = false)
let url = addonsBaseUrl & "/addon/search?gameId=432&sectionId=" & $category & "&pageSize=50&searchFilter=" & encodedQuery
let url = addonsBaseUrl & "/v1/mods/search?gameId=432&classId=" & $category & "&pageSize=50&sortField=6&sortOrder=desc&searchFilter=" & encodedQuery
try:
return get(url.Url).await.parseJson.addonsFromForgeSvc
return get(url.Url).await.parseJson["data"].addonsFromForgeSvc
except HttpRequestError:
return @[]

proc fetchAddon*(projectId: int): Future[Option[CfAddon]] {.async.} =
## get the addon with the given `projectId`.
let url = addonsBaseUrl & "/addon/" & $projectId
let url = addonsBaseUrl & "/v1/mods/" & $projectId
try:
return get(url.Url).await.parseJson.addonFromForgeSvc.some
return get(url.Url).await.parseJson["data"].addonFromForgeSvc.some
except HttpRequestError:
return none[CfAddon]()

Expand All @@ -53,16 +54,16 @@ proc fetchAddon*(slug: string): Future[Option[CfAddon]] {.async.} =

proc fetchAddonFiles*(projectId: int): Future[seq[CfAddonFile]] {.async.} =
## get all addon files associated with the given `projectId`.
let url = addonsBaseUrl & "/addon/" & $projectId & "/files"
let url = addonsBaseUrl & "/v1/mods/" & $projectId & "/files?pageSize=10000"
try:
return get(url.Url).await.parseJson.addonFilesFromForgeSvc
return get(url.Url).await.parseJson["data"].addonFilesFromForgeSvc
except HttpRequestError:
return @[]

proc fetchAddonFile*(projectId: int, fileId: int): Future[Option[CfAddonFile]] {.async.} =
## get the addon file with the given `fileId` & `projectId`.
let url = addonsBaseUrl & "/addon/" & $projectId & "/file/" & $fileId
let url = addonsBaseUrl & "/v1/mods/" & $projectId & "/files/" & $fileId
try:
return get(url.Url).await.parseJson.addonFileFromForgeSvc.some
return get(url.Url).await.parseJson["data"].addonFileFromForgeSvc.some
except HttpRequestError:
return none[CfAddonFile]()
14 changes: 7 additions & 7 deletions src/api/cfcore.nim
Expand Up @@ -49,11 +49,11 @@ converter addonFileFromForgeSvc*(json: JsonNode): CfAddonFile =
result.name = json["displayName"].getStr()
result.releaseType = json["releaseType"].getInt().CfAddonFileReleaseType
result.downloadUrl = json["downloadUrl"].getStr()
result.gameVersions = json["gameVersion"].getElems().map((x) => x.getStr().Version)
result.gameVersions = json["gameVersions"].getElems().map((x) => x.getStr().Version)
result.dependencies = collect(newSeq):
for depends in json["dependencies"].getElems():
if depends["type"].getInt() == RequiredDependencyType:
depends["addonId"].getInt()
if depends["relationType"].getInt() == RequiredDependencyType:
depends["modId"].getInt()

converter addonFilesFromForgeSvc*(json: JsonNode): seq[CfAddonFile] =
## creates addon files from json retrieved by an forgesvc endpoint
Expand All @@ -65,15 +65,15 @@ converter addonFromForgeSvc*(json: JsonNode): CfAddon =
result.projectId = json["id"].getInt()
result.name = json["name"].getStr()
result.description = json["summary"].getStr()
result.websiteUrl = json["websiteUrl"].getStr()
result.websiteUrl = json["links"]{"websiteUrl"}.getStr()
result.authors = json["authors"].getElems().map((x) => x["name"].getStr())
result.downloads = json["downloadCount"].getFloat().int
result.popularity = json["popularityScore"].getFloat()
result.popularity = json["gamePopularityRank"].getFloat()
result.latestFiles = json["latestFiles"].getElems().map(addonFileFromForgeSvc)
result.gameVersionLatestFiles = collect(newSeq):
for file in json["gameVersionLatestFiles"].getElems():
for file in json["latestFilesIndexes"].getElems():
let version = file["gameVersion"].getStr().Version
let fileId = file["projectFileId"].getInt()
let fileId = file["fileId"].getInt()
(version: version, fileId: fileId)

converter addonsFromForgeSvc*(json: JsonNode): seq[CfAddon] =
Expand Down
1 change: 0 additions & 1 deletion tests/api/tcfclient.nim
@@ -1,6 +1,5 @@
discard """
cmd: "nim $target --hints:on -d:testing -d:ssl --nimblePath:tests/deps $options $file"
disabled: "win"
"""

import asyncdispatch, options, sequtils, sugar
Expand Down

0 comments on commit cf2c9bb

Please sign in to comment.