models.py 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. import os
  2. import datetime
  3. import hashlib
  4. import flask_whooshalchemyplus
  5. from nova import app, db
  6. from sqlalchemy_utils import PasswordType, force_auto_coercion
  7. from itsdangerous import Signer, BadSignature
  8. force_auto_coercion()
  9. class User(db.Model):
  10. __tablename__ = 'users'
  11. __searchable__ = ['name']
  12. id = db.Column(db.Integer, primary_key=True)
  13. name = db.Column(db.String, unique=True)
  14. email = db.Column(db.String)
  15. fullname = db.Column(db.String)
  16. is_admin = db.Column(db.Boolean, default=False)
  17. password = db.Column(PasswordType(
  18. schemes=['pbkdf2_sha512'],
  19. pbkdf2_sha512__default_rounds=50000,
  20. pbkdf2_sha512__salt_size=16),
  21. nullable=False)
  22. token = db.Column(db.String)
  23. token_time = db.Column(db.DateTime)
  24. gravatar = db.Column(db.String)
  25. first_time = db.Column(db.Boolean, default=True)
  26. def __init__(self, name=None, fullname=None, email=None, password=None, is_admin=False):
  27. self.name = name
  28. self.fullname = fullname
  29. self.email = email
  30. self.password = password
  31. self.is_admin = is_admin
  32. self.gravatar = hashlib.md5(email.lower()).hexdigest()
  33. def __repr__(self):
  34. return '<User(name={}, fullname={}>'.format(self.name, self.fullname)
  35. def get_signer(self):
  36. return Signer(self.password.hash + self.token_time.isoformat())
  37. def generate_token(self):
  38. self.token_time = datetime.datetime.utcnow()
  39. self.token = self.get_signer().sign(str(self.id))
  40. db.session.commit()
  41. def is_token_valid(self, token):
  42. try:
  43. if str(self.id) != self.get_signer().unsign(token):
  44. return False
  45. except BadSignature:
  46. return False
  47. return True
  48. def is_authenticated(self):
  49. return True
  50. def is_active(self):
  51. return True
  52. def is_anonymous(self):
  53. False
  54. def get_id(self):
  55. return self.name
  56. class Dataset(db.Model):
  57. __tablename__ = 'datasets'
  58. __searchable__ = ['name']
  59. id = db.Column(db.Integer, primary_key=True)
  60. type = db.Column(db.String(50))
  61. name = db.Column(db.String)
  62. description = db.Column(db.String)
  63. path = db.Column(db.String)
  64. created = db.Column(db.DateTime, default=datetime.datetime.utcnow)
  65. closed = db.Column(db.Boolean, default=False)
  66. collection_id = db.Column(db.Integer, db.ForeignKey('collections.id'))
  67. has_thumbnail = db.Column(db.Boolean, default=False)
  68. collection = db.relationship('Collection')
  69. accesses = db.relationship('Access', cascade='all, delete, delete-orphan')
  70. __mapper_args__ = {
  71. 'polymorphic_identity': 'dataset',
  72. 'polymorphic_on': type
  73. }
  74. def to_dict(self):
  75. path = os.path.join(app.config['NOVA_ROOT_PATH'], self.path)
  76. return dict(name=self.name, path=path, closed=self.closed)
  77. def __repr__(self):
  78. return '<Dataset(name={}, path={}>'.format(self.name, self.path)
  79. class Taxon(db.Model):
  80. __tablename__ = 'taxons'
  81. id = db.Column(db.Integer, primary_key=True)
  82. name = db.Column(db.String)
  83. def __repr__(self):
  84. return '<Taxon(name={}>'.format(self.name)
  85. class Order(db.Model):
  86. __tablename__ = 'orders'
  87. id = db.Column(db.Integer, primary_key=True)
  88. name = db.Column(db.String)
  89. def __repr__(self):
  90. return '<Order(name={}>'.format(self.name)
  91. class Family(db.Model):
  92. __tablename__ = 'families'
  93. id = db.Column(db.Integer, primary_key=True)
  94. name = db.Column(db.String)
  95. def __repr__(self):
  96. return '<Family(name={}>'.format(self.name)
  97. class Genus(db.Model):
  98. __tablename__ = 'genuses'
  99. id = db.Column(db.Integer, primary_key=True)
  100. name = db.Column(db.String)
  101. def __repr__(self):
  102. return '<Genus(name={}>'.format(self.name)
  103. class SampleScan(Dataset):
  104. __tablename__ = 'samplescans'
  105. __mapper_args__ = {
  106. 'polymorphic_identity': 'samplescan'
  107. }
  108. id = db.Column(db.Integer, db.ForeignKey('datasets.id'), primary_key=True)
  109. taxon_id = db.Column(db.Integer, db.ForeignKey('taxons.id'), nullable=True)
  110. genus_id = db.Column(db.Integer, db.ForeignKey('genuses.id'), nullable=True)
  111. family_id = db.Column(db.Integer, db.ForeignKey('families.id'), nullable=True)
  112. order_id = db.Column(db.Integer, db.ForeignKey('orders.id'), nullable=True)
  113. taxon = db.relationship('Taxon')
  114. genus = db.relationship('Genus')
  115. family = db.relationship('Family')
  116. order = db.relationship('Order')
  117. class Volume(Dataset):
  118. __tablename__ = 'volumes'
  119. __mapper_args__ = {
  120. 'polymorphic_identity': 'volume'
  121. }
  122. id = db.Column(db.Integer, db.ForeignKey('datasets.id'), primary_key=True)
  123. slices = db.Column(db.String)
  124. class Access(db.Model):
  125. __tablename__ = 'accesses'
  126. id = db.Column(db.Integer, primary_key=True)
  127. user_id = db.Column(db.Integer, db.ForeignKey('users.id'))
  128. dataset_id = db.Column(db.Integer, db.ForeignKey('datasets.id'))
  129. owner = db.Column(db.Boolean)
  130. writable = db.Column(db.Boolean)
  131. seen = db.Column(db.Boolean, default=False)
  132. user = db.relationship('User')
  133. dataset = db.relationship('Dataset', back_populates='accesses')
  134. def __repr__(self):
  135. return '<Access(user={}, dataset={}, owner={}, writable={}>'.format(self.user.name, self.dataset.name, self.owner, self.writable)
  136. class Collection(db.Model):
  137. __tablename__ = 'collections'
  138. id = db.Column(db.Integer, primary_key=True)
  139. user_id = db.Column(db.Integer, db.ForeignKey('users.id'))
  140. name = db.Column(db.String)
  141. description = db.Column(db.String)
  142. user = db.relationship('User')
  143. datasets = db.relationship('Dataset', cascade='all, delete, delete-orphan')
  144. def __repr__(self):
  145. return '<Collection(name={})>'.format(self.name)
  146. class Notification(db.Model):
  147. __tablename__ = 'notifications'
  148. id = db.Column(db.Integer, primary_key=True)
  149. message = db.Column(db.String)
  150. user_id = db.Column(db.Integer, db.ForeignKey('users.id'))
  151. user = db.relationship('User')
  152. def __repr__(self):
  153. return '<Notification(user={}, message={})>'.format(self.user.name, self.message)
  154. class Process(db.Model):
  155. __tablename__ = 'processes'
  156. id = db.Column(db.Integer, primary_key=True)
  157. type = db.Column(db.String(50))
  158. task_uuid = db.Column(db.String)
  159. source_id = db.Column(db.Integer, db.ForeignKey('datasets.id'))
  160. destination_id = db.Column(db.Integer, db.ForeignKey('datasets.id'))
  161. source = db.relationship('Dataset', foreign_keys=[source_id])
  162. destination = db.relationship('Dataset', foreign_keys=[destination_id])
  163. __mapper_args__ = {
  164. 'polymorphic_identity': 'process',
  165. 'polymorphic_on': type
  166. }
  167. def __repr__(self):
  168. return '<Process(src={}, dst={})>'.format(self.source.name, self.destination.name)
  169. class Reconstruction(Process):
  170. __tablename__ = 'reconstructions'
  171. __mapper_args__ = {
  172. 'polymorphic_identity': 'reconstruction'
  173. }
  174. id = db.Column(db.Integer, db.ForeignKey('processes.id'), primary_key=True)
  175. flats = db.Column(db.String())
  176. darks = db.Column(db.String())
  177. projections = db.Column(db.String())
  178. output = db.Column(db.String())
  179. flask_whooshalchemyplus.whoosh_index(app, Dataset)
  180. flask_whooshalchemyplus.whoosh_index(app, User)