Advertisement
Guest User

Untitled

a guest
Jul 12th, 2016
96
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.26 KB | None | 0 0
  1. # Libraries
  2. # Standard library
  3. from datetime import datetime
  4.  
  5. # Third-party libraries
  6. from flask.ext.login import UserMixin, AnonymousUserMixin
  7.  
  8. # Other modules
  9. from lemur import db, login_manager
  10.  
  11. # Association tables for Many-To-Many relationships between various tables
  12. association_table_class_user = db.Table('association_class_user',
  13. db.Column('class_id', db.String(64),
  14. db.ForeignKey('Class.id')),
  15. db.Column('user_id', db.String(64),
  16. db.ForeignKey('User.id')))
  17. association_table_class_lab = db.Table('association_class_lab',
  18. db.Column('class_id', db.String(64),
  19. db.ForeignKey('Class.id')),
  20. db.Column('lab_id', db.String(64),
  21. db.ForeignKey(
  22. 'Lab.id')))
  23. association_table_user_lab = db.Table('association_user_lab',
  24. db.Column('user_id', db.String(64),
  25. db.ForeignKey('User.id')),
  26. db.Column('lab_id', db.String(64),
  27. db.ForeignKey(
  28. 'Lab.id')))
  29. association_table_role_power = db.Table('association_role_power',
  30. db.Column('role_name', db.String(64),
  31. db.ForeignKey('Role.name')),
  32. db.Column('power_id', db.String(64),
  33. db.ForeignKey(
  34. 'Power.id')))
  35.  
  36.  
  37. # set up class to track the date and time information for an object
  38. class DateTimeInfo(object):
  39. created_on = db.Column(db.DateTime, default=datetime.now)
  40. updated_on = db.Column(db.DateTime, default=datetime.now,
  41. onupdate=datetime.now)
  42.  
  43.  
  44. # Store general info of a lab
  45. class Lab(db.Model):
  46. __tablename__ = 'Lab'
  47. id = db.Column(db.String(128), nullable=False, unique=True,
  48. primary_key=True)
  49. name = db.Column(db.String(128), nullable=False)
  50. class_name = db.Column(db.String(128), nullable=False)
  51. prof_name = db.Column(db.String(128), nullable=False)
  52. # lab description contained in description variable
  53. description = db.Column(db.String(4096))
  54. status = db.Column(db.Enum('Activated', 'Downloadable', 'Unactivated',
  55. name='status'))
  56.  
  57. # one-to-many: a lab can have multiple experiments
  58. experiments = db.relationship('Experiment', back_populates='lab',
  59. cascade="all, delete, delete-orphan")
  60. # Many-to-Many: a class can have multiple labs and a lab can have multiple
  61. # classes
  62. classes = db.relationship("Class", secondary=association_table_class_lab,
  63. back_populates="labs")
  64. # Many-to-Many: a user can have multiple labs and a lab can have multiple
  65. # users
  66. users = db.relationship("User", secondary=association_table_user_lab,
  67. back_populates="labs")
  68.  
  69. def __repr__(self):
  70. # Representation of class object in string format
  71. tpl = ('Lab<id: {id}, name: {name}'
  72. ', class_name: {class_name}, prof_name: {prof_name}'
  73. ', description: {description}, status: {status}'
  74. ', experiments: {experiments}, classes: {classes}'
  75. ', users: {users}>')
  76. formatted = tpl.format(id=self.id, name=self.name,
  77. class_name=self.class_name,
  78. prof_name=self.prof_name,
  79. description=self.description,
  80. status=self.status,
  81. experiments=[e.name for e in self.experiments],
  82. classes=[c.name for c in self.classes],
  83. users=[u.name for u in self.users])
  84. return formatted
  85.  
  86.  
  87. # Store experiments' info of a lab
  88. class Experiment(db.Model):
  89. __tablename__ = 'Experiment'
  90. id = db.Column(db.String(128), nullable=False, unique=True,
  91. primary_key=True)
  92. name = db.Column(db.String(512), nullable=False)
  93. description = db.Column(db.String(512))
  94. order = db.Column(db.Integer, nullable=False)
  95. # Type of value expected for this experiment
  96. value_type = db.Column(db.Enum('Number', 'Text', name='value_type'))
  97. # Value range only applies when the type is a number
  98. value_range = db.Column(db.String(64))
  99. # Value candidates only applies when the type is text
  100. value_candidates = db.Column(db.String(512))
  101.  
  102. # Many-to-One: a lab can have multiple experiments
  103. lab_id = db.Column(db.String(128), db.ForeignKey('Lab.id'))
  104. lab = db.relationship("Lab", back_populates="experiments")
  105.  
  106. # one-to-many: a experiment can have multiple data
  107. observations = db.relationship('Observation', back_populates='experiment',
  108. cascade="all, delete, delete-orphan")
  109.  
  110. def __repr__(self):
  111. tpl = ('Lab<id: {id}, name: {name}, description: {description}'
  112. ', order: {order}, value_type: {value_type}'
  113. ', value_range: {value_range}'
  114. ', value_candidates: {value_candidates}'
  115. ', lab_id: {lab_id}, lab:{lab}'
  116. ', observations: {observations}>')
  117. formatted = tpl.format(id=self.id, name=self.name,
  118. description=self.description,
  119. order=self.order,
  120. value_type=self.value_type,
  121. value_range=self.value_range,
  122. value_candidates=self.value_candidates,
  123. lab_id=self.lab_id,
  124. lab=self.lab.name,
  125. observations=[ob.id for ob in self.observations])
  126. return formatted
  127.  
  128.  
  129. # Store data entered by students
  130. class Observation(db.Model, DateTimeInfo):
  131. __tablename__ = 'Observation'
  132. id = db.Column(db.String(128), nullable=False, unique=True,
  133. primary_key=True)
  134. student_name = db.Column(db.String(256), nullable=False)
  135. datum = db.Column(db.String(512), nullable=False)
  136.  
  137. # Many-to-One: an experiment can have mulitple datasets inputted by
  138. # different students
  139. experiment_id = db.Column(db.String(128), db.ForeignKey('Experiment.id'))
  140. experiment = db.relationship("Experiment", back_populates="observations")
  141.  
  142. def __repr__(self):
  143. tpl = ('Observation<experiment_id: {experiment_id}, id: {id},'
  144. 'datum: {datum}>')
  145. formatted = tpl.format(experiment_id=self.experiment_id, id=self.id,
  146. datum=self.datum)
  147. return formatted
  148.  
  149.  
  150. class Class(db.Model):
  151. __tablename__ = 'Class'
  152. id = db.Column(db.String(128), nullable=False, unique=True,
  153. primary_key=True)
  154. name = db.Column(db.String(128), nullable=False)
  155. time = db.Column(db.String(128), nullable=False)
  156. # Many-to-Many: A Class can have multiple users(both professors and
  157. # students)
  158. users = db.relationship("User", secondary=association_table_class_user,
  159. back_populates="classes")
  160. # Many-to-Many: A Class can have multiple labs
  161. labs = db.relationship("Lab", secondary=association_table_class_lab,
  162. back_populates="classes")
  163.  
  164. def __repr__(self):
  165. tpl = ('Class<id: {id}, time: {time}, name: {name}, users: {users},'
  166. 'labs: {labs}>')
  167. formatted = tpl.format(id=self.id, time=self.time,
  168. name=self.name,
  169. users=[u.name for u in self.users],
  170. labs=[lab.name for lab in self.labs])
  171. return formatted
  172.  
  173.  
  174. class User(UserMixin, db.Model):
  175. __tablename__ = 'User'
  176. id = db.Column(db.String(64), nullable=False, unique=True,
  177. primary_key=True)
  178. username = db.Column(db.String(64), nullable=False, unique=True)
  179. password = db.Column(db.String(128), nullable=False)
  180. name = db.Column(db.String(128))
  181. # Many-to-One: A role can have multiple users
  182. role_name = db.Column(db.String(64), db.ForeignKey('Role.name'))
  183. role = db.relationship("Role", back_populates="users")
  184. # Many-to-Many: A User can have multiple classes
  185. classes = db.relationship("Class", secondary=association_table_class_user,
  186. back_populates="users")
  187. # Many-to-Many: A User can have multiple labs
  188. labs = db.relationship("Lab", secondary=association_table_user_lab,
  189. back_populates="users")
  190.  
  191. def verify_password(self, password):
  192. return self.password == password
  193.  
  194. # Return the ids of all the powers a user has
  195. def get_power(self):
  196. return [p.id for p in self.role.powers]
  197.  
  198. # can function checks if user is allowed to peform an operation
  199. def can(self, power):
  200. return self.role is not None and power in self.get_power()
  201.  
  202. def __repr__(self):
  203. tpl = ('User<id: {id}, username: {username}, password: {password},'
  204. ' role: {role_name}, classes: {classes}, labs: {labs}>')
  205. formatted = tpl.format(id=self.id, username=self.username,
  206. password=self.password,
  207. role_name=self.role_name,
  208. classes=[c.id for c in self.classes],
  209. labs=[l.id for l in self.labs])
  210. return formatted
  211.  
  212.  
  213. # Function for use when user is not logged in
  214. class AnonymousUser(AnonymousUserMixin):
  215. def can(self, permissions):
  216. return False
  217. # Associate the LoginManager with the anonymous user class
  218. login_manager.anonymous_user = AnonymousUser
  219.  
  220.  
  221. # Function accepts a user id and returns the user object of that id
  222. @login_manager.user_loader
  223. def load_user(user_id):
  224. return User.query.get(user_id)
  225.  
  226.  
  227. class Role(db.Model):
  228. __tablename__ = 'Role'
  229. name = db.Column(db.String(64), nullable=False, unique=True,
  230. primary_key=True)
  231.  
  232. # Many-to-Many: A Role can have multiple power; a power can belong to
  233. # roles
  234. powers = db.relationship("Power", secondary=association_table_role_power,
  235. back_populates="roles")
  236.  
  237. # One-to-Many: A Role can have multiple users
  238. users = db.relationship('User', back_populates='role', lazy='dynamic')
  239.  
  240. # For database initialization, no object needed to use this method
  241. # Load all the Powers and Roles into the database
  242. @staticmethod
  243. def insert_roles():
  244. for p in Permission.all_permissions():
  245. db.session.add(Power(id=p))
  246. roles = {
  247. 'Student': [Permission.DATA_ENTRY],
  248. 'Admin': [Permission.DATA_ENTRY,
  249. Permission.DATA_EDIT,
  250. Permission.LAB_SETUP,
  251. Permission.ADMIN],
  252. 'SuperAdmin': [Permission.DATA_ENTRY,
  253. Permission.DATA_EDIT,
  254. Permission.LAB_SETUP,
  255. Permission.ADMIN,
  256. Permission.LAB_MANAGE,
  257. Permission.USER_MANAGE,
  258. Permission.SUPERADMIN]
  259. }
  260. for r in roles:
  261. role = Role.query.filter_by(name=r).first()
  262. if role is None:
  263. role = Role(name=r)
  264. for p in roles[r]:
  265. role.powers.append(db.session.query(Power).filter(
  266. Power.id == p).one())
  267. db.session.add(role)
  268. db.session.commit()
  269.  
  270. def __repr__(self):
  271. tpl = ('Role<name: {name},'
  272. ' permissions: {permissions}>')
  273. formatted = tpl.format(name=self.name,
  274. permissions=self.permissions)
  275. return formatted
  276.  
  277.  
  278. class Power(db.Model):
  279. __tablename__ = 'Power'
  280. id = db.Column(db.String(64), nullable=False, unique=True,
  281. primary_key=True)
  282. # Many-to-Many: A Role can have multiple power; a power can belong to
  283. # roles
  284. roles = db.relationship("Role", secondary=association_table_role_power,
  285. back_populates="powers")
  286.  
  287. def __repr__(self):
  288. tpl = ('Power<id: {id}')
  289. formatted = tpl.format(name=self.id)
  290. return formatted
  291.  
  292.  
  293. # A class which consists of all the ids of Power
  294. class Permission:
  295. DATA_ENTRY = 'DATA_ENTRY'
  296. DATA_EDIT = 'DATA_EDIT'
  297. LAB_SETUP = 'LAB_SETUP'
  298. ADMIN = 'ADMIN'
  299. LAB_ACCESS = 'LAB_ACCESS'
  300. LAB_MANAGE = 'LAB_MANAGE'
  301. USER_MANAGE = 'USER_MANAGE'
  302. SUPERADMIN = 'SUPERADMIN'
  303.  
  304. # Return all the permissions as a list
  305. @staticmethod
  306. def all_permissions():
  307. permissions_list = [Permission.DATA_ENTRY,
  308. Permission.DATA_EDIT,
  309. Permission.LAB_SETUP,
  310. Permission.ADMIN,
  311. Permission.LAB_ACCESS,
  312. Permission.LAB_MANAGE,
  313. Permission.USER_MANAGE,
  314. Permission.SUPERADMIN]
  315. return permissions_list
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement