main.py 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  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"/img", ImageHandler),
  34. (r"/download", GenFileStreamerHandler),
  35. ]
  36. settings = dict(
  37. template_path=os.path.join(os.path.dirname(__file__), "templates"),
  38. static_path="/srv/www/katrin/static",
  39. debug=True,
  40. )
  41. tornado.web.Application.__init__(self, handlers, **settings)
  42. class DATA:
  43. def __init__(self, index=None):
  44. self.con = lite.connect('fossil.db')
  45. cur = self.con.cursor()
  46. with self.con:
  47. if index == None:
  48. cur.execute("SELECT * FROM Fossil ORDER BY Id LIMIT 1")
  49. else:
  50. cur.execute("SELECT * FROM Fossil WHERE Id = ?", [index])
  51. data = cur.fetchone()
  52. if data == None:
  53. raise Exception('Database: Data Id ' + str(index) + ' does not exist.')
  54. self.index = data[0]
  55. self.name = data[1]
  56. parser = MyHTMLParser()
  57. parser.feed(data[2])
  58. self.desc = parser.get_data()
  59. self.size = ("%.2f" % (data[3] / 1000000.0))
  60. def get_index(self):
  61. return self.index
  62. def get_name(self):
  63. return self.name
  64. def get_desc(self):
  65. return self.desc
  66. def get_size(self):
  67. return self.size
  68. def slug(self, slug=None):
  69. if slug:
  70. self.slug = slug
  71. else:
  72. self.slug = "The Fossils Data"
  73. return self.slug
  74. def title(self, title=None):
  75. if title:
  76. self.title = title
  77. else:
  78. self.title = """Preservation of three-dimensional
  79. anatomy in phosphatized fossil arthropods enriches
  80. evolutionary inference"""
  81. return self.title
  82. def get_author(self):
  83. return [
  84. "Achim H Schwermann",
  85. "Tomy dos Santos Rolo",
  86. "Michael S Caterino",
  87. "Günter Bechly",
  88. "Heiko Schmied",
  89. "Tilo Baumbach",
  90. "Thomas van de Kamp"
  91. ]
  92. def get_institute(self):
  93. return [
  94. """Steinmann Institute for Geology, Mineralogy and Paleontology,
  95. University of Bonn, Bonn, Germany""",
  96. """ANKA/Institute for Photon Science and Synchrotron Radiation,
  97. Karlsruhe Institute of Technology, Eggenstein-Leopoldshafen,
  98. Germany""",
  99. """Department of Agricultural and Environmental Sciences, Clemson University,
  100. Clemson, United States""",
  101. """State Museum of Natural History Stuttgart, Stuttgart, Germany""",
  102. """Institute of Crop Science and Resource Conservation, University of Bonn,
  103. Bonn, Germany""",
  104. """Laboratory for Applications of Synchrotron Radiation, Karlsruhe Institute
  105. of Technology, Karlsruhe, Germany"""
  106. ]
  107. def get_list(self):
  108. with self.con:
  109. cur = self.con.cursor()
  110. cur.execute("SELECT * FROM Fossil ORDER BY Id")
  111. data = cur.fetchall()
  112. self.data_list = [ [x[0], x[1]] for x in data]
  113. return self.data_list
  114. class MainHandler(tornado.web.RequestHandler):
  115. def get(self):
  116. index = self.get_argument("index", None)
  117. print index
  118. data = DATA(index)
  119. self.render(
  120. "index.html",
  121. slug = data.slug(),
  122. index = data.get_index(),
  123. name = data.get_name(),
  124. title = data.title(),
  125. authors = data.get_author(),
  126. institutes = data.get_institute(),
  127. data_list = data.get_list(),
  128. desc = data.get_desc(),
  129. data_size = data.get_size()
  130. )
  131. class GenFileStreamerHandler(tornado.web.RequestHandler):
  132. CHUNK_SIZE = 512000
  133. DATA_PATH = "/home/ntj/fossils_for_nicholas"
  134. @tornado.web.asynchronous
  135. @tornado.gen.engine
  136. def get(self):
  137. cdid = self.get_arguments("did")
  138. con = lite.connect('fossil.db')
  139. with con:
  140. cur = con.cursor()
  141. cur.execute("SELECT name FROM Fossil WHERE name = ?", (cdid))
  142. data_key = cur.fetchall()
  143. if len(data_key) > 0:
  144. file_name = str(cdid[0]) + ".zip"
  145. self.path = self.DATA_PATH + str(cdid[0]) + "/" + file_name
  146. self.set_header('Content-Type',
  147. 'application/octet-stream')
  148. self.set_header('Content-Disposition',
  149. 'attachment; filename=' + file_name)
  150. self.set_header("Content-Length",
  151. os.path.getsize(self.path))
  152. self.flush()
  153. fd = open(self.path, "rb")
  154. data = fd.read(self.CHUNK_SIZE)
  155. while data:
  156. self.write(data)
  157. yield tornado.gen.Task(self.flush)
  158. data = fd.read(self.CHUNK_SIZE)
  159. fd.close()
  160. self.finish()
  161. class ImageHandler(tornado.web.RequestHandler):
  162. CHUNK_SIZE = 512000
  163. #DATA_PATH = "/srv/www/katrin/static/fossils_for_nicholas"
  164. DATA_PATH = "/home/ntj/fossils_for_nicholas"
  165. @tornado.web.asynchronous
  166. @tornado.gen.engine
  167. def get(self):
  168. did = self.get_argument("id")
  169. dname = self.get_argument("name")
  170. dtype = self.get_argument("type")
  171. dcounter = self.get_argument("counter").zfill(4)
  172. if dtype == "left" or dtype == "left-resized":
  173. prefix = "left"
  174. elif dtype == "top" or dtype == "top-resized":
  175. prefix = "top"
  176. elif dtype == "front" or dtype == "front-resized":
  177. prefix = "02_quercy_10_merged"
  178. if dtype == "preview":
  179. self.path = os.path.join(
  180. self.DATA_PATH,
  181. dname,
  182. str(dname)+".png")
  183. else:
  184. self.path = os.path.join(
  185. self.DATA_PATH,
  186. dname,
  187. dtype,
  188. prefix+str(dcounter)+".png")
  189. print did, dname, dtype, dcounter
  190. print self.path
  191. self.set_header('Content-Type', 'image/png')
  192. self.set_header("Content-Length",
  193. os.path.getsize(self.path))
  194. self.flush()
  195. fd = open(self.path, "rb")
  196. data = fd.read(self.CHUNK_SIZE)
  197. while data:
  198. self.write(data)
  199. yield tornado.gen.Task(self.flush)
  200. data = fd.read(self.CHUNK_SIZE)
  201. fd.close()
  202. self.finish()
  203. if __name__ == "__main__":
  204. tornado.options.parse_command_line()
  205. http_server = tornado.httpserver.HTTPServer(Application())
  206. http_server.listen(options.port)
  207. tornado.ioloop.IOLoop.instance().start()