mirror of
				https://github.com/advplyr/audiobookshelf.git
				synced 2025-10-27 11:18:14 +01:00 
			
		
		
		
	Merge pull request #2444 from jedrus2000/opf-multiple-series-support
Add: OPF file supports multiple series as sequence of : calibre:series and calibre:series_index; including tests
This commit is contained in:
		
						commit
						7402e4811d
					
				| @ -32,11 +32,8 @@ class OpfFileScanner { | ||||
|             bookMetadata.narrators = opfMetadata.narrators | ||||
|           } | ||||
|         } else if (key === 'series') { | ||||
|           if (opfMetadata.series) { | ||||
|             bookMetadata.series = [{ | ||||
|               name: opfMetadata.series, | ||||
|               sequence: opfMetadata.sequence || null | ||||
|             }] | ||||
|           if (opfMetadata.series?.length) { | ||||
|             bookMetadata.series = opfMetadata.series | ||||
|           } | ||||
|         } else if (opfMetadata[key] && key !== 'sequence') { | ||||
|           bookMetadata[key] = opfMetadata[key] | ||||
|  | ||||
| @ -100,13 +100,19 @@ function fetchLanguage(metadata) { | ||||
| } | ||||
| 
 | ||||
| function fetchSeries(metadataMeta) { | ||||
|   if (!metadataMeta) return null | ||||
|   return fetchTagString(metadataMeta, "calibre:series") | ||||
| } | ||||
| 
 | ||||
| function fetchVolumeNumber(metadataMeta) { | ||||
|   if (!metadataMeta) return null | ||||
|   return fetchTagString(metadataMeta, "calibre:series_index") | ||||
|   if (!metadataMeta) return [] | ||||
|   const result = [] | ||||
|   for (let i = 0; i < metadataMeta.length; i++) { | ||||
|     if (metadataMeta[i].$?.name === "calibre:series" && metadataMeta[i].$.content?.trim()) { | ||||
|       const name = metadataMeta[i].$.content.trim() | ||||
|       let sequence = null | ||||
|       if (metadataMeta[i + 1]?.$?.name === "calibre:series_index" && metadataMeta[i + 1].$?.content?.trim()) { | ||||
|         sequence = metadataMeta[i + 1].$.content.trim() | ||||
|       } | ||||
|       result.push({ name, sequence }) | ||||
|     } | ||||
|   } | ||||
|   return result | ||||
| } | ||||
| 
 | ||||
| function fetchNarrators(creators, metadata) { | ||||
| @ -173,8 +179,7 @@ module.exports.parseOpfMetadataXML = async (xml) => { | ||||
|     description: fetchDescription(metadata), | ||||
|     genres: fetchGenres(metadata), | ||||
|     language: fetchLanguage(metadata), | ||||
|     series: fetchSeries(metadata.meta), | ||||
|     sequence: fetchVolumeNumber(metadata.meta), | ||||
|     series: fetchSeries(metadataMeta), | ||||
|     tags: fetchTags(metadata) | ||||
|   } | ||||
|   return data | ||||
|  | ||||
							
								
								
									
										113
									
								
								test/server/utils/parsers/parseOpfMetadata.test.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										113
									
								
								test/server/utils/parsers/parseOpfMetadata.test.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,113 @@ | ||||
| const chai = require('chai') | ||||
| const expect = chai.expect | ||||
| const { parseOpfMetadataXML } = require('../../../../server/utils/parsers/parseOpfMetadata') | ||||
| 
 | ||||
| describe('parseOpfMetadata - test series', async () => { | ||||
|     it('test one series', async () => { | ||||
|         const opf = ` | ||||
|             <?xml version='1.0' encoding='UTF-8'?> | ||||
|             <package xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:opf="http://www.idpf.org/2007/opf" xml:lang="en" version="3.0" unique-identifier="bookid"> | ||||
|               <metadata> | ||||
|                   <meta name="calibre:series" content="Serie"/> | ||||
|                   <meta name="calibre:series_index" content="1"/> | ||||
|               </metadata> | ||||
|             </package> | ||||
|         ` | ||||
|         const parsedOpf = await parseOpfMetadataXML(opf) | ||||
|         expect(parsedOpf.series).to.deep.equal([{ "name": "Serie", "sequence": "1" }]) | ||||
|     }) | ||||
| 
 | ||||
|     it('test more then 1 series - in correct order', async () => { | ||||
|         const opf = ` | ||||
|             <?xml version='1.0' encoding='UTF-8'?> | ||||
|             <package xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:opf="http://www.idpf.org/2007/opf" xml:lang="en" version="3.0" unique-identifier="bookid"> | ||||
|               <metadata> | ||||
|                   <meta name="calibre:series" content="Serie 1"/> | ||||
|                   <meta name="calibre:series_index" content="1"/> | ||||
|                   <meta name="calibre:series" content="Serie 2"/> | ||||
|                   <meta name="calibre:series_index" content="2"/> | ||||
|                   <meta name="calibre:series" content="Serie 3"/> | ||||
|                   <meta name="calibre:series_index" content="3"/> | ||||
|               </metadata> | ||||
|             </package> | ||||
|         ` | ||||
|         const parsedOpf = await parseOpfMetadataXML(opf) | ||||
|         expect(parsedOpf.series).to.deep.equal([ | ||||
|             { "name": "Serie 1", "sequence": "1" }, | ||||
|             { "name": "Serie 2", "sequence": "2" }, | ||||
|             { "name": "Serie 3", "sequence": "3" }, | ||||
|         ]) | ||||
|     }) | ||||
| 
 | ||||
|     it('test messed order of series content and index', async () => { | ||||
|         const opf = ` | ||||
|             <?xml version='1.0' encoding='UTF-8'?> | ||||
|             <package xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:opf="http://www.idpf.org/2007/opf" xml:lang="en" version="3.0" unique-identifier="bookid"> | ||||
|               <metadata> | ||||
|                   <meta name="calibre:series" content="Serie 1"/> | ||||
|                   <meta name="calibre:series_index" content="1"/> | ||||
|                   <meta name="calibre:series_index" content="2"/> | ||||
|                   <meta name="calibre:series_index" content="3"/> | ||||
|                   <meta name="calibre:series" content="Serie 3"/> | ||||
|               </metadata> | ||||
|             </package> | ||||
|         ` | ||||
|         const parsedOpf = await parseOpfMetadataXML(opf) | ||||
|         expect(parsedOpf.series).to.deep.equal([ | ||||
|             { "name": "Serie 1", "sequence": "1" }, | ||||
|             { "name": "Serie 3", "sequence": null }, | ||||
|         ]) | ||||
|     }) | ||||
| 
 | ||||
|     it('test different values of series content and index', async () => { | ||||
|         const opf = ` | ||||
|             <?xml version='1.0' encoding='UTF-8'?> | ||||
|             <package xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:opf="http://www.idpf.org/2007/opf" xml:lang="en" version="3.0" unique-identifier="bookid"> | ||||
|               <metadata> | ||||
|                   <meta name="calibre:series" content="Serie 1"/> | ||||
|                   <meta name="calibre:series_index"/> | ||||
|                   <meta name="calibre:series" content="Serie 2"/> | ||||
|                   <meta name="calibre:series_index" content="abc"/> | ||||
|                   <meta name="calibre:series" content="Serie 3"/> | ||||
|                   <meta name="calibre:series_index" content=""/> | ||||
|               </metadata> | ||||
|             </package> | ||||
|         ` | ||||
|         const parsedOpf = await parseOpfMetadataXML(opf) | ||||
|         expect(parsedOpf.series).to.deep.equal([ | ||||
|             { "name": "Serie 1", "sequence": null }, | ||||
|             { "name": "Serie 2", "sequence": "abc" }, | ||||
|             { "name": "Serie 3", "sequence": null }, | ||||
|         ]) | ||||
|     }) | ||||
| 
 | ||||
|     it('test empty series content', async () => { | ||||
|         const opf = ` | ||||
|             <?xml version='1.0' encoding='UTF-8'?> | ||||
|             <package xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:opf="http://www.idpf.org/2007/opf" xml:lang="en" version="3.0" unique-identifier="bookid"> | ||||
|               <metadata> | ||||
|                   <meta name="calibre:series" content=""/> | ||||
|                   <meta name="calibre:series_index" content=""/> | ||||
|               </metadata> | ||||
|             </package> | ||||
|         ` | ||||
|         const parsedOpf = await parseOpfMetadataXML(opf) | ||||
|         expect(parsedOpf.series).to.deep.equal([]) | ||||
|     }) | ||||
| 
 | ||||
|     it('test series and index using an xml namespace', async () => { | ||||
|         const opf = ` | ||||
|             <?xml version='1.0' encoding='UTF-8'?> | ||||
|             <ns0:package xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:opf="http://www.idpf.org/2007/opf" xml:lang="en" version="3.0" unique-identifier="bookid"> | ||||
|               <ns0:metadata> | ||||
|                   <ns0:meta name="calibre:series" content="Serie 1"/> | ||||
|                   <ns0:meta name="calibre:series_index" content=""/> | ||||
|               </ns0:metadata> | ||||
|             </ns0:package> | ||||
|         ` | ||||
|         const parsedOpf = await parseOpfMetadataXML(opf) | ||||
|         expect(parsedOpf.series).to.deep.equal([ | ||||
|             { "name": "Serie 1", "sequence": null } | ||||
|         ]) | ||||
|     }) | ||||
| }) | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user