#!/usr/bin/env python
"""
:author: Vladan S
:copyright: D-Logic http://www.d-logic.net
"""
__program_version = '4.0.7.12'
"""
- added commands.py;
- removed many functions call;
"""
import cgi
import posixpath
import shutil
import signal
import traceback
import urllib
import urllib2
import StringIO
from commands import *
from BaseHTTPServer import BaseHTTPRequestHandler
from BaseHTTPServer import HTTPServer
from SocketServer import ThreadingMixIn
from mimetypes import types_map
from socket import *
from constants import *
from shell.ais_shell import *
global edit_time
def AisHttpGetProgramVersion():
return 'App name : {0} : {1}'.format(AIS_HTTP, __program_version)
def http_request(path, post_attrib, time_out=20):
try:
req = urllib2.Request(path, post_attrib)
req.add_header("Content-type", "application/x-www-form-urlencoded")
page = urllib2.urlopen(req, timeout=time_out)
return page.read(), page.code
except urllib2.URLError, urlExc:
return '', urlExc.reason
except urllib2.HTTPError, httpExc:
return '', httpExc.code
class GetHandler(BaseHTTPRequestHandler):
global url_query
def WriteFile(self, path):
'''Write any file to client
:param path: self.path-> path to the file
'''
if self.path == '/':
self.path = path
fname, ext = os.path.splitext(self.path)
fname = self.path.lstrip("/")
with open(os.path.join(os.sep, fname)) as t:
self.send_response(200)
self.send_header('Content-type', types_map[ext])
self.end_headers()
self.wfile.write(t.read())
t.close()
return
def list_dir(self, path):
try:
listdirs = os.listdir(path)
except os.error:
self.send_error(404)
return None
f = StringIO.StringIO()
f.write('')
f.write("\n
Directory listing\n")
f.write("\nDirectory listing for {0}
\n".format(path))
f.write("
\n\n")
for name in listdirs:
fullname = os.path.join(path, name)
displayname = linkname = name
if os.path.isdir(fullname):
displayname = name + "/"
linkname = name + "/"
if os.path.islink(fullname):
displayname = name + "@"
f.write('- %s\n' % (urllib.quote(linkname), cgi.escape(displayname)))
f.write("
\n
\n\n\n")
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
def do_HEAD(self):
f = self.send_head()
if f:
f.close()
def translate_path(self, path):
"""Translate a /-separated PATH to the local filename syntax.
:param path:current path to translate path
:return: translated path
"""
path = path.split('?', 1)[0]
path = path.split('#', 1)[0]
path = posixpath.normpath(urllib.unquote(path))
words = path.split('/')
words = filter(None, words)
path = os.getcwd()
for word in words:
drive, word = os.path.splitdrive(word)
head, word = os.path.split(word)
if word in (os.curdir, os.pardir): continue
path = os.path.join(path, word)
return path
def script_name(self):
if not os.path.basename(sys.argv[0]) == AIS_HTTP:
return [HTML_OTHER_INIT_SCRIPT, HTM_OTHER_INIT_SCRIPT]
return [HTML_INIT_SCRIPT, HTM_INIT_SCRIPT]
def send_head(self):
try:
path = self.translate_path(self.path)
f = None
if os.path.isdir(path):
scripts = self.script_name()
for index in scripts:
index = os.path.join(os.path.join(os.getcwd(), HTML_FOLDER, index))
if os.path.exists(index):
path = index
break
else:
return self.list_dir(path)
try:
f = open(path, 'rb')
except IOError:
self.send_error(404, 'File Not Found: %s' % self.path)
return None
fname, ext = os.path.splitext(path)
self.send_response(200)
self.send_header("Content-type", types_map[ext])
fs = os.fstat(f.fileno())
self.send_header("Content-Length", str(fs[6]))
self.send_header("Last-Modified", self.date_time_string(fs.st_mtime))
self.end_headers()
return f
except IOError:
self.send_error(404, 'File Not Found: %s' % self.path)
return None
def SetHeaders(self):
self.send_response(200)
# self.send_header('Content-type', 'text/html')
self.end_headers()
def do_GET(self):
try:
f = self.send_head()
if f:
shutil.copyfileobj(f, self.wfile)
f.close()
except IOError:
self.send_error(404, 'File Not Found: %s' % self.path)
return
def do_POST(self):
try:
# dev = DEV_HND
global url_query, edit_list_choise
global start_index, end_index
global start_time, end_time
ldev = device_list.S_DEVICE
ctype, pdict = cgi.parse_header(self.headers['content-type'])
if ctype == 'multipart/form-data':
pq = cgi.parse_multipart(self.rfile, pdict)
elif ctype == 'application/x-www-form-urlencoded':
length = int(self.headers['content-length'])
pq = cgi.parse_qs(self.rfile.read(length), keep_blank_values=1)
else:
pq = {}
f = ''.join(pq[FUNCTION] if pq.get(FUNCTION) else '')
device = ''.join(pq[DEVICE] if pq.get(DEVICE) else '')
try:
if device is '':
ldev.hnd = HND_LIST[0]
elif int(device) > len(HND_LIST):
self.wfile.write("\ndev[%s]NO DEVICE FOUND (or resource busy)\n" % device)
return
else:
ldev.hnd = HND_LIST[int(device, 10) - 1]
except Exception as exc:
print exc
if pq.has_key(DEVICE_TYPE):
device_type = ''.join(pq[DEVICE_TYPE])
if pq.has_key(DEVICE_ID):
device_id = ''.join(pq[DEVICE_ID])
if pq.has_key(EDIT_LIST):
edit_list_choise = ''.join(pq[EDIT_LIST])
if pq.has_key(START_INDEX) and pq.has_key(END_INDEX):
start_index = (''.join(pq[START_INDEX]))
end_index = (''.join(pq[END_INDEX]))
if pq.has_key(START_TIME) or pq.has_key(END_TIME):
start_time = (''.join(pq[START_TIME]))
end_time = (''.join(pq[END_TIME]))
if pq.has_key(WHITE_LIST_WRITE):
white_list_write = ''.join(pq[WHITE_LIST_WRITE])
if pq.has_key(BLACK_LIST_WRITE):
black_list_write = ''.join(pq[BLACK_LIST_WRITE])
if pq.has_key(DEFAULT_APP_PASS):
set_def_pass = ''.join(pq[DEFAULT_APP_PASS])
if pq.has_key(NEW_PASS):
new_pass = ''.join(pq[NEW_PASS])
if pq.has_key(UNREAD_LOG):
get_unread_log = (''.join(pq[UNREAD_LOG]))
if pq.has_key(LIGHTS):
lights_choise = ''.join(pq[LIGHTS])
self.SetHeaders()
self.wfile.write(command(f, device, ldev))
'''
# if f == 'q':
# self.SetHeaders()
# self.wfile.write(GetListInformation())
if f == 'v':
self.SetHeaders()
self.wfile.write("AIS_GetDLLVersion() >> %s\n" % AISGetLibraryVersionStr())
if f in ('x', 'X'):
self.wfile.write("\nServer stopped !\nClose program !\n")
if sys.platform.startswith('linux'):
os.system('pkill -9 python')
os.kill(os.getpid(), signal.SIGINT)
elif sys.platform.startswith('win'):
os._exit(0)
if f == 'R':
try:
self.wfile.write(AISRestart(ldev))
except TypeError:
self.wfile.write('')
if f == 'D':
try:
self.wfile.write(AISDestroy(ldev))
except TypeError:
self.wfile.write('')
'''
if f == 'Q':
if edit_list_choise == AVAILABLE_DEVICES:
self.wfile.write(edit_device_list(1))
elif edit_list_choise == ACTUAL_LIST:
self.wfile.write(edit_device_list(2))
elif edit_list_choise == CLEAR_LIST:
self.wfile.write(edit_device_list(3))
elif edit_list_choise == ADD_DEVICE:
self.wfile.write("AIS_List_AddDevicesForCheck() ...\n")
if device_type == '' or device_id == '':
self.wfile.write("You must enter values in the relevant fields !")
return
else:
self.wfile.write(
edit_device_list(4, "AIS_List_AddDeviceForCheck", int(device_type), int(device_id)))
elif edit_list_choise == ERASE_DEVICE:
self.wfile.write("AIS_List_EraseDeviceForCheck()...\n")
self.wfile.write(
edit_device_list(5, "AIS_List_EraseDeviceForCheck", int(device_type), int(device_id)))
else:
self.wfile.write("")
if f == 'o':
try:
self.wfile.write(AISOpen(ldev))
except TypeError:
self.wfile.write('')
elif f == 'c':
try:
self.wfile.write(AISClose(ldev))
except TypeError:
self.wfile.write('')
if f == 'd':
try:
res, count = AISUpdateAndGetCount()
self.wfile.write(' COUNT >> {0} {1}'.format(count, wr_status('', res)))
except WindowsError:
pass
elif f == 't':
gettime, currtimes = AISGetTime(ldev)
self.wfile.write(gettime)
elif f == 'T':
self.wfile.write(sys_get_timezone_info() + "\n")
self.wfile.write(AISSetTime(ldev))
elif f == 'r':
pass
rt = ''.join(pq[RTE])
if rt.strip() == '':
self.wfile.write('Must enter value for seconds !')
return
else:
try:
seconds = int(rt)
stop_time = c_uint64()
stop_time = time.time() + seconds # 10
# dev = DEV_HND
self.wfile.write("Wait for RTE for %d sec ...\n" % seconds)
while time.ctime(time.time()) < time.ctime(stop_time):
for hnd in HND_LIST:
ldev.hnd = hnd
r, rte = MainLoop(ldev)
if rte is not None:
self.wfile.write(rte)
time.sleep(THD_SLEEP)
self.wfile.write("End RTE listen")
except Exception as vError:
self.wfile.write(vError)
return
elif f == 'l':
self.wfile.write(log_get(ldev))
elif f == 'n':
if start_index and end_index:
self.wfile.write(log_by_index(int(start_index), int(end_index), ldev))
else:
self.wfile.write('You must enter values for START INDEX and END INDEX !')
elif f == 'N':
if start_time and end_time:
self.wfile.write(log_by_time(int(start_time), int(end_time), ldev))
else:
self.wfile.write('You must enter values for START TIME and END TIME !')
elif f == 'u':
get_unread_log = int(get_unread_log)
self.wfile.write(get_unread_log_one(get_unread_log, ldev))
elif f == 'w':
self.wfile.write(whitelist_read(ldev))
elif f == 'b':
self.wfile.write(blacklist_read(ldev))
elif f == 'W':
self.wfile.write(whitelist_write(white_list_write, ldev))
elif f == 'B':
self.wfile.write(blacklist_write(black_list_write, ldev))
elif f == 'L':
self.wfile.write(TestLights(lights_choise, ldev))
elif f == 'g':
self.wfile.write(get_io_state(ldev))
elif f == 'G':
self.wfile.write(lock_open(ldev))
elif f == 'y':
self.wfile.write(relay_toogle(ldev))
elif f == 'P':
global PASS
self.wfile.write("Actual application password is :%s\n" % PASS)
if len(set_def_pass) == 0:
self.wfile.write("Patch - new pass = default pass\n")
set_def_pass = PASS
PASS = set_def_pass
self.wfile.write(password_set_default(set_def_pass))
elif f == 'p':
global PASS
new_pass = ''
self.wfile.write("Old password is actual application password: %s\n" % PASS)
self.wfile.write("New password for units ( and application ): %s\n" % new_pass)
if len(new_pass) == 0:
self.wfile.write("Patch - new pass = default pass\n")
new_pass = PASS
self.wfile.write("Try set new password for units= %s\n" % (new_pass))
self.wfile.write(password_change(new_pass, ldev))
elif f == 'f':
self.wfile.write(AISGetVersion(ldev))
elif f == 'i':
self.wfile.write(AISGetTime(ldev)[0])
self.wfile.write(sys_get_timezone_info() + "\n")
self.wfile.write(AISGetVersion(ldev))
elif f == 'E':
self.wfile.write(ee_lock(ldev))
elif f == 'e':
self.wfile.write(ee_unlock(ldev))
elif f == 'F':
try:
if pq.has_key('fw_file'):
fw_file_name = ''.join(pq['fw_file_name'])
with open(fw_file_name, 'wb') as out:
out.write(''.join(pq['fw_file']))
out.close()
self.wfile.write(fw_update(ldev, fw_name=fw_file_name))
os.remove(fw_file_name)
except Exception as exc:
self.wfile.write("ERROR: %s" % exc)
elif f == 's':
try:
if pq[CONFIG_FILE_READ] is not None:
self.wfile.write('DEPRECATED AIS_Config_Send(), AIS_Config_Read()')
return
conf_file_rd = ''.join(pq[CONFIG_FILE_READ])
self.wfile.write(config_file_rd(fname=conf_file_rd))
from socket import gethostname, gethostbyname
ip = gethostbyname(gethostname())
with open(conf_file_rd + '.config', 'wb') as out:
http_request(ip + ":" + str(HTTP_SERVER_PORT), out.write(conf_file_rd + '.config'))
except Exception as exc:
self.wfile.write("ERROR: %s" % exc)
elif f == 'S':
try:
if pq[CONFIG_FILE_WR_NAME] is not None:
self.wfile.write('DEPRECATED AIS_Config_Send(), AIS_Config_Read()')
return
confFileNameWR = ''.join(pq[CONFIG_FILE_WR_NAME])
confFileWR = ''.join(pq[CONFIG_FILE_WRITE])
with open(confFileNameWR, 'wb') as out:
out.write(confFileWR)
self.wfile.write(config_file_wr(fname=confFileNameWR))
else:
self.wfile.write('NO FILE')
except Exception as exc:
self.wfile.write("ERROR: %s" % exc)
if not os.path.basename(sys.argv[0]) == AIS_HTTP:
try:
from ais_readers_main_process import DoPOST
writefile, content = DoPOST(f, ldev, **pq)
if writefile:
return self.WriteFile(content)
else:
self.SetHeaders()
return self.wfile.write(content)
except Exception as exc:
self.wfile.write(exc)
return self.wfile.write('\n')
except Exception as error_mess:
self.wfile.write(traceback.print_exc())
class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
"""Handle requests in a separate thread."""
def RunAll():
serv = threading.Thread(target=handler_server)
serv.start()
while True:
try:
if serv.isAlive():
serv.join(timeout=SERV_JOIN)
except (KeyboardInterrupt, SystemExit, Exception) as e:
httpd.server_close()
print '\nServer stopped\nProgram close', e
shut_event.set()
if sys.platform.startswith('linux'):
os.system('pkill -9 python')
elif sys.platform.startswith('win'):
sys.exit(0)
break
def handler_server():
global httpd
while not shut_event.is_set():
my_lock.acquire()
httpd.handle_request()
my_lock.release()
time.sleep(THD_SLEEP)
def init():
print AISGetLibraryVersionStr()
global httpd
list_device()
httpd = HTTPServer((HTTP_SERVER_NAME, HTTP_SERVER_PORT), GetHandler)
httpd.socket.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
RunAll()
my_lock = threading.Lock()
shut_event = threading.Event()
if __name__ == '__main__':
global httpd
init()