|
# -*- coding: utf-8 -*-
import datetime
import errno
import glob
import os
import re
import sqlite3
import stat
import time
from tornado.httpserver import HTTPServer
from tornado.ioloop import IOLoop
from tornado.options import define, options
from tornado.web import Application, RequestHandler, StaticFileHandler
from utils.boxinfo import get_box_status, get_unique_no
from utils.logit import log_request_arguments, logit
from utils.setter import local_string, set_time, set_version
from utils.sqlite import (CREATE_INDEX1, CREATE_INDEX2, CREATE_TABLE_STMT, DELETE_RECORD_STMT, INSERT_RECORD_STMT,
SELECT_MAX_PHOTO_ID_STMT, SELECT_ORIGIN_PATH_STMT)
from utils.tv import get_last_photo_path
define('host', default='127.0.0.1', help='run on the given host', type=str)
define('port', default=8001, help='run on the given port', type=int)
options.parse_command_line()
ROOT_PATH = '/minipai2'
conn = sqlite3.connect('minipai2.db')
cur = conn.cursor()
# Synchronous Off
# cur.execute('PRAGMA synchronous = OFF')
# Execute SQL
cur.execute(CREATE_TABLE_STMT)
cur.execute(CREATE_INDEX1)
cur.execute(CREATE_INDEX2)
conn.commit()
# FILE OPERATE
def silent_makdirs(path):
try:
os.makedirs(path)
except OSError as e:
if e.errno != errno.EEXIST:
raise
def silent_remove(path):
try:
os.remove(path)
except OSError as e:
if e.errno != errno.ENOENT:
raise
def silent_mode(path):
try:
flag = stat.S_IMODE(os.stat(path).st_mode) != 0555
except OSError as e:
flag = False
return flag
def get_session_root(lensman, session):
return '{}/{}'.format(ROOT_PATH, session)
def get_session_dir(lensman, session):
session_root = get_session_root(lensman, session)
return '{}/{}'.format(session_root, 'origin'), '{}/{}'.format(session_root, 'thumbnail')
def create_session_dir(lensman, session):
for path in get_session_dir(lensman, session):
if os.path.exists(path):
return False
silent_makdirs(path)
return True
def get_last_timestamp(lensman, session):
cur.execute(SELECT_MAX_PHOTO_ID_STMT, (lensman, session))
result = cur.fetchall()
return int(result[0][0] or 0)
def insert_session_file(files_):
start_at = time.time()
cur.executemany(INSERT_RECORD_STMT, files_)
conn.commit()
end_at = time.time()
logit('/fetch_thumbnail', start_at, key='start_at')
logit('/fetch_thumbnail', end_at, key='end_at')
logit('/fetch_thumbnail', end_at - start_at, key='delta_time')
def delete_session_file(lensman, session, name):
cur.execute(DELETE_RECORD_STMT, (lensman, session, name))
conn.commit()
def get_file_info(file_):
photo_name = file_.split('/')[-1]
photo_id = photo_name.split('.')[0]
thumb_path = file_.replace('{}/'.format(ROOT_PATH), '')
origin_path = thumb_path.replace('thumbnail', 'origin')
return photo_id, photo_name, thumb_path, origin_path
def is_file_valid(file_):
if file_.endswith('.tmp'): # Whether 'xxx.tmp' or not
return False
if not re.match(r'.*\/\d+\.\w+', file_): # Whether 'xxx/digit.xxx' or not
return False
if not os.stat(file_).st_size: # Whether `file size zero` or not
return False
return True
def get_glob_files(lensman, session):
_, thumb = get_session_dir(lensman, session)
if not os.path.exists(thumb):
stamp = float(session.split('_')[1] or 0)
ymd = datetime.datetime.fromtimestamp(stamp).strftime('%Y%m%d')
thumb = '{}/lost/{}/thumbnail'.format(ROOT_PATH, ymd)
return glob.glob('{}/*'.format(thumb))
def get_all_files(lensman, session):
# Glob Files
files = get_glob_files(lensman, session)
# Init Vars
files_ = []
# Foreach Glob Files
for file_ in files:
logit('/session_end', file_, key='globfile')
if is_file_valid(file_):
photo_id, photo_name, thumb_path, origin_path = get_file_info(file_)
# Insert When Photo_id Large Than Maxt
files_.append((lensman, session, photo_id, photo_name, thumb_path, origin_path))
# If Having Files To Insert Into SQLite
if files_:
insert_session_file(files_)
return files_
def get_new_files(lensman, session, maxid):
# Glob Files
files = get_glob_files(lensman, session)
# Init Vars
files_ = []
# Foreach Glob Files
for file_ in files:
logit('/fetch_thumbnail', file_, key='globfile')
if is_file_valid(file_):
photo_id, photo_name, thumb_path, _ = get_file_info(file_)
# Return When Photo_id Large Than Maxid
# Solve APP Doesn't Get Photo When Timeout
if int(photo_id) > maxid:
files_.append({
'id': photo_id,
'name': photo_name,
'path': thumb_path,
})
return files_
def get_origin_path_from_id(lensman, session, id_):
cur.execute(SELECT_ORIGIN_PATH_STMT, (lensman, id_))
result = cur.fetchall()
if not result:
return ''
origin_path = result[0][0]
if not os.path.isfile('{}/{}'.format(ROOT_PATH, origin_path)):
return ''
return origin_path
class HelloHandler(RequestHandler):
def get(self):
self.write('Hello Tornado')
class SessionStartHandler(RequestHandler):
@log_request_arguments
def post(self):
lensman = self.get_argument('lensman', '')
session = self.get_argument('session', '')
# Create Session Dir
created = create_session_dir(lensman, session)
# Change Mode to 0777
os.chmod(get_session_root(lensman, session), 0777)
self.write({
'status': 200,
'data': {
'created': created,
}
})
class SessionEndHandler(RequestHandler):
@log_request_arguments
def post(self):
lensman = self.get_argument('lensman', '')
session = self.get_argument('session', '')
# Session Root
session_root = get_session_root(lensman, session)
# Whether Mode Has Changed
if silent_mode(session_root):
# Insert Files Into SQLite
get_all_files(lensman, session)
# Change Mode to 0555
os.chmod(session_root, 0555)
self.write({
'status': 200,
})
class FetchThumbnailHandler(RequestHandler):
@log_request_arguments
def post(self):
lensman = self.get_argument('lensman', '')
session = self.get_argument('session', '')
maxid = int(self.get_argument('maxid', 0))
# New Files
files = get_new_files(lensman, session, maxid)
# logit(self, maxt, key='maxt')
logit(self, files, key='files')
self.write({
'status': 200,
'data': {
'files': files,
}
})
class FetchOriginHandler(RequestHandler):
@log_request_arguments
def post(self):
lensman = self.get_argument('lensman', '')
session = self.get_argument('session', '')
id_ = self.get_argument('id', '')
path = get_origin_path_from_id(lensman, session, id_)
self.write({
'status': 200,
'data': {
'path': path,
}
})
class DeletePhotoHandler(RequestHandler):
@log_request_arguments
def post(self):
lensman = self.get_argument('lensman', '')
session = self.get_argument('session', '')
id_ = self.get_argument('id', '')
name = self.get_argument('name', '')
path = self.get_argument('path', '')
# Delete Record from Sqlite3
delete_session_file(lensman, session, id_)
# Delete Photo from Disk
origin, thumb = get_session_dir(lensman, session)
# Delete Thumbnail
silent_remove('{}/{}'.format(thumb, name))
# Delete Origin
silent_remove('{}/{}'.format(origin, name))
self.write({
'status': 200,
})
class BoxInfoHandler(RequestHandler):
def post(self):
self.write({
'status': 200,
'data': {
'no.': get_unique_no(),
'status': get_box_status(),
}
})
class BoxTimeHandler(RequestHandler):
def post(self):
self.write({
'status': 200,
'data': {
'time': local_string(),
}
})
class SetTimeHandler(RequestHandler):
def post(self):
timestr = self.get_argument('time', '')
set_time(timestr)
self.write({
'status': 200,
})
class SetVersionHandler(RequestHandler):
def post(self):
bpversion_str = self.get_argument('bpversion_str', '')
set_version(bpversion_str)
self.write({
'status': 200,
})
class LastPhotoHandler(RequestHandler):
def post(self):
self.write({
'status': 200,
'data': {
'path': get_last_photo_path(),
}
})
handlers = [
(r'/', HelloHandler),
(r'/session_start', SessionStartHandler),
(r'/session_end', SessionEndHandler),
(r'/fetch_thumbnail', FetchThumbnailHandler),
(r'/fetch_origin', FetchOriginHandler),
(r'/delete_photo', DeletePhotoHandler),
(r'/box_info', BoxInfoHandler),
(r'/box_time', BoxTimeHandler),
(r'/set_time', SetTimeHandler),
(r'/set_version', SetVersionHandler),
(r'/static/(.*)', StaticFileHandler, {'path': ROOT_PATH}),
# TV APP
(r'/last_photo', LastPhotoHandler),
]
def main():
app = Application(handlers=handlers, default_host=options.host)
server = HTTPServer(app)
server.listen(options.port)
IOLoop.current().start()
if __name__ == '__main__':
main()
|