#!/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("\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: # 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()