示例#1
0
文件: results.py 项目: faanwar/avrc
def is_otp_sent(rcid, mode, contact):
    try:              
      if contact is '' or contact == None:
        raise  
        
      if mode == 'EMAIL' or Config.getboolean('aeh:results', 'otp_mock') == True :
        phone = Config.get('aeh:results','otp_mock_phone') 
      else:
        phone = contact
               
      #og.info("Phone number is:%s", phone)
      Response = requests.post(Config.get('aeh:results','otp_gen_url'), {
                              'phone': phone,
                              'userid': rcid,
                              'lifetime': Config.get('aeh:results', 'otp_lifetime'),
                              'key': Config.get('aeh:results', 'otp_key')})
                              
      status = json.loads(Response.text)
      #log.info(Response.text)
      # Textbelt doesn't email otps we do it
      if mode == 'EMAIL' and status['success'] == True:
        turbomail.send(turbomail.Message(
                        author = "ucsd - leadtheway<" + mail_settings["remind.email"] + ">",
                        organization = ["ucsd - leadtheway"],
                        bcc = [contact],
                        subject = "Your Verification Code",
                        reply_to = mail_settings["remind.email"],
                        plain = "Your verification code for access is " + status['otp'] + "."))
      
      return status['success'], status

    except:
      #log.critical(traceback.format_exc())
      return False, None
示例#2
0
def send_mail(sender_email, recipients_email, subject, body):
    """Send an email with  info to the user.
    """

    #if not sender_email or not  admin_email:
    #    log.exception('Configuration error: could not send error'
    #      'because sender and/or admin email address is not set.')
    #    raise RuntimeError

    if not isinstance(recipients_email, list):
        recipients_email = [recipients_email]

    msg = turbomail.Message(sender_email, ",".join(recipients_email), subject)
    msg.plain = body
    try:
        log.debug("Sending mail to %s %s", recipients_email, subject)
        turbomail.send(msg)
        return True
    except turbomail.MailNotEnabledException:
        log.warning("Failed sending %s with '%s' turbomail not enabled",
                    recipients_email, subject)
    except (smtplib.SMTPException, socket.error) as exc:
        log.warning("Failed sending %s with '%s'",
                    recipients_email,
                    subject,
                    exc_info=True)

    return False
示例#3
0
def main():
    try:
        args = cli.parse_args()
        settings = args.settings

        if settings['otp_mock'] == 'true':
            patient = get_patient(settings['otp_mock_rcid'], settings)
            patient['phone1'] = settings['otp_mock_phone']
            log.info("Patient Info: %s", patient)
            sent_otp, status = is_otp_sent(patient, settings)
            if sent_otp == True:
                log.info("Intentional %d sec delay", 15)
                time.sleep(15)
                if is_otp_valid(str(status['otp']), patient, settings) == True:
                    log.info("Successful OTP Verfication. OTP: %s",
                             status['otp'])
                else:
                    raise Exception("Invalid OTP")
            else:
                raise Exception("OTP not sent!")

    except Exception as e:
        log.critical(traceback.format_exc())
        turbomail.send(
            turbomail.Message(to=settings['notify.error'].split(),
                              subject='[Early Test]: OTP Exception',
                              plain=traceback.format_exc()))
示例#4
0
文件: __init__.py 项目: mbbui/Jminee
def send_email(to_addr, from_addr, subject, body):
    # Using turbomail if it exists, 'dumb' method otherwise
    if turbomail and config.get('mail.on'):
        msg = turbomail.Message(from_addr, to_addr, subject)
        msg.plain = body
        turbomail.send(msg)
    else:
        _plain_send_mail(from_addr, to_addr, subject, body)
示例#5
0
def send_mail(sender, to, subject, body, **kwargs):
    from turbomail import MailNotEnabledException
    try:
        message = turbomail.Message(sender, to, subject, **kwargs)
        message.plain = body
        turbomail.send(message)
    except MailNotEnabledException:
        log.warning("TurboMail is not enabled!")
    except Exception:
        log.exception("Exception thrown when trying to send mail")
示例#6
0
文件: mail.py 项目: walbon/beaker
def send_mail(sender, to, subject, body, **kwargs):
    from turbomail import MailNotEnabledException
    try:
        message = turbomail.Message(sender, to, subject, **kwargs)
        message.plain = body
        turbomail.send(message)
    except MailNotEnabledException:
        log.warning("TurboMail is not enabled!")
    except Exception:
        log.exception("Exception thrown when trying to send mail")
示例#7
0
文件: __init__.py 项目: mbbui/Jminee
def send_email2(to_addr, from_addr, subject, plain, rich):
    # Using turbomail if it exists, 'dumb' method otherwise
    if turbomail and config.get('mail.on'):
        msg = turbomail.Message(from_addr, to_addr, subject)
        if rich:
            msg.rich = rich
        msg.plain = plain
        turbomail.send(msg)
    else:
        ##TODO: should raise exception here
        pass        
示例#8
0
def main():
    try:
        args = cli.parse_args()
        settings = args.settings

        send_reminder(settings)

    except Exception as e:
        log.critical(traceback.format_exc())
        turbomail.send(
            turbomail.Message(
                to=settings['notify.error'].split(),
                subject='[The Early Test]: Reminder Email Exception!',
                plain=traceback.format_exc()))
示例#9
0
def send_mail(sender, to, subject, body, bulk=True, **kwargs):
    from turbomail import MailNotEnabledException
    try:
        message = turbomail.Message(sender, to, subject, **kwargs)
        if bulk:
            message.headers.extend([
                ('Auto-Submitted', 'auto-generated'),
                ('Precedence', 'bulk'),
            ])
        message.plain = body
        turbomail.send(message)
    except MailNotEnabledException:
        log.warning("TurboMail is not enabled!")
    except Exception:
        log.exception("Exception thrown when trying to send mail")
示例#10
0
def send_mail(sender, to, subject, body, bulk=True, **kwargs):
    from turbomail import MailNotEnabledException
    try:
        message = turbomail.Message(sender, to, subject, **kwargs)
        if bulk:
            message.headers.extend([
                ('Auto-Submitted', 'auto-generated'),
                ('Precedence', 'bulk'),
            ])
        message.plain = body
        turbomail.send(message)
    except MailNotEnabledException:
        log.warning("TurboMail is not enabled!")
    except Exception:
        log.exception("Exception thrown when trying to send mail")
示例#11
0
文件: sync.py 项目: faanwar/avrc
def main():
    try:
        args = cli.parse_args()
        settings = args.settings

        buckets = bucketize_results()
        sync_sql_result(buckets, settings)

    except Exception as e:
        log.critical(e)
        turbomail.send(
            turbomail.Message(
                to=settings['notify.error'].split(),
                subject=
                '[The Early Test]: RedCAP - SQLite DB Synchronization Error!',
                plain=traceback.format_exc()))
示例#12
0
def connect_project(settings):
    url = settings['cap_url']
    key = settings['cap_key']
    exp_date = settings['exp_date']

    try:
        if datetime.datetime.strptime(
                exp_date, "%Y-%m-%d").date() <= datetime.date.today():
            raise exc.RedCAPTokenExpired(exp_date)
        project = Project(url, key, verify_ssl=True)
        log.info('Project connected: %s' % project)
    except:
        log.critical('Exception on RedCap Project connect')
        turbomail.send(
            turbomail.Message(
                to=settings['notify.error'].split(),
                subject='[The Early Test]: RedCap Connection failure',
                plain=traceback.format_exc()))
        raise
    return project
示例#13
0
def send_reminder(settings):
    """ 
      Parameters: 
            
            buckets: Dict of site codes and list of Results for that site as key, value pairs
            
            settings: A dictionary of settings specified in the configuration file            
      Returns None
  """
    try:
        log.info("Early Test Email Alerts are about to be sent")
        ses_key_id = settings['ses_key_id']
        ses_key = settings['ses_key']
        rcs = json.loads(open(settings['redcap_json'], 'r').read())

        # Read from the configuration files
        rem_keys = settings['rem.codes'].split()

        pat_keys = settings['pat.codes'].split()

        keys = rem_keys + pat_keys

        months_to_notify = int(settings['months.tonotify'])

        # Connect to all the required projects in RedCAP
        redcap = RCProject(keys, rcs)
        staff_emails = get_receipients(redcap, '1')
        staff_emails_other = get_receipients(redcap, '2')

        #send other email reminders
        sdun_patient_count, sdun_emails_sent, sdun_invalid_emails_count = send_reminder_single(
            ses_key_id, ses_key, settings, staff_emails_other,
            months_to_notify)
        er_patient_count, er_emails_sent, er_invalid_emails_count, asr_patient_count, asr_emails_sent, asr_invalid_emails_count = send_reminder_etc(
            ses_key_id, ses_key, settings, staff_emails_other,
            months_to_notify)

        # Required Patient Fields
        pfields = [
            'et_pid', 'rc_id', 'phone1', 'phone2', 'email1', 'email2',
            'first_name', 'last_name'
        ]
        precords = {}

        for key in pat_keys:
            precords[key] = redcap.project[key].export_records(fields=pfields)

        # This dictionary holds a map of Patient email to a list of
        # rc_ids of that specific patient
        # NOTE: The rc_ids may also belong to multiple sites.
        hash_email = {}

        # This is a dictionary to the email ids of patients to their names
        hash_names = {}

        # This dictionary will hold the list of rcid to specific
        # sites, and therefore prevent multiple calls to the
        # RedCAP rest APIs.
        site_rcid = {}

        for site in rem_keys:
            site_rcid[site] = []

        # Today we have a single redcap project for patients. In the future
        # there can be multiple projects for patients. The below code will
        # still work and have a better performance.

        import sys
        for pat_key, pat_records in precords.iteritems():
            log.debug("Total of patient records in %s =  %d", pat_key,
                      len(pat_records))
            log.debug("The size of the records: %d Bytes",
                      sys.getsizeof(pat_records))

            # Patient Records that need to be updated
            # with working primary email for this site
            to_update = []
            invalid_emails = {}
            for patient in pat_records:
                try:

                    # Extract Site information
                    #site = patient['rc_id'].upper()

                    # The testing site visited by this patient is not configured
                    # to send email reminders. So continue to the next patient
                    #if site.startswith(tuple(rem_keys)) == False:
                    #continue
                    if patient['email1'] == '':
                        # ignore patients for whom we don't have email IDs
                        if patient['email2'] == '':
                            continue
                        else:
                            # Set the primary email and delete the secondary
                            patient['email1'] = patient['email2']
                            patient['email2'] = ''
                            to_update.append(patient)

                    if patient['et_pid'] in hash_email:
                        continue
                    else:
                        hash_email[patient['et_pid']] = [patient['email1']]
                        hash_names[patient['et_pid']] = {
                            'first_name': patient['first_name'],
                            'last_name': patient['last_name']
                        }

                    #site_rcid[patient['rc_id'][:-5]].append(patient['rc_id'])
                except KeyError as e:
                    log.critical(traceback.format_exc())
                    pass
            """if len(to_update) > 0:
        try:
          #updated_count = redcap.project[pat_key].import_records(to_update)
          log.debug(" %d Emails needed to be moved from email2 to email1 for %s", len(to_update), pat_key)
        except:
          log.critical(traceback.format_exc())
          pass"""

            # Some stats to log
            log.debug("Unique Patient with email Ids: %d",
                      len(hash_email.keys()))
            #for email, visits in hash_email.iteritems():
            #  log.debug("Patient Email: %s, Number of Visits: %d", email, len(visits))

            #History of the patients as a list returned by redcap
            patient_history = []

            # We need the following fields to decide if we need to send emails for this patient
            fields = [
                'et_pid', 'rc_id', 'visit_date', 'rapid1', 'rapid2',
                'testing_reminder', 'dhiv', 'lstremndr_dt'
            ]
            #for site, records in hash_email.iteritems():
            patient_history.extend(
                redcap.project['SDET'].export_records(fields=fields))
            patient_history.extend(
                redcap.project['76C'].export_records(fields=fields))
            log.debug("Total Patient history to Process:%d",
                      len(patient_history))

            # Patient history modified data structure for convenience
            hist_map = {}
            for history in patient_history:
                hist_map[history['rc_id']] = history

            count = 0
            for key, val in hash_email.iteritems():
                print 'key'
                print key
                print 'value'
                print val
                latest_record = None
                # At the end of the following loop, record will consists of the latest visit
                # information for this patient.(Indicated by the email string 'key')
                skip = False
                for rc_id, visit_val in hist_map.iteritems():
                    try:
                        if visit_val['et_pid'] != key:
                            continue
                        if visit_val['visit_date'] == '':
                            continue
                        print 'visit date exists'
                        print 'rcid'
                        print rc_id
                        print 'visit'
                        print visit_val
                        visit = datetime.strptime(visit_val['visit_date'],
                                                  "%Y-%m-%d")
                        if latest_record == None:
                            latest_record = visit_val
                        else:
                            latest_date = datetime.strptime(
                                latest_record['visit_date'], "%Y-%m-%d")
                            if latest_date <= visit:
                                print 'compare dates'
                                print visit
                                print latest_date
                                latest_record = hist_map[rc_id]
                    except KeyError:
                        log.critical(traceback.format_exc())

                print 'latest record'
                print latest_record
                if latest_record == None:
                    continue
                notify, months = is_reminder_required(latest_record,
                                                      months_to_notify)
                if notify == True:
                    print 'patient email process initiated ' + hash_names[key][
                        'first_name']
                    # We could send messages in bulk if it had a common body. But since the body is
                    # unique for every recipient we have to go through the non-performant process
                    # of sending one email at a time
                    template_input = {
                        'username':
                        hash_names[key]['first_name'],
                        'months':
                        months,
                        'visit_date':
                        latest_record['visit_date'],
                        'ltw_url':
                        settings['ltw_url'],
                        'unsubscribe_url':
                        settings['unsubscribe_url'] + '?email=' + val[0] +
                        "&rc_id=" + latest_record['rc_id'] +
                        "&unsubscribe.submitted=Unsubscribe",
                        'phone':
                        settings['phone'],
                        'email':
                        val[0]
                    }
                    try:
                        #turbomail.send(turbomail.Message(
                        #              author="UCSD - Good to Go<" + settings["remind.email"] + ">",
                        #              organization=["UCSD - Good to Go"],
                        #              bcc=[key],
                        #              reply_to=settings["remind.email"],
                        #              subject="UCSD Early Test - Good to Go reminders",
                        #              rich = lookup.get_template('email/reminder.mako').render(**template_input),
                        #              headers =  {'list-unsubscribe': "<" + template_input['unsubscribe_url']
                        #                                                   + ">,<mailto:" + settings["remind.email"] +">"},
                        #              plain = "this is a reminder email to complete early test at " + settings['ltw_url']))
                        p_email = []
                        p_email.append(val[0])
                        text = lookup.get_template(
                            'email/reminder.mako').render(**template_input)
                        send_email(
                            text, "UCSD Early Test - Good to Go reminders",
                            "UCSD - Good to Go<" + settings["remind.email"] +
                            ">", p_email, ses_key_id, ses_key, "html")

                        count = count + 1
                        match = next(d for d in patient_history
                                     if d['rc_id'] == latest_record['rc_id'])
                        print 'patient email date record '
                        print match
                        if match != '':
                            match['lstremndr_dt'] = datetime.today().date(
                            ).strftime('%Y/%m/%d')

                    except:
                        invalid_emails[latest_record['et_pid']] = val[0]
                        log.critical(traceback.format_exc())
                        pass

            try:
                redcap.project[site].import_records(patient_history)
                print 'patient email date updated'
            except:
                pass
            # Delete invalid email Ids from redcap. A hashSet is handy for this operation
            # invalid_emails = set(invalid_emails)

            invalid_emails_count = len(invalid_emails.keys())

            if invalid_emails_count > 0:
                with open(
                        '/var/tmp/invalid_emails_' + pat_key +
                        str(datetime.today().date()), 'wr+') as f:
                    json.dump(invalid_emails, f)
            """ This logic will be commented out, until the script is mature 
      and all other features are well tested

      # Remove wrong email ids from redcap
      for pat_key, pat_records in precords.iteritems():
        try:
          to_update = []
          for patient in pat_records:
            if patient['email1'] in invalid_emails:
              patient['email1'] = ''
              to_update.append(patient)
              log.debug("Rcid: %s, Email: %s is removed as invalid from redcap", patient['rc_id'], patient['email1'])         
          updated_count = redcap.project[pat_key].import_records(to_update)
      
        except Exception as e:
          log.critical
          pass
      """
            log.debug("Total Emails sent out today:%d", count)
            print 'data'
            print len(hash_email.keys())
            print count
            print invalid_emails_count
            print staff_emails
            stats = {
                'date': datetime.today().date(),
                'sdet_patient_count': len(hash_email.keys()),
                'sdet_emails_sent': count,
                'sdet_invalid_emails_count': invalid_emails_count,
                'sdun_patient_count': sdun_patient_count,
                'sdun_emails_sent': sdun_emails_sent,
                'sdun_invalid_emails_count': sdun_invalid_emails_count,
                'asr_patient_count': asr_patient_count,
                'asr_emails_sent': asr_emails_sent,
                'asr_invalid_emails_count': asr_invalid_emails_count,
                'er_patient_count': er_patient_count,
                'er_emails_sent': er_emails_sent,
                'er_invalid_emails_count': er_invalid_emails_count
            }
            try:
                text = lookup.get_template('email/stats.mako').render(**stats)
                #turbomail.send(turbomail.Message(
                #                author = "UCSD - Good to Go<" + settings["remind.email"] + ">",
                #                organization = ["UCSD - Good to Go"],
                #                to = staff_emails,
                #                reply_to = settings["remind.email"],
                #                subject = "Good to Go Email Reminders Statistics",
                #                plain = text))

                #send_email(text, "SDET: Good to Go Email Reminders Statistics", "UCSD - Good to Go<" + settings["remind.email"] + ">", staff_emails, ses_key_id, ses_key, "plain")
                send_email(
                    text, "Good to Go Email Reminders Statistics",
                    "UCSD - Good to Go<" + settings["remind.email"] + ">",
                    staff_emails, ses_key_id, ses_key, "plain")

            except:
                log.debug(
                    lookup.get_template('email/stats.mako').render(**stats))
                log.critical(traceback.format_exc())

    except:
        log.critical(traceback.format_exc())
        turbomail.send(
            turbomail.Message(
                to=settings['notify.error'].split(),
                subject=
                '[Early Test Reminders]:There is an exception in sending out monthly reminders!',
                plain=traceback.format_exc()))
示例#14
0
文件: sync_cts.py 项目: faanwar/avrc
def main():
    args = cli.parse_args()
    settings = args.settings

    days_till_expiration = int(settings['days.tillexpiration'])
    days_till_notify = int(settings['days.tillnotify'])

    try:
        results = sync_redcap.get_cts_results(settings)
        if not args.dry:
            Session.add_all(results)
            Session.commit()

        else:
            log.info('Dry run, not commiting changes')

        sync_site_codes = settings.get('site.codes').split()
        ucsd_site_codes = settings.get('ucsd.site.codes').split()
        emory_site_codes = settings.get('emory.site.codes').split()
        gwu_site_codes = settings.get('gwu.site.codes').split()

        rcs = json.loads(open(settings['redcap_json'], 'r').read())
        redcap = RCProject(sync_site_codes, rcs)
        # Refresh results
        for site_code in sync_site_codes:
            print 'site code'
            print site_code
            for type_ in models.TYPES:
                #notify = settings.get('notify.%s.%s' % (site_code.lower(), type_.lower()), '').split()
                notify = []
                print type_
                pnt = list(
                    r for r in results
                    if r.check(type_) is True and r.site_code == site_code)
                neg = [
                    r for r in results
                    if r.check(type_) is False and r.site_code == site_code
                ]
                odd = [
                    r for r in results
                    if r.check(type_) is None and r.site_code == site_code
                ]

                if not (pnt):
                    continue
                'clear'
                if type_ == 'dhiv':
                    notify = get_receipients(redcap, 'hiv_pos', site_code,
                                             ucsd_site_codes, emory_site_codes,
                                             gwu_site_codes)
                    t_type = 'HIV'
                elif type_ == 'dhcv':
                    notify = get_receipients(redcap, 'hcv_pos', site_code,
                                             ucsd_site_codes, emory_site_codes,
                                             gwu_site_codes)
                    t_type = 'HCV'
                elif type_ == 'dhbv':
                    notify = get_receipients(redcap, 'hbv_pos', site_code,
                                             ucsd_site_codes, emory_site_codes,
                                             gwu_site_codes)
                    t_type = 'HBV'

                print notify
                if not notify:
                    continue

                turbomail.send(
                    turbomail.Message(
                        to=notify,
                        subject='New %s+ NAT' % t_type,
                        plain=lookup.get_template('email/parse.mako').render(
                            **{
                                'timestamp': datetime.datetime.now(),
                                'type_': t_type,
                                'site_code': site_code,
                                'pnt': pnt,
                                'neg': neg,
                                'odd': odd
                            })))

                log.info('Notified %s mailing lists of results for "%s"' %
                         (site_code, type_))

        for code in sync_site_codes:
            results_count = 0
            shouldNotify = False

            # Get number of site specific results in this upload
            for r in results:
                if r.site_code == code.upper():
                    results_count += 1

            # Get list of results with missing draw dates
            missing_draw = find_missing_draw(days_till_expiration, code)
            missing_draw_count = len(missing_draw)

            # Get list of draw dates with missing Red Cross results that are more than 7 days old
            missing_results = find_missing_results(days_till_notify,
                                                   days_till_expiration,
                                                   redcap, code)
            missing_results_count = len(missing_results)

            # Notify recipients if there is anything to notify about
            if results_count > 0 or missing_results_count > 0 or missing_draw_count > 0:
                shouldNotify = True

            if shouldNotify:
                #notify = settings.get('notify.%s.sync' % code.lower()).split()
                notify = get_receipients(redcap, 'date_missing', code,
                                         ucsd_site_codes, emory_site_codes,
                                         gwu_site_codes)
                # Notify appropriate people about missing draw dates and Red Cross results
                turbomail.send(
                    turbomail.Message(
                        to=notify,
                        subject=
                        '[The Early Test]: Red Cross Synchronize Report (%s)' %
                        code,
                        plain=lookup.get_template('email/sync.mako').render(
                            **{
                                'timestamp': datetime.datetime.now(),
                                'results_count': results_count,
                                'missing_draw_count': missing_draw_count,
                                'missing_draw': missing_draw,
                                'missing_results_count': missing_results_count,
                                'missing_results': missing_results,
                                'days_till_notify': days_till_notify,
                                'code': code
                            })))

                log.info(
                    'Notified mailing lists of %s for missing draw dates' %
                    (code))
                log.info(
                    'Notified mailing lists of %s diagnostic for missing Red Cross results'
                    % (code))

    except:
        # If an unexpected error occurs, let the developers know
        turbomail.send(
            turbomail.Message(
                to=settings['notify.error'].split(),
                subject='[The Early Test]: Parser failed execution',
                plain=traceback.format_exc()))
        raise
示例#15
0
文件: sync.py 项目: faanwar/avrc
def sync_sql_result(buckets, settings):
    """ 
      Parameters: 
            
            buckets: Dict of site codes and list of Results for that site as key, value pairs
            
            settings: A dictionary of settings specified in the configuration file            
      Returns None
  """
    try:
        log.info("Synchronization Routine Started")
        #only two attributes could have been updated Draw Date or Location
        #Result should not be modified in the RedCAP directly

        rcs = json.loads(open(settings['redcap_json'], 'r').read())

        # Days after which results become invalid
        days_till_expiration = int(settings['days.tillexpiration'])

        # Days after which results can be published to patients
        days_till_notify = int(settings['days.tillnotify'])

        # Days after which tester should definitely act ASAP on CRF's or redcap entries
        days_till_urgent = int(settings['days.tillurgent'])

        pk_sites = settings.get('pk_site').split()
        redcap = RCProject(buckets.keys(), rcs)

        for key, value in buckets.iteritems():

            ctsrecords = []
            # These malformed draw dates need to be handled offline. This script will only be
            # reporting such entries
            malformed_draw = []

            # Unmindful check. This line is mostly a deadcode, I guess.
            if key not in redcap.project.keys():
                continue
            print 'key'
            print key
            #fields = ['visit_date','test_site']

            # we pass the 'label' flag to get the location value as string instead numeric values
            records = []
            if redcap.project[key].is_longitudinal(
            ) == True or key in pk_sites:
                print 'is logitudinal'
                print key
                l_records = redcap.project[key].export_records()
                records = list(x for x in l_records if x['rc_id'] in value)
            else:
                records = redcap.project[key].export_records(
                    records=value,
                    fields=redcap.nat_fields,
                    raw_or_label='label')

            ctsrecord = redcap.project['CTS'].export_records(
                records=value, fields='rec_status')

            for each in ctsrecord:
                new_ctsrecord = {}
                new_ctsrecord['rc_id'] = each['rc_id']
                new_ctsrecord['rec_status'] = 1

                ctsrecords.append(new_ctsrecord)

            # RCIDs for which we have new results will be in push records
            push_records = []
            for record in records:

                sql_row = Session.query(models.Result)\
                            .filter(models.Result.site_code == key)\
                            .filter(models.Result.reference_number == record['rc_id'][-5:]).first()

                # Visit/Draw date update in SQL DB
                if 'visit_date' in record.keys(
                ) and record['visit_date'] != '':
                    visit_date = dt.strptime(record['visit_date'],
                                             "%Y-%m-%d").date()
                    if sql_row.site_code == 'SDPT':
                        print 'dates not equal'
                        print sql_row.draw_date
                        print visit_date
                    if sql_row.draw_date != visit_date:

                        if sql_row.test_date >= visit_date:
                            print 'update visit date'
                            sql_row.draw_date = visit_date

                            min_visit_date = sql_row.test_date - datetime.timedelta(
                                days=int(settings['result_buffer']))
                            if visit_date < min_visit_date:
                                malformed_draw.append(record['rc_id'])

                        # The malformed draw dates are the ones that don't fall in to the
                        # accepted window for results. Just report them, nothin more.
                        else:
                            malformed_draw.append(record['rc_id'])

                # Location update in SQL DB
                if 'test_site' in record.keys() and record['test_site'] != '':
                    rc_location = ''
                    if redcap.project[key].is_longitudinal() == True:
                        labeled_recs = redcap.project[key].export_records(
                            raw_or_label='label')

                        fil_rec = list(x for x in labeled_recs
                                       if x['rc_id'] == record['rc_id'])[0]
                        rc_location = fil_rec['test_site']
                    else:
                        rc_location = record['test_site']
                    if sql_row.location != rc_location:
                        sql_row.location = rc_location

                # Keep track for bulk update in RedCAP later
                if 'nat_result_date' in record.keys():
                    if record['nat_result_date'] == '':
                        push_records.append(
                            update_result_redcap(record, sql_row))
                    else:
                        if 'nat_test_complete' in record.keys() and \
                            record['nat_test_complete'] == "Incomplete":
                            new_record = {}
                            new_record['rc_id'] = record['rc_id']
                            new_record['nat_test_complete'] = 2
                            push_records.append(new_record)

                Session.commit()

            # Make the bulk update for every 'key' and 'site'
            value = redcap.project[key].import_records(push_records)
            redcap.project['CTS'].import_records(ctsrecords)

            # The following lines form the sophisticated email system ;-P. Well we again
            # ask the human to help.

            malformed_draw_count = len(malformed_draw)
            # Get list of results with missing draw dates
            missing_draw, warn_draw, critical_draw = find_missing_draw(
                days_till_expiration, days_till_urgent, key)
            missing_draw_count = len(missing_draw)
            warn_draw_count = len(warn_draw)
            critical_draw_count = len(critical_draw)

            weekday = datetime.date.today().weekday()

            if warn_draw_count != 0 and time_in_range(
                    datetime.datetime.now().time()) and weekday == 5:
                #Special notifications when draw dates are missing for days_till_urgent
                # This notification is sent on Fridays(5)
                report_date = warn_draw
                report_date_count = warn_draw_count
                level = 1
                notify = settings.get('notify.%s.action' % key.lower()).split()
                turbomail.send(
                    turbomail.Message(
                        to=notify,
                        subject=
                        '[RedCAP Sync Update]: Prolonged Missing RedCAP Entries for (%s)'
                        % key,
                        plain=lookup.get_template('email/date.mako').render(
                            **{
                                'timestamp': datetime.datetime.now(),
                                'report_date': report_date,
                                'report_date_count': report_date_count,
                                'level': level,
                                'days_till_urgent': days_till_urgent,
                                'code': key
                            })))

            if critical_draw_count != 0:
                # Very critical draw date events emailed everyday
                # Between 8-9am

                time_now = datetime.datetime.now().time()
                if time_in_range(time_now):

                    log.info(
                        "Some of the draw dates are missing for over %d days" %
                        (int(days_till_urgent) + 2))
                    report_date = critical_draw
                    report_date_count = critical_draw_count
                    level = 2
                    notify = settings.get('notify.%s.action' %
                                          key.lower()).split()
                    turbomail.send(
                        turbomail.Message(
                            to=notify,
                            subject=
                            '[RedCAP Sync]: Action Required in RedCAP Entries for (%s)!'
                            % key,
                            plain=lookup.get_template(
                                'email/date.mako').render(
                                    **{
                                        'timestamp': datetime.datetime.now(),
                                        'report_date': report_date,
                                        'report_date_count': report_date_count,
                                        'level': level,
                                        'days_till_urgent': days_till_urgent,
                                        'code': key
                                    })))

            # Get list of draw dates with missing Red Cross results that are more than 7 days old
            missing_results = find_missing_results(days_till_notify,
                                                   days_till_expiration,
                                                   redcap, key)
            missing_results_count = len(missing_results)

            shouldNotify = False
            # Notify recipients if there is anything to notify about only if its a Monday
            if missing_results_count > 0 or missing_draw_count > 0 and datetime.date.today(
            ).weekday() == 1:
                shouldNotify = True

            if shouldNotify and time_in_range(datetime.datetime.now().time()):
                notify = settings.get('notify.%s.action' % key.lower()).split()

                # Notify appropriate people if notify is set to true
                turbomail.send(
                    turbomail.Message(
                        to=notify,
                        subject=
                        '[RedCAP Sync]: Synchronization Status Check (%s)' %
                        key,
                        plain=lookup.get_template('email/rcap.mako').render(
                            **{
                                'timestamp': datetime.datetime.now(),
                                'results_count': 0,
                                'missing_draw_count': missing_draw_count,
                                'missing_draw': missing_draw,
                                'missing_results_count': missing_results_count,
                                'missing_results': missing_results,
                                'days_till_notify': days_till_notify,
                                'days_till_urgent': days_till_urgent,
                                'code': key,
                                'malformed_draw_count': malformed_draw_count,
                                'malformed_draw': malformed_draw
                            })))

    except:
        turbomail.send(
            turbomail.Message(
                to=settings['notify.error'].split(),
                subject='[The Early Test]:Exception in matching visit dates!',
                plain=traceback.format_exc()))
示例#16
0
文件: parse.py 项目: faanwar/avrc
def main():
    args = cli.parse_args()
    settings = args.settings

    days_till_expiration = int(settings['days.tillexpiration'])
    days_till_notify = int(settings['days.tillnotify'])

    try:
        log.info('Called on %s' % args.srcfile)		
        results, duplicates = parser.parse(args.srcfile, settings)

        if not args.dry:
          
            if duplicates:
                raise Exception('\n'.join(
                    ['Already exists: %s%s' % (r.site_code, r.reference_number)
                    for r in duplicates]))

            # Archive processed file
            shutil.move(args.srcfile, settings['dir.raw'])
            log.info('Moved encrypted file to %s' % settings['dir.raw'])
	
      
            # Commit all changes now that we've successfully processed the file
            map(lambda r: setattr(r, 'file', os.path.basename(args.srcfile)), results)
            Session.add_all(results)
            Session.commit()

        else:
            log.info('Dry run, not commiting changes')

        
        sync_site_codes = settings.get('site.codes').split()
        rcs = json.loads(open(settings['redcap_json'], 'r').read())
        redcap = RCProject(sync_site_codes, rcs)
        # Refresh results
        for site_code in sync_site_codes:

            for type_ in models.TYPES:
                notify = settings.get('notify.%s.%s' % (site_code.lower(), type_.lower()), '').split()

                if not notify:
                    continue

                pnt = [r for r in results if r.check(type_) is True and r.site_code == site_code]
                neg = [r for r in results if r.check(type_) is False and r.site_code == site_code]
                odd = [r for r in results if r.check(type_) is None and r.site_code == site_code]

                if not (pnt or odd):
                    continue

                turbomail.send(turbomail.Message(
                    to=notify,
                    subject='[The Early Test]: New Records Notification (%s)' % type_,
                    plain=lookup.get_template('email/parse.mako').render(**{
                        'timestamp': datetime.datetime.now(),
                        'type_': type_,
                        'site_code': site_code,
                        'pnt': pnt,
                        'neg': neg,
                        'odd': odd})))

                log.info('Notified %s mailing lists of results for "%s"' % (site_code, type_))

        
        for code in sync_site_codes:
            results_count = 0
            shouldNotify = False

            # Get number of site specific results in this upload
            for r in results:
                if r.site_code == code.upper():
                    results_count += 1

            # Get list of results with missing draw dates
            missing_draw = find_missing_draw(days_till_expiration, code)
            missing_draw_count = len(missing_draw)

            # Get list of draw dates with missing Red Cross results that are more than 7 days old
            missing_results = find_missing_results(days_till_notify, days_till_expiration, redcap, code)
            missing_results_count = len(missing_results)
            
            # Notify recipients if there is anything to notify about
            if results_count > 0 or missing_results_count > 0 or missing_draw_count > 0:
                shouldNotify = True

            if shouldNotify:
                notify = settings.get('notify.%s.sync' % code.lower()).split()
                
                # Notify appropriate people about missing draw dates and Red Cross results
                turbomail.send(turbomail.Message(
                    to=notify,
                    subject='[The Early Test]: Red Cross Synchronize Report (%s)' % code,
                    plain=lookup.get_template('email/sync.mako').render(**{
                        'timestamp':      datetime.datetime.now(),
                        'results_count': results_count,
                        'missing_draw_count':  missing_draw_count,
                        'missing_draw':      missing_draw,
                        'missing_results_count': missing_results_count,
                        'missing_results': missing_results,
                        'days_till_notify': days_till_notify,
                        'code': code})))

                log.info('Notified mailing lists of %s for missing draw dates' % (code))
                log.info('Notified mailing lists of %s diagnostic for missing Red Cross results' % (code))

    except:
        # If an unexpected error occurs, let the developers know
        turbomail.send(turbomail.Message(
            to=settings['notify.error'].split(),
            subject='[The Early Test]: Parser failed execution',
            plain=traceback.format_exc()))
        raise