xilopaint Posted June 29, 2016 Share Posted June 29, 2016 (edited) Sorry if it's a dumb question. I am a beginner. I have tried to convert this Python script for PDF compression into an Alfred workflow. It relies on pdftops from Poppler and ps2pdf from Ghostscript. I have installed both Poppler and Ghostscript using Homebrew on Terminal. Since that, the script is fully functional on Terminal but I didn't manage to convert the code to an Alfred workflow using Alfred-Workflow helper library. It seems Alfred misses the Poppler library. This is my attempt: #!/usr/bin/python # encoding: utf-8 from __future__ import division import sys import argparse import tempfile import subprocess import os import shutil import contextlib from workflow import Workflow def main(wf): query = wf.args[0] argv = query def main(argv=None): parser = argparse.ArgumentParser(description="one weird PDF trick") parser.add_argument('before', nargs=1, help="PDF (before)", type=extant_file) parser.add_argument('after', nargs="?", help="PDF (after)") parser.add_argument('-t', '--tempdir', help="needs a lot of temp space", required=False) if argv is None: argv = parser.parse_args() if argv.tempdir: tempfile.tempdir = argv.tempdir if not which('pdftops'): # use poppler to create a .ps raise Exception("need pdftops from poppler") if not which('ps2pdf'): # and use ghostscript to create a .pdf raise Exception("need ps2pdf from ghostscript") with make_temp_directory(prefix='popgho') as tempdir: main_with_temp(tempdir, argv) def main_with_temp(tempdir, argv): os.environ.update({'TMPDIR': tempdir}) # for ghostscript postscript = os.path.join(tempdir, 'poppler.ps') o_pdf = argv.before[0] n_pdf = os.path.join(tempdir, 'ghost.pdf') with open(os.devnull, "w") as f: subprocess.check_call(['pdftops', o_pdf, postscript], stdout=f, stderr=f) subprocess.check_call(['ps2pdf', postscript, n_pdf], stdout=f, stderr=f, env=os.environ) o_size = os.path.getsize(o_pdf) n_size = os.path.getsize(n_pdf) compression_ratio = o_size/n_size if (argv.after): shutil.move(n_pdf, argv.after) print("compression: {1}; created: {0}" .format(argv.after, compression_ratio)) elif (compression_ratio > 1.2): shutil.move(n_pdf, o_pdf) print("compression: {1}; overwrite: {0}" .format(o_pdf, compression_ratio)) else: os.remove(n_pdf) print("compression: {0}; not worth it, deleted new file" .format(compression_ratio)) os.remove(postscript) def which(program): def is_exe(fpath): return os.path.isfile(fpath) and os.access(fpath, os.X_OK) fpath, fname = os.path.split(program) if fpath: if is_exe(program): return program else: for path in os.environ["PATH"].split(os.pathsep): path = path.strip('"') exe_file = os.path.join(path, program) if is_exe(exe_file): return exe_file return None def extant_file(x): if not os.path.exists(x): raise argparse.ArgumentError("{0} does not exist".format(x)) return x @contextlib.contextmanager def make_temp_directory(prefix): temp_dir = tempfile.mkdtemp(prefix=prefix) yield temp_dir shutil.rmtree(temp_dir) if __name__ == "__main__": sys.exit(main()) if __name__ == '__main__': wf = Workflow() sys.exit(wf.run(main)) Alfred Console: [2016-06-29 20:32:20][trigger.action] Processing output of 'action.script' with arg '( "/Users/usuario/Desktop/test.pdf" )' [2016-06-29 20:32:21][ERROR: action.script] 20:32:21 workflow.py:2157 DEBUG Workflow version : 1.0.0 20:32:21 workflow.py:2175 ERROR need pdftops from poppler Traceback (most recent call last): File "/Users/usuario/Library/Application Support/Alfred 3/Alfred.alfredpreferences/workflows/user.workflow.C3709BD1-8479-4079-B9BB-559C4B577012/workflow/workflow.py", line 2168, in run func(self) File "pdftrick.py", line 110, in main sys.exit(main()) File "pdftrick.py", line 34, in main raise Exception("need pdftops from poppler") Exception: need pdftops from poppler 20:32:21 workflow.py:2195 DEBUG Workflow finished in 0.043 seconds. Edited June 29, 2016 by xilopaint Link to comment
deanishe Posted June 30, 2016 Share Posted June 30, 2016 If you installed them with Homebrew, then presumably the programs are in /usr/local/bin. That isn't on Alfred's PATH. Use /usr/local/bin/ps2pdf instead of just ps2pdf. Link to comment
xilopaint Posted June 30, 2016 Author Share Posted June 30, 2016 (edited) It worked! Thanks again! How can I bundle the workflow with Poppler and Ghostscript for distribution since they are not python packages and I could not use pip install as the instructions of Alfred-Workflow documentation? Edited June 30, 2016 by xilopaint Link to comment
deanishe Posted June 30, 2016 Share Posted June 30, 2016 Ghostscript is 100+MB. You can't bundle that with a workflow. Link to comment
xilopaint Posted June 30, 2016 Author Share Posted June 30, 2016 Is it not possible to bundle it with less files, the strictly necessary to make pdftops and ps2pdf work? Link to comment
deanishe Posted June 30, 2016 Share Posted June 30, 2016 That's a question for the Ghostscript forum, tbh. xilopaint 1 Link to comment
xilopaint Posted June 30, 2016 Author Share Posted June 30, 2016 Ok, but if a random non-standard library is not as large how could I bundle it with the workflow once it's not a python package? Link to comment
deanishe Posted June 30, 2016 Share Posted June 30, 2016 I don't know. What do you think is a reasonable size for a workflow? Link to comment
xilopaint Posted June 30, 2016 Author Share Posted June 30, 2016 (edited) The size is not as relevant for my question. I just intend to know how I can bundle a non-python library with the workflow in case it's possible. We can suppose just as an example that Ghostscript was 2MB instead 100+. Edited June 30, 2016 by xilopaint Link to comment
deanishe Posted June 30, 2016 Share Posted June 30, 2016 Sorry, I misread your post. If you want to include a program with your workflow, put it in the workflow's directory. That's the working directory when your workflow is run. There's no guarantee any given program will work that way, nor that it will work on any system but yours. Depends on the program. Link to comment
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now