#!/usr/bin/env python
"""
@author: Vladan S
@copyright: D-Logic http://www.d-logic.net/nfc-rfid-reader-sdk/
"""
__program_version = '4.0.5.4'
'''
- display dirs list if not login.html exists'
'''
import cgi
import os
import posixpath
import requests
import shutil
import signal
import sys
import threading
import time
import urllib2
import urllib
from BaseHTTPServer import BaseHTTPRequestHandler
from BaseHTTPServer import HTTPServer
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
from StringIO import StringIO
import pdb
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.curdir, 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()
f.write('')
f.write("\n
Directory listing\n")
f.write("\nDirectory listing for {0}
\n" .format(path))
f.write("
\n\n")
for name in listdirs:
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('- %s\n'% (urllib.quote(linkname), cgi.escape(displayname)))
f.write("
\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.
Components that mean special things to the local file system
(e.g. drive or directory names) are ignored. (XXX They should
probably be diagnosed.)
"""
# abandon query parameters
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 send_head(self):
try:
path = self.translate_path(self.path)
f = None
if os.path.isdir(path):
for index in 'login.html', 'login.htm':
index = os.path.join(os.path.join(os.getcwd(), 'html', 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 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, edit_list_choise
dev = DEV_HND
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.has_key(FUNCTION) else '')
device = ''.join(pq[DEVICE] if pq.has_key(DEVICE) else '')
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 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 == 'IP':
from socket import gethostname, gethostbyname
from uuid import getnode
import subprocess
mac = getnode()
macAddress = ':'.join(("%012X" % mac)[i:i+2] for i in range(0, 12, 2))
ip = gethostbyname(gethostname())
if sys.platform.startswith('linux'):
l = subprocess.Popen(['hostname', '-I'], stdout=subprocess.PIPE)
ipMac = 'IP address :{0}MAC address :{1}' .format(l.communicate()[0], macAddress)
self.wfile.write(ipMac)
else:
ipMac = "IP address : %s\nMAC address : %s\n" % (ip, macAddress)
self.wfile.write(ipMac)
if f == 'U':
if pq[GIT_USERNAME] == None:
self.wfile.write('You must enter username !')
return
if pq[GIT_PASS] == None:
self.wfile.write('You must enter password !')
return
else:
try:
gitUserName = ''.join(pq[GIT_USERNAME])
gitPassword = ''.join(pq[GIT_PASS])
gitRepo = "https://{0}:{1}@git.d-logic.net/sw-python/ais-readers-cross_platform_client.git" .format(gitUserName, gitPassword)
output = 'git pull %s' % gitRepo
out = os.system(output)
if out == '' : out = 'Up To Date !'
self.wfile.write("GIT: %s" % out)
except Exception as exc:
self.wfile.write("Exception: %s" % exc)
if f == 'R':
import subprocess
try:
if sys.platform.startswith('win'):
output = 'Cannot use reboot for Windows !\n'
return
command = 'sudo reboot '
out = os.system(command)
output = 'System Reboot NOW: %s' % out
except Exception as exc_shut:
output = 'System Reboot Error: %s ' % exc_shut
finally:
self.wfile.write(output)
if pq.has_key(START_INDEX) or 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])
if f == 'q':
self.wfile.write(GetListInformation())
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)
# if len(HND_LIST) == 0:
# self.wfile.write("\nNO DEVICES FOUND (or resource busy) \n " )
# return
#
#
#
# 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]
#==========================================================================
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)))
elif f == 't':
self.wfile.write(active_device())
self.wfile.write(AISGetTime())
elif f == 'T':
self.wfile.write(sys_get_timezone_info()+ "\n")
self.wfile.write(AISSetTime())
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:
dev.hnd = hnd
r, rte = MainLoop()
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
elif f == 'l':
self.wfile.write(log_get(dev.hnd))
elif f == 'n':
self.wfile.write(log_by_index(int(start_index), int(end_index), dev.hnd))
elif f == 'N':
self.wfile.write(log_by_time(int(start_time), int(end_time), dev.hnd))
elif f == 'u':
get_unread_log = int(get_unread_log)
self.wfile.write(get_unread_log_one(get_unread_log))
elif f == 'w':
self.wfile.write(whitelist_read())
elif f == 'b':
self.wfile.write(blacklist_read())
elif f == 'W':
self.wfile.write(whitelist_write(white_list_write))
elif f == 'B':
self.wfile.write(blacklist_write(black_list_write))
elif f == 'L':
self.wfile.write(TestLights(lights_choise))
elif f == 'g':
self.wfile.write(get_io_state())
elif f == 'G':
self.wfile.write(lock_open())
elif f == 'y':
self.wfile.write(relay_toogle())
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))
self.wfile.write(password_change(new_pass))
elif f == 'f':
self.wfile.write(AISGetVersion())
elif f == 'i':
self.wfile.write(AISGetVersion())
self.wfile.write(AISGetTime())
self.wfile.write(sys_get_timezone_info() + "\n")
elif f == 'E':
self.wfile.write(ee_lock())
elif f == 'e':
self.wfile.write(ee_unlock())
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)
if GetBaseName() == AIS_MAIN or GetBaseName() == AIS_MAIN_EXE:
#log_dir = ''.join(pq[LOG_DIR])
log_dir = 'debug_log'
read_deb_log = ''.join(pq[READ_DEBUG_LOG] if pq.has_key(READ_DEBUG_LOG) else '')
save_deb_log = ''.join(pq[SAVE_DEBUG_LOG] if pq.has_key(SAVE_DEBUG_LOG) else '')
if f == "SD":
c = open(os.getcwd() + os.sep + log_dir + os.sep + save_deb_log.strip())
self.send_response(200)
self.send_header("Content-type","text/json")
self.end_headers()
self.wfile.write(c.read())
c.close()
self.wfile.close()
return
elif f == "D":
self.send_response(200)
self.send_header("Content-type","text/html")
self.end_headers()
c = open(os.getcwd() + os.sep + log_dir + os.sep + read_deb_log.strip())
self.wfile.write("Read Debug Log")
for line in c:
l = line.encode("utf-8")
self.wfile.write("%s
" % l)
c.close()
self.wfile.write("")
self.wfile.close()
return
try:
from ais_readers_main_process import DoPOST
writefile, content = DoPOST(f, **pq)
if writefile:
return self.WriteFile(content)
else:
return self.wfile.write(content)
except ImportError as exc:
self.wfile.write(exc.message)
if len(HND_LIST) == 0:
self.wfile.write("\nNO DEVICES FOUND (or resource busy) \n " )
return
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]
return
except Exception as error_mess:
# self.wfile.write(error_mess.message)
traceback.print_exc()
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()