#!/usr/bin/env python """ :author: d-logic development team :copyright: D-Logic http://www.d-logic.net """ __app_version__ = '4.0.7.25' """ """ import cgi import posixpath import shutil import traceback import urllib import urllib2 import StringIO import threading import urlparse 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 import device_list from shell.ais_shell import AIS_HTTP, list_device def AisHttpGetProgramVersion(): return 'App name : {0} : {1}'.format(AIS_HTTP, __app_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) if ext in DOWN_FILE_EXT: self.send_header('Content-type', 'application/x-csv') else: 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/plain') self.end_headers() def SetHeadersHtml(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 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) pq = urlparse.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 '') if f not in ['', GET_DLL_VERSION, GET_PROGRAM_VERSION, GET_IP_ADDRESS, GET_APP_VERSION, GET_DEBUG_LOG, GET_NET_TIME, GET_ADMIN_SETTINGS, GET_DEVICE_LIST, GET_LIST_DEV_INFO, GET_LIST_DEV_LENGTH, GET_PLATFORM_CHECK, GET_MAIN_VERSION, GET_RASPI_TEMP]: try: if len(DDEV_HND) == 0: self.SetHeaders() self.wfile.write('NO DEVICE !') return if device is '': devindex = 1 ldev.hnd = [k for k, v in DDEV_HND.iteritems() if v[0] is devindex][0] elif int(device) > len(DDEV_HND): self.SetHeaders() self.wfile.write("\ndev[%s]NO DEVICE FOUND (or resource busy)\n" % device) return else: devindex = int(device, 10) ldev.hnd = [k for k, v in DDEV_HND.iteritems() if v[0] is devindex][0] except Exception: print traceback.print_exc() getcommand = command(f, ldev, **pq) if getcommand: self.SetHeaders() self.wfile.write(getcommand) return else: if not os.path.basename(sys.argv[0]) == AIS_HTTP: try: from dopostprocess import procommands from ais_readers_main_process import GetOpenAisHtml content = GetOpenAisHtml(**pq) if content: return self.WriteFile(content) content = procommands(f, ldev, **pq) if content: self.SetHeaders() self.wfile.write(content) else: return '' except ImportError: print traceback.print_exc() except Exception: 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()