moved everything to a new module called backend
This commit is contained in:
9
backend/models/__init__.py
Normal file
9
backend/models/__init__.py
Normal file
@@ -0,0 +1,9 @@
|
||||
"""
|
||||
Import all models...
|
||||
"""
|
||||
from backend.models.example_model import *
|
||||
from backend.models.user_model import *
|
||||
from backend.models.post_model import *
|
||||
from backend.models.recorder_model import *
|
||||
from backend.models.room_model import *
|
||||
from backend.models.virtual_command_model import *
|
||||
15
backend/models/example_model.py
Normal file
15
backend/models/example_model.py
Normal file
@@ -0,0 +1,15 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from backend import db
|
||||
import uuid
|
||||
|
||||
|
||||
class ExampleDataItem(db.Model):
|
||||
"""
|
||||
just an example class...
|
||||
"""
|
||||
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
|
||||
mac = db.Column(db.String(32), nullable=False, unique=True, index=True)
|
||||
uuid = db.Column(db.String(36), nullable=False, unique=True, index=True, default=str(uuid.uuid4()))
|
||||
some_string_value = db.Column(db.String, nullable=True, index=True)
|
||||
name = db.Column(db.String(128), default="<not set>", nullable=False, index=True, unique=False)
|
||||
description = db.Column(db.String(4096), nullable=True, unique=False)
|
||||
19
backend/models/post_model.py
Normal file
19
backend/models/post_model.py
Normal file
@@ -0,0 +1,19 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Example post model and related models
|
||||
"""
|
||||
|
||||
from backend import db
|
||||
|
||||
|
||||
class Post(db.Model):
|
||||
"""
|
||||
A post example class
|
||||
"""
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
body = db.Column(db.String(140))
|
||||
timestamp = db.Column(db.DateTime)
|
||||
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
|
||||
|
||||
def __repr__(self):
|
||||
return '<Post %r>' % self.body
|
||||
143
backend/models/recorder_model.py
Normal file
143
backend/models/recorder_model.py
Normal file
@@ -0,0 +1,143 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Models for lecture recorder
|
||||
"""
|
||||
import json
|
||||
|
||||
from sqlalchemy import MetaData
|
||||
from sqlalchemy.ext.hybrid import hybrid_property
|
||||
from sqlalchemy.orm import validates
|
||||
|
||||
from backend import db, app, login_manager
|
||||
import re
|
||||
from sqlalchemy import or_
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
from backend.models.virtual_command_model import virtual_command_recorder_command_table, virtual_command_recorder_table
|
||||
|
||||
metadata = MetaData()
|
||||
|
||||
|
||||
class RecorderModel(db.Model):
|
||||
id = db.Column(db.Integer, autoincrement=True, primary_key=True)
|
||||
created_at = db.Column(db.DateTime, nullable=False, default=datetime.utcnow())
|
||||
last_time_modified = db.Column(db.DateTime, nullable=True, default=None)
|
||||
record_adapter_id = db.Column(db.Unicode(63), unique=True, nullable=False)
|
||||
model_name = db.Column(db.Unicode(63), unique=True, nullable=False)
|
||||
notes = db.Column(db.Unicode(255), unique=False, nullable=True, default=None)
|
||||
recorder_commands = db.relationship('RecorderCommand', back_populates='recorder_model')
|
||||
recorders = db.relationship('Recorder', back_populates='recorder_model')
|
||||
checksum = db.Column(db.String(63), unique=True, nullable=False)
|
||||
_requires_user = db.Column(db.Integer, default=False, name='requires_user')
|
||||
_requires_password = db.Column(db.Integer, default=True, name='requires_password')
|
||||
|
||||
@staticmethod
|
||||
def get_all():
|
||||
return RecorderModel.query.all()
|
||||
|
||||
@staticmethod
|
||||
def get_by_name(name):
|
||||
return RecorderModel.query.filter(RecorderModel.model_name == name).first()
|
||||
|
||||
@staticmethod
|
||||
def get_by_adapter_id(name):
|
||||
return RecorderModel.query.filter(RecorderModel.record_adapter_id == name).first()
|
||||
|
||||
@staticmethod
|
||||
def get_by_checksum(md5_sum):
|
||||
return RecorderModel.query.filter(RecorderModel.checksum == md5_sum).first()
|
||||
|
||||
@hybrid_property
|
||||
def requires_user(self):
|
||||
return self._requires_user > 0
|
||||
|
||||
@requires_user.setter
|
||||
def requires_user(self, val: bool):
|
||||
self._requires_user = 1 if val else 0
|
||||
|
||||
@hybrid_property
|
||||
def requires_password(self):
|
||||
return self._requires_password > 0
|
||||
|
||||
@requires_password.setter
|
||||
def requires_password(self, val: bool):
|
||||
self._requires_password = 1 if val else 0
|
||||
|
||||
|
||||
class Recorder(db.Model):
|
||||
id = db.Column(db.Integer, autoincrement=True, primary_key=True)
|
||||
created_at = db.Column(db.DateTime, nullable=False, default=datetime.utcnow())
|
||||
last_time_modified = db.Column(db.DateTime, nullable=False, default=datetime.utcnow())
|
||||
name = db.Column(db.Unicode(63), unique=True, nullable=False)
|
||||
locked = db.Column(db.Boolean, default=False)
|
||||
lock_message = db.Column(db.String, nullable=True, default=None)
|
||||
offline = db.Column(db.Boolean, default=False)
|
||||
description = db.Column(db.Unicode(255), unique=False, nullable=True, default="")
|
||||
room_id = db.Column(db.Integer, db.ForeignKey('room.id'))
|
||||
room = db.relationship('Room', uselist=False, back_populates='recorder') # one-to-one relation (uselist=False)
|
||||
ip = db.Column(db.String(15), unique=True, nullable=True, default=None)
|
||||
ip6 = db.Column(db.String(46), unique=True, nullable=True, default=None)
|
||||
network_name = db.Column(db.String(127), unique=True, nullable=True, default=None)
|
||||
telnet_port = db.Column(db.Integer, unique=False, nullable=False, default=23)
|
||||
ssh_port = db.Column(db.Integer, unique=False, nullable=False, default=22)
|
||||
username = db.Column(db.String, nullable=True, default=None)
|
||||
password = db.Column(db.String, nullable=True, default=None)
|
||||
recorder_model_id = db.Column(db.Integer, db.ForeignKey('recorder_model.id'))
|
||||
recorder_model = db.relationship('RecorderModel', back_populates='recorders')
|
||||
virtual_commands = db.relationship('VirtualCommand', secondary=virtual_command_recorder_table, back_populates='recorders')
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super(Recorder, self).__init__(**kwargs)
|
||||
|
||||
@staticmethod
|
||||
def get_by_name(name):
|
||||
return Recorder.query.filter(Recorder.name == name).first()
|
||||
|
||||
@staticmethod
|
||||
def get_all():
|
||||
return Recorder.query.all()
|
||||
|
||||
@validates('name')
|
||||
def validate_name(self, key, value):
|
||||
assert len(value) > 2
|
||||
return value
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
def to_dict(self):
|
||||
return dict(id=self.id, name=self.name)
|
||||
|
||||
def toJSON(self):
|
||||
return json.dumps(self.to_dict(), default=lambda o: o.__dict__,
|
||||
sort_keys=True, indent=4)
|
||||
|
||||
|
||||
class RecorderCommand(db.Model):
|
||||
"""Table containing permissions associated with groups."""
|
||||
id = db.Column(db.Integer, autoincrement=True, primary_key=True)
|
||||
created_at = db.Column(db.DateTime, nullable=False, default=datetime.utcnow())
|
||||
last_time_modified = db.Column(db.DateTime, nullable=True, default=None)
|
||||
name = db.Column(db.Unicode(63), unique=True, nullable=False)
|
||||
alternative_name = db.Column(db.Unicode(63), unique=True, nullable=True, default=None)
|
||||
disabled = db.Column(db.Boolean, default=False)
|
||||
description = db.Column(db.Unicode(511), nullable=True, default=None)
|
||||
parameters_string = db.Column(db.String(2047), nullable=True)
|
||||
recorder_model = db.relationship('RecorderModel', back_populates='recorder_commands')
|
||||
recorder_model_id = db.Column(db.Integer, db.ForeignKey('recorder_model.id'))
|
||||
virtual_commands = db.relationship('VirtualCommand', secondary=virtual_command_recorder_command_table,
|
||||
back_populates='recorder_commands')
|
||||
|
||||
@staticmethod
|
||||
def get_all():
|
||||
return RecorderCommand.query.all()
|
||||
|
||||
@property
|
||||
def parameters(self):
|
||||
if self.parameters_string is None:
|
||||
return None
|
||||
return json.loads(self.parameters_string)
|
||||
|
||||
@parameters.setter
|
||||
def parameters(self, parameters_dict: dict):
|
||||
self.parameters_string = json.dumps(parameters_dict)
|
||||
76
backend/models/room_model.py
Normal file
76
backend/models/room_model.py
Normal file
@@ -0,0 +1,76 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Models for lecture recorder
|
||||
"""
|
||||
import json
|
||||
|
||||
from sqlalchemy import MetaData, CheckConstraint
|
||||
from sqlalchemy.exc import IntegrityError
|
||||
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
from backend import db, app, login_manager
|
||||
from backend.tools.scrape_rooms import scrape_rooms
|
||||
|
||||
metadata = MetaData()
|
||||
|
||||
|
||||
class Room(db.Model):
|
||||
id = db.Column(db.Integer, autoincrement=True, primary_key=True)
|
||||
created_at = db.Column(db.DateTime, nullable=False, default=datetime.utcnow())
|
||||
name = db.Column(db.Unicode(127), unique=False, nullable=False)
|
||||
alternate_name = db.Column(db.Unicode(127), unique=False, nullable=True, default=None)
|
||||
comment = db.Column(db.Unicode(2047), unique=False, nullable=True, default="")
|
||||
number = db.Column(db.Unicode(63), unique=False, nullable=True)
|
||||
building_name = db.Column(db.Unicode(63), unique=False, nullable=True)
|
||||
building_number = db.Column(db.Unicode(63), unique=False, nullable=True)
|
||||
|
||||
recorder = db.relationship('Recorder', uselist=False, back_populates='room') # one-to-one relation (uselist=False)
|
||||
|
||||
__table_args__ = (
|
||||
CheckConstraint('length(name) > 2',
|
||||
name='name_min_length'),
|
||||
)
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super(Room, self).__init__(**kwargs)
|
||||
|
||||
@staticmethod
|
||||
def get_by_name(name):
|
||||
"""
|
||||
Find group by name
|
||||
:param name:
|
||||
:return:
|
||||
"""
|
||||
return Room.query.filter(Room.name == name).first()
|
||||
|
||||
@staticmethod
|
||||
def get_all():
|
||||
"""
|
||||
Return all rooms
|
||||
:return:
|
||||
"""
|
||||
return Room.query.all()
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
def to_dict(self):
|
||||
return dict(id=self.id, name=self.name)
|
||||
|
||||
def toJSON(self):
|
||||
return json.dumps(self.to_dict(), default=lambda o: o.__dict__,
|
||||
sort_keys=True, indent=4)
|
||||
|
||||
|
||||
def pre_fill_table():
|
||||
rooms = scrape_rooms()
|
||||
i_tunes_u_mappings = [Room(name=room['name'], number=room['room_number'],
|
||||
building_name=room['building_name'], building_number=room['building_number']) for room in
|
||||
rooms]
|
||||
|
||||
try:
|
||||
db.session.bulk_save_objects(i_tunes_u_mappings)
|
||||
db.session.commit()
|
||||
except IntegrityError as e:
|
||||
db.session.rollback()
|
||||
485
backend/models/user_model.py
Normal file
485
backend/models/user_model.py
Normal file
@@ -0,0 +1,485 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Example user model and related models
|
||||
"""
|
||||
import json
|
||||
|
||||
from sqlalchemy.orm import relation
|
||||
from sqlalchemy import MetaData
|
||||
|
||||
from backend import db, app, login_manager
|
||||
from backend.models.post_model import Post
|
||||
from backend.models.example_model import ExampleDataItem
|
||||
import re
|
||||
import jwt
|
||||
from flask_login import UserMixin
|
||||
from sqlalchemy import or_, event
|
||||
from datetime import datetime, timedelta
|
||||
from passlib.hash import sha256_crypt
|
||||
from hashlib import md5
|
||||
|
||||
|
||||
metadata = MetaData()
|
||||
|
||||
followers = db.Table('followers',
|
||||
db.Column('follower_id', db.Integer, db.ForeignKey('user.id')),
|
||||
db.Column('followed_id', db.Integer, db.ForeignKey('user.id'))
|
||||
)
|
||||
|
||||
acquaintances = db.Table('acquaintances',
|
||||
db.Column('me_id', db.Integer, db.ForeignKey('user.id')),
|
||||
db.Column('acquaintance_id', db.Integer, db.ForeignKey('user.id'))
|
||||
)
|
||||
|
||||
# This is the association table for the many-to-many relationship between
|
||||
# groups and members - this is, the memberships.
|
||||
user_group_table = db.Table('user_group',
|
||||
db.Column('user_id', db.Integer,
|
||||
db.ForeignKey('user.id',
|
||||
onupdate="CASCADE",
|
||||
ondelete="CASCADE"),
|
||||
primary_key=True),
|
||||
db.Column('group_id', db.Integer,
|
||||
db.ForeignKey('group.id',
|
||||
onupdate="CASCADE",
|
||||
ondelete="CASCADE"),
|
||||
primary_key=True))
|
||||
|
||||
|
||||
# This is the association table for the many-to-many relationship between
|
||||
# groups and permissions.
|
||||
group_permission_table = db.Table('group_permission',
|
||||
db.Column('group_id', db.Integer,
|
||||
db.ForeignKey('group.id',
|
||||
onupdate="CASCADE",
|
||||
ondelete="CASCADE"),
|
||||
primary_key=True),
|
||||
db.Column('permission_id', db.Integer,
|
||||
db.ForeignKey('permission.id',
|
||||
onupdate="CASCADE",
|
||||
ondelete="CASCADE"),
|
||||
primary_key=True))
|
||||
|
||||
|
||||
class User(UserMixin, db.Model):
|
||||
"""
|
||||
Example user model representation.
|
||||
"""
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
social_id = db.Column(db.Unicode(63), nullable=True, unique=True)
|
||||
nickname = db.Column(db.Unicode(63), index=True, unique=True)
|
||||
first_name = db.Column(db.Unicode(63), index=True, nullable=True)
|
||||
last_name = db.Column(db.Unicode(63), index=True, nullable=True)
|
||||
email = db.Column(db.String(120), nullable=False, index=True, unique=True)
|
||||
lang = db.Column(db.Unicode(32), index=False, unique=False)
|
||||
timezone = db.Column(db.Unicode(63), index=False, unique=False)
|
||||
posts = db.relationship('Post', backref='author', lazy='dynamic')
|
||||
example_data_item = db.relationship('ExampleDataItem', backref='owner')
|
||||
example_data_item_id = db.Column(db.ForeignKey(ExampleDataItem.id))
|
||||
about_me = db.Column(db.Unicode(255))
|
||||
role = db.Column(db.Unicode(63))
|
||||
groups = db.relationship('Group', secondary=user_group_table, back_populates='users')
|
||||
password = db.Column(db.String(255), nullable=True)
|
||||
registered_on = db.Column(db.DateTime, nullable=False, default=datetime.utcnow())
|
||||
external_user = db.Column(db.Boolean, default=False)
|
||||
last_seen = db.Column(db.DateTime, default=datetime.utcnow())
|
||||
last_time_modified = db.Column(db.DateTime, default=datetime.utcnow())
|
||||
jwt_exp_delta_seconds = db.Column(db.Integer, nullable=True)
|
||||
acquainted = db.relationship('User',
|
||||
secondary=acquaintances,
|
||||
primaryjoin=(acquaintances.c.me_id == id),
|
||||
secondaryjoin=(acquaintances.c.acquaintance_id == id),
|
||||
backref=db.backref('acquaintances', lazy='dynamic'),
|
||||
lazy='dynamic')
|
||||
followed = db.relationship('User',
|
||||
secondary=followers,
|
||||
primaryjoin=(followers.c.follower_id == id),
|
||||
secondaryjoin=(followers.c.followed_id == id),
|
||||
backref=db.backref('followers', lazy='dynamic'),
|
||||
lazy='dynamic')
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super(User, self).__init__(**kwargs)
|
||||
password = kwargs.get("password", None)
|
||||
external_user = kwargs.get("external_user", None)
|
||||
if password is not None:
|
||||
self.password = sha256_crypt.encrypt(password)
|
||||
if external_user is not None:
|
||||
self.external_user = external_user
|
||||
|
||||
@staticmethod
|
||||
@login_manager.user_loader
|
||||
def get_by_identifier(identifier):
|
||||
"""
|
||||
Find user by identifier, which might be the nickname or the e-mail address.
|
||||
:param identifier:
|
||||
:return:
|
||||
"""
|
||||
return User.query.filter(or_(User.nickname == identifier,
|
||||
User.email == identifier,
|
||||
User.id == identifier)).first()
|
||||
|
||||
@staticmethod
|
||||
@login_manager.user_loader
|
||||
def get_by_id(identifier):
|
||||
"""
|
||||
Find user by ID.
|
||||
:param identifier:
|
||||
:return:
|
||||
"""
|
||||
return User.query.filter(User.id == identifier).first()
|
||||
|
||||
@staticmethod
|
||||
def get_all():
|
||||
"""
|
||||
Return all users
|
||||
:return:
|
||||
"""
|
||||
return User.query.all()
|
||||
|
||||
@staticmethod
|
||||
def make_unique_nickname(nickname):
|
||||
"""
|
||||
Add suffix (counter) to nickname in order to get a unique nickname.
|
||||
:param nickname:
|
||||
:return:
|
||||
"""
|
||||
if User.query.filter_by(nickname=nickname).first() is None:
|
||||
return nickname
|
||||
version = 2
|
||||
while True:
|
||||
new_nickname = nickname + str(version)
|
||||
if User.query.filter_by(nickname=new_nickname).first() is None:
|
||||
break
|
||||
version += 1
|
||||
return new_nickname
|
||||
|
||||
@staticmethod
|
||||
def make_valid_nickname(nickname):
|
||||
"""
|
||||
Replaces certain characters (except a-zA-Z0-9_.) in nickname with blancs.
|
||||
:param nickname:
|
||||
:return:
|
||||
"""
|
||||
return re.sub('[^a-zA-Z0-9_.]', '', nickname)
|
||||
|
||||
@classmethod
|
||||
def authenticate(cls, **kwargs):
|
||||
email = kwargs.get('email')
|
||||
password = kwargs.get('password')
|
||||
|
||||
if not email or not password:
|
||||
return None
|
||||
|
||||
user = cls.query.filter_by(email=email).first()
|
||||
if not user or not user.verify_password(password):
|
||||
return None
|
||||
|
||||
return user
|
||||
|
||||
@property
|
||||
def is_authenticated(self):
|
||||
"""
|
||||
Returns true if user is authenticated.
|
||||
:return:
|
||||
"""
|
||||
# TODO: implement correctly
|
||||
return True
|
||||
|
||||
@property
|
||||
def is_active(self):
|
||||
"""
|
||||
Returns true if user is active.
|
||||
:return:
|
||||
"""
|
||||
# TODO: implement correctly
|
||||
return True
|
||||
|
||||
@property
|
||||
def is_anonymous(self):
|
||||
"""
|
||||
Returns true if user is anonymous.
|
||||
:return:
|
||||
"""
|
||||
# TODO: implement correctly
|
||||
return False
|
||||
|
||||
@property
|
||||
def is_read_only(self):
|
||||
"""
|
||||
Returns true if user is active.
|
||||
:return:
|
||||
"""
|
||||
# TODO: implement correctly
|
||||
return True
|
||||
|
||||
@staticmethod
|
||||
def decode_auth_token(auth_token):
|
||||
"""
|
||||
Decodes the auth token
|
||||
:param auth_token:
|
||||
:return: integer|string
|
||||
"""
|
||||
try:
|
||||
payload = jwt.decode(auth_token, app.config.get('SECRET_KEY'))
|
||||
is_blacklisted_token = BlacklistToken.check_blacklist(auth_token)
|
||||
if is_blacklisted_token:
|
||||
return 'Token blacklisted. Please log in again.'
|
||||
else:
|
||||
return payload['sub']
|
||||
except jwt.ExpiredSignatureError:
|
||||
return 'Signature expired. Please log in again.'
|
||||
except jwt.InvalidTokenError:
|
||||
return 'Invalid token. Please log in again.'
|
||||
|
||||
def encode_auth_token(self):
|
||||
"""
|
||||
Generates the Auth Token
|
||||
:return: string
|
||||
"""
|
||||
try:
|
||||
payload = {
|
||||
'exp': datetime.utcnow() + timedelta(days=0, hours=3, seconds=5),
|
||||
'iat': datetime.utcnow(),
|
||||
'sub': self.id
|
||||
}
|
||||
return jwt.encode(
|
||||
payload,
|
||||
app.config.get('SECRET_KEY'),
|
||||
algorithm='HS256'
|
||||
)
|
||||
except Exception as e:
|
||||
return e
|
||||
|
||||
def set_password(self, password):
|
||||
"""
|
||||
SHA256 encrypts the given password and sets it on the user.
|
||||
:param password:
|
||||
:return:
|
||||
"""
|
||||
self.password = sha256_crypt.encrypt(password)
|
||||
|
||||
def verify_password(self, password):
|
||||
"""
|
||||
Verifies that the given password matches the SHA256 encrypted password stored on the user.
|
||||
:param password:
|
||||
:return:
|
||||
"""
|
||||
if self.password is None:
|
||||
return False
|
||||
return sha256_crypt.verify(password, self.password)
|
||||
|
||||
def get_id(self):
|
||||
"""
|
||||
Returns the ID of the user.
|
||||
:return:
|
||||
"""
|
||||
try:
|
||||
# noinspection PyUnresolvedReferences
|
||||
return unicode(self.id) # python 2
|
||||
except NameError:
|
||||
return str(self.id) # python 3
|
||||
|
||||
def avatar(self, size):
|
||||
"""
|
||||
Returns an avatar URL.
|
||||
:param size:
|
||||
:return:
|
||||
"""
|
||||
return 'https://s.gravatar.com/avatar/%s?d=mm&s=%d' % (md5(self.email.encode('utf-8')).hexdigest(), size)
|
||||
|
||||
def acquaint(self, user):
|
||||
"""
|
||||
Adds an acquaintance to the user object.
|
||||
:param user:
|
||||
:return:
|
||||
"""
|
||||
if not self.is_acquainted(user):
|
||||
self.acquainted.append(user)
|
||||
return self
|
||||
|
||||
def unacquaint(self, user):
|
||||
"""
|
||||
Removes the user from the list of acquaintances.
|
||||
:param user:
|
||||
:return:
|
||||
"""
|
||||
if self.is_acquainted(user):
|
||||
self.acquainted.remove(user)
|
||||
return self
|
||||
|
||||
def is_acquainted(self, user):
|
||||
"""
|
||||
Check if the provided user is an acquaintance.
|
||||
:param user:
|
||||
:return:
|
||||
"""
|
||||
return self.acquainted.filter(acquaintances.c.acquaintance_id == user.id).count() > 0
|
||||
|
||||
def get_acquaintances(self):
|
||||
"""
|
||||
Returns the list of acquaintances.
|
||||
:return:
|
||||
"""
|
||||
return User.query.join(acquaintances, (acquaintances.c.acquaintance_id == User.id)).filter(
|
||||
acquaintances.c.me_id == self.id).order_by(User.nickname.desc())
|
||||
|
||||
def shared_example_data_items(self):
|
||||
"""
|
||||
Returns a list of the shared data items.
|
||||
:return:
|
||||
"""
|
||||
return ExampleDataItem.query.join(acquaintances,
|
||||
(acquaintances.c.acquaintance_id == ExampleDataItem.user_id)).filter(
|
||||
acquaintances.c.me_id == self.id).order_by(ExampleDataItem.timestamp.desc())
|
||||
|
||||
def follow(self, user):
|
||||
"""
|
||||
Add user to list of followers.
|
||||
:param user:
|
||||
:return:
|
||||
"""
|
||||
if not self.is_following(user):
|
||||
self.followed.append(user)
|
||||
return self
|
||||
|
||||
def unfollow(self, user):
|
||||
"""
|
||||
Remove user from the list of followers.
|
||||
:param user:
|
||||
:return:
|
||||
"""
|
||||
if self.is_following(user):
|
||||
self.followed.remove(user)
|
||||
return self
|
||||
|
||||
def is_following(self, user):
|
||||
"""
|
||||
Checks if specified user is a follower.
|
||||
:param user:
|
||||
:return:
|
||||
"""
|
||||
return self.followed.filter(followers.c.followed_id == user.id).count() > 0
|
||||
|
||||
def followed_posts(self):
|
||||
"""
|
||||
Returns list of followed posts.
|
||||
:return:
|
||||
"""
|
||||
return Post.query.join(followers, (followers.c.followed_id == Post.user_id)).filter(
|
||||
followers.c.follower_id == self.id).order_by(Post.timestamp.desc())
|
||||
|
||||
def to_dict(self):
|
||||
#return self.__dict__
|
||||
return dict(id=self.id, email=self.email, groups=[g.to_dict() for g in self.groups])
|
||||
|
||||
def toJSON(self):
|
||||
return json.dumps(self.to_dict(), default=lambda o: o.__dict__,
|
||||
sort_keys=True, indent=4)
|
||||
|
||||
def __repr__(self):
|
||||
return '<User %r>' % self.email
|
||||
|
||||
|
||||
class BlacklistToken(db.Model):
|
||||
"""
|
||||
Token Model for storing JWT tokens
|
||||
"""
|
||||
__tablename__ = 'blacklist_tokens'
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
|
||||
token = db.Column(db.String(500), unique=True, nullable=False)
|
||||
blacklisted_on = db.Column(db.DateTime, nullable=False)
|
||||
|
||||
def __init__(self, token):
|
||||
self.token = token
|
||||
self.blacklisted_on = datetime.now()
|
||||
|
||||
def __repr__(self):
|
||||
return '<id: token: {}'.format(self.token)
|
||||
|
||||
@staticmethod
|
||||
def get_by_token(jwt_id):
|
||||
return BlacklistToken.query.filter(BlacklistToken.token == jwt_id).first()
|
||||
|
||||
@staticmethod
|
||||
def check_blacklist(auth_token):
|
||||
"""
|
||||
check whether auth token has been blacklisted
|
||||
:param auth_token:
|
||||
:return:
|
||||
"""
|
||||
res = BlacklistToken.query.filter_by(token=str(auth_token)).first()
|
||||
if res:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
class Group(db.Model):
|
||||
id = db.Column(db.Integer, autoincrement=True, primary_key=True)
|
||||
name = db.Column(db.Unicode(63), unique=True, nullable=False)
|
||||
description = db.Column(db.Unicode(255), unique=False, nullable=True, default="")
|
||||
users = db.relationship('User', secondary=user_group_table, back_populates='groups')
|
||||
permissions = db.relationship('Permission', secondary=group_permission_table, back_populates='groups')
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super(Group, self).__init__(**kwargs)
|
||||
|
||||
|
||||
@staticmethod
|
||||
def get_by_name(name):
|
||||
"""
|
||||
Find group by name
|
||||
:param name:
|
||||
:return:
|
||||
"""
|
||||
return Group.query.filter(Group.name == name).first()
|
||||
|
||||
@staticmethod
|
||||
def get_all():
|
||||
"""
|
||||
Return all groups
|
||||
:return:
|
||||
"""
|
||||
return Group.query.all()
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
def to_dict(self):
|
||||
return dict(id=self.id, name=self.name)
|
||||
|
||||
def toJSON(self):
|
||||
return json.dumps(self.to_dict(), default=lambda o: o.__dict__,
|
||||
sort_keys=True, indent=4)
|
||||
|
||||
|
||||
class Permission(db.Model):
|
||||
"""Table containing permissions associated with groups."""
|
||||
id = db.Column(db.Integer, autoincrement=True, primary_key=True)
|
||||
name = db.Column(db.Unicode(63), unique=True, nullable=False)
|
||||
description = db.Column(db.Unicode(511))
|
||||
groups = db.relationship(Group, secondary=group_permission_table,
|
||||
back_populates='permissions')
|
||||
|
||||
|
||||
@event.listens_for(User.__table__, 'after_create')
|
||||
def insert_initial_users(*args, **kwargs):
|
||||
for u in app.config.get("USERS", []):
|
||||
db.session.add(User(**u))
|
||||
db.session.commit()
|
||||
|
||||
|
||||
@event.listens_for(Group.__table__, 'after_create')
|
||||
def insert_initial_groups(*args, **kwargs):
|
||||
for g in app.config.get("GROUPS", []):
|
||||
db.session.add(Group(**g))
|
||||
db.session.commit()
|
||||
|
||||
|
||||
@event.listens_for(Permission.__table__, 'after_create')
|
||||
def insert_initial_permissions(*args, **kwargs):
|
||||
for p in app.config.get("PERMISSIONS", []):
|
||||
db.session.add(Permission(name=p))
|
||||
db.session.commit()
|
||||
95
backend/models/virtual_command_model.py
Normal file
95
backend/models/virtual_command_model.py
Normal file
@@ -0,0 +1,95 @@
|
||||
import json
|
||||
from datetime import datetime
|
||||
|
||||
from sqlalchemy.ext.hybrid import hybrid_property
|
||||
from sqlalchemy.orm import backref
|
||||
|
||||
from backend import db
|
||||
|
||||
# This is the association table for the many-to-many relationship between
|
||||
# virtual commands and recorder commands.
|
||||
virtual_command_recorder_command_table = db.Table('virtual_command_recorder_command',
|
||||
db.Column('virtual_command_id', db.Integer,
|
||||
db.ForeignKey('virtual_command.id',
|
||||
onupdate="CASCADE",
|
||||
ondelete="CASCADE"),
|
||||
primary_key=True),
|
||||
db.Column('recorder_command_id', db.Integer,
|
||||
db.ForeignKey('recorder_command.id',
|
||||
onupdate="CASCADE",
|
||||
ondelete="CASCADE"),
|
||||
primary_key=True))
|
||||
|
||||
# This is the association table for the many-to-many relationship between
|
||||
# virtual commands and recorder commands.
|
||||
virtual_command_recorder_table = db.Table('virtual_command_recorder',
|
||||
db.Column('virtual_command_id', db.Integer,
|
||||
db.ForeignKey('virtual_command.id',
|
||||
onupdate="CASCADE",
|
||||
ondelete="CASCADE"),
|
||||
primary_key=True),
|
||||
db.Column('recorder_id', db.Integer,
|
||||
db.ForeignKey('recorder.id',
|
||||
onupdate="CASCADE",
|
||||
ondelete="CASCADE"),
|
||||
primary_key=True))
|
||||
|
||||
|
||||
class VirtualCommand(db.Model):
|
||||
id = db.Column(db.Integer, autoincrement=True, primary_key=True)
|
||||
created_at = db.Column(db.DateTime, nullable=False, default=datetime.utcnow())
|
||||
name = db.Column(db.Unicode(63), unique=True, nullable=False)
|
||||
description = db.Column(db.Unicode(255), unique=False, nullable=True, default="")
|
||||
|
||||
recorders = db.relationship('Recorder', secondary=virtual_command_recorder_table,
|
||||
back_populates='virtual_commands')
|
||||
|
||||
recorder_commands = db.relationship('RecorderCommand', secondary=virtual_command_recorder_command_table,
|
||||
back_populates='virtual_commands')
|
||||
|
||||
# parent_virtual_command = db.relationship('VirtualCommand', back_populates='child_virtual_commands')
|
||||
parent_virtual_command_id = db.Column(db.Integer, db.ForeignKey('virtual_command.id'))
|
||||
child_virtual_commands = db.relationship('VirtualCommand',
|
||||
backref=backref('parent_virtual_command', remote_side=[id]))
|
||||
|
||||
command_order_string = db.Column(db.String)
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super(VirtualCommand, self).__init__(**kwargs)
|
||||
|
||||
@staticmethod
|
||||
def get_by_name(name):
|
||||
"""
|
||||
Find group by name
|
||||
:param name:
|
||||
:return:
|
||||
"""
|
||||
return VirtualCommand.query.filter(VirtualCommand.name == name).first()
|
||||
|
||||
@staticmethod
|
||||
def get_all():
|
||||
"""
|
||||
Return all groups
|
||||
:return:
|
||||
"""
|
||||
return VirtualCommand.query.all()
|
||||
|
||||
@hybrid_property
|
||||
def command_order(self):
|
||||
if self.command_order_string is None:
|
||||
return []
|
||||
return json.loads(self.command_order_string)
|
||||
|
||||
@command_order.setter
|
||||
def command_order(self, ordered_list_of_commands: list):
|
||||
self.command_order_string = json.dumps(ordered_list_of_commands)
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
def to_dict(self):
|
||||
return dict(id=self.id, name=self.name, description=self.description)
|
||||
|
||||
def toJSON(self):
|
||||
return json.dumps(self.to_dict(), default=lambda o: o.__dict__,
|
||||
sort_keys=True, indent=4)
|
||||
Reference in New Issue
Block a user