Commit 8e96819f authored by Barbora Kompišová's avatar Barbora Kompišová
Browse files

groups & projects relationship

parent 97a7aabd
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -5,3 +5,4 @@ __pycache__/
.pytest_cache/
portal.local.cfg
Pipfile.lock
devel.db
 No newline at end of file

management/commands.py

0 → 100644
+61 −0
Original line number Diff line number Diff line
import click
import logging
from flask import Flask
from flask.cli import AppGroup

from portal import db
from management import data
from management.data import shared
from portal.service.general import find_user

log = logging.getLogger(__name__)

data_cli = AppGroup('data')
users_cli = AppGroup('users')

flask_app: Flask = None


def register_commands(app: Flask):
    global flask_app
    app.cli.add_command(data_cli)
    app.cli.add_command(users_cli)
    flask_app = app
    return app


@data_cli.command('init')
def cli_init_data():
    log.info("[CMD] Initializing data")
    log.debug(f"[CONFIG] DB: {flask_app.config['SQLALCHEMY_DATABASE_URI']}")
    data.init_data(db=db, app=flask_app)


@users_cli.command('create')
@click.argument('name')
def cli_users_create(name):
    with flask_app.app_context():
        log.info(f"[CMD] Create user: {name}")
        password = click.prompt('Password', hide_input=True, confirmation_prompt=True)
        creator = shared.DataCreator(db)
        user = creator.create_user(
            username=name,
            name=name,
            admin=True,
            password=password
            )
        db.session.commit()
        log.info(f"[CMD] Created user: {user}")


@users_cli.command('set-password')
@click.argument('name')
def cli_users_create(name):
    with flask_app.app_context():
        log.info(f"[CMD] Update password for user: {name}")
        password = click.prompt('Password', hide_input=True, confirmation_prompt=True)
        user = find_user(name)
        user.set_password(password=password)
        db.session.add(user)
        db.session.commit()
        log.info(f"[CMD] Updated password for user: {user}")
+5 −4
Original line number Diff line number Diff line
@@ -5,8 +5,9 @@ from management.data.data_dev import init_development_data
from management.data.data_prod import init_prod_data


def init_data(app: Flask, db: SQLAlchemy):
    if app.config.get('PORTAL_ENV', 'dev') == 'prod':
        init_prod_data(app, db)
def init_data(app: Flask, db: SQLAlchemy, env=None):
    env = env
    if env == 'prod':
        init_prod_data(db=db, app=app)
    else:
        init_development_data(app, db)
        init_development_data(db=db, app=app)
+9 −4
Original line number Diff line number Diff line
@@ -12,7 +12,7 @@ def init_development_data(app: Flask, db: SQLAlchemy):
    with app.app_context():
        creator = DataCreator(db)
        # users
        create_stub_users(app, creator, db)
        create_stub_users(app, creator)

        # courses
        cpp = creator.create_course(codename='PB161', name='C++')
@@ -25,6 +25,7 @@ def init_development_data(app: Flask, db: SQLAlchemy):
        c_students = creator.create_group(course=c, name="c_seminar01")
        c_teachers = creator.create_group(course=c, name="c_teachers")


        # projects
        cpp_p1 = creator.create_project(
            course=cpp, name="HW01", config=dict(
@@ -137,6 +138,10 @@ def init_development_data(app: Flask, db: SQLAlchemy):
        cpp_sub_p1_in_progress = Submission(user=student_cpp, project=cpp_p1, parameters="")
        cpp_sub_p1_in_progress.state = SubmissionState.IN_PROGRESS

        # Projects in groups
        cpp_students.projects.append(cpp_p1)
        c_students.projects.append(c_p1)

        db.session.add_all(
            [c_sub1, c_sub2, cpp_sub_p1_cancel, cpp_sub_p1_abort, cpp_sub_p1_finished,
             cpp_sub_p1_in_progress])
@@ -153,11 +158,11 @@ def init_development_data(app: Flask, db: SQLAlchemy):
        db.session.add_all([review])

        # components
        create_stub_components(creator, db)
        create_stub_components(creator)
        db.session.commit()


def create_stub_users(app, creator, db):
def create_stub_users(app, creator):
    creator.create_default_admin_user(app)
    creator.create_user(username='student1', uco=111)
    creator.create_user(username='student2', uco=222)
@@ -167,6 +172,6 @@ def create_stub_users(app, creator, db):
                        name='Teacher Only', uco=1002)


def create_stub_components(creator, db):
def create_stub_components(creator):
    creator.create_component(name='executor')
    creator.create_component(name='processing', type='processing')
+30 −8
Original line number Diff line number Diff line
@@ -171,6 +171,23 @@ class User(db.Model, EntityBase):
        """
        return self.query_permissions_for_course(course=course).all()

    def query_projects_by_course(self, course: 'Course') -> BaseQuery:
        groups = self.get_groups_in_course(course=course)
        pids = []
        for group in groups:
            for p in group.projects:
                pids.append(p.id)

        return Project.query.filter(Project.id.in_(pids))

    def get_projects_by_course(self, course: 'Course') -> List['Project']:
        """Gets projects from the course
        Args:
            course(Course): Course instance
        Returns(List[Project]): filtered list of projects
        """
        return self.query_projects_by_course(course=course).all()

    def __init__(self, uco: int = None, email: str = None, username: str = None,
                 is_admin: bool = False) -> None:
        """Creates user instance
@@ -231,7 +248,7 @@ class Course(db.Model, EntityBase):
        """Gets all users in the course based on their role
        Args:
            role(Role): The role to filter by
        Returns(list[User]): List of users that have the role
        Returns(List[User]): List of users that have the role
        """
        return User.query.join(User.roles) \
            .filter((Role.id == role.id) & (Role.course == self)).all()
@@ -240,18 +257,26 @@ class Course(db.Model, EntityBase):
        """Gets all users in the group
        Args:
            group(Group): The group to find users in
        Returns(list[User]): List of users that are in the group
        Returns(List[User]): List of users that are in the group
        """
        return User.query.join(User.groups) \
            .filter((Group.id == group.id) & (Group.course == self)).all()

    def get_users_by_group_and_role(self, group: 'Group', role: 'Role'):
        """Gets users  filtered by group and role
        Args:
            group(Group): the group to find users in
            role(Role): the role to filter by

        Returns(List[User]:

        """
        return User.query.join(User.groups) \
            .filter((Group.id == group.id) & (Group.course == self)) \
            .join(User.roles).filter((Role.id == role.id) & (Role.course == self)) \
            .all()

    def get_users_filtered(self, groups: List['Group'], roles: List['Role']):  # projects: List['Project']?
    def get_users_filtered(self, groups: List['Group'], roles: List['Role']):
        """Gets all users in the course who are members of at least one of the provided groups and have
        at least one of the specified roles.

@@ -262,17 +287,14 @@ class Course(db.Model, EntityBase):
        Returns: Users in the course that satisfy constraints (are in at least one group AND have at least one role).

        """
        q = Course.query.join(Course.roles).join(Role.users).filter(User.id == self.id)
        q2 = User.query.join(Role.users).join(Course.roles).filter(Role.course_id == self.id)
        q3 = User.query.join(User.roles).join(Role.course)

        query = User.query.join(User.roles).filter(Role.course_id == self.id)
        if roles:
            role_ids = [role.id for role in roles]
            query = query.filter(Role.id.in_(role_ids))
        if groups:
            group_ids = [group.id for group in groups]
            query = query.join(User.groups).filter(Group.id.in_(group_ids)).filter(Group.course_id == self.id)
            query = query.join(User.groups).filter(Group.id.in_(group_ids)).filter(
                Group.course_id == self.id)
        return query.all()


Loading