Ejemplo n.º 1
0
    def post(self, task):

        if not task.is_type(TaskType.TRANSCRIPTION, TaskType.AUDIO_CHECKING):
            raise InvalidUsage(
                "audio uploads are only available for audio tasks", 400)

        data = MyForm(
            Field("loadManager",
                  is_mandatory=True,
                  validators=[
                      simple_validators.is_dict(),
                  ]),
            Field("isEmpty",
                  is_mandatory=True,
                  validators=[
                      validators.is_bool,
                  ]),
        ).get_data()

        audio_upload = AudioUpload(
            task=task,
            data=data["loadManager"],
            hidden=AudioUpload.get_hidden_flag(data["loadManager"],
                                               data["isEmpty"]),
        )

        db.session.add(audio_upload)
        db.session.commit()
        return {"audioUpload": audio_upload.serialize()}
Ejemplo n.º 2
0
def webservices_available_qualifications():
    data = MyForm(
        Field('userId',
              is_mandatory=True,
              default=lambda: None,
              normalizer=normalize_u),
        Field('languageIds',
              is_mandatory=True,
              default=[],
              normalizer=normalize_l),
    ).get_data(is_json=False, copy=True)
    userId = data['userId']
    languageIds = data['languageIds']

    user = _get_user(userId)
    if not user or not user.isActive:
        raise InvalidUsage('user {} not found or inactive'.format(userId))

    candidates = m.Test.query.filter_by(isEnabled=True).order_by(
        m.Test.testId).all()
    result = Filterable()
    for test in candidates:
        record = TestManager.report_eligibility(test, user, languageIds)
        if record is None:
            continue
        result.append(record)
    return dict(entries=result)
Ejemplo n.º 3
0
def unlock_performance(performance):

    try:
        performance.unlock()
    except ValueError:
        raise InvalidUsage("unable to unlock performance")

    db.session.commit()
    return jsonify(success=True)
Ejemplo n.º 4
0
def move_performance(performance):
    data = MyForm(
        Field("subTaskId",
              is_mandatory=True,
              validators=[
                  SubTask.check_exists,
                  SubTask.for_task(performance.sub_task.task.task_id),
              ]), ).get_data()

    try:
        performance.move_to(data["subTaskId"], AudioCheckingChangeMethod.ADMIN,
                            session["current_user"].user_id)
    except SelfTransition:
        raise InvalidUsage("self transition")

    except LockedPerformance:
        raise InvalidUsage("performance is locked")

    except InvalidTransition:
        raise InvalidUsage("invalid transition")

    db.session.flush()
    return jsonify(performance=Performance.dump(performance))
Ejemplo n.º 5
0
def get_token():

    data = MyForm(
        Field("emailAddress",
              is_mandatory=True,
              validators=[validators.is_string]),
        Field("key", is_mandatory=True, validators=[validators.is_string]),
        Field("secret", is_mandatory=True, validators=[
            validators.is_string,
        ]),
    ).get_data()

    try:
        api_access_pair = ApiAccessPair.query.filter_by(
            key=data["key"], secret=data["secret"]).one()
    except (NoResultFound, MultipleResultsFound):
        raise InvalidUsage("access pair not found", 401)

    if api_access_pair.user.email_address != data["emailAddress"]:
        raise InvalidUsage(
            "incorrect email address for access pair: {0}".format(
                data["emailAddress"]), 401)

    if not api_access_pair.enabled:
        raise InvalidUsage("access pair is disabled", 401)

    access_token, expires_at = create_access_token(
        api_access_pair.user.appen_id)

    current_app.logger.info("access token created for user {0}: {1}".format(
        api_access_pair.user.appen_id, access_token))

    return jsonify({
        "accessToken": access_token,
        "expiresAt": expires_at,
        "appenId": api_access_pair.user.appen_id,
    })
Ejemplo n.º 6
0
def webservices_available_work():
    userId = int(request.values['userID'])

    user = _get_user(userId)
    if not user or not user.isActive:
        raise InvalidUsage('user {} not found or inactive'.format(userId))

    # is_active = lambda subTask: subTask.task.status == m.Task.STATUS_ACTIVE
    # has_supervisor = lambda subTask: len([x for x in subTask.task.supervisors
    # 	if x.receivesFeedback]) > 0
    # pay_rate_set = lambda subTask: bool(
    # 	m.SubTaskRate.query.filter_by(subTaskId=subTask.subTaskId
    # 			).filter(m.SubTaskRate.validFrom<=func.now()
    # 			).order_by(m.SubTaskRate.validFrom.desc()
    # 			).first())
    # has_batch = lambda subTask: bool(
    # 	m.Batch.query.filter_by(subTaskId=subTask.subTaskId
    # 			).filter(m.Batch.userId==None
    # 			).filter(m.Batch.onHold==False
    # 			).order_by(m.Batch.priority.desc()
    # 			).first())
    # candidates = Filterable(m.SubTask.query.filter(m.SubTask.subTaskId.in_(
    # 	SS.query(m.TaskWorker.subTaskId).filter_by(userId=userId
    # 	).filter(m.TaskWorker.removed==False))).all())
    # subTasks = candidates | is_active | has_supervisor | pay_rate_set | has_batch

    candidates = m.SubTask.query.filter(
        m.SubTask.subTaskId.in_(
            SS.query(m.TaskWorker.subTaskId).filter_by(userId=userId).filter(
                m.TaskWorker.removed == False))).all()
    subTasks = []
    for subTask in candidates:
        if subTask.task.status != m.Task.STATUS_ACTIVE:
            continue
        if not [x for x in subTask.task.supervisors if x.receivesFeedback]:
            continue
        if not subTask.currentRate:
            continue
        if not m.Batch.query.filter_by(subTaskId=subTask.subTaskId).filter(
                m.Batch.userId == None).filter(m.Batch.onHold == False).filter(
                    or_(m.Batch.notUserId.is_(None),
                        m.Batch.notUserId != userId)).order_by(
                            m.Batch.priority.desc()).first():
            continue
        subTasks.append(subTask)
    result = map(format_available_work_entry, subTasks)
    return dict(entries=result)
Ejemplo n.º 7
0
def action_assign_task_workers(userIds, taskId):
	subTask = m.SubTask.query.filter_by(taskId=taskId
		).filter(m.SubTask.workType==m.WorkType.WORK
		).order_by(m.subTask.subTaskId).first()
	if not SubTask:
		raise InvalidUsage(_('no sub task found under task {0}'
			).format(taskId))
	for userId in userIds:
		s = m.TaskWorker.query.get((userId, taskId, subTask.subTaskId))
		if not s:
			s = m.TaskWorker(userId=userId, taskId=taskId,
				subTaskId=subTask.subTaskId)
			SS.add(s)
	total = len(userIds)
	message = _('Assigned the user as a worker for task {0}' if total == 1
		else 'Assigned {1} users as workers for task {0}'
		).format(taskId, total)
	url = url_for('views.task_workers', taskId=taskId, _external=True)
	return {'message': message, 'link': url}
Ejemplo n.º 8
0
    def get(self, task):

        if not task.is_type(TaskType.TRANSCRIPTION, TaskType.AUDIO_CHECKING):
            raise InvalidUsage(
                "audio uploads are only available for audio tasks", 400)

        data = MyForm(
            Field("visibleOnly",
                  normalizer=normalizers.to_json,
                  validators=[
                      validators.is_bool,
                  ])).get_data(is_json=False, use_args=True)

        query = AudioUpload.query.filter_by(task=task)

        if data.get("visibleOnly"):
            query = query.filter_by(hidden=False)

        audio_uploads = query.all()
        return {"audioUploads": AudioUpload.dump(audio_uploads)}
Ejemplo n.º 9
0
def webservices_update_payments():
    data = MyForm(
        Field('payroll_id',
              is_mandatory=True,
              normalizer=lambda data, key, value: int(value),
              validators=[
                  check_payroll_existence,
              ]),
        Field(
            'calculated_payments',
            is_mandatory=True,
            normalizer=normalize_calculated_payments,
        ),
        Field(
            'non_calculated_payments',
            is_mandatory=True,
            normalizer=normalize_non_calculated_payments,
        ),
    ).get_data(is_json=False, copy=True)

    payrollId = data['payroll_id']

    updated = set()

    for d in data['calculated_payments']:
        cp = m.CalculatedPayment.query.get(d['calculatedPaymentId'])
        if not cp or cp.payrollId != payrollId:
            continue
        if cp.amount != d['amount']:
            cp.amount = d['amount']
            updated.add(cp.taskId)

    existingByReceiptId = dict([
        (i.identifier, i)
        for i in m.OtherPayment.query.filter_by(payrollId=payrollId)
    ])
    confirmedByReceiptId = dict([(i['identifier'], i)
                                 for i in data['non_calculated_payments']])
    existing = set(existingByReceiptId)
    confirmed = set(confirmedByReceiptId)
    to_delete = existing - confirmed
    to_add = confirmed - existing
    to_update = existing & confirmed
    for i in to_update:
        ncp = existingByReceiptId[i]
        d = confirmedByReceiptId[i]
        if ncp.amount != d['amount']:
            ncp.amount = d['amount']
            updated.add(ncp.taskId)
    for i in to_delete:
        ncp = existingByReceiptId[i]
        updated.add(ncp.taskId)
        SS.delete(ncp)

    taskIds = set([i[0] for i in SS.query(m.Task.taskId)])
    paymentTypeByName = dict([(i.name, i.paymentTypeId)
                              for i in m.PaymentType.query])
    for i in to_add:
        d = confirmedByReceiptId[i]
        user = _get_user(d['userId'])
        if not user:
            raise InvalidUsage(_('user {0} not found').format(d['userId']))
        if d['taskId'] not in taskIds:
            # TODO: raise Error instead of ignoring it
            # raise RuntimeError(_('task {0} not found').format(d['taskId']))
            continue
        paymentTypeId = paymentTypeByName.get(d['paymentType'])
        if paymentTypeId is None:
            raise InvalidUsage(
                _('payment type \'{0}\' not found').format(d['paymentType']))
        ncp = m.OtherPayment(payrollId=payrollId,
                             identifier=d['identifier'],
                             paymentTypeId=paymentTypeId,
                             taskId=d['taskId'],
                             userId=d['userId'],
                             amount=d['amount'])
        updated.add(d['taskId'])
        SS.add(ncp)

    # update impacted entries in t_costperutterance
    if updated:
        for taskId in updated:
            existingRecord = m.TaskPaymentRecord.query.get((taskId, payrollId))
            if existingRecord:
                SS.delete(existingRecord)
            newRecord = calculate_task_payment_record(taskId, payrollId)
            SS.add(newRecord)

    return dict(entries=['success'])
Ejemplo n.º 10
0
def webservices_recent_work():
    userId = int(request.values['userID'])

    user = _get_user(userId)
    if not user or not user.isActive:
        raise InvalidUsage('user {} not found or inactive'.format(userId))

    eventsBySubTaskId = {}
    for ev in m.PayableEvent.query.filter_by(userId=userId).filter(
            m.PayableEvent.calculatedPaymentId == None).order_by(
                m.PayableEvent.created):
        eventsBySubTaskId.setdefault(ev.subTaskId, []).append(ev)

    workIntervalsBySubTaskId = {}
    for subTaskId in eventsBySubTaskId:
        workIntervalsBySubTaskId[subTaskId] = m.WorkInterval.query.filter_by(
            subTaskId=subTaskId).order_by(m.WorkInterval.endTime).all()

    eventsByWorkInterval = {}
    for subTaskId, intervals in workIntervalsBySubTaskId.iteritems():
        #
        # NOTE: do not process payable events of sub tasks that don't
        # have any work intervals
        #
        if not intervals:
            # TODO: notify supervisor to add in intervals
            continue
        events = eventsBySubTaskId[subTaskId]
        receivingInterval = intervals.pop(0)
        #
        # events created before the first interval's start time will be
        # included in the first, events created after the last interval's
        # end time will be included in the last. other events that don't
        # have a corresponding interval will go into the next available
        # interval
        #
        while events:
            event = events.pop(0)
            if not receivingInterval.endTime is None:
                if event.created > receivingInterval.endTime:
                    if intervals:
                        # move to next if available
                        receivingInterval = intervals.pop(0)
            eventsByWorkInterval.setdefault(receivingInterval,
                                            []).append(event)

    taskById = {}
    subTaskById = {}
    result = []
    for interval in sorted(
            eventsByWorkInterval,
            key=lambda i:
        (i.taskId, i.subTaskId, i.endTime.strftime('%Y-%m-%d')
         if i.endTime else '9999-99-99')):
        events = eventsByWorkInterval[interval]
        subTask = subTaskById.setdefault(
            interval.subTaskId, m.SubTask.query.get(interval.subTaskId))
        task = taskById.setdefault(subTask.taskId, subTask.task)
        d = OrderedDict()
        d['weekending'] = (interval.endTime.strftime('%Y-%m-%d')
                           if interval.endTime else None)
        d['task'] = task.displayName
        d['details'] = '{0} ({1})'.format(subTask.name, subTask.workType)
        d['unitspending'] = 0
        d['unitscompleted'] = 0
        d['accuracy'] = None
        d['calcacc'] = None
        d['contact'] = ','.join([str(s.userId) for s in task.supervisors])

        slot = 'unitscompleted' if (
            interval.status
            == m.WorkInterval.STATUS_FINISHED) else 'unitspending'
        if True:  # count by item
            d[slot] += len(events)
        else:
            # TODO: add code to flag events which rawPieceId is None
            rawPieceIds = [
                event.rawPieceId for event in events
                if event.rawPieceId is not None
            ]
            d[slot] += sum([
                r.words for r in map(
                    lambda rawPieceId: m.RawPiece.query.get(rawPieceId),
                    rawPieceIds)
            ])
        result.append(d)
    return dict(entries=result)