Skip to content

Commit

Permalink
Merge pull request #75 from kiwilan/develop
Browse files Browse the repository at this point in the history
v2.4.9
  • Loading branch information
ewilan-riviere authored May 22, 2024
2 parents d451e5f + 4205cc0 commit 1519d50
Show file tree
Hide file tree
Showing 19 changed files with 218 additions and 43 deletions.
32 changes: 16 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -248,22 +248,22 @@ Specifications are based on [audiobookshelf](https://www.audiobookshelf.org/docs

Properties of `Audio::class` are:

| **ID3 Tag (case-insensitive) ** | **eBook** |
| ------------------------------- | -------------------------- |
| `artist` / `album-artist` | Authors\* |
| `album` / `title` | Title |
| `subtitle` | Extra property `subtitle` |
| `publisher` | Publisher |
| `year` | Publish Year |
| `composer` | Extra property `narrators` |
| `description` | Description |
| `genre` | Tags\*\* |
| `series` / `mvnm` | Series |
| `series-part` / `mvin` | Volume |
| `language` / `lang` | Language |
| `isbn` | Identifiers `isbn` |
| `asin` / `audible_asin` | Identifiers `asin` |
| Overdrive MediaMarkers | Extra property `chapters` |
| **ID3 Tag (case-insensitive)** | **eBook** |
| ------------------------------ | -------------------------- |
| `artist` / `album-artist` | Authors\* |
| `album` / `title` | Title |
| `subtitle` | Extra property `subtitle` |
| `publisher` | Publisher |
| `year` | Publish Year |
| `composer` | Extra property `narrators` |
| `description` | Description |
| `genre` | Tags\*\* |
| `series` / `mvnm` | Series |
| `series-part` / `mvin` | Volume |
| `language` / `lang` | Language |
| `isbn` | Identifiers `isbn` |
| `asin` / `audible_asin` | Identifiers `asin` |
| Overdrive MediaMarkers | Extra property `chapters` |

- \* Authors naming as well as multiple authors separated by `,`, `;`, `&` or `and`.
- \*\* Tags can include multiple tags separated by `/`, `//`, or `;`. e.g. "Science Fiction/Fiction/Fantasy"
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "kiwilan/php-ebook",
"description": "PHP package to read metadata and extract covers from eBooks, comics and audiobooks.",
"version": "2.4.8",
"version": "2.4.9",
"keywords": [
"php",
"ebook",
Expand Down
13 changes: 5 additions & 8 deletions src/Ebook.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
use Kiwilan\Ebook\Models\BookAuthor;
use Kiwilan\Ebook\Models\BookIdentifier;
use Kiwilan\Ebook\Models\MetaTitle;
use Kiwilan\Ebook\Utils\EbookUtils;

class Ebook
{
Expand Down Expand Up @@ -50,7 +51,7 @@ class Ebook

protected ?string $series = null;

protected ?int $volume = null;
protected int|float|null $volume = null;

protected ?string $copyright = null;

Expand Down Expand Up @@ -469,7 +470,7 @@ public function getSeries(): ?string
/**
* Volume of the book.
*/
public function getVolume(): ?int
public function getVolume(): int|float|null
{
return $this->volume;
}
Expand Down Expand Up @@ -902,13 +903,9 @@ public function setSeries(?string $series): self
return $this;
}

public function setVolume(int|string|null $volume): self
public function setVolume(int|string|float|null $volume): self
{
if (is_string($volume)) {
$volume = intval($volume);
}

$this->volume = $volume;
$this->volume = EbookUtils::parseNumber($volume);

return $this;
}
Expand Down
5 changes: 4 additions & 1 deletion src/Formats/Audio/AudiobookModule.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Kiwilan\Ebook\Formats\EbookModule;
use Kiwilan\Ebook\Models\BookAuthor;
use Kiwilan\Ebook\Models\BookIdentifier;
use Kiwilan\Ebook\Utils\EbookUtils;

class AudiobookModule extends EbookModule
{
Expand Down Expand Up @@ -62,7 +63,7 @@ private function create(): self
'synopsis' => $this->parseTag($audio->getTag('description_long')),
'genres' => $genres,
'series' => $this->parseTag($series),
'series_sequence' => $series_part ? intval($series_part) : null,
'series_sequence' => $series_part ? EbookUtils::parseNumber($series_part) : null,
'language' => $this->parseTag($language),
'isbn' => $this->parseTag($audio->getTag('isbn')),
'asin' => $this->parseTag($audio->getTag('asin') ?? $audio->getTag('audible_asin')),
Expand All @@ -79,6 +80,7 @@ private function create(): self
'audio_artist' => $audio->getArtist(),
'audio_album' => $audio->getAlbum(),
'audio_album_artist' => $audio->getAlbumArtist(),
'audio_composer' => $audio->getComposer(),
];

return $this;
Expand Down Expand Up @@ -142,6 +144,7 @@ public function toEbook(): Ebook
'audio_artist' => $this->audio['audio_artist'],
'audio_album' => $this->audio['audio_album'],
'audio_album_artist' => $this->audio['audio_album_artist'],
'audio_composer' => $this->audio['audio_composer'],
]);

$this->ebook->setHasParser(true);
Expand Down
1 change: 1 addition & 0 deletions src/Formats/Cba/CbaModule.php
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ private function parseCbam(): Ebook
alternateCount: $this->cbam->getAlternateCount(),
count: $this->cbam->getCount(),
volume: $this->cbam->getVolume(),
number: $this->cbam->getNumber(),
storyArc: $this->cbam->getStoryArc(),
storyArcNumber: $this->cbam->getStoryArcNumber(),
seriesGroup: $this->cbam->getSeriesGroup(),
Expand Down
28 changes: 19 additions & 9 deletions src/Formats/Cba/Parser/CbamTemplate.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use DateTime;
use Kiwilan\Ebook\Enums\AgeRatingEnum;
use Kiwilan\Ebook\Enums\MangaEnum;
use Kiwilan\Ebook\Utils\EbookUtils;
use Kiwilan\XmlReader\XmlReader;

/**
Expand Down Expand Up @@ -55,7 +56,7 @@ class CbamTemplate extends CbaTemplate

protected ?string $series = null;

protected ?int $number = null; // Number of the book in the series
protected int|float|null $number = null; // Number of the book in the series

protected ?string $summary = null;

Expand Down Expand Up @@ -92,11 +93,11 @@ class CbamTemplate extends CbaTemplate

protected ?int $count = null; // The total number of books in the series

protected ?int $volume = null; // Volume containing the book. Only US Comics
protected int|float|null $volume = null; // Volume containing the book. Only US Comics

protected ?string $storyArc = null;

protected ?int $storyArcNumber = null;
protected int|float|null $storyArcNumber = null;

protected ?string $seriesGroup = null;

Expand Down Expand Up @@ -127,9 +128,9 @@ private function parse(): void
{
$this->title = $this->extract('Title');
$this->series = $this->extract('Series');
$this->number = $this->extractInt('Number');
$this->number = $this->extractFloat('Number');
$this->count = $this->extractInt('Count');
$this->volume = $this->extractInt('Volume');
$this->volume = $this->extractFloat('Volume');
$this->alternateSeries = $this->extract('AlternateSeries');
$this->alternateNumber = $this->extractInt('AlternateNumber');
$this->alternateCount = $this->extract('AlternateCount');
Expand Down Expand Up @@ -173,7 +174,7 @@ private function parse(): void
$this->locations = $this->arrayable($this->extract('Locations'));
$this->scanInformation = $this->extract('ScanInformation');
$this->storyArc = $this->extract('StoryArc');
$this->storyArcNumber = $this->extractInt('StoryArcNumber');
$this->storyArcNumber = $this->extractFloat('StoryArcNumber');
$this->seriesGroup = $this->extract('SeriesGroup');

$ageRating = $this->extract('AgeRating');
Expand Down Expand Up @@ -225,6 +226,15 @@ private function extractInt(string $key): ?int
return null;
}

private function extractFloat(string $key): int|float|null
{
if ($this->extract($key)) {
return EbookUtils::parseNumber($this->extract($key));
}

return null;
}

private function normalizeString(string $string): ?string
{
if (empty($string)) {
Expand Down Expand Up @@ -352,7 +362,7 @@ public function getSeries(): ?string
return $this->series;
}

public function getNumber(): ?int
public function getNumber(): int|float|null
{
return $this->number;
}
Expand Down Expand Up @@ -445,7 +455,7 @@ public function getCount(): ?int
return $this->count;
}

public function getVolume(): ?int
public function getVolume(): int|float|null
{
return $this->volume;
}
Expand All @@ -455,7 +465,7 @@ public function getStoryArc(): ?string
return $this->storyArc;
}

public function getStoryArcNumber(): ?int
public function getStoryArcNumber(): int|float|null
{
return $this->storyArcNumber;
}
Expand Down
2 changes: 1 addition & 1 deletion src/Formats/Epub/EpubModule.php
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ public function toEbook(): Ebook
$this->ebook->setSeries($meta->getContents());
}
if ($meta->getName() === 'calibre:series_index') {
$this->ebook->setVolume((int) $meta->getContents());
$this->ebook->setVolume($meta->getContents());
}
if ($meta->getName() === 'calibre:rating') {
$rating = (float) $meta->getContents();
Expand Down
14 changes: 10 additions & 4 deletions src/Models/ComicMeta.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,10 @@ public function __construct(
protected ?int $alternateNumber = null,
protected ?string $alternateCount = null,
protected ?int $count = null,
protected ?int $volume = null,
protected int|float|null $volume = null,
protected int|float|null $number = null,
protected ?string $storyArc = null,
protected ?int $storyArcNumber = null,
protected int|float|null $storyArcNumber = null,
protected ?string $seriesGroup = null,
protected ?string $imprint = null,
protected ?string $scanInformation = null,
Expand Down Expand Up @@ -86,17 +87,22 @@ public function count(): ?int
return $this->count;
}

public function volume(): ?int
public function volume(): int|float|null
{
return $this->volume;
}

public function number(): int|float|null
{
return $this->number;
}

public function storyArc(): ?string
{
return $this->storyArc;
}

public function storyArcNumber(): ?int
public function storyArcNumber(): int|float|null
{
return $this->storyArcNumber;
}
Expand Down
43 changes: 43 additions & 0 deletions src/Utils/EbookUtils.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

namespace Kiwilan\Ebook\Utils;

class EbookUtils
{
public static function parseNumber(mixed $number): int|float|null
{
if (EbookUtils::isFloat($number)) {
return floatval($number);
}

if (is_string($number)) {
return intval($number);
}

if (is_int($number)) {
return $number;
}

return null;
}

public static function isFloat(mixed $string): bool
{
if (is_numeric($string)) {
$val = $string + 0;

$is_float = is_float($val);
if ($is_float) {
$explode = explode('.', strval($val));
$after_dot = $explode[1] ?? 0;
if ($after_dot === 0) {
return false;
}

return true;
}
}

return false;
}
}
6 changes: 6 additions & 0 deletions tests/AudiobookTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -89,3 +89,9 @@
expect($ebook->getExtra('audio_album'))->toBe("La Quête d'Ewilan #01 : D'un monde à l'autre");
expect($ebook->getExtra('audio_album_artist'))->toBe('Pierre Bottero, Kelly Marot');
});

it('can parse audiobook with alt volume', function () {
$ebook = Ebook::read(AUDIOBOOK_EWILAN_VOLUME);

expect($ebook->getVolume())->toBe(1.1);
});
10 changes: 10 additions & 0 deletions tests/CbaTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -240,3 +240,13 @@
expect($meta->mainCharacterOrTeam())->toBe('main character or team');
expect($meta->format())->toBe('format');
});

it('can parse cba with alt volume', function () {
$ebook = Ebook::read(CBZ_CBAM_VOLUME);

expect($ebook->getVolume())->toBe(22.5);
$comicMeta = $ebook->getExtras()['comicMeta'];
expect($comicMeta->volume())->toBe(1.5);
expect($comicMeta->number())->toBe(22.5);
expect($comicMeta->storyArcNumber())->toBe(2.5);
});
11 changes: 9 additions & 2 deletions tests/EpubTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -184,11 +184,17 @@
expect($ebook->getDescriptionHtml())->toBe("<div><p>1re vague : Extinction des feux.<br>2e vague : Déferlante.<br>3e vague : Pandémie.<br>4e vague : Silence.<br><br>À l'aube de la 5e vague, sur une autoroute désertée, Cassie tente de Leur échapper... Eux, ces êtres qui ressemblent trait pour trait aux humains et qui écument la campagne, exécutant quiconque a le malheur de croiser Leur chemin. Eux, qui ont balayé les dernières poches de résistance et dispersé les quelques rescapés.<br><br>Pour Cassie, rester en vie signifie rester seule. Elle se raccroche à cette règle jusqu'à ce qu'elle rencontre Evan Walker. Mystérieux et envoûtant, ce garçon pourrait bien être son ultime espoir de sauver son petit frère. Du moins si Evan est bien celui qu'il prétend...</p><p>Ils connaissent notre manière de penser.</p><p>Ils savent commentr nous exterminer.</p><p>Ils nous ont enlevé toute raison de vivre.</p><p>Ils viennent nous arracher ce pour quoi nous sommes prêts à mourir.</p></div>");
})->with([EPUB_DESCRIPTION]);

it('can parse epub with series but empty volume', function (string $path) {
it('can parse epub with series and zero volume', function (string $path) {
$ebook = Ebook::read($path);

expect($ebook->getVolume())->toBe(0);
})->with([EPUB_VOL0]);
})->with([EPUB_VOLZERO]);

it('can parse epub with series and float volume', function (string $path) {
$ebook = Ebook::read($path);

expect($ebook->getVolume())->toBe(1.5);
})->with([EPUB_VOLFLOAT]);

it('can parse epub with bad summary', function (string $path) {
$ebook = Ebook::read($path);
Expand All @@ -209,6 +215,7 @@
expect($ebook->getPublishDate()->format('Y-m-d H:i:s'))->toBe($date->format('Y-m-d H:i:s'));
expect($ebook->getLanguage())->toBe('fr');
expect($ebook->getCopyright())->toBe('© 2020 Scrineo');
expect($ebook->getVolume())->toBeNull();

$cover = $ebook->getCover();
$path = 'tests/output/cover-EPUB-DRM.jpg';
Expand Down
5 changes: 5 additions & 0 deletions tests/OpfTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -135,3 +135,8 @@

expect($opf->getDcCreators())->toBeEmpty();
})->with([EPUB_OPF_EMPTY_CREATOR]);

it('can use float volume', function () {
$opf = OpfItem::make(file_get_contents(EPUB_OPF_EPUB2_VOLUME_FLOAT), EPUB_OPF_EPUB2_VOLUME_FLOAT);
expect($opf->getMetaItem('calibre:series_index')->getContents())->toBe('1.5');
});
Loading

0 comments on commit 1519d50

Please sign in to comment.