Skip to content

Commit

Permalink
Merge pull request #65 from kiwilan/develop
Browse files Browse the repository at this point in the history
v2.3.5
  • Loading branch information
ewilan-riviere authored Jan 29, 2024
2 parents 3d70dfd + bb8a975 commit c27b8b6
Show file tree
Hide file tree
Showing 7 changed files with 114 additions and 8 deletions.
26 changes: 25 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,9 @@ $ebook->getLanguage(); // ?string
$ebook->getTags(); // string[] => `subject` in EPUB, `keywords` in PDF, `genres` in CBA
$ebook->getSeries(); // ?string => `calibre:series` in EPUB, `series` in CBA
$ebook->getVolume(); // ?int => `calibre:series_index` in EPUB, `number` in CBA
$ebook->getCreatedAt(); // ?DateTime => file modified date
$ebook->getSize(); // int => file size in bytes
$ebook->getSizeHumanReadable(); // string => file size in human readable format
```

For pages count, you can use these methods:
Expand All @@ -134,6 +137,10 @@ $ebook->getExtras(); // array<string, mixed> => additional data for book
$ebook->getExtra(string $key); // mixed => safely extract data from `extras` array
```

> [!NOTE]
>
> For audiobooks, all metadata are stored into `extras` array, you will find duplicate with `Ebook::class` properties. See [Formats specifications](#formats-specifications) for more informations.
To know if eBook is valid, you can use `isValid()` static method, before `read()`.

```php
Expand Down Expand Up @@ -163,8 +170,9 @@ And to test if some data exists:
$ebook->isArchive(); // bool => `true` if `EPUB`, `CBA`
$ebook->isMobi(); // bool => `true` if Mobipocket derivatives
$ebook->isAudio(); // bool => `true` if `mp3`, `m4a`, `m4b`, `flac`, `ogg`
$ebook->hasMetadata(); // bool => `true` if metadata exists
$ebook->hasCover(); // bool => `true` if cover exists
$ebook->hasMetadata(); // bool => `true` if metadata exists
$ebook->hasSeries(); // bool => `true` if series exists
$ebook->isBadFile(); // bool => `true` if file is not readable
```

Expand Down Expand Up @@ -237,6 +245,22 @@ $cover->getContents(bool $toBase64 = false); // ?string => content of cover, if

For audiobooks, you have to install seperately [`kiwilan/php-audio`](https://github.com/kiwilan/php-audio).

Properties of `Audio::class` are:

| **Ebook** | **Audio** |
| ----------- | ------------ |
| title | title |
| author | artist |
| description | description |
| tags | artist |
| series | album |
| volume | trackNumber |
| publishDate | artist |
| copyright | creationDate |
| author | encodingBy |

You can find all metadata into `getExtras()` array of `Ebook::class`.

#### EPUB

With `EPUB`, metadata are extracted from `OPF` file, `META-INF/container.xml` files, you could access to these metatada but you can also get chapters from `NCX` file. And with `chapters()` method you can merge `NCX` and `HTML` chapters to get full book chapters with `label`, `source` and `content`.
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.3.4",
"version": "2.3.5",
"keywords": [
"php",
"ebook",
Expand Down
69 changes: 68 additions & 1 deletion src/Ebook.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ protected function __construct(
protected string $filename,
protected string $basename,
protected string $extension,
protected int $size = 0,
protected ?DateTime $createdAt = null,
protected ?BaseArchive $archive = null,
protected ?\Kiwilan\Audio\Audio $audio = null,
protected bool $isArchive = false,
Expand Down Expand Up @@ -271,10 +273,28 @@ private function convertEbook(): self
$this->series = $ebook->getSeries();
$this->volume = $ebook->getVolume();
$this->copyright = $ebook->getCopyright();
$this->generateFileMetadata();

return $this;
}

/**
* Generate file metadata.
*/
private function generateFileMetadata(): void
{
$file = new \SplFileInfo($this->getpath());
if ($file->getMTime()) {
$ts = gmdate("Y-m-d\TH:i:s\Z", $file->getMTime());
$dt = new \DateTime($ts);
$this->createdAt = $dt;
}

if ($file->getSize()) {
$this->size = $file->getSize();
}
}

private function convertCounts(): self
{
$this->countsParsed = true;
Expand Down Expand Up @@ -473,6 +493,43 @@ public function getExtension(): string
return $this->extension;
}

/**
* Size of the ebook, in bytes.
*
* You can use `getSizeHumanReadable()` to get the size in human readable format.
*/
public function getSize(): int
{
return $this->size;
}

/**
* Size of the ebook in human readable format, e.g. `1.23 MB`.
*/
public function getSizeHumanReadable(): string
{
$bytes = $this->size;
$units = ['B', 'KB', 'MB', 'GB', 'TB'];

foreach ($units as $unit) {
if ($bytes < 1024) {
break;
}

$bytes /= 1024;
}

return round($bytes, 2).' '.$unit;
}

/**
* Creation date of the ebook.
*/
public function getCreatedAt(): ?DateTime
{
return $this->createdAt;
}

/**
* Archive reader, from `kiwilan/php-archive`.
*
Expand Down Expand Up @@ -526,6 +583,14 @@ public function isArchive(): bool
return $this->isArchive;
}

/**
* Whether the ebook has series.
*/
public function hasSeries(): bool
{
return $this->series !== null;
}

/**
* Whether the ebook has parser.
*
Expand Down Expand Up @@ -884,7 +949,7 @@ public function toArray(): array
'descriptionHtml' => $this->descriptionHtml,
'publisher' => $this->publisher,
'identifiers' => array_map(fn (BookIdentifier $identifier) => $identifier->toArray(), $this->identifiers),
'date' => $this->publishDate?->format('Y-m-d H:i:s'),
'publishDate' => $this->publishDate?->format('Y-m-d H:i:s'),
'language' => $this->language,
'tags' => $this->tags,
'series' => $this->series,
Expand All @@ -896,6 +961,8 @@ public function toArray(): array
'basename' => $this->basename,
'extension' => $this->extension,
'format' => $this->format,
'extras' => $this->extras,
'metaTitle' => $this->metaTitle?->toArray(),
'parser' => $this->parser?->toArray(),
'cover' => $this->cover?->toArray(),
];
Expand Down
13 changes: 11 additions & 2 deletions src/Formats/Audio/AudiobookModule.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,7 @@ public function toEbook(): Ebook
$date = new DateTime("{$audio->getYear()}-01-01");
}

$description = "{$audio->getDescription()} {$audio->getComment()}";
$description = trim($description);
$description = trim($audio->getDescription() ?? '');

$this->ebook->setTitle($audio->getTitle());
$this->ebook->setAuthors([$author]);
Expand All @@ -88,6 +87,16 @@ public function toEbook(): Ebook
$this->ebook->setPublishDate($date);
$this->ebook->setCopyright($audio->getEncodingBy());
$this->ebook->setExtras([
'title' => $audio->getTitle(),
'artist' => $audio->getArtist(),
'albumArtist' => $audio->getAlbumArtist(),
'album' => $audio->getAlbum(),
'genre' => $audio->getGenre(),
'year' => $audio->getYear(),
'trackNumber' => $audio->getTrackNumber(),
'description' => $audio->getDescription(),
'comment' => $audio->getComment(),
'creationDate' => $audio->getCreationDate(),
'composer' => $audio->getComposer(),
'discNumber' => $audio->getDiscNumber(),
'isCompilation' => $audio->isCompilation(),
Expand Down
6 changes: 4 additions & 2 deletions tests/AudiobookTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

$metadata = $ebook->getParser();
expect($metadata->getAudiobook()->getAudio())->toBeArray();
expect($ebook->getExtras())->toBeArray();
expect($metadata->getAudiobook()->toArray())->toBeArray();
expect($metadata->getAudiobook()->toJson())->toBeString();
expect($metadata->getAudiobook()->__toString())->toBeString();
Expand All @@ -27,7 +28,7 @@
);
// expect($ebook->getLanguage())->toBe('en');
expect($ebook->getPublisher())->toBe('P1PDD & Mr Piouf');
expect($ebook->getDescription())->toBe('http://www.p1pdd.com');
expect($ebook->getExtra('comment'))->toBe('http://www.p1pdd.com');
expect($ebook->getSeries())->toBe('P1PDD Le conclave de Troie');
expect($ebook->getVolume())->toBe(1);
expect($ebook->getPagesCount())->toBe(11);
Expand All @@ -43,7 +44,8 @@
->toBeInstanceOf(BookAuthor::class)
);
expect($ebook->getPublisher())->toBe('Ewilan');
expect($ebook->getDescription())->toBe('Epic story about audiobooks. Do you want to extract an audiobook?');
expect($ebook->getDescription())->toBe('Epic story about audiobooks.');
expect($ebook->getExtra('comment'))->toBe('Do you want to extract an audiobook?');
expect($ebook->getSeries())->toBe('Audiobook Test');
expect($ebook->getVolume())->toBe(1);
expect($ebook->getCopyright())->toBe('Ewilan Rivière');
Expand Down
3 changes: 2 additions & 1 deletion tests/EbookTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
$ebook = Ebook::read($path);

expect($ebook)->toBeInstanceOf(Ebook::class);
expect($ebook->getCreatedAt() instanceof DateTime)->toBeTrue();
expect($ebook->getpath())->toBe($path);
expect($ebook->toArray())->toBeArray();
expect($ebook->toJson())->toBeString();
Expand Down Expand Up @@ -43,7 +44,7 @@
expect($parser)->toBeInstanceOf(EbookParser::class);
expect($ebook->getParser())->toBeInstanceOf(EbookParser::class);

expect($ebook->getMetaTitle()->getUniqueFilename())->toBeString();
expect($ebook->getMetaTitle()->getSlug())->toBeString();

if ($parser->isEpub()) {
expect($parser->getEpub())->toBeInstanceOf(EpubModule::class);
Expand Down
3 changes: 3 additions & 0 deletions tests/EpubTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@
expect($ebook->getDescription(1500))->toBeString();
expect($ebook->getCopyright(255))->toBe('Copyright © 1980 by Jean M. Auel');
expect($ebook->getCopyright(10))->toBe('Copyright…');
expect($ebook->getCreatedAt())->toBeInstanceOf(DateTime::class);
expect($ebook->getSize())->toBe(555895);
expect($ebook->getSizeHumanReadable())->toBe('542.87 KB');
expect($ebook->getPublisher())->toBe('Hodder & Stoughton');
expect($ebook->getIdentifiers())->toBeArray();
expect($ebook->getIdentifiers()['google']->getValue())->toBe('ASvHBAAAQBAJ');
Expand Down

0 comments on commit c27b8b6

Please sign in to comment.