#!/usr/bin/env python """ :author: Vladan S :copyright: D-Logic http://www.d-logic.net """ """ - fixed bugs in do_POST(); - back code for ais_readers_main... module to end of do_POST(); """ __program_version = '4.0.7.8' import cgi import os import posixpath import requests import shutil import signal import sys import threading import time import urllib2 import urllib from BaseHTTPServer import BaseHTTPRequestHandler from BaseHTTPServer import HTTPServer from SocketServer import ThreadingMixIn from ctypes import * from platform import platform from socket import * from urlparse import parse_qs from urlparse import urlparse from mimetypes import types_map import traceback from StringIO import StringIO 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() f.write('') f.write("\nDirectory listing\n") f.write("\n

Directory listing for {0}

\n" .format(path)) f.write("
\n\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: global url_query, edit_list_choise global start_index, end_index global start_time, end_time # dev = DEV_HND 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.has_key(FUNCTION) else '') device = ''.join(pq[DEVICE] if pq.has_key(DEVICE) else '') if f == 'q': self.wfile.write(GetListInformation()) if f == 'v': self.wfile.write("AIS_GetDLLVersion() >> %s\n" % AISGetLibraryVersionStr()) if f in ('x', 'X'): self.wfile.write("\nServer stopped !\nClose program !\n") shut_event.set() if sys.platform.startswith('linux'): os.system('pkill -9 python') os.kill(os.getpid(), signal.SIGINT) elif sys.platform.startswith('win'): os._exit(0) 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] # if len(HND_LIST) == 0 or ldev.hnd[0].value is None: # self.wfile.write('\nNO DEVICES FOUND\n') # return 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 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 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]) 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 != 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[BIN_FIRMWARE_NAME] is not None: firmw_name = ''.join(pq[BIN_FIRMWARE_NAME]) fwFile = ''.join(pq[BIN_FNAME]) with open(firmw_name, 'wb') as out: out.write(fwFile) self.wfile.write(fw_update(fw_name=firmw_name)) else: self.wfile.write('NO FILE') except Exception as exc: self.wfile.write("ERROR: %s" % exc) elif f == 's': try: if pq[CONFIG_FILE_READ] is not None: 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: 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, **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()