def handle_request_invoice(user_id, params):
    plan = params.get('plan', None)
    plan_from_db = db_session_users.query(Plan).filter_by(
        stripe_id=plan).first()
    if not plan_from_db:
        return 'Invalid plan'
    plan_name = plan_from_db.name
    plan_id = plan_from_db.id
    current_user = db_session_users.query(User).filter_by(id=user_id).first()
    message = current_user.first_name + ' ' + current_user.last_name + ' is requesting to pay by invoice for the ' + plan_name + ' subscription. ' + current_user.first_name + ', the team at Compliance.ai will respond to your request soon!'
    try:
        email_helper.send_email(
            '*****@*****.**',
            current_user.email,
            'Invoice request from ' + current_user.first_name,
            template='feedback-inline',
            vars={
                'feedback': message,
                'User_first_name': current_user.first_name,
                'User_last_name': current_user.last_name,
            },
        )
    except SMTPException as e:
        return error_response('Could not send invoice email.', code=500)

    invoice_for_db = {
        'user_id': user_id,
        'plan_id': plan_id,
        'status': 'requested'
    }
    invoice_for_db = Invoice(invoice_for_db)
    db_session_users.add(invoice_for_db)
    db_session_users.commit()
    db_session_users.refresh(invoice_for_db)
    return {'invoice': 'invoice request sent'}
def update_saved_search(user_id, saved_search_id, params):
    name = params.get('name', None)
    name_conflict_user = db_session_users.query(UserSavedSearch).filter_by(
        user_id=user_id, name=name).first()
    if name_conflict_user:
        return jsonify({
            'errors':
            "Saved search name: " + name + " is already being used"
        }), 409

    search_args = params.get('search_args', None)

    saved_search = db_session_users.query(UserSavedSearch).filter_by(
        id=saved_search_id, user_id=user_id).first()

    if not saved_search:
        return jsonify({"errors": "No saved search for this user and id"}), 404

    if name:
        saved_search.name = name
    if search_args:
        saved_search.search_args = search_args

    db_session_users.add(saved_search)
    db_session_users.commit()
    db_session_users.refresh(saved_search)

    return jsonify({"saved_search": saved_search.to_dict()})
示例#3
0
def delete_annotation_task(annotation_task_id, params):
    # n.b. delete_with_annotations flags is intended to make it more difficult to delete tasks that have actual
    # annotations associated with them, the extra flag means users will need to take the extra step before
    # blowing them away
    delete_with_annotations = params[
        'delete_with_annotations'] if 'delete_with_annotations' in params else False
    annotation_task = db_session_users.query(AnnotationTask).filter_by(
        id=annotation_task_id).first()

    if annotation_task.active_task_id is not None:
        old_annotation_tasks = db_session_users.query(
            AnnotationTask).filter_by(active_task_id=annotation_task.id).all()
        all_task_ids = [annotation_task.id
                        ] + [o.id for o in old_annotation_tasks]

        # make sure we do a top-level check for all of the tasks if there are annotations, and return the error
        # if the delete_with_annotations flag is not set
        if db_session_users.query(TopicAnnotation).filter(TopicAnnotation.annotation_task_id.in_(all_task_ids)).count()\
                > 0 and not delete_with_annotations:
            return jsonify({'errors': 'Annotations exist for this task'}), 400

        for old_annotation_task in old_annotation_tasks:
            delete_annotation_task_by_obj(old_annotation_task,
                                          delete_with_annotations)
        delete_annotation_task_by_obj(annotation_task, delete_with_annotations)
    else:
        if db_session_users.query(TopicAnnotation).filter_by(annotation_task_id=annotation_task.id).count() > 0\
                and not delete_with_annotations:
            return jsonify({'errors': 'Annotations exist for this task'}), 400

        delete_annotation_task_by_obj(annotation_task, delete_with_annotations)

    db_session_users.commit()

    return jsonify({"success": True})
def remove_saved_search(user_id, saved_search_id):
    db_session_users.query(UserSavedSearch).filter_by(
        id=saved_search_id, user_id=user_id).delete()
    db_session_users.commit()

    # TODO is it worth validating this?
    return {"deleted": True}
def get_flagged_hidden_documents(user_id, params):
    subquery = db_session_users.query(
        UserFlaggedDocument.doc_id).filter_by(user_id=user_id,
                                              issue_severity="show_now",
                                              status="flagged").subquery()
    documents = db_session_users.query(UserFlaggedDocument).filter_by(
        user_id=user_id, status="hidden").filter(
            UserFlaggedDocument.doc_id.notin_(subquery)).all()

    return jsonify({'hidden_documents': [doc.to_dict() for doc in documents]})
def get_all_annotation_task_groups():
    task_groups = [
        g.to_dict() for g in db_session_users.query(AnnotationTaskTopicGroup)
    ]

    for group in task_groups:
        group['gold_annotator_users'] = [
            u.to_dict() for u in db_session_users.query(User).filter(
                User.id.in_(group['gold_annotator_user_ids'])).all()
        ]

    return {"annotation_task_groups": task_groups}
示例#7
0
def get_annotation_job_by_id(annotation_task_id, annotation_job_id, user_id):
    # n.b. user_id is redundant but this should prevent shenanigans here
    annotation_job = db_session_users.query(AnnotationJob).\
        filter_by(id=annotation_job_id, user_id=user_id).first()

    annotation_job_dict = annotation_job.to_dict()
    # n.b. i deliberately left the user_id restriction here in case future QA tasks might allow super annotators
    # to edit user annotations
    topic_annotations = db_session_users.query(TopicAnnotation).filter_by(annotation_job_id=annotation_job_id)
    annotation_job_dict['topic_annotations'] = [t.to_dict() for t in topic_annotations]

    doc_dict = jsearch.get_record(annotation_job.doc_id)
    return {'annotation_job': annotation_job_dict, 'document': doc_dict}
def get_all_followed_entities(user_id, params):
    if params:
        entity_type = params['entity_type']
        all_entities = db_session_users.query(UserFollowedEntity).filter_by(
            user_id=user_id, entity_type=entity_type, following=True).all()
    else:
        all_entities = db_session_users.query(UserFollowedEntity).filter_by(
            user_id=user_id, following=True).all()

    return {
        "followed_entities": [
            merge_two_dicts(e.to_dict(), get_entity_from_es(e))
            for e in all_entities
        ]
    }
def get_all_created_documents(params):
    query = db_session_users.query(UserCreatedDocument)
    if 'user_id' in params:
        query = query.filter_by(user_id=params['user_id'])
    if 'status' in params:
        query = query.filter_by(status=params['status'])
    return {"user_created_documents": [d.to_dict() for d in query]}
示例#10
0
def create_review_for_job(annotation_task_id, annotation_job_id, user_id, params):
    annotation_job = db_session_users.query(AnnotationJob).filter_by(id=annotation_job_id).first()
    annotation_job.status = AnnotationJob.COMPLETE_STATUS
    annotation_job.completed_at = datetime.datetime.now()
    db_session_users.add(annotation_job)
    db_session_users.commit()
    db_session_users.refresh(annotation_job)
    job = annotation_job.to_dict()
    doc = None

    if 'multiple_field' in params:
        multiple_field = params.get('multiple_field', None)
        flagged_doc = UserFlaggedDocument({
            'user_id': user_id,
            'doc_id': annotation_job.doc_id,
            'issue_type': UserFlaggedDocument.CONTRIBUTOR_ISSUE_TYPE,
            'multiple_field': multiple_field
        })

        db_session_users.add(flagged_doc)
        db_session_users.commit()
        db_session_users.refresh(flagged_doc)
        doc = flagged_doc.to_dict()

    return {"annotation_job": job, "flagged_doc": doc}
示例#11
0
def create_annotation_task(params):
    new_annotation_task = AnnotationTask(params)
    term_sampling_group_ids = params.get("term_sampling_group_ids", None)

    # FIXME: enforcing default values until the front-end has been updated to provide this explicitly
    if new_annotation_task.type is None:
        new_annotation_task.type = AnnotationTask.TOPIC_ANNOTATION_TYPE
    elif new_annotation_task.type == 'contributor':
        new_annotation_task.is_contributor_task = True

    db_session_users.add(new_annotation_task)
    db_session_users.commit()
    db_session_users.refresh(new_annotation_task)

    if term_sampling_group_ids is not None:
        for term_sampling_group_id in term_sampling_group_ids:
            attsg = AnnotationTaskTermSamplingGroup({
                'annotation_task_id':
                new_annotation_task.id,
                'term_sampling_group_id':
                term_sampling_group_id
            })
            db_session_users.add(attsg)
        db_session_users.commit()

    task_dict = new_annotation_task.to_dict()
    term_sampling_group_ids = db_session_users.query(AnnotationTaskTermSamplingGroup.term_sampling_group_id) \
        .filter_by(annotation_task_id=new_annotation_task.id)
    task_dict["term_sampling_group_ids"] = [
        t[0] for t in term_sampling_group_ids
    ]

    return {"annotation_task": task_dict}
示例#12
0
def get_annotation_jobs_for_task(annotation_task_id, params):
    base_query = db_session_users.query(AnnotationJob).filter_by(annotation_task_id=annotation_task_id)

    if 'status' in params:
        base_query = base_query.filter_by(status=params['status'])

    if 'type' in params:
        base_query = base_query.filter_by(status=params['type'])

    # get the total number of annotation jobs before the limit+offset breakdown
    job_count_total = base_query.count()

    if 'count_only' in params:
        return {'total': job_count_total}

    # n.b. allows pagination
    if 'offset' in params:
        base_query = base_query.offset(params['offset'])

    # n.b. 20 seems a reasonable default limit
    limit = params.get('limit', 20)
    base_query = base_query.limit(limit)

    annotation_jobs = [aj.to_dict({'topic_annotation_count': True}) for aj in base_query]

    return {'annotation_jobs': annotation_jobs, 'total': job_count_total}
def get_all_saved_searches(user_id):
    all_searches = db_session_users.query(UserSavedSearch).filter_by(
        user_id=user_id).all()
    return {
        "saved_searches":
        [get_decorated_saved_search(s) for s in all_searches]
    }
def updated_followed_entity(user_id, params):
    entities = params['entities']
    followed_entities = []

    for entity in entities:
        entity_id = entity['entity_id']
        entity_type = entity['entity_type']
        following = entity['following']

        followed_entity = db_session_users.query(UserFollowedEntity).filter_by(
            entity_id=entity_id, entity_type=entity_type,
            user_id=user_id).first()

        if not followed_entity:
            followed_entity = UserFollowedEntity({
                'entity_id': entity_id,
                'entity_type': entity_type,
                'user_id': user_id
            })

        followed_entity.following = following
        followed_entities.append(followed_entity)

    db_session_users.add_all(followed_entities)
    db_session_users.commit()

    return {
        "followed_entities": [
            merge_two_dicts(e.to_dict(), get_entity_from_es(e))
            for e in followed_entities
        ]
    }
def get_topic_annotation_breakdown_for_task(annotation_task_id, params):
    # fetch all previous incarnations of this task, so they can be included in statistics
    all_task_ids = [
        t[0] for t in db_session_users.query(AnnotationTask.id).filter_by(active_task_id=annotation_task_id).distinct().all()
    ]
    all_task_ids.append(annotation_task_id)

    # get annotation counts for user_id / is_positive pairings
    base_query = db_session_users.query(TopicAnnotation.user_id, TopicAnnotation.is_positive, func.count(TopicAnnotation.user_id))\
            .filter(TopicAnnotation.annotation_task_id.in_(all_task_ids))

    if 'to_date' in params and 'from_date' in params:
        base_query = base_query.filter(TopicAnnotation.created_at > params['from_date'])\
            .filter(TopicAnnotation.created_at < params['to_date'])
    elif 'from_date' in params:
        base_query = base_query.filter(TopicAnnotation.created_at > params['from_date'])
    elif 'to_date' in params:
        base_query = base_query.filter(TopicAnnotation.created_at < params['to_date'])

    all_counts = base_query.group_by(TopicAnnotation.user_id).group_by(TopicAnnotation.is_positive).all()

    # user_id -> email mapping for response
    user_ids = list(set([r[0] for r in all_counts]))
    user_result = db_session_users.query(User.id, User.email).filter(User.id.in_(user_ids)).all()
    user_id_email_map = {u[0]: u[1] for u in user_result}

    # get all skipped annotations
    all_skipped = db_session_users.query(AnnotationJob.user_id, func.count(AnnotationJob.user_id)).filter_by(was_skipped=True)\
    .group_by(AnnotationJob.user_id).all()
    user_id_total_skipped_map = {s[0]: s[1] for s in all_skipped}

    # build the structure of the actual response
    result = defaultdict(dict)
    totals = {"positive": 0, "negative": 0}
    for user_id, is_positive, num_annotations in all_counts:
        user_email = user_id_email_map[user_id]
        polarity = "positive" if is_positive else "negative"
        result[user_email][polarity] = num_annotations
        totals[polarity] += num_annotations
        # add number of skipped docs
        if user_id in user_id_total_skipped_map:
            result[user_email]["skipped"] = user_id_total_skipped_map[user_id]
        else:
            result[user_email]["skipped"] = 0

    result["total"] = totals
    return result
def update_subscription(subscription_id, params):
    original_subscription = db_session_users.query(Subscription).filter_by(
        id=subscription_id).first()
    new_subscription_dict = original_subscription.__dict__
    today = datetime.datetime.utcnow()
    new_subscription_dict['latest'] = True
    new_subscription_dict['notes'] = None

    if 'expiration_date' in params:
        new_exiration_date = params['expiration_date']
        new_exiration_date_obj = datetime.datetime.strptime(
            new_exiration_date, "%Y-%m-%d")
        new_subscription_dict['expiration_date'] = new_exiration_date_obj
        # update status of subscription depending on new expiration date
        if new_exiration_date_obj < today or new_exiration_date_obj.date(
        ) == today.date():
            new_subscription_dict[
                'status_reason'] = Subscription.EXPIRED_STATUS_REASON
            new_subscription_dict['status'] = Subscription.INACTIVE_STATUS
        elif new_subscription_dict['status'] != Subscription.ACTIVE_STATUS:
            new_subscription_dict[
                'status_reason'] = Subscription.REACTIVATED_STATUS_REASON
            new_subscription_dict['status'] = Subscription.ACTIVE_STATUS

    if 'plan_id' in params:
        new_plan_id = params['plan_id']
        plan = db_session_users().query(Plan).filter_by(id=new_plan_id).first()
        if plan:
            new_subscription_dict['plan_id'] = new_plan_id
            new_subscription_dict['stripe_id'] = plan.stripe_id
            new_subscription_dict['start_date'] = datetime.datetime.utcnow()
            new_subscription_dict[
                'status_reason'] = Subscription.REACTIVATED_STATUS_REASON
            new_subscription_dict['status'] = Subscription.ACTIVE_STATUS
            if plan.recurring:
                new_subscription_dict['expiration_date'] = None
            else:
                new_subscription_dict[
                    'expiration_date'] = get_default_expiration_date(plan)
        else:
            return {'errors': "Plan is not found"}

    if 'payment_type' in params:
        new_subscription_dict['payment_type'] = params['payment_type']
    if 'notes' in params:
        new_subscription_dict['notes'] = params['notes']

    new_subscription_dict['modified_by_user_id'] = g.user_id

    new_subscription = Subscription(new_subscription_dict)
    db_session_users.add(new_subscription)

    # deactivate old subscription
    deactivate_subscriptions(new_subscription_dict['user_id'])

    db_session_users.commit()
    db_session_users.refresh(new_subscription)

    return {'new_subscription': new_subscription.to_dict()}
def get_all_plans():
    plans = db_session_users.query(Plan).values(Plan.id, Plan.name)

    results = []
    for plan_id, plan_name in plans:
        results.append({'id': plan_id, 'name': plan_name})

    return {'all_plans': results}
示例#18
0
def get_marketing_campaign_details(marketing_campaign_id):
    marketing_campaign = db_session_users.query(MarketingCampaign).filter_by(
        id=marketing_campaign_id).first()
    marketing_campaign_details = marketing_campaign.to_dict()
    marketing_campaign_details['users'] = [
        u.to_dict() for u in marketing_campaign.users
    ]
    return {"marketing_campaign": marketing_campaign_details}
示例#19
0
def get_all_annotation_tasks(user_id,
                             params,
                             is_qa_user=False,
                             is_contributor_user=False):
    tasks = []
    # n.b. notin_ omits cases where type is null
    annotation_task_query = db_session_users.query(AnnotationTask).filter(AnnotationTask.active_task_id == None)\
        .filter(or_(AnnotationTask.type.notin_(TASK_TYPES_TO_SKIP), AnnotationTask.type == None))
    annotation_type = params.get("type", None)

    if is_qa_user:
        annotation_task_query = annotation_task_query.filter(
            AnnotationTask.user_ids.any(user_id))

    if is_contributor_user:
        # n.b. using is_contributor_task=True is not required right now for topic annotation type tasks
        # TODO? should this be required in the future?
        if annotation_type == 'topic_annotation':
            annotation_task_query = annotation_task_query.filter(
                AnnotationTask.user_ids.any(user_id))
            annotation_task_query = annotation_task_query.filter_by(
                type=annotation_type)
        else:
            annotation_task_query = annotation_task_query.filter_by(
                is_contributor_task=True)

            # FIXME use queries on the specific type moving forward (type filter on document_review or topic_annotation)
            annotation_task_query = annotation_task_query.filter_by(
                type='contributor')

    for task in annotation_task_query.order_by(AnnotationTask.name):
        task_dict = task.to_dict()
        task_dict["old_tasks"] = [
            t.to_dict()
            for t in db_session_users.query(AnnotationTask).filter_by(
                active_task_id=task.id)
        ]
        term_sampling_group_ids = db_session_users.query(AnnotationTaskTermSamplingGroup.term_sampling_group_id)\
            .filter_by(annotation_task_id=task.id)
        task_dict["term_sampling_group_ids"] = [
            t[0] for t in term_sampling_group_ids
        ]
        tasks.append(task_dict)

    return {"annotation_tasks": tasks}
def subscribe_users_to_plan(user_ids,
                            plan_stripe_id,
                            payment_type=None,
                            modified_by_user_id=None):
    if not (payment_type == 'invoice' or payment_type == 'stripe'
            or payment_type == None):
        return 'please use a valid payment_type'
    for user_id in user_ids:
        user = db_session_users.query(User).filter_by(id=user_id).first()
        if user is None:
            return "user doesn't exist"
        plan = db_session_users.query(Plan).filter_by(
            stripe_id=plan_stripe_id).first()
        if plan is None:
            return 'please use a valid plan'
        subscription_for_db = {
            'user_id': user_id,
            'stripe_id': plan.stripe_id,
            'plan_id': plan.id,
            'latest': True,
            'start_date': datetime.datetime.utcnow(),
            'status': 'active'
        }
        if modified_by_user_id is not None:
            subscription_for_db['modified_by_user_id'] = modified_by_user_id
        if payment_type == 'invoice' or payment_type == 'invoice':
            subscription_for_db['payment_type'] = payment_type
        else:
            # currently only free_trials have exiration dates.  all other plans are recurring
            subscription_for_db[
                'expiration_date'] = get_default_expiration_date(plan)

        try:
            deactivate_subscriptions(user_id)
        except:
            return 'unable to deactivate existing subscriptions'
        try:
            subscription_for_db = Subscription(subscription_for_db)
            db_session_users.add(subscription_for_db)
            db_session_users.commit()
        except:
            return 'unable to post subscription to database'
def deactivate_subscriptions(user_id):
    # a user should have only 1 current subscription at a time
    latest_subscriptions = db_session_users.query(Subscription).filter_by(
        user_id=user_id, latest=True).all()
    if latest_subscriptions is not None:
        for latest_subscription in latest_subscriptions:
            latest_subscription.latest = False
            latest_subscription.status = Subscription.INACTIVE_STATUS
            latest_subscription.end_date = datetime.datetime.utcnow()
            db_session_users.add(latest_subscription)
            db_session_users.commit()
            db_session_users.refresh(latest_subscription)
def get_subscriptions(user_id):
    subscriptions = db_session_users.query(Subscription).filter_by(
        user_id=user_id).join(Plan, Subscription.plan_id == Plan.id).values(
            Subscription.created_at, Subscription.latest, Subscription.user_id,
            Subscription.payment_type, Subscription.start_date,
            Subscription.end_date, Subscription.status,
            Subscription.period_count, Subscription.expiration_date, Plan.name,
            Plan.category, Plan.stripe_id, Plan.price, Plan.price_period)

    stripe_subscription = db_session_users.query(Subscription).filter_by(
        user_id=user_id, payment_type='stripe', latest=True).first()
    if stripe_subscription:
        stripe_sub = stripe.Subscription.retrieve(
            stripe_subscription.stripe_id)
        next_bill_date = stripe_sub['current_period_end']

    else:
        next_bill_date = ''
    results = []
    for created_at, latest, user_id, payment_type, start_date, end_date, status, period_count, expiration_date, name, category, stripe_id, price, price_period in subscriptions:
        results.append({
            'created_at': created_at,
            'latest': latest,
            'user_id': user_id,
            'payment_type': payment_type,
            'start_date': start_date,
            'end_date': end_date,
            'status': status,
            'period_count': period_count,
            'expiration_date': expiration_date,
            'name': name,
            'category': category,
            'stripe_id': stripe_id,
            'price': price,
            'price_period': price_period,
            'next_bill_date': next_bill_date
        })

    return {'subscriptions': results}
示例#23
0
def delete_annotation_task_by_obj(ann_task, delete_with_annotations=False):
    if db_session_users.query(TopicAnnotation).filter_by(annotation_task_id=ann_task.id).count() > 0\
            and delete_with_annotations:
        db_session_users.query(TopicAnnotation).filter_by(
            annotation_task_id=ann_task.id).delete()

    if db_session_users.query(AnnotationJob).filter_by(
            annotation_task_id=ann_task.id).count() > 0:
        db_session_users.query(AnnotationJob).filter_by(
            annotation_task_id=ann_task.id).delete()

    db_session_users.query(AnnotationTaskTermSamplingGroup).filter_by(
        annotation_task_id=ann_task.id).delete()

    db_session_users.delete(ann_task)
def update_annotation_task_group(annotation_task_group_id, params):

    # params is dict that can contain keys "name", "description", "annotation_task_ids"
    # and "arbitrary_tags"

    # get original annotation task group
    original_annotation_task_group = db_session_users.query(AnnotationTaskTopicGroup)\
                                                     .filter_by(id=annotation_task_group_id)\
                                                     .first()

    # check that task group exists
    if original_annotation_task_group is None:
        return jsonify({'errors':
                        'This annotation task group does not exist'}), 400

    # apply easy updates to annotation task group (i.e. just overwriting name or description)
    if "name" in params:
        original_annotation_task_group.name = params["name"]
    if "description" in params:
        original_annotation_task_group.description = params["description"]

    # apply more difficult updates (i.e. changing arbitrary_tags or annotation_task_ids)
    # NB: for now these are simple overwrites - if needed can later update for more granular control
    if "annotation_task_ids" in params:
        original_annotation_task_group.annotation_task_ids = params[
            "annotation_task_ids"]
    if "arbitrary_tags" in params:
        original_annotation_task_group.arbitrary_tags = params[
            "arbitrary_tags"]

    # n.b. for case where wrong topic was chosen at outset
    if "topic_id" in params:
        original_annotation_task_group.topic_id = params['topic_id']

    if "gold_annotator_user_ids" in params:
        original_annotation_task_group.gold_annotator_user_ids = params[
            'gold_annotator_user_ids']

    if "active_topic_annotation_model_id" in params:
        original_annotation_task_group.active_topic_annotation_model_id = params[
            'active_topic_annotation_model_id']

    # update database with new values
    db_session_users.add(original_annotation_task_group)
    db_session_users.commit()
    task_group_to_return = original_annotation_task_group  # original task group has been updated

    # return updated annotation task group
    task_group_dict = task_group_to_return.to_dict()
    return jsonify({"annotation_task_group": task_group_dict})
def update_research_mode_gold_standard(aggregated_annotation_id, params):
    """
    Update aggregated_annotation so that it points to a new annotation task as a gold standard.
    If the update is None, then aggregated_annotation.is_gold_standard is set to False.

    :param aggregated_annotation_id: int
    :param params: dict, must contain 'topic_annotation_id' as key with topic_annotation_id as value;
                   this is the topic_annotation that is the new gold standard
                   If topic_annotation_id is None, then no topic_annotation is a gold standard
    :return: dict
    """
    agg_annotation = db_session_users.query(AggregatedAnnotations)\
                                     .filter_by(id=aggregated_annotation_id)\
                                     .first()
    agg_annotation.gold_topic_annotation_id = params['topic_annotation_id']

    # update is_gold_standard now that gold_topic_annotation_id is set
    if agg_annotation.gold_topic_annotation_id is not None:
        agg_annotation.is_gold_standard = True
        # update arbitrary_tags and user_difficulty of agg_annotation with values from the new gold standard annotation
        gold_standard_topic_annotation = db_session_users.query(TopicAnnotation)\
                                                         .filter_by(id=params['topic_annotation_id']) \
                                                         .options(subqueryload(TopicAnnotation.annotation_job))\
                                                         .first()
        agg_annotation.arbitrary_tags = gold_standard_topic_annotation.annotation_job.arbitrary_tags
        agg_annotation.gold_difficulty = gold_standard_topic_annotation.annotation_job.user_difficulty
    else:
        agg_annotation.is_gold_standard = False
        # update aggregated_annotation.arbitrary_tags to be nothing
        agg_annotation.arbitrary_tags = []
        agg_annotation.gold_difficulty = None

    # commit change
    db_session_users.commit()

    # n.b. return a deliberately simple response here to avoid a large json response that isn't strictly needed
    return jsonify({"success": True})
示例#26
0
def get_reviews_count_for_user(annotation_task_id, user_id, params):
    # fetch all previous incarnations of this task, so they can be included in statistics
    all_task_ids = [
        t[0] for t in db_session_users.query(AnnotationTask.id).filter_by(active_task_id=annotation_task_id).distinct().all()
    ]
    all_task_ids.append(annotation_task_id)

    # use the utc value for the start of the day pacific time
    now = datetime.datetime.now() - datetime.timedelta(hours=8)
    today_date = str(now.month) + "/" + str(now.day) + "/" + str(now.year)

    # get start date of the billing month
    subscription_created = db_session_users.query(Subscription.created_at).filter_by(user_id=user_id, latest=True).first()
    month_start_date = get_currentsubscription_month_date(subscription_created[0])

    # get annotation counts for user_id / is_positive pairings
    base_query = db_session_users.query(AnnotationJob).filter(AnnotationJob.annotation_task_id.in_(all_task_ids)).filter_by(user_id=user_id)\
        .filter(AnnotationJob.status == AnnotationJob.COMPLETE_STATUS)

    today_total = base_query.filter(AnnotationJob.completed_at >= today_date).count()

    current_month_total = base_query.filter(AnnotationJob.completed_at >= month_start_date).count()

    return {'today_total': today_total, 'current_month_total': current_month_total}
def delete_annotation_task_group(annotation_task_group_id, params):

    # find if task with this id in database
    annotation_task_group = db_session_users.query(AnnotationTaskTopicGroup)\
                                            .filter_by(id=annotation_task_group_id)\
                                            .first()
    if annotation_task_group is None:
        return jsonify({'errors':
                        'This annotation task group does not exist'}), 400

    # if this annotation task group exists, delete it from database
    db_session_users.delete(annotation_task_group)
    db_session_users.commit()

    return jsonify({"success": True})
def get_all_annotation_tasks_in_group(annotation_task_group_id):

    # get list of annotation task ids for annotation task group
    task_group = db_session_users.query(AnnotationTaskTopicGroup)\
                                 .filter_by(id=annotation_task_group_id)\
                                 .first()
    if task_group is None:
        return jsonify({'errors':
                        'This annotation task group does not exist'}), 400
    task_group_dict = task_group.to_dict()
    task_ids = task_group_dict["annotation_task_ids"]

    # create annotation task dicts
    tasks = [
        db_session_users.query(AnnotationTask).filter_by(
            id=task_id).first().to_dict() for task_id in task_ids
    ]

    # return list of annotation task dicts, total number of tasks, and annotation task group dict
    return jsonify({
        "annotation_tasks_in_group": tasks,
        "total_tasks": len(tasks),
        "annotation_task_group_dict": task_group_dict
    })
def flag_document(user_id, doc_id, params):
    issue_severity = params.get('issue_severity',
                                UserFlaggedDocument.REVIEW_SEVERITY)
    issue_type = params.get('issue_type', None)
    notes = params.get('notes', None)
    field = params.get('field', None)
    user_flagged_document_id = params.get('id', None)
    status = params.get('status', None)

    # for creating new user flagged documents
    if user_flagged_document_id is None:
        if not issue_type or issue_type not in ValidIssueTypes:
            return {
                'errors': "Issue type must be one of: " + str(ValidIssueTypes)
            }

        if issue_severity not in ValidIssueSeverities:
            return {
                'errors':
                "Issue severity must be one of: " + str(ValidIssueSeverities)
            }

        flagged_doc = UserFlaggedDocument({
            'user_id': user_id,
            'doc_id': doc_id,
            'issue_severity': issue_severity,
            'issue_type': issue_type,
            'notes': notes,
            'field': field,
        })

    # for updating an existing user flagged document (status is the only relevant use-case)
    else:
        flagged_doc = db_session_users.query(UserFlaggedDocument).filter_by(
            id=user_flagged_document_id).first()
        if status is not None:
            if status in ValidIssueStatuses:
                flagged_doc.status = status
            else:
                return {
                    'errors':
                    "Issue status must be one of: " + str(ValidIssueStatuses)
                }

    db_session_users.add(flagged_doc)
    db_session_users.commit()
    db_session_users.refresh(flagged_doc)
    return flagged_doc.to_dict()
示例#30
0
def get_most_popular_sources(params):
    num_queries = params.get("num_queries",
                             5)  # n.b. 5 is an arbitrary default
    fed_agency_ids = get_all_fed_agency_ids()

    most_popular_sources = db_session_users.query(UserAgency.agency_id, func.count(UserAgency.agency_id).label('total')) \
        .filter(UserAgency.user_id.in_(get_external_user_id_subquery()))\
        .filter(UserAgency.agency_id.in_(fed_agency_ids)).group_by(UserAgency.agency_id).order_by(text('total desc'))\
        .limit(num_queries).all()

    return {
        "popular_sources": [{
            "agency_id": d[0],
            "count": d[1]
        } for d in most_popular_sources]
    }