mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2026-11-13 12:23:34 +01:00
Keep iTunes author credentials attached to the name
This commit is contained in:
1 parent
ce41ce489c
commit
087099faa3
2 files changed
+103
-5
No files matched your search
@@ -27,6 +27,55 @@ const htmlSanitizer = require('../utils/htmlSanitizer')
|
|||||||
* @property {boolean} explicit
|
* @property {boolean} explicit
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Split a list of authors on commas. A piece with no space is a credential and is glued onto the previous name.
|
||||||
|
*
|
||||||
|
* @param {string} text
|
||||||
|
* @returns {string[]}
|
||||||
|
*/
|
||||||
|
function parseAuthorPieces(text) {
|
||||||
|
const authors = []
|
||||||
|
for (const piece of (text || '').split(',')) {
|
||||||
|
const name = piece.trim()
|
||||||
|
if (!name) continue
|
||||||
|
if (!name.includes(' ') && authors.length) {
|
||||||
|
authors[authors.length - 1] = `${authors[authors.length - 1]} ${name}`
|
||||||
|
} else {
|
||||||
|
authors.push(name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return authors
|
||||||
|
}
|
||||||
|
|
||||||
|
function stripCommasFromName(name) {
|
||||||
|
return (name || '').replace(/,/g, '').replace(/\s+/g, ' ').trim()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apple lists authors as "Name1, Name2 & Name3", but a comma can also sit inside one name ("Rick Hanson, PhD").
|
||||||
|
* A comma-separated piece with no space is treated as a credential and glued onto the previous name.
|
||||||
|
* The text after the last " & " is a single author, so commas there are removed.
|
||||||
|
* @see https://github.com/advplyr/audiobookshelf/issues/1022
|
||||||
|
* @see https://github.com/advplyr/audiobookshelf/issues/2661
|
||||||
|
*
|
||||||
|
* @param {string} artistName
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
function cleanAuthor(artistName) {
|
||||||
|
const raw = (artistName || '').trim()
|
||||||
|
if (!raw) return ''
|
||||||
|
|
||||||
|
const lastAmpIndex = raw.lastIndexOf(' & ')
|
||||||
|
if (lastAmpIndex === -1) {
|
||||||
|
return stripCommasFromName(raw)
|
||||||
|
}
|
||||||
|
|
||||||
|
const authors = parseAuthorPieces(raw.slice(0, lastAmpIndex))
|
||||||
|
const lastAuthor = stripCommasFromName(raw.slice(lastAmpIndex + 3))
|
||||||
|
if (lastAuthor) authors.push(lastAuthor)
|
||||||
|
return authors.join(', ')
|
||||||
|
}
|
||||||
|
|
||||||
class iTunes {
|
class iTunes {
|
||||||
#responseTimeout = 10000
|
#responseTimeout = 10000
|
||||||
|
|
||||||
@@ -103,15 +152,11 @@ class iTunes {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cleanAudiobook(data) {
|
cleanAudiobook(data) {
|
||||||
// artistName can be "Name1, Name2 & Name3" so we refactor this to "Name1, Name2, Name3"
|
|
||||||
// see: https://github.com/advplyr/audiobookshelf/issues/1022
|
|
||||||
const author = (data.artistName || '').split(' & ').join(', ')
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: data.collectionId,
|
id: data.collectionId,
|
||||||
artistId: data.artistId,
|
artistId: data.artistId,
|
||||||
title: data.collectionName,
|
title: data.collectionName,
|
||||||
author,
|
author: cleanAuthor(data.artistName),
|
||||||
description: data.description || null,
|
description: data.description || null,
|
||||||
publishedYear: data.releaseDate ? data.releaseDate.split('-')[0] : null,
|
publishedYear: data.releaseDate ? data.releaseDate.split('-')[0] : null,
|
||||||
genres: data.primaryGenreName ? [data.primaryGenreName] : null,
|
genres: data.primaryGenreName ? [data.primaryGenreName] : null,
|
||||||
|
|||||||
@@ -0,0 +1,53 @@
|
|||||||
|
const iTunes = require('../../../server/providers/iTunes')
|
||||||
|
const { expect } = require('chai')
|
||||||
|
|
||||||
|
describe('iTunes', () => {
|
||||||
|
let itunes
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
itunes = new iTunes()
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('cleanAudiobook', () => {
|
||||||
|
function authorFrom(artistName) {
|
||||||
|
return itunes.cleanAudiobook({ artistName }).author
|
||||||
|
}
|
||||||
|
|
||||||
|
it('should return an empty string if artistName is missing', () => {
|
||||||
|
expect(authorFrom()).to.equal('')
|
||||||
|
expect(authorFrom('')).to.equal('')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should keep a single author without commas', () => {
|
||||||
|
expect(authorFrom('Joy Fielding')).to.equal('Joy Fielding')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should strip commas from a single author with a credential', () => {
|
||||||
|
expect(authorFrom('Rick Hanson, PhD')).to.equal('Rick Hanson PhD')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should split two authors joined by an ampersand', () => {
|
||||||
|
expect(authorFrom('Name1 & Name2')).to.equal('Name1, Name2')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should split three authors using commas and an ampersand', () => {
|
||||||
|
expect(authorFrom('Keltie Knight, Becca Tobin & Jac Vanek')).to.equal('Keltie Knight, Becca Tobin, Jac Vanek')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should glue a one-word credential onto the previous author before the ampersand', () => {
|
||||||
|
expect(authorFrom('Rick Hanson, PhD & Jane Doe')).to.equal('Rick Hanson PhD, Jane Doe')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should glue several one-word credentials in a row', () => {
|
||||||
|
expect(authorFrom('Rick Hanson, PhD, MD & Jane Doe')).to.equal('Rick Hanson PhD MD, Jane Doe')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should strip commas from the last author', () => {
|
||||||
|
expect(authorFrom('Rick Hanson & Jane Doe, PhD')).to.equal('Rick Hanson, Jane Doe PhD')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should glue credentials before the ampersand and strip commas from the last author', () => {
|
||||||
|
expect(authorFrom('Rick Hanson, PhD & Jane Doe, PhD')).to.equal('Rick Hanson PhD, Jane Doe PhD')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
Reference in new issue
Block a user