Skip to content
ais_http.py 22.3 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
"""
 - all function sent device parametar (dev) to ais_shell;
"""



developer7's avatar
developer7 committed
__program_version = '4.0.7.5'
developer23's avatar
developer23 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



developer23's avatar
developer23 committed

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

developer23's avatar
developer23 committed
    
developer23's avatar
developer23 committed
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
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
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("/")
developer23's avatar
developer23 committed
        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
    
developer23's avatar
developer23 committed
    
developer23's avatar
developer23 committed
    def list_dir(self,path):
        try:
            listdirs = os.listdir(path)
        except os.error:
            self.send_error(404)
            return None        
        f = StringIO()                
        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           
            if os.path.isdir(fullname):
                displayname = name + "/"
                linkname = name + "/"                             
            if os.path.islink(fullname):
                displayname = name + "@"
            f.write('<li><a href="%s">%s</a>\n'% (urllib.quote(linkname), cgi.escape(displayname)))                                                     
developer23's avatar
developer23 committed
        f.write("</ul>\n<hr>\n</body>\n</html>\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
developer23's avatar
developer23 committed
      
    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.
developer23's avatar
developer23 committed
           :param path:current path to translate path
           :return: translated path
developer23's avatar
developer23 committed
       
        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):
developer23's avatar
developer23 committed
        try:                        
            path = self.translate_path(self.path)
            f = None             
developer23's avatar
developer23 committed
            if os.path.isdir(path):
                scripts = self.script_name()                                                    
                for index in scripts:
developer23's avatar
developer23 committed
                    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
developer23's avatar
developer23 committed
            
            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)
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):
developer23's avatar
developer23 committed
        try:                                                         
developer23's avatar
developer23 committed
            if f:                                                                    
                shutil.copyfileobj(f, self.wfile)                        
developer23's avatar
developer23 committed
        except IOError:
            self.send_error(404, 'File Not Found: %s' % self.path)
        return    
    
    def do_POST(self):
        try:    
            global url_query, edit_list_choise
developer7's avatar
developer7 committed
            global start_index, end_index
            global start_time, end_time

            # dev = DEV_HND

            ldev = device_list.S_DEVICE

developer23's avatar
developer23 committed
            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 = {}
                        
                 
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 len(HND_LIST) == 0:
            #     self.wfile.write("dev[%s]NO DEVICE FOUND (or resource busy)" % device)
            #     return
developer7's avatar
developer7 committed

            if f == 'q':
                self.wfile.write(GetListInformation())


developer7's avatar
developer7 committed
            try:
                if not device.isdigit():
                    ldev.hnd = HND_LIST[0]
                elif int(device) > len(HND_LIST) or int(device) == 0:
developer7's avatar
developer7 committed
                    self.wfile.write("\ndev[%s]NO DEVICE FOUND (or resource busy)" % device)
developer7's avatar
developer7 committed
                    return
                else:
                    ldev.hnd = HND_LIST[int(device) -1]
            except Exception as exc:
                print exc
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 == '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:                    
                    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("") 
                                  
developer23's avatar
developer23 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 = int(''.join(pq[START_INDEX]))
               end_index   = int(''.join(pq[END_INDEX]))

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

           
            
developer7's avatar
developer7 committed

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

developer23's avatar
developer23 committed
    #==========================================================================            
           
            if f == 'o':                            
                pass                
                self.wfile.write(AISOpen())                
                    
            elif f == 'c':
                self.wfile.write(AISClose())
            
            if f == 'd':
                res, count= AISUpdateAndGetCount()                
                self.wfile.write(' COUNT >> {0} {1}'.format(count, wr_status('', res)))
                                      
        
developer7's avatar
developer7 committed
            elif f == 't':
                # self.wfile.write(active_device())
                # gettime, _ = AISGetTime()

developer7's avatar
developer7 committed
                # ldev = device_list.S_DEVICE
                # ldev.hnd = HND_LIST[int(device) - 1]
                # print ldev.hnd
developer7's avatar
developer7 committed

developer7's avatar
developer7 committed
                # self.wfile.write(active_device(ldev))
developer7's avatar
developer7 committed
                gettime, _ = AISGetTime(ldev)
                self.wfile.write(gettime)
developer23's avatar
developer23 committed
            
            elif f == 'T':             
                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])                                
                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
developer7's avatar
developer7 committed
                        #dev = DEV_HND
developer23's avatar
developer23 committed
                        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:
developer7's avatar
developer7 committed
                                ldev.hnd = hnd
                                r, rte = MainLoop(ldev)
developer23's avatar
developer23 committed
                                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   
                
                  
developer7's avatar
developer7 committed
            elif f == 'l':
developer7's avatar
developer7 committed
                self.wfile.write(log_get(ldev))
developer23's avatar
developer23 committed
                
           
developer7's avatar
developer7 committed
            elif f == 'n':
                self.wfile.write(log_by_index(start_index, end_index, ldev))
developer23's avatar
developer23 committed
               
                
developer7's avatar
developer7 committed
            elif f == 'N':
developer7's avatar
developer7 committed
                self.wfile.write(log_by_time(int(start_time), int(end_time), ldev))
developer23's avatar
developer23 committed
                
                
developer7's avatar
developer7 committed
            elif f == 'u':
developer23's avatar
developer23 committed
                get_unread_log = int(get_unread_log)                                
developer7's avatar
developer7 committed
                self.wfile.write(get_unread_log_one(get_unread_log, ldev))
developer23's avatar
developer23 committed
                                      
            elif f == 'w':               
developer7's avatar
developer7 committed
                self.wfile.write(whitelist_read(ldev))
developer23's avatar
developer23 committed
                                
            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))
developer23's avatar
developer23 committed
                
            elif f == 'g':               
developer7's avatar
developer7 committed
                self.wfile.write(get_io_state(ldev))
developer23's avatar
developer23 committed
            elif f == 'G':               
developer7's avatar
developer7 committed
                self.wfile.write(lock_open(ldev))
developer23's avatar
developer23 committed
            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)
                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
                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))
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))
developer23's avatar
developer23 committed
            
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))
developer23's avatar
developer23 committed
           
            elif f == 'F':              
                try:
                    if pq[BIN_FIRMWARE_NAME] != 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] != 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] != 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) 
                    
developer23's avatar
developer23 committed

developer23's avatar
developer23 committed
            if not os.path.basename(sys.argv[0]) == AIS_HTTP: 
developer23's avatar
developer23 committed
                try:
                    from ais_readers_main_process import DoPOST                                                                              
developer23's avatar
developer23 committed
                    writefile, content = DoPOST(f, **pq)                                    
developer23's avatar
developer23 committed
                    if writefile:
                        return self.WriteFile(content)
developer23's avatar
developer23 committed
                    else: 
developer7's avatar
developer7 committed
                       # self.SetHeaders()
developer23's avatar
developer23 committed
                        return self.wfile.write(content)                    
developer23's avatar
developer23 committed
                except Exception as exc:
                    self.wfile.write(exc)
developer23's avatar
developer23 committed
                        
developer23's avatar
developer23 committed
            
developer7's avatar
developer7 committed
            # if len(HND_LIST) == 0:
            #     self.wfile.write("\nNO DEVICES FOUND (or resource busy) \n " )
            # return
developer23's avatar
developer23 committed
                                 
developer7's avatar
developer7 committed
            # if not device.isdigit():
            #     dev.hnd = HND_LIST[0]
            # elif int(device) > len(HND_LIST) or int(device) == 0:
            #     self.wfile.write("dev[%s]NO DEVICE FOUND (or resource busy)" % device)
            #     return
            # else:
            #     dev.hnd = HND_LIST[int(device) -1]
developer7's avatar
developer7 committed

developer23's avatar
developer23 committed
            return
                                
        except Exception as error_mess:                                         
#             self.wfile.write(error_mess.message)
            traceback.print_exc()                               
           

developer23's avatar
developer23 committed
class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
    """Handle requests in a separate thread."""
developer23's avatar
developer23 committed
        
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   
    #dev_list() 
    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()