2020-08-24 11:32:50 +00:00
|
|
|
#! /usr/bin/python3
|
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
|
|
|
# file lyxpaperview.py
|
|
|
|
# This file is part of LyX, the document processor.
|
|
|
|
# Licence details can be found in the file COPYING.
|
|
|
|
|
|
|
|
# author Jürgen Spitzmüller
|
2020-08-24 13:59:26 +00:00
|
|
|
# This draws on a bash script and conceptual idea by Pavel Sanda
|
2020-08-24 11:32:50 +00:00
|
|
|
# Full author contact details are available in file CREDITS
|
|
|
|
|
|
|
|
# This script searches the home directory for a PDF or PS
|
|
|
|
# file with a name containing year and author. If found,
|
|
|
|
# it opens the file in a viewer.
|
|
|
|
|
|
|
|
import getopt, os, sys, subprocess
|
|
|
|
|
|
|
|
pdf_viewers = ('pdfview', 'kpdf', 'okular', 'qpdfview --unique',
|
|
|
|
'evince', 'xreader', 'kghostview', 'xpdf', 'SumatraPDF',
|
|
|
|
'acrobat', 'acroread', 'mupdf',
|
|
|
|
'gv', 'ghostview', 'AcroRd32', 'gsview64', 'gsview32')
|
|
|
|
|
|
|
|
ps_viewers = ("kghostview", "okular", "qpdfview --unique",
|
|
|
|
"evince", "xreader", "gv", "ghostview -swap",
|
|
|
|
"gsview64", "gsview32")
|
|
|
|
|
|
|
|
def message(message):
|
|
|
|
sys.stderr.write("lyxpaperview: %s\n" % message)
|
|
|
|
|
|
|
|
def error(message):
|
|
|
|
sys.stderr.write("lyxpaperview error: %s\n" % message)
|
|
|
|
exit(1)
|
|
|
|
|
|
|
|
def usage(prog_name):
|
2020-08-24 13:38:55 +00:00
|
|
|
msg = "Usage: %s [-v pdfviewer] [-w psviewer] titletoken-1 [titletoken-2] ... [titletoken-n]\n" \
|
2020-08-24 13:41:52 +00:00
|
|
|
" Each title token must occur in the filename (at an arbitrary position).\n" \
|
2020-08-24 13:38:55 +00:00
|
|
|
" You might use quotes to enter multi-word tokens"
|
2020-08-24 11:32:50 +00:00
|
|
|
return msg % prog_name
|
|
|
|
|
|
|
|
# Copied from lyxpreview_tools.py
|
|
|
|
# PATH and PATHEXT environment variables
|
|
|
|
path = os.environ["PATH"].split(os.pathsep)
|
|
|
|
extlist = ['']
|
|
|
|
if "PATHEXT" in os.environ:
|
|
|
|
extlist += os.environ["PATHEXT"].split(os.pathsep)
|
|
|
|
extlist.append('.py')
|
|
|
|
|
|
|
|
def find_exe(candidates):
|
|
|
|
global extlist, path
|
|
|
|
|
|
|
|
for command in candidates:
|
|
|
|
prog = command.split()[0]
|
|
|
|
for directory in path:
|
|
|
|
for ext in extlist:
|
|
|
|
full_path = os.path.join(directory, prog + ext)
|
|
|
|
if os.access(full_path, os.X_OK):
|
|
|
|
# The thing is in the PATH already (or we wouldn't
|
|
|
|
# have found it). Return just the basename to avoid
|
|
|
|
# problems when the path to the executable contains
|
|
|
|
# spaces.
|
|
|
|
if full_path.lower().endswith('.py'):
|
|
|
|
return command.replace(prog, '"%s" "%s"'
|
|
|
|
% (sys.executable, full_path))
|
|
|
|
return command
|
|
|
|
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
|
|
|
def find_exe_or_terminate(candidates):
|
|
|
|
exe = find_exe(candidates)
|
|
|
|
if exe == None:
|
|
|
|
error("Unable to find executable from '%s'" % " ".join(candidates))
|
|
|
|
|
|
|
|
return exe
|
|
|
|
|
2020-08-24 13:38:55 +00:00
|
|
|
def find(args, path):
|
2020-08-24 11:32:50 +00:00
|
|
|
if os.name != 'nt':
|
|
|
|
# use locate if possible (faster)
|
|
|
|
if find_exe(['locate']):
|
2020-08-24 13:38:55 +00:00
|
|
|
p1 = subprocess.Popen(['locate', '-i', args[0].lower()], stdout=subprocess.PIPE)
|
2022-07-31 18:08:44 +00:00
|
|
|
px = subprocess.Popen(['grep', '-Ei', r'\.pdf$|\.ps$'], stdin=p1.stdout, stdout=subprocess.PIPE)
|
2020-08-24 13:38:55 +00:00
|
|
|
for arg in args:
|
|
|
|
if arg == args[0]:
|
|
|
|
# have this already
|
|
|
|
continue
|
|
|
|
px = subprocess.Popen(['grep', '-i', arg], stdin=px.stdout, stdout=subprocess.PIPE)
|
2020-08-27 10:05:49 +00:00
|
|
|
p4 = subprocess.Popen(['head', '-n 1'], stdin=px.stdout, stdout=subprocess.PIPE)
|
2020-08-24 11:32:50 +00:00
|
|
|
p1.stdout.close()
|
|
|
|
output = p4.communicate()
|
|
|
|
return output[0].decode("utf8")[:-1]# strip trailing '\n'
|
|
|
|
# FIXME add something for windows as well?
|
|
|
|
# Maybe dir /s /b %WINDIR%\*author* | findstr .*year.*\."ps pdf"
|
|
|
|
|
|
|
|
for root, dirs, files in os.walk(path):
|
|
|
|
for fname in files:
|
|
|
|
lfname = fname.lower()
|
2020-08-24 13:38:55 +00:00
|
|
|
if lfname.endswith(('.pdf', '.ps')):
|
|
|
|
caught = True
|
|
|
|
for arg in args:
|
|
|
|
if lfname.find(arg.lower()) == -1:
|
|
|
|
caught = False
|
|
|
|
break
|
|
|
|
if caught:
|
|
|
|
return os.path.join(root, fname)
|
2020-08-24 11:32:50 +00:00
|
|
|
return ""
|
|
|
|
|
|
|
|
def main(argv):
|
|
|
|
progname = argv[0]
|
|
|
|
|
|
|
|
opts, args = getopt.getopt(sys.argv[1:], "v:w:")
|
|
|
|
pdfviewer = ""
|
|
|
|
psviewer = ""
|
|
|
|
for o, v in opts:
|
|
|
|
if o == "-v":
|
|
|
|
pdfviewer = v
|
|
|
|
if o == "-w":
|
|
|
|
psviewer = v
|
|
|
|
|
2020-08-24 13:38:55 +00:00
|
|
|
if len(args) < 1:
|
2020-08-24 11:32:50 +00:00
|
|
|
error(usage(progname))
|
|
|
|
|
2020-08-24 13:38:55 +00:00
|
|
|
result = find(args, path = os.environ["HOME"])
|
2020-08-24 11:32:50 +00:00
|
|
|
if result == "":
|
|
|
|
message("no document found!")
|
2020-08-27 09:52:52 +00:00
|
|
|
exit(2)
|
2020-08-24 11:32:50 +00:00
|
|
|
else:
|
|
|
|
message("found document %s" % result)
|
|
|
|
|
|
|
|
viewer = ""
|
|
|
|
if result.lower().endswith('.ps'):
|
|
|
|
if psviewer == "":
|
|
|
|
viewer = find_exe_or_terminate(ps_viewers)
|
|
|
|
else:
|
|
|
|
viewer = psviewer
|
|
|
|
else:
|
|
|
|
if pdfviewer == "":
|
|
|
|
viewer = find_exe_or_terminate(pdf_viewers)
|
|
|
|
else:
|
|
|
|
viewer = pdfviewer
|
|
|
|
|
2023-02-20 22:05:26 +00:00
|
|
|
cmdline = viewer.split(" -", 1)
|
|
|
|
|
|
|
|
if len(cmdline) == 1:
|
2023-08-17 21:36:18 +00:00
|
|
|
subprocess.Popen([viewer, result], stderr=subprocess.DEVNULL, stdout=subprocess.DEVNULL)
|
2023-02-20 22:05:26 +00:00
|
|
|
elif len(cmdline) == 2:
|
2023-02-24 19:44:37 +00:00
|
|
|
subprocess.Popen([cmdline[0], "-" + cmdline[1] , result], stderr=subprocess.DEVNULL, stdout=subprocess.DEVNULL)
|
2020-08-24 11:32:50 +00:00
|
|
|
|
2020-08-27 09:52:52 +00:00
|
|
|
exit(0)
|
2020-08-24 11:32:50 +00:00
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
main(sys.argv)
|