#!/usr/bin/python # -*- coding: utf-8 -*- import os import io import math from PIL import Image from HTMLParser import HTMLParser import sqlite3 as lite import tornado.httpserver import tornado.ioloop import tornado.options import tornado.web from tornado.options import define, options define("port", default=8080, help="run on the given port", type=int) PATH=os.path.dirname(os.path.abspath(__file__)) static_path_dir = os.path.join(PATH, 'static/fossil') data_path_dir = "/mnt/fossils" class MyHTMLParser(HTMLParser): def __init__(self): self.reset() self.ttype = "p" self.fed = [] def handle_starttag(self, tag, attrs): self.ttype = str(tag) def handle_endtag(self, tag): self.ttype = "p" def handle_data(self, data): self.fed.append({"type": self.ttype, "text": data.strip()}) def get_data(self): return self.fed class Application(tornado.web.Application): def __init__(self): handlers = [ (r"/", MainHandler), (r"/update", UpdateHandler), (r"/img", ImageHandler), (r"/download", GenFileStreamerHandler), (r"/getpage", PageHandler), #(r'/fossils/static/(.*)', tornado.web.StaticFileHandler, {'path': static_path_dir}), ] settings = dict( template_path=os.path.join(os.path.dirname(__file__), "templates"), static_path=static_path_dir, debug=True, ) tornado.web.Application.__init__(self, handlers, **settings) class DATA: def __init__(self, index=None): self.con = lite.connect('fossil.db') cur = self.con.cursor() with self.con: if index == None: cur.execute("SELECT * FROM Fossil ORDER BY Name LIMIT 1") else: cur.execute("SELECT * FROM Fossil WHERE Name = ?", [index]) data = cur.fetchone() if data == None: raise Exception('Database: Data Id ' + str(index) + ' does not exist.') #self.index = data[0] print data self.name = data[0] parser = MyHTMLParser() parser.feed(data[1]) self.desc = parser.get_data() self.size = ("%.2f" % (data[2] / 1000000.0)) self.left_count = data[3] self.top_count = data[4] self.front_count = data[5] self.left_width = data[7] self.top_width = data[8] self.front_width = data[9] #def get_index(self): # return self.index def get_name(self): return self.name def get_desc(self): return self.desc def get_size(self): return self.size def get_left_width(self): return self.left_width def get_top_width(self): return self.top_width def get_front_width(self): return self.front_width def get_left_count(self): return self.left_count def get_top_count(self): return self.top_count def get_front_count(self): return self.front_count def slug(self, slug=None): if slug: self.slug = slug else: self.slug = "The Fossils Data" return self.slug def title(self, title=None): if title: self.title = title else: self.title = """Parasitoid biology preserved in mineralized fossils""" return self.title def get_list(self, page=None): if page == None: page = 1 page_lower = (page - 1) * 10 page_upper = page_lower + 10 with self.con: cur = self.con.cursor() #cur.execute("SELECT * FROM Fossil WHERE Id > 0 AND Id <= 10 ORDER BY Id ASC") cur.execute("SELECT * FROM Fossil WHERE Id > " + str(page_lower) + " AND Id <= " + str(page_upper) + " ORDER BY Id ASC") data = cur.fetchall() tmp_data = [] for i, item in enumerate(data): parser = MyHTMLParser() parser.feed(item[1]) tmp_data.append([ item[0], parser.get_data(), "%.2f" % (item[2] / 1000000.0), item[3], item[4], item[5], item[6], item[7], item[8], item[9] ]) self.data_list = tmp_data return self.data_list class PageHandler(tornado.web.RequestHandler): def get(self): page = int(self.get_argument("page", 1)) filter_type = self.get_argument("type", "0") total_item_per_page = 10 self.con = lite.connect('fossil.db') cur = self.con.cursor() with self.con: cur = self.con.cursor() if filter_type == "0": cur.execute("SELECT * FROM Fossil ORDER BY Id ASC") print "0 type" else: cur.execute("SELECT * FROM Fossil WHERE Description LIKE '%"+filter_type+"%' ORDER BY Id ASC") data = cur.fetchall() total_items = len(data) for unit in data: print unit lower_limit = (page - 1) * 10 upper_limit = lower_limit + 10 if upper_limit > total_items: upper_limit = total_items print page, lower_limit, upper_limit tmp_data = [] for i, item in enumerate(data[lower_limit:upper_limit]): parser = MyHTMLParser() parser.feed(item[1]) tmp_data.append([ item[0], parser.get_data(), "%.2f" % (item[2] / 1000000.0), item[3], item[4], item[5], item[6], item[7], item[8], item[9] ]) output = {} output["data"] = tmp_data output["total_items"] = total_items delta = upper_limit - lower_limit if delta < 0: delta = 0 output["total_items_per_page"] = delta output["total_pages"] = math.ceil(total_items / 10.0) self.write(output) class UpdateHandler(tornado.web.RequestHandler): def get(self): index = self.get_argument("index", None) name = self.get_argument("name", None) print index, name selected_data = DATA(index) self.write({ "name": name, "index": index, "data_size": selected_data.get_size(), "desc": selected_data.get_desc(), "top_count": selected_data.get_top_count(), "left_count": selected_data.get_left_count(), "front_count": selected_data.get_front_count() }) class MainHandler(tornado.web.RequestHandler): def get(self): index = self.get_argument("index", None) print index data = DATA(index) print data.get_list() self.render( "fossil.html", slug = data.slug(), #index = data.get_index(), name = data.get_name(), title = data.title(), data_list = data.get_list(), desc = data.get_desc(), data_size = data.get_size(), left_count = data.get_left_count(), top_count = data.get_top_count(), front_count = data.get_front_count(), left_width = data.get_left_width(), top_width = data.get_top_width(), front_width = data.get_front_width() ) class GenFileStreamerHandler(tornado.web.RequestHandler): CHUNK_SIZE = 512000 DATA_PATH = data_path_dir @tornado.web.asynchronous @tornado.gen.engine def get(self): cdid = self.get_argument("did") print cdid con = lite.connect('fossil.db') with con: cur = con.cursor() cur.execute("SELECT name FROM Fossil WHERE name = ?", [cdid]) data_key = cur.fetchall() if len(data_key) > 0: file_name = str(cdid) + ".zip" self.path = os.path.join( self.DATA_PATH, str(cdid), file_name) self.set_header('Content-Type', 'application/octet-stream') self.set_header('Content-Disposition', 'attachment; filename="' + file_name) self.set_header("Content-Length", os.path.getsize(self.path)) self.flush() fd = open(self.path, "rb") data = fd.read(self.CHUNK_SIZE) while data: self.write(data) yield tornado.gen.Task(self.flush) data = fd.read(self.CHUNK_SIZE) fd.close() self.finish() class ImageHandler(tornado.web.RequestHandler): CHUNK_SIZE = 512000 DATA_PATH = data_path_dir @tornado.web.asynchronous @tornado.gen.engine def get(self): did = self.get_argument("id", None) dname = self.get_argument("name", None) dtype = self.get_argument("type", None) dcounter = self.get_argument("counter", "0").zfill(4) if dname.split(" ")[0] == "undefined": self.finish() return print did, dname, dtype, dcounter if dtype == "left" or dtype == "left-resized" or dtype == "left-resized-mini": prefix = "left" elif dtype == "top" or dtype == "top-resized" or dtype == "top-resized-mini": prefix = "top" elif dtype == "front" or dtype == "front-resized" or dtype == "front-resized-mini": prefix = "front" if dtype == "volren": self.path = os.path.join( self.DATA_PATH, dname, str(dname)+".jpg") elif dtype == "photo": self.path = os.path.join( self.DATA_PATH, dname, str(dname)+"_photo.jpg") else: self.path = os.path.join( self.DATA_PATH, dname, dtype, prefix+str(dcounter)+".png") #print did, dname, dtype, dcounter #print self.path self.set_header('Content-Type', 'image/png') self.set_header("Content-Length", os.path.getsize(self.path)) self.flush() fd = open(self.path, "rb") data = fd.read(self.CHUNK_SIZE) while data: self.write(data) yield tornado.gen.Task(self.flush) data = fd.read(self.CHUNK_SIZE) fd.close() self.finish() if __name__ == "__main__": tornado.options.parse_command_line() http_server = tornado.httpserver.HTTPServer(Application()) http_server.listen(options.port) tornado.ioloop.IOLoop.instance().start()