main.py 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. #!/usr/bin/python
  2. # -*- coding: utf-8 -*-
  3. import os
  4. import io
  5. from PIL import Image
  6. from HTMLParser import HTMLParser
  7. import sqlite3 as lite
  8. import tornado.httpserver
  9. import tornado.ioloop
  10. import tornado.options
  11. import tornado.web
  12. from tornado.options import define, options
  13. define("port", default=8000, help="run on the given port", type=int)
  14. PATH=os.path.dirname(os.path.abspath(__file__))
  15. class MyHTMLParser(HTMLParser):
  16. def __init__(self):
  17. self.reset()
  18. self.ttype = "p"
  19. self.fed = []
  20. def handle_starttag(self, tag, attrs):
  21. self.ttype = str(tag)
  22. def handle_endtag(self, tag):
  23. self.ttype = "p"
  24. def handle_data(self, data):
  25. self.fed.append({"type": self.ttype,
  26. "text": data.strip()})
  27. def get_data(self):
  28. return self.fed
  29. class Application(tornado.web.Application):
  30. def __init__(self):
  31. handlers = [
  32. (r"/", MainHandler),
  33. (r"/update", UpdateHandler),
  34. (r"/img", ImageHandler),
  35. (r"/download", GenFileStreamerHandler),
  36. ]
  37. settings = dict(
  38. template_path=os.path.join(os.path.dirname(__file__), "templates"),
  39. static_path="/srv/www/katrin/static",
  40. debug=True,
  41. )
  42. tornado.web.Application.__init__(self, handlers, **settings)
  43. class DATA:
  44. def __init__(self, index=None):
  45. self.con = lite.connect('fossil.db')
  46. cur = self.con.cursor()
  47. with self.con:
  48. if index == None:
  49. cur.execute("SELECT * FROM Fossil ORDER BY Id LIMIT 1")
  50. else:
  51. cur.execute("SELECT * FROM Fossil WHERE Id = ?", [index])
  52. data = cur.fetchone()
  53. if data == None:
  54. raise Exception('Database: Data Id ' + str(index) + ' does not exist.')
  55. self.index = data[0]
  56. self.name = data[1]
  57. parser = MyHTMLParser()
  58. parser.feed(data[2])
  59. self.desc = parser.get_data()
  60. self.size = ("%.2f" % (data[3] / 1000000.0))
  61. self.left_count = data[4]
  62. self.top_count = data[5]
  63. self.front_count = data[6]
  64. def get_index(self):
  65. return self.index
  66. def get_name(self):
  67. return self.name
  68. def get_desc(self):
  69. return self.desc
  70. def get_size(self):
  71. return self.size
  72. def get_left_count(self):
  73. return self.left_count
  74. def get_top_count(self):
  75. return self.top_count
  76. def get_front_count(self):
  77. return self.front_count
  78. def slug(self, slug=None):
  79. if slug:
  80. self.slug = slug
  81. else:
  82. self.slug = "The Fossils Data"
  83. return self.slug
  84. def title(self, title=None):
  85. if title:
  86. self.title = title
  87. else:
  88. self.title = """Preservation of three-dimensional
  89. anatomy in phosphatized fossil arthropods enriches
  90. evolutionary inference"""
  91. return self.title
  92. def get_author(self):
  93. return [
  94. "Achim H Schwermann",
  95. "Tomy dos Santos Rolo",
  96. "Michael S Caterino",
  97. "Günter Bechly",
  98. "Heiko Schmied",
  99. "Tilo Baumbach",
  100. "Thomas van de Kamp"
  101. ]
  102. def get_institute(self):
  103. return [
  104. """Steinmann Institute for Geology, Mineralogy and Paleontology,
  105. University of Bonn, Bonn, Germany""",
  106. """ANKA/Institute for Photon Science and Synchrotron Radiation,
  107. Karlsruhe Institute of Technology, Eggenstein-Leopoldshafen,
  108. Germany""",
  109. """Department of Agricultural and Environmental Sciences, Clemson University,
  110. Clemson, United States""",
  111. """State Museum of Natural History Stuttgart, Stuttgart, Germany""",
  112. """Institute of Crop Science and Resource Conservation, University of Bonn,
  113. Bonn, Germany""",
  114. """Laboratory for Applications of Synchrotron Radiation, Karlsruhe Institute
  115. of Technology, Karlsruhe, Germany"""
  116. ]
  117. def get_list(self):
  118. with self.con:
  119. cur = self.con.cursor()
  120. cur.execute("SELECT * FROM Fossil ORDER BY Id")
  121. data = cur.fetchall()
  122. self.data_list = [ [x[0], x[1]] for x in data]
  123. return self.data_list
  124. class UpdateHandler(tornado.web.RequestHandler):
  125. def get(self):
  126. index = self.get_argument("index", None)
  127. name = self.get_argument("name", None)
  128. print index, name
  129. selected_data = DATA(index)
  130. self.write({
  131. "name": name,
  132. "index": index,
  133. "data_size": selected_data.get_size(),
  134. "desc": selected_data.get_desc(),
  135. "top_count": selected_data.get_top_count(),
  136. "left_count": selected_data.get_left_count(),
  137. "front_count": selected_data.get_front_count()
  138. })
  139. class MainHandler(tornado.web.RequestHandler):
  140. def get(self):
  141. index = self.get_argument("index", None)
  142. print index
  143. data = DATA(index)
  144. self.render(
  145. "index.html",
  146. slug = data.slug(),
  147. index = data.get_index(),
  148. name = data.get_name(),
  149. title = data.title(),
  150. authors = data.get_author(),
  151. institutes = data.get_institute(),
  152. data_list = data.get_list(),
  153. desc = data.get_desc(),
  154. data_size = data.get_size(),
  155. left_count = data.get_left_count(),
  156. top_count = data.get_top_count(),
  157. front_count = data.get_front_count()
  158. )
  159. class GenFileStreamerHandler(tornado.web.RequestHandler):
  160. CHUNK_SIZE = 512000
  161. DATA_PATH = "/home/ntj/fossils_for_nicholas"
  162. @tornado.web.asynchronous
  163. @tornado.gen.engine
  164. def get(self):
  165. cdid = self.get_argument("did")
  166. print cdid
  167. con = lite.connect('fossil.db')
  168. with con:
  169. cur = con.cursor()
  170. cur.execute("SELECT name FROM Fossil WHERE name = ?", [cdid])
  171. data_key = cur.fetchall()
  172. if len(data_key) > 0:
  173. file_name = str(cdid) + ".zip"
  174. self.path = os.path.join(
  175. self.DATA_PATH,
  176. str(cdid),
  177. file_name)
  178. self.set_header('Content-Type',
  179. 'application/octet-stream')
  180. self.set_header('Content-Disposition',
  181. 'attachment; filename="' + file_name)
  182. self.set_header("Content-Length",
  183. os.path.getsize(self.path))
  184. self.flush()
  185. fd = open(self.path, "rb")
  186. data = fd.read(self.CHUNK_SIZE)
  187. while data:
  188. self.write(data)
  189. yield tornado.gen.Task(self.flush)
  190. data = fd.read(self.CHUNK_SIZE)
  191. fd.close()
  192. self.finish()
  193. class ImageHandler(tornado.web.RequestHandler):
  194. CHUNK_SIZE = 512000
  195. #DATA_PATH = "/srv/www/katrin/static/fossils_for_nicholas"
  196. DATA_PATH = "/home/ntj/fossils_for_nicholas"
  197. @tornado.web.asynchronous
  198. @tornado.gen.engine
  199. def get(self):
  200. did = self.get_argument("id")
  201. dname = self.get_argument("name")
  202. dtype = self.get_argument("type")
  203. dcounter = self.get_argument("counter").zfill(4)
  204. if dtype == "left" or dtype == "left-resized" or dtype == "left-resized-mini":
  205. prefix = "left"
  206. elif dtype == "top" or dtype == "top-resized" or dtype == "top-resized-mini":
  207. prefix = "top"
  208. elif dtype == "front" or dtype == "front-resized" or dtype == "front-resized-mini":
  209. prefix = "front"
  210. if dtype == "preview":
  211. self.path = os.path.join(
  212. self.DATA_PATH,
  213. dname,
  214. str(dname)+".png")
  215. else:
  216. self.path = os.path.join(
  217. self.DATA_PATH,
  218. dname,
  219. dtype,
  220. prefix+str(dcounter)+".png")
  221. #print did, dname, dtype, dcounter
  222. #print self.path
  223. self.set_header('Content-Type', 'image/png')
  224. self.set_header("Content-Length",
  225. os.path.getsize(self.path))
  226. self.flush()
  227. fd = open(self.path, "rb")
  228. data = fd.read(self.CHUNK_SIZE)
  229. while data:
  230. self.write(data)
  231. yield tornado.gen.Task(self.flush)
  232. data = fd.read(self.CHUNK_SIZE)
  233. fd.close()
  234. self.finish()
  235. if __name__ == "__main__":
  236. tornado.options.parse_command_line()
  237. http_server = tornado.httpserver.HTTPServer(Application())
  238. http_server.listen(options.port)
  239. tornado.ioloop.IOLoop.instance().start()