mirror of
				https://github.com/advplyr/audiobookshelf.git
				synced 2025-10-27 11:18:14 +01:00 
			
		
		
		
	Supporting more file structures for series and publish year
This commit is contained in:
		
							parent
							
								
									7df0708f38
								
							
						
					
					
						commit
						08c3f84c06
					
				@ -4,6 +4,7 @@ npm-debug.log
 | 
			
		||||
.gitignore
 | 
			
		||||
/config
 | 
			
		||||
/audiobooks
 | 
			
		||||
/audiobooks2
 | 
			
		||||
/metadata
 | 
			
		||||
dev.js
 | 
			
		||||
/test/
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@ -2,6 +2,7 @@ dev.js
 | 
			
		||||
node_modules/
 | 
			
		||||
/config/
 | 
			
		||||
/audiobooks/
 | 
			
		||||
/audiobooks2/
 | 
			
		||||
/metadata/
 | 
			
		||||
/test/
 | 
			
		||||
/client/.nuxt/
 | 
			
		||||
@ -12,7 +12,14 @@
 | 
			
		||||
    <form @submit.prevent="submitForm">
 | 
			
		||||
      <ui-text-input-with-label v-model="details.title" label="Title" />
 | 
			
		||||
 | 
			
		||||
      <ui-text-input-with-label v-model="details.author" label="Author" class="mt-2" />
 | 
			
		||||
      <div class="flex mt-2 -mx-1">
 | 
			
		||||
        <div class="w-3/4 px-1">
 | 
			
		||||
          <ui-text-input-with-label v-model="details.author" label="Author" />
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="flex-grow px-1">
 | 
			
		||||
          <ui-text-input-with-label v-model="details.publishYear" type="number" label="Publish Year" />
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
 | 
			
		||||
      <ui-text-input-with-label v-model="details.series" label="Series" class="mt-2" />
 | 
			
		||||
 | 
			
		||||
@ -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?`)) {
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div class="w-full">
 | 
			
		||||
    <p class="px-1 text-sm">{{ label }}</p>
 | 
			
		||||
    <ui-text-input v-model="inputValue" :disabled="disabled" class="w-full" />
 | 
			
		||||
    <ui-text-input v-model="inputValue" :disabled="disabled" :type="type" class="w-full" />
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
@ -10,6 +10,10 @@ export default {
 | 
			
		||||
  props: {
 | 
			
		||||
    value: [String, Number],
 | 
			
		||||
    label: String,
 | 
			
		||||
    type: {
 | 
			
		||||
      type: String,
 | 
			
		||||
      default: 'text'
 | 
			
		||||
    },
 | 
			
		||||
    disabled: Boolean
 | 
			
		||||
  },
 | 
			
		||||
  data() {
 | 
			
		||||
 | 
			
		||||
@ -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": {
 | 
			
		||||
 | 
			
		||||
@ -6,9 +6,16 @@ AudioBookshelf is a self-hosted audiobook server for managing and playing your a
 | 
			
		||||
 | 
			
		||||
<img alt="Screenshot1" src="https://github.com/advplyr/audiobookshelf/raw/master/images/ss_bookshelf.png" />
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
 | 
			
		||||
@ -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 || []
 | 
			
		||||
 | 
			
		||||
@ -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)
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user