mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2026-11-13 12:23:34 +01:00
Merge pull request #5694 from mikiher/fix-itunes-parsing
Keep iTunes author credentials attached to the name
This commit is contained in:
2 files changed
+103
-5
No files matched your search
@@ -27,6 +27,55 @@ const htmlSanitizer = require('../utils/htmlSanitizer')
|
||||
* @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 {
|
||||
#responseTimeout = 10000
|
||||
|
||||
@@ -103,15 +152,11 @@ class iTunes {
|
||||
}
|
||||
|
||||
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 {
|
||||
id: data.collectionId,
|
||||
artistId: data.artistId,
|
||||
title: data.collectionName,
|
||||
author,
|
||||
author: cleanAuthor(data.artistName),
|
||||
description: data.description || null,
|
||||
publishedYear: data.releaseDate ? data.releaseDate.split('-')[0] : 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