From cbe47ea5931427193bc853e80b8faae40135ec1a Mon Sep 17 00:00:00 2001 From: Gauthier Roebroeck Date: Thu, 11 Mar 2021 22:47:14 +0800 Subject: [PATCH] feat: localize server side errors --- ERRORCODES.md | 13 +++++++++++++ komga-webui/src/functions/book-format.ts | 6 ++++-- komga-webui/src/functions/error-codes.ts | 10 ++++++++++ komga-webui/src/locales/en.json | 17 ++++++++++++++--- komga-webui/src/locales/fr.json | 11 +++++++++++ komga-webui/src/views/BrowseBook.vue | 6 +++++- komga-webui/src/views/SettingsMediaAnalysis.vue | 2 ++ .../org/gotson/komga/domain/model/Exceptions.kt | 13 +++++++------ .../gotson/komga/domain/service/BookAnalyzer.kt | 10 +++++----- .../mediacontainer/RarExtractor.kt | 6 +++--- 10 files changed, 74 insertions(+), 20 deletions(-) create mode 100644 ERRORCODES.md create mode 100644 komga-webui/src/functions/error-codes.ts diff --git a/ERRORCODES.md b/ERRORCODES.md new file mode 100644 index 000000000..250737216 --- /dev/null +++ b/ERRORCODES.md @@ -0,0 +1,13 @@ +# Error codes + +Code | Description +---|--- +ERR_1000 | File could not be accessed during analysis +ERR_1001 | Media type is not supported during analysis +ERR_1002 | Encrypted RAR archives are not supported +ERR_1003 | Solid RAR archives are not supported +ERR_1004 | Multi-Volume RAR archives are not supported +ERR_1005 | Unknown error while analyzing book +ERR_1006 | Book does not contain any page +ERR_1007 | Some entries could not be analyzed +ERR_1008 | Unknown error while getting book's entries diff --git a/komga-webui/src/functions/book-format.ts b/komga-webui/src/functions/book-format.ts index e98216981..7a72475fd 100644 --- a/komga-webui/src/functions/book-format.ts +++ b/komga-webui/src/functions/book-format.ts @@ -1,4 +1,4 @@ -import { BookFormat } from '@/types/komga-books' +import {BookFormat} from '@/types/komga-books' export function getBookFormatFromMediaType (mediaType: string): BookFormat { switch (mediaType) { @@ -11,7 +11,9 @@ export function getBookFormatFromMediaType (mediaType: string): BookFormat { return { type: 'PDF', color: '#FF5722' } case 'application/epub+zip': return { type: 'EPUB', color: '#ff5ab1' } + case 'application/x-rar-compressed; version=5': + return { type: 'RAR5', color: '#000000' } default: - return { type: '?', color: '#000000' } + return { type: mediaType, color: '#000000' } } } diff --git a/komga-webui/src/functions/error-codes.ts b/komga-webui/src/functions/error-codes.ts new file mode 100644 index 000000000..03e444486 --- /dev/null +++ b/komga-webui/src/functions/error-codes.ts @@ -0,0 +1,10 @@ +import i18n from "@/i18n"; + +export function convertErrorCodes(message: string): string { + const match = message.match(/ERR_\d{4}/g) + let r = message + if(match){ + match.forEach(x => r = r.replace(x, i18n.t(`error_codes.${x}`).toString())) + } + return r +} diff --git a/komga-webui/src/locales/en.json b/komga-webui/src/locales/en.json index 7f1d97dfd..90e417576 100644 --- a/komga-webui/src/locales/en.json +++ b/komga-webui/src/locales/en.json @@ -243,6 +243,7 @@ "button_confirm_edit": "Edit", "dialog_title_add": "Add Library", "dialot_title_edit": "Edit Library", + "field_import_barcode_isbn": "ISBN barcode", "field_import_comicinfo_book": "Book metadata", "field_import_comicinfo_collections": "Collections", "field_import_comicinfo_readlists": "Read lists", @@ -256,14 +257,13 @@ "field_scanner_force_directory_modified_time": "Force directory modified time", "file_browser_dialog_button_confirm": "Choose", "file_browser_dialog_title": "Library's root folder", + "label_import_barcode_isbn": "Import ISBN within barcode", "label_import_comicinfo": "Import metadata for CBR/CBZ containing a ComicInfo.xml file", "label_import_epub": "Import metadata from EPUB files", "label_import_local": "Import local media assets", "label_scanner": "Scanner", "tab_general": "General", - "tab_options": "Options", - "field_import_barcode_isbn": "ISBN barcode", - "label_import_barcode_isbn": "Import ISBN within barcode" + "tab_options": "Options" }, "edit_readlist": { "button_cancel": "Cancel", @@ -352,6 +352,17 @@ "ONGOING": "Ongoing" } }, + "error_codes": { + "ERR_1000": "File could not be accessed during analysis", + "ERR_1001": "Media type is not supported", + "ERR_1002": "Encrypted RAR archives are not supported", + "ERR_1003": "Solid RAR archives are not supported", + "ERR_1004": "Multi-Volume RAR archives are not supported", + "ERR_1005": "Unknown error while analyzing book", + "ERR_1006": "Book does not contain any page", + "ERR_1007": "Some entries could not be analyzed", + "ERR_1008": "Unknown error while getting book's entries" + }, "filter": { "age_rating": "age rating", "age_rating_none": "None", diff --git a/komga-webui/src/locales/fr.json b/komga-webui/src/locales/fr.json index fb2bd14d1..f774c57e0 100644 --- a/komga-webui/src/locales/fr.json +++ b/komga-webui/src/locales/fr.json @@ -347,6 +347,17 @@ "ONGOING": "En cours" } }, + "error_codes": { + "ERR_1000": "Le fichier n'etait pas accessible pendant l'analyse", + "ERR_1001": "Le type de média n'est pas supporté", + "ERR_1002": "Les archives RAR encryptées ne sont pas supportées", + "ERR_1003": "Les archives RAR solides ne sont pas supportées", + "ERR_1004": "Les archives RAR multi-volumes ne sont pas supportées", + "ERR_1005": "Erreur inconnue pendant l'analyse", + "ERR_1006": "Le livre ne contient aucune page", + "ERR_1007": "Certaines entrées n'ont pas pu être analysées", + "ERR_1008": "Erreur inconnue pendant la recuperation des entrées" + }, "filter": { "age_rating": "Âge minimal", "age_rating_none": "Aucun", diff --git a/komga-webui/src/views/BrowseBook.vue b/komga-webui/src/views/BrowseBook.vue index fd39bf2bf..ee1d17ac8 100644 --- a/komga-webui/src/views/BrowseBook.vue +++ b/komga-webui/src/views/BrowseBook.vue @@ -252,7 +252,7 @@ {{ $t('browse_book.comment') }} - {{ book.media.comment }} + {{ mediaComment }} @@ -294,6 +294,7 @@ import {SeriesDto} from "@/types/komga-series"; import ReadMore from "@/components/ReadMore.vue"; import VueHorizontal from "vue-horizontal"; import {authorRoles} from "@/types/author-roles"; +import {convertErrorCodes} from "@/functions/error-codes"; export default Vue.extend({ name: 'BrowseBook', @@ -376,6 +377,9 @@ export default Vue.extend({ contextReadList(): boolean { return this.context.origin === ContextOrigin.READLIST }, + mediaComment(): string { + return convertErrorCodes(this.book.media.comment) + }, }, methods: { libraryDeleted(event: EventLibraryDeleted) { diff --git a/komga-webui/src/views/SettingsMediaAnalysis.vue b/komga-webui/src/views/SettingsMediaAnalysis.vue index b35a26a42..ed5fd054e 100644 --- a/komga-webui/src/views/SettingsMediaAnalysis.vue +++ b/komga-webui/src/views/SettingsMediaAnalysis.vue @@ -24,6 +24,7 @@ import Vue from 'vue' import {MediaStatus} from '@/types/enum-books' import {BookDto} from '@/types/komga-books' +import {convertErrorCodes} from "@/functions/error-codes"; export default Vue.extend({ name: 'SettingsMediaAnalysis', @@ -59,6 +60,7 @@ export default Vue.extend({ ...b, media: { ...b.media, + comment: convertErrorCodes(b.media.comment), status: this.$t(`enums.media_status.${b.media.status}`).toString()}, })) }, diff --git a/komga/src/main/kotlin/org/gotson/komga/domain/model/Exceptions.kt b/komga/src/main/kotlin/org/gotson/komga/domain/model/Exceptions.kt index 5441f80ed..df0deb1c3 100644 --- a/komga/src/main/kotlin/org/gotson/komga/domain/model/Exceptions.kt +++ b/komga/src/main/kotlin/org/gotson/komga/domain/model/Exceptions.kt @@ -1,9 +1,10 @@ package org.gotson.komga.domain.model +open class CodedException(message: String, val code: String) : Exception(message) class MediaNotReadyException : Exception() -class MediaUnsupportedException(message: String) : Exception(message) -class ImageConversionException(message: String) : Exception(message) -class DirectoryNotFoundException(message: String) : Exception(message) -class DuplicateNameException(message: String) : Exception(message) -class PathContainedInPath(message: String) : Exception(message) -class UserEmailAlreadyExistsException(message: String) : Exception(message) +class MediaUnsupportedException(message: String, code: String = "") : CodedException(message, code) +class ImageConversionException(message: String, code: String = "") : CodedException(message, code) +class DirectoryNotFoundException(message: String, code: String = "") : CodedException(message, code) +class DuplicateNameException(message: String, code: String = "") : CodedException(message, code) +class PathContainedInPath(message: String, code: String = "") : CodedException(message, code) +class UserEmailAlreadyExistsException(message: String, code: String = "") : CodedException(message, code) diff --git a/komga/src/main/kotlin/org/gotson/komga/domain/service/BookAnalyzer.kt b/komga/src/main/kotlin/org/gotson/komga/domain/service/BookAnalyzer.kt index 3f306b699..bd7a0bd80 100644 --- a/komga/src/main/kotlin/org/gotson/komga/domain/service/BookAnalyzer.kt +++ b/komga/src/main/kotlin/org/gotson/komga/domain/service/BookAnalyzer.kt @@ -36,15 +36,15 @@ class BookAnalyzer( val mediaType = contentDetector.detectMediaType(book.path()) logger.info { "Detected media type: $mediaType" } if (!supportedMediaTypes.containsKey(mediaType)) - return Media(mediaType = mediaType, status = Media.Status.UNSUPPORTED, comment = "Media type $mediaType is not supported") + return Media(mediaType = mediaType, status = Media.Status.UNSUPPORTED, comment = "ERR_1001") val entries = try { supportedMediaTypes.getValue(mediaType).getEntries(book.path()) } catch (ex: MediaUnsupportedException) { - return Media(mediaType = mediaType, status = Media.Status.UNSUPPORTED, comment = ex.message) + return Media(mediaType = mediaType, status = Media.Status.UNSUPPORTED, comment = ex.code) } catch (ex: Exception) { logger.error(ex) { "Error while analyzing book: $book" } - return Media(mediaType = mediaType, status = Media.Status.ERROR, comment = ex.message) + return Media(mediaType = mediaType, status = Media.Status.ERROR, comment = "ERR_1008") } val (pages, others) = entries @@ -61,11 +61,11 @@ class BookAnalyzer( .filter { it.mediaType.isNullOrBlank() } .map { it.name } .ifEmpty { null } - ?.joinToString(prefix = "Some entries could not be analyzed: [", postfix = "]") { it } + ?.joinToString(prefix = "ERR_1007 [", postfix = "]") { it } if (pages.isEmpty()) { logger.warn { "Book $book does not contain any pages" } - return Media(mediaType = mediaType, status = Media.Status.ERROR, comment = "Book does not contain any pages") + return Media(mediaType = mediaType, status = Media.Status.ERROR, comment = "ERR_1006") } logger.info { "Book has ${pages.size} pages" } diff --git a/komga/src/main/kotlin/org/gotson/komga/infrastructure/mediacontainer/RarExtractor.kt b/komga/src/main/kotlin/org/gotson/komga/infrastructure/mediacontainer/RarExtractor.kt index 60721e41d..0a54186d7 100644 --- a/komga/src/main/kotlin/org/gotson/komga/infrastructure/mediacontainer/RarExtractor.kt +++ b/komga/src/main/kotlin/org/gotson/komga/infrastructure/mediacontainer/RarExtractor.kt @@ -27,9 +27,9 @@ class RarExtractor( override fun getEntries(path: Path): List = Archive(path.toFile()).use { rar -> - if (rar.isPasswordProtected) throw MediaUnsupportedException("Encrypted RAR archives are not supported") - if (rar.mainHeader.isSolid) throw MediaUnsupportedException("Solid RAR archives are not supported") - if (rar.mainHeader.isMultiVolume) throw MediaUnsupportedException("Multi-Volume RAR archives are not supported") + if (rar.isPasswordProtected) throw MediaUnsupportedException("Encrypted RAR archives are not supported", "ERR_1002") + if (rar.mainHeader.isSolid) throw MediaUnsupportedException("Solid RAR archives are not supported", "ERR_1003") + if (rar.mainHeader.isMultiVolume) throw MediaUnsupportedException("Multi-Volume RAR archives are not supported", "ERR_1004") rar.fileHeaders .filter { !it.isDirectory } .map { hd ->