Compare commits
10 Commits
509d8945aa
...
7e5888e7e5
Author | SHA1 | Date | |
---|---|---|---|
7e5888e7e5 | |||
![]() |
fae080ea87 | ||
![]() |
de31838195 | ||
![]() |
1e32cb8688 | ||
![]() |
d420bec782 | ||
![]() |
2a4d927a41 | ||
![]() |
b21deaee5f | ||
![]() |
7493724cd7 | ||
![]() |
4d9991ce75 | ||
![]() |
5fc1cea49d |
@ -55,7 +55,7 @@ jobs:
|
|||||||
org.opencontainers.image.version=${{ env.EW_VERSION }}
|
org.opencontainers.image.version=${{ env.EW_VERSION }}
|
||||||
tags: "${{ steps.set-tag.outputs.tags }}"
|
tags: "${{ steps.set-tag.outputs.tags }}"
|
||||||
file: "docker/Dockerfile"
|
file: "docker/Dockerfile"
|
||||||
platforms: linux/amd64
|
platforms: linux/amd64 #,linux/arm64
|
||||||
|
|
||||||
# arm64 builds OOM without the git fetch setting. c.f.
|
# arm64 builds OOM without the git fetch setting. c.f.
|
||||||
# https://github.com/rust-lang/cargo/issues/10583
|
# https://github.com/rust-lang/cargo/issues/10583
|
||||||
|
56
.forgejo/workflows/release.yml
Normal file
56
.forgejo/workflows/release.yml
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
name: Build release binaries
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags: 'v*'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checking out branch
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Install Rust
|
||||||
|
shell: bash
|
||||||
|
run: curl -sSf https://sh.rustup.rs | sh -s -- -y --no-modify-path --default-toolchain stable --profile minimal
|
||||||
|
|
||||||
|
- name: Set up Node.js
|
||||||
|
uses: actions/setup-node@v2
|
||||||
|
with:
|
||||||
|
node-version: '18'
|
||||||
|
|
||||||
|
- name: Create out directory
|
||||||
|
run: |
|
||||||
|
mkdir out
|
||||||
|
|
||||||
|
- name: Build webui
|
||||||
|
run: |
|
||||||
|
cd webui
|
||||||
|
npm install
|
||||||
|
npm run build
|
||||||
|
|
||||||
|
- name: Build x86_64-unknown-linux-gnu
|
||||||
|
run: |
|
||||||
|
. "$HOME/.cargo/env"
|
||||||
|
cargo build --target x86_64-unknown-linux-gnu --release || echo "Failed to build"
|
||||||
|
mv target/x86_64-unknown-linux-gnu/release/ew out/ew-x86_64-unknown-linux-gnu
|
||||||
|
|
||||||
|
- name: Build x86_64-pc-windows-gnu
|
||||||
|
run: |
|
||||||
|
. "$HOME/.cargo/env"
|
||||||
|
sudo apt update && sudo apt install gcc-mingw-w64 -y
|
||||||
|
rustup target add x86_64-pc-windows-gnu
|
||||||
|
cargo build --target x86_64-pc-windows-gnu --release || echo "Failed to build"
|
||||||
|
mv target/x86_64-pc-windows-gnu/release/ew.exe out/ew-x86_64-pc-windows-gnu.exe
|
||||||
|
|
||||||
|
- name: Publish release
|
||||||
|
uses: actions/forgejo-release@v2
|
||||||
|
with:
|
||||||
|
direction: upload
|
||||||
|
release-dir: ./out/
|
||||||
|
release-notes-assistant: true
|
||||||
|
tag: "${{ github.ref_name }}"
|
||||||
|
sha: "${{ github.sha }}"
|
||||||
|
title: "Release ${{ github.ref_name }}"
|
||||||
|
token: ${{ github.token }}
|
6
.gitignore
vendored
6
.gitignore
vendored
@ -1,5 +1,5 @@
|
|||||||
asset_server/node_modules/
|
data/
|
||||||
asset_server/resources/
|
asset/
|
||||||
target/
|
target/
|
||||||
python/
|
python/
|
||||||
*.db
|
*.db
|
||||||
@ -7,3 +7,5 @@ webui/node_modules/
|
|||||||
webui/dist/
|
webui/dist/
|
||||||
config.json
|
config.json
|
||||||
docker/data/
|
docker/data/
|
||||||
|
.idea
|
||||||
|
*.lock
|
2482
Cargo.lock
generated
2482
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
17
Cargo.toml
17
Cargo.toml
@ -4,12 +4,12 @@ version = "1.0.0"
|
|||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
actix-web = { version = "4.9.0", features = [ "openssl" ] }
|
actix-web = { version = "4.9.0" }
|
||||||
rusqlite = { version = "0.30.0", features = ["bundled"] }
|
rusqlite = { version = "0.32.1", features = ["bundled"] }
|
||||||
openssl = { version = "0.10", features = ["vendored"] }
|
openssl = { version = "0.10", features = ["vendored"] }
|
||||||
reqwest = { version = "0.11", features = ["blocking"] }
|
reqwest = { version = "0.12", features = ["blocking"] }
|
||||||
clap = { version = "4.5.20", features = ["derive"]}
|
clap = { version = "4.5.21", features = ["derive"]}
|
||||||
base64 = "0.21.7"
|
base64 = "0.22.1"
|
||||||
json = "0.12.4"
|
json = "0.12.4"
|
||||||
rand = "0.8.5"
|
rand = "0.8.5"
|
||||||
lazy_static = "1.5.0"
|
lazy_static = "1.5.0"
|
||||||
@ -26,5 +26,8 @@ mime = "0.3.17"
|
|||||||
sha2 = "0.10.8"
|
sha2 = "0.10.8"
|
||||||
include-flate-codegen = "0.3.0"
|
include-flate-codegen = "0.3.0"
|
||||||
libflate = "2.1.0"
|
libflate = "2.1.0"
|
||||||
serde_json = "1.0.129"
|
serde_json = "1.0.133"
|
||||||
serde = { version = "1.0.210", features = ["derive"] }
|
serde = { version = "1.0.215", features = ["derive"] }
|
||||||
|
futures = "0.3.31"
|
||||||
|
mime_guess = "2.0.5"
|
||||||
|
actix-files = "0.6.6"
|
||||||
|
@ -1,4 +1,10 @@
|
|||||||
FROM docker.io/library/debian:latest as builder
|
# 打包命令
|
||||||
|
# docker buildx build -t lovelive_sif2:1.0.0 --platform=linux/amd64 .
|
||||||
|
# 使用适用于 Linux x86 的基础映像
|
||||||
|
# 保存镜像
|
||||||
|
# docker save -o lovelive_sif2.tar lovelive_sif2:1.0.0
|
||||||
|
|
||||||
|
FROM docker.io/library/debian:latest AS builder
|
||||||
|
|
||||||
# First - build
|
# First - build
|
||||||
|
|
||||||
@ -11,6 +17,14 @@ WORKDIR /ew/
|
|||||||
|
|
||||||
COPY ./ ./
|
COPY ./ ./
|
||||||
|
|
||||||
|
RUN rm -f ./*.db
|
||||||
|
RUN rm -f ./*.lock
|
||||||
|
RUN rm -rf ./.idea
|
||||||
|
RUN rm -rf ./target
|
||||||
|
RUN rm -rf ./webui/node_modules
|
||||||
|
RUN rm -rf ./webui/dist
|
||||||
|
RUN rm -rf ./webui/*.lock
|
||||||
|
|
||||||
WORKDIR /ew/webui/
|
WORKDIR /ew/webui/
|
||||||
|
|
||||||
RUN npm i && npm run build
|
RUN npm i && npm run build
|
||||||
@ -29,4 +43,7 @@ COPY ./docker/start.sh /root/ew/start.sh
|
|||||||
|
|
||||||
RUN chmod +x /root/ew/start.sh
|
RUN chmod +x /root/ew/start.sh
|
||||||
|
|
||||||
|
EXPOSE 8080
|
||||||
|
EXPOSE 8000
|
||||||
|
|
||||||
ENTRYPOINT ["/root/ew/start.sh"]
|
ENTRYPOINT ["/root/ew/start.sh"]
|
@ -1,56 +0,0 @@
|
|||||||
const express = require('express')
|
|
||||||
const app = express()
|
|
||||||
const fs = require('fs');
|
|
||||||
var http = require('http');
|
|
||||||
|
|
||||||
const ip = '0.0.0.0';
|
|
||||||
const port = 8887;
|
|
||||||
//https://lovelive-schoolidolfestival2-album.akamaized.net
|
|
||||||
app.use(function (req, res, next) {
|
|
||||||
console.log(req.method, ":", req.url);
|
|
||||||
next();
|
|
||||||
})
|
|
||||||
function createDirFromFile(path) {
|
|
||||||
fs.mkdirSync(require('path').dirname(path), { recursive: true });
|
|
||||||
}
|
|
||||||
|
|
||||||
app.get('/*', function (req, res) {
|
|
||||||
const expectedPath = __dirname + "/resources"+req.url.split("?")[0];
|
|
||||||
createDirFromFile(expectedPath);
|
|
||||||
|
|
||||||
let downloading = [];
|
|
||||||
if (fs.existsSync(expectedPath)) {
|
|
||||||
res.sendFile(expectedPath)
|
|
||||||
} else {
|
|
||||||
let url;
|
|
||||||
if (req.url.split("/")[2].length !== 2) {
|
|
||||||
url = (req.url.toLowerCase().startsWith("/android") || req.url.toLowerCase().startsWith("/ios") ? "https://lovelive-schoolidolfestival2-assets.akamaized.net" : "https://lovelive-schoolidolfestival2-album.akamaized.net") + req.url;
|
|
||||||
} else {
|
|
||||||
url = (req.url.toLowerCase().startsWith("/android") || req.url.toLowerCase().startsWith("/ios") ? "https://img-sif2.lovelive-sif2.com" : "https://album-sif2.lovelive-sif2.com") + req.url;
|
|
||||||
}
|
|
||||||
const request = require('https').get(url, function(response) {
|
|
||||||
response.pipe(res);
|
|
||||||
});
|
|
||||||
if (downloading.includes(req.url)) return;
|
|
||||||
require('https').get(url, function(response) {
|
|
||||||
console.log("Downloading " + req.url);
|
|
||||||
downloading.push(req.url);
|
|
||||||
const file = fs.createWriteStream(expectedPath);
|
|
||||||
response.pipe(file);
|
|
||||||
|
|
||||||
// after download completed close filestream
|
|
||||||
file.on("finish", () => {
|
|
||||||
file.close();
|
|
||||||
console.log("Download Completed " + req.url);
|
|
||||||
});
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
var httpsServer = http.createServer(app);
|
|
||||||
|
|
||||||
|
|
||||||
httpsServer.listen(port, ip, () => {
|
|
||||||
let url = 'http://' + ip + ':' + port
|
|
||||||
console.log('Server is listening at', url)
|
|
||||||
})
|
|
690
asset_server/package-lock.json
generated
690
asset_server/package-lock.json
generated
@ -1,690 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "a",
|
|
||||||
"lockfileVersion": 3,
|
|
||||||
"requires": true,
|
|
||||||
"packages": {
|
|
||||||
"": {
|
|
||||||
"dependencies": {
|
|
||||||
"express": "^4.18.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/accepts": {
|
|
||||||
"version": "1.3.8",
|
|
||||||
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
|
|
||||||
"integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
|
|
||||||
"dependencies": {
|
|
||||||
"mime-types": "~2.1.34",
|
|
||||||
"negotiator": "0.6.3"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/array-flatten": {
|
|
||||||
"version": "1.1.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
|
|
||||||
"integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="
|
|
||||||
},
|
|
||||||
"node_modules/body-parser": {
|
|
||||||
"version": "1.20.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz",
|
|
||||||
"integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==",
|
|
||||||
"dependencies": {
|
|
||||||
"bytes": "3.1.2",
|
|
||||||
"content-type": "~1.0.4",
|
|
||||||
"debug": "2.6.9",
|
|
||||||
"depd": "2.0.0",
|
|
||||||
"destroy": "1.2.0",
|
|
||||||
"http-errors": "2.0.0",
|
|
||||||
"iconv-lite": "0.4.24",
|
|
||||||
"on-finished": "2.4.1",
|
|
||||||
"qs": "6.11.0",
|
|
||||||
"raw-body": "2.5.1",
|
|
||||||
"type-is": "~1.6.18",
|
|
||||||
"unpipe": "1.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.8",
|
|
||||||
"npm": "1.2.8000 || >= 1.4.16"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/bytes": {
|
|
||||||
"version": "3.1.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
|
|
||||||
"integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/call-bind": {
|
|
||||||
"version": "1.0.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz",
|
|
||||||
"integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==",
|
|
||||||
"dependencies": {
|
|
||||||
"es-define-property": "^1.0.0",
|
|
||||||
"es-errors": "^1.3.0",
|
|
||||||
"function-bind": "^1.1.2",
|
|
||||||
"get-intrinsic": "^1.2.4",
|
|
||||||
"set-function-length": "^1.2.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.4"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/ljharb"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/content-disposition": {
|
|
||||||
"version": "0.5.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
|
|
||||||
"integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
|
|
||||||
"dependencies": {
|
|
||||||
"safe-buffer": "5.2.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/content-type": {
|
|
||||||
"version": "1.0.5",
|
|
||||||
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
|
|
||||||
"integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/cookie": {
|
|
||||||
"version": "0.5.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
|
|
||||||
"integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/cookie-signature": {
|
|
||||||
"version": "1.0.6",
|
|
||||||
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
|
|
||||||
"integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="
|
|
||||||
},
|
|
||||||
"node_modules/debug": {
|
|
||||||
"version": "2.6.9",
|
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
|
||||||
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
|
||||||
"dependencies": {
|
|
||||||
"ms": "2.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/define-data-property": {
|
|
||||||
"version": "1.1.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
|
|
||||||
"integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
|
|
||||||
"dependencies": {
|
|
||||||
"es-define-property": "^1.0.0",
|
|
||||||
"es-errors": "^1.3.0",
|
|
||||||
"gopd": "^1.0.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.4"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/ljharb"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/depd": {
|
|
||||||
"version": "2.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
|
|
||||||
"integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/destroy": {
|
|
||||||
"version": "1.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
|
|
||||||
"integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.8",
|
|
||||||
"npm": "1.2.8000 || >= 1.4.16"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/ee-first": {
|
|
||||||
"version": "1.1.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
|
|
||||||
"integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
|
|
||||||
},
|
|
||||||
"node_modules/encodeurl": {
|
|
||||||
"version": "1.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
|
|
||||||
"integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/es-define-property": {
|
|
||||||
"version": "1.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz",
|
|
||||||
"integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==",
|
|
||||||
"dependencies": {
|
|
||||||
"get-intrinsic": "^1.2.4"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.4"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/es-errors": {
|
|
||||||
"version": "1.3.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
|
|
||||||
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.4"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/escape-html": {
|
|
||||||
"version": "1.0.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
|
|
||||||
"integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
|
|
||||||
},
|
|
||||||
"node_modules/etag": {
|
|
||||||
"version": "1.8.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
|
|
||||||
"integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/express": {
|
|
||||||
"version": "4.18.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz",
|
|
||||||
"integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==",
|
|
||||||
"dependencies": {
|
|
||||||
"accepts": "~1.3.8",
|
|
||||||
"array-flatten": "1.1.1",
|
|
||||||
"body-parser": "1.20.1",
|
|
||||||
"content-disposition": "0.5.4",
|
|
||||||
"content-type": "~1.0.4",
|
|
||||||
"cookie": "0.5.0",
|
|
||||||
"cookie-signature": "1.0.6",
|
|
||||||
"debug": "2.6.9",
|
|
||||||
"depd": "2.0.0",
|
|
||||||
"encodeurl": "~1.0.2",
|
|
||||||
"escape-html": "~1.0.3",
|
|
||||||
"etag": "~1.8.1",
|
|
||||||
"finalhandler": "1.2.0",
|
|
||||||
"fresh": "0.5.2",
|
|
||||||
"http-errors": "2.0.0",
|
|
||||||
"merge-descriptors": "1.0.1",
|
|
||||||
"methods": "~1.1.2",
|
|
||||||
"on-finished": "2.4.1",
|
|
||||||
"parseurl": "~1.3.3",
|
|
||||||
"path-to-regexp": "0.1.7",
|
|
||||||
"proxy-addr": "~2.0.7",
|
|
||||||
"qs": "6.11.0",
|
|
||||||
"range-parser": "~1.2.1",
|
|
||||||
"safe-buffer": "5.2.1",
|
|
||||||
"send": "0.18.0",
|
|
||||||
"serve-static": "1.15.0",
|
|
||||||
"setprototypeof": "1.2.0",
|
|
||||||
"statuses": "2.0.1",
|
|
||||||
"type-is": "~1.6.18",
|
|
||||||
"utils-merge": "1.0.1",
|
|
||||||
"vary": "~1.1.2"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.10.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/finalhandler": {
|
|
||||||
"version": "1.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz",
|
|
||||||
"integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==",
|
|
||||||
"dependencies": {
|
|
||||||
"debug": "2.6.9",
|
|
||||||
"encodeurl": "~1.0.2",
|
|
||||||
"escape-html": "~1.0.3",
|
|
||||||
"on-finished": "2.4.1",
|
|
||||||
"parseurl": "~1.3.3",
|
|
||||||
"statuses": "2.0.1",
|
|
||||||
"unpipe": "~1.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/forwarded": {
|
|
||||||
"version": "0.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
|
|
||||||
"integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/fresh": {
|
|
||||||
"version": "0.5.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
|
|
||||||
"integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/function-bind": {
|
|
||||||
"version": "1.1.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
|
|
||||||
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/ljharb"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/get-intrinsic": {
|
|
||||||
"version": "1.2.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
|
|
||||||
"integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
|
|
||||||
"dependencies": {
|
|
||||||
"es-errors": "^1.3.0",
|
|
||||||
"function-bind": "^1.1.2",
|
|
||||||
"has-proto": "^1.0.1",
|
|
||||||
"has-symbols": "^1.0.3",
|
|
||||||
"hasown": "^2.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.4"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/ljharb"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/gopd": {
|
|
||||||
"version": "1.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
|
|
||||||
"integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==",
|
|
||||||
"dependencies": {
|
|
||||||
"get-intrinsic": "^1.1.3"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/ljharb"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/has-property-descriptors": {
|
|
||||||
"version": "1.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
|
|
||||||
"integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
|
|
||||||
"dependencies": {
|
|
||||||
"es-define-property": "^1.0.0"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/ljharb"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/has-proto": {
|
|
||||||
"version": "1.0.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz",
|
|
||||||
"integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.4"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/ljharb"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/has-symbols": {
|
|
||||||
"version": "1.0.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
|
|
||||||
"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.4"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/ljharb"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/hasown": {
|
|
||||||
"version": "2.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.1.tgz",
|
|
||||||
"integrity": "sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==",
|
|
||||||
"dependencies": {
|
|
||||||
"function-bind": "^1.1.2"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.4"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/http-errors": {
|
|
||||||
"version": "2.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
|
|
||||||
"integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
|
|
||||||
"dependencies": {
|
|
||||||
"depd": "2.0.0",
|
|
||||||
"inherits": "2.0.4",
|
|
||||||
"setprototypeof": "1.2.0",
|
|
||||||
"statuses": "2.0.1",
|
|
||||||
"toidentifier": "1.0.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/iconv-lite": {
|
|
||||||
"version": "0.4.24",
|
|
||||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
|
|
||||||
"integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
|
|
||||||
"dependencies": {
|
|
||||||
"safer-buffer": ">= 2.1.2 < 3"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.10.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/inherits": {
|
|
||||||
"version": "2.0.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
|
||||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
|
||||||
},
|
|
||||||
"node_modules/ipaddr.js": {
|
|
||||||
"version": "1.9.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
|
|
||||||
"integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/media-typer": {
|
|
||||||
"version": "0.3.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
|
|
||||||
"integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/merge-descriptors": {
|
|
||||||
"version": "1.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
|
|
||||||
"integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w=="
|
|
||||||
},
|
|
||||||
"node_modules/methods": {
|
|
||||||
"version": "1.1.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
|
|
||||||
"integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/mime": {
|
|
||||||
"version": "1.6.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
|
|
||||||
"integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
|
|
||||||
"bin": {
|
|
||||||
"mime": "cli.js"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=4"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/mime-db": {
|
|
||||||
"version": "1.52.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
|
|
||||||
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/mime-types": {
|
|
||||||
"version": "2.1.35",
|
|
||||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
|
|
||||||
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
|
|
||||||
"dependencies": {
|
|
||||||
"mime-db": "1.52.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/ms": {
|
|
||||||
"version": "2.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
|
||||||
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
|
|
||||||
},
|
|
||||||
"node_modules/negotiator": {
|
|
||||||
"version": "0.6.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
|
|
||||||
"integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/object-inspect": {
|
|
||||||
"version": "1.13.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz",
|
|
||||||
"integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==",
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/ljharb"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/on-finished": {
|
|
||||||
"version": "2.4.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
|
|
||||||
"integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
|
|
||||||
"dependencies": {
|
|
||||||
"ee-first": "1.1.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/parseurl": {
|
|
||||||
"version": "1.3.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
|
|
||||||
"integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/path-to-regexp": {
|
|
||||||
"version": "0.1.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
|
|
||||||
"integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ=="
|
|
||||||
},
|
|
||||||
"node_modules/proxy-addr": {
|
|
||||||
"version": "2.0.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
|
|
||||||
"integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
|
|
||||||
"dependencies": {
|
|
||||||
"forwarded": "0.2.0",
|
|
||||||
"ipaddr.js": "1.9.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/qs": {
|
|
||||||
"version": "6.11.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
|
|
||||||
"integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==",
|
|
||||||
"dependencies": {
|
|
||||||
"side-channel": "^1.0.4"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.6"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/ljharb"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/range-parser": {
|
|
||||||
"version": "1.2.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
|
|
||||||
"integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/raw-body": {
|
|
||||||
"version": "2.5.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz",
|
|
||||||
"integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==",
|
|
||||||
"dependencies": {
|
|
||||||
"bytes": "3.1.2",
|
|
||||||
"http-errors": "2.0.0",
|
|
||||||
"iconv-lite": "0.4.24",
|
|
||||||
"unpipe": "1.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/safe-buffer": {
|
|
||||||
"version": "5.2.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
|
||||||
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
|
|
||||||
"funding": [
|
|
||||||
{
|
|
||||||
"type": "github",
|
|
||||||
"url": "https://github.com/sponsors/feross"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "patreon",
|
|
||||||
"url": "https://www.patreon.com/feross"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "consulting",
|
|
||||||
"url": "https://feross.org/support"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"node_modules/safer-buffer": {
|
|
||||||
"version": "2.1.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
|
||||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
|
|
||||||
},
|
|
||||||
"node_modules/send": {
|
|
||||||
"version": "0.18.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz",
|
|
||||||
"integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==",
|
|
||||||
"dependencies": {
|
|
||||||
"debug": "2.6.9",
|
|
||||||
"depd": "2.0.0",
|
|
||||||
"destroy": "1.2.0",
|
|
||||||
"encodeurl": "~1.0.2",
|
|
||||||
"escape-html": "~1.0.3",
|
|
||||||
"etag": "~1.8.1",
|
|
||||||
"fresh": "0.5.2",
|
|
||||||
"http-errors": "2.0.0",
|
|
||||||
"mime": "1.6.0",
|
|
||||||
"ms": "2.1.3",
|
|
||||||
"on-finished": "2.4.1",
|
|
||||||
"range-parser": "~1.2.1",
|
|
||||||
"statuses": "2.0.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.8.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/send/node_modules/ms": {
|
|
||||||
"version": "2.1.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
|
||||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
|
|
||||||
},
|
|
||||||
"node_modules/serve-static": {
|
|
||||||
"version": "1.15.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz",
|
|
||||||
"integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==",
|
|
||||||
"dependencies": {
|
|
||||||
"encodeurl": "~1.0.2",
|
|
||||||
"escape-html": "~1.0.3",
|
|
||||||
"parseurl": "~1.3.3",
|
|
||||||
"send": "0.18.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.8.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/set-function-length": {
|
|
||||||
"version": "1.2.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.1.tgz",
|
|
||||||
"integrity": "sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g==",
|
|
||||||
"dependencies": {
|
|
||||||
"define-data-property": "^1.1.2",
|
|
||||||
"es-errors": "^1.3.0",
|
|
||||||
"function-bind": "^1.1.2",
|
|
||||||
"get-intrinsic": "^1.2.3",
|
|
||||||
"gopd": "^1.0.1",
|
|
||||||
"has-property-descriptors": "^1.0.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.4"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/setprototypeof": {
|
|
||||||
"version": "1.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
|
|
||||||
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
|
|
||||||
},
|
|
||||||
"node_modules/side-channel": {
|
|
||||||
"version": "1.0.5",
|
|
||||||
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.5.tgz",
|
|
||||||
"integrity": "sha512-QcgiIWV4WV7qWExbN5llt6frQB/lBven9pqliLXfGPB+K9ZYXxDozp0wLkHS24kWCm+6YXH/f0HhnObZnZOBnQ==",
|
|
||||||
"dependencies": {
|
|
||||||
"call-bind": "^1.0.6",
|
|
||||||
"es-errors": "^1.3.0",
|
|
||||||
"get-intrinsic": "^1.2.4",
|
|
||||||
"object-inspect": "^1.13.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.4"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/ljharb"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/statuses": {
|
|
||||||
"version": "2.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
|
|
||||||
"integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/toidentifier": {
|
|
||||||
"version": "1.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
|
|
||||||
"integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/type-is": {
|
|
||||||
"version": "1.6.18",
|
|
||||||
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
|
|
||||||
"integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
|
|
||||||
"dependencies": {
|
|
||||||
"media-typer": "0.3.0",
|
|
||||||
"mime-types": "~2.1.24"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/unpipe": {
|
|
||||||
"version": "1.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
|
|
||||||
"integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/utils-merge": {
|
|
||||||
"version": "1.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
|
|
||||||
"integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.4.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/vary": {
|
|
||||||
"version": "1.1.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
|
||||||
"integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.8"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,5 +0,0 @@
|
|||||||
{
|
|
||||||
"dependencies": {
|
|
||||||
"express": "^4.18.2"
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,15 +1,16 @@
|
|||||||
version: '3'
|
version: '3'
|
||||||
services:
|
services:
|
||||||
sif2-ew:
|
lovelive_sif2:
|
||||||
image: sif2-ew:latest
|
image: lovelive_sif2:latest
|
||||||
container_name: sif2-ew
|
container_name: lovelive_sif2
|
||||||
build:
|
|
||||||
dockerfile: "./Dockerfile"
|
|
||||||
environment:
|
environment:
|
||||||
PORT: 8080
|
PORT: 8080
|
||||||
|
ASSET_PORT: 8000
|
||||||
DIRECTORY: /data/
|
DIRECTORY: /data/
|
||||||
|
ASSET_DIRECTORY: /assets/
|
||||||
HTTPS: false
|
HTTPS: false
|
||||||
NPPS4_ADDRESS: "http://127.0.0.1:51376"
|
ENABLE_ASSET_SERVER: false
|
||||||
|
#NPPS4_ADDRESS: "http://127.0.0.1:51376"
|
||||||
MAXTIME: 1717045200 # A day before global EOS
|
MAXTIME: 1717045200 # A day before global EOS
|
||||||
HIDDEN: false # Will disable the webui
|
HIDDEN: false # Will disable the webui
|
||||||
DISABLE_IMPORTS: false # Will disable account imports
|
DISABLE_IMPORTS: false # Will disable account imports
|
||||||
@ -22,7 +23,12 @@ services:
|
|||||||
#IOS_JAPAN: "link.to/ios/japan.ipa"
|
#IOS_JAPAN: "link.to/ios/japan.ipa"
|
||||||
#ASSET_URL: "link.to/client/assets/"
|
#ASSET_URL: "link.to/client/assets/"
|
||||||
ports:
|
ports:
|
||||||
- 8080:8080
|
- "8080:8080"
|
||||||
|
- "8000:8000"
|
||||||
volumes:
|
volumes:
|
||||||
|
# 只修改左侧本地路径
|
||||||
|
# 数据库存放路径(建议添加)
|
||||||
- ./data:/data
|
- ./data:/data
|
||||||
|
# 资源文件存放路径(搭建asset server需要指定本地资源路径)
|
||||||
|
- ./assets:/assets
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
@ -1,8 +1,15 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
port="${PORT:-8080}"
|
port="${PORT:-8080}"
|
||||||
|
|
||||||
directory="${DIRECTORY:-/data/}"
|
directory="${DIRECTORY:-/data/}"
|
||||||
|
|
||||||
|
enable_asset_server=$([ "$ENABLE_ASSET_SERVER" = "true" ] && echo "--enable_asset_server" || echo "")
|
||||||
|
|
||||||
|
asset_port="${ASSET_PORT:-8000}"
|
||||||
|
|
||||||
|
assets_directory="${ASSET_DIRECTORY:-/assets/}"
|
||||||
|
|
||||||
npps4="${NPPS4_ADDRESS:-http://127.0.0.1:51376}"
|
npps4="${NPPS4_ADDRESS:-http://127.0.0.1:51376}"
|
||||||
|
|
||||||
https=$([ "$HTTPS" = "true" ] && echo "--https" || echo "")
|
https=$([ "$HTTPS" = "true" ] && echo "--https" || echo "")
|
||||||
@ -25,4 +32,25 @@ asset_android_en=$([ "$EN_ANDROID_ASSET_HASH" != "" ] && echo "--en-android-asse
|
|||||||
|
|
||||||
asset_ios_en=$([ "$EN_IOS_ASSET_HASH" != "" ] && echo "--en-ios-asset-hash $EN_IOS_ASSET_HASH" || echo "")
|
asset_ios_en=$([ "$EN_IOS_ASSET_HASH" != "" ] && echo "--en-ios-asset-hash $EN_IOS_ASSET_HASH" || echo "")
|
||||||
|
|
||||||
/root/ew/ew --path $directory --port $port --npps4 $npps4 $asset_android_jp $asset_ios_jp $asset_android_en $asset_ios_en $exports $imports $purge $hidden $https --global-android "$ANDROID_GLOBAL" --japan-android "$ANDROID_JAPAN" --global-ios "$IOS_GLOBAL" --japan-ios "$IOS_JAPAN" --assets-url "$ASSET_URL" --max-time $maxTime
|
/root/ew/ew \
|
||||||
|
--path "$directory" \
|
||||||
|
--port "$port" \
|
||||||
|
"$enable_asset_server" \
|
||||||
|
--asset_path "$assets_directory" \
|
||||||
|
--asset_port "$asset_port" \
|
||||||
|
--npps4 "$npps4" \
|
||||||
|
"$asset_android_jp" \
|
||||||
|
"$asset_ios_jp" \
|
||||||
|
"$asset_android_en" \
|
||||||
|
"$asset_ios_en" \
|
||||||
|
"$exports" \
|
||||||
|
"$imports" \
|
||||||
|
"$purge" \
|
||||||
|
"$hidden" \
|
||||||
|
"$https" \
|
||||||
|
--global-android "$ANDROID_GLOBAL" \
|
||||||
|
--japan-android "$ANDROID_JAPAN" \
|
||||||
|
--global-ios "$IOS_GLOBAL" \
|
||||||
|
--japan-ios "$IOS_JAPAN" \
|
||||||
|
--assets-url "$ASSET_URL" \
|
||||||
|
--max-time "$maxTime"
|
||||||
|
61
src/main.rs
61
src/main.rs
@ -17,6 +17,7 @@ use clap::Parser;
|
|||||||
use std::fs;
|
use std::fs;
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
use actix_web::dev::{Server, ServerHandle};
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
|
|
||||||
#[get("/index.css")]
|
#[get("/index.css")]
|
||||||
@ -38,9 +39,18 @@ pub struct Args {
|
|||||||
#[arg(short, long, default_value_t = 8080, help = "Port to listen on")]
|
#[arg(short, long, default_value_t = 8080, help = "Port to listen on")]
|
||||||
port: u16,
|
port: u16,
|
||||||
|
|
||||||
|
#[arg(short, long, default_value_t = 8000, help = "Assets port to listen on")]
|
||||||
|
asset_port: u16,
|
||||||
|
|
||||||
#[arg(long, default_value = "./", help = "Path to store database files")]
|
#[arg(long, default_value = "./", help = "Path to store database files")]
|
||||||
path: String,
|
path: String,
|
||||||
|
|
||||||
|
#[arg(long, default_value = "./asset/", help = "Path to store database files")]
|
||||||
|
asset_path: String,
|
||||||
|
|
||||||
|
#[arg(long, default_value_t = false, help = "Enable assets server")]
|
||||||
|
enable_asset_server: bool,
|
||||||
|
|
||||||
#[arg(long, default_value_t = false, help = "Serve gree headers with https. WILL NOT ACCEPT HTTPS REQUESTS")]
|
#[arg(long, default_value_t = false, help = "Serve gree headers with https. WILL NOT ACCEPT HTTPS REQUESTS")]
|
||||||
https: bool,
|
https: bool,
|
||||||
|
|
||||||
@ -96,6 +106,8 @@ pub struct Args {
|
|||||||
async fn run_server(in_thread: bool) -> std::io::Result<()> {
|
async fn run_server(in_thread: bool) -> std::io::Result<()> {
|
||||||
let args = get_args();
|
let args = get_args();
|
||||||
let port = args.port;
|
let port = args.port;
|
||||||
|
let enable_asset_server = args.enable_asset_server;
|
||||||
|
let asset_port = args.asset_port;
|
||||||
|
|
||||||
if args.purge {
|
if args.purge {
|
||||||
println!("Purging accounts...");
|
println!("Purging accounts...");
|
||||||
@ -103,9 +115,9 @@ async fn run_server(in_thread: bool) -> std::io::Result<()> {
|
|||||||
println!("Purged {} accounts", ct);
|
println!("Purged {} accounts", ct);
|
||||||
}
|
}
|
||||||
|
|
||||||
let rv = HttpServer::new(|| App::new()
|
let webui_server = HttpServer::new(|| App::new()
|
||||||
.wrap_fn(|req, srv| {
|
.wrap_fn(|req, srv| {
|
||||||
println!("Request: {}", req.path());
|
println!("WebUI Request: {}", req.path());
|
||||||
srv.call(req)
|
srv.call(req)
|
||||||
})
|
})
|
||||||
.app_data(web::PayloadConfig::default().limit(1024 * 1024 * 25))
|
.app_data(web::PayloadConfig::default().limit(1024 * 1024 * 25))
|
||||||
@ -114,26 +126,56 @@ async fn run_server(in_thread: bool) -> std::io::Result<()> {
|
|||||||
.default_service(web::route().to(router::request))
|
.default_service(web::route().to(router::request))
|
||||||
).bind(("0.0.0.0", port))?.run();
|
).bind(("0.0.0.0", port))?.run();
|
||||||
|
|
||||||
println!("Server started: http://0.0.0.0:{}", port);
|
println!("WebUI Server started: http://0.0.0.0:{}", port);
|
||||||
println!("Data path is set to {}", args.path);
|
println!("Database path is set to {}", args.path);
|
||||||
println!("Sif1 transfer requests will attempt to contact NPPS4 at {}", args.npps4);
|
println!("Sif1 transfer requests will attempt to contact NPPS4 at {}", args.npps4);
|
||||||
|
|
||||||
|
let mut asset_server: Option<Server> = None;
|
||||||
|
if enable_asset_server {
|
||||||
|
asset_server = Some(HttpServer::new(|| App::new()
|
||||||
|
.wrap_fn(|req, srv| {
|
||||||
|
println!("Assets Request: {}", req.path());
|
||||||
|
srv.call(req)
|
||||||
|
})
|
||||||
|
.app_data(web::PayloadConfig::default().limit(1024 * 1024 * 1024))
|
||||||
|
.default_service(web::route().to(router::asset_request))
|
||||||
|
).bind(("0.0.0.0", asset_port))?.run());
|
||||||
|
|
||||||
|
println!("Assets Server started: http://0.0.0.0:{}", asset_port);
|
||||||
|
println!("Assets path is set to {}", args.asset_path);
|
||||||
|
}
|
||||||
|
|
||||||
if args.https {
|
if args.https {
|
||||||
println!("Note: gree is set to https mode. http requests will fail on jp clients.");
|
println!("Note: gree is set to https mode. http requests will fail on jp clients.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if in_thread {
|
if in_thread {
|
||||||
set_running(true).await;
|
set_running(true).await;
|
||||||
let handle = rv.handle();
|
let handle = webui_server.handle();
|
||||||
rt::spawn(rv);
|
rt::spawn(webui_server);
|
||||||
|
let mut handle2: Option<ServerHandle> = None;
|
||||||
|
if asset_server.is_some() {
|
||||||
|
let server = asset_server.unwrap();
|
||||||
|
handle2 = Some(server.handle());
|
||||||
|
rt::spawn(server);
|
||||||
|
}
|
||||||
|
|
||||||
while get_running().await {
|
while get_running().await {
|
||||||
actix_web::rt::time::sleep(Duration::from_millis(100)).await;
|
actix_web::rt::time::sleep(Duration::from_millis(100)).await;
|
||||||
}
|
}
|
||||||
handle.stop(false).await;
|
handle.stop(false).await;
|
||||||
|
if handle2.is_some() {
|
||||||
|
handle2.unwrap().stop(false).await;
|
||||||
|
}
|
||||||
println!("Stopped");
|
println!("Stopped");
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
rv.await
|
if asset_server.is_some() {
|
||||||
|
let _ = futures::join!(webui_server, asset_server.unwrap());
|
||||||
|
} else {
|
||||||
|
webui_server.await?
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[actix_web::main]
|
#[actix_web::main]
|
||||||
@ -153,7 +195,7 @@ pub fn get_args() -> Args {
|
|||||||
pub fn get_data_path(file_name: &str) -> String {
|
pub fn get_data_path(file_name: &str) -> String {
|
||||||
let args = get_args();
|
let args = get_args();
|
||||||
let mut path = args.path;
|
let mut path = args.path;
|
||||||
while path.ends_with("/") {
|
while path.ends_with('/') {
|
||||||
path.pop();
|
path.pop();
|
||||||
}
|
}
|
||||||
fs::create_dir_all(&path).unwrap();
|
fs::create_dir_all(&path).unwrap();
|
||||||
@ -190,6 +232,7 @@ macro_rules! lock_onto_mutex {
|
|||||||
break value;
|
break value;
|
||||||
}
|
}
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
|
$mutex.clear_poison();
|
||||||
actix_web::rt::time::sleep(std::time::Duration::from_millis(15)).await;
|
actix_web::rt::time::sleep(std::time::Duration::from_millis(15)).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -208,5 +251,5 @@ async fn set_running(running: bool) {
|
|||||||
|
|
||||||
async fn get_running() -> bool {
|
async fn get_running() -> bool {
|
||||||
let result = lock_onto_mutex!(RUNNING);
|
let result = lock_onto_mutex!(RUNNING);
|
||||||
return *result;
|
*result
|
||||||
}
|
}
|
||||||
|
@ -28,12 +28,7 @@ pub mod databases;
|
|||||||
pub mod location;
|
pub mod location;
|
||||||
pub mod event_ranking;
|
pub mod event_ranking;
|
||||||
|
|
||||||
use actix_web::{
|
use actix_web::{HttpResponse, HttpRequest, http::header::HeaderValue, http::header::HeaderMap, Responder};
|
||||||
HttpResponse,
|
|
||||||
HttpRequest,
|
|
||||||
http::header::HeaderValue,
|
|
||||||
http::header::HeaderMap
|
|
||||||
};
|
|
||||||
use json::{JsonValue, object};
|
use json::{JsonValue, object};
|
||||||
use crate::encryption;
|
use crate::encryption;
|
||||||
|
|
||||||
@ -51,7 +46,7 @@ fn not_found(headers: &HeaderMap) -> HttpResponse {
|
|||||||
"server_time": global::timestamp(),
|
"server_time": global::timestamp(),
|
||||||
"message": ""
|
"message": ""
|
||||||
};
|
};
|
||||||
return global::send(rv, 0, &headers)
|
global::send(rv, 0, headers)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn api_req(req: HttpRequest, body: String) -> HttpResponse {
|
async fn api_req(req: HttpRequest, body: String) -> HttpResponse {
|
||||||
@ -167,15 +162,19 @@ async fn api_req(req: HttpRequest, body: String) -> HttpResponse {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn asset_request(req: HttpRequest) -> impl Responder {
|
||||||
|
webui::asset(req).await
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn request(req: HttpRequest, body: String) -> HttpResponse {
|
pub async fn request(req: HttpRequest, body: String) -> HttpResponse {
|
||||||
let args = crate::get_args();
|
let args = crate::get_args();
|
||||||
let headers = req.headers();
|
let headers = req.headers();
|
||||||
if args.hidden && req.path().starts_with("/api/webui/") {
|
if args.hidden && req.path().starts_with("/api/webui/") {
|
||||||
return not_found(&headers);
|
return not_found(headers);
|
||||||
}
|
}
|
||||||
if headers.get("aoharu-asset-version").is_none() && req.path().starts_with("/api") && !req.path().starts_with("/api/webui") {
|
if headers.get("aoharu-asset-version").is_none() && req.path().starts_with("/api") && !req.path().starts_with("/api/webui") {
|
||||||
if args.hidden {
|
if args.hidden {
|
||||||
return not_found(&headers);
|
return not_found(headers);
|
||||||
} else {
|
} else {
|
||||||
return webui::main(req);
|
return webui::main(req);
|
||||||
}
|
}
|
||||||
|
@ -35,16 +35,14 @@ fn do_reinforce(user: &mut JsonValue, body: &JsonValue, exp_id: &str, money_mult
|
|||||||
data["amount"] = (data["amount"].as_i64().unwrap() - money).into();
|
data["amount"] = (data["amount"].as_i64().unwrap() - money).into();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if evolve {
|
if evolve && !databases::CHARACTER_CHATS[card["master_card_id"].to_string()]["50"].is_empty() {
|
||||||
if !databases::CHARACTER_CHATS[card["master_card_id"].to_string()]["50"].is_empty() {
|
let chat = &databases::CHARACTER_CHATS[card["master_card_id"].to_string()]["50"];
|
||||||
let chat = &databases::CHARACTER_CHATS[card["master_card_id"].to_string()]["50"];
|
let mission_id = databases::MISSION_REWARD[chat[0].to_string()]["value"].as_i64().unwrap();
|
||||||
let mission_id = databases::MISSION_REWARD[chat[0].to_string()]["value"].as_i64().unwrap();
|
|
||||||
|
|
||||||
if crate::router::chat::add_chat_from_chapter_id(mission_id, chats) {
|
if crate::router::chat::add_chat_from_chapter_id(mission_id, chats) {
|
||||||
items::update_mission_status(chat[1].as_i64().unwrap(), 0, true, true, 1, missions);
|
items::update_mission_status(chat[1].as_i64().unwrap(), 0, true, true, 1, missions);
|
||||||
if !clear_mission_ids.contains(chat[1].as_i64().unwrap()) {
|
if !clear_mission_ids.contains(chat[1].as_i64().unwrap()) {
|
||||||
clear_mission_ids.push(chat[1].clone()).unwrap();
|
clear_mission_ids.push(chat[1].clone()).unwrap();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -167,18 +167,20 @@ fn get_json() -> JsonValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn get_clearrate_json() -> JsonValue {
|
async fn get_clearrate_json() -> JsonValue {
|
||||||
let mut result = crate::lock_onto_mutex!(CACHED_DATA);
|
let cache = {
|
||||||
if result.is_none() {
|
let mut result = crate::lock_onto_mutex!(CACHED_DATA);
|
||||||
result.replace(get_json());
|
if result.is_none() {
|
||||||
}
|
result.replace(get_json());
|
||||||
let cache = result.as_ref().unwrap();
|
}
|
||||||
|
result.as_ref().unwrap().clone()
|
||||||
|
};
|
||||||
let rv = cache["cache"].clone();
|
let rv = cache["cache"].clone();
|
||||||
if cache["last_updated"].as_u64().unwrap() + (60 * 60) < global::timestamp() {
|
if cache["last_updated"].as_u64().unwrap() + (60 * 60) < global::timestamp() {
|
||||||
let mut result = crate::lock_onto_mutex!(CACHED_DATA);
|
let mut result = crate::lock_onto_mutex!(CACHED_DATA);
|
||||||
let new = get_json();
|
let new = get_json();
|
||||||
result.replace(new.clone());
|
result.replace(new.clone());
|
||||||
}
|
}
|
||||||
return rv;
|
rv
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn clearrate(_req: HttpRequest) -> Option<JsonValue> {
|
pub async fn clearrate(_req: HttpRequest) -> Option<JsonValue> {
|
||||||
|
@ -60,7 +60,7 @@ fn get_random_song() -> JsonValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn switch_music(event: &mut JsonValue, index: i32) {
|
fn switch_music(event: &mut JsonValue, index: i32) {
|
||||||
if index > 5 || index < 1 {
|
if !(1..=5).contains(&index) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,16 +98,18 @@ fn get_json() -> JsonValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_scores_json() -> JsonValue {
|
pub async fn get_scores_json() -> JsonValue {
|
||||||
let mut result = crate::lock_onto_mutex!(CACHED_DATA);
|
let cache = {
|
||||||
if result.is_none() {
|
let mut result = crate::lock_onto_mutex!(CACHED_DATA);
|
||||||
result.replace(get_json());
|
if result.is_none() {
|
||||||
}
|
result.replace(get_json());
|
||||||
let cache = result.as_ref().unwrap();
|
}
|
||||||
|
result.as_ref().unwrap().clone()
|
||||||
|
};
|
||||||
let rv = cache["cache"].clone();
|
let rv = cache["cache"].clone();
|
||||||
if cache["last_updated"].as_u64().unwrap() + (60 * 60) < global::timestamp() {
|
if cache["last_updated"].as_u64().unwrap() + (60 * 60) < global::timestamp() {
|
||||||
let mut result = crate::lock_onto_mutex!(CACHED_DATA);
|
let mut result = crate::lock_onto_mutex!(CACHED_DATA);
|
||||||
let new = get_json();
|
let new = get_json();
|
||||||
result.replace(new.clone());
|
result.replace(new.clone());
|
||||||
}
|
}
|
||||||
return rv;
|
rv
|
||||||
}
|
}
|
||||||
|
@ -27,12 +27,10 @@ pub fn get_asset_hash(asset_version: String, android: bool) -> String {
|
|||||||
} else {
|
} else {
|
||||||
ASSET_HASH_ANDROID_JP.to_string()
|
ASSET_HASH_ANDROID_JP.to_string()
|
||||||
}
|
}
|
||||||
|
} else if args.jp_ios_asset_hash != String::new() {
|
||||||
|
args.jp_ios_asset_hash
|
||||||
} else {
|
} else {
|
||||||
if args.jp_ios_asset_hash != String::new() {
|
ASSET_HASH_IOS_JP.to_string()
|
||||||
args.jp_ios_asset_hash
|
|
||||||
} else {
|
|
||||||
ASSET_HASH_IOS_JP.to_string()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else if android {
|
} else if android {
|
||||||
if args.en_android_asset_hash != String::new() {
|
if args.en_android_asset_hash != String::new() {
|
||||||
@ -40,12 +38,10 @@ pub fn get_asset_hash(asset_version: String, android: bool) -> String {
|
|||||||
} else {
|
} else {
|
||||||
ASSET_HASH_ANDROID.to_string()
|
ASSET_HASH_ANDROID.to_string()
|
||||||
}
|
}
|
||||||
|
} else if args.en_ios_asset_hash != String::new() {
|
||||||
|
args.en_ios_asset_hash
|
||||||
} else {
|
} else {
|
||||||
if args.en_ios_asset_hash != String::new() {
|
ASSET_HASH_IOS.to_string()
|
||||||
args.en_ios_asset_hash
|
|
||||||
} else {
|
|
||||||
ASSET_HASH_IOS.to_string()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -356,7 +356,7 @@ pub fn migration_password_register(req: HttpRequest, body: String) -> HttpRespon
|
|||||||
|
|
||||||
pub fn get_protocol() -> String {
|
pub fn get_protocol() -> String {
|
||||||
let args = crate::get_args();
|
let args = crate::get_args();
|
||||||
if args.https == true {
|
if args.https {
|
||||||
return String::from("https");
|
return String::from("https");
|
||||||
}
|
}
|
||||||
String::from("http")
|
String::from("http")
|
||||||
|
@ -325,7 +325,7 @@ async fn npps4_req(sha_id: String) -> Option<JsonValue> {
|
|||||||
let args = crate::get_args();
|
let args = crate::get_args();
|
||||||
|
|
||||||
let mut host = args.npps4;
|
let mut host = args.npps4;
|
||||||
while host.ends_with("/") {
|
while host.ends_with('/') {
|
||||||
host.pop();
|
host.pop();
|
||||||
}
|
}
|
||||||
let url = format!("{}/ewexport?sha1={}", host, sha_id);
|
let url = format!("{}/ewexport?sha1={}", host, sha_id);
|
||||||
@ -334,7 +334,7 @@ async fn npps4_req(sha_id: String) -> Option<JsonValue> {
|
|||||||
let client = reqwest::Client::new();
|
let client = reqwest::Client::new();
|
||||||
let response = client.get(url);
|
let response = client.get(url);
|
||||||
let response_body = response.send().await.ok()?.text().await.ok()?;
|
let response_body = response.send().await.ok()?.text().await.ok()?;
|
||||||
Some(json::parse(&response_body).ok()?)
|
json::parse(&response_body).ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clean_sif_data(current: &JsonValue) -> JsonValue {
|
fn clean_sif_data(current: &JsonValue) -> JsonValue {
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
use actix_web::{
|
use actix_web::{HttpResponse, HttpRequest, http::header::HeaderValue, http::header::ContentType, Responder};
|
||||||
HttpResponse,
|
use actix_files::NamedFile;
|
||||||
HttpRequest,
|
use std::path::PathBuf;
|
||||||
http::header::HeaderValue,
|
|
||||||
http::header::ContentType
|
|
||||||
};
|
|
||||||
use json::{JsonValue, object};
|
use json::{JsonValue, object};
|
||||||
|
|
||||||
use crate::include_file;
|
use crate::include_file;
|
||||||
@ -163,6 +160,28 @@ pub fn main(req: HttpRequest) -> HttpResponse {
|
|||||||
.body(include_file!("webui/dist/index.html"))
|
.body(include_file!("webui/dist/index.html"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn asset(req: HttpRequest) -> impl Responder {
|
||||||
|
let args = crate::get_args();
|
||||||
|
|
||||||
|
if req.path() == "/" {
|
||||||
|
return HttpResponse::Ok()
|
||||||
|
.insert_header(ContentType::html())
|
||||||
|
.body(include_file!("webui/dist/asset_index.html"));
|
||||||
|
}
|
||||||
|
|
||||||
|
let path = req.path();
|
||||||
|
let mut modified_path = format!("{}{}", args.asset_path, path);
|
||||||
|
|
||||||
|
modified_path = modified_path.trim_end_matches('/').to_string();
|
||||||
|
|
||||||
|
let filename: PathBuf = modified_path.trim_start_matches('/').into();
|
||||||
|
|
||||||
|
match NamedFile::open(&filename) {
|
||||||
|
Ok(file) => file.into_response(&req),
|
||||||
|
Err(_) => HttpResponse::NotFound().body("File not found"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn export(req: HttpRequest) -> HttpResponse {
|
pub fn export(req: HttpRequest) -> HttpResponse {
|
||||||
if !get_config()["export"].as_bool().unwrap() {
|
if !get_config()["export"].as_bool().unwrap() {
|
||||||
return error("Exporting accounts is disabled on this server.");
|
return error("Exporting accounts is disabled on this server.");
|
||||||
|
40
src/sql.rs
40
src/sql.rs
@ -4,11 +4,6 @@ use json::{JsonValue, array};
|
|||||||
|
|
||||||
use crate::router::clear_rate::Live;
|
use crate::router::clear_rate::Live;
|
||||||
|
|
||||||
pub struct SQLite {
|
|
||||||
engine: Mutex<Connection>
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is duplicated, for ease of people wanting to use this file in their project
|
|
||||||
macro_rules! lock_onto_mutex {
|
macro_rules! lock_onto_mutex {
|
||||||
($mutex:expr) => {{
|
($mutex:expr) => {{
|
||||||
loop {
|
loop {
|
||||||
@ -17,6 +12,7 @@ macro_rules! lock_onto_mutex {
|
|||||||
break value;
|
break value;
|
||||||
}
|
}
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
|
$mutex.clear_poison();
|
||||||
std::thread::sleep(std::time::Duration::from_millis(10));
|
std::thread::sleep(std::time::Duration::from_millis(10));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -24,6 +20,10 @@ macro_rules! lock_onto_mutex {
|
|||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct SQLite {
|
||||||
|
engine: Mutex<Connection>
|
||||||
|
}
|
||||||
|
|
||||||
impl SQLite {
|
impl SQLite {
|
||||||
pub fn new(path: &str, setup: fn(&SQLite)) -> SQLite {
|
pub fn new(path: &str, setup: fn(&SQLite)) -> SQLite {
|
||||||
let conn = Connection::open(crate::get_data_path(path)).unwrap();
|
let conn = Connection::open(crate::get_data_path(path)).unwrap();
|
||||||
@ -41,12 +41,12 @@ impl SQLite {
|
|||||||
pub fn lock_and_select(&self, command: &str, args: &[&dyn ToSql]) -> Result<String, rusqlite::Error> {
|
pub fn lock_and_select(&self, command: &str, args: &[&dyn ToSql]) -> Result<String, rusqlite::Error> {
|
||||||
let conn = lock_onto_mutex!(self.engine);
|
let conn = lock_onto_mutex!(self.engine);
|
||||||
let mut stmt = conn.prepare(command)?;
|
let mut stmt = conn.prepare(command)?;
|
||||||
return stmt.query_row(args, |row| {
|
stmt.query_row(args, |row| {
|
||||||
match row.get::<usize, i64>(0) {
|
match row.get::<usize, i64>(0) {
|
||||||
Ok(val) => Ok(val.to_string()),
|
Ok(val) => Ok(val.to_string()),
|
||||||
Err(_) => row.get(0)
|
Err(_) => row.get(0)
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
pub fn lock_and_select_all(&self, command: &str, args: &[&dyn ToSql]) -> Result<JsonValue, rusqlite::Error> {
|
pub fn lock_and_select_all(&self, command: &str, args: &[&dyn ToSql]) -> Result<JsonValue, rusqlite::Error> {
|
||||||
let conn = lock_onto_mutex!(self.engine);
|
let conn = lock_onto_mutex!(self.engine);
|
||||||
@ -62,27 +62,27 @@ impl SQLite {
|
|||||||
let res = val?;
|
let res = val?;
|
||||||
match res.clone().parse::<i64>() {
|
match res.clone().parse::<i64>() {
|
||||||
Ok(v) => rv.push(v).unwrap(),
|
Ok(v) => rv.push(v).unwrap(),
|
||||||
Err(_) => rv.push(res).unwrap()
|
Err(_) => rv.push(res).unwrap()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return Ok(rv);
|
Ok(rv)
|
||||||
}
|
}
|
||||||
pub fn get_live_data(&self, id: i64) -> Result<Live, rusqlite::Error> {
|
pub fn get_live_data(&self, id: i64) -> Result<Live, rusqlite::Error> {
|
||||||
let conn = lock_onto_mutex!(self.engine);
|
let conn = lock_onto_mutex!(self.engine);
|
||||||
let mut stmt = conn.prepare("SELECT * FROM lives WHERE live_id=?1")?;
|
let mut stmt = conn.prepare("SELECT * FROM lives WHERE live_id=?1")?;
|
||||||
return stmt.query_row(params!(id), |row| {
|
stmt.query_row(params!(id), |row| {
|
||||||
Ok(Live {
|
Ok(Live {
|
||||||
live_id: row.get(0)?,
|
live_id: row.get(0)?,
|
||||||
normal_failed: row.get(1)?,
|
normal_failed: row.get(1)?,
|
||||||
normal_pass: row.get(2)?,
|
normal_pass: row.get(2)?,
|
||||||
hard_failed: row.get(3)?,
|
hard_failed: row.get(3)?,
|
||||||
hard_pass: row.get(4)?,
|
hard_pass: row.get(4)?,
|
||||||
expert_failed: row.get(5)?,
|
expert_failed: row.get(5)?,
|
||||||
expert_pass: row.get(6)?,
|
expert_pass: row.get(6)?,
|
||||||
master_failed: row.get(7)?,
|
master_failed: row.get(7)?,
|
||||||
master_pass: row.get(8)?,
|
master_pass: row.get(8)?,
|
||||||
})
|
})
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
pub fn create_store_v2(&self, table: &str) {
|
pub fn create_store_v2(&self, table: &str) {
|
||||||
self.lock_and_exec(table, params!());
|
self.lock_and_exec(table, params!());
|
||||||
|
1
webui/.gitignore
vendored
1
webui/.gitignore
vendored
@ -22,3 +22,4 @@ dist-ssr
|
|||||||
*.njsproj
|
*.njsproj
|
||||||
*.sln
|
*.sln
|
||||||
*.sw?
|
*.sw?
|
||||||
|
*.lock
|
||||||
|
@ -60,6 +60,7 @@ function Login() {
|
|||||||
<button onClick={help}>Need help?</button><br/><br/>
|
<button onClick={help}>Need help?</button><br/><br/>
|
||||||
{ error[0] ? <p>Error: { error[0] } </p> : <p></p> }
|
{ error[0] ? <p>Error: { error[0] } </p> : <p></p> }
|
||||||
</div>
|
</div>
|
||||||
|
<p>EW Version 1.0.0 - <a href="https://git.ethanthesleepy.one/ethanaobrien/ew">View source</a> - <a href="https://git.ethanthesleepy.one/ethanaobrien/ew/src/branch/main/LICENSE">View license</a></p>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user