Skip to content
ais_http.py 19.2 KiB
Newer Older
developer23's avatar
developer23 committed
#!/usr/bin/env python

"""
developer23's avatar
developer23 committed
:author: Vladan S
:copyright: D-Logic   http://www.d-logic.net
developer23's avatar
developer23 committed
 
"""
developer7's avatar
developer7 committed
__program_version = '4.0.7.11'
developer7's avatar
developer7 committed
"""
developer7's avatar
developer7 committed
  - added local ldev parametar when call DoPOST();
developer7's avatar
developer7 committed
   
  
developer7's avatar
developer7 committed
"""

developer23's avatar
developer23 committed
import cgi
import os
developer23's avatar
developer23 committed
import requests
import shutil
import signal
import sys
import threading
import time
import urllib2
import urllib

from BaseHTTPServer import BaseHTTPRequestHandler
from BaseHTTPServer import HTTPServer
developer23's avatar
developer23 committed
from SocketServer import ThreadingMixIn

developer23's avatar
developer23 committed
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

developer23's avatar
developer23 committed
from StringIO import StringIO

developer23's avatar
developer23 committed
from constants import *
from shell.ais_shell import *

global edit_time

developer23's avatar
developer23 committed

developer23's avatar
developer23 committed
def AisHttpGetProgramVersion():
    return 'App name  : {0}  : {1}'.format(AIS_HTTP, __program_version)
developer23's avatar
developer23 committed

developer23's avatar
developer23 committed

developer23's avatar
developer23 committed
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")
developer23's avatar
developer23 committed
        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
developer23's avatar
developer23 committed
class GetHandler(BaseHTTPRequestHandler):
    global url_query

    def WriteFile(self, path):
        '''Write any file to client
developer23's avatar
developer23 committed
           :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):
developer23's avatar
developer23 committed
        try:
            listdirs = os.listdir(path)
        except os.error:
            self.send_error(404)
            return None
        f = StringIO()
developer23's avatar
developer23 committed
        f.write('<!DOCTYPE html>')
        f.write("<html>\n<title>Directory listing</title>\n")
        f.write("<body>\n<h2>Directory listing for {0}</h2>\n".format(path))
        f.write("<hr>\n<ul>\n")
        for name in listdirs:
developer23's avatar
developer23 committed
            fullname = os.path.join(path, name)
            displayname = linkname = name
developer23's avatar
developer23 committed
            if os.path.isdir(fullname):
                displayname = name + "/"
                linkname = name + "/"
developer23's avatar
developer23 committed
            if os.path.islink(fullname):
                displayname = name + "@"
            f.write('<li><a href="%s">%s</a>\n' % (urllib.quote(linkname), cgi.escape(displayname)))
        f.write("</ul>\n<hr>\n</body>\n</html>\n")
developer23's avatar
developer23 committed
        length = f.tell()
        f.seek(0)
developer23's avatar
developer23 committed
        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()
developer23's avatar
developer23 committed
        return f
    def do_HEAD(self):
        f = self.send_head()
    def translate_path(self, path):
        """Translate a /-separated PATH to the local filename syntax.
developer23's avatar
developer23 committed
           :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
developer23's avatar
developer23 committed
    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):
            path = self.translate_path(self.path)
            f = None
developer23's avatar
developer23 committed
            if os.path.isdir(path):
                scripts = self.script_name()
developer23's avatar
developer23 committed
                for index in scripts:
                    index = os.path.join(os.path.join(os.getcwd(), HTML_FOLDER, index))
                    if os.path.exists(index):
                        path = index
                        break
                    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()
        except IOError:
            self.send_error(404, 'File Not Found: %s' % self.path)
developer23's avatar
developer23 committed
    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()
developer23's avatar
developer23 committed
        except IOError:
            self.send_error(404, 'File Not Found: %s' % self.path)
developer23's avatar
developer23 committed
    def do_POST(self):
            # dev = DEV_HND
developer23's avatar
developer23 committed
            global url_query, edit_list_choise
developer7's avatar
developer7 committed
            global start_index, end_index
            global start_time, end_time

            ldev = device_list.S_DEVICE
developer23's avatar
developer23 committed
            ctype, pdict = cgi.parse_header(self.headers['content-type'])
developer23's avatar
developer23 committed
            if ctype == 'multipart/form-data':
                pq = cgi.parse_multipart(self.rfile, pdict)
developer23's avatar
developer23 committed
            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)
developer23's avatar
developer23 committed
            else:
                pq = {}
developer7's avatar
developer7 committed

developer7's avatar
developer7 committed
            f = ''.join(pq[FUNCTION] if pq.has_key(FUNCTION) else '')
developer23's avatar
developer23 committed
            device = ''.join(pq[DEVICE] if pq.has_key(DEVICE) else '')
developer7's avatar
developer7 committed

developer7's avatar
developer7 committed
            if f == 'q':
developer7's avatar
developer7 committed
                self.SetHeaders()
developer7's avatar
developer7 committed
                self.wfile.write(GetListInformation())

developer7's avatar
developer7 committed
            if f == 'v':
developer7's avatar
developer7 committed
                self.SetHeaders()
developer7's avatar
developer7 committed
                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)

developer7's avatar
developer7 committed
            try:
developer7's avatar
developer7 committed
                if device is '':
developer7's avatar
developer7 committed
                    ldev.hnd = HND_LIST[0]
developer7's avatar
developer7 committed
                elif int(device) > len(HND_LIST):
                    self.wfile.write("\ndev[%s]NO DEVICE FOUND (or resource busy)\n" % device)
developer7's avatar
developer7 committed
                    return
                else:
developer7's avatar
developer7 committed
                    ldev.hnd = HND_LIST[int(device, 10) - 1]
developer7's avatar
developer7 committed
            except Exception as exc:
                print exc
developer7's avatar
developer7 committed

developer23's avatar
developer23 committed
            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])

developer7's avatar
developer7 committed
            if f == 'R':
developer7's avatar
developer7 committed
                try:
                    self.wfile.write(AISRestart(ldev))
                except TypeError:
                    self.wfile.write('')
developer7's avatar
developer7 committed

            if f == 'D':
developer7's avatar
developer7 committed
                try:
                    self.wfile.write(AISDestroy(ldev))
                except TypeError:
                    self.wfile.write('')
developer7's avatar
developer7 committed

developer7's avatar
developer7 committed
            if f == 'Q':
                if edit_list_choise == AVAILABLE_DEVICES:
developer23's avatar
developer23 committed
                    self.wfile.write(edit_device_list(1))
                elif edit_list_choise == ACTUAL_LIST:
developer23's avatar
developer23 committed
                    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)))
developer23's avatar
developer23 committed
                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)))
developer23's avatar
developer23 committed
                else:
                    self.wfile.write("")
developer7's avatar
developer7 committed

developer7's avatar
developer7 committed
            if pq.has_key(START_INDEX) and pq.has_key(END_INDEX):
developer7's avatar
developer7 committed
                start_index = (''.join(pq[START_INDEX]))
                end_index = (''.join(pq[END_INDEX]))
developer7's avatar
developer7 committed

            if pq.has_key(START_TIME) or pq.has_key(END_TIME):
developer7's avatar
developer7 committed
                start_time = (''.join(pq[START_TIME]))
                end_time = (''.join(pq[END_TIME]))

            if pq.has_key(WHITE_LIST_WRITE):
developer23's avatar
developer23 committed
                white_list_write = ''.join(pq[WHITE_LIST_WRITE])
developer7's avatar
developer7 committed

developer23's avatar
developer23 committed
            if pq.has_key(BLACK_LIST_WRITE):
                black_list_write = ''.join(pq[BLACK_LIST_WRITE])

developer23's avatar
developer23 committed
            if pq.has_key(DEFAULT_APP_PASS):
                set_def_pass = ''.join(pq[DEFAULT_APP_PASS])
developer23's avatar
developer23 committed
            if pq.has_key(NEW_PASS):
developer7's avatar
developer7 committed
                new_pass = ''.join(pq[NEW_PASS])

            if pq.has_key(UNREAD_LOG):
developer23's avatar
developer23 committed
                get_unread_log = (''.join(pq[UNREAD_LOG]))
developer23's avatar
developer23 committed
            if pq.has_key(LIGHTS):
                lights_choise = ''.join(pq[LIGHTS])
developer23's avatar
developer23 committed

developer7's avatar
developer7 committed
            if f == 'o':
developer7's avatar
developer7 committed
                try:
                    self.wfile.write(AISOpen(ldev))
                except TypeError:
                    self.wfile.write('')
developer23's avatar
developer23 committed
            elif f == 'c':
developer7's avatar
developer7 committed
                try:
                    self.wfile.write(AISClose(ldev))
                except TypeError:
                    self.wfile.write('')
developer23's avatar
developer23 committed
            if f == 'd':
developer7's avatar
developer7 committed
                try:
                    res, count = AISUpdateAndGetCount()
developer7's avatar
developer7 committed
                    self.wfile.write(' COUNT >> {0} {1}'.format(count, wr_status('', res)))
                except WindowsError:
                    pass

developer7's avatar
developer7 committed
            elif f == 't':
developer7's avatar
developer7 committed
                gettime, currtimes = AISGetTime(ldev)
developer7's avatar
developer7 committed
                self.wfile.write(gettime)

            elif f == 'T':
developer7's avatar
developer7 committed
                self.wfile.write(sys_get_timezone_info() + "\n")
developer7's avatar
developer7 committed
                self.wfile.write(AISSetTime(ldev))
developer23's avatar
developer23 committed
            elif f == 'r':
                pass
                rt = ''.join(pq[RTE])
developer23's avatar
developer23 committed
                if rt.strip() == '':
                    self.wfile.write('Must enter value for seconds !')
                    return
                else:
developer23's avatar
developer23 committed
                        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)
developer7's avatar
developer7 committed
                        while time.ctime(time.time()) < time.ctime(stop_time):
developer23's avatar
developer23 committed
                            for hnd in HND_LIST:
developer7's avatar
developer7 committed
                                ldev.hnd = hnd
                                r, rte = MainLoop(ldev)
developer7's avatar
developer7 committed
                                if rte is not None:
developer23's avatar
developer23 committed
                                    self.wfile.write(rte)
                            time.sleep(THD_SLEEP)
                        self.wfile.write("End RTE listen")
developer23's avatar
developer23 committed
                    except Exception as vError:
                        self.wfile.write(vError)
developer7's avatar
developer7 committed

developer7's avatar
developer7 committed
            elif f == 'l':
developer7's avatar
developer7 committed
                self.wfile.write(log_get(ldev))
developer7's avatar
developer7 committed

developer7's avatar
developer7 committed
            elif f == 'n':
developer7's avatar
developer7 committed
                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 !')
developer7's avatar
developer7 committed

developer7's avatar
developer7 committed
            elif f == 'N':
developer7's avatar
developer7 committed
                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 !')
developer7's avatar
developer7 committed

developer7's avatar
developer7 committed
            elif f == 'u':
                get_unread_log = int(get_unread_log)
developer7's avatar
developer7 committed
                self.wfile.write(get_unread_log_one(get_unread_log, ldev))

            elif f == 'w':
developer7's avatar
developer7 committed
                self.wfile.write(whitelist_read(ldev))

            elif f == 'b':
developer7's avatar
developer7 committed
                self.wfile.write(blacklist_read(ldev))
developer23's avatar
developer23 committed

            elif f == 'W':
developer7's avatar
developer7 committed
                self.wfile.write(whitelist_write(white_list_write, ldev))
developer23's avatar
developer23 committed

            elif f == 'B':
developer7's avatar
developer7 committed
                self.wfile.write(blacklist_write(black_list_write, ldev))
developer23's avatar
developer23 committed

            elif f == 'L':
developer7's avatar
developer7 committed
                self.wfile.write(TestLights(lights_choise, ldev))

            elif f == 'g':
developer7's avatar
developer7 committed
                self.wfile.write(get_io_state(ldev))
            elif f == 'G':
developer7's avatar
developer7 committed
                self.wfile.write(lock_open(ldev))
            elif f == 'y':
developer7's avatar
developer7 committed
                self.wfile.write(relay_toogle(ldev))
developer23's avatar
developer23 committed
            elif f == 'P':
                global PASS
                self.wfile.write("Actual application password is :%s\n" % PASS)
developer7's avatar
developer7 committed
                if len(set_def_pass) == 0:
developer23's avatar
developer23 committed
                    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))

developer23's avatar
developer23 committed
            elif f == 'p':
                global PASS
developer7's avatar
developer7 committed
                new_pass = ''
                self.wfile.write("Old password is actual application password: %s\n" % PASS)
developer23's avatar
developer23 committed
                self.wfile.write("New password for units ( and application ): %s\n" % new_pass)
                if len(new_pass) == 0:
developer7's avatar
developer7 committed
                    self.wfile.write("Patch - new pass = default pass\n")
                    new_pass = PASS
developer23's avatar
developer23 committed
                self.wfile.write("Try set new password for units= %s\n" % (new_pass))
developer7's avatar
developer7 committed
                self.wfile.write(password_change(new_pass, ldev))
developer23's avatar
developer23 committed

            elif f == 'f':
developer7's avatar
developer7 committed
                self.wfile.write(AISGetVersion(ldev))
developer7's avatar
developer7 committed
            elif f == 'i':
                self.wfile.write(AISGetTime(ldev)[0])
developer23's avatar
developer23 committed
                self.wfile.write(sys_get_timezone_info() + "\n")
developer7's avatar
developer7 committed
                self.wfile.write(AISGetVersion(ldev))

developer23's avatar
developer23 committed
            elif f == 'E':
developer7's avatar
developer7 committed
                self.wfile.write(ee_lock(ldev))
developer23's avatar
developer23 committed
            elif f == 'e':
developer7's avatar
developer7 committed
                self.wfile.write(ee_unlock(ldev))

            elif f == 'F':
developer23's avatar
developer23 committed
                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()
developer7's avatar
developer7 committed
                        self.wfile.write(fw_update(ldev, fw_name=fw_file_name))
                        os.remove(fw_file_name)
developer23's avatar
developer23 committed
                except Exception as exc:
                    self.wfile.write("ERROR: %s" % exc)
developer23's avatar
developer23 committed
            elif f == 's':
                try:
developer7's avatar
developer7 committed
                    if pq[CONFIG_FILE_READ] is not None:
developer7's avatar
developer7 committed
                        self.wfile.write('DEPRECATED AIS_Config_Send(), AIS_Config_Read()')
                        return
developer23's avatar
developer23 committed
                        conf_file_rd = ''.join(pq[CONFIG_FILE_READ])
                        self.wfile.write(config_file_rd(fname=conf_file_rd))

                        from socket import gethostname, gethostbyname
developer23's avatar
developer23 committed
                        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'))
developer23's avatar
developer23 committed
                except Exception as exc:
                    self.wfile.write("ERROR: %s" % exc)
developer7's avatar
developer7 committed

            elif f == 'S':
developer23's avatar
developer23 committed
                try:
developer7's avatar
developer7 committed
                    if pq[CONFIG_FILE_WR_NAME] is not None:
developer7's avatar
developer7 committed
                        self.wfile.write('DEPRECATED AIS_Config_Send(), AIS_Config_Read()')
                        return
developer23's avatar
developer23 committed
                        confFileNameWR = ''.join(pq[CONFIG_FILE_WR_NAME])
                        confFileWR = ''.join(pq[CONFIG_FILE_WRITE])
developer23's avatar
developer23 committed
                        with open(confFileNameWR, 'wb') as out:
                            out.write(confFileWR)
                        self.wfile.write(config_file_wr(fname=confFileNameWR))
developer23's avatar
developer23 committed
                    else:
                        self.wfile.write('NO FILE')
                except Exception as exc:
                    self.wfile.write("ERROR: %s" % exc)
developer23's avatar
developer23 committed

developer7's avatar
developer7 committed
            if not os.path.basename(sys.argv[0]) == AIS_HTTP:
                try:
                    from ais_readers_main_process import DoPOST
developer7's avatar
developer7 committed
                    writefile, content = DoPOST(f, ldev, **pq)
developer7's avatar
developer7 committed
                    if writefile:
                        return self.WriteFile(content)
                    else:
developer7's avatar
developer7 committed
                        self.SetHeaders()
developer7's avatar
developer7 committed
                        return self.wfile.write(content)
developer7's avatar
developer7 committed

developer7's avatar
developer7 committed
                except Exception as exc:
                    self.wfile.write(exc)
developer7's avatar
developer7 committed

developer7's avatar
developer7 committed
            return self.wfile.write('\n')

        except Exception as error_mess:
            self.wfile.write(traceback.print_exc())
developer7's avatar
developer7 committed

developer23's avatar
developer23 committed

developer23's avatar
developer23 committed
class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
    """Handle requests in a separate thread."""
developer7's avatar
developer7 committed


def RunAll():
    serv = threading.Thread(target=handler_server)
    serv.start()
developer23's avatar
developer23 committed
    while True:
        try:
            if serv.isAlive():
                serv.join(timeout=SERV_JOIN)
developer23's avatar
developer23 committed
        except (KeyboardInterrupt, SystemExit, Exception) as e:
            httpd.server_close()
            print '\nServer stopped\nProgram close', e
developer23's avatar
developer23 committed
            shut_event.set()
            if sys.platform.startswith('linux'):
                os.system('pkill -9 python')
            elif sys.platform.startswith('win'):
                sys.exit(0)
developer23's avatar
developer23 committed
            break
developer23's avatar
developer23 committed

def handler_server():
    global httpd
    while not shut_event.is_set():
        my_lock.acquire()
developer23's avatar
developer23 committed
        httpd.handle_request()
        my_lock.release()
        time.sleep(THD_SLEEP)

developer7's avatar
developer7 committed

def init():
    print AISGetLibraryVersionStr()
developer7's avatar
developer7 committed
    global httpd
    list_device()
    httpd = HTTPServer((HTTP_SERVER_NAME, HTTP_SERVER_PORT), GetHandler)
    httpd.socket.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
    RunAll()
developer23's avatar
developer23 committed


my_lock = threading.Lock()
shut_event = threading.Event()

if __name__ == '__main__':
    global httpd
    init()