main.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373
  1. #!/usr/bin/python
  2. # -*- coding: utf-8 -*-
  3. import os
  4. import io
  5. import math
  6. from PIL import Image
  7. from HTMLParser import HTMLParser
  8. import sqlite3 as lite
  9. import tornado.httpserver
  10. import tornado.ioloop
  11. import tornado.options
  12. import tornado.web
  13. from tornado.options import define, options
  14. define("port", default=8080, help="run on the given port", type=int)
  15. PATH=os.path.dirname(os.path.abspath(__file__))
  16. static_path_dir = os.path.join(PATH, 'static/fossil')
  17. data_path_dir = "/mnt/fossils"
  18. class MyHTMLParser(HTMLParser):
  19. def __init__(self):
  20. self.reset()
  21. self.ttype = "p"
  22. self.fed = []
  23. def handle_starttag(self, tag, attrs):
  24. self.ttype = str(tag)
  25. def handle_endtag(self, tag):
  26. self.ttype = "p"
  27. def handle_data(self, data):
  28. self.fed.append({"type": self.ttype,
  29. "text": data.strip()})
  30. def get_data(self):
  31. return self.fed
  32. class Application(tornado.web.Application):
  33. def __init__(self):
  34. handlers = [
  35. (r"/", MainHandler),
  36. (r"/update", UpdateHandler),
  37. (r"/img", ImageHandler),
  38. (r"/download", GenFileStreamerHandler),
  39. (r"/getpage", PageHandler),
  40. #(r'/fossils/static/(.*)', tornado.web.StaticFileHandler, {'path': static_path_dir}),
  41. ]
  42. settings = dict(
  43. template_path=os.path.join(os.path.dirname(__file__), "templates"),
  44. static_path=static_path_dir,
  45. debug=True,
  46. )
  47. tornado.web.Application.__init__(self, handlers, **settings)
  48. class DATA:
  49. def __init__(self, index=None):
  50. self.con = lite.connect('fossil.db')
  51. cur = self.con.cursor()
  52. with self.con:
  53. if index == None:
  54. cur.execute("SELECT * FROM Fossil ORDER BY Name LIMIT 1")
  55. else:
  56. cur.execute("SELECT * FROM Fossil WHERE Name = ?", [index])
  57. data = cur.fetchone()
  58. if data == None:
  59. raise Exception('Database: Data Id ' + str(index) + ' does not exist.')
  60. #self.index = data[0]
  61. print data
  62. self.name = data[0]
  63. parser = MyHTMLParser()
  64. parser.feed(data[1])
  65. self.desc = parser.get_data()
  66. self.size = ("%.2f" % (data[2] / 1000000.0))
  67. self.left_count = data[3]
  68. self.top_count = data[4]
  69. self.front_count = data[5]
  70. self.left_width = data[7]
  71. self.top_width = data[8]
  72. self.front_width = data[9]
  73. #def get_index(self):
  74. # return self.index
  75. def get_name(self):
  76. return self.name
  77. def get_desc(self):
  78. return self.desc
  79. def get_size(self):
  80. return self.size
  81. def get_left_width(self):
  82. return self.left_width
  83. def get_top_width(self):
  84. return self.top_width
  85. def get_front_width(self):
  86. return self.front_width
  87. def get_left_count(self):
  88. return self.left_count
  89. def get_top_count(self):
  90. return self.top_count
  91. def get_front_count(self):
  92. return self.front_count
  93. def slug(self, slug=None):
  94. if slug:
  95. self.slug = slug
  96. else:
  97. self.slug = "The Fossils Data"
  98. return self.slug
  99. def title(self, title=None):
  100. if title:
  101. self.title = title
  102. else:
  103. self.title = """Parasitoid biology preserved in mineralized fossils"""
  104. return self.title
  105. def get_list(self, page=None):
  106. if page == None:
  107. page = 1
  108. page_lower = (page - 1) * 10
  109. page_upper = page_lower + 10
  110. with self.con:
  111. cur = self.con.cursor()
  112. #cur.execute("SELECT * FROM Fossil WHERE Id > 0 AND Id <= 10 ORDER BY Id ASC")
  113. cur.execute("SELECT * FROM Fossil WHERE Id > " + str(page_lower) + " AND Id <= " + str(page_upper) + " ORDER BY Id ASC")
  114. data = cur.fetchall()
  115. tmp_data = []
  116. for i, item in enumerate(data):
  117. parser = MyHTMLParser()
  118. parser.feed(item[1])
  119. tmp_data.append([
  120. item[0],
  121. parser.get_data(),
  122. "%.2f" % (item[2] / 1000000.0),
  123. item[3],
  124. item[4],
  125. item[5],
  126. item[6],
  127. item[7],
  128. item[8],
  129. item[9]
  130. ])
  131. self.data_list = tmp_data
  132. return self.data_list
  133. class PageHandler(tornado.web.RequestHandler):
  134. def get(self):
  135. page = int(self.get_argument("page", 1))
  136. filter_type = self.get_argument("type", "0")
  137. total_item_per_page = 10
  138. self.con = lite.connect('fossil.db')
  139. cur = self.con.cursor()
  140. with self.con:
  141. cur = self.con.cursor()
  142. if filter_type == "0":
  143. cur.execute("SELECT * FROM Fossil ORDER BY Id ASC")
  144. print "0 type"
  145. else:
  146. cur.execute("SELECT * FROM Fossil WHERE Description LIKE '%"+filter_type+"%' ORDER BY Id ASC")
  147. data = cur.fetchall()
  148. total_items = len(data)
  149. for unit in data:
  150. print unit
  151. lower_limit = (page - 1) * 10
  152. upper_limit = lower_limit + 10
  153. if upper_limit > total_items:
  154. upper_limit = total_items
  155. print page, lower_limit, upper_limit
  156. tmp_data = []
  157. for i, item in enumerate(data[lower_limit:upper_limit]):
  158. parser = MyHTMLParser()
  159. parser.feed(item[1])
  160. tmp_data.append([
  161. item[0],
  162. parser.get_data(),
  163. "%.2f" % (item[2] / 1000000.0),
  164. item[3],
  165. item[4],
  166. item[5],
  167. item[6],
  168. item[7],
  169. item[8],
  170. item[9]
  171. ])
  172. output = {}
  173. output["data"] = tmp_data
  174. output["total_items"] = total_items
  175. delta = upper_limit - lower_limit
  176. if delta < 0:
  177. delta = 0
  178. output["total_items_per_page"] = delta
  179. output["total_pages"] = math.ceil(total_items / 10.0)
  180. self.write(output)
  181. class UpdateHandler(tornado.web.RequestHandler):
  182. def get(self):
  183. index = self.get_argument("index", None)
  184. name = self.get_argument("name", None)
  185. print index, name
  186. selected_data = DATA(index)
  187. self.write({
  188. "name": name,
  189. "index": index,
  190. "data_size": selected_data.get_size(),
  191. "desc": selected_data.get_desc(),
  192. "top_count": selected_data.get_top_count(),
  193. "left_count": selected_data.get_left_count(),
  194. "front_count": selected_data.get_front_count()
  195. })
  196. class MainHandler(tornado.web.RequestHandler):
  197. def get(self):
  198. index = self.get_argument("index", None)
  199. print index
  200. data = DATA(index)
  201. print data.get_list()
  202. self.render(
  203. "fossil.html",
  204. slug = data.slug(),
  205. #index = data.get_index(),
  206. name = data.get_name(),
  207. title = data.title(),
  208. data_list = data.get_list(),
  209. desc = data.get_desc(),
  210. data_size = data.get_size(),
  211. left_count = data.get_left_count(),
  212. top_count = data.get_top_count(),
  213. front_count = data.get_front_count(),
  214. left_width = data.get_left_width(),
  215. top_width = data.get_top_width(),
  216. front_width = data.get_front_width()
  217. )
  218. class GenFileStreamerHandler(tornado.web.RequestHandler):
  219. CHUNK_SIZE = 512000
  220. DATA_PATH = data_path_dir
  221. @tornado.web.asynchronous
  222. @tornado.gen.engine
  223. def get(self):
  224. cdid = self.get_argument("did")
  225. print cdid
  226. con = lite.connect('fossil.db')
  227. with con:
  228. cur = con.cursor()
  229. cur.execute("SELECT name FROM Fossil WHERE name = ?", [cdid])
  230. data_key = cur.fetchall()
  231. if len(data_key) > 0:
  232. file_name = str(cdid) + ".zip"
  233. self.path = os.path.join(
  234. self.DATA_PATH,
  235. str(cdid),
  236. file_name)
  237. self.set_header('Content-Type',
  238. 'application/octet-stream')
  239. self.set_header('Content-Disposition',
  240. 'attachment; filename="' + file_name)
  241. self.set_header("Content-Length",
  242. os.path.getsize(self.path))
  243. self.flush()
  244. fd = open(self.path, "rb")
  245. data = fd.read(self.CHUNK_SIZE)
  246. while data:
  247. self.write(data)
  248. yield tornado.gen.Task(self.flush)
  249. data = fd.read(self.CHUNK_SIZE)
  250. fd.close()
  251. self.finish()
  252. class ImageHandler(tornado.web.RequestHandler):
  253. CHUNK_SIZE = 512000
  254. DATA_PATH = data_path_dir
  255. @tornado.web.asynchronous
  256. @tornado.gen.engine
  257. def get(self):
  258. did = self.get_argument("id", None)
  259. dname = self.get_argument("name", None)
  260. dtype = self.get_argument("type", None)
  261. dcounter = self.get_argument("counter", "0").zfill(4)
  262. if dname.split(" ")[0] == "undefined":
  263. self.finish()
  264. return
  265. print did, dname, dtype, dcounter
  266. if dtype == "left" or dtype == "left-resized" or dtype == "left-resized-mini":
  267. prefix = "left"
  268. elif dtype == "top" or dtype == "top-resized" or dtype == "top-resized-mini":
  269. prefix = "top"
  270. elif dtype == "front" or dtype == "front-resized" or dtype == "front-resized-mini":
  271. prefix = "front"
  272. if dtype == "volren":
  273. self.path = os.path.join(
  274. self.DATA_PATH,
  275. dname,
  276. str(dname)+".jpg")
  277. elif dtype == "photo":
  278. self.path = os.path.join(
  279. self.DATA_PATH,
  280. dname,
  281. str(dname)+"_photo.jpg")
  282. else:
  283. self.path = os.path.join(
  284. self.DATA_PATH,
  285. dname,
  286. dtype,
  287. prefix+str(dcounter)+".png")
  288. #print did, dname, dtype, dcounter
  289. #print self.path
  290. self.set_header('Content-Type', 'image/png')
  291. self.set_header("Content-Length",
  292. os.path.getsize(self.path))
  293. self.flush()
  294. fd = open(self.path, "rb")
  295. data = fd.read(self.CHUNK_SIZE)
  296. while data:
  297. self.write(data)
  298. yield tornado.gen.Task(self.flush)
  299. data = fd.read(self.CHUNK_SIZE)
  300. fd.close()
  301. self.finish()
  302. if __name__ == "__main__":
  303. tornado.options.parse_command_line()
  304. http_server = tornado.httpserver.HTTPServer(Application())
  305. http_server.listen(options.port)
  306. tornado.ioloop.IOLoop.instance().start()