reitzig / scripts

Collection of arguably useful shell scripts.
GNU General Public License v3.0
20 stars 10 forks source link

pdfinvert.rb does not work if Inkscape can not access /tmp #1

Open TheDarkTron opened 4 years ago

TheDarkTron commented 4 years ago

I really appreciate the work you put in the pdfinvert script. I searched long on the internet to find sth useful to invert pdf 😀 But I get an exception when executing. Here is the debug output:

â–¶ ruby pdfinvert.rb sheet01.pdf sheet01_inv.pdf          
Exception `Gem::LoadError' at /System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib/ruby/2.3.0/rubygems/dependency.rb:319 - Could not find 'parallel' (>= 0) among 15 total gem(s)
Checked in 'GEM_PATH=/Users/renekud/.gem/ruby/2.3.0:/Library/Ruby/Gems/2.3.0:/System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib/ruby/gems/2.3.0', execute `gem env` for more information
Exception `Errno::ENOENT' at pdfinvert.rb:222 - No such file or directory @ rb_sysopen - input_0001.svg
pdfinvert.rb:222:in `initialize': No such file or directory @ rb_sysopen - input_0001.svg (Errno::ENOENT)
    from pdfinvert.rb:222:in `open'
    from pdfinvert.rb:222:in `invert'
    from pdfinvert.rb:354:in `block in <main>'
    from pdfinvert.rb:353:in `each'
    from pdfinvert.rb:353:in `rescue in <main>'
    from pdfinvert.rb:343:in `<main>'

I have the script in the same directory like the pdf that I want to invert. It would be wonderfull if we could fix this. Sadly I never did sth in ruby :D Here are the files of the /tmp/pdfinvert folder: pdfinvert_sheet01.zip

reitzig commented 4 years ago

Oh wow, somebody landed on this ol' thing! :D

Two observations:

Does that help?

TheDarkTron commented 4 years ago

Wow nice u actually responded :D That helped a little. The script is now running and also finds the parallel gem. But it cannot find the converted .svg files.

â–¶ ruby pdfinvert.rb sheet01.pdf sheet01_inv.pdf
Exception `Errno::ENOENT' at pdfinvert.rb:222 - No such file or directory @ rb_sysopen - input_0002.svg
Exception `Errno::ENOENT' at /Users/renekud/.rvm/rubies/ruby-2.6.3/lib/ruby/gems/2.6.0/gems/parallel-1.19.1/lib/parallel.rb:76 - No such file or directory @ rb_sysopen - input_0002.svg
Exception `Errno::ENOENT' at pdfinvert.rb:222 - No such file or directory @ rb_sysopen - input_0001.svg
Exception `Errno::ENOENT' at /Users/renekud/.rvm/rubies/ruby-2.6.3/lib/ruby/gems/2.6.0/gems/parallel-1.19.1/lib/parallel.rb:76 - No such file or directory @ rb_sysopen - input_0001.svg
Exception `Errno::ENOENT' at pdfinvert.rb:222 - No such file or directory @ rb_sysopen - input_0003.svg
Exception `Errno::ENOENT' at /Users/renekud/.rvm/rubies/ruby-2.6.3/lib/ruby/gems/2.6.0/gems/parallel-1.19.1/lib/parallel.rb:76 - No such file or directory @ rb_sysopen - input_0003.svg
Exception `Errno::ENOENT' at /Users/renekud/.rvm/rubies/ruby-2.6.3/lib/ruby/gems/2.6.0/gems/parallel-1.19.1/lib/parallel.rb:488 - No such file or directory @ rb_sysopen - input_0003.svg
Traceback (most recent call last):
    15: from pdfinvert.rb:347:in `<main>'
    14: from /Users/renekud/.rvm/rubies/ruby-2.6.3/lib/ruby/gems/2.6.0/gems/parallel-1.19.1/lib/parallel.rb:277:in `map'
    13: from /Users/renekud/.rvm/rubies/ruby-2.6.3/lib/ruby/gems/2.6.0/gems/parallel-1.19.1/lib/parallel.rb:373:in `work_in_processes'
    12: from /Users/renekud/.rvm/rubies/ruby-2.6.3/lib/ruby/gems/2.6.0/gems/parallel-1.19.1/lib/parallel.rb:434:in `create_workers'
    11: from /Users/renekud/.rvm/rubies/ruby-2.6.3/lib/ruby/gems/2.6.0/gems/parallel-1.19.1/lib/parallel.rb:434:in `each_with_index'
    10: from /Users/renekud/.rvm/rubies/ruby-2.6.3/lib/ruby/gems/2.6.0/gems/parallel-1.19.1/lib/parallel.rb:434:in `each'
     9: from /Users/renekud/.rvm/rubies/ruby-2.6.3/lib/ruby/gems/2.6.0/gems/parallel-1.19.1/lib/parallel.rb:435:in `block in create_workers'
     8: from /Users/renekud/.rvm/rubies/ruby-2.6.3/lib/ruby/gems/2.6.0/gems/parallel-1.19.1/lib/parallel.rb:444:in `worker'
     7: from /Users/renekud/.rvm/rubies/ruby-2.6.3/lib/ruby/gems/2.6.0/gems/parallel-1.19.1/lib/parallel.rb:444:in `fork'
     6: from /Users/renekud/.rvm/rubies/ruby-2.6.3/lib/ruby/gems/2.6.0/gems/parallel-1.19.1/lib/parallel.rb:453:in `block in worker'
     5: from /Users/renekud/.rvm/rubies/ruby-2.6.3/lib/ruby/gems/2.6.0/gems/parallel-1.19.1/lib/parallel.rb:471:in `process_incoming_jobs'
     4: from /Users/renekud/.rvm/rubies/ruby-2.6.3/lib/ruby/gems/2.6.0/gems/parallel-1.19.1/lib/parallel.rb:507:in `call_with_index'
     3: from pdfinvert.rb:348:in `block in <main>'
     2: from pdfinvert.rb:222:in `invert'
     1: from pdfinvert.rb:222:in `open'
pdfinvert.rb:222:in `initialize': No such file or directory @ rb_sysopen - input_0003.svg (Errno::ENOENT)

Here is the tmp folder: pdfinvert_sheet01.zip

Seems like no .svg files are created.

May this be a problem with File.open? https://stackoverflow.com/a/36350388

reitzig commented 4 years ago

Hm, it appears the real error message remains hidden. Apparently, the conversion to SVG fails.

Did you check the list of requirements? Inkscape needs to be installed. You can turn on debug mode by changing line 72 to

$DEBUG = true

and re-run; a log file should then be written, which hopefully reveals what's going on.

TheDarkTron commented 4 years ago

Yes, I checked the requirements. Inkscape and imagemagic are installed. I also did set debug to true. I attached the log and the whole tmp filter in the 2 previous posts.

Oh, and I run on macOS

reitzig commented 4 years ago

I don't see any logs.

If it's a Mac issue -- and it might very well be! -- I won't be able to help you much since I don't have one. I'm happy to check later whether the script still runs for me, but beyond that you'll have to follow the trail of error messages for yourself, sorry. :/

TheDarkTron commented 4 years ago

Thank you for your kind support :) I will try my best. If I find a solution I will try to create a pull request for you. Cheers!

reitzig commented 4 years ago

@TheDarkTron I found some time to run it myself, finally. Unsuccessfully, too.

Error handling the script is a mess. :/ I pushed a small improvement that should allow log to be written even though inkscape fails.

That's what's happening for me (Ubuntu 18.04): I have inkscape installed as snap, and it can't see the files the script puts in /tmp (apparently, each snap has its own "view" on /tmp). I don't know such details about macOS, but afaik they do some sandboxing with applications. Hence, the issue may be similar.

I currently don't see a way around it in my case: I don't know how to put files into the snap context (one should not be able to, really); maybe installing with --classic would help. Inkscape itself is not help: it's not built to read from stdin; it can only consume SVG in that way.

For googlers: removing the Inkscape snap and instead installing via apt solves the issue. (For macOS, maybe installing it through Homebrew helps?)

TheDarkTron commented 4 years ago

Yes, seems like this is the issue! I just tried to run the script again. The log file in /tmp says:

Inverting input_0001.pdf...
** Message: couldn't open the PDF file.

** (inkscape-bin:71813): WARNING **: Can't open file: input_0001.pdf (doesn't exist)

** (inkscape-bin:71813): WARNING **: Specified document input_0001.pdf cannot be opened (does not exist or not a valid SVG file)
Conversion to SVG failed

Inverting input_0003.pdf...
** Message: couldn't open the PDF file.

** (inkscape-bin:71814): WARNING **: Can't open file: input_0003.pdf (doesn't exist)

** (inkscape-bin:71814): WARNING **: Specified document input_0003.pdf cannot be opened (does not exist or not a valid SVG file)
Conversion to SVG failed

Inverting input_0002.pdf...
** Message: couldn't open the PDF file.

** (inkscape-bin:71812): WARNING **: Can't open file: input_0002.pdf (doesn't exist)

** (inkscape-bin:71812): WARNING **: Specified document input_0002.pdf cannot be opened (does not exist or not a valid SVG file)
Conversion to SVG failed
No inverted pages found. Aborting.

Installing inkscape through brew does not help :/

Maybe we can simply save the temporal files in the directory of the pdf?

reitzig commented 4 years ago

We could but I dislike transient data in folders that might be backed up; I prefer to use a location that I can expect to get cleaned up, even if I mess up.

I really should be using Dir.mktmpdir there instead of hard-coding /tmp/, but it'd still go for the system location, not a user-specific one. Unfortunately, there doesn't seem to be a standard for user-space temporary files, even in the GNU/Linux sphere.

According to the many topics on the snapcraft forums, the issue is well known and pretty much by design. While /tmp/snap.inkscape/ could potentially be used, access requires sudo.

For me, I'm cutting this off for now since snaps do not seem to be intended to be used with non-snap software, and as such they can't really be used as scripting primitives. That's probably okay from a sandboxing/security perspective, even if it's unfortunate here.

IMHO, the best way forward in this particular case would be for Inkscape to support being a part of a pipeline -- then we wouldn't need it to access files at all. I created an issue, and it seems they actually have half of it already in the recently released 1.0!

reitzig commented 4 years ago

Hah! Turns out they did solve this at least partially in 1.0, I just didn't find it in the docs. As Nathan Lee helpfully points out, this works:

inkscape --pipe --export-type=pdf < foo.svg > foo.pdf

Unfortunately, as of now

inkscape --pipe --export-type=svg < foo.pdf > foo.svg

does not. So with the issue isolated, we'll have to wait for them to adapt.

(You can implement a workaround for yourself by setting $tmp differently.)

reitzig commented 4 years ago

So fixing this well is currently blocked by choosing input type with --pipe.

A further issue I noticed in my ... inept scripting from back then is error handling, and Inkscape doesn't help.

reitzig commented 2 months ago

I just found some local changes to that script that may or may not have been intended to address this. Apparently I started doing something years ago but never finished. I pushed those edits on a new branch, for whatever they're worth.