]> git.lyx.org Git - lyx.git/blob - lib/scripts/lyxpaperview.py
Merge branch 'feature/docbook' into master
[lyx.git] / lib / scripts / lyxpaperview.py
1 #! /usr/bin/python3
2 # -*- coding: utf-8 -*-
3
4 # file lyxpaperview.py
5 # This file is part of LyX, the document processor.
6 # Licence details can be found in the file COPYING.
7
8 # author Jürgen Spitzmüller
9 # This draws on a bash script and conceptual idea by Pavel Sanda
10 # Full author contact details are available in file CREDITS
11
12 # This script searches the home directory for a PDF or PS
13 # file with a name containing year and author. If found,
14 # it opens the file in a viewer. 
15
16 import getopt, os, sys, subprocess
17
18 pdf_viewers = ('pdfview', 'kpdf', 'okular', 'qpdfview --unique',
19                'evince', 'xreader', 'kghostview', 'xpdf', 'SumatraPDF',
20                'acrobat', 'acroread', 'mupdf',
21                'gv', 'ghostview', 'AcroRd32', 'gsview64', 'gsview32')
22
23 ps_viewers = ("kghostview", "okular", "qpdfview --unique",
24               "evince", "xreader", "gv", "ghostview -swap",
25               "gsview64", "gsview32")
26
27 def message(message):
28     sys.stderr.write("lyxpaperview: %s\n" % message)
29
30 def error(message):
31     sys.stderr.write("lyxpaperview error: %s\n" % message)
32     exit(1)
33
34 def usage(prog_name):
35     msg = "Usage: %s [-v pdfviewer] [-w psviewer] titletoken-1 [titletoken-2] ... [titletoken-n]\n" \
36           "    Each title token must occur in the filename (at an arbitrary position).\n" \
37           "    You might use quotes to enter multi-word tokens"
38     return  msg % prog_name
39
40 # Copied from lyxpreview_tools.py
41 # PATH and PATHEXT environment variables
42 path = os.environ["PATH"].split(os.pathsep)
43 extlist = ['']
44 if "PATHEXT" in os.environ:
45     extlist += os.environ["PATHEXT"].split(os.pathsep)
46 extlist.append('.py')
47
48 def find_exe(candidates):
49     global extlist, path
50
51     for command in candidates:
52         prog = command.split()[0]
53         for directory in path:
54             for ext in extlist:
55                 full_path = os.path.join(directory, prog + ext)
56                 if os.access(full_path, os.X_OK):
57                     # The thing is in the PATH already (or we wouldn't
58                     # have found it). Return just the basename to avoid
59                     # problems when the path to the executable contains
60                     # spaces.
61                     if full_path.lower().endswith('.py'):
62                         return command.replace(prog, '"%s" "%s"'
63                             % (sys.executable, full_path))
64                     return command
65
66     return None
67
68
69 def find_exe_or_terminate(candidates):
70     exe = find_exe(candidates)
71     if exe == None:
72         error("Unable to find executable from '%s'" % " ".join(candidates))
73
74     return exe
75
76 def find(args, path):
77     if os.name != 'nt':
78         # use locate if possible (faster)
79         if find_exe(['locate']):
80             p1 = subprocess.Popen(['locate', '-i', args[0].lower()], stdout=subprocess.PIPE)
81             px = subprocess.Popen(['grep', '-Ei', '\.pdf$|\.ps$'], stdin=p1.stdout, stdout=subprocess.PIPE)
82             for arg in args:
83                if arg == args[0]:
84                    # have this already
85                    continue
86                px = subprocess.Popen(['grep', '-i', arg], stdin=px.stdout, stdout=subprocess.PIPE)
87             p4 = subprocess.Popen(['head', '-n 1'], stdin=px.stdout, stdout=subprocess.PIPE)
88             p1.stdout.close()
89             output = p4.communicate()
90             return output[0].decode("utf8")[:-1]# strip trailing '\n'
91      # FIXME add something for windows as well?
92      # Maybe dir /s /b %WINDIR%\*author* | findstr .*year.*\."ps pdf"
93
94     for root, dirs, files in os.walk(path):
95         for fname in files:
96             lfname = fname.lower()
97             if lfname.endswith(('.pdf', '.ps')):
98                 caught = True
99                 for arg in args:
100                     if lfname.find(arg.lower()) == -1:
101                         caught = False
102                         break
103                 if caught:
104                     return os.path.join(root, fname)
105     return ""
106
107 def main(argv):
108     progname = argv[0]
109     
110     opts, args = getopt.getopt(sys.argv[1:], "v:w:")
111     pdfviewer = ""
112     psviewer = ""
113     for o, v in opts:
114       if o == "-v":
115         pdfviewer = v
116       if o == "-w":
117         psviewer = v
118     
119     if len(args) < 1:
120       error(usage(progname))
121
122     result = find(args, path = os.environ["HOME"])
123     if result == "":
124         message("no document found!")
125         exit(2)
126     else:
127         message("found document %s" % result)
128
129     viewer = ""
130     if result.lower().endswith('.ps'):
131         if psviewer == "":
132             viewer = find_exe_or_terminate(ps_viewers)
133         else:
134             viewer = psviewer
135     else:
136         if pdfviewer == "":
137            viewer = find_exe_or_terminate(pdf_viewers)
138         else:
139             viewer = pdfviewer
140     
141     subprocess.call([viewer, result])
142     
143     exit(0)
144
145 if __name__ == "__main__":
146     main(sys.argv)