def index():
  assigned_task = []
  author_tasks = []
  author_projects = []
  if session.get('logged_in', None):
    username = session['username']
    assigned_task = list(Task.view('tasks/by_assigned', key = username))
    author_tasks = list(Task.view('tasks/by_author', key = username))
    author_projects = list(Project.view('projects/by_author', key = username))
  return render_template('index.html', assigned_tasks = assigned_task, \
    author_tasks = author_tasks, author_projects = author_projects)
def index():
    assigned_task = []
    author_tasks = []
    author_projects = []
    if session.get('logged_in', None):
        username = session['username']
        assigned_task = list(Task.view('tasks/by_assigned', key=username))
        author_tasks = list(Task.view('tasks/by_author', key=username))
        author_projects = list(Project.view('projects/by_author',
                                            key=username))
    return render_template('index.html', assigned_tasks = assigned_task, \
      author_tasks = author_tasks, author_projects = author_projects)
def edit(id):
  errors = []
  form = EditTaskForm(request.form)
  task = None

  possible_assigned = [elem.username for elem in list(User.view('users/by_username'))]
  possible_project = [elem.title for elem in list (Project.view('projects/by_title'))]
 
  if id == NEW_TASK_ID:
    task = Task()
  else:
    if not g.db.doc_exist(id):
      abort(404)
    task = Task.get(id)
    if request.method == 'GET':
      form = EditTaskForm(obj=task)
  
  form.assigned.choices = zip(possible_assigned, possible_assigned)
  form.project.choices = zip(possible_project, possible_project)
  # dirty hack here: we use referrer to determine from which
  # project we came from and set correct value to select field
  if PROJECT_ROUTE in request.referrer:
    project = request.referrer.split('/')[-1]
    project = Project.get(project_id)
    form.project.default = project.title
    form.process()

  if request.method == 'POST' and form.validate():
    form.populate_obj(task)
    task.author = session['username']
    task.update_date = datetime.datetime.utcnow()
    task.tags = ' '.join(set(task.tags.split()))
    
    if id == NEW_TASK_ID:
      task.create_date = task.update_date

    task.save()
    for ff in request.files.keys():
      f = request.files[ff]
      if f:
        fname = secure_filename(f.filename)
        fld = os.path.join(UPLOADED_FILES, task._id)
        if not os.path.exists(fld):
          os.mkdir(fld)

        target_path = os.path.join(fld, fname)
        while os.path.exists(target_path):
          filename, ext = os.path.splitext(target_path)
          r = ''.join(random.choice('0123456789abcdef') for i in range(8))
          target_path = os.path.join(fld, filename + '-' + r + ext)
        f.save(target_path)
        flash('Successfully uploaded %s' % fname)

    flash('Task was successfully %s' % ('created' if id == NEW_TASK_ID else 'updated'))
    return redirect(url_for('tasks.show', id=task._id))

  errors.extend(format_form_errors(form.errors.items()))
  return render_template('task_edit.html', id = id, form = form, errors = errors)
Exemple #4
0
def test_single_row_restrictions_disabled(c):
    with c.application.app_context():
        task = Task.get()
        office = task.offices[0]

        if Settings.get().single_row:
            c.get('/settings/single_row', follow_redirects=True)

        assert Settings.get().single_row is False

    message = f'flag setting single_row must be disabled'
    contains_message = lambda p: message in c\
        .get(p, follow_redirects=True)\
        .data.decode('utf-8')

    assert contains_message(f'/serial/{task.id}') is False
    assert contains_message('/serial_ra') is False
    assert contains_message(f'/serial_rt/{task.id}') is False
    assert contains_message(f'/touch/1') is False
    assert contains_message(f'/offices/{office.id}') is False
    assert contains_message(f'/office_a') is False
    assert contains_message(f'/office_d/{office.id}') is False
    assert contains_message(f'/office_da') is False
    assert contains_message(f'/task/{task.id}') is False
    assert contains_message(f'/task_d/{task.id}') is False
    assert contains_message(f'/common_task_a') is False
    assert contains_message(f'/task_a/{office.id}') is False
Exemple #5
0
def test_update_common_task_offices(c):
    task = Task.get_first_common()
    unchecked_office = task.offices[0]
    checked_office = task.offices[1]
    unchecked_office_tickets_numbers = [
        ticket.number
        for ticket in Serial.query.filter_by(task_id=task.id,
                                             office_id=unchecked_office.id)
    ]
    old_name = task.name
    new_name = f'{uuid4()}'.replace('-', '')

    c.post(f'/task/{task.id}',
           data={
               'name': new_name,
               f'check{checked_office.id}': True
           },
           follow_redirects=True)

    updated_task = Task.query.filter_by(name=new_name).first()

    assert Task.query.filter_by(name=old_name).first() is None
    assert updated_task is not None
    assert len(task.offices) > len(updated_task.offices)
    assert checked_office.id in ids(updated_task.offices)
    assert unchecked_office.id not in ids(updated_task.offices)

    # Test unchecked office tickets were migrated
    for number in unchecked_office_tickets_numbers:
        ticket = Serial.query.filter_by(number=number).first()

        assert ticket is not None
        assert ticket.office_id != unchecked_office.id
Exemple #6
0
def test_pull_common_task_strict_pulling(_, c):
    with c.application.app_context():
        # NOTE: Finding the proper next common ticket to be pulled
        ticket_to_be_pulled = None
        tickets = Serial.query.order_by(Serial.number)\
                              .filter(Serial.number != 100, Serial.p != True)\
                              .all()

        for ticket in tickets:
            task = Task.get(ticket.task_id)
            office = Office.get(ticket.office_id)

            if task.common:
                ticket_to_be_pulled = ticket
                break

    response = c.get(f'/pull/{task.id}/{office.id}', follow_redirects=True)
    pulled_ticket = Serial.query.filter_by(number=ticket_to_be_pulled.number,
                                           office_id=office.id,
                                           task_id=task.id,
                                           p=True)\
                                .order_by(Serial.number)\
                                .first()

    assert response.status == '200 OK'
    assert pulled_ticket is not None
    assert pulled_ticket.task_id == task.id
    assert pulled_ticket.office_id == office.id
Exemple #7
0
def test_pull_tickets_from_common_task(_, c):
    with c.application.app_context():
        # NOTE: Disabling strict pulling
        settings = Settings.get()
        settings.strict_pulling = False
        db.session.commit()

        task = Task.get_first_common()
        office = choice(task.offices)
        ticket_to_be_pulled = Serial.query.order_by(Serial.number)\
                                          .filter(Serial.number != 100, Serial.p != True,
                                                  Serial.task_id == task.id)\
                                          .first()

    response = c.get(f'/pull/{task.id}/{office.id}', follow_redirects=True)
    pulled_ticket = Serial.query.filter_by(number=ticket_to_be_pulled.number,
                                           office_id=office.id,
                                           task_id=task.id,
                                           p=True)\
                                .order_by(Serial.number)\
                                .first()

    assert response.status == '200 OK'
    assert ticket_to_be_pulled is not None
    assert ticket_to_be_pulled.p is False
    assert pulled_ticket is not None
    assert pulled_ticket.task_id == task.id
    assert pulled_ticket.office_id == office.id
Exemple #8
0
def test_single_row_restrictions_enabled(c):
    task = Task.get()
    office = task.offices[0]

    if not Settings.get().single_row:
        c.get('/settings/single_row', follow_redirects=True)

    assert Settings.get().single_row is True

    message = f'flag setting single_row must be disabled'
    contains_message = lambda p: message in c\
        .get(p, follow_redirects=True)\
        .data.decode('utf-8')

    assert contains_message(f'/serial/{task.id}') is True
    assert contains_message('/serial_ra') is True
    assert contains_message(f'/serial_rt/{task.id}') is True
    assert contains_message(f'/pull_unordered/1/test') is True
    assert contains_message(f'/on_hold/1/test') is True
    assert contains_message(f'/touch/1') is True
    assert contains_message(f'/offices/{office.id}') is True
    assert contains_message(f'/office_a') is True
    assert contains_message(f'/office_d/{office.id}') is True
    assert contains_message(f'/office_da') is True
    assert contains_message(f'/task/{task.id}') is True
    assert contains_message(f'/task_d/{task.id}') is True
    assert contains_message(f'/common_task_a') is True
    assert contains_message(f'/task_a/{office.id}') is True
Exemple #9
0
def show(id):
    if not g.db.doc_exist(id):
        abort(404)

    errors = []
    task = Task.get(id)
    form = CommentForm(request.form)
    comments = list(Comment.view('comments/by_task_id', key=id))
    comments = sorted(comments, key=lambda x: x.date)

    if request.method == 'POST' and form.validate():
        new_comment = Comment()
        new_comment.author = session['username']
        new_comment.text = form.text.data
        new_comment.date = datetime.datetime.utcnow()
        new_comment.task_id = id
        new_comment.save()
        flash('Comment was successfully added')
        return redirect(url_for('tasks.show', id=id))

    fpath = os.path.join(UPLOADED_FILES, id)
    files = None
    if os.path.exists(fpath):
        files = os.listdir(fpath)

    errors.extend(format_form_errors(form.errors.items()))
    return render_template('task_show.html', \
      task = task, comments = comments, form = form, errors = errors, \
      files = files)
def show(id):
  if not g.db.doc_exist(id):
    abort(404)

  errors = []
  task = Task.get(id)
  form = CommentForm(request.form)
  comments = list(Comment.view('comments/by_task_id', key = id))
  comments = sorted(comments, key = lambda x: x.date)

  if request.method == 'POST' and form.validate():
    new_comment = Comment()
    new_comment.author = session['username']
    new_comment.text = form.text.data
    new_comment.date = datetime.datetime.utcnow()
    new_comment.task_id = id
    new_comment.save()
    flash('Comment was successfully added')
    return redirect(url_for('tasks.show', id = id))

  fpath = os.path.join(UPLOADED_FILES, id)
  files = None
  if os.path.exists(fpath):
    files = os.listdir(fpath)

  errors.extend(format_form_errors(form.errors.items()))
  return render_template('task_show.html', \
    task = task, comments = comments, form = form, errors = errors, \
    files = files)
Exemple #11
0
def test_single_row_switch_handler(c):
    single_row(True)

    assert Office.get(0) is not None
    assert [Task.get(0)] == Office.get(0).tasks

    single_row(False)

    assert Office.get(0) is None
Exemple #12
0
def fill_tasks(entry_number=10):
    for _ in range(entry_number):
        name = f'TEST{randint(10000, 99999999)}'
        offices = []
        # First task will be uncommon task
        number_of_offices = 1 if _ == 0 else choice(range(1, 5))

        while number_of_offices > len(offices):
            office = choice(Office.query.all())

            if office not in offices:
                offices.append(office)
        
        task = Task(name)
        db.session.add(task)
        db.session.commit()
        task.offices = offices
        db.session.commit()


# TODO: get refactor the helper to fit the testing process
# def fill_tickets(entery_number=10, s_task=None):
#     for i in range(entery_number):
#         forin = Task.query if s_task is None else Task.query.filter_by(
#             id=s_task)
#         for task in forin:
#             num = Serial.query.order_by(Serial.timestamp.desc()).first()
#             num = num.number if num is not None else None
#             name = choice(names)
#             t_id = task.id
#             f_id = choice(task.offices).id
#             # if i >= 11: WTF ?!
#             db.session.add(Serial(number=num + 1,
#                                     office_id=f_id,
#                                     task_id=t_id, name=name, n=True))
#     for a in range(Waiting.query.count(), 11):
#         for b in Serial.query.filter_by(p=False).order_by(Serial.timestamp):
#             if Waiting.query.filter_by(office_id=b.office_id,
#                                        number=b.number,
#                                        task_id=b.task_id).first() is None:
#                 db.session.add(Waiting(b.number, b.office_id,
#                                        b.task_id, b.name, b.n))
#     db.session.commit()
Exemple #13
0
def single_row(status):
    ''' `single_row` flag setting switch handler.

    Parameters
    ----------
        status: bool
            setting switched to status.
    '''
    office = Office.get(id=0)
    task = Task.get(id=0)

    if status:  # NOTE: Enabled
        office = office or Office.create_generic(id=0)
        task = task or Task.create_generic(id=0)

        task.offices.append(office)
        db.session.commit()
    else:
        office and office.delete_all()
Exemple #14
0
def test_single_row_switch_handler(c):
    with c.application.app_context():
        single_row(True)

        assert Office.get(0) is not None
        assert [Task.get(0)] == Office.get(0).tasks

        single_row(False)

        assert Office.get(0) is None
Exemple #15
0
    def getter():
        tickets = Serial.query.order_by(Serial.number)\
                              .filter(Serial.number != 100, Serial.p != True)\
                              .all()

        for ticket in tickets:
            task = Task.get(ticket.task_id)
            office = Office.get(ticket.office_id)

            if task.common:
                return ticket, office, task
Exemple #16
0
def fill_tasks(entry_number=ENTRY_NUMBER):
    for _ in range(entry_number):
        name = f'TEST{randint(10000, 99999999)}'
        offices = []
        # First task will be uncommon task and the second is common
        number_of_offices = 1 if _ == 0 else 2 if _ == 1 else choice(range(1, 5))

        while number_of_offices > len(offices):
            office = choice(Office.query.all())

            if office not in offices:
                offices.append(office)

        task = Task(name)
        db.session.add(task)
        db.session.commit()
        task.offices = offices
        # Add tasks initial tickets
        db.session.add(Serial(number=100, office_id=office.id, task_id=task.id))
        db.session.commit()
Exemple #17
0
def test_delete_office_after_reset(c):
    office = choice(Office.query.all())
    migrated_common_tasks = [t for t in office.tasks if t.common]

    c.get(f'/serial_r/{office.id}')  # NOTE: reseting office before deleting it
    response = c.get(f'/office_d/{office.id}', follow_redirects=True)

    assert response.status == '200 OK'
    assert Office.query.filter_by(name=office.name).first() is None

    for task in migrated_common_tasks:
        assert Task.get(task.id) is not None
Exemple #18
0
def test_list_tickets(c):
    auth_token = AuthTokens.get()
    response = c.get(BASE,
                     follow_redirects=True,
                     headers={'Authorization': auth_token.token})

    assert response.status == '200 OK'
    assert len(response.json) > 0
    assert LIMIT_PER_CHUNK > len(response.json)

    for t in response.json:
        assert Task.get(t.get('id')) is not None
        assert all(p in t for p in get_module_columns(Task)) is True
Exemple #19
0
def test_list_office_with_common_task(c):
    task = Task.get_first_common()
    office = choice(task.offices)
    tickets = Serial.all_office_tickets(office.id)\
                    .filter(Serial.number != 100)\
                    .order_by(Serial.p, Serial.timestamp.desc())\
                    .limit(10)

    response = c.get(f'/offices/{office.id}', follow_redirects=True)
    page_content = response.data.decode('utf-8')

    assert response.status == '200 OK'

    for ticket in tickets:
        assert f'<b> {office.prefix}{ticket.number}.</b>' in page_content
Exemple #20
0
def show(id):
    if not g.db.doc_exist(id):
        abort(404)

    errors = []
    project = Project.get(id)
    tasks = list(Task.view('tasks/by_project', key=project.title))
    '''
  fpath = os.path.join(UPLOADED_FILES, id)
  files = None
  if os.path.exists(fpath):
    files = os.listdir(fpath)
  '''

    return render_template('project_show.html', \
      project = project, tasks = split_by_priority(tasks), errors = errors)
def show(id):
  if not g.db.doc_exist(id):
    abort(404)

  errors = []
  project = Project.get(id)
  tasks = list(Task.view('tasks/by_project', key = project.title))

  '''
  fpath = os.path.join(UPLOADED_FILES, id)
  files = None
  if os.path.exists(fpath):
    files = os.listdir(fpath)
  '''

  return render_template('project_show.html', \
    project = project, tasks = split_by_priority(tasks), errors = errors)
Exemple #22
0
def test_pull_tickets_from_common_task(_, c):
    settings = Settings.get()
    settings.strict_pulling = False
    db.session.commit()
    task = Task.get_first_common()
    office = choice(task.offices)
    ticket_to_be_pulled = do_until_truthy(
        fill_tickets, lambda: Serial.query.order_by(Serial.number).filter(
            Serial.number != 100, Serial.p != True, Serial.task_id == task.id).
        first())

    response = c.get(f'/pull/{task.id}/{office.id}', follow_redirects=True)
    pulled_ticket = Serial.get(ticket_to_be_pulled.id)

    assert response.status == '200 OK'
    assert ticket_to_be_pulled is not None
    assert ticket_to_be_pulled.p is False
    assert pulled_ticket is not None
    assert pulled_ticket.task_id == task.id
    assert pulled_ticket.office_id == office.id
Exemple #23
0
def test_generate_ticket(c):
    name = 'new testing name'
    task = Task.get()
    office = task.offices[0]
    auth_token = AuthTokens.get()
    response = c.post(f'{BASE}',
                      follow_redirects=True,
                      headers={'Authorization': auth_token.token},
                      json={
                          'name': name,
                          'task_id': task.id,
                          'office_id': office.id
                      })
    ticket = Serial.get(response.json.get('id'))

    assert response.status == '200 OK'
    assert ticket is not None
    assert ticket.name == name
    assert ticket.task_id == task.id
    assert ticket.office_id == office.id
    assert all(p in response.json for p in get_module_columns(Serial)) is True
Exemple #24
0
        def post(self):
            ''' Generate a new ticket. '''
            registered = api.payload.get('n', False)
            name_or_number = api.payload.get('name', None)
            task = Task.get(api.payload.get('task_id', None))
            office = Office.get(api.payload.get('office_id', None))

            if not task:
                abort(message='Task not found', code=HTTPStatus.NOT_FOUND)

            if registered and not name_or_number:
                abort(message='Name must be entered for registered tickets.',
                      code=HTTPStatus.NOT_FOUND)

            ticket, exception = Serial.create_new_ticket(
                task, office, name_or_number)

            if exception:
                abort(message=str(exception))

            return ticket, HTTPStatus.OK
Exemple #25
0
def edit(id):
    errors = []
    form = EditTaskForm(request.form)
    task = None

    possible_assigned = [
        elem.username for elem in list(User.view('users/by_username'))
    ]
    possible_project = [
        elem.title for elem in list(Project.view('projects/by_title'))
    ]

    if id == NEW_TASK_ID:
        task = Task()
    else:
        if not g.db.doc_exist(id):
            abort(404)
        task = Task.get(id)
        if request.method == 'GET':
            form = EditTaskForm(obj=task)

    form.assigned.choices = zip(possible_assigned, possible_assigned)
    form.project.choices = zip(possible_project, possible_project)
    # dirty hack here: we use referrer to determine from which
    # project we came from and set correct value to select field
    if PROJECT_ROUTE in request.referrer:
        project = request.referrer.split('/')[-1]
        project = Project.get(project_id)
        form.project.default = project.title
        form.process()

    if request.method == 'POST' and form.validate():
        form.populate_obj(task)
        task.author = session['username']
        task.update_date = datetime.datetime.utcnow()
        task.tags = ' '.join(set(task.tags.split()))

        if id == NEW_TASK_ID:
            task.create_date = task.update_date

        task.save()
        for ff in request.files.keys():
            f = request.files[ff]
            if f:
                fname = secure_filename(f.filename)
                fld = os.path.join(UPLOADED_FILES, task._id)
                if not os.path.exists(fld):
                    os.mkdir(fld)

                target_path = os.path.join(fld, fname)
                while os.path.exists(target_path):
                    filename, ext = os.path.splitext(target_path)
                    r = ''.join(
                        random.choice('0123456789abcdef') for i in range(8))
                    target_path = os.path.join(fld, filename + '-' + r + ext)
                f.save(target_path)
                flash('Successfully uploaded %s' % fname)

        flash('Task was successfully %s' %
              ('created' if id == NEW_TASK_ID else 'updated'))
        return redirect(url_for('tasks.show', id=task._id))

    errors.extend(format_form_errors(form.errors.items()))
    return render_template('task_edit.html', id=id, form=form, errors=errors)
def add_task(task):
    db = connect_db(app.config.get("DB"))
    Task.set_db(db)
    Project.set_db(db)
    #
    db_task = Task()
    #
    db_project = list(Project.view("projects/by_title", key=task["project"]))[0]

    db_task.author = task["author"]
    db_task.assigned = task["assigned"]
    db_task.priority = task["priority"]
    db_task.title = task["title"]
    db_task.text = task["text"]
    db_task.status = task["status"]
    db_task.project = db_project.title
    db_task.create_date = datetime.datetime.utcnow()
    db_task.update_date = datetime.datetime.utcnow()
    db_task.due_date = datetime.date.today()
    #
    db.save_doc(db_task)
def add_task(task):
    db = connect_db(app.config.get('DB'))
    Task.set_db(db)
    Project.set_db(db)
    #
    db_task = Task()
    #
    db_project = list(Project.view('projects/by_title',
                                   key=task['project']))[0]

    db_task.author = task['author']
    db_task.assigned = task['assigned']
    db_task.priority = task['priority']
    db_task.title = task['title']
    db_task.text = task['text']
    db_task.status = task['status']
    db_task.project = db_project.title
    db_task.create_date = datetime.datetime.utcnow()
    db_task.update_date = datetime.datetime.utcnow()
    db_task.due_date = datetime.date.today()
    #
    db.save_doc(db_task)