mikespub-org / seblucas-cops

Calibre OPDS (and HTML) PHP Server : web-based light alternative to Calibre content server / Calibre2OPDS to serve ebooks (epub, mobi, pdf, ...)
http://blog.slucas.fr/en/oss/calibre-opds-php-server
GNU General Public License v2.0
55 stars 7 forks source link

kepub.epub download and UTF8 Content-Disposition #71

Open tobybryans opened 6 months ago

tobybryans commented 6 months ago

Hi all,

Some background: I have just upgraded to 2.2.1 from 2.1.5, although I suspect this goes back past that as I'm not sure I have tired to download books from my COPS when I moved from the original SebLucas version to this one until now.

On Kobos, if you don't put the suffix .kepub.epub on the file the reading experience is severely reduced. I thought the rename process in COPS was working, but it turns out the Kobo browser doesn't support UTF8 encoding in Content-Disposition. So, for example, this doesn't work:

Content-Disposition: attachment; filename*=UTF-8''Kewin%2C%20Simon%20-%20Dead%20Star.kepub.epub

...and results in the file being called the original .epub filename.

But, this works:

Content-Disposition: attachment; filename="Kewin, Simon - Dead Star.kepub.epub"

To get COPS to produce the above, I made the following change to vendor/maennchen/zipstream-php/src/ZipStream.php, function sendHttpHeaders()

#            $disposition .= "; filename*=UTF-8''{$urlencoded}";
            $disposition .= "; filename=\"{$safeOutput}\"";

however, there may well be a better way and place to fix it (not in the vendor code, for example!), or of course I have missed some other way of making this work. Happy to share config_local.php if that would help.

mikespub commented 6 months ago

Thanks for tracking this down.

At the moment in fetch.php the renaming to .kepub.epub (based on cops_provide_kepub) depends on enabling the update of the metadata as well (based on cops_update_epub-metadata). And it's actually that last part that requires us to re-build the EPUB file and go through ZipStream.

https://github.com/mikespub-org/seblucas-cops/blob/630075c8159038c6eb110ec12459bf1b4c1d38e9/fetch.php#L80-L86

From what I can see in the code, the only actual change inside the EPUB file for Kobo in Book->getUpdatedEpub() is to add another property for cover-image if there is a cover image in EPub->updateForKepub(). If you can live without that part, we could change the logic and send the unchanged EPUB file directly in fetch.php with a .kepub.epub filename instead.

https://github.com/mikespub-org/seblucas-cops/blob/630075c8159038c6eb110ec12459bf1b4c1d38e9/fetch.php#L90

But I don't know if you need that updated metadata for anything else for Kobo or not...

tobybryans commented 6 months ago

Thank you @mikespub for looking into this, much appreciated. I have a feeling that the property update is probably needed for cover display (one of the things that doesn't work as well on Kobo's with .epub files is the covers) but more than willing to test to see whether that is the case or not! Is there an easy way for me to stop the cover property change?

mikespub commented 4 months ago

The change above allows you to test provide_kepub without update_epub-metadata if you want...

Since this will not update the opf properties for cover-image in the EPub file, this might not work correctly for Kobo, but if it does work you won't need to hack the ZipStream library after each upgrade anymore

SenorSmartyPants commented 3 months ago

Would using kepubify be a possible solution to all this?

dunxd commented 3 months ago

If the epubs are uploaded to the Kobo from Calibre without using COPS at all what happens? Is the same problem there? Is there a setting in Calibre that fixes the issue?