mirror of
https://github.com/gotson/komga.git
synced 2025-12-06 08:32:25 +01:00
Compare commits
57 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
361d20df2c | ||
|
|
ced89c5c54 | ||
|
|
a5548a5429 | ||
|
|
8f8d20a324 | ||
|
|
0f69a3a4cb | ||
|
|
9d10ed31a7 | ||
|
|
dde0169f2a | ||
|
|
a2ed7d319d | ||
|
|
475f026749 | ||
|
|
a03f1bdf7b | ||
|
|
b43046fbeb | ||
|
|
3739951b36 | ||
|
|
0f25453949 | ||
|
|
cd47fc777a | ||
|
|
f138fe31e7 | ||
|
|
454c6c7202 | ||
|
|
ce3ad4c1c7 | ||
|
|
b925f3e19d | ||
|
|
9a56b30b6c | ||
|
|
6b07fda273 | ||
|
|
727fe39e6d | ||
|
|
f8ca936ee7 | ||
|
|
fe40ede34a | ||
|
|
c23f2d3810 | ||
|
|
af66144060 | ||
|
|
ba7b82631f | ||
|
|
a166f96bdf | ||
|
|
2259e4bf1c | ||
|
|
f75ad77e85 | ||
|
|
f2913d1e83 | ||
|
|
0b3307cd70 | ||
|
|
1213309f35 | ||
|
|
5a5f8d701e | ||
|
|
bdca990e82 | ||
|
|
8081439009 | ||
|
|
80c604e089 | ||
|
|
f19d7aac1e | ||
|
|
43c1018e3e | ||
|
|
eb8bdfc94c | ||
|
|
e842a5287f | ||
|
|
e0b583ff1d | ||
|
|
5e3ca4d571 | ||
|
|
730b093a5f | ||
|
|
2f9b4e75d2 | ||
|
|
d9657587c4 | ||
|
|
69ba569b04 | ||
|
|
e850cdcd2f | ||
|
|
51bfb353e7 | ||
|
|
3f64435afa | ||
|
|
166b1ee371 | ||
|
|
0e63e7454b | ||
|
|
058af49807 | ||
|
|
7888a53dbf | ||
|
|
2ec0e295fa | ||
|
|
1776174d3f | ||
|
|
b837963f0e | ||
|
|
6b4d81e0ba |
76 changed files with 2783 additions and 468 deletions
2
.github/workflows/browserlist-update.yml
vendored
2
.github/workflows/browserlist-update.yml
vendored
|
|
@ -14,7 +14,7 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Configure git
|
||||
|
|
|
|||
2
.github/workflows/dispatch.yml
vendored
2
.github/workflows/dispatch.yml
vendored
|
|
@ -11,7 +11,7 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Repository Dispatch
|
||||
uses: peter-evans/repository-dispatch@v3
|
||||
uses: peter-evans/repository-dispatch@v4
|
||||
with:
|
||||
token: ${{ secrets.REPO_ACCESS_TOKEN }}
|
||||
repository: gotson/komga-website
|
||||
|
|
|
|||
2
.github/workflows/dockerhub_description.yml
vendored
2
.github/workflows/dockerhub_description.yml
vendored
|
|
@ -15,7 +15,7 @@ jobs:
|
|||
steps:
|
||||
- uses: actions/checkout@master
|
||||
- name: DockerHub Description
|
||||
uses: peter-evans/dockerhub-description@v4.0.2
|
||||
uses: peter-evans/dockerhub-description@v5.0.0
|
||||
env:
|
||||
DOCKERHUB_USERNAME: ${{ secrets.DOCKER_USERNAME }}
|
||||
DOCKERHUB_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
|
||||
|
|
|
|||
28
.github/workflows/release.yml
vendored
28
.github/workflows/release.yml
vendored
|
|
@ -43,14 +43,14 @@ jobs:
|
|||
version_next: ${{ steps.versions.outputs.version_next }}
|
||||
should_release: ${{ steps.versions.outputs.should_release }}
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Set up Homebrew
|
||||
id: set-up-homebrew
|
||||
uses: Homebrew/actions/setup-homebrew@master
|
||||
- name: Install svu
|
||||
run: brew install caarlos0/tap/svu
|
||||
run: brew install --cask caarlos0/tap/svu
|
||||
- name: Compute next version for release
|
||||
run: |
|
||||
echo "VERSION_NEXT=`svu ${{ inputs.bump }}`" | tee -a $GITHUB_ENV
|
||||
|
|
@ -72,7 +72,7 @@ jobs:
|
|||
sudo rm -rf /usr/share/dotnet
|
||||
sudo rm -rf "$AGENT_TOOLSDIRECTORY"
|
||||
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
|
|
@ -84,14 +84,14 @@ jobs:
|
|||
if: needs.version.outputs.should_release #only redo if the version changed
|
||||
run: sed -i -e "s/version=.*/version=${{ needs.version.outputs.version_next }}/" gradle.properties
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: 'npm'
|
||||
cache-dependency-path: komga-webui/package-lock.json
|
||||
|
||||
- name: Setup Java 21
|
||||
uses: actions/setup-java@v4
|
||||
uses: actions/setup-java@v5
|
||||
with:
|
||||
java-version: 21
|
||||
java-package: 'jdk'
|
||||
|
|
@ -117,7 +117,7 @@ jobs:
|
|||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Setup Gradle
|
||||
uses: gradle/actions/setup-gradle@v4
|
||||
uses: gradle/actions/setup-gradle@v5
|
||||
|
||||
- name: Build
|
||||
run: ./gradlew :komga:prepareThymeLeaf :komga:bootJar :komga-tray:jar
|
||||
|
|
@ -143,7 +143,7 @@ jobs:
|
|||
JRELEASER_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: JReleaser Changelog output
|
||||
if: always() && needs.version.outputs.should_release
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v5
|
||||
with:
|
||||
name: jreleaser-changelog
|
||||
path: |
|
||||
|
|
@ -167,7 +167,7 @@ jobs:
|
|||
echo $APPLE_PRIVATE_KEY | base64 --decode > ./secret/apple_private_key.p8
|
||||
|
||||
- name: Conveyor make copied-site
|
||||
uses: hydraulic-software/conveyor/actions/build@v19.0
|
||||
uses: hydraulic-software/conveyor/actions/build@v20.0
|
||||
if: inputs.conveyor-copied-site
|
||||
with:
|
||||
command: --cache-limit=2.0 -f conveyor.ci.conf make copied-site -o ./output/site
|
||||
|
|
@ -182,7 +182,7 @@ jobs:
|
|||
AWS_SECRET_ACCESS_KEY: ${{ secrets.B2_SECRET_ACCESS_KEY }}
|
||||
- name: Upload Conveyor log
|
||||
if: always() && inputs.conveyor-copied-site
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v5
|
||||
with:
|
||||
name: conveyor-make-copied-site
|
||||
path: ~/.cache/hydraulic/conveyor/logs/log.latest.txt
|
||||
|
|
@ -194,7 +194,7 @@ jobs:
|
|||
JRELEASER_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: JReleaser Release output
|
||||
if: always() && inputs.github_release
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v5
|
||||
with:
|
||||
name: jreleaser-release
|
||||
path: |
|
||||
|
|
@ -212,7 +212,7 @@ jobs:
|
|||
JRELEASER_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: JReleaser Publish output
|
||||
if: always() && inputs.docker_release
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v5
|
||||
with:
|
||||
name: jreleaser-publish
|
||||
path: |
|
||||
|
|
@ -220,7 +220,7 @@ jobs:
|
|||
build/jreleaser/output.properties
|
||||
|
||||
- name: Conveyor - publish to Microsoft Store
|
||||
uses: hydraulic-software/conveyor/actions/build@v19.0
|
||||
uses: hydraulic-software/conveyor/actions/build@v20.0
|
||||
if: inputs.msstore_release
|
||||
with:
|
||||
command: --cache-limit=2.0 -f conveyor.msstore.ci.conf make ms-store-release -o ./output/msstore
|
||||
|
|
@ -236,7 +236,7 @@ jobs:
|
|||
AWS_SECRET_ACCESS_KEY: ${{ secrets.B2_SECRET_ACCESS_KEY }}
|
||||
- name: Upload Conveyor log
|
||||
if: always() && inputs.msstore_release
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v5
|
||||
with:
|
||||
name: conveyor-ms-store-release
|
||||
path: ~/.cache/hydraulic/conveyor/logs/log.latest.txt
|
||||
|
|
@ -246,7 +246,7 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Repository Dispatch
|
||||
uses: peter-evans/repository-dispatch@v3
|
||||
uses: peter-evans/repository-dispatch@v4
|
||||
with:
|
||||
token: ${{ secrets.REPO_ACCESS_TOKEN }}
|
||||
repository: gotson/komga-website
|
||||
|
|
|
|||
20
.github/workflows/tests.yml
vendored
20
.github/workflows/tests.yml
vendored
|
|
@ -19,36 +19,36 @@ jobs:
|
|||
fail-fast: false
|
||||
name: Test server - ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
- name: Setup Java 21
|
||||
uses: actions/setup-java@v4
|
||||
uses: actions/setup-java@v5
|
||||
with:
|
||||
java-version: 21
|
||||
java-package: 'jdk'
|
||||
distribution: 'temurin'
|
||||
|
||||
- name: Setup Gradle
|
||||
uses: gradle/actions/setup-gradle@v4
|
||||
uses: gradle/actions/setup-gradle@v5
|
||||
|
||||
- name: Build
|
||||
run: ./gradlew build :komga-tray:jar
|
||||
|
||||
- name: Upload Unit Test Results
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v5
|
||||
with:
|
||||
name: test-results-${{ matrix.os }}
|
||||
path: komga/build/test-results/
|
||||
|
||||
- name: Upload Unit Test Reports
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v5
|
||||
with:
|
||||
name: test-reports-${{ matrix.os }}
|
||||
path: komga/build/reports/tests/
|
||||
|
||||
- name: Publish Test Report
|
||||
uses: mikepenz/action-junit-report@v5
|
||||
uses: mikepenz/action-junit-report@v6
|
||||
if: always()
|
||||
with:
|
||||
report_paths: '**/build/test-results/test/TEST-*.xml'
|
||||
|
|
@ -56,7 +56,7 @@ jobs:
|
|||
|
||||
- name: Conveyor - compute JDK module list
|
||||
if: github.event_name == 'push' && github.repository_owner == 'gotson' && contains(matrix.os, 'ubuntu')
|
||||
uses: hydraulic-software/conveyor/actions/build@v19.0
|
||||
uses: hydraulic-software/conveyor/actions/build@v20.0
|
||||
with:
|
||||
command: -f conveyor.detect.conf -Kapp.machines=mac.aarch64 make processed-jars
|
||||
signing_key: ${{ secrets.CONVEYOR_SIGNING_KEY }}
|
||||
|
|
@ -69,7 +69,7 @@ jobs:
|
|||
|
||||
- name: Upload JDK required modules
|
||||
if: steps.conveyor_compare.outcome == 'failure'
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v5
|
||||
with:
|
||||
name: conveyor-required-jdk-modules
|
||||
path: ./output/required-jdk-modules.txt
|
||||
|
|
@ -78,8 +78,8 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
name: Test webui builds
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: 'npm'
|
||||
|
|
|
|||
131
CHANGELOG.md
131
CHANGELOG.md
|
|
@ -1,3 +1,134 @@
|
|||
# [1.23.6](https://github.com/gotson/komga/compare/1.23.5...1.23.6) (2025-11-28)
|
||||
## 🐛 Fixes
|
||||
**kobo**
|
||||
- proxy 401 errors on initialization ([3739951](https://github.com/gotson/komga/commits/3739951))
|
||||
- prevent double URL encoding when proxying ([ce3ad4c](https://github.com/gotson/komga/commits/ce3ad4c)), closes [#2130](https://github.com/gotson/komga/issues/2130)
|
||||
- proxy Content-Type headers for kobo ([b925f3e](https://github.com/gotson/komga/commits/b925f3e)), closes [#2074](https://github.com/gotson/komga/issues/2074)
|
||||
|
||||
**unscoped**
|
||||
- properly decode cover href when generating epub cover ([f8ca936](https://github.com/gotson/komga/commits/f8ca936)), closes [#2118](https://github.com/gotson/komga/issues/2118)
|
||||
|
||||
## 🔄️ Changes
|
||||
**kobo**
|
||||
- log error responses ([454c6c7](https://github.com/gotson/komga/commits/454c6c7))
|
||||
|
||||
## 🛠 Build
|
||||
**docker**
|
||||
- use old-releases apt repo ([ba7b826](https://github.com/gotson/komga/commits/ba7b826))
|
||||
|
||||
**webui**
|
||||
- update Browserslist db ([727fe39](https://github.com/gotson/komga/commits/727fe39))
|
||||
|
||||
**unscoped**
|
||||
- fix svu install ([9a56b30](https://github.com/gotson/komga/commits/9a56b30))
|
||||
|
||||
## 📝 Documentation
|
||||
**api**
|
||||
- fix mediatype ([af66144](https://github.com/gotson/komga/commits/af66144))
|
||||
|
||||
## 🌐 Translation
|
||||
**komga-tray**
|
||||
- translated using Weblate (Arabic) ([a5548a5](https://github.com/gotson/komga/commits/a5548a5))
|
||||
- translated using Weblate (Russian) ([8f8d20a](https://github.com/gotson/komga/commits/8f8d20a))
|
||||
- translated using Weblate (Galician) ([0f69a3a](https://github.com/gotson/komga/commits/0f69a3a))
|
||||
|
||||
**webui**
|
||||
- translated using Weblate (Croatian) ([dde0169](https://github.com/gotson/komga/commits/dde0169))
|
||||
- translated using Weblate (Russian) ([a2ed7d3](https://github.com/gotson/komga/commits/a2ed7d3))
|
||||
- translated using Weblate (Portuguese (Brazil)) ([475f026](https://github.com/gotson/komga/commits/475f026))
|
||||
- translated using Weblate (Thai) ([a03f1bd](https://github.com/gotson/komga/commits/a03f1bd))
|
||||
|
||||
## ⚙️ Dependencies
|
||||
**ci**
|
||||
- bump actions/checkout from 5 to 6 ([f138fe3](https://github.com/gotson/komga/commits/f138fe3))
|
||||
- bump mikepenz/action-junit-report from 5 to 6 ([6b07fda](https://github.com/gotson/komga/commits/6b07fda))
|
||||
- bump actions/upload-artifact from 4 to 5 ([fe40ede](https://github.com/gotson/komga/commits/fe40ede))
|
||||
- bump actions/setup-node from 5 to 6 ([c23f2d3](https://github.com/gotson/komga/commits/c23f2d3))
|
||||
|
||||
**webui**
|
||||
- bump node-forge from 1.3.1 to 1.3.2 in /komga-webui ([0f25453](https://github.com/gotson/komga/commits/0f25453))
|
||||
- bump js-yaml from 3.14.1 to 3.14.2 in /komga-webui ([cd47fc7](https://github.com/gotson/komga/commits/cd47fc7))
|
||||
|
||||
# [1.23.5](https://github.com/gotson/komga/compare/1.23.4...1.23.5) (2025-10-08)
|
||||
## 🚀 Features
|
||||
|
||||
- support local artwork in gif format ([f19d7aa](https://github.com/gotson/komga/commits/f19d7aa)), closes [#1853](https://github.com/gotson/komga/issues/1853)
|
||||
|
||||
## 🐛 Fixes
|
||||
**api**
|
||||
- empty content when x-api-key is sent alongside session ([5a5f8d7](https://github.com/gotson/komga/commits/5a5f8d7)), closes [#2099](https://github.com/gotson/komga/issues/2099)
|
||||
- relax JSON deserializer ([eb8bdfc](https://github.com/gotson/komga/commits/eb8bdfc))
|
||||
- add id field in HistoricalEventDto ([5e3ca4d](https://github.com/gotson/komga/commits/5e3ca4d))
|
||||
|
||||
## 🏎 Perf
|
||||
**api**
|
||||
- remove no-transform cache-control from response header ([43c1018](https://github.com/gotson/komga/commits/43c1018)), closes [#2091](https://github.com/gotson/komga/issues/2091)
|
||||
|
||||
## 🔄️ Changes
|
||||
|
||||
- add more logs when epub extension is missing ([730b093](https://github.com/gotson/komga/commits/730b093))
|
||||
- add more logs to koreader sync controller ([2f9b4e7](https://github.com/gotson/komga/commits/2f9b4e7))
|
||||
- make dslRO transaction aware ([69ba569](https://github.com/gotson/komga/commits/69ba569))
|
||||
|
||||
## 🛠 Build
|
||||
**webui**
|
||||
- update Browserslist db ([e842a52](https://github.com/gotson/komga/commits/e842a52))
|
||||
|
||||
## 🌐 Translation
|
||||
**komga-tray**
|
||||
- translated using Weblate (Portuguese (Brazil)) ([2259e4b](https://github.com/gotson/komga/commits/2259e4b))
|
||||
|
||||
**webui**
|
||||
- translated using Weblate (Slovak) ([f75ad77](https://github.com/gotson/komga/commits/f75ad77))
|
||||
- translated using Weblate (Croatian) ([f2913d1](https://github.com/gotson/komga/commits/f2913d1))
|
||||
- translated using Weblate (Czech) ([0b3307c](https://github.com/gotson/komga/commits/0b3307c))
|
||||
- translated using Weblate (Portuguese (Brazil)) ([1213309](https://github.com/gotson/komga/commits/1213309))
|
||||
|
||||
## ⚙️ Dependencies
|
||||
**ci**
|
||||
- bump peter-evans/dockerhub-description from 4.0.2 to 5.0.0 ([bdca990](https://github.com/gotson/komga/commits/bdca990))
|
||||
- bump gradle/actions from 4 to 5 ([8081439](https://github.com/gotson/komga/commits/8081439))
|
||||
- bump peter-evans/repository-dispatch from 3 to 4 ([80c604e](https://github.com/gotson/komga/commits/80c604e))
|
||||
- bump hydraulic-software/conveyor from 19.0 to 20.0 ([e0b583f](https://github.com/gotson/komga/commits/e0b583f))
|
||||
|
||||
**webui**
|
||||
- bump axios from 1.8.2 to 1.12.0 in /komga-webui ([d965758](https://github.com/gotson/komga/commits/d965758))
|
||||
|
||||
# [1.23.4](https://github.com/gotson/komga/compare/1.23.3...1.23.4) (2025-09-09)
|
||||
## 🐛 Fixes
|
||||
**kobo**
|
||||
- update default kobo resources ([166b1ee](https://github.com/gotson/komga/commits/166b1ee)), closes [#2066](https://github.com/gotson/komga/issues/2066)
|
||||
- fail to create proxy url ([058af49](https://github.com/gotson/komga/commits/058af49)), closes [#2063](https://github.com/gotson/komga/issues/2063)
|
||||
|
||||
## 🏎 Perf
|
||||
|
||||
- send events outside of db transaction ([51bfb35](https://github.com/gotson/komga/commits/51bfb35))
|
||||
|
||||
## 🧪 Tests
|
||||
|
||||
- run tests with a WAL database instead of memorydb ([7888a53](https://github.com/gotson/komga/commits/7888a53))
|
||||
|
||||
## 🛠 Build
|
||||
**webui**
|
||||
- update Browserslist db ([0e63e74](https://github.com/gotson/komga/commits/0e63e74))
|
||||
|
||||
## ⚙️ Dependencies
|
||||
**ci**
|
||||
- bump actions/setup-node from 4 to 5 ([3f64435](https://github.com/gotson/komga/commits/3f64435))
|
||||
|
||||
# [1.23.3](https://github.com/gotson/komga/compare/1.23.2...1.23.3) (2025-08-28)
|
||||
## 🐛 Fixes
|
||||
**api**
|
||||
- cannot create readlist or collection with database in WAL mode ([1776174](https://github.com/gotson/komga/commits/1776174))
|
||||
|
||||
## 🛠 Build
|
||||
**release**
|
||||
- fail jreleaser on publish errors ([6b4d81e](https://github.com/gotson/komga/commits/6b4d81e))
|
||||
|
||||
## ⚙️ Dependencies
|
||||
**ci**
|
||||
- bump actions/setup-java from 4 to 5 ([b837963](https://github.com/gotson/komga/commits/b837963))
|
||||
|
||||
# [1.23.2](https://github.com/gotson/komga/compare/1.23.1...1.23.2) (2025-08-25)
|
||||
## 🐛 Fixes
|
||||
**kobo**
|
||||
|
|
|
|||
|
|
@ -164,7 +164,7 @@ jreleaser {
|
|||
packagers {
|
||||
docker {
|
||||
active = Active.RELEASE
|
||||
continueOnError = true
|
||||
continueOnError = false
|
||||
templateDirectory = rootDir.resolve("komga/docker")
|
||||
repository.active = Active.NEVER
|
||||
buildArgs = listOf("--cache-from", "gotson/komga:latest")
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
version=1.23.2
|
||||
version=1.23.6
|
||||
org.gradle.jvmargs=-Xmx2G
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
dialog_error.close=إغلاق
|
||||
dialog_error.copy_clipboard=النسخ إلى الحافظة
|
||||
dialog_error.title=Komga لم يقدر على البدء
|
||||
error_message.port_in_use=الباب {} على قيد الاستعمال.\nربما Komga جارٍ بالفعل.\nتحقق أيقونة علبة النظام أو القائمة لأيقونة Komga.
|
||||
error_message.unexpected=حصل خطأ غير متوقع.
|
||||
menu.open_komga=فتح Komga
|
||||
menu.quit=إغلاق Komga
|
||||
menu.show_conf_dir=فتح موقع الإعدادات
|
||||
menu.show_log=إظهار ملف السجل
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
dialog_error.close=Pechar
|
||||
dialog_error.copy_clipboard=Copiar ao portapapeis
|
||||
dialog_error.title=Komga fallou ao iniciar
|
||||
error_message.port_in_use=O porto {} está en uso.\nÉ probable que Komga xa esté a executarse.\nBusca a icona de Komga na bandexa de sistema ou a barra de menú.
|
||||
error_message.unexpected=Aconteceu un erro imprevisto.
|
||||
menu.open_komga=Abrir Komga
|
||||
menu.quit=Saír de Komga
|
||||
menu.show_conf_dir=Abrir o cartafol de configuración
|
||||
menu.show_log=Amosar o ficheiro de rexistro
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
dialog_error.close=Fechar
|
||||
dialog_error.copy_clipboard=Copiar para área de transferência
|
||||
dialog_error.title=Komga falhou ao inicializar
|
||||
error_message.port_in_use=A porta {} já está em uso.\nProvavelmente o Komga já está rodando.\nVerifique o ícone na barra de tarefas ou a barra de menu.
|
||||
error_message.unexpected=Ocorreu um erro inesperado.
|
||||
menu.open_komga=Abrir Komga
|
||||
menu.quit=Sair do Komga
|
||||
menu.show_conf_dir=Abrir configuração de diretório
|
||||
menu.show_log=Mostrar arquivo de logs
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
dialog_error.close=Закрыть
|
||||
dialog_error.copy_clipboard=Скопировать в буфер обмена
|
||||
dialog_error.title=Komga не смог запуститься
|
||||
error_message.port_in_use=Порт {] уже используется.\nKomga возможно уже работает.\nПроверьте панель задач или меню на наличие иконки Komga.
|
||||
dialog_error.title=Komga не удалось запустить
|
||||
error_message.port_in_use=Порт {} уже используется.\nВероятно, Komga уже запущен.\nПроверьте область уведомлений или панель меню на наличие иконки Komga.
|
||||
error_message.unexpected=Произошла непредвиденная ошибка.
|
||||
menu.open_komga=Открыть Komga
|
||||
menu.quit=Закрыть Komga
|
||||
|
|
|
|||
303
komga-webui/package-lock.json
generated
303
komga-webui/package-lock.json
generated
|
|
@ -10,7 +10,7 @@
|
|||
"dependencies": {
|
||||
"@d-i-t-a/reader": "github:gotson/R2D2BC#fork",
|
||||
"@saekitominaga/isbn-verify": "^2.0.1",
|
||||
"axios": "^1.8.2",
|
||||
"axios": "^1.12.0",
|
||||
"chart.js": "^2.9.4",
|
||||
"core-js": "^3.8.3",
|
||||
"date-fns": "^2.30.0",
|
||||
|
|
@ -5102,13 +5102,12 @@
|
|||
"integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg=="
|
||||
},
|
||||
"node_modules/axios": {
|
||||
"version": "1.8.2",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.8.2.tgz",
|
||||
"integrity": "sha512-ls4GYBm5aig9vWx8AWDSGLpnpDQRtWAfrjU+EuytuODrFBkqesN2RkOQCBzrA1RQNHw1SmRMSDDDSwzNAYQ6Rg==",
|
||||
"license": "MIT",
|
||||
"version": "1.12.0",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.12.0.tgz",
|
||||
"integrity": "sha512-oXTDccv8PcfjZmPGlWsPSwtOJCZ/b6W5jAMCNcfwJbCzDckwG0jrYJFaWH1yvivfCXjVzV/SPDEhMB3Q+DSurg==",
|
||||
"dependencies": {
|
||||
"follow-redirects": "^1.15.6",
|
||||
"form-data": "^4.0.0",
|
||||
"form-data": "^4.0.4",
|
||||
"proxy-from-env": "^1.1.0"
|
||||
}
|
||||
},
|
||||
|
|
@ -5715,6 +5714,18 @@
|
|||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/call-bind-apply-helpers": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
|
||||
"integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
|
||||
"dependencies": {
|
||||
"es-errors": "^1.3.0",
|
||||
"function-bind": "^1.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/callsite": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz",
|
||||
|
|
@ -5768,9 +5779,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/caniuse-lite": {
|
||||
"version": "1.0.30001731",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001731.tgz",
|
||||
"integrity": "sha512-lDdp2/wrOmTRWuoB5DpfNkC0rJDU8DqRa6nYL6HK6sytw70QMopt/NIc/9SM7ylItlBWfACXk0tEn37UWM/+mg==",
|
||||
"version": "1.0.30001757",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001757.tgz",
|
||||
"integrity": "sha512-r0nnL/I28Zi/yjk1el6ilj27tKcdjLsNqAOZr0yVjWPrSQyHgKI2INaEWw21bAQSv2LXRt1XuCS/GomNpWOxsQ==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
|
|
@ -7288,6 +7299,19 @@
|
|||
"integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/dunder-proto": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
|
||||
"integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
|
||||
"dependencies": {
|
||||
"call-bind-apply-helpers": "^1.0.1",
|
||||
"es-errors": "^1.3.0",
|
||||
"gopd": "^1.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/duplexer": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz",
|
||||
|
|
@ -7614,12 +7638,9 @@
|
|||
}
|
||||
},
|
||||
"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"
|
||||
},
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
|
||||
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
|
|
@ -7638,15 +7659,26 @@
|
|||
"integrity": "sha512-JUFAyicQV9mXc3YRxPnDlrfBKpqt6hUYzz9/boprUJHs4e4KVr3XwOF70doO6gwXUor6EWZJAyWAfKki84t20Q==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/es-set-tostringtag": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz",
|
||||
"integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==",
|
||||
"dev": true,
|
||||
"node_modules/es-object-atoms": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
|
||||
"integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
|
||||
"dependencies": {
|
||||
"get-intrinsic": "^1.1.3",
|
||||
"has": "^1.0.3",
|
||||
"has-tostringtag": "^1.0.0"
|
||||
"es-errors": "^1.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/es-set-tostringtag": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
|
||||
"integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
|
||||
"dependencies": {
|
||||
"es-errors": "^1.3.0",
|
||||
"get-intrinsic": "^1.2.6",
|
||||
"has-tostringtag": "^1.0.2",
|
||||
"hasown": "^2.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
|
|
@ -9240,12 +9272,14 @@
|
|||
"dev": true
|
||||
},
|
||||
"node_modules/form-data": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
|
||||
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz",
|
||||
"integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==",
|
||||
"dependencies": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.8",
|
||||
"es-set-tostringtag": "^2.1.0",
|
||||
"hasown": "^2.0.2",
|
||||
"mime-types": "^2.1.12"
|
||||
},
|
||||
"engines": {
|
||||
|
|
@ -9406,15 +9440,20 @@
|
|||
}
|
||||
},
|
||||
"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==",
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
|
||||
"integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
|
||||
"dependencies": {
|
||||
"call-bind-apply-helpers": "^1.0.2",
|
||||
"es-define-property": "^1.0.1",
|
||||
"es-errors": "^1.3.0",
|
||||
"es-object-atoms": "^1.1.1",
|
||||
"function-bind": "^1.1.2",
|
||||
"has-proto": "^1.0.1",
|
||||
"has-symbols": "^1.0.3",
|
||||
"hasown": "^2.0.0"
|
||||
"get-proto": "^1.0.1",
|
||||
"gopd": "^1.2.0",
|
||||
"has-symbols": "^1.1.0",
|
||||
"hasown": "^2.0.2",
|
||||
"math-intrinsics": "^1.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
|
|
@ -9432,6 +9471,18 @@
|
|||
"node": ">=8.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/get-proto": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
|
||||
"integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
|
||||
"dependencies": {
|
||||
"dunder-proto": "^1.0.1",
|
||||
"es-object-atoms": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/get-stream": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
|
||||
|
|
@ -9549,11 +9600,11 @@
|
|||
}
|
||||
},
|
||||
"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"
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
|
||||
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
|
|
@ -9657,6 +9708,7 @@
|
|||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz",
|
||||
"integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
|
|
@ -9665,9 +9717,9 @@
|
|||
}
|
||||
},
|
||||
"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==",
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
|
||||
"integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
|
|
@ -9676,11 +9728,11 @@
|
|||
}
|
||||
},
|
||||
"node_modules/has-tostringtag": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz",
|
||||
"integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==",
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
|
||||
"integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
|
||||
"dependencies": {
|
||||
"has-symbols": "^1.0.2"
|
||||
"has-symbols": "^1.0.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
|
|
@ -12974,9 +13026,9 @@
|
|||
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
|
||||
},
|
||||
"node_modules/js-yaml": {
|
||||
"version": "3.14.1",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
|
||||
"integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
|
||||
"version": "3.14.2",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz",
|
||||
"integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"argparse": "^1.0.7",
|
||||
|
|
@ -13683,6 +13735,14 @@
|
|||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/math-intrinsics": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
|
||||
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/mdn-data": {
|
||||
"version": "2.0.30",
|
||||
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz",
|
||||
|
|
@ -14101,9 +14161,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/node-forge": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz",
|
||||
"integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==",
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.2.tgz",
|
||||
"integrity": "sha512-6xKiQ+cph9KImrRh0VsjH2d8/GXA4FIMlgU4B757iI1ApvcyA9VlouP0yZJha01V+huImO+kKMU7ih+2+E14fw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 6.13.0"
|
||||
|
|
@ -23587,12 +23647,12 @@
|
|||
"integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg=="
|
||||
},
|
||||
"axios": {
|
||||
"version": "1.8.2",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.8.2.tgz",
|
||||
"integrity": "sha512-ls4GYBm5aig9vWx8AWDSGLpnpDQRtWAfrjU+EuytuODrFBkqesN2RkOQCBzrA1RQNHw1SmRMSDDDSwzNAYQ6Rg==",
|
||||
"version": "1.12.0",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.12.0.tgz",
|
||||
"integrity": "sha512-oXTDccv8PcfjZmPGlWsPSwtOJCZ/b6W5jAMCNcfwJbCzDckwG0jrYJFaWH1yvivfCXjVzV/SPDEhMB3Q+DSurg==",
|
||||
"requires": {
|
||||
"follow-redirects": "^1.15.6",
|
||||
"form-data": "^4.0.0",
|
||||
"form-data": "^4.0.4",
|
||||
"proxy-from-env": "^1.1.0"
|
||||
}
|
||||
},
|
||||
|
|
@ -24043,6 +24103,15 @@
|
|||
"set-function-length": "^1.2.1"
|
||||
}
|
||||
},
|
||||
"call-bind-apply-helpers": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
|
||||
"integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
|
||||
"requires": {
|
||||
"es-errors": "^1.3.0",
|
||||
"function-bind": "^1.1.2"
|
||||
}
|
||||
},
|
||||
"callsite": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz",
|
||||
|
|
@ -24084,9 +24153,9 @@
|
|||
}
|
||||
},
|
||||
"caniuse-lite": {
|
||||
"version": "1.0.30001731",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001731.tgz",
|
||||
"integrity": "sha512-lDdp2/wrOmTRWuoB5DpfNkC0rJDU8DqRa6nYL6HK6sytw70QMopt/NIc/9SM7ylItlBWfACXk0tEn37UWM/+mg=="
|
||||
"version": "1.0.30001757",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001757.tgz",
|
||||
"integrity": "sha512-r0nnL/I28Zi/yjk1el6ilj27tKcdjLsNqAOZr0yVjWPrSQyHgKI2INaEWw21bAQSv2LXRt1XuCS/GomNpWOxsQ=="
|
||||
},
|
||||
"case-sensitive-paths-webpack-plugin": {
|
||||
"version": "2.4.0",
|
||||
|
|
@ -25214,6 +25283,16 @@
|
|||
"integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==",
|
||||
"dev": true
|
||||
},
|
||||
"dunder-proto": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
|
||||
"integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
|
||||
"requires": {
|
||||
"call-bind-apply-helpers": "^1.0.1",
|
||||
"es-errors": "^1.3.0",
|
||||
"gopd": "^1.2.0"
|
||||
}
|
||||
},
|
||||
"duplexer": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz",
|
||||
|
|
@ -25489,12 +25568,9 @@
|
|||
}
|
||||
},
|
||||
"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==",
|
||||
"requires": {
|
||||
"get-intrinsic": "^1.2.4"
|
||||
}
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
|
||||
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="
|
||||
},
|
||||
"es-errors": {
|
||||
"version": "1.3.0",
|
||||
|
|
@ -25507,15 +25583,23 @@
|
|||
"integrity": "sha512-JUFAyicQV9mXc3YRxPnDlrfBKpqt6hUYzz9/boprUJHs4e4KVr3XwOF70doO6gwXUor6EWZJAyWAfKki84t20Q==",
|
||||
"dev": true
|
||||
},
|
||||
"es-set-tostringtag": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz",
|
||||
"integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==",
|
||||
"dev": true,
|
||||
"es-object-atoms": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
|
||||
"integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
|
||||
"requires": {
|
||||
"get-intrinsic": "^1.1.3",
|
||||
"has": "^1.0.3",
|
||||
"has-tostringtag": "^1.0.0"
|
||||
"es-errors": "^1.3.0"
|
||||
}
|
||||
},
|
||||
"es-set-tostringtag": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
|
||||
"integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
|
||||
"requires": {
|
||||
"es-errors": "^1.3.0",
|
||||
"get-intrinsic": "^1.2.6",
|
||||
"has-tostringtag": "^1.0.2",
|
||||
"hasown": "^2.0.2"
|
||||
}
|
||||
},
|
||||
"es-shim-unscopables": {
|
||||
|
|
@ -26700,12 +26784,14 @@
|
|||
}
|
||||
},
|
||||
"form-data": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
|
||||
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz",
|
||||
"integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==",
|
||||
"requires": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.8",
|
||||
"es-set-tostringtag": "^2.1.0",
|
||||
"hasown": "^2.0.2",
|
||||
"mime-types": "^2.1.12"
|
||||
}
|
||||
},
|
||||
|
|
@ -26818,15 +26904,20 @@
|
|||
"dev": true
|
||||
},
|
||||
"get-intrinsic": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
|
||||
"integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
|
||||
"integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
|
||||
"requires": {
|
||||
"call-bind-apply-helpers": "^1.0.2",
|
||||
"es-define-property": "^1.0.1",
|
||||
"es-errors": "^1.3.0",
|
||||
"es-object-atoms": "^1.1.1",
|
||||
"function-bind": "^1.1.2",
|
||||
"has-proto": "^1.0.1",
|
||||
"has-symbols": "^1.0.3",
|
||||
"hasown": "^2.0.0"
|
||||
"get-proto": "^1.0.1",
|
||||
"gopd": "^1.2.0",
|
||||
"has-symbols": "^1.1.0",
|
||||
"hasown": "^2.0.2",
|
||||
"math-intrinsics": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"get-package-type": {
|
||||
|
|
@ -26835,6 +26926,15 @@
|
|||
"integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==",
|
||||
"dev": true
|
||||
},
|
||||
"get-proto": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
|
||||
"integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
|
||||
"requires": {
|
||||
"dunder-proto": "^1.0.1",
|
||||
"es-object-atoms": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"get-stream": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
|
||||
|
|
@ -26919,12 +27019,9 @@
|
|||
}
|
||||
},
|
||||
"gopd": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
|
||||
"integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==",
|
||||
"requires": {
|
||||
"get-intrinsic": "^1.1.3"
|
||||
}
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
|
||||
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="
|
||||
},
|
||||
"graceful-fs": {
|
||||
"version": "4.2.11",
|
||||
|
|
@ -26998,19 +27095,20 @@
|
|||
"has-proto": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz",
|
||||
"integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg=="
|
||||
"integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==",
|
||||
"dev": true
|
||||
},
|
||||
"has-symbols": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
|
||||
"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
|
||||
"integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ=="
|
||||
},
|
||||
"has-tostringtag": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz",
|
||||
"integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==",
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
|
||||
"integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
|
||||
"requires": {
|
||||
"has-symbols": "^1.0.2"
|
||||
"has-symbols": "^1.0.3"
|
||||
}
|
||||
},
|
||||
"hash-sum": {
|
||||
|
|
@ -29407,9 +29505,9 @@
|
|||
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
|
||||
},
|
||||
"js-yaml": {
|
||||
"version": "3.14.1",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
|
||||
"integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
|
||||
"version": "3.14.2",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz",
|
||||
"integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"argparse": "^1.0.7",
|
||||
|
|
@ -29975,6 +30073,11 @@
|
|||
"resolved": "https://registry.npmjs.org/marked/-/marked-15.0.4.tgz",
|
||||
"integrity": "sha512-TCHvDqmb3ZJ4PWG7VEGVgtefA5/euFmsIhxtD0XsBxI39gUSKL81mIRFdt0AiNQozUahd4ke98ZdirExd/vSEw=="
|
||||
},
|
||||
"math-intrinsics": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
|
||||
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="
|
||||
},
|
||||
"mdn-data": {
|
||||
"version": "2.0.30",
|
||||
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz",
|
||||
|
|
@ -30295,9 +30398,9 @@
|
|||
}
|
||||
},
|
||||
"node-forge": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz",
|
||||
"integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==",
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.2.tgz",
|
||||
"integrity": "sha512-6xKiQ+cph9KImrRh0VsjH2d8/GXA4FIMlgU4B757iI1ApvcyA9VlouP0yZJha01V+huImO+kKMU7ih+2+E14fw==",
|
||||
"dev": true
|
||||
},
|
||||
"node-int64": {
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
"dependencies": {
|
||||
"@d-i-t-a/reader": "github:gotson/R2D2BC#fork",
|
||||
"@saekitominaga/isbn-verify": "^2.0.1",
|
||||
"axios": "^1.8.2",
|
||||
"axios": "^1.12.0",
|
||||
"chart.js": "^2.9.4",
|
||||
"core-js": "^3.8.3",
|
||||
"date-fns": "^2.30.0",
|
||||
|
|
|
|||
|
|
@ -19,7 +19,15 @@
|
|||
},
|
||||
"account_settings": {
|
||||
"account_settings": "إعدادات الحساب",
|
||||
"change_password": "تغيير كلمة السر"
|
||||
"api_key": {
|
||||
"created_date": "تاريخ الصنع: {date}",
|
||||
"force_kobo_sync": "إجبار مزامنة Kobo",
|
||||
"generate_api_key": "توليد مفتاح API",
|
||||
"no_keys": "لم يخلق مفتاح API بعد"
|
||||
},
|
||||
"change_password": "تغيير كلمة السر",
|
||||
"details": "تفاصيل",
|
||||
"my_account": "حسابي"
|
||||
},
|
||||
"announcements": {
|
||||
"mark_all_read": "اشر عليها بانها قرأت",
|
||||
|
|
@ -27,6 +35,7 @@
|
|||
"tab_title": "إعلانات"
|
||||
},
|
||||
"authentication_activity": {
|
||||
"api_key": "مفتاح API",
|
||||
"datetime": "التاريخ والوقت",
|
||||
"email": "البريد الإلكتروني",
|
||||
"error": "خطأ",
|
||||
|
|
@ -85,7 +94,8 @@
|
|||
"bookreader": {
|
||||
"beginning_of_book": "أنت في بداية الكتاب.",
|
||||
"changing_reading_direction": "تغيير اتجاه القراءة إلى",
|
||||
"cycling_page_layout": "تخطيط دوري للصفحة",
|
||||
"cycling_page_layout": "تغيير تخطيط الصفحة",
|
||||
"cycling_page_margin": "تغيير هامش الصفحة",
|
||||
"cycling_scale": "تغيير حجم التحرير",
|
||||
"cycling_side_padding": "تغيير الحدود الجانبية",
|
||||
"download_current_page": "تنزيل الصفحة الحالية",
|
||||
|
|
@ -128,6 +138,7 @@
|
|||
"general": "إعدادات عامة",
|
||||
"gestures": "الإيماءات",
|
||||
"page_layout": "تخطيط الصفحة",
|
||||
"page_margin": "هامش الصفحة",
|
||||
"paged": "خيارات القارئ المرقم",
|
||||
"reading_mode": "وضع القراءة",
|
||||
"scale_type": "نوع القياس",
|
||||
|
|
@ -137,8 +148,9 @@
|
|||
},
|
||||
"shortcuts": {
|
||||
"close": "إغلاق",
|
||||
"cycle_page_layout": "دورة تخطيط الصفحة",
|
||||
"cycle_scale": "مقياس الدورة",
|
||||
"cycle_page_layout": "تغيير تخطيط الصفحة",
|
||||
"cycle_page_margin": "تغيير هامش الصفحة",
|
||||
"cycle_scale": "تغيير الحجم",
|
||||
"cycle_side_padding": "تغيير الحدود الجانبية",
|
||||
"first_page": "الصفحة الأولى",
|
||||
"fullscreen": "إدخال/إنهاء ملء الشاشة",
|
||||
|
|
@ -161,6 +173,8 @@
|
|||
},
|
||||
"browse_book": {
|
||||
"comment": "تعليق",
|
||||
"date_created": "صُنِع",
|
||||
"date_modified": "آخر تعديل",
|
||||
"download_file": "تحميل الملف",
|
||||
"file": "ملف",
|
||||
"format": "صيغة",
|
||||
|
|
@ -170,6 +184,8 @@
|
|||
"outdated_tooltip": "تم تغيير ملف هذا الكتاب ، يجب إعادة تحليل هذا الكتاب",
|
||||
"read_book": "قراءة كتاب",
|
||||
"read_incognito": "قراءة التصفح المتخفي",
|
||||
"remove_from_collection": "إزالة الكتاب من المجموعة",
|
||||
"remove_from_readlist": "إزالة الكتاب من قائمة القراءة",
|
||||
"size": "حجم"
|
||||
},
|
||||
"browse_collection": {
|
||||
|
|
@ -184,6 +200,7 @@
|
|||
},
|
||||
"browse_series": {
|
||||
"earliest_year_from_release_dates": "هذه هي السنة الأولى من تواريخ الإصدار لجميع الكتب في السلسلة",
|
||||
"remove_from_collection": "إزالة السلسلة من المجموعة",
|
||||
"series_no_summary": "هذه السلسلة لا تحتوي على ملخص ، لذلك اخترنا واحدًا لك!",
|
||||
"summary_from_book": "ملخص من الكتاب {number}:"
|
||||
},
|
||||
|
|
@ -194,6 +211,8 @@
|
|||
"common": {
|
||||
"age": "العمر",
|
||||
"all_libraries": "كل المكتبات",
|
||||
"all_of": "كل من",
|
||||
"any_of": "أي من",
|
||||
"book": "كتاب",
|
||||
"books": "كتب",
|
||||
"books_n": "لا يوجد كتاب | 1 كتاب | {count} كتب",
|
||||
|
|
@ -203,15 +222,19 @@
|
|||
"choose_image": "اختر صورة",
|
||||
"close": "إغلاق",
|
||||
"collections": "المجموعات",
|
||||
"copied": "تم النسخ!",
|
||||
"create": "صنع",
|
||||
"delete": "حذف",
|
||||
"discard": "تجاهل",
|
||||
"dimension": "ع:{width}, ط:{height}",
|
||||
"discard": "تخلص",
|
||||
"disk_space": "مساحة القرص",
|
||||
"dismiss": "رفض",
|
||||
"download": "تحميل",
|
||||
"drag_drop": "أمسك واسحب",
|
||||
"duplicate": "مكرر",
|
||||
"email": "البريد الإلكتروني",
|
||||
"epub": "Epub",
|
||||
"epub": "EPUB",
|
||||
"error": "خطأ",
|
||||
"filename": "اسم الملف",
|
||||
"filter_no_matches": "الفلتر النشط ليس له تطابق",
|
||||
"genre": "نوع",
|
||||
|
|
@ -219,13 +242,17 @@
|
|||
"go_to_library": "اذهب إلى المكتبة",
|
||||
"go_to_readlist": "انتقل إلى قائمة القراءة",
|
||||
"go_to_series": "الانتقال إلى السلسلة",
|
||||
"i_understand": "فهمت",
|
||||
"library": "مكتبة",
|
||||
"locale_name": "العربية",
|
||||
"locale_rtl": "true",
|
||||
"lock_all": "قفل الكل",
|
||||
"media": "الوسائط",
|
||||
"more": "المزيد",
|
||||
"n_selected": "{count} مختار",
|
||||
"nothing_to_show": "لا شيء للعرض",
|
||||
"oneshot": "طلقة واحدة",
|
||||
"ok": "حسنا",
|
||||
"oneshot": "قصة منفردة",
|
||||
"outdated": "متقادمة",
|
||||
"page": "صفحة",
|
||||
"page_number": "رقم الصفحة",
|
||||
|
|
@ -235,19 +262,23 @@
|
|||
"password": "كلمة السر",
|
||||
"pdf": "PDF",
|
||||
"pending_tasks": "لا توجد مهام معلقة | مهمة واحدة معلقة | {count} مهام معلقة",
|
||||
"pinned_libraries": "المكتبات المثبتة",
|
||||
"publisher": "الناشر",
|
||||
"read": "اقرأ",
|
||||
"read_on": "قرأ في {date}",
|
||||
"readlist": "قائمة القراءة",
|
||||
"readlists": "قوائم القراءة",
|
||||
"remember-me": "تذكرني",
|
||||
"reorder": "تغيير الترتيب",
|
||||
"required": "مطلوب",
|
||||
"reset_filters": "إعادة تعيين فلتر",
|
||||
"roles": "أدوار",
|
||||
"save_changes": "حفظ التغييرات",
|
||||
"series": "سلسلة",
|
||||
"settings": "الإعدادات",
|
||||
"sidecars": "Sidecars",
|
||||
"tags": "التصنيف",
|
||||
"ui": "واجهة المستخدم",
|
||||
"unavailable": "غير متوفر",
|
||||
"unlock_all": "فتح الكل",
|
||||
"url": "عنوان URL",
|
||||
|
|
@ -271,10 +302,11 @@
|
|||
"comicrack_preambule_html": "يمكنك استيراد قوائم قراءة ComicRack الحالية بتنسيق <code>cbl</code>.<br>سيحاول Komga مطابقة السلسلة ورقم الكتاب المقدمين مع السلسلة والكتب في مكتباتك.",
|
||||
"dialog_confirmation": {
|
||||
"body": "{unmatched} / {total} الكتب غير متطابقة",
|
||||
"body2": "{duplicates} / {total} كتاب مكرر",
|
||||
"create": "الخلق على أي حال",
|
||||
"title": "بعض الكتب لا تتطابق"
|
||||
},
|
||||
"field_file_label": "ComicRack Reading List (.cbl)",
|
||||
"field_file_label": "قائمة قراءة ComicRack (من نوع cbl.)",
|
||||
"field_files_label": "قوائم القراءة ComicRack (.cbl)",
|
||||
"import_read_lists": "استيراد قوائم القراءة",
|
||||
"imported_as": "مستورد كـ {name}",
|
||||
|
|
@ -286,6 +318,14 @@
|
|||
"tab_title": "استيراد البيانات"
|
||||
},
|
||||
"dialog": {
|
||||
"add_api_key": {
|
||||
"button_confirm": "توليد",
|
||||
"context": "يمكن استعمال مفاتيح الAPI للتوثيق عبر بروتوكول Kobo Sync.",
|
||||
"dialog_title": "توليد مفتاح API جديد",
|
||||
"field_comment": "تعليق",
|
||||
"field_comment_hint": "ما الغرض من مفتاح الAPI هذا؟",
|
||||
"info_copy": "يرجى التأكد من نسخ مفتاح الAPI الآن. لا يستطاع النظر عليه مجددا!"
|
||||
},
|
||||
"add_to_collection": {
|
||||
"button_create": "خلق",
|
||||
"card_collection_subtitle": "لا توجد سلسلة | 1 سلسلة | {count} سلسلة",
|
||||
|
|
@ -319,6 +359,12 @@
|
|||
"filter": "مصنف حسب رقم الكتاب أو العنوان أو تاريخ الإصدار",
|
||||
"title": "حدد كتاب"
|
||||
},
|
||||
"delete_apikey": {
|
||||
"button_confirm": "حذف",
|
||||
"confirm_delete": "فهمت, حذف مفتاح الAPI المسمى {name}",
|
||||
"dialog_title": "حذف مفتاح الAPI",
|
||||
"warning_html": "كل التطبيقات التي تستعمل مفتاح الAPI هذا ستصبح غير قادرة على الوصول إلى الAPI التابع لKomga. لا يمكن التراجع عن هذا الإجراء."
|
||||
},
|
||||
"delete_book": {
|
||||
"button_confirm": "حذف",
|
||||
"confirm_delete": "نعم، حذف كتاب \"{name}\" وملفاته",
|
||||
|
|
@ -389,6 +435,8 @@
|
|||
"field_summary": "ملخص",
|
||||
"field_tags": "التصنيف",
|
||||
"field_title": "العنوان",
|
||||
"number_sort_decrement": "تقليل الجميع ب1",
|
||||
"number_sort_increment": "زيادة الجميع ب1",
|
||||
"tab_authors": "المؤلفون",
|
||||
"tab_general": "إعدادات عامة",
|
||||
"tab_links": "الروابط",
|
||||
|
|
@ -415,6 +463,7 @@
|
|||
"dialot_title_edit": "تحرير المكتبة",
|
||||
"field_analysis_analyze_dimensions": "تحليل أبعاد الصفحات",
|
||||
"field_analysis_hash_files": "حساب تجزئة للملفات",
|
||||
"field_analysis_hash_koreader": "حسابة التلبيد لملفات KOReader",
|
||||
"field_analysis_hash_pages": "حساب تجزئة الصفحات",
|
||||
"field_convert_to_cbz": "تحويل تلقائيا إلى CBZ",
|
||||
"field_import_barcode_isbn": "الباركود ردمك",
|
||||
|
|
@ -422,15 +471,19 @@
|
|||
"field_import_comicinfo_collections": "المجموعات",
|
||||
"field_import_comicinfo_readlists": "قوائم القراءة",
|
||||
"field_import_comicinfo_series": "سلسلة البيانات الوصفية",
|
||||
"field_import_comicinfo_series_append_volume": "إضافة المجلد إلى عنوان المسلسل",
|
||||
"field_import_epub_book": "البيانات الوصفية للكتاب",
|
||||
"field_import_epub_series": "سلسلة البيانات الوصفية",
|
||||
"field_import_local_artwork": "الأعمال الفنية المحلية",
|
||||
"field_import_mylar_series": "سلسلة البيانات الوصفية",
|
||||
"field_name": "الاسم",
|
||||
"field_oneshotsdirectory": "موقع القصص المنفردة",
|
||||
"field_repair_extensions": "إصلاح ملحقات الملفات غير الصحيحة تلقائيًا",
|
||||
"field_root_folder": "المجلد الرئيسي",
|
||||
"field_scan_interval": "تكرار البحث عن الملفات",
|
||||
"field_scanner_empty_trash_after_scan": "تفريغ المهملات تلقائيا بعد كل فحص",
|
||||
"field_scanner_force_directory_modified_time": "فرض وقت تعديل الدليل",
|
||||
"field_scanner_scan_startup": "البحث عن الملفات عند بدء البرنامج",
|
||||
"field_series_cover": "غلاف السلسلة",
|
||||
"file_browser_dialog_button_confirm": "إختيار",
|
||||
"file_browser_dialog_title": "المجلد الجذر للمكتبة",
|
||||
|
|
@ -441,11 +494,14 @@
|
|||
"label_import_epub": "استيراد البيانات الوصفية من ملفات EPUB",
|
||||
"label_import_local": "استيراد أصول الوسائط المحلية",
|
||||
"label_import_mylar": "استيراد البيانات الوصفية التي تم إنشاؤها بواسطة Mylar",
|
||||
"label_scan_directory_exclusions": "استبعاد المواقع",
|
||||
"label_scan_types": "البحث عن أنواع الملفات هذه",
|
||||
"label_scanner": "الماسح الضوئي",
|
||||
"label_series_cover": "غلاف السلسلة",
|
||||
"tab_general": "إعدادات عامة",
|
||||
"tab_metadata": "البيانات الوصفية",
|
||||
"tab_options": "الخيارات",
|
||||
"tooltip_oneshotsdirectory": "يترك فارغا للتعطيل",
|
||||
"tooltip_scanner_force_modified_time": "تمكين إذا كانت المكتبة على Google Drive",
|
||||
"tooltip_use_resources": "يمكن أن تستهلك الكثير من الموارد في مكتبات كبيرة أو أجهزة بطيئة"
|
||||
},
|
||||
|
|
@ -453,11 +509,16 @@
|
|||
"button_cancel": "إلغاء",
|
||||
"button_confirm": "حفظ التغييرات",
|
||||
"dialog_title": "تحرير قائمة القراءة",
|
||||
"field_manual_ordering": "ترتيب يدوي",
|
||||
"field_name": "الاسم",
|
||||
"field_summary": "ملخص",
|
||||
"tab_general": "عام",
|
||||
"tab_poster": "ملصق"
|
||||
},
|
||||
"edit_recommended": {
|
||||
"button_confirm": "حفظ التعديلات",
|
||||
"button_reset": "الإعادة إلى التعديلات الأصلية"
|
||||
},
|
||||
"edit_series": {
|
||||
"button_cancel": "إلغاء",
|
||||
"button_confirm": "حفظ التغييرات",
|
||||
|
|
@ -483,6 +544,7 @@
|
|||
"tab_poster": "ملصق",
|
||||
"tab_sharing": "مشاركة",
|
||||
"tab_tags": "التصنيف",
|
||||
"tab_titles": "العناوين البديلة",
|
||||
"tags_notice_multiple_edit": "أنت تقوم بتحرير العلامات لسلسلة متعددة. سيؤدي هذا إلى تجاوز العلامات الموجودة في كل سلسلة."
|
||||
},
|
||||
"edit_user": {
|
||||
|
|
@ -525,6 +587,9 @@
|
|||
},
|
||||
"title": "اسم الوجهة"
|
||||
},
|
||||
"force_kobo_sync": {
|
||||
"dialog_title": "إجبار مزامنة Kobo"
|
||||
},
|
||||
"password_change": {
|
||||
"button_cancel": "إلغاء",
|
||||
"button_confirm": "تغيير كلمة السر",
|
||||
|
|
@ -541,6 +606,7 @@
|
|||
},
|
||||
"series_picker": {
|
||||
"label_search_series": "سلسلة البحث",
|
||||
"no_results": "لم يتم العثور على أي سلسلة",
|
||||
"title": "اختيار سلسلة"
|
||||
},
|
||||
"server_stop": {
|
||||
|
|
@ -579,21 +645,31 @@
|
|||
}
|
||||
},
|
||||
"duplicate_pages": {
|
||||
"action_auto_delete_remaining": "باق إلغاء {count} أوتوماتيكيا",
|
||||
"action_delete_auto": "حذف تلقائي",
|
||||
"action_delete_manual": "حذف يدوي",
|
||||
"action_delete_matches": "حذف المطابقات",
|
||||
"action_ignore": "تجاهل",
|
||||
"action_ignore_remaining": "تجاهل الباقي ({count})",
|
||||
"action_manual_delete_remaining": "إلغاء الباقي يدويا ({count})",
|
||||
"delete_to_save": "حذف لحفظ {size}",
|
||||
"deleted_count": "تم حذف {count} مرة",
|
||||
"empty_title": "لم يتم العثور على صفحات مكررة",
|
||||
"empty_title_known": "لا توجد نسخ مكررة معروف عنها",
|
||||
"filter": {
|
||||
"count": "عدد",
|
||||
"date_added": "تاريخ الإضافة",
|
||||
"date_modified": "تاريخ التعديل",
|
||||
"delete_count": "عدد الحذف",
|
||||
"delete_size": "المساحة المحفوظة",
|
||||
"match_count": "عدد النتائج المتطابقة",
|
||||
"size": "حجم",
|
||||
"total_size": "الحجم الإجمالي"
|
||||
},
|
||||
"info": "حذف الصفحات المكررة سيغيّر ملفاتك. احتفظ بنسخة احتياطية من ملفاتك واستخدم الحذف اليدوي قبل استخدام الحذف التلقائي.",
|
||||
"known": "المعروفة",
|
||||
"matches_n": "لا يوجد تطابق | 1 تطابق | {count} التطابق",
|
||||
"new": "الجديدة",
|
||||
"saved_size": "حُفظ {size}",
|
||||
"title": "صفحات مكررة",
|
||||
"unknown_size": "حجم مجهول"
|
||||
|
|
@ -609,6 +685,23 @@
|
|||
"HARDLINK": "ملفات الروابط الثابتة/النسخ",
|
||||
"MOVE": "نقل الملفات"
|
||||
},
|
||||
"epubreader": {
|
||||
"appearances": {
|
||||
"day": "النهار",
|
||||
"night": "الليل",
|
||||
"sepia": "سيبيا"
|
||||
},
|
||||
"column_count": {
|
||||
"auto": "أوتوماتيكي",
|
||||
"one": "واحد",
|
||||
"two": "اثنان"
|
||||
},
|
||||
"reading_direction": {
|
||||
"auto": "أوتوماتيكي",
|
||||
"ltr": "من اليسار إلى اليمين",
|
||||
"rtl": "من اليمين إلى اليسار"
|
||||
}
|
||||
},
|
||||
"historical_event_type": {
|
||||
"BookConverted": "تمّ تحويل الكتاب",
|
||||
"BookFileDeleted": "تمّ مسح ملف الكتاب",
|
||||
|
|
@ -616,6 +709,11 @@
|
|||
"DuplicatePageDeleted": "تمّ حذف الصفحة المكررة",
|
||||
"SeriesFolderDeleted": "تمّ حذف مجلد السلسلة"
|
||||
},
|
||||
"media_profile": {
|
||||
"DIVINA": "DIVINA",
|
||||
"EPUB": "EPUB",
|
||||
"PDF": "PDF"
|
||||
},
|
||||
"media_status": {
|
||||
"ERROR": "خطأ",
|
||||
"OUTDATED": "قديمه",
|
||||
|
|
@ -634,6 +732,14 @@
|
|||
"VERTICAL": "عمودي",
|
||||
"WEBTOON": "ويبتون"
|
||||
},
|
||||
"scan_interval": {
|
||||
"DAILY": "يوميا",
|
||||
"DISABLED": "معطل",
|
||||
"EVERY_12H": "كل 12 ساعة",
|
||||
"EVERY_6H": "كل 6 ساعات",
|
||||
"HOURLY": "كل ساعة",
|
||||
"WEEKLY": "كل أسبوع"
|
||||
},
|
||||
"series_cover": {
|
||||
"FIRST": "أول",
|
||||
"LAST": "أخير"
|
||||
|
|
@ -645,6 +751,34 @@
|
|||
"ONGOING": "مستمر"
|
||||
}
|
||||
},
|
||||
"epubreader": {
|
||||
"current_chapter": "الفصل الحالي",
|
||||
"page_of": "الصفحة {page} من {count}",
|
||||
"publisher_font": "الناشر",
|
||||
"settings": {
|
||||
"column_count": "عدد أعمدة",
|
||||
"font_family": "الخط",
|
||||
"layout": "تخطيط",
|
||||
"layout_scroll": "تمرير",
|
||||
"navigation_mode": "وضع التنقل",
|
||||
"navigation_options": {
|
||||
"both": "كلاهما",
|
||||
"buttons": "أزرار",
|
||||
"click": "نقر/ضغط"
|
||||
},
|
||||
"page_margins": "هوامش الصفحة"
|
||||
},
|
||||
"shortcuts": {
|
||||
"cycle_pagination": "تغيير عدد الأعمدة",
|
||||
"font_size_decrease": "تصغير الخط",
|
||||
"font_size_increase": "تكبير الخط",
|
||||
"menus": "القائمات",
|
||||
"next": "أمام",
|
||||
"previous": "خلف",
|
||||
"settings": "الإعدادات",
|
||||
"show_hide_toc": "إظهار/إخفاء الفهرس"
|
||||
}
|
||||
},
|
||||
"error_codes": {
|
||||
"ERR_1000": "تعذر الوصول إلى الملف أثناء التحليل",
|
||||
"ERR_1001": "نوع الوسائط غير مدعوم",
|
||||
|
|
@ -667,11 +801,13 @@
|
|||
"filter": {
|
||||
"age_rating": "التصنيف العمري",
|
||||
"age_rating_none": "لا شيء",
|
||||
"any": "أي",
|
||||
"complete": "اكتمل",
|
||||
"genre": "نوع",
|
||||
"in_progress": "قيد التقدم",
|
||||
"language": "اللغة",
|
||||
"library": "المكتبة",
|
||||
"oneshot": "قصة منفردة",
|
||||
"publisher": "الناشر",
|
||||
"read": "اقرأ",
|
||||
"release_date": "تاريخ الاصدار",
|
||||
|
|
@ -699,6 +835,8 @@
|
|||
},
|
||||
"library_navigation": {
|
||||
"browse": "تصفّح",
|
||||
"browse_books": "كتب",
|
||||
"browse_series": "سلسلات",
|
||||
"collections": "المجموعات",
|
||||
"readlists": "قوائم القراءة",
|
||||
"recommended": "موصى به"
|
||||
|
|
@ -730,6 +868,7 @@
|
|||
"empty_trash": "إفراغ سلة المهملات",
|
||||
"mark_read": "تحديد كمقروء",
|
||||
"mark_unread": "تحديد كغير مقروء",
|
||||
"pin": "تثبيت",
|
||||
"refresh_metadata": "تحديث البيانات الوصفية",
|
||||
"scan_library_files": "فحص ملفات المكتبة",
|
||||
"select_all": "تحديد الكل"
|
||||
|
|
@ -745,6 +884,9 @@
|
|||
"libraries": "المكتبات",
|
||||
"logout": "تسجيل الخروج"
|
||||
},
|
||||
"no_libraries_pinned": {
|
||||
"title": "لا مكتبات مثبتة"
|
||||
},
|
||||
"page_not_found": {
|
||||
"go_back_to_home_page": "العودة إلى الصفحة الرئيسية",
|
||||
"page_does_not_exist": "الصفحة التي تبحث عنها غير موجودة.",
|
||||
|
|
@ -754,6 +896,12 @@
|
|||
"less": "أقرأ أقل",
|
||||
"more": "اقرأ أكثر"
|
||||
},
|
||||
"readlist_import": {
|
||||
"row": {
|
||||
"duplicate_book": "كتاب مكرر",
|
||||
"error_choose_book": "اختيار كتاب"
|
||||
}
|
||||
},
|
||||
"readlists_expansion_panel": {
|
||||
"manage_readlist": "إدارة قائمة القراءة",
|
||||
"title": "{name} قائمة القراءة"
|
||||
|
|
@ -775,12 +923,21 @@
|
|||
"button_empty_trash": "إفراغ سلة المهملات لكل المكتبات",
|
||||
"button_scan_libraries": "مسح جميع المكتبات",
|
||||
"button_shutdown": "إيقاف التشغيل",
|
||||
"download_log": "تحميل ملف السجل",
|
||||
"notification_tasks_cancelled": "لا يوجد مهام لإلغائها | تمّ إلغاء 1 مهمة | تمّ إلغاء {count} مهمة",
|
||||
"section_title": "إدارة الخادم"
|
||||
},
|
||||
"tab_title": "خادم"
|
||||
"tab_title": "خادم",
|
||||
"updates": "تحديثات"
|
||||
},
|
||||
"server_settings": {
|
||||
"dialog_regenerate_thumbnails": {
|
||||
"btn_alternate": "نعم، جميع الكتب",
|
||||
"btn_cancel": "لا",
|
||||
"btn_confirm": "نعم، لكن فقط إن كانت اكبر"
|
||||
},
|
||||
"label_kobo_port": "باب مزامنة Kobo الخارجي",
|
||||
"label_server_port": "باب الخادم",
|
||||
"server_settings": "إعدادات الخادم"
|
||||
},
|
||||
"settings_user": {
|
||||
|
|
@ -795,12 +952,15 @@
|
|||
"sort": {
|
||||
"books_count": "عدد الكتب",
|
||||
"date_added": "تاريخ الإضافة",
|
||||
"date_read": "تاريخ القراءة",
|
||||
"date_updated": "تاريخ التحديث",
|
||||
"file_name": "اسم الملف",
|
||||
"file_size": "حجم الملف",
|
||||
"folder_name": "اسم المجلد",
|
||||
"name": "الاسم",
|
||||
"number": "رقم",
|
||||
"page_count": "عدد الصفحات",
|
||||
"random": "عشوائي",
|
||||
"release_date": "تاريخ الإصدار"
|
||||
},
|
||||
"theme": {
|
||||
|
|
@ -818,16 +978,36 @@
|
|||
"tooltip_too_big": "الملف كبير جدًا!",
|
||||
"tooltip_user_uploaded": "تمّ الرفع بواسطة المستخدم"
|
||||
},
|
||||
"titles_more": {
|
||||
"less": "عناوين أقل",
|
||||
"more": "عناوين أكثر"
|
||||
},
|
||||
"ui_settings": {
|
||||
"general": "عام",
|
||||
"section_oauth2": "OAuth2",
|
||||
"series_groups": {
|
||||
"alpha": "ابجدي",
|
||||
"japanese": "غوجون (ياباني)"
|
||||
}
|
||||
},
|
||||
"updates": {
|
||||
"available": "توجد تحديثات"
|
||||
},
|
||||
"user_roles": {
|
||||
"ADMIN": "مدير",
|
||||
"FILE_DOWNLOAD": "تحميل الملف",
|
||||
"PAGE_STREAMING": "صفحات البث",
|
||||
"KOBO_SYNC": "مزامنة Kobo",
|
||||
"KOREADER_SYNC": "مزامنة KOReader",
|
||||
"PAGE_STREAMING": "بث الصفحات",
|
||||
"USER": "مستخدم"
|
||||
},
|
||||
"users": {
|
||||
"api_keys": "مفاتيح الAPI",
|
||||
"users": "المستخدمين"
|
||||
},
|
||||
"validation": {
|
||||
"one_or_more": "يجب أن يكون 1 أو أكثر",
|
||||
"tcp_port": "يجب أن يكون بين 1 و 65535",
|
||||
"zero_or_more": "يجب أن يكون 0 أو أكثر"
|
||||
},
|
||||
"welcome": {
|
||||
|
|
|
|||
|
|
@ -827,7 +827,12 @@
|
|||
"ERR_1031": "V ComicRack CBL Book chybí série nebo číslo",
|
||||
"ERR_1032": "Soubor EPUB má chybný typ média",
|
||||
"ERR_1033": "Některé položky chybí",
|
||||
"ERR_1034": "API key s touto poznámkou již existuje"
|
||||
"ERR_1034": "API key s touto poznámkou již existuje",
|
||||
"ERR_1035": "Chyba při získávání obsahu EPUB",
|
||||
"ERR_1036": "Chyba při získávání záložek EPUB",
|
||||
"ERR_1037": "CHyba při získávání seznamu stran EPUB",
|
||||
"ERR_1038": "Chyba při získávání stran EPUB Divina",
|
||||
"ERR_1039": "Chyba při získávání pozic EPUB"
|
||||
},
|
||||
"filter": {
|
||||
"age_rating": "Věkové hodnocení",
|
||||
|
|
|
|||
|
|
@ -19,7 +19,15 @@
|
|||
},
|
||||
"account_settings": {
|
||||
"account_settings": "Configuración da conta",
|
||||
"change_password": "Cambiar o contrasinal"
|
||||
"api_key": {
|
||||
"created_date": "Data de creación: {date}",
|
||||
"force_kobo_sync": "Forzar a sincronización con Kobo",
|
||||
"generate_api_key": "Xerar clave API",
|
||||
"no_keys": "Aínda non se xerou clave API ningunha"
|
||||
},
|
||||
"change_password": "Cambiar o contrasinal",
|
||||
"details": "Detalles",
|
||||
"my_account": "A miña conta"
|
||||
},
|
||||
"announcements": {
|
||||
"mark_all_read": "Marcar todo como lido",
|
||||
|
|
@ -27,6 +35,7 @@
|
|||
"tab_title": "Avisos"
|
||||
},
|
||||
"authentication_activity": {
|
||||
"api_key": "Clave API",
|
||||
"datetime": "Data e Hora",
|
||||
"email": "Correo electrónico",
|
||||
"error": "Erro",
|
||||
|
|
@ -58,9 +67,159 @@
|
|||
"button_scan": "Escanear",
|
||||
"button_select_series": "Escolle a serie",
|
||||
"field_import_path": "Importar dende un cartafol",
|
||||
"info_part1": "Esta pantalla permitiralle importar arquivos que están fóra das súas bibliotecas existentes. Só pódese importar arquivos a series que xa existan, nese caso Komga moverá ou copiará os arquivos cara o directorio da serie escollida."
|
||||
"info_part1": "Esta pantalla permitiralle importar arquivos que están fóra das súas bibliotecas existentes. Só pódese importar arquivos a series que xa existan, nese caso Komga moverá ou copiará os arquivos cara o directorio da serie escollida.",
|
||||
"info_part2": "Se escolles un número para un libro e existe xa algún outro libro con ese número, poderás comparalos. Se decides importar o libro, Komga actualizará o existente co novo, substituindo o ficheiro existente co novo.",
|
||||
"no_files_found": "Non se atoparon ficheiros",
|
||||
"notification": {
|
||||
"go_to_book": "Ir ao libro",
|
||||
"import_failure": "Fallou a importación do libro: {file}",
|
||||
"import_successful": "Libro importado con éxito: {book}",
|
||||
"source_file": "Ficheiro orixe: {file}"
|
||||
},
|
||||
"row": {
|
||||
"error_analyze_first": "É necesario analizar antes o libro",
|
||||
"error_choose_series": "Escoller serie",
|
||||
"error_only_import_no_errors": "Só se poden importar libros sen erros",
|
||||
"warning_upgrade": "Actualizarase o libro existente"
|
||||
},
|
||||
"table": {
|
||||
"destination_name": "Nome de destino",
|
||||
"file_name": "Nome do ficheiro",
|
||||
"number": "Número",
|
||||
"series": "Serie"
|
||||
},
|
||||
"title": "Importar",
|
||||
"try_another_directory": "Tenta atopar outro directorio"
|
||||
},
|
||||
"bookreader": {
|
||||
"beginning_of_book": "Atópaste ao principio do libro.",
|
||||
"changing_reading_direction": "Trocar o sentido de lectura a",
|
||||
"download_current_page": "Baixar a páxina actual",
|
||||
"end_of_book": "Chegaches ao final do libro.",
|
||||
"from_series_metadata": "dende os metadatos da serie",
|
||||
"move_next": "Volve pulsar \"Seguinte\" para pasar ao seguinte libro.",
|
||||
"move_next_exit": "Volve pulser \"Seguinte\" para saír do lector.",
|
||||
"move_previous": "Volve pulsar \"Anterior\" para pasar ao libro anterior.",
|
||||
"notification_poster_set_book": "A portada do libro estableceuse á páxina actual.",
|
||||
"notification_poster_set_readlist": "A portada da lista de lectura estableceuse á páxina actual.",
|
||||
"notification_poster_set_series": "A portada de serie estableceuse á páxina actual.",
|
||||
"paged_reader_layout": {
|
||||
"double": "Dobre páxina",
|
||||
"double_no_cover": "Dobre páxina (sen portada)",
|
||||
"single": "Páxina simple"
|
||||
},
|
||||
"reader_settings": "Configuración do lector",
|
||||
"scale_type": {
|
||||
"continuous_original": "Orixinal",
|
||||
"continuous_width": "Axuste á anchura",
|
||||
"height": "Axuste á altura",
|
||||
"original": "Orixinal",
|
||||
"screen": "Pantalla"
|
||||
},
|
||||
"settings": {
|
||||
"always_fullscreen": "Sempre a pantalla completa",
|
||||
"animate_page_transitions": "Transicións de páxina animadas",
|
||||
"background_color": "Cor de fondo",
|
||||
"background_colors": {
|
||||
"black": "Negro",
|
||||
"gray": "Gris",
|
||||
"white": "Branco"
|
||||
},
|
||||
"general": "Xeral",
|
||||
"gestures": "Xestos",
|
||||
"page_layout": "Disposición de páxina",
|
||||
"page_margin": "Marxe de páxina",
|
||||
"reading_mode": "Modo de lectura",
|
||||
"side_padding_none": "Ningún"
|
||||
},
|
||||
"shortcuts": {
|
||||
"close": "Pechar",
|
||||
"first_page": "Primeira páxina",
|
||||
"last_page": "Derradeira páxina",
|
||||
"left_to_right": "De esquerda a dereita",
|
||||
"menus": "Menús",
|
||||
"next_page": "Seguinte páxina",
|
||||
"previous_page": "Páxina anterior",
|
||||
"right_to_left": "De dereita a esquerda"
|
||||
},
|
||||
"tooltip_incognito": "Non se gardará o progreso de lectura"
|
||||
},
|
||||
"browse_book": {
|
||||
"comment": "COMENTARIO",
|
||||
"date_created": "CREACIÓN",
|
||||
"date_modified": "ÚLTIMA MODIFICACIÓN",
|
||||
"download_file": "Baixar ficheiro",
|
||||
"file": "FICHEIRO",
|
||||
"format": "FORMATO",
|
||||
"isbn": "ISBN",
|
||||
"links": "LIGAZÓNS",
|
||||
"outdated_tooltip": "Cambiouse o ficheiro deste libro; é necesario volver analizalo",
|
||||
"read_book": "Ler libro",
|
||||
"read_incognito": "Ler de incógnito",
|
||||
"remove_from_collection": "Quitar libro da colección",
|
||||
"remove_from_readlist": "Quitar libro da lista de lectura",
|
||||
"size": "TAMAÑO"
|
||||
},
|
||||
"browse_collection": {
|
||||
"edit_collection": "Editar colección",
|
||||
"edit_elements": "Editar elementos",
|
||||
"manual_ordering": "Ordenación manual"
|
||||
},
|
||||
"browse_readlist": {
|
||||
"edit_elements": "Editar elementos",
|
||||
"edit_readlist": "Editar lista de lectura",
|
||||
"manual_ordering": "Ordenación manual"
|
||||
},
|
||||
"browse_series": {
|
||||
"earliest_year_from_release_dates": "Este é o ano máis temperán entre as datas de lanzamento de tódolos libros da serie",
|
||||
"remove_from_collection": "Quitar serie da colección",
|
||||
"series_no_summary": "Esta serie non ten sumario, así que escollemos un por ti!",
|
||||
"summary_from_book": "Sumario do libro {number}:"
|
||||
},
|
||||
"collections_expansion_panel": {
|
||||
"manage_collection": "Xestionar colección",
|
||||
"title": "{name} colección"
|
||||
},
|
||||
"common": {
|
||||
"locale_name": "Galego"
|
||||
"age": "Idade",
|
||||
"all_libraries": "Tódalas bibliotecas",
|
||||
"all_of": "Todo",
|
||||
"any_of": "Calquera",
|
||||
"book": "Libro",
|
||||
"books": "Libros",
|
||||
"books_n": "Ningún libro | 1 libro | {count} libros",
|
||||
"books_total": "{count} / {total} libros",
|
||||
"cancel": "Cancelar",
|
||||
"choose_image": "Escoller unha imaxe",
|
||||
"close": "Pechar",
|
||||
"collections": "Coleccións",
|
||||
"copied": "Copiado!",
|
||||
"create": "Crear",
|
||||
"delete": "Borrar",
|
||||
"discard": "Descartar",
|
||||
"disk_space": "Espazo en disco",
|
||||
"download": "Baixar",
|
||||
"duplicate": "Duplicar",
|
||||
"epub": "EPUB",
|
||||
"error": "Erro",
|
||||
"filename": "Nome de ficheiro",
|
||||
"genre": "Xénero",
|
||||
"go_to_collection": "Ir á colección",
|
||||
"go_to_library": "Ir á biblioteca",
|
||||
"go_to_readlist": "Ir á lista de lectura",
|
||||
"go_to_series": "Ir á serie",
|
||||
"i_understand": "Entendido",
|
||||
"library": "Biblioteca",
|
||||
"locale_name": "Galego",
|
||||
"more": "Máis",
|
||||
"nothing_to_show": "Nada que amosar",
|
||||
"page": "Páxina",
|
||||
"page_number": "Número de páxina",
|
||||
"pages": "páxinas",
|
||||
"pages_left": "Non quedan páxinas | Queda 1 páxina | Quedan {count} páxinas",
|
||||
"pages_n": "Ningunha páxina | 1 páxina | {count} páxinas",
|
||||
"password": "Contrasinal",
|
||||
"pdf": "PDF",
|
||||
"pending_tasks": "Sen tarefas pendentes | 1 tarefa pendente | {count} tarefas pendentes"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@
|
|||
},
|
||||
"author_roles": {
|
||||
"colorist": "koloristi",
|
||||
"cover": "omot",
|
||||
"cover": "naslovnica",
|
||||
"editor": "urednici",
|
||||
"inker": "bojitelj",
|
||||
"letterer": "tipografi",
|
||||
|
|
@ -109,7 +109,7 @@
|
|||
"notification_poster_set_series": "Trenutačna stranica je sada postavljena kao poster serije.",
|
||||
"paged_reader_layout": {
|
||||
"double": "Dvije stranice",
|
||||
"double_no_cover": "Dvije stranice (bez omota)",
|
||||
"double_no_cover": "Dvije stranice (bez naslovnice)",
|
||||
"single": "Jedna stranica"
|
||||
},
|
||||
"reader_settings": "Postavke čitača",
|
||||
|
|
@ -138,7 +138,7 @@
|
|||
"general": "Općenito",
|
||||
"gestures": "Geste",
|
||||
"page_layout": "Raspored stranica",
|
||||
"page_margin": "Margine stranica",
|
||||
"page_margin": "Margina stranice",
|
||||
"paged": "Postavke prikaza stranica",
|
||||
"reading_mode": "Modus čitanja",
|
||||
"scale_type": "Vrsta skaliranja",
|
||||
|
|
@ -484,7 +484,7 @@
|
|||
"field_scanner_empty_trash_after_scan": "Automatski isprazni smeće nakon svakog pretraživanja",
|
||||
"field_scanner_force_directory_modified_time": "Pretraži mape na osnovi vremena promjene",
|
||||
"field_scanner_scan_startup": "Pretraži tijekom pokretanja",
|
||||
"field_series_cover": "Omot serije",
|
||||
"field_series_cover": "Naslovnica serije",
|
||||
"file_browser_dialog_button_confirm": "Odaberi",
|
||||
"file_browser_dialog_title": "Osnovna mapa biblioteke",
|
||||
"label_analysis": "Analiza",
|
||||
|
|
@ -497,7 +497,7 @@
|
|||
"label_scan_directory_exclusions": "Isključivanja mapa",
|
||||
"label_scan_types": "Traži ove vrste datoteka",
|
||||
"label_scanner": "Tražilica",
|
||||
"label_series_cover": "Omot serije",
|
||||
"label_series_cover": "Naslovnica serije",
|
||||
"tab_general": "Općenito",
|
||||
"tab_metadata": "Metapodaci",
|
||||
"tab_options": "Opcije",
|
||||
|
|
@ -780,7 +780,7 @@
|
|||
"buttons": "Gumbovi",
|
||||
"click": "Pritisni / Dodirni"
|
||||
},
|
||||
"page_margins": "Margine stranica",
|
||||
"page_margins": "Margine stranice",
|
||||
"viewing_theme": "Tema prikaza"
|
||||
},
|
||||
"shortcuts": {
|
||||
|
|
@ -827,7 +827,12 @@
|
|||
"ERR_1031": "ComicRack CBL knjizi nedostaje serija ili broj",
|
||||
"ERR_1032": "EPUB datoteka sadrži neispravnu vrstu medija",
|
||||
"ERR_1033": "Neki unosi nedostaju",
|
||||
"ERR_1034": "API ključ s tim komentarom već postoji"
|
||||
"ERR_1034": "API ključ s tim komentarom već postoji",
|
||||
"ERR_1035": "Greška prilikom dohvaćanja tablice sadržaja EPUB-a",
|
||||
"ERR_1036": "Greška prilikom dohvaćanja straničnika EPUB-a",
|
||||
"ERR_1037": "Greška prilikom dohvaćanja popisa stranica EPUB-a",
|
||||
"ERR_1038": "Greška prilikom dohvaćanja divina stranica EPUB-a",
|
||||
"ERR_1039": "Greška prilikom dohvaćanja pozicija EPUB-a"
|
||||
},
|
||||
"filter": {
|
||||
"age_rating": "dobna kategorija",
|
||||
|
|
@ -984,7 +989,7 @@
|
|||
"btn_confirm": "Da, ali samo ako su veće",
|
||||
"title": "Nanovo generiraj minijature"
|
||||
},
|
||||
"hint_kobo_port": "Postavi samo u slučaju problema sa sinkronizacijom omota i preuzimanja",
|
||||
"hint_kobo_port": "Postavi samo u slučaju problema sa sinkronizacijom naslovnica i preuzimanja",
|
||||
"label_delete_empty_collections": "Izbriši prazne zbirke nakon pretraživanja",
|
||||
"label_delete_empty_readlists": "Izbriši prazne liste čitanja nakon pretraživanja",
|
||||
"label_kepubify_path": "Staza do kepubify",
|
||||
|
|
|
|||
|
|
@ -19,7 +19,15 @@
|
|||
},
|
||||
"account_settings": {
|
||||
"account_settings": "Configurações de conta",
|
||||
"change_password": "alterar senha"
|
||||
"api_key": {
|
||||
"created_date": "Data de criação: {date}",
|
||||
"force_kobo_sync": "Forçar sincronização com Kobo",
|
||||
"generate_api_key": "Gerar chave de API",
|
||||
"no_keys": "Nenhuma Chave de API foi criada"
|
||||
},
|
||||
"change_password": "alterar senha",
|
||||
"details": "Detalhes",
|
||||
"my_account": "Minha conta"
|
||||
},
|
||||
"announcements": {
|
||||
"mark_all_read": "Marque todos como lido",
|
||||
|
|
@ -27,6 +35,7 @@
|
|||
"tab_title": "Anúncios"
|
||||
},
|
||||
"authentication_activity": {
|
||||
"api_key": "Chave de API",
|
||||
"datetime": "Data e Hora",
|
||||
"email": "E-mail",
|
||||
"error": "Erro",
|
||||
|
|
@ -86,6 +95,7 @@
|
|||
"beginning_of_book": "Você está no inicio do livro.",
|
||||
"changing_reading_direction": "Mudar Direção de Leitura para",
|
||||
"cycling_page_layout": "Alterando Layout de Página",
|
||||
"cycling_page_margin": "Alterando Margem de Página",
|
||||
"cycling_scale": "Alterando Escala",
|
||||
"cycling_side_padding": "Alterando Preenchimento Lateral",
|
||||
"download_current_page": "Baixar a pagina atual",
|
||||
|
|
@ -128,6 +138,7 @@
|
|||
"general": "Geral",
|
||||
"gestures": "Gestos",
|
||||
"page_layout": "Layout de página",
|
||||
"page_margin": "Margem de página",
|
||||
"paged": "Opções do Reader paginado",
|
||||
"reading_mode": "Modo de leitura",
|
||||
"scale_type": "Tipo de escala",
|
||||
|
|
@ -138,6 +149,7 @@
|
|||
"shortcuts": {
|
||||
"close": "Fechar",
|
||||
"cycle_page_layout": "Alterar layout de página",
|
||||
"cycle_page_margin": "Alterar margem de página",
|
||||
"cycle_scale": "Alterar escala",
|
||||
"cycle_side_padding": "Alterar preenchimento lateral",
|
||||
"first_page": "Primeira página",
|
||||
|
|
@ -161,6 +173,8 @@
|
|||
},
|
||||
"browse_book": {
|
||||
"comment": "COMENTÁRIO",
|
||||
"date_created": "CRIADO",
|
||||
"date_modified": "MODIFICADO POR ÚLTIMO",
|
||||
"download_file": "Baixar arquivo",
|
||||
"file": "ARQUIVO",
|
||||
"format": "FORMATO",
|
||||
|
|
@ -170,6 +184,8 @@
|
|||
"outdated_tooltip": "O arquivo para este livro foi alterado, este livro deve ser reanalisado",
|
||||
"read_book": "Ler livro",
|
||||
"read_incognito": "Ler incógnito",
|
||||
"remove_from_collection": "Remover livro da coleção",
|
||||
"remove_from_readlist": "Remover livro da lista de leitura",
|
||||
"size": "TAMANHO"
|
||||
},
|
||||
"browse_collection": {
|
||||
|
|
@ -184,6 +200,7 @@
|
|||
},
|
||||
"browse_series": {
|
||||
"earliest_year_from_release_dates": "Este é o ano mais antigo dentre as datas de lançamento de todos os livros na série",
|
||||
"remove_from_collection": "Remover série da coleção",
|
||||
"series_no_summary": "Esta série não contém um resumo, então escolhemos um para você!",
|
||||
"summary_from_book": "Resumo do livro {number}:"
|
||||
},
|
||||
|
|
@ -194,6 +211,8 @@
|
|||
"common": {
|
||||
"age": "Idade",
|
||||
"all_libraries": "Todas as bibliotecas",
|
||||
"all_of": "Todos",
|
||||
"any_of": "Qualquer",
|
||||
"book": "Livro",
|
||||
"books": "Livros",
|
||||
"books_n": "Nenhum livro | 1 livro | {count} livros",
|
||||
|
|
@ -203,6 +222,7 @@
|
|||
"choose_image": "Escolher uma imagem",
|
||||
"close": "Fechar",
|
||||
"collections": "Coleções",
|
||||
"copied": "Copiado!",
|
||||
"create": "Criar",
|
||||
"delete": "Excluir",
|
||||
"dimension": "l: {width}, a:{height}",
|
||||
|
|
@ -211,8 +231,10 @@
|
|||
"dismiss": "Ignorar",
|
||||
"download": "Baixar",
|
||||
"drag_drop": "Arrastar e soltar",
|
||||
"duplicate": "Duplicado",
|
||||
"email": "Email",
|
||||
"epub": "Epub",
|
||||
"error": "Erro",
|
||||
"filename": "Nome do arquivo",
|
||||
"filter_no_matches": "O filtro ativo não contém correspondências",
|
||||
"genre": "Gênero",
|
||||
|
|
@ -220,12 +242,17 @@
|
|||
"go_to_library": "Ir para biblioteca",
|
||||
"go_to_readlist": "Ir para lista de lidos",
|
||||
"go_to_series": "Ir para séries",
|
||||
"i_understand": "Eu compreendo",
|
||||
"library": "Biblioteca",
|
||||
"locale_name": "Português (Brasil)",
|
||||
"locale_rtl": "false",
|
||||
"lock_all": "Bloquear todos",
|
||||
"media": "Mídia",
|
||||
"more": "Mais",
|
||||
"n_selected": "{count} selecionados",
|
||||
"nothing_to_show": "Nada para exibir",
|
||||
"ok": "OK",
|
||||
"oneshot": "One-shot",
|
||||
"outdated": "Desatualizado",
|
||||
"page": "Página",
|
||||
"page_number": "Número da página",
|
||||
|
|
@ -235,19 +262,23 @@
|
|||
"password": "Senha",
|
||||
"pdf": "PDF",
|
||||
"pending_tasks": "Nenhuma tarefa pendente | 1 tarefa pendente | {count} tarefas pendentes",
|
||||
"pinned_libraries": "Bibliotecas Fixadas",
|
||||
"publisher": "Editora",
|
||||
"read": "Ler",
|
||||
"read_on": "Lido em {date}",
|
||||
"readlist": "Lista de Leitura",
|
||||
"readlists": "Listas de Leitura",
|
||||
"remember-me": "Me lembre",
|
||||
"reorder": "Reordernar",
|
||||
"required": "Obrigatório",
|
||||
"reset_filters": "Redefinir filtros",
|
||||
"roles": "Funções",
|
||||
"save_changes": "Salvar mudanças",
|
||||
"series": "Séries | Séries",
|
||||
"settings": "Configurações",
|
||||
"sidecars": "Carrinho",
|
||||
"tags": "Tags",
|
||||
"ui": "Interface de Usuário",
|
||||
"unavailable": "Indisponível",
|
||||
"unlock_all": "Desbloquear tudo",
|
||||
"url": "URL",
|
||||
|
|
@ -271,6 +302,7 @@
|
|||
"comicrack_preambule_html": "Você pode importar Listas de Leitura do ComicRack existentes no formato <code>.cbl</code><br>Komga tentará combinar a série fornecida e o número do livro com as séries e livros em suas bibliotecas.",
|
||||
"dialog_confirmation": {
|
||||
"body": "{unmatched} / {total} livro(s) não foram marcados",
|
||||
"body2": "{duplicates} / {total} livros são duplicados",
|
||||
"create": "Criar de todo modo",
|
||||
"title": "Alguns livros não estão combinados"
|
||||
},
|
||||
|
|
@ -286,6 +318,14 @@
|
|||
"tab_title": "Importação de Dados"
|
||||
},
|
||||
"dialog": {
|
||||
"add_api_key": {
|
||||
"button_confirm": "Gerar",
|
||||
"context": "Chaves API podem ser usadas para autenticar no protocolo Kobo Sync.",
|
||||
"dialog_title": "Gerar chave de API",
|
||||
"field_comment": "Comentar",
|
||||
"field_comment_hint": "Como a chave API será usada?",
|
||||
"info_copy": "Tenha a certeza de que a chave API foi salva. Você não poderá vê-la novamente!"
|
||||
},
|
||||
"add_to_collection": {
|
||||
"button_create": "Criar",
|
||||
"card_collection_subtitle": "Nenhuma série | 1 série | {count} série",
|
||||
|
|
@ -319,6 +359,12 @@
|
|||
"filter": "Filtrar por número, título ou data de lançamento",
|
||||
"title": "Selecionar livro"
|
||||
},
|
||||
"delete_apikey": {
|
||||
"button_confirm": "Excluir",
|
||||
"confirm_delete": "Eu entendo, exclua a chave API \"{name}\"",
|
||||
"dialog_title": "Deletar chave API",
|
||||
"warning_html": "Quaisquer aplicativos ou scripts que utilizem esta chave API não poderão mais acessar a API Komga. Você não poderá desfazer esta ação."
|
||||
},
|
||||
"delete_book": {
|
||||
"button_confirm": "Excluir",
|
||||
"confirm_delete": "Sim, exclua o livro \"{name}\" e seus arquivos",
|
||||
|
|
@ -468,6 +514,9 @@
|
|||
"tab_general": "Geral",
|
||||
"tab_poster": "Pôster"
|
||||
},
|
||||
"edit_recommended": {
|
||||
"button_confirm": "Salvar mudanças"
|
||||
},
|
||||
"edit_series": {
|
||||
"button_cancel": "Cancelar",
|
||||
"button_confirm": "Salvar mudanças",
|
||||
|
|
@ -536,6 +585,9 @@
|
|||
},
|
||||
"title": "Nome do Arquivo de Destino"
|
||||
},
|
||||
"force_kobo_sync": {
|
||||
"dialog_title": "Forçar sincronização com Kobo"
|
||||
},
|
||||
"password_change": {
|
||||
"button_cancel": "Cancelar",
|
||||
"button_confirm": "Mudar senha",
|
||||
|
|
@ -603,6 +655,9 @@
|
|||
"HARDLINK": "Hardlink/Copiar arquivos",
|
||||
"MOVE": "Mover Arquivos"
|
||||
},
|
||||
"media_profile": {
|
||||
"PDF": "PDF"
|
||||
},
|
||||
"media_status": {
|
||||
"ERROR": "Erro",
|
||||
"OUTDATED": "Desatualizado",
|
||||
|
|
@ -629,6 +684,14 @@
|
|||
"ONGOING": "Em andamento"
|
||||
}
|
||||
},
|
||||
"epubreader": {
|
||||
"settings": {
|
||||
"page_margins": "Margem de Páginas"
|
||||
},
|
||||
"shortcuts": {
|
||||
"settings": "Configurações"
|
||||
}
|
||||
},
|
||||
"error_codes": {
|
||||
"ERR_1000": "O arquivo não pôde ser acessado durante a análise",
|
||||
"ERR_1001": "O tipo de mídia não é compatível",
|
||||
|
|
@ -660,6 +723,7 @@
|
|||
"in_progress": "Em progresso",
|
||||
"language": "idioma",
|
||||
"library": "biblioteca",
|
||||
"oneshot": "One-shot",
|
||||
"publisher": "editora",
|
||||
"read": "Lidos",
|
||||
"release_date": "data de lançamento",
|
||||
|
|
@ -673,7 +737,8 @@
|
|||
},
|
||||
"history": {
|
||||
"header": {
|
||||
"book": "Livro"
|
||||
"book": "Livro",
|
||||
"details": "Detalhes"
|
||||
}
|
||||
},
|
||||
"home": {
|
||||
|
|
@ -795,6 +860,9 @@
|
|||
"tooltip_too_big": "Arquivo muito grande!",
|
||||
"tooltip_user_uploaded": "Enviado pelo usuário"
|
||||
},
|
||||
"ui_settings": {
|
||||
"general": "Geral"
|
||||
},
|
||||
"user_roles": {
|
||||
"ADMIN": "Administrador",
|
||||
"FILE_DOWNLOAD": "Baixar arquivos",
|
||||
|
|
@ -802,6 +870,7 @@
|
|||
"USER": "Usuário"
|
||||
},
|
||||
"users": {
|
||||
"api_keys": "Chaves API",
|
||||
"authentication_activity": "Atividade de Autenticação",
|
||||
"users": "Usuários"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@
|
|||
"pageText": "{0}-{1} из {2}"
|
||||
},
|
||||
"dataIterator": {
|
||||
"loadingText": "Загрузка объектов...",
|
||||
"noResultsText": "Подходящих записей не найдено"
|
||||
"loadingText": "Загрузка элементов...",
|
||||
"noResultsText": "Совпадений не найдено"
|
||||
},
|
||||
"dataTable": {
|
||||
"itemsPerPageText": "Строк на странице:",
|
||||
|
|
@ -15,30 +15,33 @@
|
|||
"counter": "Файлов: {0}",
|
||||
"counterSize": "Файлов: {0} (всего {1})"
|
||||
},
|
||||
"noDataText": "Отсутствуют данные"
|
||||
"noDataText": "Данные отсутствуют"
|
||||
},
|
||||
"account_settings": {
|
||||
"account_settings": "Настройки Аккаунта",
|
||||
"account_settings": "Настройки аккаунта",
|
||||
"api_key": {
|
||||
"created_date": "Дата создания: {date}",
|
||||
"generate_api_key": "Сгенерировать API ключ",
|
||||
"force_kobo_sync": "Принудительная синхронизация с Kobo",
|
||||
"generate_api_key": "Сгенерировать ключ API",
|
||||
"no_keys": "Ни одного ключа API еще не создано"
|
||||
},
|
||||
"change_password": "изменить пароль"
|
||||
"change_password": "изменить пароль",
|
||||
"details": "Подробности",
|
||||
"my_account": "Мой аккаунт"
|
||||
},
|
||||
"announcements": {
|
||||
"mark_all_read": "Пометить всё как прочитанное",
|
||||
"mark_read": "Пометить как прочитанное",
|
||||
"mark_all_read": "Отметить всё как прочитанное",
|
||||
"mark_read": "Отметить как прочитанное",
|
||||
"tab_title": "Объявления"
|
||||
},
|
||||
"authentication_activity": {
|
||||
"api_key": "API Ключ",
|
||||
"api_key": "API-ключ",
|
||||
"datetime": "Дата/Время",
|
||||
"email": "Эл. почта",
|
||||
"error": "Ошибка",
|
||||
"ip": "IP-адрес",
|
||||
"source": "Источник",
|
||||
"success": "Статус",
|
||||
"success": "Успех",
|
||||
"user_agent": "User Agent"
|
||||
},
|
||||
"author_roles": {
|
||||
|
|
@ -54,18 +57,18 @@
|
|||
"book_card": {
|
||||
"error": "Ошибка",
|
||||
"no_release_date": "Дата релиза отсутствует",
|
||||
"unknown": "Необходимо проанализировать",
|
||||
"unknown": "Подлежит анализу",
|
||||
"unread": "Не прочитано",
|
||||
"unsupported": "Неподдерживаемый"
|
||||
"unsupported": "Не поддерживается"
|
||||
},
|
||||
"book_import": {
|
||||
"button_browse": "Обзор",
|
||||
"button_import": "Импортировать",
|
||||
"button_import": "Импорт",
|
||||
"button_scan": "Сканировать",
|
||||
"button_select_series": "Выберите Серию",
|
||||
"button_select_series": "Выберите серию",
|
||||
"field_import_path": "Импортировать из каталога",
|
||||
"info_part1": "Этот раздел позволяет вам импортировать файлы, которые находятся за пределами ваших существующих библиотек. Вы можете импортировать файлы только в существующие Серии, в этом случае Komga переместит или скопирует файлы в каталог выбранной Серии.",
|
||||
"info_part2": "Если вы выберете номер для книги и книга с таким номером уже существует, то вы сможете сравнить 2 книги. Если вы решите импортировать книгу, Komga обновит существующую книгу, эффективно заменив старый файл новым.",
|
||||
"info_part1": "Этот раздел позволяет вам импортировать файлы, которые находятся за пределами ваших существующих библиотек. Вы можете импортировать файлы только в существующие серии; в этом случае Komga переместит или скопирует файлы в каталог выбранной серии.",
|
||||
"info_part2": "Если вы укажете номер для книги, и книга с таким номером уже существует, вы сможете сравнить оба варианта. Если вы решите импортировать книгу, Komga обновит существующий вариант, заменив старый файл новым.",
|
||||
"no_files_found": "Файлы не найдены",
|
||||
"notification": {
|
||||
"go_to_book": "Перейти к книге",
|
||||
|
|
@ -74,9 +77,9 @@
|
|||
"source_file": "Исходный файл: {file}"
|
||||
},
|
||||
"row": {
|
||||
"error_analyze_first": "Книгу нужно сначала проанализировать",
|
||||
"error_analyze_first": "Книга нуждается в предварительном анализе",
|
||||
"error_choose_series": "Выберите серию",
|
||||
"error_only_import_no_errors": "Можно импортировать только книги без ошибок",
|
||||
"error_only_import_no_errors": "Можно импортировать только книги без наличия ошибок",
|
||||
"warning_upgrade": "Существующая книга будет обновлена"
|
||||
},
|
||||
"table": {
|
||||
|
|
@ -90,10 +93,11 @@
|
|||
},
|
||||
"bookreader": {
|
||||
"beginning_of_book": "Вы находитесь в начале книги.",
|
||||
"changing_reading_direction": "Изменение Направления Чтения на",
|
||||
"cycling_page_layout": "Переключить Формат Страниц",
|
||||
"cycling_scale": "Переключить Масштабирование",
|
||||
"cycling_side_padding": "Переключить Боковой Отступ",
|
||||
"changing_reading_direction": "Изменение направления чтения на",
|
||||
"cycling_page_layout": "Переключение макета страницы",
|
||||
"cycling_page_margin": "Переключение полей страницы",
|
||||
"cycling_scale": "Масштабирование",
|
||||
"cycling_side_padding": "Переключение боковых отступов",
|
||||
"download_current_page": "Скачать текущую страницу",
|
||||
"end_of_book": "Вы достигли конца книги.",
|
||||
"from_series_metadata": "из метаданных серии",
|
||||
|
|
@ -104,8 +108,8 @@
|
|||
"notification_poster_set_readlist": "Текущая страница теперь используется в качестве постера списка чтения.",
|
||||
"notification_poster_set_series": "Текущая страница теперь используется в качестве постера серии.",
|
||||
"paged_reader_layout": {
|
||||
"double": "Двойные страницы",
|
||||
"double_no_cover": "Двойные страницы (без обложки)",
|
||||
"double": "Две страницы",
|
||||
"double_no_cover": "Две страницы (без обложки)",
|
||||
"single": "Одна страница"
|
||||
},
|
||||
"reader_settings": "Настройки Ридера",
|
||||
|
|
@ -114,16 +118,16 @@
|
|||
"continuous_width": "По ширине",
|
||||
"height": "По высоте",
|
||||
"original": "Исходное",
|
||||
"screen": "По экрану",
|
||||
"screen": "По размеру экрана",
|
||||
"width": "По ширине",
|
||||
"width_shrink_only": "По ширине (с отступами)"
|
||||
},
|
||||
"set_current_page_as_book_poster": "Установить страницу в качестве постера для книги",
|
||||
"set_current_page_as_readlist_poster": "Установить страницу в качестве постера для списка чтения",
|
||||
"set_current_page_as_series_poster": "Установить страницу в качестве постера для серии",
|
||||
"set_current_page_as_book_poster": "Установить страницу в качестве обложки для книги",
|
||||
"set_current_page_as_readlist_poster": "Установить страницу в качестве обложки для списка чтения",
|
||||
"set_current_page_as_series_poster": "Установить страницу в качестве обложки для серии",
|
||||
"settings": {
|
||||
"always_fullscreen": "Всегда в полный экран",
|
||||
"animate_page_transitions": "Анимировать переходы страниц",
|
||||
"always_fullscreen": "Всегда полноэкранный режим",
|
||||
"animate_page_transitions": "Анимировать переходы между страницами",
|
||||
"background_color": "Цвет фона",
|
||||
"background_colors": {
|
||||
"black": "Чёрный",
|
||||
|
|
@ -134,54 +138,60 @@
|
|||
"general": "Общее",
|
||||
"gestures": "Жесты",
|
||||
"page_layout": "Формат страницы",
|
||||
"paged": "Настройки Отображения Страниц",
|
||||
"page_margin": "Поля страницы",
|
||||
"paged": "Настройки отображения страниц",
|
||||
"reading_mode": "Режим чтения",
|
||||
"scale_type": "Масштабирование",
|
||||
"side_padding": "Боковой отступ",
|
||||
"side_padding": "Боковые отступы",
|
||||
"side_padding_none": "Нет",
|
||||
"webtoon": "Параметры Режима Webtoon"
|
||||
"webtoon": "Настройки режима цифрового комикса"
|
||||
},
|
||||
"shortcuts": {
|
||||
"close": "Закрыть",
|
||||
"cycle_page_layout": "Переключить формат страниц",
|
||||
"cycle_page_layout": "Переключить макет страницы",
|
||||
"cycle_page_margin": "Переключить поля страницы",
|
||||
"cycle_scale": "Переключить масштаб",
|
||||
"cycle_side_padding": "Переключить боковой отступ",
|
||||
"cycle_side_padding": "Переключить боковые отступы",
|
||||
"first_page": "Первая страница",
|
||||
"fullscreen": "Войти/выйти из полноэкранного режима",
|
||||
"last_page": "Последняя страница",
|
||||
"left_to_right": "Слева Направо",
|
||||
"left_to_right": "Слева направо",
|
||||
"menus": "Меню",
|
||||
"next_page": "Следующая страница",
|
||||
"previous_page": "Предыдущая страница",
|
||||
"reader_navigation": "Навигация",
|
||||
"right_to_left": "Справа Налево",
|
||||
"right_to_left": "Справа налево",
|
||||
"settings": "Настройки",
|
||||
"show_hide_help": "Показать/скрыть помощь",
|
||||
"show_hide_settings": "Показать/скрыть меню настроек",
|
||||
"show_hide_thumbnails": "Показать/скрыть просмотр эскизов",
|
||||
"show_hide_thumbnails": "Показать/скрыть обозреватель миниатюр",
|
||||
"show_hide_toolbars": "Показать/скрыть панели инструментов",
|
||||
"vertical": "Вертикально",
|
||||
"webtoon": "Webtoon"
|
||||
"webtoon": "Цифровой комикс"
|
||||
},
|
||||
"tooltip_incognito": "Прогресс чтения не будет сохранен"
|
||||
},
|
||||
"browse_book": {
|
||||
"comment": "КОММЕНТАРИЙ",
|
||||
"date_created": "СОЗДАНО",
|
||||
"date_modified": "ПОСЛЕДНЕЕ ИЗМЕНЕНИЕ",
|
||||
"download_file": "Скачать файл",
|
||||
"file": "ФАЙЛ",
|
||||
"format": "ФОРМАТ",
|
||||
"isbn": "ISBN",
|
||||
"links": "ССЫЛКИ",
|
||||
"navigation_within_readlist": "Навигация в пределах списка чтения: {name}",
|
||||
"outdated_tooltip": "Файл этой книги изменен, книгу необходимо повторно проанализировать",
|
||||
"navigation_within_readlist": "Навигация внутри списка чтения: {name}",
|
||||
"outdated_tooltip": "Файл этой книги изменился, книгу необходимо повторно проанализировать",
|
||||
"read_book": "Читать книгу",
|
||||
"read_incognito": "Читать инкогнито",
|
||||
"remove_from_collection": "Удалить книгу из коллекции",
|
||||
"remove_from_readlist": "Удалить книгу из списка чтения",
|
||||
"size": "РАЗМЕР"
|
||||
},
|
||||
"browse_collection": {
|
||||
"edit_collection": "Редактировать коллекцию",
|
||||
"edit_elements": "Редактировать элементы",
|
||||
"manual_ordering": "ручной порядок"
|
||||
"manual_ordering": "ручная сортировка"
|
||||
},
|
||||
"browse_readlist": {
|
||||
"edit_elements": "Редактировать элементы",
|
||||
|
|
@ -189,17 +199,19 @@
|
|||
"manual_ordering": "ручная сортировка"
|
||||
},
|
||||
"browse_series": {
|
||||
"earliest_year_from_release_dates": "Это самая ранняя дата выпуска из всех книг в этой серии",
|
||||
"series_no_summary": "У серии нет описания, поэтому мы подобрали его для вас!",
|
||||
"earliest_year_from_release_dates": "Это самый ранний год из дат выхода всех книг серии",
|
||||
"remove_from_collection": "Удалить серию из коллекции",
|
||||
"series_no_summary": "У этой серии нет описания, поэтому мы подобрали его для вас!",
|
||||
"summary_from_book": "Краткое описание из книги {number}:"
|
||||
},
|
||||
"collections_expansion_panel": {
|
||||
"manage_collection": "Управлять коллекцией",
|
||||
"manage_collection": "Управление коллекцией",
|
||||
"title": "Коллекция {name}"
|
||||
},
|
||||
"common": {
|
||||
"age": "Возраст",
|
||||
"all_libraries": "Все Библиотеки",
|
||||
"all_libraries": "Все библиотеки",
|
||||
"any_of": "Любой из",
|
||||
"book": "Книга",
|
||||
"books": "Книги",
|
||||
"books_n": "Книг нет | 1 книга | {count} книг",
|
||||
|
|
@ -212,14 +224,16 @@
|
|||
"copied": "Скопировано!",
|
||||
"create": "Создать",
|
||||
"delete": "Удалить",
|
||||
"dimension": "шир.: {width} выс.: {height}",
|
||||
"dimension": "шир.: {width}, выс.: {height}",
|
||||
"discard": "Отмена",
|
||||
"disk_space": "Дисковое пространство",
|
||||
"dismiss": "Отклонить",
|
||||
"download": "Скачать",
|
||||
"drag_drop": "перетащить",
|
||||
"duplicate": "Дублировать",
|
||||
"email": "Эл. почта",
|
||||
"epub": "Epub",
|
||||
"error": "Ошибка",
|
||||
"filename": "Имя файла",
|
||||
"filter_no_matches": "Нет совпадений по заданному фильтру",
|
||||
"genre": "Жанр",
|
||||
|
|
@ -227,12 +241,16 @@
|
|||
"go_to_library": "Вернуться к библиотеке",
|
||||
"go_to_readlist": "Перейти к списку чтения",
|
||||
"go_to_series": "Перейти к серии",
|
||||
"i_understand": "Я понимаю",
|
||||
"library": "Библиотека",
|
||||
"locale_name": "Русский",
|
||||
"locale_rtl": "false",
|
||||
"lock_all": "Заблокировать все",
|
||||
"media": "Медиа",
|
||||
"more": "Ещё",
|
||||
"n_selected": "{count} выбрано",
|
||||
"nothing_to_show": "Нет данных для отображения",
|
||||
"ok": "OK",
|
||||
"outdated": "Устарело",
|
||||
"page": "Страница",
|
||||
"page_number": "Номер страницы",
|
||||
|
|
@ -242,17 +260,20 @@
|
|||
"password": "Пароль",
|
||||
"pdf": "PDF",
|
||||
"pending_tasks": "Нет незавершенных задач | 1 незавершенная задача | {count} незавершенных задач",
|
||||
"pinned_libraries": "Закреплённые библиотеки",
|
||||
"publisher": "Издатель",
|
||||
"read": "Читать",
|
||||
"read_on": "Читать {date}",
|
||||
"read_on": "Прочитано {date}",
|
||||
"readlist": "Список чтения",
|
||||
"readlists": "Списки чтения",
|
||||
"remember-me": "Запомнить",
|
||||
"required": "Необходимо",
|
||||
"remember-me": "Запомнить меня",
|
||||
"reorder": "Изменить порядок",
|
||||
"required": "Обязательно",
|
||||
"reset_filters": "Сбросить фильтры",
|
||||
"roles": "Роли",
|
||||
"save_changes": "Сохранить изменения",
|
||||
"series": "Серии",
|
||||
"settings": "Настройки",
|
||||
"tags": "Теги",
|
||||
"unavailable": "Недоступно",
|
||||
"unlock_all": "Разблокировать все",
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@
|
|||
"button_scan": "Skenovať",
|
||||
"button_select_series": "Vybrať sériu",
|
||||
"field_import_path": "Importovať z priečinka",
|
||||
"info_part1": "Na tejto obrazovke môžete importovať súbory, ktoré nie sú súčasťou vašich existujúcich knižníc. Súbory môžete importovať iba do existujúcich sérií, pričom Komga presunie alebo skopíruje súbory do adresára zvolenej série.",
|
||||
"info_part1": "Na tejto obrazovke môžete importovať súbory, ktoré nie sú súčasťou vašich existujúcich knižníc. Súbory môžete importovať iba do existujúcich sérií, pričom Komga presunie alebo skopíruje súbory do priečinka zvolenej série.",
|
||||
"info_part2": "Ak vyberiete číslo pre knihu a kniha s týmto číslom už existuje, budete môcť porovnať obe knihy. Ak sa rozhodnete knihu importovať, Komga aktualizuje existujúcu knihu novou verziou, čím efektívne nahradí starý súbor novým.",
|
||||
"no_files_found": "Nenašli sa žiadne súbory",
|
||||
"notification": {
|
||||
|
|
@ -89,12 +89,12 @@
|
|||
"series": "Séria"
|
||||
},
|
||||
"title": "Importovať",
|
||||
"try_another_directory": "Skúste vyhľadať v inom adresári"
|
||||
"try_another_directory": "Skúste vyhľadať v inom priečinku"
|
||||
},
|
||||
"bookreader": {
|
||||
"beginning_of_book": "Ste na začiatku knihy.",
|
||||
"changing_reading_direction": "Zmena smeru čítania na",
|
||||
"cycling_page_layout": "Zmeniť vzhľad strany",
|
||||
"cycling_page_layout": "Zmeniť rozloženie strany",
|
||||
"cycling_page_margin": "Zmeniť okraj strany",
|
||||
"cycling_scale": "Zmeniť mierku",
|
||||
"cycling_side_padding": "Zmeniť odsadenie strany",
|
||||
|
|
@ -105,8 +105,8 @@
|
|||
"move_next_exit": "Kliknite alebo stlačte znovu tlačidlo „Ďalej“, aby ste opustili čítačku.",
|
||||
"move_previous": "Kliknite alebo stlačte znovu tlačidlo „Predchádzajúca“, aby ste prešli na predchádzajúcu knihu.",
|
||||
"notification_poster_set_book": "Súčasná strana bola nastavená ako plagát knihy.",
|
||||
"notification_poster_set_readlist": "Súčasná strana bola nastavená ako plagát zoznamu čítania.",
|
||||
"notification_poster_set_series": "Súčasná strana bola nastavená ako plagát série.",
|
||||
"notification_poster_set_readlist": "Aktuálna strana bola nastavená ako plagát zoznamu čítania.",
|
||||
"notification_poster_set_series": "Aktuálna strana bola nastavená ako plagát série.",
|
||||
"paged_reader_layout": {
|
||||
"double": "Dvojstránka",
|
||||
"double_no_cover": "Dvojstránka (bez obálky)",
|
||||
|
|
@ -252,6 +252,7 @@
|
|||
"n_selected": "{count} vybrané",
|
||||
"nothing_to_show": "Nič na zobrazenie",
|
||||
"ok": "OK",
|
||||
"oneshot": "Samostatný diel",
|
||||
"outdated": "Zastarané",
|
||||
"page": "Strana",
|
||||
"page_number": "Číslo strany",
|
||||
|
|
@ -267,7 +268,7 @@
|
|||
"read_on": "Čítané {date}",
|
||||
"readlist": "Zoznam čítania",
|
||||
"readlists": "Zoznamy čítania",
|
||||
"remember-me": "Zapamätaj si ma",
|
||||
"remember-me": "Zapamätať si ma",
|
||||
"reorder": "Zmeniť poradie",
|
||||
"required": "Povinné",
|
||||
"reset_filters": "Resetovať filtre",
|
||||
|
|
@ -275,6 +276,7 @@
|
|||
"save_changes": "Uložiť zmeny",
|
||||
"series": "Séria | Série",
|
||||
"settings": "Nastavenia",
|
||||
"sidecars": "Sprievodne súbory",
|
||||
"tags": "Štítky",
|
||||
"ui": "Používateľské rozhranie",
|
||||
"unavailable": "Nedostupné",
|
||||
|
|
@ -296,6 +298,7 @@
|
|||
"book_number": "Číslo knihy: {name}",
|
||||
"book_series": "Séria: {name}",
|
||||
"button_import": "Importovať",
|
||||
"button_match": "Porovnať",
|
||||
"comicrack_preambule_html": "Existujúce zoznamy čítania ComicRack môžete importovať vo formáte <code>.cbl</code>.<br>Komga sa pokúsi priradiť zadané čísla sérií a kníh k sériám a knihám vo vašich knižniciach.",
|
||||
"dialog_confirmation": {
|
||||
"body": "{unmatched} / {total} kníh je neporovnaných",
|
||||
|
|
@ -318,7 +321,7 @@
|
|||
"add_api_key": {
|
||||
"button_confirm": "Generovať",
|
||||
"context": "Kľúče API možno používať na overenie prostredníctvom protokolu Kobo Sync.",
|
||||
"dialog_title": "Generovať nový kľúč API",
|
||||
"dialog_title": "Generovať nový API kľúč",
|
||||
"field_comment": "Poznámka",
|
||||
"field_comment_hint": "Na čo slúži tento API kľúč?",
|
||||
"info_copy": "Nezabudnite si teraz skopírovať svoj API kľúč. Už ho nebudete môcť znovu zobraziť!"
|
||||
|
|
@ -392,13 +395,16 @@
|
|||
"confirm_delete_multiple": "Áno, odstrániť {count} zoznamy čítania",
|
||||
"dialog_title": "Odstrániť zoznam čítania",
|
||||
"dialog_title_multiple": "Odstrániť zoznamy čítania",
|
||||
"warning_html": "Zoznam čítania <b>{name}</b> bude odstránený z tohto servera. Vaše mediálne súbory nebudú ovplyvnené. Túto akciu <b>nie je možné</b> vrátiť späť. Pokračovať?"
|
||||
"warning_html": "Zoznam čítania <b>{name}</b> bude odstránený z tohto servera. Vaše mediálne súbory nebudú ovplyvnené. Túto akciu <b>nie je možné</b> vrátiť späť. Pokračovať?",
|
||||
"warning_multiple_html": "{count} zoznamy čítania budú z tohto servera odstránené. Vaše mediálne súbory nebudú ovplyvnené. Túto akciu <b>nie je možné</b> vrátiť späť. Pokračovať?"
|
||||
},
|
||||
"delete_series": {
|
||||
"button_confirm": "Odstrániť",
|
||||
"confirm_delete": "Áno, odstrániť sériu \"{name}\" a jej súbory",
|
||||
"confirm_delete_multiple": "Áno, odstrániť {count} série a ich súbory",
|
||||
"dialog_title": "Odstrániť sériu"
|
||||
"dialog_title": "Odstrániť sériu",
|
||||
"warning_html": "Séria <b>{name}</b> bude spolu s uloženými mediálnymi súbormi odstránená z tohto servera. Túto akciu <b>nie je možné</b> vrátiť späť. Pokračovať?",
|
||||
"warning_multiple_html": "{count} sérií bude z tohto servera odstránených spolu s uloženými mediálnymi súbormi. Túto akciu <b>nie je možné</b> vrátiť späť. Pokračovať?"
|
||||
},
|
||||
"delete_user": {
|
||||
"button_confirm": "Odstrániť",
|
||||
|
|
@ -406,11 +412,239 @@
|
|||
"dialog_title": "Odstrániť používateľa",
|
||||
"warning_html": "Používateľ <b>{name}</b> bude odstránený z tohto servera. Túto akciu <b>nie je možné</b> vrátiť späť. Pokračovať?"
|
||||
},
|
||||
"edit_books": {
|
||||
"add_author_role_error_duplicate": "Už existuje",
|
||||
"authors_notice_multiple_edit": "Upravujete autorov viacerých kníh. Týmto sa prepíšu existujúci autori každej knihy.",
|
||||
"button_cancel": "Zrušiť",
|
||||
"button_confirm": "Uložiť zmeny",
|
||||
"copy_from": "Kopírovať z {field}",
|
||||
"dialog_title_multiple": "Upraviť {count} knihu | Upraviť {count} knihy",
|
||||
"dialog_title_single": "Upraviť {book}",
|
||||
"field_alternate_title": "Alternatívny názov",
|
||||
"field_isbn": "ISBN",
|
||||
"field_isbn_error": "Musí byť platné ISBN 13",
|
||||
"field_link_label": "Značka",
|
||||
"field_link_url": "URL",
|
||||
"field_link_url_error_protocol": "Musí byť http alebo https",
|
||||
"field_link_url_error_url": "Musí byť platná adresa URL",
|
||||
"field_number": "Číslo",
|
||||
"field_number_sort": "Poradové číslo",
|
||||
"field_number_sort_hint": "Môžete použiť desatinné čísla",
|
||||
"field_release_date": "Dátum vydania",
|
||||
"field_release_date_error": "Musí byť platný dátum vo formáte RRRR-MM-DD",
|
||||
"field_summary": "Zhrnutie",
|
||||
"field_tags": "Štítky",
|
||||
"field_title": "Titul",
|
||||
"number_sort_decrement": "Znížiť všetky o 1",
|
||||
"number_sort_increment": "Zvýšiť všetko o 1",
|
||||
"tab_authors": "Autori",
|
||||
"tab_general": "Všeobecné",
|
||||
"tab_links": "Odkazy",
|
||||
"tab_poster": "Plagát",
|
||||
"tab_tags": "Štítky",
|
||||
"tags_notice_multiple_edit": "Upravujete štítky pre viacero kníh. Týmto sa prepíšu existujúce štítky každej knihy."
|
||||
},
|
||||
"edit_collection": {
|
||||
"button_cancel": "Zrušiť",
|
||||
"button_confirm": "Uložiť zmeny",
|
||||
"dialog_title": "Upraviť zbierku",
|
||||
"field_manual_ordering": "Manuálne zoradenie",
|
||||
"label_ordering": "V predvolenom nastavení budú série v zbierke zoradené podľa názvu. Môžete aktivovať ručné zoradenie a definovať si vlastné poradie.",
|
||||
"tab_general": "Všeobecné",
|
||||
"tab_poster": "Plagát"
|
||||
},
|
||||
"edit_library": {
|
||||
"button_browse": "Prechádzať",
|
||||
"button_cancel": "Zrušiť",
|
||||
"button_confirm_add": "Pridať",
|
||||
"button_confirm_edit": "Upraviť",
|
||||
"button_next": "Ďalší",
|
||||
"dialog_title_add": "Pridať knižnicu",
|
||||
"dialot_title_edit": "Upraviť knižnicu",
|
||||
"field_analysis_analyze_dimensions": "Analyzovať rozmery strán",
|
||||
"field_analysis_hash_files": "Vypočítať hash pre súbory",
|
||||
"field_analysis_hash_koreader": "Vypočítať hash súborov pre KOReader",
|
||||
"field_analysis_hash_pages": "Vypočítať hash pre strany",
|
||||
"field_convert_to_cbz": "Automaticky konvertovať na CBZ",
|
||||
"field_import_barcode_isbn": "ISBN čiarový kód",
|
||||
"field_import_comicinfo_book": "Metadáta knihy",
|
||||
"field_import_comicinfo_collections": "Zbierky",
|
||||
"field_import_comicinfo_readlists": "Zoznamy čítania",
|
||||
"field_import_comicinfo_series": "Metadáta série",
|
||||
"field_import_comicinfo_series_append_volume": "Pridať zväzok k názvu série",
|
||||
"field_import_epub_book": "Metadáta knihy",
|
||||
"field_import_epub_series": "Metadáta série",
|
||||
"field_import_local_artwork": "Lokálne ilustrácie",
|
||||
"field_import_mylar_series": "Metadáta série",
|
||||
"field_name": "Názov",
|
||||
"field_oneshotsdirectory": "Priečinok samostatných dielov",
|
||||
"field_repair_extensions": "Automaticky opraviť nesprávne prípony súborov",
|
||||
"field_root_folder": "Koreňový priečinok",
|
||||
"field_scan_interval": "Interval skenovania",
|
||||
"field_scanner_empty_trash_after_scan": "Po každom skenovaní automaticky vyprázdniť kôš",
|
||||
"field_scanner_force_directory_modified_time": "Vynútiť čas úpravy priečinka",
|
||||
"field_scanner_scan_startup": "Skenovať pri spustení",
|
||||
"field_series_cover": "Obálka série",
|
||||
"file_browser_dialog_button_confirm": "Vybrať",
|
||||
"file_browser_dialog_title": "Koreňový priečinok knižnice",
|
||||
"label_analysis": "Analýza",
|
||||
"label_file_management": "Správa súborov",
|
||||
"label_import_barcode_isbn": "Importovať ISBN z čiarového kódu",
|
||||
"label_import_comicinfo": "Importovať metadáta pre CBR/CBZ obsahujúce súbor ComicInfo.xml",
|
||||
"label_import_epub": "Importovať metadáta zo súborov EPUB",
|
||||
"label_import_local": "Importovať lokálne mediálne súbory",
|
||||
"label_import_mylar": "Importovať metadáta generované pomocou Mylar",
|
||||
"label_scan_directory_exclusions": "Vyňaté priečinky",
|
||||
"label_scan_types": "Skenovať tieto typy súborov",
|
||||
"label_scanner": "Skener",
|
||||
"label_series_cover": "Obálka série",
|
||||
"tab_general": "Všeobecné",
|
||||
"tab_metadata": "Metadáta",
|
||||
"tab_options": "Možnosti",
|
||||
"tooltip_oneshotsdirectory": "Nechajte prázdne, pre deaktiváciu",
|
||||
"tooltip_scanner_force_modified_time": "Aktivujte, ak je knižnica na disku Google Drive",
|
||||
"tooltip_use_resources": "Môže spotrebovať veľa zdrojov na veľkých knižniciach alebo pomalom hardvéri"
|
||||
},
|
||||
"edit_readlist": {
|
||||
"button_cancel": "Zrušiť",
|
||||
"button_confirm": "Uložiť zmeny",
|
||||
"dialog_title": "Upraviť zoznam čítania",
|
||||
"field_manual_ordering": "Manuálne zoradenie",
|
||||
"field_name": "Názov",
|
||||
"field_summary": "Zhrnutie",
|
||||
"label_ordering": "Knihy v zozname čítania sú pri východzom nastavení zoradené ručne. Ručné zoradenie môžete vypnúť a knihy zoradiť podľa dátumu vydania.",
|
||||
"tab_general": "Všeobecné",
|
||||
"tab_poster": "Plagát"
|
||||
},
|
||||
"edit_recommended": {
|
||||
"button_confirm": "Uložiť zmeny",
|
||||
"button_reset": "Obnoviť predvolené nastavenia",
|
||||
"dialog_title": "Upraviť odporúčané zobrazenie"
|
||||
},
|
||||
"edit_series": {
|
||||
"button_cancel": "Zrušiť",
|
||||
"button_confirm": "Uložiť zmeny",
|
||||
"dialog_title_multiple": "Upraviť {count} sériu | Upraviť {count} série",
|
||||
"dialog_title_single": "Upraviť {series}",
|
||||
"field_age_rating": "Vekové hodnotenie",
|
||||
"field_age_rating_error": "Vekové hodnotenie musí byť 0 alebo viac",
|
||||
"field_genres": "Žánre",
|
||||
"field_labels": "Značky",
|
||||
"field_language": "Jazyk",
|
||||
"field_language_hint": "Jazyková značka IETF BCP 47",
|
||||
"field_publisher": "Vydavateľ",
|
||||
"field_reading_direction": "Smer čítania",
|
||||
"field_sort_title": "Názov pre radenie",
|
||||
"field_status": "Stav",
|
||||
"field_summary": "Zhrnutie",
|
||||
"field_tags": "Štítky",
|
||||
"field_title": "Titul",
|
||||
"field_total_book_count": "Celkový počet kníh",
|
||||
"field_total_book_count_error": "Celkový počet kníh musí byť 1 alebo viac",
|
||||
"mixed": "ZMIEŠANÉ",
|
||||
"tab_general": "Všeobecné",
|
||||
"tab_poster": "Plagát",
|
||||
"tab_sharing": "Zdieľanie",
|
||||
"tab_tags": "Štítky",
|
||||
"tab_titles": "Alternatívne názvy",
|
||||
"tags_notice_multiple_edit": "Upravujete štítky pre viacero sérií. Týmto sa prepíšu existujúce štítky každej série."
|
||||
},
|
||||
"edit_user": {
|
||||
"button_cancel": "Zrušiť",
|
||||
"button_confirm": "Uložiť zmeny",
|
||||
"dialog_title": "Upraviť používateľa",
|
||||
"label_roles_for": "Roly pre {name}"
|
||||
},
|
||||
"edit_user_restrictions": {
|
||||
"age_restriction": {
|
||||
"allow_under": "Povoliť len do",
|
||||
"exclude_over": "Vylúčiť nad",
|
||||
"none": "Bez obmedzení"
|
||||
},
|
||||
"edit_restrictions_for": "Upraviť obmedzenia pre {name}",
|
||||
"label_age_restriction": "Vekové obmedzenie",
|
||||
"label_allow_only_labels": "Povoliť iba tieto označenia",
|
||||
"label_exclude_labels": "Vylúčiť tieto označenia",
|
||||
"tab_content_restrictions": "Obmedzenia obsahu",
|
||||
"tab_shared_libraries": "Zdieľané knižnice"
|
||||
},
|
||||
"empty_trash": {
|
||||
"body": "V štandardnom nastavení mediálny server neodstraňuje informácie o médiách ihneď. To je užitočné v prípade, ak je disk dočasne odpojený. Keď vyprázdnite kôš knižnice, všetky informácie o chýbajúcich médiách sa odstránia."
|
||||
"body": "V štandardnom nastavení mediálny server neodstraňuje informácie o médiách ihneď. To je užitočné v prípade, ak je disk dočasne odpojený. Keď vyprázdnite kôš knižnice, všetky informácie o chýbajúcich médiách sa odstránia.",
|
||||
"button_confirm": "Vyprázdniť",
|
||||
"title": "Vyprázdniť kôš pre knižnicu"
|
||||
},
|
||||
"file_browser": {
|
||||
"button_cancel": "Zrušiť",
|
||||
"button_confirm_default": "Vybrať",
|
||||
"dialog_title_default": "Prehliadač súborov",
|
||||
"parent_directory": "Nadriadený"
|
||||
},
|
||||
"filename_chooser": {
|
||||
"button_choose": "Vybrať",
|
||||
"field_destination_filename": "Názov cieľového súboru",
|
||||
"label_source_filename": "Názov zdrojového súboru",
|
||||
"table": {
|
||||
"existing_file": "Existujúci súbor",
|
||||
"order": "Poradie"
|
||||
},
|
||||
"title": "Názov cieľového súboru"
|
||||
},
|
||||
"force_kobo_sync": {
|
||||
"dialog_title": "Vynútiť synchronizáciu Kobo",
|
||||
"warning_html": "Týmto sa vymaže celá história synchronizácie pre tento kľúč API. Váš Kobo synchronizuje všetko pri najbližšej synchronizácii."
|
||||
},
|
||||
"password_change": {
|
||||
"button_cancel": "Zrušiť",
|
||||
"button_confirm": "Zmeniť heslo",
|
||||
"dialog_title": "Zmeniť heslo",
|
||||
"field_new_password": "Nové heslo",
|
||||
"field_new_password_error": "Je nutné zadať nové heslo.",
|
||||
"field_repeat_password": "Zopakujte nové heslo",
|
||||
"field_repeat_password_error": "Heslá sa musia zhodovať."
|
||||
},
|
||||
"refresh_library_metadata": {
|
||||
"body": "Obnoví metadáta všetkých mediálnych súborov v knižnici. V závislosti od veľkosti knižnice to môže trvať dlhší čas.",
|
||||
"button_confirm": "Obnoviť",
|
||||
"title": "Obnoviť metadáta pre knižnicu"
|
||||
},
|
||||
"series_picker": {
|
||||
"label_search_series": "Vyhľadať sériu",
|
||||
"no_results": "Nenašla sa žiadna séria",
|
||||
"title": "Vybrať sériu"
|
||||
},
|
||||
"server_stop": {
|
||||
"button_confirm": "Stop",
|
||||
"confirmation_message": "Naozaj chcete zastaviť Komga?",
|
||||
"dialog_title": "Vypnúť server"
|
||||
},
|
||||
"shortcut_help": {
|
||||
"label_description": "Popis",
|
||||
"label_key": "Kľúč"
|
||||
},
|
||||
"transient_book_details": {
|
||||
"label_candidate": "Kandidát",
|
||||
"label_existing": "Existujúci",
|
||||
"label_format": "Formát",
|
||||
"label_name": "Názov",
|
||||
"label_pages": "Strany",
|
||||
"label_size": "Veľkosť",
|
||||
"pages_table": {
|
||||
"filename": "Názov súboru",
|
||||
"height": "Výška",
|
||||
"index": "Index",
|
||||
"media_type": "Typ média",
|
||||
"size": "Veľkosť",
|
||||
"width": "Šírka"
|
||||
},
|
||||
"title": "Podrobnosti o knihe",
|
||||
"title_comparison": "Porovnanie kníh"
|
||||
},
|
||||
"transient_book_viewer": {
|
||||
"label_candidate": "Kandidát",
|
||||
"label_existing": "Existujúci",
|
||||
"page_of_pages": "{page} / {pages}",
|
||||
"title": "Preskúmať knihu",
|
||||
"title_comparison": "Porovnanie kníh"
|
||||
}
|
||||
},
|
||||
"duplicate_pages": {
|
||||
|
|
@ -418,30 +652,441 @@
|
|||
"action_delete_auto": "Automatické odstránenie",
|
||||
"action_delete_manual": "Manuálne odstránenie",
|
||||
"action_delete_matches": "Odstrániť zhody",
|
||||
"action_ignore": "Ignorovať",
|
||||
"action_ignore_remaining": "Ignorovať zostávajúcich ({count})",
|
||||
"action_manual_delete_remaining": "Manuálne odstránenie zostávajúcich ({count})",
|
||||
"confirm_auto_delete_remaining": "Všetky zostávajúce hashe strán na tejto stránke ({count}) budú označené na automatické vymazanie.",
|
||||
"confirm_manual_delete_remaining": "Všetky zostávajúce hashe strán na tejto stránke ({count}) budú označené na manuálne vymazanie.",
|
||||
"delete_to_save": "Odstrániť, aby sa ušetrilo {size}",
|
||||
"deleted_count": "Odstránené {count} krát"
|
||||
"deleted_count": "Odstránené {count} krát",
|
||||
"empty_title": "Nenašli sa žiadne duplicitné strany",
|
||||
"empty_title_known": "Žiadne známe duplicity",
|
||||
"filter": {
|
||||
"count": "Počet",
|
||||
"date_added": "Dátum pridania",
|
||||
"date_modified": "Dátum úpravy",
|
||||
"delete_count": "Počet vymazaní",
|
||||
"delete_size": "Ušetrené miesto",
|
||||
"match_count": "Počet zhôd",
|
||||
"size": "Veľkosť",
|
||||
"total_size": "Celková veľkosť"
|
||||
},
|
||||
"info": "Odstránenie duplicitných stránok spôsobí úpravu vašich súborov. Pred použitím automatického odstránenia si zálohujte súbory a použite ručné odstránenie.",
|
||||
"known": "Známe",
|
||||
"matches_n": "Žiadne zhody | 1 zhoda | {count} zhody",
|
||||
"new": "Nové",
|
||||
"saved_size": "Ušetrené {size}",
|
||||
"title": "Duplicitné strany",
|
||||
"unknown_size": "Neznáma veľkosť"
|
||||
},
|
||||
"duplicates": {
|
||||
"file_hash": "Hash súboru",
|
||||
"size": "Veľkosť",
|
||||
"title": "Duplicitné súbory",
|
||||
"url": "URL"
|
||||
},
|
||||
"enums": {
|
||||
"copy_mode": {
|
||||
"HARDLINK": "Hardlink/Kopírovanie súborov",
|
||||
"MOVE": "Presunúť súbory"
|
||||
},
|
||||
"epubreader": {
|
||||
"appearances": {
|
||||
"day": "Deň",
|
||||
"night": "Noc",
|
||||
"sepia": "Sépia"
|
||||
},
|
||||
"column_count": {
|
||||
"auto": "Auto",
|
||||
"one": "Jeden",
|
||||
"two": "Dva"
|
||||
},
|
||||
"reading_direction": {
|
||||
"auto": "Automatický",
|
||||
"ltr": "Zľava doprava",
|
||||
"rtl": "Sprava doľava"
|
||||
}
|
||||
},
|
||||
"historical_event_type": {
|
||||
"BookConverted": "Kniha konvertovaná",
|
||||
"BookFileDeleted": "Súbor knihy bol odstránený",
|
||||
"BookImported": "Kniha importovaná",
|
||||
"DuplicatePageDeleted": "Duplicitná strana bola odstránená",
|
||||
"SeriesFolderDeleted": "Priečinok série bol odstránený"
|
||||
},
|
||||
"media_profile": {
|
||||
"DIVINA": "DIVINA",
|
||||
"EPUB": "EPUB",
|
||||
"PDF": "PDF"
|
||||
},
|
||||
"media_status": {
|
||||
"ERROR": "Chyba",
|
||||
"OUTDATED": "Zastarané",
|
||||
"READY": "Pripravený",
|
||||
"UNKNOWN": "Neznámy",
|
||||
"UNSUPPORTED": "Nepodporované"
|
||||
},
|
||||
"page_hash_action": {
|
||||
"DELETE_AUTO": "Automatické odstránenie",
|
||||
"DELETE_MANUAL": "Manuálne odstránenie"
|
||||
"DELETE_MANUAL": "Manuálne odstránenie",
|
||||
"IGNORE": "Ignorovať"
|
||||
},
|
||||
"reading_direction": {
|
||||
"LEFT_TO_RIGHT": "Zľava doprava",
|
||||
"RIGHT_TO_LEFT": "Sprava doľava",
|
||||
"VERTICAL": "Vertikálny",
|
||||
"WEBTOON": "Webtoon"
|
||||
},
|
||||
"scan_interval": {
|
||||
"DAILY": "Denne",
|
||||
"DISABLED": "Vypnuté",
|
||||
"EVERY_12H": "Každých 12 hodín",
|
||||
"EVERY_6H": "Každých 6 hodín",
|
||||
"HOURLY": "Každú hodinu",
|
||||
"WEEKLY": "Týždenne"
|
||||
},
|
||||
"series_cover": {
|
||||
"FIRST": "Prvá",
|
||||
"FIRST_UNREAD_OR_FIRST": "Najskôr neprečítané, inak prvé",
|
||||
"FIRST_UNREAD_OR_LAST": "Najskôr neprečítané, inak posledné",
|
||||
"LAST": "Posledný"
|
||||
},
|
||||
"series_status": {
|
||||
"ABANDONED": "Opustená",
|
||||
"ENDED": "Ukončená",
|
||||
"HIATUS": "Pozastavená",
|
||||
"ONGOING": "Prebiehajúca"
|
||||
},
|
||||
"thumbnail_size": {
|
||||
"DEFAULT": "Predvolené (300px)",
|
||||
"LARGE": "Veľký (900px)",
|
||||
"MEDIUM": "Stredný (600px)",
|
||||
"XLARGE": "Extra veľký (1200px)"
|
||||
}
|
||||
},
|
||||
"epubreader": {
|
||||
"current_chapter": "Aktuálna kapitola",
|
||||
"page_of": "Strana {page} z {count}",
|
||||
"publisher_font": "Vydavateľ",
|
||||
"settings": {
|
||||
"column_count": "Počet stĺpcov",
|
||||
"font_family": "Písmo",
|
||||
"layout": "Rozloženie",
|
||||
"layout_paginated": "Stránkované",
|
||||
"layout_scroll": "Posuvné",
|
||||
"navigation_mode": "Režim navigácie",
|
||||
"navigation_options": {
|
||||
"both": "Oba",
|
||||
"buttons": "Tlačidlá",
|
||||
"click": "Kliknutie / Klepnutie"
|
||||
},
|
||||
"page_margins": "Okraje strany",
|
||||
"viewing_theme": "Motív zobrazenia"
|
||||
},
|
||||
"shortcuts": {
|
||||
"cycle_pagination": "Zmena počtu stĺpcov",
|
||||
"cycle_viewing_theme": "Zmena motívu zobrazenia",
|
||||
"font_size_decrease": "Zmenšiť veľkosť písma",
|
||||
"font_size_increase": "Zväčšiť veľkosť písma",
|
||||
"menus": "Ponuky",
|
||||
"next": "Vpred",
|
||||
"previous": "Späť",
|
||||
"reader_navigation": "Navigácia v čítačke",
|
||||
"scroll": "Zmeniť rozloženie na posúvanie",
|
||||
"settings": "Nastavenia",
|
||||
"show_hide_toc": "Zobraziť/skryť obsah"
|
||||
}
|
||||
},
|
||||
"error_codes": {
|
||||
"ERR_1000": "Počas analýzy nebolo možné získať prístup k súboru",
|
||||
"ERR_1001": "Typ média nie je podporovaný",
|
||||
"ERR_1002": "Šifrované archívy RAR nie sú podporované",
|
||||
"ERR_1003": "Solid RAR archívy nie sú podporované",
|
||||
"ERR_1004": "Viaczväzkové archívy RAR nie sú podporované",
|
||||
"ERR_1005": "Neznáma chyba pri analýze knihy",
|
||||
"ERR_1006": "Kniha neobsahuje žiadnu stranu",
|
||||
"ERR_1007": "Niektoré záznamy nebolo možné analyzovať",
|
||||
"ERR_1008": "Neznáma chyba pri získavaní záznamov o knihe",
|
||||
"ERR_1009": "Zoznam čítania s týmto názvom už existuje",
|
||||
"ERR_1015": "Chyba pri deserializácii ComicRack CBL",
|
||||
"ERR_1016": "Priečinok nie je dostupný alebo nie je priečinkom",
|
||||
"ERR_1017": "Nie je možné skenovať priečinok, ktorý je súčasťou existujúcej knižnice",
|
||||
"ERR_1018": "Súbor nenájdený",
|
||||
"ERR_1019": "Nie je možné importovať súbor, ktorý je súčasťou existujúcej knižnice",
|
||||
"ERR_1020": "Kniha na upgrade nepatrí do poskytnutej série",
|
||||
"ERR_1021": "Cieľový súbor už existuje",
|
||||
"ERR_1022": "Novo importovaná kniha sa nedala naskenovať",
|
||||
"ERR_1023": "Kniha sa už nachádza v ReadingList",
|
||||
"ERR_1024": "Chyba prihlásenia OAuth2: chýba atribút e-mail",
|
||||
"ERR_1025": "Chyba prihlásenia OAuth2: neexistuje žiadny lokálny používateľ s touto e-mailovou adresou",
|
||||
"ERR_1026": "Chyba prihlásenia OpenID Connect: e-mail nebol overený",
|
||||
"ERR_1027": "Chyba prihlásenia OpenID Connect: chýba atribút email_verified",
|
||||
"ERR_1028": "Chyba prihlásenia OpenID Connect: chýba atribút email",
|
||||
"ERR_1029": "ComicRack CBL neobsahuje žiadny element Book",
|
||||
"ERR_1030": "ComicRack CBL neobsahuje žiaden element Name",
|
||||
"ERR_1031": "ComicRack CBL Book chýba séria alebo číslo",
|
||||
"ERR_1032": "Súbor EPUB má nesprávny typ média",
|
||||
"ERR_1033": "Niektoré položky chýbajú",
|
||||
"ERR_1034": "Kľúč API s týmto komentárom už existuje",
|
||||
"ERR_1035": "Chyba pri získavaní EPUB TOC",
|
||||
"ERR_1036": "Chyba pri získavaní EPUB Landmarks",
|
||||
"ERR_1037": "Chyba pri získavaní zoznamu stránok EPUB",
|
||||
"ERR_1038": "Chyba pri načítaní stránok EPUB divina",
|
||||
"ERR_1039": "Chyba pri získavaní EPUB pozícií"
|
||||
},
|
||||
"filter": {
|
||||
"age_rating": "vekové hodnotenie",
|
||||
"age_rating_none": "Bez obmedzení",
|
||||
"any": "Akýkoľvek",
|
||||
"complete": "Kompletná",
|
||||
"genre": "žáner",
|
||||
"in_progress": "Rozčítaná",
|
||||
"language": "jazyk",
|
||||
"library": "knižnica",
|
||||
"media_profile": "Profil média",
|
||||
"media_status": "Stav médií",
|
||||
"oneshot": "Samostatný diel",
|
||||
"publisher": "vydavateľ",
|
||||
"read": "Prečítaná",
|
||||
"release_date": "dátum vydania",
|
||||
"sharing_label": "Značka zdieľania",
|
||||
"status": "stav",
|
||||
"tag": "štítok",
|
||||
"unread": "Neprečítaná"
|
||||
},
|
||||
"filter_drawer": {
|
||||
"filter": "filter",
|
||||
"sort": "zoradiť"
|
||||
},
|
||||
"history": {
|
||||
"header": {
|
||||
"book": "Kniha",
|
||||
"date": "Dátum",
|
||||
"details": "Podrobnosti",
|
||||
"series": "Séria",
|
||||
"type": "Typ"
|
||||
},
|
||||
"title": "História"
|
||||
},
|
||||
"home": {
|
||||
"theme": "Vzhľad",
|
||||
"translation": "Preklad"
|
||||
},
|
||||
"library_navigation": {
|
||||
"browse": "Prechádzať",
|
||||
"browse_books": "Knihy",
|
||||
"browse_series": "Série",
|
||||
"collections": "Zbierky",
|
||||
"readlists": "Zoznamy čítania",
|
||||
"recommended": "Odporúčané"
|
||||
},
|
||||
"login": {
|
||||
"create_user_account": "Vytvoriť používateľský účet",
|
||||
"login": "Prihlásiť sa",
|
||||
"unclaimed_html": "Tento server Komga ešte nie je aktívny, aby ste mali k nemu prístup, musíte si vytvoriť používateľský účet. <br><br>Zvoľte si <strong>e-mailovú adresu</strong> a <strong>heslo</strong> a kliknite na <strong>Vytvoriť používateľský účet</strong>."
|
||||
},
|
||||
"media_analysis": {
|
||||
"comment": "Komentár",
|
||||
"media_analysis": "Analýza médií",
|
||||
"media_type": "Typ média",
|
||||
"name": "Názov",
|
||||
"size": "Veľkosť",
|
||||
"status": "Stav",
|
||||
"url": "URL"
|
||||
},
|
||||
"menu": {
|
||||
"delete": "Odstrániť"
|
||||
"add_to_collection": "Pridať do zbierky",
|
||||
"add_to_readlist": "Pridať do zoznamu čítania",
|
||||
"analyze": "Analyzovať",
|
||||
"bulk_edit_metadata": "Hromadná úprava metadát",
|
||||
"delete": "Odstrániť",
|
||||
"deselect_all": "Zrušiť označenie všetkých",
|
||||
"download_readlist": "Stiahnuť zoznam čítania",
|
||||
"download_series": "Stiahnuť sériu",
|
||||
"edit": "Upraviť",
|
||||
"edit_metadata": "Upraviť metadáta",
|
||||
"empty_trash": "Vyprázdniť kôš",
|
||||
"mark_read": "Označiť ako prečítané",
|
||||
"mark_unread": "Označiť ako neprečítané",
|
||||
"pin": "Pripnúť",
|
||||
"refresh_metadata": "Obnoviť metadáta",
|
||||
"scan_library_files": "Skenovať súbory knižnice",
|
||||
"scan_library_files_deep": "Skenovať súbory knižnice (hĺbkovo)",
|
||||
"select_all": "Vybrať všetko",
|
||||
"unpin": "Odopnúť"
|
||||
},
|
||||
"metrics": {
|
||||
"library_books": "Počet kníh na knižnicu",
|
||||
"library_disk_space": "Miesto na disku knižnice",
|
||||
"library_series": "Počet sérií na knižnicu",
|
||||
"library_sidecars": "Počet sprievodných súborov na knižnicu",
|
||||
"tasks_executed": "Vykonané úlohy",
|
||||
"tasks_total_time": "Celkový čas úloh",
|
||||
"title": "Metriky"
|
||||
},
|
||||
"missing_posters": {
|
||||
"title": "Chýbajúce plagáty"
|
||||
},
|
||||
"navigation": {
|
||||
"home": "Domov",
|
||||
"libraries": "Knižnice",
|
||||
"logout": "Odhlásiť sa"
|
||||
},
|
||||
"no_libraries_pinned": {
|
||||
"subtitle": "Knižnicu môžete pripnúť z menu s tromi bodkami",
|
||||
"title": "Žiadne pripnuté knižnice"
|
||||
},
|
||||
"page_not_found": {
|
||||
"go_back_to_home_page": "Vrátiť sa na hlavnú stránku",
|
||||
"page_does_not_exist": "Stránka, ktorú hľadáte, neexistuje.",
|
||||
"page_not_found": "Stránka nenájdená"
|
||||
},
|
||||
"read_more": {
|
||||
"less": "Menej",
|
||||
"more": "Viac"
|
||||
},
|
||||
"readlist_import": {
|
||||
"row": {
|
||||
"duplicate_book": "Duplicitná kniha",
|
||||
"error_choose_book": "Vybrať knihu"
|
||||
}
|
||||
},
|
||||
"readlists_expansion_panel": {
|
||||
"manage_readlist": "Spravovať zoznam čítania",
|
||||
"title": "{name} zoznam čítania"
|
||||
},
|
||||
"search": {
|
||||
"no_results": "Vyhľadávanie nevrátilo žiadne výsledky",
|
||||
"search": "Vyhľadávanie",
|
||||
"search_for_something_else": "Skúste vyhľadať niečo iné",
|
||||
"search_results_for": "Výsledky vyhľadávania pre \"{name}\""
|
||||
},
|
||||
"searchbox": {
|
||||
"in_library": "v {library}",
|
||||
"no_results": "Žiadne výsledky",
|
||||
"search_all": "Vyhľadávať všetko…"
|
||||
},
|
||||
"server": {
|
||||
"server_management": {
|
||||
"button_cancel_all_tasks": "Zrušiť všetky úlohy",
|
||||
"button_empty_trash": "Vyprázdniť kôš pre všetky knižnice",
|
||||
"button_scan_libraries": "Skenovať všetky knižnice",
|
||||
"button_scan_libraries_deep": "Skenovať všetky knižnice (hĺbkovo)",
|
||||
"button_shutdown": "Vypnúť",
|
||||
"download_log": "Stiahnuť log súbor",
|
||||
"notification_tasks_cancelled": "Žiadne úlohy na zrušenie | Jedna úloha zrušená | {count} úlohy zrušené",
|
||||
"section_title": "Správa servera"
|
||||
},
|
||||
"tab_title": "Server",
|
||||
"updates": "Aktualizácie"
|
||||
},
|
||||
"server_settings": {
|
||||
"config_precedence": "Má prednosť pred konfiguračným súborom",
|
||||
"dialog_regenerate_thumbnails": {
|
||||
"body": "Veľkosť náhľadov sa zmenila. Chcete znovu vygenerovať náhľady kníh?",
|
||||
"btn_alternate": "Áno, všetky knihy",
|
||||
"btn_cancel": "Nie",
|
||||
"btn_confirm": "Áno, ale len ak je väčší",
|
||||
"title": "Regenerovať náhľady"
|
||||
},
|
||||
"hint_kobo_port": "Nastavte len v prípade problémov so synchronizáciou obálok a sťahovaním",
|
||||
"label_delete_empty_collections": "Po skenovaní odstrániť prázdne zbierky",
|
||||
"label_delete_empty_readlists": "Po skenovaní odstrániť prázdne zoznamy čítania"
|
||||
"label_delete_empty_readlists": "Po skenovaní odstrániť prázdne zoznamy čítania",
|
||||
"label_kepubify_path": "Cesta ku kepubify",
|
||||
"label_kobo_port": "Externý port Kobo Sync",
|
||||
"label_kobo_proxy": "Presmerovať požiadavky Kobo Sync na Kobo Store",
|
||||
"label_rememberme_duration": "Doba trvania \"Zapamätať si ma\" (v dňoch)",
|
||||
"label_server_context_path": "Základná URL adresa",
|
||||
"label_server_port": "Port servera",
|
||||
"label_task_pool_size": "Vlákna pre úlohy",
|
||||
"label_thumbnail_size": "Veľkosť náhľadov",
|
||||
"requires_restart": "Vyžaduje reštart, aby sa zmeny prejavili",
|
||||
"server_settings": "Nastavenia servera"
|
||||
},
|
||||
"settings_user": {
|
||||
"change_password": "Zmeniť heslo",
|
||||
"edit_restrictions": "Upravovať obmedzenia",
|
||||
"edit_user": "Upraviť používateľa",
|
||||
"latest_activity": "Posledná aktivita: {date}",
|
||||
"no_recent_activity": "Žiadna nedávna aktivita",
|
||||
"role_administrator": "Administrátor",
|
||||
"role_user": "Používateľ"
|
||||
},
|
||||
"sort": {
|
||||
"books_count": "Počet kníh",
|
||||
"date_added": "Dátum pridania",
|
||||
"date_read": "Dátum prečítania",
|
||||
"date_updated": "Dátum aktualizácie",
|
||||
"file_name": "Názov súboru",
|
||||
"file_size": "Veľkosť súboru",
|
||||
"folder_name": "Názov priečinka",
|
||||
"name": "Názov",
|
||||
"number": "Číslo",
|
||||
"page_count": "Počet strán",
|
||||
"random": "Náhodné",
|
||||
"release_date": "Dátum vydania",
|
||||
"series": "Séria"
|
||||
},
|
||||
"theme": {
|
||||
"dark": "Tmavý",
|
||||
"light": "Svetlý",
|
||||
"system": "Systém"
|
||||
},
|
||||
"thumbnail_card": {
|
||||
"tooltip_delete": "Odstrániť",
|
||||
"tooltip_to_be_deleted": "Na odstránenie"
|
||||
"tooltip_generated": "Vygenerované ilustrácie",
|
||||
"tooltip_mark_as_selected": "Označiť ako vybrané",
|
||||
"tooltip_selected": "Vybrané",
|
||||
"tooltip_sidecar": "Miestna ilustrácia",
|
||||
"tooltip_to_be_deleted": "Na odstránenie",
|
||||
"tooltip_to_be_uploaded": "Na nahranie",
|
||||
"tooltip_too_big": "Súbor je príliš veľký!",
|
||||
"tooltip_user_uploaded": "Nahrané používateľom"
|
||||
},
|
||||
"titles_more": {
|
||||
"less": "Menej titulov",
|
||||
"more": "Viac titulov"
|
||||
},
|
||||
"ui_settings": {
|
||||
"general": "Všeobecné",
|
||||
"label_oauth2_auto_login": "Automatické prihlásenie cez OAuth2",
|
||||
"label_oauth2_hide_login": "Skryť prihlasovacie polia, ak je povolené OAuth2",
|
||||
"label_poster_blur_unread": "Rozmazať plagát pre neprečítané knihy a série",
|
||||
"label_poster_stretch": "Prispôsobiť plagát karte",
|
||||
"label_series_groups": "Zoskupovanie sérií",
|
||||
"section_oauth2": "OAuth2",
|
||||
"series_groups": {
|
||||
"alpha": "Abecedne",
|
||||
"japanese": "Gojūon (japonský)"
|
||||
},
|
||||
"tooltip_oauth2_auto_login": "Vyžaduje jedného poskytovateľa OAuth2 a povolenú funkciu 'skryť prihlasovacie polia'"
|
||||
},
|
||||
"updates": {
|
||||
"available": "Aktualizácie sú k dispozícii",
|
||||
"latest_installed": "Najnovšia verzia Komga je už nainštalovaná"
|
||||
},
|
||||
"user_roles": {
|
||||
"ADMIN": "Administrátor",
|
||||
"FILE_DOWNLOAD": "Stiahnutie súboru",
|
||||
"KOBO_SYNC": "Kobo Sync",
|
||||
"KOREADER_SYNC": "Synchronizácia KOReader",
|
||||
"PAGE_STREAMING": "Streamovanie strán",
|
||||
"USER": "Používateľ"
|
||||
},
|
||||
"users": {
|
||||
"api_keys": "API kľúče",
|
||||
"authentication_activity": "Autentifikačná aktivita",
|
||||
"users": "Používatelia"
|
||||
},
|
||||
"validation": {
|
||||
"context_path": "Musí začínať znakom '/', nesmie končiť znakmi '/-_', a môže obsahovať iba znaky '/-_a-z0-9'",
|
||||
"one_or_more": "Musí byť 1 alebo viac",
|
||||
"tcp_port": "Musí byť medzi 1 a 65535",
|
||||
"zero_or_more": "Musí byť 0 alebo viac"
|
||||
},
|
||||
"welcome": {
|
||||
"add_library": "Pridať knižnicu",
|
||||
"no_libraries_yet": "Zatiaľ neboli pridané žiadne knižnice!",
|
||||
"welcome_message": "Vitajte v Komga"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -9,7 +9,8 @@ FROM ubuntu:24.10 as build-amd64
|
|||
ENV JAVA_HOME=/opt/java/openjdk
|
||||
COPY --from=eclipse-temurin:23-jre $JAVA_HOME $JAVA_HOME
|
||||
ENV PATH="${JAVA_HOME}/bin:${PATH}"
|
||||
RUN apt -y update && \
|
||||
RUN sed -i -re 's/([a-z]{2}\.)?archive.ubuntu.com|security.ubuntu.com/old-releases.ubuntu.com/g' /etc/apt/sources.list.d/ubuntu.sources && \
|
||||
apt -y update && \
|
||||
apt -y install ca-certificates locales libjxl-dev libheif-dev libwebp-dev libarchive-dev wget curl && \
|
||||
echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen && \
|
||||
locale-gen en_US.UTF-8 && \
|
||||
|
|
@ -23,7 +24,8 @@ FROM ubuntu:24.10 as build-arm64
|
|||
ENV JAVA_HOME=/opt/java/openjdk
|
||||
COPY --from=eclipse-temurin:23-jre $JAVA_HOME $JAVA_HOME
|
||||
ENV PATH="${JAVA_HOME}/bin:${PATH}"
|
||||
RUN apt -y update && \
|
||||
RUN sed -i -re 's/([a-z]{2}\.)?ports.ubuntu.com\/ubuntu-ports/old-releases.ubuntu.com\/ubuntu/g' /etc/apt/sources.list.d/ubuntu.sources && \
|
||||
apt -y update && \
|
||||
apt -y install ca-certificates locales libjxl-dev libheif-dev libwebp-dev libarchive-dev wget curl && \
|
||||
echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen && \
|
||||
locale-gen en_US.UTF-8 && \
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
"url": "https://github.com/gotson/komga/blob/master/LICENSE"
|
||||
},
|
||||
"title": "Komga API",
|
||||
"version": "1.23.2"
|
||||
"version": "1.23.6"
|
||||
},
|
||||
"externalDocs": {
|
||||
"description": "Komga documentation",
|
||||
|
|
@ -4919,7 +4919,7 @@
|
|||
"operationId": "matchComicRackList",
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"multipart/form-data": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
|
@ -10313,6 +10313,9 @@
|
|||
"bookId": {
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
|
|
@ -10331,6 +10334,7 @@
|
|||
}
|
||||
},
|
||||
"required": [
|
||||
"id",
|
||||
"properties",
|
||||
"timestamp",
|
||||
"type"
|
||||
|
|
|
|||
|
|
@ -418,6 +418,7 @@ class BookLifecycle(
|
|||
val extension =
|
||||
mediaRepository.findExtensionByIdOrNull(book.id) as? MediaExtensionEpub
|
||||
?: throw IllegalArgumentException("Epub extension not found")
|
||||
.also { logger.error { "Epub extension not found for book ${book.id}. Book should be re-analyzed." } }
|
||||
extension.positions[page - 1]
|
||||
} else {
|
||||
null
|
||||
|
|
@ -496,6 +497,7 @@ class BookLifecycle(
|
|||
val extension =
|
||||
mediaRepository.findExtensionByIdOrNull(book.id) as? MediaExtensionEpub
|
||||
?: throw IllegalArgumentException("Epub extension not found")
|
||||
.also { logger.error { "Epub extension not found for book ${book.id}. Book should be re-analyzed." } }
|
||||
// match progression with positions
|
||||
val matchingPositions = extension.positions.filter { it.href == href }
|
||||
val matchedPosition =
|
||||
|
|
|
|||
|
|
@ -113,14 +113,14 @@ class ReadListLifecycle(
|
|||
|
||||
fun deleteEmptyReadLists() {
|
||||
logger.info { "Deleting empty read lists" }
|
||||
transactionTemplate.executeWithoutResult {
|
||||
val toDelete = readListRepository.findAllEmpty()
|
||||
transactionTemplate.executeWithoutResult {
|
||||
thumbnailReadListRepository.deleteByReadListIds(toDelete.map { it.id })
|
||||
readListRepository.delete(toDelete.map { it.id })
|
||||
}
|
||||
|
||||
toDelete.forEach { eventPublisher.publishEvent(DomainEvent.ReadListDeleted(it)) }
|
||||
}
|
||||
}
|
||||
|
||||
fun addThumbnail(thumbnail: ThumbnailReadList): ThumbnailReadList {
|
||||
when (thumbnail.type) {
|
||||
|
|
|
|||
|
|
@ -99,14 +99,14 @@ class SeriesCollectionLifecycle(
|
|||
|
||||
fun deleteEmptyCollections() {
|
||||
logger.info { "Deleting empty collections" }
|
||||
transactionTemplate.executeWithoutResult {
|
||||
val toDelete = collectionRepository.findAllEmpty()
|
||||
transactionTemplate.executeWithoutResult {
|
||||
thumbnailSeriesCollectionRepository.deleteByCollectionIds(toDelete.map { it.id })
|
||||
collectionRepository.delete(toDelete.map { it.id })
|
||||
}
|
||||
|
||||
toDelete.forEach { eventPublisher.publishEvent(DomainEvent.CollectionDeleted(it)) }
|
||||
}
|
||||
}
|
||||
|
||||
fun addThumbnail(thumbnail: ThumbnailSeriesCollection): ThumbnailSeriesCollection {
|
||||
when (thumbnail.type) {
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@ class Hasher {
|
|||
return computeHash(path.inputStream())
|
||||
}
|
||||
|
||||
fun computeHash(string: String): String = computeHash(string.byteInputStream())
|
||||
|
||||
fun computeHash(stream: InputStream): String {
|
||||
val hash = Algorithm.XXH3_128.Seeded(SEED.toLong()).createDigest()
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
package org.gotson.komga.infrastructure.jooq
|
||||
|
||||
import org.jooq.DSLContext
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager
|
||||
|
||||
abstract class SplitDslDaoBase {
|
||||
val dslRW: DSLContext
|
||||
private val _dslRO: DSLContext
|
||||
|
||||
constructor(dslRW: DSLContext, dslRO: DSLContext) {
|
||||
this.dslRW = dslRW
|
||||
this._dslRO = dslRO
|
||||
}
|
||||
|
||||
val dslRO: DSLContext
|
||||
get() =
|
||||
if (TransactionSynchronizationManager.isActualTransactionActive() && !TransactionSynchronizationManager.isCurrentTransactionReadOnly())
|
||||
dslRW
|
||||
else
|
||||
_dslRO
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@ package org.gotson.komga.infrastructure.jooq.main
|
|||
import org.gotson.komga.domain.model.AuthenticationActivity
|
||||
import org.gotson.komga.domain.model.KomgaUser
|
||||
import org.gotson.komga.domain.persistence.AuthenticationActivityRepository
|
||||
import org.gotson.komga.infrastructure.jooq.SplitDslDaoBase
|
||||
import org.gotson.komga.infrastructure.jooq.toOrderBy
|
||||
import org.gotson.komga.jooq.main.Tables
|
||||
import org.gotson.komga.jooq.main.tables.records.AuthenticationActivityRecord
|
||||
|
|
@ -21,9 +22,10 @@ import java.time.LocalDateTime
|
|||
|
||||
@Component
|
||||
class AuthenticationActivityDao(
|
||||
private val dslRW: DSLContext,
|
||||
@Qualifier("dslContextRO") private val dslRO: DSLContext,
|
||||
) : AuthenticationActivityRepository {
|
||||
dslRW: DSLContext,
|
||||
@Qualifier("dslContextRO") dslRO: DSLContext,
|
||||
) : SplitDslDaoBase(dslRW, dslRO),
|
||||
AuthenticationActivityRepository {
|
||||
private val aa = Tables.AUTHENTICATION_ACTIVITY
|
||||
|
||||
private val sorts =
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package org.gotson.komga.infrastructure.jooq.main
|
||||
|
||||
import org.gotson.komga.domain.model.ContentRestrictions
|
||||
import org.gotson.komga.infrastructure.jooq.SplitDslDaoBase
|
||||
import org.gotson.komga.infrastructure.jooq.toCondition
|
||||
import org.gotson.komga.jooq.main.Tables
|
||||
import org.jooq.DSLContext
|
||||
|
|
@ -19,8 +20,9 @@ import java.time.LocalDateTime
|
|||
|
||||
@Component
|
||||
class BookCommonDao(
|
||||
@Qualifier("dslContextRO") private val dslRO: DSLContext,
|
||||
) {
|
||||
dslRW: DSLContext,
|
||||
@Qualifier("dslContextRO") dslRO: DSLContext,
|
||||
) : SplitDslDaoBase(dslRW, dslRO) {
|
||||
private val b = Tables.BOOK
|
||||
private val m = Tables.MEDIA
|
||||
private val d = Tables.BOOK_METADATA
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import org.gotson.komga.domain.model.SearchContext
|
|||
import org.gotson.komga.domain.persistence.BookRepository
|
||||
import org.gotson.komga.infrastructure.jooq.BookSearchHelper
|
||||
import org.gotson.komga.infrastructure.jooq.RequiredJoin
|
||||
import org.gotson.komga.infrastructure.jooq.SplitDslDaoBase
|
||||
import org.gotson.komga.infrastructure.jooq.TempTable.Companion.withTempTable
|
||||
import org.gotson.komga.infrastructure.jooq.rlbAlias
|
||||
import org.gotson.komga.infrastructure.jooq.toOrderBy
|
||||
|
|
@ -30,10 +31,11 @@ import java.time.ZoneId
|
|||
|
||||
@Component
|
||||
class BookDao(
|
||||
private val dslRW: DSLContext,
|
||||
@Qualifier("dslContextRO") private val dslRO: DSLContext,
|
||||
dslRW: DSLContext,
|
||||
@Qualifier("dslContextRO") dslRO: DSLContext,
|
||||
@param:Value("#{@komgaProperties.database.batchChunkSize}") private val batchSize: Int,
|
||||
) : BookRepository {
|
||||
) : SplitDslDaoBase(dslRW, dslRO),
|
||||
BookRepository {
|
||||
private val b = Tables.BOOK
|
||||
private val m = Tables.MEDIA
|
||||
private val d = Tables.BOOK_METADATA
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import org.gotson.komga.domain.model.SearchContext
|
|||
import org.gotson.komga.infrastructure.datasource.SqliteUdfDataSource
|
||||
import org.gotson.komga.infrastructure.jooq.BookSearchHelper
|
||||
import org.gotson.komga.infrastructure.jooq.RequiredJoin
|
||||
import org.gotson.komga.infrastructure.jooq.SplitDslDaoBase
|
||||
import org.gotson.komga.infrastructure.jooq.TempTable
|
||||
import org.gotson.komga.infrastructure.jooq.TempTable.Companion.withTempTable
|
||||
import org.gotson.komga.infrastructure.jooq.noCase
|
||||
|
|
@ -51,11 +52,13 @@ import java.net.URL
|
|||
|
||||
@Component
|
||||
class BookDtoDao(
|
||||
@Qualifier("dslContextRO") private val dslRO: DSLContext,
|
||||
dslRW: DSLContext,
|
||||
@Qualifier("dslContextRO") dslRO: DSLContext,
|
||||
private val luceneHelper: LuceneHelper,
|
||||
@param:Value("#{@komgaProperties.database.batchChunkSize}") private val batchSize: Int,
|
||||
private val bookCommonDao: BookCommonDao,
|
||||
) : BookDtoRepository {
|
||||
) : SplitDslDaoBase(dslRW, dslRO),
|
||||
BookDtoRepository {
|
||||
private val b = Tables.BOOK
|
||||
private val m = Tables.MEDIA
|
||||
private val d = Tables.BOOK_METADATA
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package org.gotson.komga.infrastructure.jooq.main
|
|||
import org.gotson.komga.domain.model.Author
|
||||
import org.gotson.komga.domain.model.BookMetadataAggregation
|
||||
import org.gotson.komga.domain.persistence.BookMetadataAggregationRepository
|
||||
import org.gotson.komga.infrastructure.jooq.SplitDslDaoBase
|
||||
import org.gotson.komga.infrastructure.jooq.TempTable.Companion.withTempTable
|
||||
import org.gotson.komga.jooq.main.Tables
|
||||
import org.gotson.komga.jooq.main.tables.records.BookMetadataAggregationAuthorRecord
|
||||
|
|
@ -18,10 +19,11 @@ import java.time.ZoneId
|
|||
|
||||
@Component
|
||||
class BookMetadataAggregationDao(
|
||||
private val dslRW: DSLContext,
|
||||
@Qualifier("dslContextRO") private val dslRO: DSLContext,
|
||||
dslRW: DSLContext,
|
||||
@Qualifier("dslContextRO") dslRO: DSLContext,
|
||||
@param:Value("#{@komgaProperties.database.batchChunkSize}") private val batchSize: Int,
|
||||
) : BookMetadataAggregationRepository {
|
||||
) : SplitDslDaoBase(dslRW, dslRO),
|
||||
BookMetadataAggregationRepository {
|
||||
private val d = Tables.BOOK_METADATA_AGGREGATION
|
||||
private val a = Tables.BOOK_METADATA_AGGREGATION_AUTHOR
|
||||
private val t = Tables.BOOK_METADATA_AGGREGATION_TAG
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import org.gotson.komga.domain.model.Author
|
|||
import org.gotson.komga.domain.model.BookMetadata
|
||||
import org.gotson.komga.domain.model.WebLink
|
||||
import org.gotson.komga.domain.persistence.BookMetadataRepository
|
||||
import org.gotson.komga.infrastructure.jooq.SplitDslDaoBase
|
||||
import org.gotson.komga.infrastructure.jooq.TempTable.Companion.withTempTable
|
||||
import org.gotson.komga.jooq.main.Tables
|
||||
import org.gotson.komga.jooq.main.tables.records.BookMetadataAuthorRecord
|
||||
|
|
@ -20,10 +21,11 @@ import java.time.ZoneId
|
|||
|
||||
@Component
|
||||
class BookMetadataDao(
|
||||
private val dslRW: DSLContext,
|
||||
@Qualifier("dslContextRO") private val dslRO: DSLContext,
|
||||
dslRW: DSLContext,
|
||||
@Qualifier("dslContextRO") dslRO: DSLContext,
|
||||
@param:Value("#{@komgaProperties.database.batchChunkSize}") private val batchSize: Int,
|
||||
) : BookMetadataRepository {
|
||||
) : SplitDslDaoBase(dslRW, dslRO),
|
||||
BookMetadataRepository {
|
||||
private val d = Tables.BOOK_METADATA
|
||||
private val a = Tables.BOOK_METADATA_AUTHOR
|
||||
private val bt = Tables.BOOK_METADATA_TAG
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package org.gotson.komga.infrastructure.jooq.main
|
||||
|
||||
import org.gotson.komga.infrastructure.jooq.SplitDslDaoBase
|
||||
import org.gotson.komga.interfaces.api.rest.dto.ClientSettingDto
|
||||
import org.gotson.komga.jooq.main.Tables
|
||||
import org.jooq.DSLContext
|
||||
|
|
@ -8,9 +9,9 @@ import org.springframework.stereotype.Component
|
|||
|
||||
@Component
|
||||
class ClientSettingsDtoDao(
|
||||
private val dslRW: DSLContext,
|
||||
@Qualifier("dslContextRO") private val dslRO: DSLContext,
|
||||
) {
|
||||
dslRW: DSLContext,
|
||||
@Qualifier("dslContextRO") dslRO: DSLContext,
|
||||
) : SplitDslDaoBase(dslRW, dslRO) {
|
||||
private val g = Tables.CLIENT_SETTINGS_GLOBAL
|
||||
private val u = Tables.CLIENT_SETTINGS_USER
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package org.gotson.komga.infrastructure.jooq.main
|
||||
|
||||
import org.gotson.komga.infrastructure.jooq.SplitDslDaoBase
|
||||
import org.gotson.komga.infrastructure.jooq.toOrderBy
|
||||
import org.gotson.komga.interfaces.api.persistence.HistoricalEventDtoRepository
|
||||
import org.gotson.komga.interfaces.api.rest.dto.HistoricalEventDto
|
||||
|
|
@ -15,8 +16,10 @@ import org.springframework.stereotype.Component
|
|||
|
||||
@Component
|
||||
class HistoricalEventDtoDao(
|
||||
@Qualifier("dslContextRO") private val dslRO: DSLContext,
|
||||
) : HistoricalEventDtoRepository {
|
||||
dslRW: DSLContext,
|
||||
@Qualifier("dslContextRO") dslRO: DSLContext,
|
||||
) : SplitDslDaoBase(dslRW, dslRO),
|
||||
HistoricalEventDtoRepository {
|
||||
private val e = Tables.HISTORICAL_EVENT
|
||||
private val ep = Tables.HISTORICAL_EVENT_PROPERTIES
|
||||
|
||||
|
|
@ -41,6 +44,7 @@ class HistoricalEventDtoDao(
|
|||
.map { er ->
|
||||
val epr = dslRO.selectFrom(ep).where(ep.ID.eq(er.id)).fetch()
|
||||
HistoricalEventDto(
|
||||
id = er.id,
|
||||
type = er.type,
|
||||
timestamp = er.timestamp,
|
||||
bookId = er.bookId,
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package org.gotson.komga.infrastructure.jooq.main
|
|||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import org.gotson.komga.domain.model.MediaExtensionEpub
|
||||
import org.gotson.komga.infrastructure.jooq.SplitDslDaoBase
|
||||
import org.gotson.komga.infrastructure.jooq.deserializeMediaExtension
|
||||
import org.gotson.komga.interfaces.api.kobo.dto.ContributorDto
|
||||
import org.gotson.komga.interfaces.api.kobo.dto.KoboBookMetadataDto
|
||||
|
|
@ -16,9 +17,11 @@ import java.time.ZoneId
|
|||
|
||||
@Component
|
||||
class KoboDtoDao(
|
||||
@Qualifier("dslContextRO") private val dslRO: DSLContext,
|
||||
dslRW: DSLContext,
|
||||
@Qualifier("dslContextRO") dslRO: DSLContext,
|
||||
private val mapper: ObjectMapper,
|
||||
) : KoboDtoRepository {
|
||||
) : SplitDslDaoBase(dslRW, dslRO),
|
||||
KoboDtoRepository {
|
||||
private val b = Tables.BOOK
|
||||
private val m = Tables.MEDIA
|
||||
private val d = Tables.BOOK_METADATA
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import org.gotson.komga.domain.model.ContentRestrictions
|
|||
import org.gotson.komga.domain.model.KomgaUser
|
||||
import org.gotson.komga.domain.model.UserRoles
|
||||
import org.gotson.komga.domain.persistence.KomgaUserRepository
|
||||
import org.gotson.komga.infrastructure.jooq.SplitDslDaoBase
|
||||
import org.gotson.komga.jooq.main.Tables
|
||||
import org.gotson.komga.jooq.main.tables.records.UserApiKeyRecord
|
||||
import org.gotson.komga.language.toCurrentTimeZone
|
||||
|
|
@ -21,9 +22,10 @@ import java.time.ZoneId
|
|||
|
||||
@Component
|
||||
class KomgaUserDao(
|
||||
private val dslRW: DSLContext,
|
||||
@Qualifier("dslContextRO") private val dslRO: DSLContext,
|
||||
) : KomgaUserRepository {
|
||||
dslRW: DSLContext,
|
||||
@Qualifier("dslContextRO") dslRO: DSLContext,
|
||||
) : SplitDslDaoBase(dslRW, dslRO),
|
||||
KomgaUserRepository {
|
||||
private val u = Tables.USER
|
||||
private val ur = Tables.USER_ROLE
|
||||
private val ul = Tables.USER_LIBRARY_SHARING
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package org.gotson.komga.infrastructure.jooq.main
|
|||
|
||||
import org.gotson.komga.domain.model.Library
|
||||
import org.gotson.komga.domain.persistence.LibraryRepository
|
||||
import org.gotson.komga.infrastructure.jooq.SplitDslDaoBase
|
||||
import org.gotson.komga.jooq.main.Tables
|
||||
import org.gotson.komga.jooq.main.tables.records.LibraryRecord
|
||||
import org.gotson.komga.language.toCurrentTimeZone
|
||||
|
|
@ -17,9 +18,10 @@ import java.time.ZoneId
|
|||
|
||||
@Component
|
||||
class LibraryDao(
|
||||
private val dslRW: DSLContext,
|
||||
@Qualifier("dslContextRO") private val dslRO: DSLContext,
|
||||
) : LibraryRepository {
|
||||
dslRW: DSLContext,
|
||||
@Qualifier("dslContextRO") dslRO: DSLContext,
|
||||
) : SplitDslDaoBase(dslRW, dslRO),
|
||||
LibraryRepository {
|
||||
private val l = Tables.LIBRARY
|
||||
private val ul = Tables.USER_LIBRARY_SHARING
|
||||
private val le = Tables.LIBRARY_EXCLUSIONS
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import org.gotson.komga.domain.model.MediaExtension
|
|||
import org.gotson.komga.domain.model.MediaFile
|
||||
import org.gotson.komga.domain.model.ProxyExtension
|
||||
import org.gotson.komga.domain.persistence.MediaRepository
|
||||
import org.gotson.komga.infrastructure.jooq.SplitDslDaoBase
|
||||
import org.gotson.komga.infrastructure.jooq.TempTable.Companion.withTempTable
|
||||
import org.gotson.komga.infrastructure.jooq.deserializeMediaExtension
|
||||
import org.gotson.komga.infrastructure.jooq.serializeJsonGz
|
||||
|
|
@ -27,11 +28,12 @@ import java.time.ZoneId
|
|||
|
||||
@Component
|
||||
class MediaDao(
|
||||
private val dslRW: DSLContext,
|
||||
@Qualifier("dslContextRO") private val dslRO: DSLContext,
|
||||
dslRW: DSLContext,
|
||||
@Qualifier("dslContextRO") dslRO: DSLContext,
|
||||
@param:Value("#{@komgaProperties.database.batchChunkSize}") private val batchSize: Int,
|
||||
private val mapper: ObjectMapper,
|
||||
) : MediaRepository {
|
||||
) : SplitDslDaoBase(dslRW, dslRO),
|
||||
MediaRepository {
|
||||
private val m = Tables.MEDIA
|
||||
private val p = Tables.MEDIA_PAGE
|
||||
private val f = Tables.MEDIA_FILE
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import org.gotson.komga.domain.model.PageHashKnown
|
|||
import org.gotson.komga.domain.model.PageHashMatch
|
||||
import org.gotson.komga.domain.model.PageHashUnknown
|
||||
import org.gotson.komga.domain.persistence.PageHashRepository
|
||||
import org.gotson.komga.infrastructure.jooq.SplitDslDaoBase
|
||||
import org.gotson.komga.infrastructure.jooq.toOrderBy
|
||||
import org.gotson.komga.jooq.main.Tables
|
||||
import org.gotson.komga.jooq.main.tables.records.PageHashRecord
|
||||
|
|
@ -25,9 +26,10 @@ import java.time.ZoneId
|
|||
|
||||
@Component
|
||||
class PageHashDao(
|
||||
private val dslRW: DSLContext,
|
||||
@Qualifier("dslContextRO") private val dslRO: DSLContext,
|
||||
) : PageHashRepository {
|
||||
dslRW: DSLContext,
|
||||
@Qualifier("dslContextRO") dslRO: DSLContext,
|
||||
) : SplitDslDaoBase(dslRW, dslRO),
|
||||
PageHashRepository {
|
||||
private val p = Tables.MEDIA_PAGE
|
||||
private val b = Tables.BOOK
|
||||
private val ph = Tables.PAGE_HASH
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import org.gotson.komga.domain.model.ContentRestrictions
|
|||
import org.gotson.komga.domain.model.ReadList
|
||||
import org.gotson.komga.domain.persistence.ReadListRepository
|
||||
import org.gotson.komga.infrastructure.datasource.SqliteUdfDataSource
|
||||
import org.gotson.komga.infrastructure.jooq.SplitDslDaoBase
|
||||
import org.gotson.komga.infrastructure.jooq.TempTable.Companion.withTempTable
|
||||
import org.gotson.komga.infrastructure.jooq.inOrNoCondition
|
||||
import org.gotson.komga.infrastructure.jooq.sortByValues
|
||||
|
|
@ -32,11 +33,12 @@ import java.util.SortedMap
|
|||
|
||||
@Component
|
||||
class ReadListDao(
|
||||
private val dslRW: DSLContext,
|
||||
@Qualifier("dslContextRO") private val dslRO: DSLContext,
|
||||
dslRW: DSLContext,
|
||||
@Qualifier("dslContextRO") dslRO: DSLContext,
|
||||
private val luceneHelper: LuceneHelper,
|
||||
@param:Value("#{@komgaProperties.database.batchChunkSize}") private val batchSize: Int,
|
||||
) : ReadListRepository {
|
||||
) : SplitDslDaoBase(dslRW, dslRO),
|
||||
ReadListRepository {
|
||||
private val rl = Tables.READLIST
|
||||
private val rlb = Tables.READLIST_BOOK
|
||||
private val b = Tables.BOOK
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import org.gotson.komga.domain.model.ReadListRequestBookMatchBook
|
|||
import org.gotson.komga.domain.model.ReadListRequestBookMatchSeries
|
||||
import org.gotson.komga.domain.model.ReadListRequestBookMatches
|
||||
import org.gotson.komga.domain.persistence.ReadListRequestRepository
|
||||
import org.gotson.komga.infrastructure.jooq.SplitDslDaoBase
|
||||
import org.gotson.komga.infrastructure.jooq.noCase
|
||||
import org.gotson.komga.jooq.main.Tables
|
||||
import org.jooq.DSLContext
|
||||
|
|
@ -18,8 +19,10 @@ import java.time.LocalDate
|
|||
|
||||
@Component
|
||||
class ReadListRequestDao(
|
||||
@Qualifier("dslContextRO") private val dslRO: DSLContext,
|
||||
) : ReadListRequestRepository {
|
||||
dslRW: DSLContext,
|
||||
@Qualifier("dslContextRO") dslRO: DSLContext,
|
||||
) : SplitDslDaoBase(dslRW, dslRO),
|
||||
ReadListRequestRepository {
|
||||
private val sd = Tables.SERIES_METADATA
|
||||
private val b = Tables.BOOK
|
||||
private val bd = Tables.BOOK_METADATA
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import com.fasterxml.jackson.databind.ObjectMapper
|
|||
import org.gotson.komga.domain.model.R2Locator
|
||||
import org.gotson.komga.domain.model.ReadProgress
|
||||
import org.gotson.komga.domain.persistence.ReadProgressRepository
|
||||
import org.gotson.komga.infrastructure.jooq.SplitDslDaoBase
|
||||
import org.gotson.komga.infrastructure.jooq.TempTable
|
||||
import org.gotson.komga.infrastructure.jooq.TempTable.Companion.withTempTable
|
||||
import org.gotson.komga.infrastructure.jooq.deserializeJsonGz
|
||||
|
|
@ -24,11 +25,12 @@ import java.time.ZoneId
|
|||
|
||||
@Component
|
||||
class ReadProgressDao(
|
||||
private val dslRW: DSLContext,
|
||||
@Qualifier("dslContextRO") private val dslRO: DSLContext,
|
||||
dslRW: DSLContext,
|
||||
@Qualifier("dslContextRO") dslRO: DSLContext,
|
||||
@param:Value("#{@komgaProperties.database.batchChunkSize}") private val batchSize: Int,
|
||||
private val mapper: ObjectMapper,
|
||||
) : ReadProgressRepository {
|
||||
) : SplitDslDaoBase(dslRW, dslRO),
|
||||
ReadProgressRepository {
|
||||
private val r = Tables.READ_PROGRESS
|
||||
private val rs = Tables.READ_PROGRESS_SERIES
|
||||
private val b = Tables.BOOK
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package org.gotson.komga.infrastructure.jooq.main
|
||||
|
||||
import org.gotson.komga.infrastructure.jooq.SplitDslDaoBase
|
||||
import org.gotson.komga.interfaces.api.persistence.ReadProgressDtoRepository
|
||||
import org.gotson.komga.interfaces.api.rest.dto.TachiyomiReadProgressDto
|
||||
import org.gotson.komga.interfaces.api.rest.dto.TachiyomiReadProgressV2Dto
|
||||
|
|
@ -16,8 +17,10 @@ import java.math.BigDecimal
|
|||
|
||||
@Component
|
||||
class ReadProgressDtoDao(
|
||||
@Qualifier("dslContextRO") private val dslRO: DSLContext,
|
||||
) : ReadProgressDtoRepository {
|
||||
dslRW: DSLContext,
|
||||
@Qualifier("dslContextRO") dslRO: DSLContext,
|
||||
) : SplitDslDaoBase(dslRW, dslRO),
|
||||
ReadProgressDtoRepository {
|
||||
private val rlb = Tables.READLIST_BOOK
|
||||
private val b = Tables.BOOK
|
||||
private val d = Tables.BOOK_METADATA
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package org.gotson.komga.infrastructure.jooq.main
|
|||
import org.gotson.komga.domain.model.Author
|
||||
import org.gotson.komga.domain.persistence.ReferentialRepository
|
||||
import org.gotson.komga.infrastructure.datasource.SqliteUdfDataSource
|
||||
import org.gotson.komga.infrastructure.jooq.SplitDslDaoBase
|
||||
import org.gotson.komga.infrastructure.jooq.udfStripAccents
|
||||
import org.gotson.komga.jooq.main.Tables
|
||||
import org.gotson.komga.jooq.main.tables.records.BookMetadataAggregationAuthorRecord
|
||||
|
|
@ -22,8 +23,10 @@ import java.time.LocalDate
|
|||
|
||||
@Component
|
||||
class ReferentialDao(
|
||||
@Qualifier("dslContextRO") private val dslRO: DSLContext,
|
||||
) : ReferentialRepository {
|
||||
dslRW: DSLContext,
|
||||
@Qualifier("dslContextRO") dslRO: DSLContext,
|
||||
) : SplitDslDaoBase(dslRW, dslRO),
|
||||
ReferentialRepository {
|
||||
private val a = Tables.BOOK_METADATA_AUTHOR
|
||||
private val sd = Tables.SERIES_METADATA
|
||||
private val bma = Tables.BOOK_METADATA_AGGREGATION
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import org.gotson.komga.domain.model.ContentRestrictions
|
|||
import org.gotson.komga.domain.model.SeriesCollection
|
||||
import org.gotson.komga.domain.persistence.SeriesCollectionRepository
|
||||
import org.gotson.komga.infrastructure.datasource.SqliteUdfDataSource
|
||||
import org.gotson.komga.infrastructure.jooq.SplitDslDaoBase
|
||||
import org.gotson.komga.infrastructure.jooq.TempTable.Companion.withTempTable
|
||||
import org.gotson.komga.infrastructure.jooq.inOrNoCondition
|
||||
import org.gotson.komga.infrastructure.jooq.sortByValues
|
||||
|
|
@ -31,11 +32,12 @@ import java.time.ZoneId
|
|||
|
||||
@Component
|
||||
class SeriesCollectionDao(
|
||||
private val dslRW: DSLContext,
|
||||
@Qualifier("dslContextRO") private val dslRO: DSLContext,
|
||||
dslRW: DSLContext,
|
||||
@Qualifier("dslContextRO") dslRO: DSLContext,
|
||||
private val luceneHelper: LuceneHelper,
|
||||
@param:Value("#{@komgaProperties.database.batchChunkSize}") private val batchSize: Int,
|
||||
) : SeriesCollectionRepository {
|
||||
) : SplitDslDaoBase(dslRW, dslRO),
|
||||
SeriesCollectionRepository {
|
||||
private val c = Tables.COLLECTION
|
||||
private val cs = Tables.COLLECTION_SERIES
|
||||
private val s = Tables.SERIES
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import org.gotson.komga.domain.model.Series
|
|||
import org.gotson.komga.domain.persistence.SeriesRepository
|
||||
import org.gotson.komga.infrastructure.jooq.RequiredJoin
|
||||
import org.gotson.komga.infrastructure.jooq.SeriesSearchHelper
|
||||
import org.gotson.komga.infrastructure.jooq.SplitDslDaoBase
|
||||
import org.gotson.komga.infrastructure.jooq.TempTable.Companion.withTempTable
|
||||
import org.gotson.komga.infrastructure.jooq.csAlias
|
||||
import org.gotson.komga.jooq.main.Tables
|
||||
|
|
@ -28,10 +29,11 @@ import java.time.ZoneId
|
|||
|
||||
@Component
|
||||
class SeriesDao(
|
||||
private val dslRW: DSLContext,
|
||||
@Qualifier("dslContextRO") private val dslRO: DSLContext,
|
||||
dslRW: DSLContext,
|
||||
@Qualifier("dslContextRO") dslRO: DSLContext,
|
||||
@param:Value("#{@komgaProperties.database.batchChunkSize}") private val batchSize: Int,
|
||||
) : SeriesRepository {
|
||||
) : SplitDslDaoBase(dslRW, dslRO),
|
||||
SeriesRepository {
|
||||
private val s = Tables.SERIES
|
||||
private val d = Tables.SERIES_METADATA
|
||||
private val rs = Tables.READ_PROGRESS_SERIES
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import org.gotson.komga.domain.model.SeriesSearch
|
|||
import org.gotson.komga.infrastructure.datasource.SqliteUdfDataSource
|
||||
import org.gotson.komga.infrastructure.jooq.RequiredJoin
|
||||
import org.gotson.komga.infrastructure.jooq.SeriesSearchHelper
|
||||
import org.gotson.komga.infrastructure.jooq.SplitDslDaoBase
|
||||
import org.gotson.komga.infrastructure.jooq.TempTable.Companion.withTempTable
|
||||
import org.gotson.komga.infrastructure.jooq.csAlias
|
||||
import org.gotson.komga.infrastructure.jooq.inOrNoCondition
|
||||
|
|
@ -52,10 +53,12 @@ const val BOOKS_READ_COUNT = "booksReadCount"
|
|||
|
||||
@Component
|
||||
class SeriesDtoDao(
|
||||
@Qualifier("dslContextRO") private val dslRO: DSLContext,
|
||||
dslRW: DSLContext,
|
||||
@Qualifier("dslContextRO") dslRO: DSLContext,
|
||||
private val luceneHelper: LuceneHelper,
|
||||
@param:Value("#{@komgaProperties.database.batchChunkSize}") private val batchSize: Int,
|
||||
) : SeriesDtoRepository {
|
||||
) : SplitDslDaoBase(dslRW, dslRO),
|
||||
SeriesDtoRepository {
|
||||
private val s = Tables.SERIES
|
||||
private val d = Tables.SERIES_METADATA
|
||||
private val rs = Tables.READ_PROGRESS_SERIES
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import org.gotson.komga.domain.model.AlternateTitle
|
|||
import org.gotson.komga.domain.model.SeriesMetadata
|
||||
import org.gotson.komga.domain.model.WebLink
|
||||
import org.gotson.komga.domain.persistence.SeriesMetadataRepository
|
||||
import org.gotson.komga.infrastructure.jooq.SplitDslDaoBase
|
||||
import org.gotson.komga.infrastructure.jooq.TempTable.Companion.withTempTable
|
||||
import org.gotson.komga.jooq.main.Tables
|
||||
import org.gotson.komga.jooq.main.tables.records.SeriesMetadataRecord
|
||||
|
|
@ -19,10 +20,11 @@ import java.time.ZoneId
|
|||
|
||||
@Component
|
||||
class SeriesMetadataDao(
|
||||
private val dslRW: DSLContext,
|
||||
@Qualifier("dslContextRO") private val dslRO: DSLContext,
|
||||
dslRW: DSLContext,
|
||||
@Qualifier("dslContextRO") dslRO: DSLContext,
|
||||
@param:Value("#{@komgaProperties.database.batchChunkSize}") private val batchSize: Int,
|
||||
) : SeriesMetadataRepository {
|
||||
) : SplitDslDaoBase(dslRW, dslRO),
|
||||
SeriesMetadataRepository {
|
||||
private val d = Tables.SERIES_METADATA
|
||||
private val g = Tables.SERIES_METADATA_GENRE
|
||||
private val st = Tables.SERIES_METADATA_TAG
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package org.gotson.komga.infrastructure.jooq.main
|
||||
|
||||
import org.gotson.komga.infrastructure.jooq.SplitDslDaoBase
|
||||
import org.gotson.komga.jooq.main.Tables
|
||||
import org.jooq.DSLContext
|
||||
import org.springframework.beans.factory.annotation.Qualifier
|
||||
|
|
@ -7,9 +8,9 @@ import org.springframework.stereotype.Component
|
|||
|
||||
@Component
|
||||
class ServerSettingsDao(
|
||||
private val dslRW: DSLContext,
|
||||
@Qualifier("dslContextRO") private val dslRO: DSLContext,
|
||||
) {
|
||||
dslRW: DSLContext,
|
||||
@Qualifier("dslContextRO") dslRO: DSLContext,
|
||||
) : SplitDslDaoBase(dslRW, dslRO) {
|
||||
private val s = Tables.SERVER_SETTINGS
|
||||
|
||||
fun <T> getSettingByKey(
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package org.gotson.komga.infrastructure.jooq.main
|
|||
import org.gotson.komga.domain.model.Sidecar
|
||||
import org.gotson.komga.domain.model.SidecarStored
|
||||
import org.gotson.komga.domain.persistence.SidecarRepository
|
||||
import org.gotson.komga.infrastructure.jooq.SplitDslDaoBase
|
||||
import org.gotson.komga.infrastructure.jooq.TempTable.Companion.withTempTable
|
||||
import org.gotson.komga.jooq.main.Tables
|
||||
import org.gotson.komga.jooq.main.tables.records.SidecarRecord
|
||||
|
|
@ -16,10 +17,11 @@ import java.net.URL
|
|||
|
||||
@Component
|
||||
class SidecarDao(
|
||||
private val dslRW: DSLContext,
|
||||
@Qualifier("dslContextRO") private val dslRO: DSLContext,
|
||||
dslRW: DSLContext,
|
||||
@Qualifier("dslContextRO") dslRO: DSLContext,
|
||||
@param:Value("#{@komgaProperties.database.batchChunkSize}") private val batchSize: Int,
|
||||
) : SidecarRepository {
|
||||
) : SplitDslDaoBase(dslRW, dslRO),
|
||||
SidecarRepository {
|
||||
private val sc = Tables.SIDECAR
|
||||
|
||||
override fun findAll(): Collection<SidecarStored> = dslRO.selectFrom(sc).fetch().map { it.toDomain() }
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import org.gotson.komga.domain.model.SyncPoint.ReadList.Companion.ON_DECK_ID
|
|||
import org.gotson.komga.domain.persistence.SyncPointRepository
|
||||
import org.gotson.komga.infrastructure.jooq.BookSearchHelper
|
||||
import org.gotson.komga.infrastructure.jooq.RequiredJoin
|
||||
import org.gotson.komga.infrastructure.jooq.SplitDslDaoBase
|
||||
import org.gotson.komga.jooq.main.Tables
|
||||
import org.gotson.komga.language.toZonedDateTime
|
||||
import org.jooq.DSLContext
|
||||
|
|
@ -28,10 +29,11 @@ import java.time.ZoneId
|
|||
|
||||
@Component
|
||||
class SyncPointDao(
|
||||
private val dslRW: DSLContext,
|
||||
@Qualifier("dslContextRO") private val dslRO: DSLContext,
|
||||
dslRW: DSLContext,
|
||||
@Qualifier("dslContextRO") dslRO: DSLContext,
|
||||
private val bookCommonDao: BookCommonDao,
|
||||
) : SyncPointRepository {
|
||||
) : SplitDslDaoBase(dslRW, dslRO),
|
||||
SyncPointRepository {
|
||||
private val b = Tables.BOOK
|
||||
private val m = Tables.MEDIA
|
||||
private val d = Tables.BOOK_METADATA
|
||||
|
|
@ -128,7 +130,7 @@ class SyncPointDao(
|
|||
.where(condition),
|
||||
).execute()
|
||||
|
||||
return dslRW.findByIdOrNull(syncPointId)!!
|
||||
return findByIdOrNull(syncPointId)!!
|
||||
}
|
||||
|
||||
@Transactional
|
||||
|
|
@ -172,10 +174,9 @@ class SyncPointDao(
|
|||
}
|
||||
}
|
||||
|
||||
override fun findByIdOrNull(syncPointId: String): SyncPoint? = dslRO.findByIdOrNull(syncPointId)
|
||||
|
||||
private fun DSLContext.findByIdOrNull(syncPointId: String): SyncPoint? =
|
||||
selectFrom(sp)
|
||||
override fun findByIdOrNull(syncPointId: String): SyncPoint? =
|
||||
dslRO
|
||||
.selectFrom(sp)
|
||||
.where(sp.ID.eq(syncPointId))
|
||||
.fetchInto(sp)
|
||||
.map {
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package org.gotson.komga.infrastructure.jooq.main
|
|||
import org.gotson.komga.domain.model.Dimension
|
||||
import org.gotson.komga.domain.model.ThumbnailBook
|
||||
import org.gotson.komga.domain.persistence.ThumbnailBookRepository
|
||||
import org.gotson.komga.infrastructure.jooq.SplitDslDaoBase
|
||||
import org.gotson.komga.infrastructure.jooq.TempTable.Companion.withTempTable
|
||||
import org.gotson.komga.jooq.main.Tables
|
||||
import org.gotson.komga.jooq.main.tables.records.ThumbnailBookRecord
|
||||
|
|
@ -15,10 +16,11 @@ import java.net.URL
|
|||
|
||||
@Component
|
||||
class ThumbnailBookDao(
|
||||
private val dslRW: DSLContext,
|
||||
@Qualifier("dslContextRO") private val dslRO: DSLContext,
|
||||
dslRW: DSLContext,
|
||||
@Qualifier("dslContextRO") dslRO: DSLContext,
|
||||
@param:Value("#{@komgaProperties.database.batchChunkSize}") private val batchSize: Int,
|
||||
) : ThumbnailBookRepository {
|
||||
) : SplitDslDaoBase(dslRW, dslRO),
|
||||
ThumbnailBookRepository {
|
||||
private val tb = Tables.THUMBNAIL_BOOK
|
||||
|
||||
override fun findAllByBookId(bookId: String): Collection<ThumbnailBook> =
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package org.gotson.komga.infrastructure.jooq.main
|
|||
import org.gotson.komga.domain.model.Dimension
|
||||
import org.gotson.komga.domain.model.ThumbnailReadList
|
||||
import org.gotson.komga.domain.persistence.ThumbnailReadListRepository
|
||||
import org.gotson.komga.infrastructure.jooq.SplitDslDaoBase
|
||||
import org.gotson.komga.jooq.main.Tables
|
||||
import org.gotson.komga.jooq.main.tables.records.ThumbnailReadlistRecord
|
||||
import org.jooq.DSLContext
|
||||
|
|
@ -12,9 +13,10 @@ import org.springframework.transaction.annotation.Transactional
|
|||
|
||||
@Component
|
||||
class ThumbnailReadListDao(
|
||||
private val dslRW: DSLContext,
|
||||
@Qualifier("dslContextRO") private val dslRO: DSLContext,
|
||||
) : ThumbnailReadListRepository {
|
||||
dslRW: DSLContext,
|
||||
@Qualifier("dslContextRO") dslRO: DSLContext,
|
||||
) : SplitDslDaoBase(dslRW, dslRO),
|
||||
ThumbnailReadListRepository {
|
||||
private val tr = Tables.THUMBNAIL_READLIST
|
||||
|
||||
override fun findAllByReadListId(readListId: String): Collection<ThumbnailReadList> =
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package org.gotson.komga.infrastructure.jooq.main
|
|||
import org.gotson.komga.domain.model.Dimension
|
||||
import org.gotson.komga.domain.model.ThumbnailSeriesCollection
|
||||
import org.gotson.komga.domain.persistence.ThumbnailSeriesCollectionRepository
|
||||
import org.gotson.komga.infrastructure.jooq.SplitDslDaoBase
|
||||
import org.gotson.komga.jooq.main.Tables
|
||||
import org.gotson.komga.jooq.main.tables.records.ThumbnailCollectionRecord
|
||||
import org.jooq.DSLContext
|
||||
|
|
@ -12,9 +13,10 @@ import org.springframework.transaction.annotation.Transactional
|
|||
|
||||
@Component
|
||||
class ThumbnailSeriesCollectionDao(
|
||||
private val dslRW: DSLContext,
|
||||
@Qualifier("dslContextRO") private val dslRO: DSLContext,
|
||||
) : ThumbnailSeriesCollectionRepository {
|
||||
dslRW: DSLContext,
|
||||
@Qualifier("dslContextRO") dslRO: DSLContext,
|
||||
) : SplitDslDaoBase(dslRW, dslRO),
|
||||
ThumbnailSeriesCollectionRepository {
|
||||
private val tc = Tables.THUMBNAIL_COLLECTION
|
||||
|
||||
override fun findByIdOrNull(thumbnailId: String): ThumbnailSeriesCollection? =
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package org.gotson.komga.infrastructure.jooq.main
|
|||
import org.gotson.komga.domain.model.Dimension
|
||||
import org.gotson.komga.domain.model.ThumbnailSeries
|
||||
import org.gotson.komga.domain.persistence.ThumbnailSeriesRepository
|
||||
import org.gotson.komga.infrastructure.jooq.SplitDslDaoBase
|
||||
import org.gotson.komga.infrastructure.jooq.TempTable.Companion.withTempTable
|
||||
import org.gotson.komga.jooq.main.Tables
|
||||
import org.gotson.komga.jooq.main.tables.records.ThumbnailSeriesRecord
|
||||
|
|
@ -15,10 +16,11 @@ import java.net.URL
|
|||
|
||||
@Component
|
||||
class ThumbnailSeriesDao(
|
||||
private val dslRW: DSLContext,
|
||||
@Qualifier("dslContextRO") private val dslRO: DSLContext,
|
||||
dslRW: DSLContext,
|
||||
@Qualifier("dslContextRO") dslRO: DSLContext,
|
||||
@param:Value("#{@komgaProperties.database.batchChunkSize}") private val batchSize: Int,
|
||||
) : ThumbnailSeriesRepository {
|
||||
) : SplitDslDaoBase(dslRW, dslRO),
|
||||
ThumbnailSeriesRepository {
|
||||
private val ts = Tables.THUMBNAIL_SERIES
|
||||
|
||||
override fun findByIdOrNull(thumbnailId: String): ThumbnailSeries? =
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import com.fasterxml.jackson.databind.ObjectMapper
|
|||
import io.github.oshai.kotlinlogging.KotlinLogging
|
||||
import org.gotson.komga.application.tasks.Task
|
||||
import org.gotson.komga.application.tasks.TasksRepository
|
||||
import org.gotson.komga.infrastructure.jooq.SplitDslDaoBase
|
||||
import org.gotson.komga.jooq.tasks.Tables
|
||||
import org.jooq.DSLContext
|
||||
import org.jooq.Query
|
||||
|
|
@ -22,11 +23,12 @@ private val logger = KotlinLogging.logger {}
|
|||
@Component
|
||||
@DependsOn("flywaySecondaryMigrationInitializer")
|
||||
class TasksDao(
|
||||
@Qualifier("tasksDslContextRW") private val dslRW: DSLContext,
|
||||
@Qualifier("tasksDslContextRO") private val dslRO: DSLContext,
|
||||
@Qualifier("tasksDslContextRW") dslRW: DSLContext,
|
||||
@Qualifier("tasksDslContextRO") dslRO: DSLContext,
|
||||
@param:Value("#{@komgaProperties.tasksDb.batchChunkSize}") private val batchSize: Int,
|
||||
private val objectMapper: ObjectMapper,
|
||||
) : TasksRepository {
|
||||
) : SplitDslDaoBase(dslRW, dslRO),
|
||||
TasksRepository {
|
||||
private val t = Tables.TASK
|
||||
|
||||
private val tasksAvailableCondition =
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ import org.springframework.util.LinkedMultiValueMap
|
|||
import org.springframework.web.client.RestClient
|
||||
import org.springframework.web.client.toEntity
|
||||
import org.springframework.web.server.ResponseStatusException
|
||||
import org.springframework.web.util.DefaultUriBuilderFactory
|
||||
import kotlin.time.Duration.Companion.minutes
|
||||
import kotlin.time.toJavaDuration
|
||||
|
||||
|
|
@ -29,11 +30,15 @@ class KoboProxy(
|
|||
private val komgaSyncTokenGenerator: KomgaSyncTokenGenerator,
|
||||
private val komgaSettingsProvider: KomgaSettingsProvider,
|
||||
) {
|
||||
private val koboApiClient =
|
||||
private val koboApiClient: RestClient =
|
||||
RestClient
|
||||
.builder()
|
||||
.baseUrl("https://storeapi.kobo.com")
|
||||
.requestFactory(
|
||||
.uriBuilderFactory(
|
||||
DefaultUriBuilderFactory("https://storeapi.kobo.com")
|
||||
.apply {
|
||||
this.encodingMode = DefaultUriBuilderFactory.EncodingMode.NONE
|
||||
},
|
||||
).requestFactory(
|
||||
ClientHttpRequestFactoryBuilder.reactor().build(
|
||||
ClientHttpRequestFactorySettings
|
||||
.defaults()
|
||||
|
|
@ -42,7 +47,7 @@ class KoboProxy(
|
|||
),
|
||||
).build()
|
||||
|
||||
private val pathRegex = """\/kobo\/[-\w]*(.*)""".toRegex()
|
||||
private val pathRegex = """/kobo/[-\w]*(.*)""".toRegex()
|
||||
|
||||
private val headersOutInclude =
|
||||
setOf(
|
||||
|
|
@ -50,6 +55,7 @@ class KoboProxy(
|
|||
HttpHeaders.USER_AGENT,
|
||||
HttpHeaders.ACCEPT,
|
||||
HttpHeaders.ACCEPT_LANGUAGE,
|
||||
HttpHeaders.CONTENT_TYPE,
|
||||
)
|
||||
|
||||
private val headersOutExclude =
|
||||
|
|
@ -88,7 +94,7 @@ class KoboProxy(
|
|||
.uri { uriBuilder ->
|
||||
uriBuilder
|
||||
.path(path)
|
||||
.queryParams(LinkedMultiValueMap(request.parameterMap.mapValues { it.value.toList() }))
|
||||
.query(request.queryString)
|
||||
.build()
|
||||
.also { logger.debug { "Proxy URL: $it" } }
|
||||
}.headers { headersOut ->
|
||||
|
|
@ -110,6 +116,7 @@ class KoboProxy(
|
|||
}.apply { if (body != null) body(body) }
|
||||
.retrieve()
|
||||
.onStatus(HttpStatusCode::isError) { _, response ->
|
||||
logger.debug { "Kobo response: ${response.statusCode}: ${response.body.bufferedReader().use { it.readText() }}" }
|
||||
throw ResponseStatusException(response.statusCode, response.statusText)
|
||||
}.toEntity<JsonNode>()
|
||||
|
||||
|
|
@ -161,6 +168,7 @@ class KoboProxy(
|
|||
"audiobook_subscription_tiers": "https://www.kobo.com/{region}/{language}/checkoutoption/21C6D938-934B-4A91-B979-E14D70B2F280",
|
||||
"authorproduct_recommendations": "https://storeapi.kobo.com/v1/products/books/authors/recommendations",
|
||||
"autocomplete": "https://storeapi.kobo.com/v1/products/autocomplete",
|
||||
"bam": "https://storeapi.kobo.com/v2/activity/bam/success",
|
||||
"blackstone_header": {
|
||||
"key": "x-amz-request-payer",
|
||||
"value": "requester"
|
||||
|
|
@ -173,6 +181,7 @@ class KoboProxy(
|
|||
"browse_history": "https://storeapi.kobo.com/v1/user/browsehistory",
|
||||
"categories": "https://storeapi.kobo.com/v1/categories",
|
||||
"categories_page": "https://www.kobo.com/ebooks/categories",
|
||||
"categoriesv2": "https://storeapi.kobo.com/api/v2/Categories/Top",
|
||||
"category": "https://storeapi.kobo.com/v1/categories/{CategoryId}",
|
||||
"category_featured_lists": "https://storeapi.kobo.com/v1/categories/{CategoryId}/featured",
|
||||
"category_products": "https://storeapi.kobo.com/v1/categories/{CategoryId}/products",
|
||||
|
|
@ -180,6 +189,7 @@ class KoboProxy(
|
|||
"client_authd_referral": "https://authorize.kobo.com/api/AuthenticatedReferral/client/v1/getLink",
|
||||
"configuration_data": "https://storeapi.kobo.com/v1/configuration",
|
||||
"content_access_book": "https://storeapi.kobo.com/v1/products/books/{ProductId}/access",
|
||||
"contributorsv2": "https://storeapi.kobo.com/v2/contributors/author",
|
||||
"customer_care_live_chat": "https://v2.zopim.com/widget/livechat.html?key=Y6gwUmnu4OATxN3Tli4Av9bYN319BTdO",
|
||||
"daily_deal": "https://storeapi.kobo.com/v1/products/dailydeal",
|
||||
"deals": "https://storeapi.kobo.com/v1/deals",
|
||||
|
|
@ -190,14 +200,19 @@ class KoboProxy(
|
|||
"device_refresh": "https://storeapi.kobo.com/v1/auth/refresh",
|
||||
"dictionary_host": "https://ereaderfiles.kobo.com",
|
||||
"discovery_host": "https://discovery.kobobooks.com",
|
||||
"display_accessibility_enabled": "False",
|
||||
"display_parental_controls_enabled": "True",
|
||||
"dropbox_link_account_poll": "https://authorize.kobo.com/{region}/{language}/LinkDropbox",
|
||||
"dropbox_link_account_start": "https://authorize.kobo.com/LinkDropbox/start",
|
||||
"ereaderdevices": "https://storeapi.kobo.com/v2/products/EReaderDeviceFeeds",
|
||||
"eula_page": "https://www.kobo.com/termsofuse?style=onestore",
|
||||
"exchange_auth": "https://storeapi.kobo.com/v1/auth/exchange",
|
||||
"external_book": "https://storeapi.kobo.com/v1/products/books/external/{Ids}",
|
||||
"facebook_sso_page": "https://authorize.kobo.com/signin/provider/Facebook/login?returnUrl=http://kobo.com/",
|
||||
"facebook_sso_page": "https://authorize.kobo.com/signin/provider/Facebook/login?returnUrl=https://kobo.com/",
|
||||
"featured_list": "https://storeapi.kobo.com/v1/products/featured/{FeaturedListId}",
|
||||
"featured_lists": "https://storeapi.kobo.com/v1/products/featured",
|
||||
"featuredlist2": "https://storeapi.kobo.com/v2/products/list/featured",
|
||||
"fixed_layout_page_cache_enabled": "True",
|
||||
"free_books_page": {
|
||||
"EN": "https://www.kobo.com/{region}/{language}/p/free-ebooks",
|
||||
"FR": "https://www.kobo.com/{region}/{language}/p/livres-gratuits",
|
||||
|
|
@ -207,6 +222,7 @@ class KoboProxy(
|
|||
},
|
||||
"fte_feedback": "https://storeapi.kobo.com/v1/products/ftefeedback",
|
||||
"funnel_metrics": "https://storeapi.kobo.com/v1/funnelmetrics",
|
||||
"geography_data": "https://storeapi.kobo.com/v2/configuration/geography/country",
|
||||
"get_download_keys": "https://storeapi.kobo.com/v1/library/downloadkeys",
|
||||
"get_download_link": "https://storeapi.kobo.com/v1/library/downloadlink",
|
||||
"get_tests_request": "https://storeapi.kobo.com/v1/analytics/gettests",
|
||||
|
|
@ -214,10 +230,13 @@ class KoboProxy(
|
|||
"giftcard_redeem_url": "https://www.kobo.com/{storefront}/{language}/redeem",
|
||||
"googledrive_link_account_start": "https://authorize.kobo.com/{region}/{language}/linkcloudstorage/provider/google_drive",
|
||||
"gpb_flow_enabled": "False",
|
||||
"help_page": "http://www.kobo.com/help",
|
||||
"help_page": "https://www.kobo.com/help",
|
||||
"image_host": "//cdn.kobo.com/book-images/",
|
||||
"image_url_quality_template": "https://cdn.kobo.com/book-images/{ImageId}/{Width}/{Height}/{Quality}/{IsGreyscale}/image.jpg",
|
||||
"image_url_template": "https://cdn.kobo.com/book-images/{ImageId}/{Width}/{Height}/false/image.jpg",
|
||||
"instapaper_enabled": "True",
|
||||
"instapaper_env_url": "https://www.instapaper.com/api/kobo",
|
||||
"instapaper_link_account_start": "https://authorize.kobo.com/{region}/{language}/linkinstapaper",
|
||||
"kobo_audiobooks_credit_redemption": "True",
|
||||
"kobo_audiobooks_enabled": "True",
|
||||
"kobo_audiobooks_orange_deal_enabled": "True",
|
||||
|
|
@ -244,7 +263,8 @@ class KoboProxy(
|
|||
"love_dashboard_page": "https://www.kobo.com/{region}/{language}/kobosuperpoints",
|
||||
"love_points_redemption_page": "https://www.kobo.com/{region}/{language}/KoboSuperPointsRedemption?productId={ProductId}",
|
||||
"magazine_landing_page": "https://www.kobo.com/emagazines",
|
||||
"more_sign_in_options": "https://authorize.kobo.com/signin?returnUrl=http://kobo.com/#allProviders",
|
||||
"more_sign_in_options": "https://authorize.kobo.com/signin?returnUrl=https://kobo.com/#allProviders",
|
||||
"morebyauthor": "https://storeapi.kobo.com/v2/products/recommendations/morebyauthor",
|
||||
"notebooks": "https://storeapi.kobo.com/api/internal/notebooks",
|
||||
"notifications_registration_issue": "https://storeapi.kobo.com/v1/notifications/registration",
|
||||
"oauth_host": "https://oauth.kobo.com",
|
||||
|
|
@ -258,9 +278,13 @@ class KoboProxy(
|
|||
"product_prices": "https://storeapi.kobo.com/v1/products/{ProductIds}/prices",
|
||||
"product_recommendations": "https://storeapi.kobo.com/v1/products/{ProductId}/recommendations",
|
||||
"product_reviews": "https://storeapi.kobo.com/v1/products/{ProductIds}/reviews",
|
||||
"productbyid": "https://storeapi.kobo.com/v2/products/itemDetailById/{ProductType}/{Id}",
|
||||
"productbyslug": "https://storeapi.kobo.com/v2/products/itemDetail/{ProductType}/{Slug}",
|
||||
"products": "https://storeapi.kobo.com/v1/products",
|
||||
"productstatebyid": "https://storeapi.kobo.com/v2/products/itemStateById/{ProductType}/{Id}",
|
||||
"productstatebyslug": "https://storeapi.kobo.com/v2/products/itemState/{ProductType}/{Slug}",
|
||||
"productsv2": "https://storeapi.kobo.com/v2/products",
|
||||
"provider_external_sign_in_page": "https://authorize.kobo.com/ExternalSignIn/{providerName}?returnUrl=http://kobo.com/",
|
||||
"provider_external_sign_in_page": "https://authorize.kobo.com/ExternalSignIn/{providerName}?returnUrl=https://kobo.com/",
|
||||
"purchase_buy": "https://www.kobo.com/checkoutoption/",
|
||||
"purchase_buy_templated": "https://www.kobo.com/{region}/{language}/checkoutoption/{ProductId}",
|
||||
"quickbuy_checkout": "https://storeapi.kobo.com/v1/store/quickbuy/{PurchaseId}/checkout",
|
||||
|
|
@ -270,7 +294,9 @@ class KoboProxy(
|
|||
"reading_services_host": "https://readingservices.kobo.com",
|
||||
"reading_state": "https://storeapi.kobo.com/v1/library/{Ids}/state",
|
||||
"redeem_interstitial_page": "https://www.kobo.com",
|
||||
"registration_page": "https://authorize.kobo.com/signup?returnUrl=http://kobo.com/",
|
||||
"reflowable_page_cache_enabled": "True",
|
||||
"registration_page": "https://authorize.kobo.com/signup?returnUrl=https://kobo.com/",
|
||||
"related": "https://storeapi.kobo.com/v2/products/recommendations/related",
|
||||
"related_items": "https://storeapi.kobo.com/v1/products/{Id}/related",
|
||||
"remaining_book_series": "https://storeapi.kobo.com/v1/products/books/series/{SeriesId}",
|
||||
"rename_tag": "https://storeapi.kobo.com/v1/library/tags/{TagId}",
|
||||
|
|
@ -293,14 +319,19 @@ class KoboProxy(
|
|||
"tags": "https://storeapi.kobo.com/v1/library/tags",
|
||||
"taste_profile": "https://storeapi.kobo.com/v1/products/tasteprofile",
|
||||
"terms_of_sale_page": "https://authorize.kobo.com/{region}/{language}/terms/termsofsale",
|
||||
"topproducts": "https://storeapi.kobo.com/v2/products/list/topproducts",
|
||||
"tracking": "https://storeapi.kobo.com/v2/tracking/searchperformed",
|
||||
"update_accessibility_to_preview": "https://storeapi.kobo.com/v1/library/{EntitlementIds}/preview",
|
||||
"use_one_store": "True",
|
||||
"user_currencyconversion": "https://storeapi.kobo.com/v1/user/currency/convert",
|
||||
"user_loyalty_benefits": "https://storeapi.kobo.com/v1/user/loyalty/benefits",
|
||||
"user_platform": "https://storeapi.kobo.com/v1/user/platform",
|
||||
"user_profile": "https://storeapi.kobo.com/v1/user/profile",
|
||||
"user_ratings": "https://storeapi.kobo.com/v1/user/ratings",
|
||||
"user_recommendations": "https://storeapi.kobo.com/v1/user/recommendations",
|
||||
"user_reviews": "https://storeapi.kobo.com/v1/user/reviews",
|
||||
"user_tasteprofile_complete": "https://storeapi.kobo.com/v2/user/tasteprofile/complete",
|
||||
"user_tasteprofile_genre": "https://storeapi.kobo.com/v2/user/tasteprofile/genre",
|
||||
"user_wishlist": "https://storeapi.kobo.com/v1/user/wishlist",
|
||||
"userguide_host": "https://ereaderfiles.kobo.com",
|
||||
"wishlist_page": "https://www.kobo.com/{region}/{language}/account/wishlist"
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ class EpubExtractor(
|
|||
?: // try id="cover-image"
|
||||
manifest.values.firstOrNull { it.id == "cover-image" }
|
||||
if (coverManifestItem != null) {
|
||||
val href = coverManifestItem.href
|
||||
val href = URLDecoder.decode(coverManifestItem.href, Charsets.UTF_8)
|
||||
val mediaType = coverManifestItem.mediaType
|
||||
val coverPath = normalizeHref(opfDir, href)
|
||||
zip.getEntryBytes(coverPath)?.let { coverBytes ->
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ class LocalArtworkProvider(
|
|||
private val imageAnalyzer: ImageAnalyzer,
|
||||
) : SidecarSeriesConsumer,
|
||||
SidecarBookConsumer {
|
||||
val supportedExtensions = listOf("png", "jpeg", "jpg", "tbn", "webp")
|
||||
val supportedExtensions = listOf("png", "jpeg", "jpg", "tbn", "webp", "gif")
|
||||
val supportedSeriesFiles = listOf("cover", "default", "folder", "poster", "series")
|
||||
|
||||
fun getBookThumbnails(book: Book): List<ThumbnailBook> {
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package org.gotson.komga.infrastructure.security
|
|||
import jakarta.servlet.Filter
|
||||
import org.gotson.komga.domain.model.UserRoles
|
||||
import org.gotson.komga.infrastructure.configuration.KomgaSettingsProvider
|
||||
import org.gotson.komga.infrastructure.hash.Hasher
|
||||
import org.gotson.komga.infrastructure.security.apikey.ApiKeyAuthenticationFilter
|
||||
import org.gotson.komga.infrastructure.security.apikey.ApiKeyAuthenticationProvider
|
||||
import org.gotson.komga.infrastructure.security.apikey.HeaderApiKeyAuthenticationConverter
|
||||
|
|
@ -34,6 +35,7 @@ import org.springframework.security.web.authentication.AnonymousAuthenticationFi
|
|||
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler
|
||||
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource
|
||||
import org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices
|
||||
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter
|
||||
import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher
|
||||
|
||||
@Configuration
|
||||
|
|
@ -51,6 +53,7 @@ class SecurityConfiguration(
|
|||
private val opdsAuthenticationEntryPoint: OpdsAuthenticationEntryPoint,
|
||||
private val authenticationEventPublisher: AuthenticationEventPublisher,
|
||||
private val tokenEncoder: TokenEncoder,
|
||||
private val hasher: Hasher,
|
||||
clientRegistrationRepository: InMemoryClientRegistrationRepository?,
|
||||
) {
|
||||
private val oauth2Enabled = clientRegistrationRepository != null
|
||||
|
|
@ -158,7 +161,7 @@ class SecurityConfiguration(
|
|||
)
|
||||
}
|
||||
|
||||
http.addFilterBefore(restAuthenticationFilter(), AnonymousAuthenticationFilter::class.java)
|
||||
http.addFilterAfter(restAuthenticationFilter(), BasicAuthenticationFilter::class.java)
|
||||
|
||||
return http.build()
|
||||
}
|
||||
|
|
@ -239,19 +242,19 @@ class SecurityConfiguration(
|
|||
fun koboAuthenticationFilter(): Filter =
|
||||
ApiKeyAuthenticationFilter(
|
||||
apiKeyAuthenticationProvider(),
|
||||
UriRegexApiKeyAuthenticationConverter(Regex("""/kobo/([\w-]+)"""), tokenEncoder, userAgentWebAuthenticationDetailsSource),
|
||||
UriRegexApiKeyAuthenticationConverter(Regex("""/kobo/([\w-]+)"""), hasher, tokenEncoder, userAgentWebAuthenticationDetailsSource),
|
||||
)
|
||||
|
||||
fun kosyncAuthenticationFilter(): Filter =
|
||||
ApiKeyAuthenticationFilter(
|
||||
apiKeyAuthenticationProvider(),
|
||||
HeaderApiKeyAuthenticationConverter("X-Auth-User", tokenEncoder, userAgentWebAuthenticationDetailsSource),
|
||||
HeaderApiKeyAuthenticationConverter("X-Auth-User", hasher, tokenEncoder, userAgentWebAuthenticationDetailsSource),
|
||||
)
|
||||
|
||||
fun restAuthenticationFilter(): Filter =
|
||||
ApiKeyAuthenticationFilter(
|
||||
apiKeyAuthenticationProvider(),
|
||||
HeaderApiKeyAuthenticationConverter("X-API-Key", tokenEncoder, userAgentWebAuthenticationDetailsSource),
|
||||
HeaderApiKeyAuthenticationConverter("X-API-Key", hasher, tokenEncoder, userAgentWebAuthenticationDetailsSource),
|
||||
)
|
||||
|
||||
fun apiKeyAuthenticationProvider(): AuthenticationManager =
|
||||
|
|
|
|||
|
|
@ -55,6 +55,8 @@ class ApiKeyAuthenticationFilter(
|
|||
} catch (ex: AuthenticationException) {
|
||||
unsuccessfulAuthentication(request, response, ex)
|
||||
}
|
||||
|
||||
filterChain.doFilter(request, response)
|
||||
}
|
||||
|
||||
private fun unsuccessfulAuthentication(
|
||||
|
|
@ -78,7 +80,6 @@ class ApiKeyAuthenticationFilter(
|
|||
}
|
||||
securityContextHolderStrategy.context = context
|
||||
securityContextRepository.saveContext(context, request, response)
|
||||
filterChain.doFilter(request, response)
|
||||
}
|
||||
|
||||
private fun authenticationIsRequired(username: String): Boolean {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package org.gotson.komga.infrastructure.security.apikey
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest
|
||||
import org.gotson.komga.infrastructure.hash.Hasher
|
||||
import org.gotson.komga.infrastructure.security.TokenEncoder
|
||||
import org.springframework.security.authentication.AuthenticationDetailsSource
|
||||
import org.springframework.security.core.Authentication
|
||||
|
|
@ -11,11 +12,13 @@ import org.springframework.security.web.authentication.AuthenticationConverter
|
|||
* and convert it to an [ApiKeyAuthenticationToken]
|
||||
*
|
||||
* @property headerName the header name from which to retrieve the API key
|
||||
* @property hasher the hasher to use to encode the API key as username in the [Authentication] object
|
||||
* @property tokenEncoder the encoder to use to encode the API key in the [Authentication] object
|
||||
* @property authenticationDetailsSource the [AuthenticationDetailsSource] to enrich the [Authentication] details
|
||||
*/
|
||||
class HeaderApiKeyAuthenticationConverter(
|
||||
private val headerName: String,
|
||||
private val hasher: Hasher,
|
||||
private val tokenEncoder: TokenEncoder,
|
||||
private val authenticationDetailsSource: AuthenticationDetailsSource<HttpServletRequest, *>,
|
||||
) : AuthenticationConverter {
|
||||
|
|
@ -23,7 +26,8 @@ class HeaderApiKeyAuthenticationConverter(
|
|||
request
|
||||
.getHeader(headerName)
|
||||
?.let {
|
||||
val (maskedToken, hashedToken) = it.take(6) + "*".repeat(6) to tokenEncoder.encode(it)
|
||||
val maskedToken = hasher.computeHash(it)
|
||||
val hashedToken = tokenEncoder.encode(it)
|
||||
ApiKeyAuthenticationToken
|
||||
.unauthenticated(maskedToken, hashedToken)
|
||||
.apply { details = authenticationDetailsSource.buildDetails(request) }
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package org.gotson.komga.infrastructure.security.apikey
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest
|
||||
import org.gotson.komga.infrastructure.hash.Hasher
|
||||
import org.gotson.komga.infrastructure.security.TokenEncoder
|
||||
import org.springframework.security.authentication.AuthenticationDetailsSource
|
||||
import org.springframework.security.core.Authentication
|
||||
|
|
@ -11,11 +12,13 @@ import org.springframework.security.web.authentication.AuthenticationConverter
|
|||
* request URI, and convert it to an [ApiKeyAuthenticationToken]
|
||||
*
|
||||
* @property tokenRegex the regex used to extract the API key
|
||||
* @property tokenEncoder the encoder to use to encode the API key in the [Authentication] object
|
||||
* @property hasher the hasher to use to encode the API key as username in the [Authentication] object
|
||||
* @property tokenEncoder the encoder to use to encode the API key as credentials in the [Authentication] object
|
||||
* @property authenticationDetailsSource the [AuthenticationDetailsSource] to enrich the [Authentication] details
|
||||
*/
|
||||
class UriRegexApiKeyAuthenticationConverter(
|
||||
private val tokenRegex: Regex,
|
||||
private val hasher: Hasher,
|
||||
private val tokenEncoder: TokenEncoder,
|
||||
private val authenticationDetailsSource: AuthenticationDetailsSource<HttpServletRequest, *>,
|
||||
) : AuthenticationConverter {
|
||||
|
|
@ -24,7 +27,8 @@ class UriRegexApiKeyAuthenticationConverter(
|
|||
?.let {
|
||||
tokenRegex.find(it)?.groupValues?.lastOrNull()
|
||||
}?.let {
|
||||
val (maskedToken, hashedToken) = it.take(6) + "*".repeat(6) to tokenEncoder.encode(it)
|
||||
val maskedToken = hasher.computeHash(it)
|
||||
val hashedToken = tokenEncoder.encode(it)
|
||||
ApiKeyAuthenticationToken
|
||||
.unauthenticated(maskedToken, hashedToken)
|
||||
.apply { details = authenticationDetailsSource.buildDetails(request) }
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@ fun ResponseEntity.BodyBuilder.setCachePrivate() = this.cacheControl(cachePrivat
|
|||
val cachePrivate =
|
||||
CacheControl
|
||||
.maxAge(0, TimeUnit.SECONDS)
|
||||
.noTransform()
|
||||
.cachePrivate()
|
||||
.mustRevalidate()
|
||||
|
||||
|
|
|
|||
|
|
@ -194,6 +194,7 @@ class KoboController(
|
|||
try {
|
||||
koboProxy.proxyCurrentRequest().body?.get("Resources")
|
||||
} catch (e: Exception) {
|
||||
if (e is ResponseStatusException && e.statusCode == HttpStatus.UNAUTHORIZED) throw e
|
||||
logger.warn { "Failed to get response from Kobo /v1/initialization, fallback to noproxy" }
|
||||
null
|
||||
} ?: koboProxy.nativeKoboResources
|
||||
|
|
@ -233,7 +234,7 @@ class KoboController(
|
|||
): Any {
|
||||
try {
|
||||
return koboProxy.proxyCurrentRequest(body)
|
||||
} catch (e: Exception) {
|
||||
} catch (_: Exception) {
|
||||
logger.warn { "Failed to get response from Kobo /v1/auth/device, fallback to noproxy" }
|
||||
}
|
||||
|
||||
|
|
@ -395,7 +396,7 @@ class KoboController(
|
|||
addAll(
|
||||
// changed books are also passed as changed reading state because Kobo does not process ChangedEntitlement even if it contains a ReadingState
|
||||
(booksChanged.content + changedReadingState.content).mapNotNull { book ->
|
||||
readProgress[book.bookId]?.let { it ->
|
||||
readProgress[book.bookId]?.let {
|
||||
ChangedReadingStateDto(
|
||||
WrappedReadingStateDto(
|
||||
it.toDto(),
|
||||
|
|
@ -570,7 +571,10 @@ class KoboController(
|
|||
locator =
|
||||
if (koboUpdate.statusInfo.status == StatusDto.FINISHED) {
|
||||
// If the book is finished, Kobo sends the first resource instead of the last, so we can't trust what Kobo sent
|
||||
val epubExtension = mediaRepository.findExtensionByIdOrNull(book.id) as? MediaExtensionEpub ?: throw IllegalArgumentException("Epub extension not found")
|
||||
val epubExtension =
|
||||
mediaRepository.findExtensionByIdOrNull(book.id) as? MediaExtensionEpub
|
||||
?: throw IllegalArgumentException("Epub extension not found")
|
||||
.also { logger.error { "Epub extension not found for book ${book.id}. Book should be re-analyzed." } }
|
||||
epubExtension.positions.last()
|
||||
} else {
|
||||
R2Locator(
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package org.gotson.komga.interfaces.api.kosync
|
||||
|
||||
import io.github.oshai.kotlinlogging.KotlinLogging
|
||||
import org.gotson.komga.domain.model.MediaExtensionEpub
|
||||
import org.gotson.komga.domain.model.MediaProfile
|
||||
import org.gotson.komga.domain.model.R2Device
|
||||
|
|
@ -25,6 +26,8 @@ import org.springframework.web.bind.annotation.RestController
|
|||
import org.springframework.web.server.ResponseStatusException
|
||||
import java.time.ZonedDateTime
|
||||
|
||||
private val logger = KotlinLogging.logger {}
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/koreader", produces = ["application/vnd.koreader.v1+json"])
|
||||
class KoreaderSyncController(
|
||||
|
|
@ -48,8 +51,14 @@ class KoreaderSyncController(
|
|||
@PathVariable bookHash: String,
|
||||
): DocumentProgressDto {
|
||||
val books = bookRepository.findAllByHashKoreader(bookHash)
|
||||
if (books.isEmpty()) throw ResponseStatusException(HttpStatus.NOT_FOUND, "Book not found")
|
||||
if (books.size > 1) throw ResponseStatusException(HttpStatus.CONFLICT, "More than 1 book found with the same hash")
|
||||
if (books.isEmpty()) {
|
||||
logger.debug { "No book found with KOReader hash: $bookHash" }
|
||||
throw ResponseStatusException(HttpStatus.NOT_FOUND, "Book not found")
|
||||
}
|
||||
if (books.size > 1) {
|
||||
logger.debug { "No unique book found with KOReader hash: $bookHash. Found ${books.size} books with the same hash." }
|
||||
throw ResponseStatusException(HttpStatus.CONFLICT, "More than 1 book found with the same hash")
|
||||
}
|
||||
|
||||
val book = books.first()
|
||||
val media = mediaRepository.findById(book.id)
|
||||
|
|
@ -69,7 +78,10 @@ class KoreaderSyncController(
|
|||
when (media.profile) {
|
||||
MediaProfile.DIVINA, MediaProfile.PDF -> readProgress.page.toString()
|
||||
MediaProfile.EPUB -> {
|
||||
val extension = mediaRepository.findExtensionByIdOrNull(book.id) as? MediaExtensionEpub ?: throw ResponseStatusException(HttpStatus.BAD_REQUEST, "Epub extension not found")
|
||||
val extension =
|
||||
mediaRepository.findExtensionByIdOrNull(book.id) as? MediaExtensionEpub
|
||||
?: throw ResponseStatusException(HttpStatus.BAD_REQUEST, "Epub extension not found")
|
||||
.also { logger.error { "Epub extension not found for book ${book.id}. Book should be re-analyzed." } }
|
||||
|
||||
// convert the href to its index for KOReader
|
||||
val resourceIndex =
|
||||
|
|
@ -81,6 +93,7 @@ class KoreaderSyncController(
|
|||
// return a progress string that points to the beginning of the resource
|
||||
"/body/DocFragment[${resourceIndex + 1}].0"
|
||||
}
|
||||
|
||||
null -> throw ResponseStatusException(HttpStatus.NOT_FOUND, "Book has no media profile")
|
||||
}
|
||||
|
||||
|
|
@ -99,8 +112,14 @@ class KoreaderSyncController(
|
|||
@RequestBody koreaderProgress: DocumentProgressDto,
|
||||
) {
|
||||
val books = bookRepository.findAllByHashKoreader(koreaderProgress.document)
|
||||
if (books.isEmpty()) throw ResponseStatusException(HttpStatus.NOT_FOUND, "Book not found")
|
||||
if (books.size > 1) throw ResponseStatusException(HttpStatus.CONFLICT, "More than 1 book found with the same hash")
|
||||
if (books.isEmpty()) {
|
||||
logger.debug { "No book found with KOReader hash: ${koreaderProgress.document}" }
|
||||
throw ResponseStatusException(HttpStatus.NOT_FOUND, "Book not found")
|
||||
}
|
||||
if (books.size > 1) {
|
||||
logger.debug { "No unique book found with KOReader hash: ${koreaderProgress.document}. Found ${books.size} books with the same hash." }
|
||||
throw ResponseStatusException(HttpStatus.CONFLICT, "More than 1 book found with the same hash")
|
||||
}
|
||||
|
||||
val book = books.first()
|
||||
val media = mediaRepository.findById(book.id)
|
||||
|
|
@ -139,8 +158,12 @@ class KoreaderSyncController(
|
|||
?.value
|
||||
?.toIntOrNull()
|
||||
?: throw ResponseStatusException(HttpStatus.BAD_REQUEST, "Could not get Epub resource index from progress: ${koreaderProgress.progress}")
|
||||
.also { logger.error { "Could not get Epub resource index from progress: ${koreaderProgress.progress}" } }
|
||||
|
||||
val extension = mediaRepository.findExtensionByIdOrNull(book.id) as? MediaExtensionEpub ?: throw ResponseStatusException(HttpStatus.BAD_REQUEST, "Epub extension not found")
|
||||
val extension =
|
||||
mediaRepository.findExtensionByIdOrNull(book.id) as? MediaExtensionEpub
|
||||
?: throw ResponseStatusException(HttpStatus.BAD_REQUEST, "Epub extension not found")
|
||||
.also { logger.error { "Epub extension not found for book ${book.id}. Book should be re-analyzed." } }
|
||||
|
||||
// get the href from the index provided by KOReader
|
||||
val href =
|
||||
|
|
|
|||
|
|
@ -268,7 +268,7 @@ class ReadListController(
|
|||
}
|
||||
|
||||
@Operation(summary = "Match ComicRack list", tags = [OpenApiConfiguration.TagNames.COMICRACK])
|
||||
@PostMapping("match/comicrack")
|
||||
@PostMapping("match/comicrack", consumes = [MediaType.MULTIPART_FORM_DATA_VALUE])
|
||||
@PreAuthorize("hasRole('ADMIN')")
|
||||
fun matchComicRackList(
|
||||
@RequestParam("file") file: MultipartFile,
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package org.gotson.komga.interfaces.api.rest.dto
|
|||
import java.time.LocalDateTime
|
||||
|
||||
data class HistoricalEventDto(
|
||||
val id: String,
|
||||
val type: String,
|
||||
val timestamp: LocalDateTime,
|
||||
val bookId: String?,
|
||||
|
|
|
|||
|
|
@ -46,6 +46,9 @@ spring:
|
|||
jackson:
|
||||
deserialization:
|
||||
FAIL_ON_NULL_FOR_PRIMITIVES: true
|
||||
mapper:
|
||||
accept-case-insensitive-properties: true
|
||||
accept-case-insensitive-values: true
|
||||
config:
|
||||
import:
|
||||
- "optional:file:\${komga.config-dir}/application.yml"
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ import javax.sql.DataSource
|
|||
|
||||
class DataSourcesConfigurationTest {
|
||||
@SpringBootTest
|
||||
@ActiveProfiles("test", "waltest")
|
||||
@Nested
|
||||
inner class WalMode(
|
||||
@Autowired private val dataSourceRW: DataSource,
|
||||
|
|
@ -27,6 +26,7 @@ class DataSourcesConfigurationTest {
|
|||
}
|
||||
|
||||
@SpringBootTest
|
||||
@ActiveProfiles("test", "memorydb")
|
||||
@Nested
|
||||
inner class MemoryMode(
|
||||
@Autowired private val dataSourceRW: DataSource,
|
||||
|
|
|
|||
5
komga/src/test/resources/application-memorydb.yml
Normal file
5
komga/src/test/resources/application-memorydb.yml
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
komga:
|
||||
database:
|
||||
file: "file:database?mode=memory"
|
||||
tasks-db:
|
||||
file: "file:tasks?mode=memory"
|
||||
|
|
@ -2,9 +2,11 @@ application.version: TESTING
|
|||
|
||||
komga:
|
||||
database:
|
||||
file: "file:database?mode=memory"
|
||||
file: "\${java.io.tmpdir}/database\${random.uuid}.sqlite"
|
||||
journal-mode: WAL
|
||||
tasks-db:
|
||||
file: "file:tasks?mode=memory"
|
||||
file: "\${java.io.tmpdir}/tasks\${random.uuid}.sqlite"
|
||||
journal-mode: WAL
|
||||
|
||||
spring:
|
||||
flyway:
|
||||
|
|
|
|||
|
|
@ -1,7 +0,0 @@
|
|||
komga:
|
||||
database:
|
||||
file: "\${java.io.tmpdir}/database.sqlite"
|
||||
journal-mode: WAL
|
||||
tasks-db:
|
||||
file: "\${java.io.tmpdir}/tasks.sqlite"
|
||||
journal-mode: WAL
|
||||
Loading…
Reference in a new issue