Example #1
0
def trial_request(trial_id):

    # determine mode.
    mode = request.args.get('delete')
    if mode == '1':
        delete = True
    else:
        delete = False

    # set headers.
    headers = {
        'Content-Type': 'application/json',
        'Authorization': 'Basic ' + base64.b64encode(f'{API_TOKEN}'.encode('utf-8')).decode('utf-8'),
    }

    # create the request.
    qstr = "where=%s" % json.dumps(({"protocol_no": trial_id}))

    # get the trial list from db.
    url = '%s/trial?%s' % (API_ADDRESS, qstr)
    r = requests.get(url, headers=headers)
    output = r.json()

    # sanity check item.
    if len(output['_items']) == 0:
        return "No trial found with id: %s, try uploading from the file" % trial_id

    trial = r.json()['_items'][0]
    mongo_id = trial['_id']
    etag = trial['_etag']

    # add the defaults
    headers['If-Match'] = etag

    # strip meta
    for key in list(trial.keys()):
        if key[0] == "_":
            del trial[key]

    # return the file if we aren't looking to delete it.
    if not delete:
        response = _yamlize(trial, trial_id)

    else:

        # issue delete.
        get_db().trial.remove({"protocol_no": trial_id})
        remove_trial_from_elasticsearch_by_es_id(trial_id)

        if r.status_code < 300:
            return redirect("/curate")

        else:
            return r.text

    return response
Example #2
0
    def test_extract_cancer_types(self):

        m = MatchEngine(get_db())
        match_tree = match_tree_example
        g = m.create_match_tree(match_tree)
        pmt = ParseMatchTree(g)
        cancer_type_dict = pmt.extract_cancer_types()

        assert sorted(cancer_type_dict['diagnoses']) == sorted(
            ['Ocular Melanoma']), cancer_type_dict['diagnoses']

        assert sorted(cancer_type_dict['cancer_types_expanded']) == sorted([
            'Ocular Melanoma', 'Uveal Melanoma', 'Conjunctival Melanoma'
        ]), cancer_type_dict['cancer_types_expanded']

        assert sorted(cancer_type_dict['excluded_cancer_types']
                      ) == [], cancer_type_dict['excluded_cancer_types']
        assert cancer_type_dict['primary_cancer_types'] == [
            'Eye'
        ], cancer_type_dict['primary_cancer_types']

        m = MatchEngine(get_db())
        match_tree = match_tree_example2
        g = m.create_match_tree(match_tree)
        pmt = ParseMatchTree(g)
        cancer_type_dict = pmt.extract_cancer_types()

        assert sorted(cancer_type_dict['diagnoses']) == sorted(
            ['_SOLID_']), cancer_type_dict['diagnoses']
        assert 'Acute Lymphoid Leukemia' not in cancer_type_dict[
            'cancer_types_expanded'], cancer_type_dict['cancer_types_expanded']
        assert sorted(cancer_type_dict['excluded_cancer_types']
                      ) == [], cancer_type_dict['excluded_cancer_types']
        assert cancer_type_dict['primary_cancer_types'] == [
            'All Solid Tumors'
        ], cancer_type_dict['primary_cancer_types']

        m = MatchEngine(get_db())
        match_tree = match_tree_example3
        g = m.create_match_tree(match_tree)
        pmt = ParseMatchTree(g)
        cancer_type_dict = pmt.extract_cancer_types()

        assert sorted(cancer_type_dict['diagnoses']) == sorted(
            ['_LIQUID_']), cancer_type_dict['diagnoses']
        assert 'Acute Lymphoid Leukemia' in cancer_type_dict[
            'cancer_types_expanded'], cancer_type_dict['cancer_types_expanded']
        assert sorted(cancer_type_dict['excluded_cancer_types']
                      ) == [], cancer_type_dict['excluded_cancer_types']
        assert cancer_type_dict['primary_cancer_types'] == [
            'All Liquid Tumors'
        ], cancer_type_dict['primary_cancer_types']
Example #3
0
    def _validate_normalized(self, normalized, field, value):
        ''' use normalization dictionary to control values
        return validation error if it isn't a true value
        in the dictionary'''

        # load the mapping
        db = get_db()
        normalize_table = db['normalize'].find_one()

        if not normalize_table:
            return

        for key, val in value.iteritems():
            if (isinstance(val, str) or isinstance(val, unicode)) and val[0] == "!":
                val = val[1:]

            if key == 'oncotree_primary_diagnosis':
                if val not in normalize_table['values']['oncotree_primary_diagnosis'].values():
                    self._error(field, "%s is not a valid value for oncotree_primary_diagnosis" % val)

            elif key == 'hugo_symbol':
                if 'hugo_symbol' in normalize_table['values'] and val not in normalize_table['values']['hugo_symbol']:
                    self._error(422, "%s is not a valid hugo symbol" % val)

            elif isinstance(val, dict):
                self._validate_normalized(normalized, field, val)

            elif isinstance(val, list):
                for subitem in val:
                    if isinstance(subitem, dict):
                        self._validate_normalized(normalized, field, subitem)
Example #4
0
def after_request(response):

    # test for response
    is_response, item_id = parse_response(request.url)

    # only redirect if response
    if is_response:

        # do the redirect.
        db = get_db()
        item = db['response'].find_one({"_id": ObjectId(item_id)})

        # if it exists return the redirect.
        if item is not None:
            return make_response(redirect(item['return_url']))

    # remove these headers
    response.headers.add('Last-Modified', datetime.now())
    response.headers.add('Expires', '-1')

    # dont use these headers because IE11 doesn't like them with fonts.
    if response.content_type != 'application/json':
        response.headers.add(
            'Cache-Control',
            'no-store, no-cache, must-revalidate, post-check=0, pre-check=0, max-age=0'
        )
        response.headers.add('Pragma', 'no-cache')

    return response
Example #5
0
def get_public_stats(resp):
    """Returns the number of clinical trials and the number of patients to the UI"""
    db = database.get_db()
    resp['_items'].append({
        'num_clinical_trials': len(list(db['trial'].distinct('protocol_no'))),
        'num_patients': len(list(db['clinical'].distinct("MRN")))
    })
Example #6
0
def email_matchminer(patient, status):
    """Emails the matchminer service email account to keep track of physician responses to the email blast"""

    cur_stamp = datetime.datetime.now().strftime("%I:%M%p on %B %d, %Y")

    html = '''<html><head></head><body>%s</body></html>''' % emails.EMAIL_BLAST_RESPONSE_BODY.format(
        patient['ORD_PHYSICIAN_NAME'],
        patient['FIRST_NAME'],
        patient['LAST_NAME'],
        patient['MRN'],
        status,
        cur_stamp
    )

    # put email object in db
    db = database.get_db()
    email_item = {
        'email_from': settings.EMAIL_AUTHOR_PROTECTED,
        'email_to': settings.EMAIL_AUTHOR_PROTECTED,
        'subject': 'Email Blast Response',
        'body': html,
        'cc': [],
        'sent': False,
        'num_failures': 0,
        'errors': []
    }
    db['email'].insert(email_item)
Example #7
0
def email_filter_owner(user, patient, filter_name, variant, status):

    if variant:
        alteration = get_alterations(variant)
    else:
        alteration = 'unknown'

    cur_stamp = datetime.datetime.now().strftime("%I:%M%p on %B %d, %Y")
    html = _user_email_filter_owner(user, patient, alteration, status, cur_stamp)

    subject = '%s : Patient %s' % (filter_name, status)
    author = settings.EMAIL_AUTHOR_PROTECTED

    # put email object in db
    db = database.get_db()
    email_item = {
        'email_from': author,
        'email_to': user['email'],
        'subject': subject,
        'body': html,
        'cc': settings.EMAIL_TRIAL_CC_LIST,
        'sent': False,
        'num_failures': 0,
        'errors': []
    }
    db['email'].insert(email_item)
Example #8
0
def _get_new_filters_match_counts(team_id, filters_with_new_matches, run_id):
    """
    Aggregate new filter match counts by team

    :param team_id: Team with associated filters
    :param filters_with_new_matches: List of filter IDs associated with single team
    :return:
    """
    db = database.get_db()
    new_filter_match_counts = {}
    for filter_id in filters_with_new_matches:
        matches_query = {
            "TEAM_ID": team_id,
            "FILTER_ID": filter_id,
            "is_disabled": False,
            "_me_id": run_id
        }
        num_matches = len(list(db.match.find(matches_query, {"_id": 1})))

        if num_matches < 1:
            continue
        else:
            filter_ = list(db.filter.find({'_id': filter_id}))[0]
            new_filter_match_counts[filter_id] = {
                "num_matches": num_matches,
                "description": filter_['description'],
                "label": filter_['label'],
                "protocol_id": filter_['protocol_id']
            }
    return new_filter_match_counts
Example #9
0
def get_public_stats(resp):
    """Returns the number of clinical trials and the number of patients to the UI"""
    db = database.get_db()
    resp['_items'].append({
        'num_clinical_trials': len(list(db['trial'].distinct('protocol_no'))),
        'num_patients': len(list(db['clinical'].distinct("MRN")))
    })
Example #10
0
    def setUp(self):

        # prepare the app
        settings_file = os.path.join(SETTINGS_DIR, 'settings.py')
        self.app = eve.Eve(settings=settings_file,
                           url_converters=None,
                           auth=TokenAuth,
                           validator=ConsentValidatorEve)

        # load normalization.
        with open(BSON_FILE) as fin:
            mappings = list(bson.decode_iter(fin.read()))

        # add normalization.
        self.db = get_db()
        for mapping in mappings:
            self.db['normalize'].drop()
            self.db['normalize'].insert(mapping)

        # create the validator.
        resource_def = self.app.config['DOMAIN']['trial']
        schema = resource_def['schema']

        #print self.app.config['SOURCES']
        with self.app.app_context():
            self.v = self.app.validator(schema=schema, resource='trial')
Example #11
0
    def setUp(self):

        # prepare the app
        settings_file = os.path.join(SETTINGS_DIR, 'settings.py')
        self.app = eve.Eve(settings=settings_file,
                            url_converters = None,
                            auth = TokenAuth,
                            validator = ConsentValidatorEve)

        # load normalization.
        with open(BSON_FILE) as fin:
            mappings = list(bson.decode_iter(fin.read()))

        # add normalization.
        self.db = get_db()
        for mapping in mappings:
            self.db['normalize'].drop()
            self.db['normalize'].insert(mapping)

        # create the validator.
        resource_def = self.app.config['DOMAIN']['trial']
        schema = resource_def['schema']

        #print self.app.config['SOURCES']
        with self.app.app_context():
            self.v = self.app.validator(schema=schema, resource='trial')
Example #12
0
def build_redirect_url_epic(user, trial_match):
    """
    When redirecting to a patient for integration with EPIC, set appropriate tokens, headers, and cookies
    :param user:
    :param trial_match:
    :return:
    """
    db = database.get_db()

    # Set token. Must match token set in cookie
    token = str(uuid.uuid4())
    db['user'].update_one({'_id': user['_id']}, {
        '$set': {'token': token, 'last_auth': datetime.datetime.now()}
    })

    # Build redirect URL
    patient_id = str(trial_match["_id"])
    url = FRONT_END_ADDRESS + 'dashboard/patients/' + patient_id + '?epic=true'
    redirect_to_patient = redirect(url)
    logging.info('[EPIC] redirect to URL: ' + url)

    # Build response headers
    response = app.make_response(redirect_to_patient)
    response.headers.add('Authorization', 'Basic' + base64.b64encode(f'{token}:'.encode('utf-8')).decode())
    response.headers.add('Last-Modified', datetime.datetime.now())
    response.headers.add('Cache-Control', 'no-store, no-cache, must-revalidate, post-check=0, pre-check=0, max-age=0')
    response.headers.add('Pragma', 'no-cache')
    response.headers.add('Content-Type', 'application/json')
    response.headers.add('Location', url)

    # Set cookies
    response.set_cookie('user_id', value=str(user['_id']), expires=0)
    response.set_cookie('team_id', value=str(user['teams'][0]), expires=0)
    response.set_cookie('token', value=token, expires=0)
    return response
Example #13
0
def email_filter_owner(user, patient, filter_name, variant, status):

    if variant:
        alteration = get_alterations(variant)
    else:
        alteration = 'unknown'

    cur_stamp = datetime.datetime.now().strftime("%I:%M%p on %B %d, %Y")
    html = _user_email_filter_owner(user, patient, alteration, status,
                                    cur_stamp)

    subject = '%s : Patient %s' % (filter_name, status)
    author = settings.EMAIL_AUTHOR_PROTECTED

    # put email object in db
    db = database.get_db()
    email_item = {
        'email_from': author,
        'email_to': user['email'],
        'subject': subject,
        'body': html,
        'cc': settings.EMAIL_TRIAL_CC_LIST,
        'sent': False,
        'num_failures': 0,
        'errors': []
    }
    db['email'].insert(email_item)
Example #14
0
def email_matchminer(patient, status):
    """Emails the matchminer service email account to keep track of physician responses to the email blast"""

    cur_stamp = datetime.datetime.now().strftime("%I:%M%p on %B %d, %Y")

    html = '''<html><head></head><body>%s</body></html>''' % emails.EMAIL_BLAST_RESPONSE_BODY.format(
        patient['ORD_PHYSICIAN_NAME'],
        patient['FIRST_NAME'],
        patient['LAST_NAME'],
        patient['MRN'],
        status,
        cur_stamp
    )

    # put email object in db
    db = database.get_db()
    email_item = {
        'email_from': settings.EMAIL_AUTHOR_PROTECTED,
        'email_to': settings.EMAIL_AUTHOR_PROTECTED,
        'subject': 'Email Blast Response',
        'body': html,
        'cc': [],
        'sent': False,
        'num_failures': 0,
        'errors': []
    }
    db['email'].insert(email_item)
Example #15
0
def start_filter_run(silent=False, datapush_id=None):
    """
    Wrapper function which calls rerun filters.
    Creates a record in active_process collection to make sure multiple filter
    matching runs are not created simultaneously.

    :param silent: Whether to send emails or not
    :param datapush_id: ID to append to output matches if relevant
    :return:
    """
    db = database.get_db()
    db.active_processes.insert({"filters_running": True})
    filters = list(
        db.filter.find({
            "temporary": False,
            "status": {
                "$in": [0, 1]
            }
        }))
    transform_filter_to_CTML(filters, save=True)
    _, run_id = rerun_filters(datapush_id=datapush_id)
    db.active_processes.drop()

    if not silent:
        email_matches(run_id)

    return run_id
Example #16
0
def maintain_filters():
    """
    recalculate text descriptions

    :return:
    """
    logging.info("maintain filters")

    # get database connection.
    db = database.get_db()

    # find all filters status.
    filters = list(db['filter'].find())

    for filter in filters:

        # skip inactive.
        if 'temporary' not in filter:
            continue
        if filter['temporary'] == True:
            continue

        # get the text string.
        try:
            c, g, txt = miner.prepare_criteria(filter)
            gen_txt, clin_txt = txt
            description = []
        except KeyError:
            continue

        # setup clincal portion.
        cancer, age, gender = clin_txt

        c_test = cancer == ""
        g_test = gender == ""
        a_test = age == ""

        # handle cancer sentance.
        if not c_test:
            description = "%s in %s" % (gen_txt, cancer)
        else:
            description = gen_txt

        # handle the rest.
        if not g_test and a_test:
            description = "%s, Gender: %s" % (description, gender)

        elif not g_test and not a_test:
            description = "%s, Gender: %s, Age %s" % (description, gender, age)

        elif g_test and not a_test:
            description = "%s, Age %s" % (description, age)

        # hack fix
        if description == []:
            description = ''

        # update record with this.
        result = db['filter'].update_one({"_id": filter["_id"]}, {"$set": {"description": description}})
Example #17
0
def assess_vital_status(update, original):
    """If a patient's VITAL STATUS has been changed to deceased, remove their matches from the database"""

    db = database.get_db()
    if 'VITAL_STATUS' in update and update[
            'VITAL_STATUS'] == 'deceased' and original[
                'VITAL_STATUS'] == 'alive':
        db['match'].remove({'CLINICAL_ID': original['_id']})
Example #18
0
def maintain_matches():
    """
    this function does 2 tasks on matches: 1st it determines if any matches belong to a deleted filter and
    also deletes them. 2nd it adds the MRN to existing matches.

    :return:
    """
    logging.info("maintain matches")

    # get database connection.
    db = database.get_db()

    # find all filters status.
    filters = list(db['filter'].find())

    filters_status = {}
    for filter in filters:
        filters_status[filter['_id']] = filter['status']

    # build a patient lu.
    patient_lu = {}

    # loop over each match and delete if its stale.
    to_delete = list()
    for match in db['match'].find():

        # check if the filter is deleted.
        delete = False
        if match['FILTER_ID'] not in filters_status:
            delete = True

        elif filters_status[match['FILTER_ID']] != 1:
            delete = True

        if delete:
            db['match'].remove({"_id": match['_id']})
            to_delete.append(match['_id'])

        # update it if not deleted.
        if not delete:

            # get patient info.
            if match['CLINICAL_ID'] not in patient_lu:
                patient_lu[match['CLINICAL_ID']] = db['clinical'].find_one(
                    {"_id": match['CLINICAL_ID']})

            # get MRN.
            patient_mrn = patient_lu[match['CLINICAL_ID']]['MRN']

            # update the record.
            db['match'].update_one({"_id": match['_id']},
                                   {"$set": {
                                       "PATIENT_MRN": patient_mrn
                                   }})

    # return the count.
    return to_delete
Example #19
0
    def test_extract_hr_status(self):

        m = MatchEngine(get_db())
        match_tree = trial['treatment_list']['step'][0]['match'][5]
        g = m.create_match_tree(match_tree)
        pmt = ParseMatchTree(g)
        hr = pmt.extract_hr_status()

        assert sorted(hr) == sorted(['HER2 Negative', 'ER Negative', 'PR Positive'])
Example #20
0
    def setUp(self):

        # set up fake db
        self.db = get_db()
        self.db['response'].drop()
        self.db['clinical'].insert_many([self.fake_patient, self.fake_patient2])
        self.db['match'].insert_many([self.match_contacted, self.match_flagged])
        self.db['filter'].insert_one(self.fake_filter)
        self.db['user'].insert_one(self.fake_filter_owner)
Example #21
0
def update_response(item):

    if 'allow_update' not in item or not item['allow_update']:
        abort(501)

    bin_key = settings.match_status_mapping
    db = database.get_db()

    # add time_clicked and ip_address to response
    db['response'].update_one({'_id': item['_id']}, {
        '$set': {
            'time_clicked':
            formatdate(time.mktime(datetime.datetime.now().timetuple()),
                       localtime=False,
                       usegmt=True),
            'ip_address':
            _get_ip()
        }
    })

    # Get match from match table
    match_db = db['match']
    match = match_db.find_one({'_id': item['match_id']})
    patient = db['clinical'].find_one({'_id': match['CLINICAL_ID']})

    # get clinician response
    status = item['match_status']

    # get new status
    new_status = bin_key[status]

    # Update match status
    result = match_db.update_one({"_id": item["match_id"]}, {
        "$set": {
            "MATCH_STATUS": new_status,
            "_updated": datetime.datetime.utcnow().replace(microsecond=0)
        }
    })

    if status == 'Eligible' or status == 'Deferred':
        # get the filter owner
        user_db = db['user']
        filter_owner = user_db.find_one({'_id': item['notification_id']})

        # get filter
        filter_name = match['FILTER_NAME']

        # get the list of matched variant
        variant = []
        genomic_db = db['genomic']
        for v in match['VARIANTS']:
            variant.extend(list(genomic_db.find({'_id': v})))

        email_filter_owner(filter_owner, patient, filter_name, variant, status)

    elif status == 'Not Eligible' or status == 'Deceased':
        email_matchminer(patient, status)
Example #22
0
    def test_extract_hr_status(self):

        m = MatchEngine(get_db())
        match_tree = trial['treatment_list']['step'][0]['match'][5]
        g = m.create_match_tree(match_tree)
        pmt = ParseMatchTree(g)
        hr = pmt.extract_hr_status()

        assert sorted(hr) == sorted(['HER2 Negative', 'ER Negative', 'PR Positive'])
Example #23
0
    def setUp(self):

        # set up fake db
        self.db = get_db()
        self.db['response'].drop()
        self.db['clinical'].insert_many([self.fake_patient, self.fake_patient2])
        self.db['match'].insert_many([self.match_contacted, self.match_flagged])
        self.db['filter'].insert_one(self.fake_filter)
        self.db['user'].insert_one(self.fake_filter_owner)
Example #24
0
    def test_extract_cancer_types(self):

        m = MatchEngine(get_db())
        match_tree = match_tree_example
        g = m.create_match_tree(match_tree)
        pmt = ParseMatchTree(g)
        cancer_type_dict = pmt.extract_cancer_types()

        assert sorted(cancer_type_dict['diagnoses']) == sorted([
            'Ocular Melanoma'
        ]), cancer_type_dict['diagnoses']

        assert sorted(cancer_type_dict['cancer_types_expanded']) == sorted([
            'Ocular Melanoma',
            'Uveal Melanoma',
            'Conjunctival Melanoma'
        ]), cancer_type_dict['cancer_types_expanded']

        assert sorted(cancer_type_dict['excluded_cancer_types']) == [], cancer_type_dict['excluded_cancer_types']
        assert cancer_type_dict['primary_cancer_types'] == ['Eye'], cancer_type_dict['primary_cancer_types']

        m = MatchEngine(get_db())
        match_tree = match_tree_example2
        g = m.create_match_tree(match_tree)
        pmt = ParseMatchTree(g)
        cancer_type_dict = pmt.extract_cancer_types()

        assert sorted(cancer_type_dict['diagnoses']) == sorted(['_SOLID_']), cancer_type_dict['diagnoses']
        assert 'Acute Lymphoid Leukemia' not in cancer_type_dict['cancer_types_expanded'], cancer_type_dict['cancer_types_expanded']
        assert sorted(cancer_type_dict['excluded_cancer_types']) == [], cancer_type_dict['excluded_cancer_types']
        assert cancer_type_dict['primary_cancer_types'] == ['All Solid Tumors'], cancer_type_dict['primary_cancer_types']

        m = MatchEngine(get_db())
        match_tree = match_tree_example3
        g = m.create_match_tree(match_tree)
        pmt = ParseMatchTree(g)
        cancer_type_dict = pmt.extract_cancer_types()

        assert sorted(cancer_type_dict['diagnoses']) == sorted(['_LIQUID_']), cancer_type_dict['diagnoses']
        assert 'Acute Lymphoid Leukemia' in cancer_type_dict['cancer_types_expanded'], cancer_type_dict[
            'cancer_types_expanded']
        assert sorted(cancer_type_dict['excluded_cancer_types']) == [], cancer_type_dict['excluded_cancer_types']
        assert cancer_type_dict['primary_cancer_types'] == ['All Liquid Tumors'], cancer_type_dict['primary_cancer_types']
Example #25
0
    def test_extract_signatures(self):

        m = MatchEngine(get_db())
        match_tree = trial['treatment_list']['step'][0]['match'][3]
        g = m.create_match_tree(match_tree)
        pmt = ParseMatchTree(g)
        s = pmt.extract_signatures()

        assert 'MMR-D' in s[0]
        assert 'MSI-H' in s[1]
Example #26
0
    def test_extract_signatures(self):

        m = MatchEngine(get_db())
        match_tree = trial['treatment_list']['step'][0]['match'][3]
        g = m.create_match_tree(match_tree)
        pmt = ParseMatchTree(g)
        s = pmt.extract_signatures()

        assert 'MMR-D' in s[0]
        assert 'MSI-H' in s[1]
Example #27
0
def assess_vital_status(update, original):
    """If a patient's VITAL STATUS has been changed to deceased, remove their matches from the database"""

    db = database.get_db()
    if 'VITAL_STATUS' in update and update[
            'VITAL_STATUS'] == 'deceased' and original[
                'VITAL_STATUS'] == 'alive':
        update = {'is_disabled': True, "_updated": datetime.datetime.now()}
        db['match'].update_many({'CLINICAL_ID': original['_id']},
                                {'$set': update})
Example #28
0
def update_response(item):

    if 'allow_update' not in item or not item['allow_update']:
        abort(501)

    bin_key = settings.match_status_mapping
    db = database.get_db()

    # add time_clicked and ip_address to response
    db['response'].update_one(
        {'_id': item['_id']},
        {'$set': {
            'time_clicked': formatdate(time.mktime(datetime.datetime.now().timetuple())),
            'ip_address': _get_ip()
        }}
    )

    # Get match from match table
    match_db = db['match']
    match = match_db.find_one({'_id': item['match_id']})
    patient = db['clinical'].find_one({'_id': match['CLINICAL_ID']})

    # get clinician response
    status = item['match_status']

    # get new status
    new_status = bin_key[status]

    # Update match status
    result = match_db.update_one(
        {"_id": item["match_id"]},
        {"$set": {
            "MATCH_STATUS": new_status,
            "_updated": datetime.datetime.utcnow().replace(microsecond=0)
        }}
    )

    if status == 'Eligible' or status == 'Deferred':
        # get the filter owner
        user_db = db['user']
        filter_owner = user_db.find_one({'_id': item['notification_id']})

        # get filter
        filter_name = match['FILTER_NAME']

        # get the list of matched variant
        variant = []
        genomic_db = db['genomic']
        for v in match['VARIANTS']:
            variant.extend(list(genomic_db.find({'_id': v})))

        email_filter_owner(filter_owner, patient, filter_name, variant, status)

    elif status == 'Not Eligible' or status == 'Deceased':
        email_matchminer(patient, status)
Example #29
0
def run_matchengine():
    """
    Computes matches between all trials in the database and the given subset list of patient MRNs

    :param mrns: List of patient MRNs
    :return: database collection of trial matches
    """

    db = database.get_db()
    me = MatchEngine(db)
    me.find_trial_matches()
Example #30
0
def run_matchengine():
    """
    Computes matches between all trials in the database and the given subset list of patient MRNs

    :param mrns: List of patient MRNs
    :return: database collection of trial matches
    """

    db = database.get_db()
    me = MatchEngine(db)
    me.find_trial_matches()
Example #31
0
def is_engine_running():
    db = database.get_db()

    running_processes = list(db.active_processes.find())
    is_running = True if len(running_processes) > 0 else False

    logging.info(f"/api/is_matchengine_running {str(is_running)}")
    resp = Response(response=json.dumps({"is_running": is_running}),
                    status=200,
                    mimetype="application/json")
    return resp
Example #32
0
    def entry_replace(resource, item, original):

        # get all records from db
        db = get_db()
        records = db['normalize'].find_one({"key": resource})
        if records is None:
            return
        mapping = records['values']

        # check all keys.
        NormalizeHook._recursive_check(item, mapping)
Example #33
0
    def entry_replace(resource, item, original):

        # get all records from db
        db = get_db()
        records = db['normalize'].find_one({"key": resource})
        if records is None:
            return
        mapping = records['values']

        # check all keys.
        NormalizeHook._recursive_check(item, mapping)
Example #34
0
def maintain_matches():
    """
    this function does 2 tasks on matches: 1st it determines if any matches belong to a deleted filter and
    also deletes them. 2nd it adds the MRN to existing matches.

    :return:
    """
    logging.info("maintain matches")

    # get database connection.
    db = database.get_db()

    # find all filters status.
    filters = list(db['filter'].find())

    filters_status = {}
    for filter in filters:
        filters_status[filter['_id']] = filter['status']

    # build a patient lu.
    patient_lu = {}

    # loop over each match and delete if its stale.
    to_delete = list()
    for match in db['match'].find():

        # check if the filter is deleted.
        delete = False
        if match['FILTER_ID'] not in filters_status:
            delete = True

        elif filters_status[match['FILTER_ID']] != 1:
            delete = True

        if delete:
            db['match'].remove({"_id": match['_id']})
            to_delete.append(match['_id'])

        # update it if not deleted.
        if not delete:

            # get patient info.
            if match['CLINICAL_ID'] not in patient_lu:
                patient_lu[match['CLINICAL_ID']] = db['clinical'].find_one({"_id": match['CLINICAL_ID']})

            # get MRN.
            patient_mrn = patient_lu[match['CLINICAL_ID']]['MRN']

            # update the record.
            db['match'].update_one({"_id": match['_id']}, {"$set": {"PATIENT_MRN": patient_mrn}})


    # return the count.
    return to_delete
Example #35
0
    def entry_insert(resource, items):

        # get all records from db
        db = get_db()
        records = db['normalize'].find_one({"key": resource})
        if records is None:
            return
        mapping = records['values']

        # check all keys.
        for item in items:
            NormalizeHook._recursive_check(item, mapping)
Example #36
0
    def entry_insert(resource, items):

        # get all records from db
        db = get_db()
        records = db['normalize'].find_one({"key": resource})
        if records is None:
            return
        mapping = records['values']

        # check all keys.
        for item in items:
            NormalizeHook._recursive_check(item, mapping)
def bootstrap_restore(args):

    # restore the important collections.
    data_dir = settings.DATA_DIR_PROD
    if data_dir == "":
        data_dir = settings.DATA_DIR

    restore_collections(data_dir, settings)

    # fetch the database.
    db = get_db()
    db['clinical'].update_many({"VITAL_STATUS": "dead"}, {"$set": {"VITAL_STATUS": "deceased"}})
Example #38
0
def reannotate_trials():
    db = database.get_db()
    trials = list(db['trial'].find())

    # modify trials to be inserted in bulk later
    events.trial_insert(trials)

    # re-insert.
    for trial in trials:
        db['trial'].delete_one({'_id': trial['_id']})
        db['trial'].insert_one(trial)

    logging.info("DONE")
Example #39
0
    def test_extract_variants(self):

        m = MatchEngine(get_db())
        match_tree = trial['treatment_list']['step'][0]['match'][0]
        g = m.create_match_tree(match_tree)
        pmt = ParseMatchTree(g)
        v = pmt.extract_variants()
        assert 'BRAF V600E' in v['variants']
        assert 'BRAF V600K' in v['variants']
        assert 'KRAS any' in v['variants']
        assert 'EGFR wt' in v['wts']
        assert len(v['variants']) == 3
        assert len(v['wts']) == 1

        match_tree = trial['treatment_list']['step'][0]['match'][1]
        g = m.create_match_tree(match_tree)
        pmt = ParseMatchTree(g)
        v = pmt.extract_variants()

        assert 'PTEN CNV' in v['cnvs']
        assert 'BRCA1 SV' in v['svs']
        assert 'BRAF V600' in v['exclusions']
        assert len(v['variants']) == 0
        assert len(v['cnvs']) == 1
        assert len(v['svs']) == 1
        assert len(v['wts']) == 0
        assert len(v['exclusions']) == 1

        match_tree = trial['treatment_list']['step'][0]['match'][2]
        g = m.create_match_tree(match_tree)
        pmt = ParseMatchTree(g)
        v = pmt.extract_variants()
        assert 'BRAF V600E' not in v['variants']
        assert len(v['variants']) == 0
        assert len(v['wts']) == 0
        assert 'BRAF V600E' in v['exclusions']

        match_tree = trial['treatment_list']['step'][0]['match'][4]
        g = m.create_match_tree(match_tree)
        pmt = ParseMatchTree(g)
        v = pmt.extract_variants()
        assert 'BRAF V600K' in v['variants']
        assert 'EGFR any' in v['variants']
        assert len(v['variants']) == 2
        assert 'PTEN CNV' in v['cnvs']
        assert len(v['cnvs']) == 1
        assert 'KRAS' in v['exclusions']
        assert 'NRAS' in v['exclusions']
        assert len(v['exclusions']) == 2
        assert 'NTRK1 wt' in v['wts']
        assert len(v['wts']) == 1
Example #40
0
def trial_insert(items):

    # get database connection.
    db = database.get_db()

    # loop over each item.
    for item in items:

        # log this.
        logging.info("trial inserted")

        # build tree.
        me = MatchEngine(db)
        status, trial_tree = me.create_trial_tree(item, no_validate=True)

        # look at every node.
        genomic = {}
        clinical = {}
        other = {}
        for n in trial_tree.nodes():

            # get parent.
            if 'node_id' not in trial_tree.node[n]:
                continue

            node_id = trial_tree.node[n]['node_id']

            # look for multi-level nodes (right now its only match).
            if 'match_tree' in trial_tree.node[n]:
                # compress categories.
                mt = trial_tree.node[n]['match_tree']
                for x in mt:
                    if mt.node[x]['type'] == 'genomic':
                        insert_data_genomic(genomic, mt.node[x]['value'],
                                            node_id)
                    if mt.node[x]['type'] == 'clinical':
                        insert_data_clinical(clinical, mt.node[x]['value'],
                                             node_id)

            # add the other nodes.
            insert_data_other(trial_tree, node_id, n, other)

        # create _summary, _suggest, and _elasticsearch fields
        summary = Summary(clinical, genomic, other, trial_tree)
        item['_summary'] = summary.create_summary(item)

        autocomplete = Autocomplete(item)
        item['_suggest'], item['_elasticsearch'], item['_summary']['primary_tumor_types'] = \
            autocomplete.add_autocomplete()

    return items
Example #41
0
    def test_extract_variants(self):

        m = MatchEngine(get_db())
        match_tree = trial['treatment_list']['step'][0]['match'][0]
        g = m.create_match_tree(match_tree)
        pmt = ParseMatchTree(g)
        v = pmt.extract_variants()
        assert 'BRAF V600E' in v['variants']
        assert 'BRAF V600K' in v['variants']
        assert 'KRAS any' in v['variants']
        assert 'EGFR wt' in v['wts']
        assert len(v['variants']) == 3
        assert len(v['wts']) == 1

        match_tree = trial['treatment_list']['step'][0]['match'][1]
        g = m.create_match_tree(match_tree)
        pmt = ParseMatchTree(g)
        v = pmt.extract_variants()

        assert 'PTEN CNV' in v['cnvs']
        assert 'BRCA1 SV' in v['svs']
        assert 'BRAF V600' in v['exclusions']
        assert len(v['variants']) == 0
        assert len(v['cnvs']) == 1
        assert len(v['svs']) == 1
        assert len(v['wts']) == 0
        assert len(v['exclusions']) == 1

        match_tree = trial['treatment_list']['step'][0]['match'][2]
        g = m.create_match_tree(match_tree)
        pmt = ParseMatchTree(g)
        v = pmt.extract_variants()
        assert 'BRAF V600E' not in v['variants']
        assert len(v['variants']) == 0
        assert len(v['wts']) == 0
        assert 'BRAF V600E' in v['exclusions']

        match_tree = trial['treatment_list']['step'][0]['match'][4]
        g = m.create_match_tree(match_tree)
        pmt = ParseMatchTree(g)
        v = pmt.extract_variants()
        assert 'BRAF V600K' in v['variants']
        assert 'EGFR any' in v['variants']
        assert len(v['variants']) == 2
        assert 'PTEN CNV' in v['cnvs']
        assert len(v['cnvs']) == 1
        assert 'KRAS' in v['exclusions']
        assert 'NRAS' in v['exclusions']
        assert len(v['exclusions']) == 2
        assert 'NTRK1 wt' in v['wts']
        assert len(v['wts']) == 1
Example #42
0
def find_filter_matches(items):
    db = database.get_db()
    for item in items:
        do_update = False if item['temporary'] else True
        num_matches, run_id = rerun_filters(filters=[item['_id']],
                                            do_update=do_update,
                                            datapush_id=None)
        enrollments = get_enrollment(num_matches[item['_id']])
        item['num_samples'] = len(num_matches[item['_id']])
        item['enrollment'] = enrollments

        # don't persist temporary filters
        if item['status'] == 2 and item['temporary'] == True:
            db.filter.remove({"_id": item['_id']})
Example #43
0
    def setUp(self):
        self.db = get_db()
        self.db.status.drop()

        self.now = '2017-0{0}-01 05:00:00'

        self.db.status.insert_many([{
            'updated_genomic': 0,
            'new_genomic': 10,
            'updated_clinical': 0,
            'new_clinical': 5,
            'last_update': dt.now(),
            'data_push_id': self.now.format(m)
        } for m in [1, 2, 3, 4, 5, 6]])
Example #44
0
    def setUp(self, settings_file=None, url_converters=None):
        super(TestResponse, self).setUp(settings_file=None, url_converters=None)
        self.user_token = None

        # add to database
        self.db = get_db()
        self.db.response.drop()
        self.db['clinical'].insert_one(self.fake_patient)
        self.db['match'].insert_one(self.match_flagged)
        self.db['filter'].insert_one(self.fake_filter)
        self.db['user'].insert_one(self.fake_filter_owner)
        self.db['response'].insert_many(demo_resps)
        self.response_ids = [resp['_id'] for resp in demo_resps]
        self.email_ids = [email['_id'] for email in list(self.db['email'].find())]
Example #45
0
    def setUp(self):
        self.db = get_db()
        self.db.status.drop()

        self.now = '2017-0{0}-01 05:00:00'

        self.db.status.insert_many([{
            'updated_genomic': 0,
            'new_genomic': 10,
            'updated_clinical': 0,
            'new_clinical': 5,
            'last_update': dt.now(),
            'data_push_id': self.now.format(m)
        } for m in [1, 2, 3, 4, 5, 6]])
Example #46
0
def trial_insert(items):

    # get database connection.
    db = database.get_db()

    # loop over each item.
    for item in items:

        # log this.
        logging.info("trial inserted")

        # build tree.
        me = MatchEngine(db)
        status, trial_tree = me.create_trial_tree(item, no_validate=True)

        # look at every node.
        genomic = {}
        clinical = {}
        other = {}
        for n in trial_tree.nodes():

            # get parent.
            if 'node_id' not in trial_tree.node[n]:
                continue

            node_id = trial_tree.node[n]['node_id']

            # look for multi-level nodes (right now its only match).
            if 'match_tree' in trial_tree.node[n]:
                # compress categories.
                mt = trial_tree.node[n]['match_tree']
                for x in mt:
                    if mt.node[x]['type'] == 'genomic':
                        insert_data_genomic(genomic, mt.node[x]['value'], node_id)
                    if mt.node[x]['type'] == 'clinical':
                        insert_data_clinical(clinical, mt.node[x]['value'], node_id)

            # add the other nodes.
            insert_data_other(trial_tree, node_id, n, other)

        # create _summary, _suggest, and _elasticsearch fields
        summary = Summary(clinical, genomic, other, trial_tree)
        item['_summary'] = summary.create_summary(item)

        autocomplete = Autocomplete(item)
        item['_suggest'], item['_elasticsearch'], item['_summary']['primary_tumor_types'] = \
            autocomplete.add_autocomplete()

    return items
Example #47
0
    def test_trial_summary(self):

        on_trial['_genomic'] = {'hugo_symbol': [{'value': 'TEST'}]}
        on_trial['_clinical'] = {'disease_status': [{'value': ['TEST']}]}
        other = {'management_group': [{'value': 'TEST'}]}

        # create trial tree
        db = get_db()
        me = MatchEngine(db)
        status, trial_tree = me.create_trial_tree(on_trial, no_validate=True)

        # validate summary
        summary = Summary(on_trial['_clinical'],
                          on_trial['_genomic'],
                          other,
                          trial_tree)
        item = summary.create_summary(on_trial)
        status_fields = ['drugs', 'genes', 'tumor_types', 'sponsor',
                         'phase_summary', 'accrual_goal', 'investigator', 'age_summary', 'protocol_number',
                         'disease_status', 'nct_number', 'disease_center', 'short_title',
                         'hormone_receptor_status']

        for field in status_fields:
            assert field in item, self._debug(item, field)

            if field not in ['dfci_investigator', 'hormone_receptor_status']:
                assert item[field], '%s| %s' % (field, item)

        # remove all fields and validate that the summary will not error
        del on_trial['age']
        del on_trial['phase']
        del on_trial['nct_id']
        del on_trial['protocol_no']
        del on_trial['principal_investigator']
        del on_trial['cancer_center_accrual_goal_upper']
        del on_trial['site_list']
        del on_trial['sponsor_list']
        del on_trial['drug_list']
        del on_trial['staff_list']

        status, trial_tree = me.create_trial_tree(on_trial, no_validate=True)
        summary = Summary(on_trial['_clinical'],
                          on_trial['_genomic'],
                          other,
                          trial_tree)
        item = summary.create_summary(on_trial)

        for field in status_fields:
            assert field in item, self._debug(item, field)
Example #48
0
    def test_trial_summary(self):

        on_trial['_genomic'] = {'hugo_symbol': [{'value': 'TEST'}]}
        on_trial['_clinical'] = {'disease_status': [{'value': ['TEST']}]}
        other = {'management_group': [{'value': 'TEST'}]}

        # create trial tree
        db = get_db()
        me = MatchEngine(db)
        status, trial_tree = me.create_trial_tree(on_trial, no_validate=True)

        # validate summary
        summary = Summary(on_trial['_clinical'],
                          on_trial['_genomic'],
                          other,
                          trial_tree)
        item = summary.create_summary(on_trial)
        status_fields = ['drugs', 'genes', 'tumor_types', 'sponsor',
                         'phase_summary', 'accrual_goal', 'investigator', 'age_summary', 'protocol_number',
                         'disease_status', 'nct_number', 'disease_center', 'short_title',
                         'hormone_receptor_status']

        for field in status_fields:
            assert field in item, self._debug(item, field)

            if field not in ['dfci_investigator', 'hormone_receptor_status']:
                assert item[field], '%s| %s' % (field, item)

        # remove all fields and validate that the summary will not error
        del on_trial['age']
        del on_trial['phase']
        del on_trial['nct_id']
        del on_trial['protocol_no']
        del on_trial['principal_investigator']
        del on_trial['cancer_center_accrual_goal_upper']
        del on_trial['site_list']
        del on_trial['sponsor_list']
        del on_trial['drug_list']
        del on_trial['staff_list']

        status, trial_tree = me.create_trial_tree(on_trial, no_validate=True)
        summary = Summary(on_trial['_clinical'],
                          on_trial['_genomic'],
                          other,
                          trial_tree)
        item = summary.create_summary(on_trial)

        for field in status_fields:
            assert field in item, self._debug(item, field)
Example #49
0
    def setUp(self, settings_file=None, url_converters=None):

        super(TestResponse, self).setUp(settings_file=None, url_converters=None)
        self.user_token = None

        # add to database
        self.db = get_db()
        self.db.response.drop()
        self.db['clinical'].insert_one(self.fake_patient)
        self.db['match'].insert_one(self.match_flagged)
        self.db['filter'].insert_one(self.fake_filter)
        self.db['user'].insert_one(self.fake_filter_owner)
        self.db['response'].insert_many(demo_resps)
        self.response_ids = [resp['_id'] for resp in demo_resps]
        self.email_ids = [email['_id'] for email in list(self.db['email'].find())]
Example #50
0
    def setUp(self):
        self.db = get_db()
        self.db.negative_genomic.drop()

        self.item = {
            'clinical_id': ObjectId(),
            'sample_id': 'XXXX',
            'true_hugo_symbol': 'PTEN',
            'true_transcript_exon': 1,
            'true_codon': None,
            'coverage': 100000.,
            'coverage_type': 'PN',
            'panel': 'None',
            'roi_type': 'G'
        }
Example #51
0
    def test_trial_normalization(self):

        db = get_db()
        db['normalize'].insert(MAPPING)

        # define test json
        with open(os.path.join(YAML_DIR, "00-001.yml")) as fin:
            test_json = yaml.load(fin)

        # do the mapping.
        UtilHooks.NormalizeHook.entry_insert("trial", [test_json])

        trial_insert([test_json])

        db['normalize'].drop()
Example #52
0
    def setUp(self):
        self.db = get_db()
        self.db.negative_genomic.drop()

        self.item = {
            'clinical_id': ObjectId(),
            'sample_id': 'XXXX',
            'true_hugo_symbol': 'PTEN',
            'true_transcript_exon': 1,
            'true_codon': None,
            'coverage': 100000.,
            'coverage_type': 'PN',
            'panel': 'None',
            'roi_type': 'G'
        }
Example #53
0
def reannotate_trials():

    # connect to the database.
    db = database.get_db()

    # get all trials.
    trials = list(db['trial'].find())

    # call hooks.
    events.trial_insert(trials)

    # re-insert.
    for trial in trials:
        db['trial'].delete_one({'_id': trial['_id']})
        db['trial'].insert_one(trial)
Example #54
0
def maintain_users():
    """
    ensure all users have a role

    :return:
    """
    logging.info("maintain users")

    # get database connection.
    db = database.get_db()

    # find all filters status.
    users = list(db['user'].find())

    # check each user.
    for user in users:
        if 'roles' not in user:
            db['user'].update_one({"_id": user['_id']}, {"$set": {"roles": ["user"]}})
Example #55
0
    def test_extract_genes(self):

        m = MatchEngine(get_db())
        match_tree = trial['treatment_list']['step'][0]['match'][0]
        g = m.create_match_tree(match_tree)
        pmt = ParseMatchTree(g)
        genes = pmt.extract_genes()

        assert 'BRAF' in genes, genes
        assert 'KRAS' in genes, genes
        assert 'EGFR' not in genes
        assert 'test' not in genes, genes
        assert len(genes) == 2, genes

        match_tree = trial['treatment_list']['step'][0]['match'][2]
        g = m.create_match_tree(match_tree)
        pmt = ParseMatchTree(g)
        genes = pmt.extract_genes()
        assert 'BRAF' not in genes, genes
Example #56
0
    def test_ms_status(self):

        on_trial['_clinical'] = {}
        on_trial['_genomic'] = {'mmr_status': [{'value': 'MMR-Proficient'}]}
        db = get_db()
        me = MatchEngine(db)
        status, trial_tree = me.create_trial_tree(on_trial, no_validate=True)
        summary = Summary(on_trial['_clinical'],
                          on_trial['_genomic'],
                          {},
                          trial_tree)
        item = summary.create_summary(on_trial)
        assert 'mmr_status' in item, self._debug(item, 'mmr_status')

        on_trial['_genomic'] = {'ms_status': [{'value': 'MSI-H'}]}
        status, trial_tree = me.create_trial_tree(on_trial, no_validate=True)
        summary = Summary(on_trial['_clinical'],
                          on_trial['_genomic'],
                          {},
                          trial_tree)
        item = summary.create_summary(on_trial)
        assert 'ms_status' in item, self._debug(item, 'ms_status')
Example #57
0
    def  mapping_oncotree(self):

        # insert the mapping
        db = get_db()
        mapping = {
            "key": "trial",
            "values": {
                "oncotree_primary_diagnosis": {"cns/brain": "CNS/Brain"}
            }
        }
        db['normalize'].insert(mapping)

        # set data example
        data = {'match': [{'or': [{'or': [{'clinical': {'oncotree_primary_diagnosis': 'Breast', 'age_numerical': '>=18'}}, {
            'clinical': {'oncotree_primary_diagnosis': 'Renal Cell Carcinoma', 'age_numerical': '>=18'}}, {
                                    'clinical': {'oncotree_primary_diagnosis': 'Pleural Mesothelioma',
                                                 'age_numerical': '>=18'}}, {
                                    'clinical': {'oncotree_primary_diagnosis': 'Peritoneal Mesotheliom',
                                                 'age_numerical': '>=18'}}, {
                                    'clinical': {'oncotree_primary_diagnosis': 'Gastrointestinal Stromal Tumor',
                                                 'age_numerical': '>=18'}}]}, {'and': [{'or': [
            {'genomic': {'wildcard_protein_change': 'p.G12', 'hugo_symbol': 'KRAS'}},
            {'genomic': {'wildcard_protein_change': 'p.G13', 'hugo_symbol': 'KRAS'}},
            {'genomic': {'wildcard_protein_change': 'p.Q61', 'hugo_symbol': 'KRAS'}}]}, {'clinical': {
            'oncotree_primary_diagnosis': 'Lung Adenocarcinoma', 'age_numerical': '>=18'}}]}, {'and': [{'or': [
            {'genomic': {'variant_category': 'Mutation', 'hugo_symbol': 'IDH1'}},
            {'genomic': {'variant_category': 'Mutation', 'hugo_symbol': 'IDH2'}}]}, {'and': [
            {'clinical': {'oncotree_primary_diagnosis': '_SOLID_', 'age_numerical': '>=18'}},
            {'clinical': {'oncotree_primary_diagnosis': '!CNS/Brain', 'age_numerical': '>=18'}}]}]}, {
                            'and': [{'genomic': {'hugo_symbol': 'MYC', 'cnv_call': 'High Amplification'}}, {
                                'clinical': {'oncotree_primary_diagnosis': '_SOLID_', 'age_numerical': '>=18'}}]}]}]}

        # do the mapping.
        UtilHooks.NormalizeHook.entry_insert("trial", [data])

        # assert it is updated.
        assert data['match'][0]['or'][2]['and'][1]['and'][1]['clinical']['oncotree_primary_diagnosis'] == '!CNS/Brain'
Example #58
0
    def setUp(self, settings_file=None, url_converters=None):

        # call parent
        super(TestNegGenomic, self).setUp(settings_file=None, url_converters=None)

        # switch to service account.
        self.user_token = self.service_token

        self.db = get_db()
        self.db.negative_genomic.drop()

        self.clinical_id = ObjectId()
        self.db.clinical.insert_one({'_id': self.clinical_id})
        self.item = {
            'clinical_id': str(self.clinical_id),
            'sample_id': 'XXXX',
            'true_hugo_symbol': 'PTEN',
            'true_transcript_exon': 1,
            'true_codon': None,
            'coverage': 100000.,
            'coverage_type': 'PN',
            'panel': 'none',
            'roi_type': 'G'
        }
Example #59
0
def email_user(items):

    # skip unless production.
    if settings.WELCOME_EMAIL != "YES":
        logging.debug("welcome email skipped")
        return

    # loop over each user.
    for user in items:

        # do not email users not approved by Susan
        if user['user_name'] == '':
            continue

        # generate email.
        recipient_email = user['email']

        # create the message.
        cur_date = datetime.date.today().strftime("%B %d, %Y")
        cur_stamp = datetime.datetime.now().strftime("%I:%M%p on %B %d, %Y")

        # generate text
        html = _user_email_text(user, cur_date, cur_stamp)

        db = database.get_db()
        email_item = {
            'email_from': settings.EMAIL_AUTHOR_PROTECTED,
            'email_to': recipient_email,
            'subject': 'Welcome to MatchMiner - %s' % cur_date,
            'body': html,
            'cc': [],
            'sent': False,
            'num_failures': 0,
            'errors': []
        }
        db['email'].insert(email_item)
Example #60
0
def email_matches():

    # get the database links.
    match_db = database.get_collection("match")
    user_db = database.get_collection('user')
    filter_db = database.get_collection('filter')

    logging.info("starting email search")

    # get distinct list of team ids
    teams = match_db.find().distinct("TEAM_ID")

    # loop over each team.
    message_list = []
    for teamid in teams:

        # get the counts.
        num_filters, num_matches = _email_counts(teamid, match_db, filter_db)

        # skip if no updates.
        if num_matches < 1:
            continue

        # get users in this team
        team_members = list(user_db.find({'teams': {'$elemMatch': {'$in': [teamid]}}}))
        for user in team_members:

            # skip if silenced.
            if 'silent' in user and user['silent']:
                continue

            # simplify.
            recipient_email = user['email']
            match_str = "matches"
            if num_matches == 1:
                match_str = "match"

            # create the message.
            cur_date = datetime.date.today().strftime("%B %d, %Y")
            cur_stamp = datetime.datetime.now().strftime("%I:%M%p on %B %d, %Y")

            # generate text
            html = _email_text(user, num_matches, match_str, num_filters, cur_date, cur_stamp)

            db = database.get_db()
            email_item = {
                'email_from': settings.EMAIL_AUTHOR_PROTECTED,
                'email_to': recipient_email,
                'subject': 'New MatchMiner Hits - %s' % cur_date,
                'body': html,
                'cc': [],
                'sent': False,
                'num_failures': 0,
                'errors': []
            }
            db['email'].insert(email_item)

            message_list.append(html)

    # return the message lists
    return message_list