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 ->