Skip to content
ais_http.py 9.04 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.14 (backup)'
developer7's avatar
developer7 committed
"""
developer7's avatar
developer7 committed
  - added commands.py;
  - removed many functions call;
developer7's avatar
developer7 committed
  - added import dopostprocess
developer7's avatar
developer7 committed
   
developer7's avatar
developer7 committed
"""

developer23's avatar
developer23 committed
import cgi
developer23's avatar
developer23 committed
import shutil
developer7's avatar
developer7 committed
import traceback
developer23's avatar
developer23 committed
import urllib
developer7's avatar
developer7 committed
import urllib2
import StringIO
developer7's avatar
developer7 committed
import threading
developer23's avatar
developer23 committed

developer7's avatar
developer7 committed
from commands import *
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 mimetypes import types_map
developer7's avatar
developer7 committed
from socket import *
developer23's avatar
developer23 committed
from constants import *
developer7's avatar
developer7 committed
from shell import device_list
from shell.ais_shell import AIS_HTTP, list_device
developer23's avatar
developer23 committed

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
developer7's avatar
developer7 committed
        f = StringIO.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)
developer7's avatar
developer7 committed
        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()
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):
developer7's avatar
developer7 committed
            global url_query
developer7's avatar
developer7 committed
            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.get(FUNCTION) else '')
            device = ''.join(pq[DEVICE] if pq.get(DEVICE) else '')
developer7's avatar
developer7 committed

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

developer7's avatar
developer7 committed
            getcommand = command(f, ldev, **pq)
            if getcommand:
                self.SetHeaders()
developer7's avatar
developer7 committed
                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 Exception as exc:
                        print traceback.print_exc()
developer7's avatar
developer7 committed

        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()