-
Notifications
You must be signed in to change notification settings - Fork 15
/
webserver.py
224 lines (197 loc) · 10.4 KB
/
webserver.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
#!/usr/bin/python
import cgi
import os
import socket
import SocketServer
import sys
import time
import urllib
from SimpleHTTPServer import SimpleHTTPRequestHandler
from StringIO import StringIO
PROG_VER = "ver 3.4 written by Claude Pageau"
'''
SimpleHTTPServer python program to allow selection of images from right panel and display in an iframe left panel
Use for local network use only since this is not guaranteed to be a secure web server.
based on original code by zeekay and modified by Claude Pageau Nov-2015 for use with pi-timolo.py on a Raspberry Pi
from http://stackoverflow.com/questions/8044873/python-how-to-override-simplehttpserver-to-show-timestamp-in-directory-listing
1 - Use nano editor to change webserver.py web_server_root and other variables to suit at bottom of config.py
nano settings.py # Webserver settings are near the end of the file
ctrl-x y to save changes
2 - On Terminal session execute command below. This will display file access information
./webserver.py # ctrl-c to stop web server. Note if you close terminal session webserver.py will stop.
3 - To Run this script as a background daemon execute the command below.
Once running you can close the terminal session and webserver will continue to run.
./webserver.sh start
To check status of webserver type command below with no parameter
./webserver.sh
4 - On a LAN computer web browser url bar, input this RPI ip address and port number per below
example http://192.168.1.110:8090
Variable Settings are imported from settings.py
'''
SCRIPT_PATH = os.path.abspath(__file__) # Find the full path of this python script
BASE_DIR = os.path.dirname(SCRIPT_PATH) # Get the path location only (excluding script name)
PROG_NAME = os.path.basename(__file__) # Name of this program
# Check for variable file to import and error out if not found.
CONFIG_FILE_PATH = os.path.join(BASE_DIR, "settings.py")
if not os.path.exists(CONFIG_FILE_PATH):
print("ERROR - Cannot Import Configuration Variables.")
print(" Missing Configuration File %s" % CONFIG_FILE_PATH)
sys.exit(1)
else:
# Read Configuration variables from settings.py file
print("Importing Configuration Variables from File %s" % CONFIG_FILE_PATH)
from settings import *
os.chdir(web_server_root)
web_root = os.getcwd()
os.chdir(BASE_DIR)
try:
myip = ([l for l in ([ip for ip in socket.gethostbyname_ex(socket.gethostname())[2] if not ip.startswith("127.")][:1],
[[(s.connect(('8.8.8.8', 53)),
s.getsockname()[0], s.close()) for s in [socket.socket(socket.AF_INET,
socket.SOCK_DGRAM)]][0][1]]) if l][0][0])
except:
print("ERROR - Can't Find a Network IP Address on this Raspberry Pi")
print(" Configure Network and Try Again")
sys.exit(1)
if web_list_by_datetime:
dir_sort = 'DateTime'
else:
dir_sort = 'FileName'
if web_list_sort_descending:
dir_order = 'Descend'
else:
dir_order = 'Ascend'
list_title = "%s %s" % (dir_sort, dir_order)
class DirectoryHandler(SimpleHTTPRequestHandler):
def list_directory(self, path):
try:
list = os.listdir(path)
all_entries = len(list)
except os.error:
self.send_error(404, "No permission to list directory")
return None
if web_list_by_datetime:
# Sort by most recent modified date/time first
list.sort(key=lambda x: os.stat(os.path.join(path, x)).st_mtime, reverse=web_list_sort_descending)
else:
# Sort by File Name
list.sort(key=lambda a: a.lower(), reverse=web_list_sort_descending)
f = StringIO()
displaypath = cgi.escape(urllib.unquote(self.path))
# Start HTML formatting code
f.write('<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">')
f.write('<head>')
# Setup Meta Tags
f.write('<meta "Content-Type" content="txt/html; charset=ISO-8859-1" />')
f.write('<meta name="viewport" content="width=device-width, initial-scale=1.0" />')
if web_page_refresh_on:
f.write('<meta http-equiv="refresh" content="%s" />' % web_page_refresh_sec)
f.write('</head>')
tpath, cur_folder = os.path.split(self.path)
f.write("<html><title>%s %s</title>" % (web_page_title, self.path))
f.write("<body>")
# Start Left iframe Image Panel
f.write('<iframe width="%s" height="%s" align="left"'
% (web_iframe_width_usage, web_image_height))
if web_page_blank:
f.write('src="%s" name="imgbox" id="imgbox" alt="%s">'
% ("about:blank", web_page_title))
# display second entry in right list since list[0] may still be in progress
else:
f.write('src="%s" name="imgbox" id="imgbox" alt="%s">'
% (list[0], web_page_title))
# display second entry in right list since list[0] may still be in progress
f.write('<p>iframes are not supported by your browser.</p></iframe>')
# Start Right File selection List Panel
list_style = '<div style="height: ' + web_list_height + 'px; overflow: auto; white-space: nowrap;">'
f.write(list_style)
# f.write('<center><b>%s</b></center>' % (self.path))
f.write('<center><b>%s</b></center>' % list_title)
f.write('<ul name="menu" id="menu" style="list-style-type:none; padding-left: 4px">')
# Create the formatted list of right panel hyperlinks to files in the specified directory
if not self.path is "/": # Display folder Back arrow navigation if not in web root
f.write('<li><a href="%s" >%s</a></li>\n'
% (urllib.quote(".."), cgi.escape("< BACK")))
display_entries = 0
for name in list:
display_entries += 1
if web_max_list_entries > 1:
if display_entries >= web_max_list_entries:
break
fullname = os.path.join(path, name)
displayname = linkname = name
date_modified = time.strftime('%H:%M:%S %d-%b-%Y', time.localtime(os.path.getmtime(fullname)))
# Append / for directories or @ for symbolic links
if os.path.islink(fullname):
displayname = name + "@"
# Note: a link to a directory displays with @ and links with /
if os.path.isdir(fullname):
# Note this will open a new tab to display the selected folder.
displayname = name + "/"
linkname = os.path.join(displaypath, displayname)
f.write('<li><a href="%s" >%s</a></li>\n'
% (urllib.quote(linkname), cgi.escape(displayname)))
else:
f.write('<li><a href="%s" target="imgbox">%s</a> - %s</li>\n'
% (urllib.quote(linkname), cgi.escape(displayname), date_modified))
if (not self.path is "/") and display_entries > 35: # Display folder Back arrow navigation if not in web root
f.write('<li><a href="%s" >%s</a></li>\n' % (urllib.quote(".."), cgi.escape("< BACK")))
f.write('</ul></div><p><b>')
f.write('<div style="float: left; padding-left: 40px;">Web Root is [ %s ]</div>' % web_server_root)
f.write('<div style="text-align: center;">%s</div>' % web_page_title)
if web_page_refresh_on:
f.write('<div style="float: left; padding-left: 40px;">Auto Refresh [ %s sec ]</div>' % web_page_refresh_sec)
if web_max_list_entries > 1:
f.write('<div style="text-align: right; padding-right: 40px;">Listing Only %i of %i Files in [ %s ]</div>'
% (display_entries, all_entries, self.path))
else:
f.write('<div style="text-align: right; padding-right: 50px;">Listing All %i Files in [ %s ]</div>'
% (all_entries, self.path))
# Display web refresh info only if setting is turned on
f.write('</b></p>')
length = f.tell()
f.seek(0)
self.send_response(200)
encoding = sys.getfilesystemencoding()
self.send_header("Content-type", "text/html; charset=%s" % encoding)
self.send_header("Content-Length", str(length))
self.end_headers()
return f
# Start Web Server Processing
os.chdir(web_server_root)
SocketServer.TCPServer.allow_reuse_address = True
httpd = SocketServer.TCPServer(("", web_server_port), DirectoryHandler)
print("----------------------------------------------------------------")
print("%s %s" % (PROG_NAME, PROG_VER))
print("---------------------------- Settings --------------------------")
print("Server - web_page_title = %s" % web_page_title)
print(" web_server_root = %s/%s" % (BASE_DIR, web_server_root))
print(" web_server_port = %i " % web_server_port)
print("Content - web_image_height = %s px (height of content)" % web_image_height)
print(" web_iframe_width = %s web_iframe_height = %s" % (web_iframe_width, web_iframe_height))
print(" web_iframe_width_usage = %s (of avail screen)" % (web_iframe_width_usage))
print(" web_page_refresh_sec = %s (default=180 sec)" % web_page_refresh_sec)
print(" web_page_blank = %s ( True=blank left pane until item selected)" % web_page_blank)
print("Listing - web_max_list_entries = %s ( 0=all )" % web_max_list_entries)
print(" web_list_by_datetime = %s sort_decending = %s" % (web_list_by_datetime, web_list_sort_descending))
print("----------------------------------------------------------------")
print("From a computer on the same LAN. Use a Web Browser to access this server at")
print("Type the URL below into the browser url bar then hit enter key.")
print("")
print(" http://%s:%i" % (myip, web_server_port))
print("")
print("IMPORTANT: If You Get - socket.error: [Errno 98] Address already in use")
print(" Wait a minute or so for webserver to timeout and Retry.")
print(" ctrl-c to exit this webserver script")
print("----------------------------------------------------------------")
try:
httpd.serve_forever()
except KeyboardInterrupt:
print("")
print("User Pressed ctrl-c")
print("%s %s" % (PROG_NAME, PROG_VER))
print("Exiting Bye ...")
httpd.shutdown()
httpd.socket.close()
except IOError as e:
print("I/O error({0}): {1}".format(e.errno, e.strerror))