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