Skip to content

Commit

Permalink
Merge pull request #235 from mhearne-usgs/anchorfix
Browse files Browse the repository at this point in the history
Anchorfix
  • Loading branch information
emthompson-usgs authored Feb 21, 2019
2 parents 78bb536 + d0ac7bb commit ba96854
Show file tree
Hide file tree
Showing 48 changed files with 1,125 additions and 1,169 deletions.
182 changes: 108 additions & 74 deletions adminpager → bin/adminpager

Large diffs are not rendered by default.

File renamed without changes.
152 changes: 87 additions & 65 deletions emailpager → bin/emailpager
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,11 @@ ALERT_DICT = {'green': 0,
'orange': 2,
'red': 3}


def get_version(session, pdata, release=False, renotify=False):
eventid = pdata.id
event = session.query(es.Event).filter(es.Event.eventcode == eventid).first()
event = session.query(es.Event).filter(
es.Event.eventcode == eventid).first()
ccinfo = None
authid = eventid
if event is None:
Expand All @@ -41,7 +43,8 @@ def get_version(session, pdata, release=False, renotify=False):
allids.insert(0, authid)
allids.remove(eventid)
for testid in allids:
event = session.query(es.Event).filter(es.Event.eventcode == testid).first()
event = session.query(es.Event).filter(
es.Event.eventcode == testid).first()
if event is not None:
break
except:
Expand All @@ -67,7 +70,7 @@ def get_version(session, pdata, release=False, renotify=False):
if len(sversions) and renotify:
version = sversions[-1]
return (version, event, ccinfo)

prow = pdata.toSeries()
country = prow['Impacted Country ($)']
# Now create a new version
Expand All @@ -78,26 +81,27 @@ def get_version(session, pdata, release=False, renotify=False):
if pending == 'pending':
released = False
was_pending = True

alert = ALERT_DICT[pdata.summary_alert]
version = es.Version(versioncode = eventid,
time = pdata.time,
country = country,
lat = pdata.latitude,
lon = pdata.longitude,
depth = pdata.depth,
magnitude = pdata.magnitude,
number = len(event.versions) + 1,
fatlevel = ALERT_DICT[pdata.fatality_alert],
ecolevel = ALERT_DICT[pdata.fatality_alert],
summarylevel = alert,
released = released,
was_pending = was_pending,
processtime = pdata.processing_time,
maxmmi = pdata.maxmmi)
version = es.Version(versioncode=eventid,
time=pdata.time,
country=country,
lat=pdata.latitude,
lon=pdata.longitude,
depth=pdata.depth,
magnitude=pdata.magnitude,
number=len(event.versions) + 1,
fatlevel=ALERT_DICT[pdata.fatality_alert],
ecolevel=ALERT_DICT[pdata.fatality_alert],
summarylevel=alert,
released=released,
was_pending=was_pending,
processtime=pdata.processing_time,
maxmmi=pdata.maxmmi)
event.versions.append(version)
return (version, event, ccinfo)


def send_emails(version, addresses, properties, msg, subject, DEBUG, attachments=[]):
props = properties.copy()
props['recipients'] = [address.email for address in addresses]
Expand All @@ -114,31 +118,37 @@ def send_emails(version, addresses, properties, msg, subject, DEBUG, attachments
version.addresses += addresses
return version


def main(args):

DEBUG = False
if args.debug:
DEBUG = True

# get all of the information from the mail config file
config = read_mail_config()

if 'log_folder' in config:
eventid = args.eventid
tnowstr = datetime.utcnow().strftime('%Y%m%d%H%M%S')
logfile = os.path.join(config['log_folder'], 'emailpager_%s_%s.log' % (eventid, tnowstr))
logging.basicConfig(filename=logfile, level=logging.DEBUG, format='%(asctime)s %(message)s')
logfile = os.path.join(
config['log_folder'], 'emailpager_%s_%s.log' % (eventid, tnowstr))
logging.basicConfig(filename=logfile, level=logging.DEBUG,
format='%(asctime)s %(message)s')
else:
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(message)s')

logging.basicConfig(level=logging.DEBUG,
format='%(asctime)s %(message)s')

# check the status of the system - stop if we are NOT primary
if 'status' not in config or config['status'] != 'primary':
logging.warning('This system is not configured to send email. Stopping.')
logging.warning(
'This system is not configured to send email. Stopping.')
sys.exit(0)

# first make sure this is a losspager product
if args.type != 'losspager':
logging.warning('emailpager is only configured to work with losspager products. Exiting.')
if args.type not in ['losspager', 'losspager-admin']:
logging.warning(
'emailpager is only configured to work with losspager/losspager-admin products. Exiting.')
sys.exit(1)

# TODO: Do something with delete messages
Expand All @@ -149,7 +159,8 @@ def main(args):

jsondir = os.path.join(args.directory, 'json')
if not os.path.isdir(jsondir):
logging.warning('JSON directory "%s" containing PAGER output not found. Exiting.' % args.directory)
logging.warning(
'JSON directory "%s" containing PAGER output not found. Exiting.' % args.directory)
sys.exit(1)

# check to see if a --property-renotify option has been set
Expand All @@ -170,11 +181,10 @@ def main(args):
# scenario events are frequently set in the future. Since we NEVER anticipate
# wanting to send emails for scenario events for any reason, let's set a check
# for this. Times look like this: 2018-03-11T04:45:36.000Z
etime = datetime.strptime(args.time,'%Y-%m-%dT%H:%M:%S.%fZ')
etime = datetime.strptime(args.time, '%Y-%m-%dT%H:%M:%S.%fZ')
if etime > datetime.utcnow():
logging.warning('The event time stamp is in the future. Exiting.')
sys.exit(1)


# Everything is cool...
logging.debug('Loading from data directory...')
Expand All @@ -185,21 +195,23 @@ def main(args):
logging.debug('Connecting to database...')
dburl = config['email']['database']['url']
session = es.get_session(url=dburl, create_db=False)

# Find event in database, or create it if not found. Return a new version for that event,
# or (if event has just been released and previous version was not released, return most recent
# version with released column set to True.
logging.debug('Finding event in database...')
version, event, ccinfo = get_version(session, pdata, release=release, renotify=renotify)
version, event, ccinfo = get_version(
session, pdata, release=release, renotify=renotify)

# check to see if we forced and the event is older than the configured threshold
past_email_deadline = False
if force_email:
nowtime = datetime.utcnow()
threshtime = version.time + timedelta(seconds=config['release_threshold']*3600)
threshtime = version.time + \
timedelta(seconds=config['release_threshold']*3600)
if nowtime > threshtime:
past_email_deadline = True

# add/commit the event for now, but we may have to delete it if we crash for any reason
session.add(event)
session.commit()
Expand All @@ -220,9 +232,9 @@ def main(args):
logging.debug('Determining which users should get emailed...')
for address in all_addresses:
should_alert, notified_before = address.shouldAlert(version,
renotify=renotify,
release=release,
ignore_time_limit=force_email)
renotify=renotify,
release=release,
ignore_time_limit=force_email)
if should_alert:
if address.format == 'short':
if notified_before:
Expand All @@ -240,15 +252,18 @@ def main(args):
else:
pdf_addresses_nonupdate.append(address)


# how many emails are we sending
logging.debug('%i new short addresses.' % (len(short_addresses_update)))
logging.debug('%i short addresses to update.' % (len(short_addresses_nonupdate)))
logging.debug('%i new short addresses.' %
(len(short_addresses_update)))
logging.debug('%i short addresses to update.' %
(len(short_addresses_nonupdate)))
logging.debug('%i new long addresses.' % (len(long_addresses_update)))
logging.debug('%i long addresses to update.' % (len(long_addresses_nonupdate)))
logging.debug('%i long addresses to update.' %
(len(long_addresses_nonupdate)))
logging.debug('%i new pdf addresses.' % (len(pdf_addresses_update)))
logging.debug('%i pdf addresses to update.' % (len(pdf_addresses_nonupdate)))

logging.debug('%i pdf addresses to update.' %
(len(pdf_addresses_nonupdate)))

# try to find the event url
logging.debug('Getting event url...')
if ccinfo is not None:
Expand All @@ -258,8 +273,10 @@ def main(args):

# create the short and long message texts
logging.debug('Creating message text and subject...')
short_msg = format_msg(version, pdata, 'short', event_url, past_email_deadline=past_email_deadline)
long_msg = format_msg(version, pdata, 'long', event_url, past_email_deadline=past_email_deadline)
short_msg = format_msg(
version, pdata, 'short', event_url, past_email_deadline=past_email_deadline)
long_msg = format_msg(version, pdata, 'long', event_url,
past_email_deadline=past_email_deadline)

# create the long and short subjects
subject, subject_update = generate_subject_line(version, pdata)
Expand All @@ -273,16 +290,20 @@ def main(args):
# send emails to all short format addresses
logging.debug('Sending short addresses...')
if len(short_addresses_update):
version = send_emails(version, short_addresses_update, all_props, short_msg, subject_update, DEBUG)
version = send_emails(
version, short_addresses_update, all_props, short_msg, subject_update, DEBUG)
if len(short_addresses_nonupdate):
version = send_emails(version, short_addresses_nonupdate, all_props, short_msg, subject, DEBUG)
version = send_emails(
version, short_addresses_nonupdate, all_props, short_msg, subject, DEBUG)

# send emails to all long format addresses
logging.debug('Sending long addresses...')
if len(long_addresses_update):
version = send_emails(version, long_addresses_update, all_props, long_msg, subject_update, DEBUG)
version = send_emails(
version, long_addresses_update, all_props, long_msg, subject_update, DEBUG)
if len(long_addresses_nonupdate):
version = send_emails(version, long_addresses_nonupdate, all_props, long_msg, subject, DEBUG)
version = send_emails(
version, long_addresses_nonupdate, all_props, long_msg, subject, DEBUG)

# send emails to all pdf format addresses
logging.debug('Sending pdf addresses...')
Expand All @@ -300,57 +321,58 @@ def main(args):
version = send_emails(version, pdf_addresses_nonupdate,
all_props, long_msg, subject, DEBUG,
attachments=attachments)

logging.debug('Done.')
except Exception as e:
# if we have any errors, we want to back out the event and version we added above.
# todo - the event might not be new, we can't just delete it, only if its empty
print('Exception "%s" on input %s Backing out any new events/versions.' % (str(e), args.directory))
print('Exception "%s" on input %s Backing out any new events/versions.' %
(str(e), args.directory))
session.delete(version)
if len(event.versions) == 0:
session.delete(event)
session.commit()
session.commit()
session.close()
sys.exit(0)


if __name__ == '__main__':
# pdl passes in property arguments surrounded by double quotes. At the command shell,
# or in ipython, this are replaced for you. When called from PDL (presumably from a Java
# system call, they are NOT, and therefore those arguments are not parsed correctly.
sys.argv = [arg.replace('"', '') for arg in sys.argv]
desc='Send emails to PAGER users.'

desc = 'Send emails to PAGER users.'
argparser = argparse.ArgumentParser(description=desc,
formatter_class=argparse.ArgumentDefaultsHelpFormatter)

argparser.add_argument("--debug", action='store_true', default=False,
help='Turn off emailing, print out who *would* be notified.')
argparser.add_argument("--directory",
help="Directory where PAGER data can be found", metavar='DIRECTORY')
argparser.add_argument("--type",
argparser.add_argument("--type",
help="Product type", metavar='TYPE')
argparser.add_argument("--code",
argparser.add_argument("--code",
help="Product code", metavar='CODE')
argparser.add_argument("--source",
argparser.add_argument("--source",
help="Product source", metavar='SOURCE')
argparser.add_argument("--status",

argparser.add_argument("--status",
help="Product status", metavar='STATUS')
argparser.add_argument("--action",
argparser.add_argument("--action",
help="Product action", metavar='ACTION')
argparser.add_argument("--preferred-latitude", type=float,
help="Event latitude", metavar='LAT', dest='lat')
argparser.add_argument("--preferred-longitude", type=float,
help="Event longitude", metavar='LON', dest='lon')
argparser.add_argument("--preferred-eventid",
argparser.add_argument("--preferred-eventid",
help="Event ID", metavar='ID', dest='eventid')
argparser.add_argument("--preferred-depth", type=float,
help="Event depth", metavar='DEPTH', dest='depth')
argparser.add_argument("--preferred-magnitude", type=float,
help="Event magnitude", metavar='MAG', dest='magnitude')
argparser.add_argument("--preferred-eventtime",
argparser.add_argument("--preferred-eventtime",
help="Event time", metavar='TIME', dest='time')

argparser.add_argument("--property-renotify", dest='renotify',
Expand Down
Loading

0 comments on commit ba96854

Please sign in to comment.