diff --git a/komga-webui/src/locales/ar.json b/komga-webui/src/locales/ar.json index 861c80b77..761f271d4 100644 --- a/komga-webui/src/locales/ar.json +++ b/komga-webui/src/locales/ar.json @@ -7,6 +7,10 @@ "itemsPerPageText": "الصفوف لكل صفحة:", "sortBy": "مفروزة حسب" }, + "fileInput": { + "counter": "{0} ملفات", + "counterSize": "{0} ملفات ({1} في المجموع)" + }, "noDataText": "لا توجد بيانات متاحة" }, "account_settings": { diff --git a/komga-webui/src/locales/de.json b/komga-webui/src/locales/de.json index dd6a09e3f..196d2bdc0 100644 --- a/komga-webui/src/locales/de.json +++ b/komga-webui/src/locales/de.json @@ -7,6 +7,10 @@ "itemsPerPageText": "Zeilen pro Seite:", "sortBy": "Sortiere nach" }, + "fileInput": { + "counter": "{0} Dateien", + "counterSize": "{0} Dateien ({1} gesamt)" + }, "noDataText": "Keine Daten vorhanden" }, "account_settings": { diff --git a/komga-webui/src/locales/en.json b/komga-webui/src/locales/en.json index 9e33c6c6e..c82427cc6 100644 --- a/komga-webui/src/locales/en.json +++ b/komga-webui/src/locales/en.json @@ -7,6 +7,10 @@ "itemsPerPageText": "Rows per page:", "sortBy": "Sort by" }, + "fileInput": { + "counter": "{0} files", + "counterSize": "{0} files ({1} in total)" + }, "noDataText": "No data available" }, "account_settings": { @@ -153,6 +157,18 @@ "recently_added_series": "Recently Added Series", "recently_updated_series": "Recently Updated Series" }, + "data_import": { + "book_number": "Book number: {name}", + "book_series": "Series: {name}", + "button_import": "Import", + "comicrack_preambule_html": "You can import existing ComicRack Reading Lists in .cbl format.
Komga will try to match the provided series and book number with series and books in your libraries.", + "field_files_label": "ComicRack Reading Lists (.cbl)", + "import_read_lists": "Import Read Lists", + "imported_as": "Imported as {name}", + "results_preambule": "Result of the import is shown below. You can also check the unmatched books for each provided file.", + "size_limit": "Size should be less than {size} MB", + "tab_title": "Data Import" + }, "dialog": { "add_to_collection": { "button_create": "Create", @@ -363,7 +379,14 @@ "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" + "ERR_1008": "Unknown error while getting book's entries", + "ERR_1009": "A read list with that name already exists", + "ERR_1010": "No books were matched within the read list request", + "ERR_1011": "No unique match for series", + "ERR_1012": "No match for series", + "ERR_1013": "No unique match for book number within series", + "ERR_1014": "No match for book number within series", + "ERR_1015": "Error while deserializing ComicRack ReadingList" }, "filter": { "age_rating": "age rating", diff --git a/komga-webui/src/locales/es.json b/komga-webui/src/locales/es.json index 5ae62dae1..3fca6299e 100644 --- a/komga-webui/src/locales/es.json +++ b/komga-webui/src/locales/es.json @@ -7,6 +7,10 @@ "itemsPerPageText": "Filas por página:", "sortBy": "Ordenado por" }, + "fileInput": { + "counter": "{0} archivos", + "counterSize": "{0} archivos ({1} en total)" + }, "noDataText": "No hay datos disponibles" }, "account_settings": { diff --git a/komga-webui/src/locales/fr.json b/komga-webui/src/locales/fr.json index d7b5530b8..c8c90ba09 100644 --- a/komga-webui/src/locales/fr.json +++ b/komga-webui/src/locales/fr.json @@ -7,6 +7,10 @@ "itemsPerPageText": "Élements par page :", "sortBy": "Trier par" }, + "fileInput": { + "counter": "{0} fichiers", + "counterSize": "{0} fichiers ({1} au total)" + }, "noDataText": "Aucune donnée disponible" }, "account_settings": { diff --git a/komga-webui/src/locales/it.json b/komga-webui/src/locales/it.json index 4490c2fc1..166d74332 100644 --- a/komga-webui/src/locales/it.json +++ b/komga-webui/src/locales/it.json @@ -6,7 +6,12 @@ "dataTable": { "itemsPerPageText": "Righe per pagina:", "sortBy": "Ordina per" - } + }, + "fileInput": { + "counter": "{0} files", + "counterSize": "{0} files ({1} in totale)" + }, + "noDataText": "Nessun elemento disponibile" }, "account_settings": { "account_settings": "Impostazioni Account", diff --git a/komga-webui/src/locales/ja.json b/komga-webui/src/locales/ja.json index ca3b0d267..fd6126e34 100644 --- a/komga-webui/src/locales/ja.json +++ b/komga-webui/src/locales/ja.json @@ -7,6 +7,10 @@ "itemsPerPageText": "ページ毎の行数:", "sortBy": "ソート方式" }, + "fileInput": { + "counter": "{0} ファイル", + "counterSize": "{0} ファイル (合計 {1})" + }, "noDataText": "データがありません" }, "account_settings": { diff --git a/komga-webui/src/locales/nb.json b/komga-webui/src/locales/nb.json index 570397289..779cdc5ed 100644 --- a/komga-webui/src/locales/nb.json +++ b/komga-webui/src/locales/nb.json @@ -7,6 +7,10 @@ "itemsPerPageText": "Rader per side:", "sortBy": "Sorter etter" }, + "fileInput": { + "counter": "{0} filer", + "counterSize": "{0} filer ({1} totalt)" + }, "noDataText": "Ingen data er tilgjengelig" }, "account_settings": { diff --git a/komga-webui/src/locales/pt-BR.json b/komga-webui/src/locales/pt-BR.json index d2a0b3bbe..018245710 100644 --- a/komga-webui/src/locales/pt-BR.json +++ b/komga-webui/src/locales/pt-BR.json @@ -7,6 +7,10 @@ "itemsPerPageText": "Linhas por página:", "sortBy": "Ordenar por" }, + "fileInput": { + "counter": "{0} arquivo(s)", + "counterSize": "{0} arquivo(s) ({1} no total)" + }, "noDataText": "Não há dados disponíveis" }, "account_settings": { diff --git a/komga-webui/src/locales/ru.json b/komga-webui/src/locales/ru.json index 1bb7aadf9..24467c7ad 100644 --- a/komga-webui/src/locales/ru.json +++ b/komga-webui/src/locales/ru.json @@ -7,6 +7,10 @@ "itemsPerPageText": "Строк на странице:", "sortBy": "Сортировать по" }, + "fileInput": { + "counter": "Файлов: {0}", + "counterSize": "Файлов: {0} (всего {1})" + }, "noDataText": "Отсутствуют данные" }, "account_settings": { diff --git a/komga-webui/src/locales/sv.json b/komga-webui/src/locales/sv.json index 4e99ca3db..d253e1df8 100644 --- a/komga-webui/src/locales/sv.json +++ b/komga-webui/src/locales/sv.json @@ -7,6 +7,10 @@ "itemsPerPageText": "Rader per sida:", "sortBy": "Sortera efter" }, + "fileInput": { + "counter": "{0} filer", + "counterSize": "{0} filer (av {1} totalt)" + }, "noDataText": "Ingen data tillgänglig" }, "account_settings": { diff --git a/komga-webui/src/locales/zh-Hans.json b/komga-webui/src/locales/zh-Hans.json index b6e9360cb..9f56aba5b 100644 --- a/komga-webui/src/locales/zh-Hans.json +++ b/komga-webui/src/locales/zh-Hans.json @@ -7,6 +7,10 @@ "itemsPerPageText": "每页行数:", "sortBy": "排序方式" }, + "fileInput": { + "counter": "{0} 个文件", + "counterSize": "{0} 个文件(共 {1})" + }, "noDataText": "无数据可用" }, "account_settings": { diff --git a/komga-webui/src/router.ts b/komga-webui/src/router.ts index a5302a8cb..29373a691 100644 --- a/komga-webui/src/router.ts +++ b/komga-webui/src/router.ts @@ -70,6 +70,12 @@ const router = new Router({ beforeEnter: adminGuard, component: () => import(/* webpackChunkName: "settings-server" */ './views/SettingsServer.vue'), }, + { + path: '/settings/data-import', + name: 'settings-data-import', + beforeEnter: adminGuard, + component: () => import(/* webpackChunkName: "settings-data-import" */ './views/SettingsDataImport.vue'), + }, ], }, { diff --git a/komga-webui/src/services/komga-readlists.service.ts b/komga-webui/src/services/komga-readlists.service.ts index 98db8c45b..7c270df1c 100644 --- a/komga-webui/src/services/komga-readlists.service.ts +++ b/komga-webui/src/services/komga-readlists.service.ts @@ -1,5 +1,5 @@ -import { AxiosInstance } from 'axios' -import { BookDto } from '@/types/komga-books' +import {AxiosInstance} from 'axios' +import {BookDto} from '@/types/komga-books' const qs = require('qs') @@ -8,19 +8,19 @@ const API_READLISTS = '/api/v1/readlists' export default class KomgaReadListsService { private http: AxiosInstance - constructor (http: AxiosInstance) { + constructor(http: AxiosInstance) { this.http = http } - async getReadLists (libraryIds?: string[], pageRequest?: PageRequest, search?: string): Promise> { + async getReadLists(libraryIds?: string[], pageRequest?: PageRequest, search?: string): Promise> { try { - const params = { ...pageRequest } as any + const params = {...pageRequest} as any if (libraryIds) params.library_id = libraryIds if (search) params.search = search return (await this.http.get(API_READLISTS, { params: params, - paramsSerializer: params => qs.stringify(params, { indices: false }), + paramsSerializer: params => qs.stringify(params, {indices: false}), })).data } catch (e) { let msg = 'An error occurred while trying to retrieve readLists' @@ -31,7 +31,7 @@ export default class KomgaReadListsService { } } - async getOneReadList (readListId: string): Promise { + async getOneReadList(readListId: string): Promise { try { return (await this.http.get(`${API_READLISTS}/${readListId}`)).data } catch (e) { @@ -43,7 +43,7 @@ export default class KomgaReadListsService { } } - async postReadList (readList: ReadListCreationDto): Promise { + async postReadList(readList: ReadListCreationDto): Promise { try { return (await this.http.post(API_READLISTS, readList)).data } catch (e) { @@ -55,7 +55,25 @@ export default class KomgaReadListsService { } } - async patchReadList (readListId: string, readList: ReadListUpdateDto) { + async postReadListImport(files: any): Promise { + try { + const formData = new FormData(); + files.forEach((f: any) => formData.append("files", f)) + return (await this.http.post(`${API_READLISTS}/import`, formData, { + headers: { + 'Content-Type': 'multipart/form-data', + }, + })).data + } catch (e) { + let msg = `An error occurred while trying to import readlists'` + if (e.response.data.message) { + msg += `: ${e.response.data.message}` + } + throw new Error(msg) + } + } + + async patchReadList(readListId: string, readList: ReadListUpdateDto) { try { await this.http.patch(`${API_READLISTS}/${readListId}`, readList) } catch (e) { @@ -67,7 +85,7 @@ export default class KomgaReadListsService { } } - async deleteReadList (readListId: string) { + async deleteReadList(readListId: string) { try { await this.http.delete(`${API_READLISTS}/${readListId}`) } catch (e) { @@ -79,9 +97,9 @@ export default class KomgaReadListsService { } } - async getBooks (readListId: string, pageRequest?: PageRequest): Promise> { + async getBooks(readListId: string, pageRequest?: PageRequest): Promise> { try { - const params = { ...pageRequest } + const params = {...pageRequest} return (await this.http.get(`${API_READLISTS}/${readListId}/books`, { params: params, })).data @@ -94,7 +112,7 @@ export default class KomgaReadListsService { } } - async getBookSiblingNext (readListId: string, bookId: string): Promise { + async getBookSiblingNext(readListId: string, bookId: string): Promise { try { return (await this.http.get(`${API_READLISTS}/${readListId}/books/${bookId}/next`)).data } catch (e) { @@ -106,7 +124,7 @@ export default class KomgaReadListsService { } } - async getBookSiblingPrevious (readListId: string, bookId: string): Promise { + async getBookSiblingPrevious(readListId: string, bookId: string): Promise { try { return (await this.http.get(`${API_READLISTS}/${readListId}/books/${bookId}/previous`)).data } catch (e) { diff --git a/komga-webui/src/types/komga-readlists.ts b/komga-webui/src/types/komga-readlists.ts index a99cfc915..d024595b0 100644 --- a/komga-webui/src/types/komga-readlists.ts +++ b/komga-webui/src/types/komga-readlists.ts @@ -16,3 +16,20 @@ interface ReadListUpdateDto { name?: string, bookIds?: string[] } + +interface ReadListRequestResultDto { + readList?: ReadListDto, + unmatchedBooks: ReadListRequestResultBookDto[], + errorCode: string, + requestName: string, +} + +interface ReadListRequestResultBookDto { + book: ReadListRequestBookDto, + errorCode: string, +} + +interface ReadListRequestBookDto { + series: string, + number: number, +} diff --git a/komga-webui/src/views/Settings.vue b/komga-webui/src/views/Settings.vue index b7bb84ad4..d46cfb68e 100644 --- a/komga-webui/src/views/Settings.vue +++ b/komga-webui/src/views/Settings.vue @@ -4,6 +4,7 @@ {{ $t('media_analysis.media_analysis') }} {{ $t('users.users') }} {{ $t('server.tab_title') }} + {{ $t('data_import.tab_title') }} diff --git a/komga-webui/src/views/SettingsDataImport.vue b/komga-webui/src/views/SettingsDataImport.vue new file mode 100644 index 000000000..931101bfe --- /dev/null +++ b/komga-webui/src/views/SettingsDataImport.vue @@ -0,0 +1,121 @@ + + + + +