diff --git a/.dockerignore b/.dockerignore index 688adc70..7c0fca62 100644 --- a/.dockerignore +++ b/.dockerignore @@ -4,6 +4,7 @@ npm-debug.log .gitignore /config /audiobooks +/audiobooks2 /metadata dev.js /test/ diff --git a/.gitignore b/.gitignore index 1cfa80f5..b3ab7bd8 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ dev.js node_modules/ /config/ /audiobooks/ +/audiobooks2/ /metadata/ /test/ /client/.nuxt/ \ No newline at end of file diff --git a/client/components/modals/edit-tabs/Details.vue b/client/components/modals/edit-tabs/Details.vue index 7ad3784f..a1183e7d 100644 --- a/client/components/modals/edit-tabs/Details.vue +++ b/client/components/modals/edit-tabs/Details.vue @@ -12,7 +12,14 @@
- +
+
+ +
+
+ +
+
@@ -45,6 +52,7 @@ export default { description: null, author: null, series: null, + publishYear: null, genres: [] }, resettingProgress: false, @@ -111,6 +119,7 @@ export default { this.details.author = this.book.author this.details.genres = this.book.genres || [] this.details.series = this.book.series + this.details.publishYear = this.book.publishYear }, resetProgress() { if (confirm(`Are you sure you want to reset your progress?`)) { diff --git a/client/components/ui/TextInputWithLabel.vue b/client/components/ui/TextInputWithLabel.vue index f74d7a9a..b7d5789c 100644 --- a/client/components/ui/TextInputWithLabel.vue +++ b/client/components/ui/TextInputWithLabel.vue @@ -1,7 +1,7 @@ @@ -10,6 +10,10 @@ export default { props: { value: [String, Number], label: String, + type: { + type: String, + default: 'text' + }, disabled: Boolean }, data() { diff --git a/package.json b/package.json index ff8c3296..20b32cf6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "audiobookshelf", - "version": "0.9.52", + "version": "0.9.53", "description": "Self-hosted audiobook server for managing and playing audiobooks.", "main": "index.js", "scripts": { diff --git a/readme.md b/readme.md index ca0ba6a2..0f7e40a2 100644 --- a/readme.md +++ b/readme.md @@ -6,9 +6,16 @@ AudioBookshelf is a self-hosted audiobook server for managing and playing your a Screenshot1 +Folder Structures Supported: + +* `/[TITLE]/...` +* `/[AUTHOR]/[TITLE]/...` +* `/[AUTHOR]/[SERIES]/[TITLE]/...` +* Title can start with a year and hyphen like, "1989 - Book Title Here", which will use 1989 as the publish year. + + Missing a lot of features still, like... -* Scanner is intended for file structure `[author name]/[title]/...` * Adding new audiobooks require pressing Scan button again (on settings page) * Matching is all manual now and only using 1 source (openlibrary) * Need to add cover selection from match results diff --git a/server/Book.js b/server/Book.js index be8f1a20..09bd6eae 100644 --- a/server/Book.js +++ b/server/Book.js @@ -20,7 +20,7 @@ class Book { this.title = book.title this.author = book.author this.series = book.series - this.publishYear = book.publish_year + this.publishYear = book.publishYear this.publisher = book.publisher this.description = book.description this.cover = book.cover @@ -33,7 +33,7 @@ class Book { title: this.title, author: this.author, series: this.series, - publishYear: this.publish_year, + publishYear: this.publishYear, publisher: this.publisher, description: this.description, cover: this.cover, @@ -42,11 +42,12 @@ class Book { } setData(data) { + console.log('SET DATA', data) this.olid = data.olid || null this.title = data.title || null this.author = data.author || null this.series = data.series || null - this.publishYear = data.publish_year || null + this.publishYear = data.publishYear || null this.description = data.description || null this.cover = data.cover || null this.genres = data.genres || [] diff --git a/server/utils/scandir.js b/server/utils/scandir.js index 74bfbaa2..ea69a1c4 100644 --- a/server/utils/scandir.js +++ b/server/utils/scandir.js @@ -29,22 +29,41 @@ function getFileType(ext) { return 'unknown' } -async function getAllAudiobookFiles(path) { - console.log('getAllAudiobooks', path) - var paths = await getPaths(path) +async function getAllAudiobookFiles(abRootPath) { + var paths = await getPaths(abRootPath) var audiobooks = {} paths.files.forEach((filepath) => { - var relpath = filepath.replace(path, '').slice(1) + var relpath = filepath.replace(abRootPath, '').slice(1) var pathformat = Path.parse(relpath) - var authordir = Path.dirname(pathformat.dir) - var bookdir = Path.basename(pathformat.dir) - if (!audiobooks[bookdir]) { - audiobooks[bookdir] = { - author: authordir, - title: bookdir, - path: pathformat.dir, - fullPath: Path.join(path, pathformat.dir), + var path = pathformat.dir + + // If relative file directory has 3 folders, then the middle folder will be series + var splitDir = pathformat.dir.split(Path.sep) + var author = splitDir.shift() + var series = null + if (splitDir.length > 1) series = splitDir.shift() + var title = splitDir.shift() + + var publishYear = null + + // If Title is of format 1999 - Title, then use 1999 as publish year + var publishYearMatch = title.match(/^([0-9]{4}) - (.+)/) + if (publishYearMatch && publishYearMatch.length > 2) { + if (!isNaN(publishYearMatch[1])) { + publishYear = publishYearMatch[1] + title = publishYearMatch[2] + } + } + + if (!audiobooks[path]) { + audiobooks[path] = { + author: author, + title: title, + series: series, + publishYear: publishYear, + path: relpath, + fullPath: Path.join(abRootPath, path), parts: [], otherFiles: [] } @@ -52,7 +71,7 @@ async function getAllAudiobookFiles(path) { var filetype = getFileType(pathformat.ext) if (filetype === 'abpart') { - audiobooks[bookdir].parts.push(pathformat.base) + audiobooks[path].parts.push(pathformat.base) } else { var fileObj = { filetype: filetype, @@ -61,7 +80,7 @@ async function getAllAudiobookFiles(path) { fullPath: filepath, ext: pathformat.ext } - audiobooks[bookdir].otherFiles.push(fileObj) + audiobooks[path].otherFiles.push(fileObj) } }) return Object.values(audiobooks)