Skip to content

Commit 6884a7f

Browse files
authored
Merge pull request #323 from mpsonntag/odmlview
CLI script to locally view odml files via webbrowser LGTM
2 parents 0c6b514 + 547b553 commit 6884a7f

File tree

2 files changed

+109
-1
lines changed

2 files changed

+109
-1
lines changed

odml/scripts/odml_view.py

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
"""odmlview
2+
3+
odmlview sets up a minimal webserver to view odml files saved in the
4+
XML format via the webbrowser. After it is started, the webserver will
5+
open a new tab in the default webbrowser and display the content of
6+
the directory the server was started from. odML files can then be
7+
viewed from there.
8+
To properly render XML, an odML file may contain the element
9+
'<?xml-stylesheet type="text/xsl" href="odmlTerms.xsl"?>' where the
10+
'odmlTerms.xsl' stylesheet should reside in the same directory as the
11+
odML file to be rendered. By using the '--fetch' flag the latest version
12+
of this stylesheet will be downloaded from 'templates.g-node.org' to
13+
the current directory when starting up the service.
14+
15+
Usage: odmlview [-p PORT] [--fetch]
16+
17+
Options:
18+
-p PORT Port the server will use. Default: 8000
19+
--fetch Fetch latest stylesheet from templates.g-node.org
20+
to current directory
21+
-h --help Show this screen
22+
--version Show version
23+
"""
24+
25+
import os
26+
try:
27+
import http.server as hs
28+
except ImportError:
29+
print("This script is only supported with Python 3")
30+
exit(-1)
31+
32+
import socketserver
33+
import sys
34+
import urllib.request as urllib2
35+
import webbrowser
36+
37+
from docopt import docopt
38+
39+
PORT = 8000
40+
REPOSITORY = "https://templates.g-node.org/_resources/"
41+
STYLESHEET = "odmlTerms.xsl"
42+
43+
44+
def download_file(repo, filename):
45+
"""
46+
download_file fetches 'filename' from url 'repo' and
47+
saves it in the current directory as file 'filename'.
48+
"""
49+
try:
50+
data = urllib2.urlopen("%s%s" % (repo, filename)).read()
51+
data = data.decode("utf-8")
52+
except Exception as err:
53+
print("[Warning] Failed loading '%s%s': %s" % (repo, filename, err))
54+
return
55+
56+
with open(filename, "w") as local_file:
57+
local_file.write(str(data))
58+
59+
60+
def run(port=PORT, extensions=None):
61+
"""
62+
run starts a simple webserver on localhost serving the current directory.
63+
Once started, it will open a tab on the default webbrowser and will continue
64+
to serve until manually stopped.
65+
66+
:param port: server port
67+
:param extensions: dictionary containing additional file extension - mime type
68+
mappings the server should be aware of.
69+
e.g. {'.xml': 'application/xml'}
70+
"""
71+
handler = hs.SimpleHTTPRequestHandler
72+
73+
if extensions:
74+
handler.extensions_map.update(extensions)
75+
76+
server_address = ('', port)
77+
78+
socketserver.TCPServer.allow_reuse_address = True
79+
with socketserver.TCPServer(server_address, handler) as httpd:
80+
webbrowser.open_new_tab('http://localhost:%s' % port)
81+
try:
82+
print("[Info] The server can be stopped by pressing Ctrl+C")
83+
httpd.serve_forever()
84+
except KeyboardInterrupt:
85+
print("[Info] Received Keyboard interrupt, shutting down")
86+
httpd.shutdown()
87+
httpd.server_close()
88+
89+
90+
def main(args=None):
91+
parser = docopt(__doc__, argv=args, version="0.1.0")
92+
93+
# Fetch stylesheet
94+
if parser['--fetch'] and not os.path.exists(STYLESHEET):
95+
print("[Info] Downloading stylesheet '%s'" % STYLESHEET)
96+
download_file(REPOSITORY, STYLESHEET)
97+
98+
server_port = int(parser['-p']) if parser['-p'] else PORT
99+
100+
# files with odML file extensions should be interpreted as XML
101+
extensions = {'.odml': 'application/xml'}
102+
103+
run(server_port, extensions)
104+
105+
106+
if __name__ == "__main__":
107+
main(sys.argv[1:])

setup.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,5 +49,6 @@
4949
classifiers=CLASSIFIERS,
5050
license="BSD",
5151
entry_points={'console_scripts': ['odmltordf=odml.scripts.odml_to_rdf:main',
52-
'odmlconversion=odml.scripts.odml_conversion:main']}
52+
'odmlconversion=odml.scripts.odml_conversion:main',
53+
'odmlview=odml.scripts.odml_view:main']}
5354
)

0 commit comments

Comments
 (0)