A couple of years ago I decided to try LibreOffice’s «–convert-to» parameter to generate different formats of a document, instead of using the ancient listen-on-port-8100 service and use an external Python script in order to do the dirty job of conversion. The results of the tests where great: excelent performance, reliable results, avoid the control of port 8100: IM-PRESSIVE! 🙂
Recently an ancient Rails 2.3 app was failing in the generation of PDFs via this 8100 port + Python script stuff 🙁 I could try to figure out which the error was (dive into Python) or migrate to that convert-to simple solution: no doubt!.
I change my scripts for PDF generation, but something nasty was waiting me around the corner 🙁
- It didn’t work just out of the box.
- Local development setup was working right.
- Debugging time! 🙂
First I tried at CLI:
libreoffice --headless --convert-to --outdir /tmp my-test-file.odt
It works!. So problem is not neither with Libreoffice and Ruby version. Trouble is elsewhere. Next I consider my code: perhaps something was interfering and I decided to set a simple «runner» task just to call the system:
# simple-task.tb
`libreoffice --headless --convert-to --outdir /tmp my-test-file.odt`
Nope, seems to fail again 🙁 Then I tried to get the output error. I found an excellent post about: http://blog.bigbinary.com/2012/10/18/backtick-system-exec-in-ruby.html. So I changed my task:
# simple-task.tb
output = `libreoffice --headless --convert-to --outdir /tmp my-test-file.odt 2>&1`
Rails.logger.info('DEBUG: ' + output)
The output was a simple: «Error: source file could not be loaded» :/ After so many searches at DuckDuckGo (please avoid Google-vil) I found a tip at Stackoverflow here: http://stackoverflow.com/questions/37772250/using-soffice-within-python-command-works-in-terminal-but-not-in-python-subproc. Then I tried to reproduce it: yes if the source file (the one to be converted) does not exist then, the same error shows up!. Mmmm, path issue?, naaahh. Seems to be a dead-end, so time for lateral thinking 🙂
The server has some other apps with the same environment (Rails 2.3, Ruby 1.8.7): what if try the same runner task with them?. I found interesting results: some of them worked and some don’t. So the failure had to be with subtle difference somewhere between apps: almost there 🙂
Finally I found the guilty code: a stupid line at «config/environments/production.rb»:
ENV['TMPDIR'] = '/srv/rails/tmp'
That path does not exist in current server, so LibreOffice was unable to generate/find the middle temporary file in order to convert the document. Remove that line and yes!, I have it up and running again 🙂
What do I’ve learned after 2 days debugging session?:
- I manage the stress better than 2 before 😀
- Put configuration environment constants elsewhere is a bad habit
- Debugging is nice: you learn a lot of things, but it so stressful 🙁
- Going for a walk or so helps a lot in lateral thinking 🙂
Cheers! 🙂