Updated return data for public endpoint & added bulk admin endpoint
This commit is contained in:
parent
5ef33a9f49
commit
6a0dcce2bd
87
packages/admin/uploading-charts.md
Normal file
87
packages/admin/uploading-charts.md
Normal file
@ -0,0 +1,87 @@
|
||||
# Process for Uploading Charts
|
||||
|
||||
1. Find a bms bundle/zip ie. `p_stands_for_party_newbga_ogg.zip`
|
||||
2. Upload zip to BackBlaze B2 storage bucket
|
||||
3. Open the admin dashboard for bms-repository
|
||||
4. Unzip the bms bundle/zip on your local machine
|
||||
5. For each bms file in the unzipped folder:
|
||||
1. Copy the zip friendly url from BackBlaze B2
|
||||
2. Create a new chart in the admin dashboard
|
||||
3. Paste the zip friendly url into the `resourceUri` field
|
||||
4. Set the `md5` and `sha256` fields to the md5 and sha256 of the bms file
|
||||
5. Set the `name` field to the name of the chart + difficulty
|
||||
- ie. `"P" stands for "Party!" [Another]`
|
||||
|
||||
## Script for generating chart JSON
|
||||
Run in the freshly unzipped folder
|
||||
|
||||
```shell
|
||||
#!/bin/bash
|
||||
|
||||
FILES=($(find . -name "*.bm*"));
|
||||
|
||||
|
||||
JSON="["
|
||||
for CHART in "${FILES[@]}"
|
||||
do
|
||||
MD5=$(md5sum "$CHART" | cut -d ' ' -f 1)
|
||||
SHA256=$(sha256sum "$CHART" | cut -d ' ' -f 1)
|
||||
TITLE=$(cat "$CHART" | grep "#TITLE" | sed -e s/^.*\#TITLE// | xargs | tr -d '\r')
|
||||
UUID=$(uuidgen)
|
||||
|
||||
JSON+=$(jq -n \
|
||||
--arg chartId "$UUID" \
|
||||
--arg md5 "$MD5" \
|
||||
--arg sha256 "$SHA256" \
|
||||
--arg name "$TITLE" \
|
||||
--arg resourceUri "$1" \
|
||||
'. += $ARGS.named')
|
||||
done
|
||||
|
||||
echo "$JSON]" | sed -e s/\}\{/},{/g | jq # Lazy, couldn't get JQ append working lol
|
||||
```
|
||||
|
||||
First argument is the upload url
|
||||
```shell
|
||||
./export.sh https://example.com/zips/myzip.zip
|
||||
```
|
||||
|
||||
While authenticated as an admin user, hit the `bulk` endpoint with the generated JSON after confirming that it is valid.
|
||||
|
||||
|
||||
```shell
|
||||
curl --request POST \
|
||||
--url https://<API_URL>/chart/admin/bulk \
|
||||
--header 'Authorization: Bearer Token' \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data '[
|
||||
{
|
||||
"chartId": "9923c511-355c-4ed8-9551-4b31fec45560",
|
||||
"md5": "8d80d1732fa4c81dcbd4ddfd1673d949",
|
||||
"sha256": "b796cdef4fa8865035d282be275cbda878203359c8ba630ac9ba619b52322346",
|
||||
"name": "P stands for Party! [Hyper]",
|
||||
"resourceUri": "https://f002.backblazeb2.com/file/bms-chart-storage-staging/p_stands_for_party_newbga_ogg.zip"
|
||||
},
|
||||
{
|
||||
"chartId": "4684b205-d1d9-4bcc-ace3-47e044988ff0",
|
||||
"md5": "b81eea46f8600fabab3e3f6bce2a2cc7",
|
||||
"sha256": "806c56cbb413d390c84a8d49b9888fecaac4571d5a2337b450ec23f28b10c725",
|
||||
"name": "P stands for Party! [Another]",
|
||||
"resourceUri": "https://f002.backblazeb2.com/file/bms-chart-storage-staging/p_stands_for_party_newbga_ogg.zip"
|
||||
},
|
||||
{
|
||||
"chartId": "ce9af400-4726-49ed-9ee2-13652bd98410",
|
||||
"md5": "b963e1f212e3783cfd566b59b5cb472d",
|
||||
"sha256": "17588424eea6479ed90dec7d7ffa1991bc049fd4c2ea218a1408f8febed64121",
|
||||
"name": "P stands for Party! [Beginner]",
|
||||
"resourceUri": "https://f002.backblazeb2.com/file/bms-chart-storage-staging/p_stands_for_party_newbga_ogg.zip"
|
||||
},
|
||||
{
|
||||
"chartId": "9834898f-c0ba-4a4f-a0b9-ac701e8a6f3a",
|
||||
"md5": "c6c5e5e20b53983ba59252ddcc205b5b",
|
||||
"sha256": "a60bdb0e6d2cd9d54c53decc33932b2eee7cd15966e0dd0666c368ff58070a3a",
|
||||
"name": "P stands for Party! [Normal]",
|
||||
"resourceUri": "https://f002.backblazeb2.com/file/bms-chart-storage-staging/p_stands_for_party_newbga_ogg.zip"
|
||||
}
|
||||
]'
|
||||
```
|
@ -35,6 +35,32 @@ app.post('/chart/admin', [
|
||||
},
|
||||
]);
|
||||
|
||||
app.post('/chart/admin/bulk', [
|
||||
isAdmin,
|
||||
async (req: RequestContext, res: Response) => {
|
||||
try {
|
||||
const chartData = (req.body as Chart[]).map((chart) => ({
|
||||
md5: chart.md5,
|
||||
sha256: chart.sha256,
|
||||
resourceUri: chart.resourceUri,
|
||||
parentChart: chart.parentChart,
|
||||
name: chart.name,
|
||||
comment: chart.comment,
|
||||
}));
|
||||
|
||||
const charts = await Promise.all(
|
||||
chartData.map((chart) => chartService.create(chart)),
|
||||
);
|
||||
|
||||
res.json(charts.map(chartMapper));
|
||||
} catch (error) {
|
||||
const message = getErrorMessage(error);
|
||||
console.error(`Failed to create chart ${message}`);
|
||||
res.status(400).json({ error: 'Failed to create chart' });
|
||||
}
|
||||
},
|
||||
]);
|
||||
|
||||
app.patch('/chart/admin', [
|
||||
isAdmin,
|
||||
async (req: RequestContext, res: Response) => {
|
||||
|
@ -4,7 +4,7 @@ import { RequestContext } from '../../util/request-context.type';
|
||||
import { Response } from 'express';
|
||||
import { getErrorMessage } from '../../util/error-message';
|
||||
import { getChartsByMd5, getChartsBySha256 } from './chart.service';
|
||||
import { flatten, keyBy } from 'lodash-es';
|
||||
import { flatten, uniqBy } from 'lodash-es';
|
||||
|
||||
const app = createApp();
|
||||
export const handler = createAuthenticatedHandler(app);
|
||||
@ -17,22 +17,30 @@ app.post('/chart/public', [
|
||||
sha256: string[];
|
||||
};
|
||||
|
||||
/** @TODO Ask herman how to batch query */
|
||||
const md5Charts = flatten(
|
||||
await Promise.all(md5.map((md5) => getChartsByMd5(md5))),
|
||||
);
|
||||
const md5ChartsKeyedByMd5 = keyBy(md5Charts, 'md5');
|
||||
|
||||
console.log(md5Charts);
|
||||
const md5ChartsFound = md5Charts.map((chart) => chart.md5);
|
||||
const md5ChartsNotFound = md5.filter(
|
||||
(md5) => !md5ChartsFound.includes(md5),
|
||||
);
|
||||
|
||||
const sha256Charts = flatten(
|
||||
await Promise.all(sha256.map((sha256) => getChartsBySha256(sha256))),
|
||||
);
|
||||
const sha256ChartsKeyedBySha256 = keyBy(sha256Charts, 'sha256');
|
||||
const sha256ChartsFound = sha256Charts.map((chart) => chart.sha256);
|
||||
const sha256ChartsNotFound = sha256.filter(
|
||||
(sha256) => !sha256ChartsFound.includes(sha256),
|
||||
);
|
||||
|
||||
res.json({
|
||||
md5: md5ChartsKeyedByMd5,
|
||||
sha256: sha256ChartsKeyedBySha256,
|
||||
resources: uniqBy([...md5Charts, ...sha256Charts], 'resourceUri').map(
|
||||
(chart) => chart.resourceUri,
|
||||
),
|
||||
metadata: {
|
||||
success: [...md5ChartsFound, ...sha256ChartsFound],
|
||||
failure: [...md5ChartsNotFound, ...sha256ChartsNotFound],
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
const message = getErrorMessage(error);
|
||||
|
Loading…
Reference in New Issue
Block a user