Skip to content

Commit fc0b384

Browse files
committed
Merge branch 'development' into main
2 parents 9e0c939 + 722dd8f commit fc0b384

37 files changed

+141
-111
lines changed

.github/workflows/check.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ jobs:
1919
with:
2020
nim-version: ${{ env.NIM_VERSION }}
2121
- name: Build
22-
run: nimble build -y -d:ssl -d:release
22+
run: nimble build -d:release -y
2323

2424
test:
2525
runs-on: ${{ matrix.os }}

.github/workflows/main.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ jobs:
4141
with:
4242
nim-version: ${{ env.NIM_VERSION }}
4343
- name: Build
44-
run: nimble build -y -d:ssl -d:release
44+
run: nimble build -d:release -y
4545
- name: Store artifacts
4646
uses: actions/upload-artifact@v2
4747
with:

pax.nimble

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,3 @@ requires "zippy >= 0.6.2"
1818

1919
task test, "Test project":
2020
exec "testament all"
21-
22-
task buildDev, "Build for usage during development":
23-
exec "nimble build -d:ssl"
24-
25-
task buildProd, "Build for production":
26-
exec "nimble build -d:ssl -d:release"
27-
28-
task buildCI, "Build for production on the CI machine":
29-
exec "nimble build -d:ssl -d:release -y"

readme.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ You'll need:
6767
* A C compiler (depending on your operating system, one might be already installed)
6868

6969
Clone and `cd` into the repository - and you're good to go!\
70-
Run `nimble buildDev` to build the application for development, or run `nimble buildProd` to create an optimized release build.\
70+
Run `nimble build` to build the application for development, or run `nimble build -d:release` to create an optimized release build.\
7171
Execute the program with `./pax` (on Linux) or `pax.exe` (on Windows).
7272

7373

src/api/cfapi.nim

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,35 +22,35 @@ const
2222
type
2323
CfApiError* = object of HttpRequestError
2424

25-
proc fetchAddonsByQuery*(query: string, category: Option[CfAddonGameCategory]): Future[JsonNode] {.async.} =
25+
proc fetchAddonsByQuery*(query: string, category: Option[CfAddonGameCategory]): Future[seq[CfAddon]] {.async.} =
2626
## retrieves all addons that match the given `query` search and `category`.
2727
let encodedQuery = encodeUrl(query, usePlus = false)
2828
var url = addonsBaseUrl & "/v1/mods/search?gameId=432&pageSize=50&sortField=6&sortOrder=desc&searchFilter=" & encodedQuery
2929
if category.isSome:
3030
url = url & "&classId=" & $ord(category.get())
31-
return get(url.Url).await.parseJson["data"]
31+
return get(url.Url).await.parseJson["data"].addonsFromForgeSvc
3232

33-
proc fetchAddon*(projectId: int): Future[JsonNode] {.async.} =
33+
proc fetchAddon*(projectId: int): Future[CfAddon] {.async.} =
3434
## get the addon with the given `projectId`.
3535
let url = addonsBaseUrl & "/v1/mods/" & $projectId
3636
try:
37-
return get(url.Url).await.parseJson["data"]
37+
return get(url.Url).await.parseJson["data"].addonFromForgeSvc
3838
except HttpRequestError:
3939
raise newException(CfApiError, "addon with project id '" & $projectId & "' not found.")
4040

41-
proc fetchAddons*(projectIds: seq[int]): Future[JsonNode] {.async.} =
41+
proc fetchAddons*(projectIds: seq[int]): Future[seq[CfAddon]] {.async.} =
4242
## get all addons with their given `projectId`.
4343
let url = addonsBaseUrl & "/v1/mods/"
4444
let body = %* { "modIds": projectIds }
4545
try:
46-
let addons = post(url.Url, $body).await.parseJson["data"]
46+
let addons = post(url.Url, $body).await.parseJson["data"].addonsFromForgeSvc
4747
if projectIds.len != addons.len:
4848
raise newException(CfApiError, "one of the addons of project ids '" & $projectIds & "' was not found.")
4949
return addons
5050
except HttpRequestError:
5151
raise newException(CfApiError, "one of the addons of project ids '" & $projectIds & "' was not found.")
5252

53-
proc fetchAddon*(slug: string): Future[JsonNode] {.async.} =
53+
proc fetchAddon*(slug: string): Future[CfAddon] {.async.} =
5454
## get the addon matching the `slug`.
5555
let reqBody = %* {
5656
"query": "{ addons(slug: \"" & slug & "\") { id }}"
@@ -62,30 +62,30 @@ proc fetchAddon*(slug: string): Future[JsonNode] {.async.} =
6262
let projectId = addons[0]["id"].getInt()
6363
return await fetchAddon(projectId)
6464

65-
proc fetchAddonFiles*(projectId: int): Future[JsonNode] {.async.} =
65+
proc fetchAddonFiles*(projectId: int): Future[seq[CfAddonFile]] {.async.} =
6666
## get all addon files associated with the given `projectId`.
6767
let url = addonsBaseUrl & "/v1/mods/" & $projectId & "/files?pageSize=10000"
6868
try:
69-
return get(url.Url).await.parseJson["data"]
69+
return get(url.Url).await.parseJson["data"].addonFilesFromForgeSvc
7070
except HttpRequestError:
7171
raise newException(CfApiError, "addon with project id '" & $projectId & "' not found.")
7272

73-
proc fetchAddonFiles*(fileIds: seq[int]): Future[JsonNode] {.async.} =
73+
proc fetchAddonFiles*(fileIds: seq[int]): Future[seq[CfAddonFile]] {.async.} =
7474
## get all addon files with their given `fileIds`.
7575
let url = addonsBaseUrl & "/v1/mods/files"
7676
let body = %* { "fileIds": fileIds }
7777
try:
78-
let files = post(url.Url, $body).await.parseJson["data"]
78+
let files = post(url.Url, $body).await.parseJson["data"].addonFilesFromForgeSvc
7979
if fileIds.len != files.len:
8080
raise newException(CfApiError, "one of the addon files of file ids '" & $fileIds & "' was not found.")
8181
return files
8282
except HttpRequestError:
8383
raise newException(CfApiError, "one of the addon files of file ids '" & $fileIds & "' was not found.")
8484

85-
proc fetchAddonFile*(projectId: int, fileId: int): Future[JsonNode] {.async.} =
85+
proc fetchAddonFile*(projectId: int, fileId: int): Future[CfAddonFile] {.async.} =
8686
## get the addon file with the given `fileId` & `projectId`.
8787
let url = addonsBaseUrl & "/v1/mods/" & $projectId & "/files/" & $fileId
8888
try:
89-
return get(url.Url).await.parseJson["data"]
89+
return get(url.Url).await.parseJson["data"].addonFileFromForgeSvc
9090
except HttpRequestError:
9191
raise newException(CfApiError, "addon with project & file id '" & $projectId & ':' & $fileId & "' not found.")

src/api/cfcache.nim

Lines changed: 29 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -6,89 +6,87 @@
66
## and instead data from the local file system is returned.
77

88
import std/[json, options, os, times]
9+
import cfcore
910

1011
const
11-
cacheDir* = getCacheDir("pax") ## the cache folder
1212
addonCacheTime = 30.minutes ## how long an addon is cached
1313
addonFileCacheTime = 1.days ## how long an addon file is cached
1414

1515
proc getAddonFilename*(projectId: int): string {.inline.} =
1616
## get the filename of an addon in the cache.
17-
return cacheDir / ("addon:" & $projectId)
17+
return getCacheDir("pax") / ("addon:" & $projectId)
1818

1919
proc getAddonFileFilename*(fileId: int): string {.inline.} =
2020
## get the filename of an addon file in the cache.
21-
return cacheDir / ("file:" & $fileId)
21+
return getCacheDir("pax") / ("file:" & $fileId)
2222

23-
proc putAddon*(json: JsonNode): void =
23+
proc putAddon*(addon: CfAddon): void =
2424
## put an addon in the cache.
25-
let projectId = json["id"].getInt()
26-
let filename = getAddonFilename(projectId)
25+
let filename = getAddonFilename(addon.projectId)
2726
try:
28-
writeFile(filename, $json)
27+
writeFile(filename, $addon.toJson)
2928
except IOError:
3029
discard
3130

32-
proc putAddons*(json: JsonNode): void =
31+
proc putAddons*(addons: seq[CfAddon]): void =
3332
## put multiple addons in the cache.
34-
for elems in json.getElems():
35-
putAddon(elems)
33+
for addon in addons:
34+
putAddon(addon)
3635

37-
proc putAddonFile*(json: JsonNode): void =
36+
proc putAddonFile*(addonFile: CfAddonFile): void =
3837
## put an addon file in the cache.
39-
let fileId = json["id"].getInt()
40-
let filename = getAddonFileFilename(fileId)
38+
let filename = getAddonFileFilename(addonFile.fileId)
4139
try:
42-
writeFile(filename, $json)
40+
writeFile(filename, $addonFile.toJson)
4341
except IOError:
4442
discard
4543

46-
proc putAddonFiles*(json: JsonNode): void =
44+
proc putAddonFiles*(addonFiles: seq[CfAddonFile]): void =
4745
## put multiple addons in the cache.
48-
for elems in json.getElems():
49-
putAddonFile(elems)
46+
for addonFile in addonFiles:
47+
putAddonFile(addonFile)
5048

51-
proc getAddon*(projectId: int): Option[JsonNode] =
49+
proc getAddon*(projectId: int): Option[CfAddon] =
5250
## retrieve an addon from cache.
5351
let filename = getAddonFilename(projectId)
5452
if not fileExists(filename):
55-
return none[JsonNode]()
53+
return none[CfAddon]()
5654
let info = getFileInfo(filename)
5755
if info.lastWriteTime + addonCacheTime > getTime():
5856
let file = try:
5957
readFile(filename)
6058
except IOError:
61-
return none[JsonNode]()
62-
return some(file.parseJson)
63-
return none[JsonNode]()
59+
return none[CfAddon]()
60+
return some(file.parseJson.addonFromForgeSvc)
61+
return none[CfAddon]()
6462
65-
proc getAddonFile*(fileId: int): Option[JsonNode] =
63+
proc getAddonFile*(fileId: int): Option[CfAddonFile] =
6664
## retrieve an addon file from cache.
6765
let filename = getAddonFileFilename(fileId)
6866
if not fileExists(filename):
69-
return none[JsonNode]()
67+
return none[CfAddonFile]()
7068
let info = getFileInfo(filename)
7169
if info.lastWriteTime + addonFileCacheTime > getTime():
7270
let file = try:
7371
readFile(filename)
7472
except IOError:
75-
return none[JsonNode]()
76-
return some(file.parseJson)
77-
return none[JsonNode]()
73+
return none[CfAddonFile]()
74+
return some(file.parseJson.addonFileFromForgeSvc)
75+
return none[CfAddonFile]()
7876
7977
proc clean*(): int =
8078
## remove old files from the cache.
8179
## returns the number of files cleared.
8280
result = 0
83-
for filename in walkFiles(cacheDir / "addon:*"):
81+
for filename in walkFiles(getCacheDir("pax") / "addon:*"):
8482
let info = getFileInfo(filename)
8583
if info.lastWriteTime + addonCacheTime < getTime():
8684
try:
8785
removeFile(filename)
8886
inc(result)
8987
except IOError:
9088
discard
91-
for filename in walkFiles(cacheDir / "file:*"):
89+
for filename in walkFiles(getCacheDir("pax") / "file:*"):
9290
let info = getFileInfo(filename)
9391
if info.lastWriteTime + addonFileCacheTime < getTime():
9492
try:
@@ -100,8 +98,8 @@ proc clean*(): int =
10098
proc purge*(): void =
10199
## remove all files from the cache.
102100
try:
103-
removeDir(cacheDir)
104-
createDir(cacheDir)
101+
removeDir(getCacheDir("pax"))
102+
createDir(getCacheDir("pax"))
105103
except IOError:
106104
discard
107105

src/api/cfclient.nim

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ proc fetchAddonsByQuery*(query: string, category: Option[CfAddonGameCategory]):
3131
## retrieves all addons that match the given `query` search and `category`.
3232
let data = await cfapi.fetchAddonsByQuery(query, category)
3333
cfcache.putAddons(data)
34-
return data.addonsFromForgeSvc
34+
return data
3535
3636
proc fetchAddonsByQuery*(query: string, category: CfAddonGameCategory): Future[seq[CfAddon]] =
3737
## retrieves all addons that match the given `query` search and `category`.
@@ -45,10 +45,10 @@ proc fetchAddon(projectId: int, lookupCache: bool): Future[CfAddon] {.async.} =
4545
## get the addon with the given `projectId`.
4646
if lookupCache:
4747
withCachedAddon(addon, projectId):
48-
return addon.addonFromForgeSvc
48+
return addon
4949
let data = await cfapi.fetchAddon(projectId)
5050
cfcache.putAddon(data)
51-
return data.addonFromForgeSvc
51+
return data
5252
5353
proc fetchAddon*(projectId: int): Future[CfAddon] =
5454
## get the addon with the given `projectId`.
@@ -61,7 +61,7 @@ proc fetchAddonsChunks(projectIds: seq[int]): Future[seq[CfAddon]] {.async.} =
6161
try:
6262
let data = await cfapi.fetchAddons(projectIds)
6363
cfcache.putAddons(data)
64-
return data.addonsFromForgeSvc
64+
return data
6565
except CfApiError:
6666
# fallback to looking up the ids individually
6767
return await all(projectIds.map((x) => fetchAddon(x, lookupCache = false)))
@@ -104,13 +104,13 @@ proc fetchAddon*(slug: string): Future[CfAddon] {.async.} =
104104
## get the addon matching the `slug`.
105105
let data = await cfapi.fetchAddon(slug)
106106
cfcache.putAddon(data)
107-
return data.addonFromForgeSvc
107+
return data
108108

109109
proc fetchAddonFiles*(projectId: int): Future[seq[CfAddonFile]] {.async.} =
110110
## get all addon files associated with the given `projectId`.
111111
let data = await cfapi.fetchAddonFiles(projectId)
112112
cfcache.putAddonFiles(data)
113-
return data.addonFilesFromForgeSvc
113+
return data
114114

115115
proc fetchAddonFilesChunks(fileIds: seq[int], fallback = true): Future[seq[CfAddonFile]] {.async.} =
116116
## get all addons with their given `projectId`.
@@ -119,7 +119,7 @@ proc fetchAddonFilesChunks(fileIds: seq[int], fallback = true): Future[seq[CfAdd
119119
try:
120120
let data = await cfapi.fetchAddonFiles(fileIds)
121121
cfcache.putAddonFiles(data)
122-
return data.addonFilesFromForgeSvc
122+
return data
123123
except CfApiError as e:
124124
# fallback to looking up the ids individually
125125
if fallback:
@@ -161,8 +161,8 @@ proc fetchAddonFiles*(fileIds: seq[int], chunk = true): Future[seq[CfAddonFile]]
161161
proc fetchAddonFile*(projectId: int, fileId: int): Future[CfAddonFile] {.async.} =
162162
## get the addon file with the given `fileId` & `projectId`.
163163
withCachedAddonFile(addonFile, fileId):
164-
return addonFile.addonFileFromForgeSvc
164+
return addonFile
165165

166166
let data = await cfapi.fetchAddonFile(projectId, fileId)
167167
cfcache.putAddonFile(data)
168-
return data.addonFileFromForgeSvc
168+
return data

src/api/cfcore.nim

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,20 @@ converter addonFilesFromForgeSvc*(json: JsonNode): seq[CfAddonFile] =
6262
## creates addon files from json retrieved by an forgesvc endpoint
6363
return json.getElems().map(addonFileFromForgeSvc)
6464

65+
converter toJson*(file: CfAddonFile): JsonNode =
66+
## creates json from an addon file
67+
result = %* {
68+
"id": file.fileId,
69+
"displayName": file.name,
70+
"releaseType": file.releaseType.ord,
71+
"downloadUrl": file.downloadUrl,
72+
"gameVersions": file.gameVersions.map((x) => $x),
73+
"dependencies": file.dependencies.map((x) => %* {
74+
"relationType": RequiredDependencyType,
75+
"modId": x
76+
})
77+
}
78+
6579
converter addonFromForgeSvc*(json: JsonNode): CfAddon =
6680
## creates an addon from json retrieved by an forgesvc endpoint
6781
result = CfAddon()
@@ -83,6 +97,26 @@ converter addonsFromForgeSvc*(json: JsonNode): seq[CfAddon] =
8397
## creates addons from json retrieved by an forgesvc endpoint
8498
result = json.getElems().map(addonFromForgeSvc)
8599

100+
converter toJson*(addon: CfAddon): JsonNode =
101+
result = %* {
102+
"id": addon.projectId,
103+
"name": addon.name,
104+
"summary": addon.description,
105+
"links": {
106+
"websiteUrl": addon.websiteUrl
107+
},
108+
"authors": addon.authors.map((x) => %* {
109+
"name": x
110+
}),
111+
"downloadCount": addon.downloads,
112+
"gamePopularityRank": addon.popularity,
113+
"latestFiles": addon.latestFiles.map((x) => x.toJson()),
114+
"latestFilesIndexes": addon.gameVersionLatestFiles.map((x) => %* {
115+
"gameVersion": x.version.`$`,
116+
"fileId": x.fileId
117+
})
118+
}
119+
86120
proc isFabricCompatible*(file: CfAddonFile): bool =
87121
## returns true if `file` is compatible with the fabric loader.
88122
if "Fabric".Version in file.gameVersions:

src/nim.cfg

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
-d:ssl

src/pax.nim

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import std/os
22
import therapist
3-
import api/cfcache
43
import cmd/[add, cache, expo, impo, init, list, pin, remove, update, upgrade, version]
54
import term/[color, prompt]
65
import util/paxVersion
@@ -212,7 +211,7 @@ let spec = (
212211
)
213212

214213
spec.parseOrHelp()
215-
createDir(cfcache.cacheDir)
214+
createDir(getCacheDir("pax"))
216215

217216
# GLOBAL OPTIONS
218217
if commonArgs.yes.seen:

0 commit comments

Comments
 (0)