johnfactotum / foliate

Read e-books in style
https://johnfactotum.github.io/foliate/
GNU General Public License v3.0
6.44k stars 296 forks source link

Add multiple books to library at once #1196

Open crimsonfall opened 11 months ago

crimsonfall commented 11 months ago

Currently the only way to add a book (.epub file) to your personal Foliate library is to open them, however you can only do so one-at-a-time (there's no way to select multiple books at once). This makes it frustrating if, for example, you already have a sizeable collection of ebooks you want to transfer over to Foliate, but would have to spend a considerable amount of time adding each book to your library. In previous versions of Foliate, you were able add multiple books to your library at once.

A solution to this issue would be of course to simply have a feature where you can add multiple ebooks (.epub files or other formats) to your library at once without opening them all. Perhaps a simple ‘Add’ or ‘+’ button would suffice, which upon pressing it, would open your file manager and allow you to select your ebook(s).

Edit: I forgot to mention earlier, but I think adding the ability to also remove multiple books from a library at once would also be nice.

(Congratulations on your app rewrite by the way, it looks and functions far better than before!)

jaybent commented 5 months ago

Workaround: find . -type f -print0 | xargs -0 -I {} bash -c 'foliate "{}" & sleep 1' && sleep 10 && killall foliate

Explanation: This workaround allows opens multiple files with foliate and then close all instances of foliate at once, effectively bulk adding all files under current path (recursively).

  1. find . -print0 recursively finds all files from the current directory (the period), printing them separated by null characters.
  2. xargs -0 -I {} bash -c 'foliate "{}" & sleep 1' uses xargs to pass each found item to the bash command:
    • foliate "{}" opens the file with foliate and runs it in the background.
    • sleep 1 gives a brief pause to ensure the GUI window has time to load for each instance.
  3. && sleep 10 waits for 10 seconds after all instances have been started, giving them time to fully load.
  4. killall foliate terminates all instances of foliate at once.

Caveat: The sleep timers (sleep 1 and sleep 10) might need to be tweaked depending on your system and/or disk speed to ensure all windows have time to open properly, and for foliate to write all required files before being closed.

This assumes all files under current path are e-books, it is undefined what happens if any other files exists. Modify the find command if this is a problem, example: find . -type f -iname *.pdf -print0 will only match files with names ending in .pdf, likely being PDFs.

Warning: This command will open all files found, it could potentially consume a huge amount of RAM and crash the system if there is a lot of files or they are large.

IBBoard commented 1 month ago

An alternative command that should use less RAM (but will take a little longer):

find . -type f -print0 | xargs -0 -I {} bash -c 'foliate "{}" & FOLIATE_PID=$! && sleep 3 && kill $FOLIATE_PID'

The difference is that it captures the PID for the backgrounded process, waits slightly longer so that the app has started properly, and then explicitly kills that process rather than trying to "killall" at the end.