def get_jabbers(self, uri, uri2=None): """return the standard [[text, html, xtra], ] for jabber""" res = [] xtra = {'product_id': self.get_product_id()} for seg in self.segments: # Skip any segments that don't have UGC information if not seg.ugcs: continue headline = "[No headline was found in SPS]" if seg.headlines: headline = (seg.headlines[0]).replace("\n", " ") elif SPECIAL_WX_STATEMENT.search(seg.unixtext): headline = "Special Weather Statement" counties = " for %s" % (ugcs_to_text(seg.ugcs), ) expire = "" if seg.ugcexpire is not None: expire = " till %s %s" % ( (seg.ugcexpire - datetime.timedelta(hours=reference.offsets.get(self.z, 0)) ).strftime("%-I:%M %p"), self.z) counties, expire = dedup_headline(headline, seg.ugcs, counties, expire) xtra['channels'] = self._get_channels(seg) mess = ("%s issues %s%s%s %s?pid=%s") % (self.source[1:], headline, counties, expire, uri, xtra['product_id']) htmlmess = ("<p>%s issues <a href='%s?pid=%s'>%s</a>%s%s</p>") % ( self.source[1:], uri, xtra['product_id'], headline, counties, expire) xtra['twitter'] = "%s%s%s %s?pid=%s" % (headline, counties, expire, uri, xtra['product_id']) res.append([mess, htmlmess, xtra]) return res
def test_totextstr(): """ See if we can generate a proper string from a UGCS """ ugcs = [ ugc.UGC("DC", "Z", "001"), ugc.UGC("IA", "C", "001"), ugc.UGC("IA", "C", "002"), ] assert ( ugc.ugcs_to_text(ugcs) == "((DCZ001)) [DC] and ((IAC001)), ((IAC002)) [IA]" )
def get_jabbers(self, uri, river_uri=None): """Return a list of triples representing how this goes to social Arguments: uri -- The URL for the VTEC Browser river_uri -- The URL of the River App Returns: [[plain, html, xtra]] -- A list of triples of plain text, html, xtra """ wfo = self.source[1:] if self.skip_con: xtra = { 'product_id': self.get_product_id(), 'channels': ",".join(self.get_affected_wfos()) + ",FLS" + wfo, 'twitter': ('%s issues updated FLS product %s?wfo=%s' ) % (wfo, river_uri, wfo)} text = ("%s has sent an updated FLS product (continued products " "were not reported here). Consult this website for more " "details. %s?wfo=%s") % (wfo, river_uri, wfo) html = ("<p>%s has sent an updated FLS product " "(continued products were not reported here). Consult " "<a href=\"%s?wfo=%s\">this website</a> for more " "details.</p>") % (wfo, river_uri, wfo) return [(text, html, xtra)] msgs = [] actions = [] long_actions = [] html_long_actions = [] for segment in self.segments: for vtec in segment.vtec: if vtec.action == 'ROU' or vtec.status == 'T': continue # CRITICAL: redefine this for each loop as it gets passed by # reference below and is subsequently overwritten otherwise! if self.afos[:3] in ['MWW', 'RFW']: channels = ["%s%s" % (self.afos[:3], s) for s in self.get_affected_wfos()] else: channels = self.get_affected_wfos() channels.append('%s.%s' % (vtec.phenomena, vtec.significance)) channels.append(self.afos) channels.append('%s.%s.%s' % (vtec.phenomena, vtec.significance, vtec.office)) for ugc in segment.ugcs: channels.append('%s.%s.%s' % (vtec.phenomena, vtec.significance, str(ugc))) channels.append(str(ugc)) xtra = {'product_id': self.get_product_id(), 'channels': ",".join(channels), 'status': vtec.status, 'vtec': vtec.getID(self.valid.year), 'ptype': vtec.phenomena, 'twitter': ''} long_actions.append("%s %s" % (vtec.get_action_string(), ugcs_to_text(segment.ugcs))) html_long_actions.append(("<span style='font-weight: bold;'>" "%s</span> %s" ) % (vtec.get_action_string(), ugcs_to_text(segment.ugcs))) actions.append("%s %s area%s" % ( vtec.get_action_string(), len(segment.ugcs), "s" if len(segment.ugcs) > 1 else "")) if segment.giswkt is not None: xtra['category'] = 'SBW' xtra['geometry'] = segment.giswkt.replace("SRID=4326;", "") if vtec.endts is not None: xtra['expire'] = vtec.endts.strftime("%Y%m%dT%H:%M:00") # Set up Jabber Dict for stuff to fill in jmsg_dict = {'wfo': vtec.office, 'product': vtec.product_string(), 'county': ugcs_to_text(segment.ugcs), 'sts': ' ', 'ets': ' ', 'svr_special': segment.special_tags_to_text(), 'svs_special': '', 'svs_special_html': '', 'year': self.valid.year, 'phenomena': vtec.phenomena, 'eventid': vtec.ETN, 'significance': vtec.significance, 'url': "%s%s" % (uri, vtec.url(self.valid.year))} if (len(segment.hvtec) > 0 and segment.hvtec[0].nwsli.id != '00000'): jmsg_dict['county'] = segment.hvtec[0].nwsli.get_name() if (vtec.begints is not None and vtec.begints > (self.utcnow + datetime.timedelta( hours=1))): jmsg_dict['sts'] = ' %s ' % (vtec.get_begin_string(self),) jmsg_dict['ets'] = vtec.get_end_string(self) # Include the special bulletin for Tornado Warnings if vtec.phenomena == 'TO' and vtec.significance == 'W': jmsg_dict['svs_special'] = segment.svs_search() jmsg_dict['svs_special_html'] = segment.svs_search() # Emergencies if vtec.phenomena in ['TO', 'FF'] and vtec.significance == 'W': _btext = segment.svs_search() if (_btext == "" and vtec.phenomena == 'TO' and vtec.action not in ['CAN', 'EXP']): self.warnings.append(("Could not find bullet text in " "segment! %s" ) % (segment.unixtext,)) elif (_btext != "" and vtec.phenomena == 'FF' and _btext.find("FLASH FLOOD EMERGENCY") > 0): jmsg_dict['svs_special'] = _btext jmsg_dict['svs_special_html'] = _btext.replace( "FLASH FLOOD EMERGENCY", ('<span style="color: #FF0000;">' 'FLASH FLOOD EMERGENCY</span>')) elif _btext != "" and vtec.phenomena == 'TO': jmsg_dict['svs_special_html'] = _btext.replace( "TORNADO EMERGENCY", ('<span style="color: #FF0000;">' 'TORNADO EMERGENCY</span>')) plain = ("%(wfo)s %(product)s %(svr_special)s%(sts)s for " "%(county)s %(ets)s %(svs_special)s " "%(url)s") % jmsg_dict html = ("<p>%(wfo)s <a href=\"%(url)s\">%(product)s</a> " "%(svr_special)s%(sts)s for %(county)s " "%(ets)s %(svs_special_html)s</p>") % jmsg_dict xtra['twitter'] = ("%(wfo)s %(product)s%(sts)sfor %(county)s " "%(ets)s %(url)s") % jmsg_dict # brute force removal of duplicate spaces xtra['twitter'] = ' '.join(xtra['twitter'].split()) msgs.append([" ".join(plain.split()), " ".join(html.split()), xtra]) # If we have a homogeneous product and we have more than one # message, lets try to condense it down, some of the xtra settings # from above will be used here, this is probably bad design if self.is_homogeneous() and len(msgs) > 1: vtec = self.get_first_non_cancel_vtec() if vtec is None: vtec = self.segments[0].vtec[0] segment = self.get_first_non_cancel_segment() if segment is None: segment = self.segments[0] if self.afos[:3] in ['MWW', 'RFW']: channels = ["%s%s" % (self.afos[:3], s) for s in self.get_affected_wfos()] else: channels = self.get_affected_wfos() channels.append('%s.%s' % (vtec.phenomena, vtec.significance)) channels.append(self.afos) channels.append('%s.%s.%s' % (vtec.phenomena, vtec.significance, vtec.office)) for seg in self.segments: for ugc in seg.ugcs: channels.append('%s.%s.%s' % (vtec.phenomena, vtec.significance, str(ugc))) channels.append(str(ugc)) xtra['channels'] = ",".join(channels) jdict = { 'as': ", ".join(actions), 'asl': ", ".join(long_actions), 'hasl': ", ".join(html_long_actions), 'wfo': vtec.office, 'ets': vtec.get_end_string(self), 'svr_special': segment.special_tags_to_text(), 'svs_special': '', 'sts': '', 'action': self.get_action(), 'product': vtec.get_ps_string(), 'url': "%s%s" % (uri, vtec.url(self.valid.year)), } # Include the special bulletin for Tornado Warnings if vtec.phenomena in ['TO', ] and vtec.significance == 'W': jdict['svs_special'] = segment.svs_search() if (vtec.begints is not None and vtec.begints > (self.utcnow + datetime.timedelta( hours=1))): jdict['sts'] = ' %s ' % (vtec.get_begin_string(self),) plain = ("%(wfo)s %(action)s %(product)s%(svr_special)s" "%(sts)s (%(asl)s) %(ets)s. %(svs_special)s %(url)s" ) % jdict xtra['twitter'] = ("%(wfo)s %(action)s %(product)s" "%(svr_special)s%(sts)s (%(asl)s) " "%(ets)s") % jdict if len(xtra['twitter']) > (140-25): xtra['twitter'] = ("%(wfo)s %(action)s %(product)s%(sts)s " "(%(as)s) %(ets)s") % jdict if len(xtra['twitter']) > (140-25): xtra['twitter'] = ("%(wfo)s %(action)s %(product)s%(sts)s " "%(ets)s") % jdict xtra['twitter'] += " %(url)s" % jdict html = ("<p>%(wfo)s <a href=\"%(url)s\">%(action)s %(product)s</a>" "%(svr_special)s%(sts)s " "(%(hasl)s) %(ets)s. %(svs_special)s</p>") % jdict return [(" ".join(plain.split()), " ".join(html.split()), xtra)] return msgs
def get_jabbers(self, uri, river_uri=None): """Return a list of triples representing how this goes to social Arguments: uri -- The URL for the VTEC Browser river_uri -- The URL of the River App Returns: [[plain, html, xtra]] -- A list of triples of plain text, html, xtra """ wfo = self.source[1:] if self.skip_con: xtra = { 'product_id': self.get_product_id(), 'channels': ",".join(self.get_affected_wfos()) + ",FLS" + wfo, 'twitter': ('%s issues updated FLS product %s?wfo=%s') % (wfo, river_uri, wfo) } text = ("%s has sent an updated FLS product (continued products " "were not reported here). Consult this website for more " "details. %s?wfo=%s") % (wfo, river_uri, wfo) html = ("<p>%s has sent an updated FLS product " "(continued products were not reported here). Consult " "<a href=\"%s?wfo=%s\">this website</a> for more " "details.</p>") % (wfo, river_uri, wfo) return [(text, html, xtra)] msgs = [] actions = [] long_actions = [] html_long_actions = [] for segment in self.segments: for vtec in segment.vtec: if vtec.action == 'ROU' or vtec.status == 'T': continue # CRITICAL: redefine this for each loop as it gets passed by # reference below and is subsequently overwritten otherwise! if self.afos[:3] in ['MWW', 'RFW']: channels = [ "%s%s" % (self.afos[:3], s) for s in self.get_affected_wfos() ] else: channels = self.get_affected_wfos() channels.append('%s.%s' % (vtec.phenomena, vtec.significance)) channels.append(self.afos) channels.append( '%s.%s.%s' % (vtec.phenomena, vtec.significance, vtec.office)) for ugc in segment.ugcs: channels.append( '%s.%s.%s' % (vtec.phenomena, vtec.significance, str(ugc))) channels.append(str(ugc)) xtra = { 'product_id': self.get_product_id(), 'channels': ",".join(channels), 'status': vtec.status, 'vtec': vtec.get_id(self.valid.year), 'ptype': vtec.phenomena, 'twitter': '' } long_actions.append( "%s %s" % (vtec.get_action_string(), ugcs_to_text(segment.ugcs))) html_long_actions.append( ("<span style='font-weight: bold;'>" "%s</span> %s") % (vtec.get_action_string(), ugcs_to_text(segment.ugcs))) actions.append("%s %s area%s" % (vtec.get_action_string(), len(segment.ugcs), "s" if len(segment.ugcs) > 1 else "")) if segment.giswkt is not None: xtra['category'] = 'SBW' xtra['geometry'] = segment.giswkt.replace("SRID=4326;", "") if vtec.endts is not None: xtra['expire'] = vtec.endts.strftime("%Y%m%dT%H:%M:00") # Set up Jabber Dict for stuff to fill in jmsg_dict = { 'wfo': vtec.office, 'product': vtec.product_string(), 'county': ugcs_to_text(segment.ugcs), 'sts': ' ', 'ets': ' ', 'svr_special': segment.special_tags_to_text(), 'svs_special': '', 'svs_special_html': '', 'year': self.valid.year, 'phenomena': vtec.phenomena, 'eventid': vtec.etn, 'significance': vtec.significance, 'url': "%s%s" % (uri, vtec.url(self.valid.year)) } if (segment.hvtec and segment.hvtec[0].nwsli.id != '00000'): jmsg_dict['county'] = segment.hvtec[0].nwsli.get_name() if (vtec.begints is not None and vtec.begints > (self.utcnow + datetime.timedelta(hours=1))): jmsg_dict['sts'] = ' %s ' % (vtec.get_begin_string(self), ) jmsg_dict['ets'] = vtec.get_end_string(self) # Include the special bulletin for Tornado Warnings if vtec.phenomena == 'TO' and vtec.significance == 'W': jmsg_dict['svs_special'] = segment.svs_search() jmsg_dict['svs_special_html'] = segment.svs_search() # Emergencies if vtec.phenomena in ['TO', 'FF'] and vtec.significance == 'W': _btext = segment.svs_search() if (_btext == "" and vtec.phenomena == 'TO' and vtec.action not in ['CAN', 'EXP']): self.warnings.append( ("Could not find bullet text in " "segment! %s") % (segment.unixtext, )) elif (_btext != "" and vtec.phenomena == 'FF' and _btext.find("FLASH FLOOD EMERGENCY") > 0): jmsg_dict['svs_special'] = _btext jmsg_dict['svs_special_html'] = _btext.replace( "FLASH FLOOD EMERGENCY", ('<span style="color: #FF0000;">' 'FLASH FLOOD EMERGENCY</span>')) elif _btext != "" and vtec.phenomena == 'TO': jmsg_dict['svs_special_html'] = _btext.replace( "TORNADO EMERGENCY", ('<span style="color: #FF0000;">' 'TORNADO EMERGENCY</span>')) plain = ("%(wfo)s %(product)s %(svr_special)s%(sts)s for " "%(county)s %(ets)s %(svs_special)s " "%(url)s") % jmsg_dict html = ("<p>%(wfo)s <a href=\"%(url)s\">%(product)s</a> " "%(svr_special)s%(sts)s for %(county)s " "%(ets)s %(svs_special_html)s</p>") % jmsg_dict xtra['twitter'] = ("%(wfo)s %(product)s%(sts)sfor %(county)s " "%(ets)s %(url)s") % jmsg_dict # brute force removal of duplicate spaces xtra['twitter'] = ' '.join(xtra['twitter'].split()) msgs.append( [" ".join(plain.split()), " ".join(html.split()), xtra]) # If we have a homogeneous product and we have more than one # message, lets try to condense it down, some of the xtra settings # from above will be used here, this is probably bad design if self.is_homogeneous() and len(msgs) > 1: vtec = self.get_first_non_cancel_vtec() if vtec is None: vtec = self.segments[0].vtec[0] segment = self.get_first_non_cancel_segment() if segment is None: segment = self.segments[0] if self.afos[:3] in ['MWW', 'RFW']: channels = [ "%s%s" % (self.afos[:3], s) for s in self.get_affected_wfos() ] else: channels = self.get_affected_wfos() channels.append('%s.%s' % (vtec.phenomena, vtec.significance)) channels.append(self.afos) channels.append('%s.%s.%s' % (vtec.phenomena, vtec.significance, vtec.office)) for seg in self.segments: for ugc in seg.ugcs: channels.append( '%s.%s.%s' % (vtec.phenomena, vtec.significance, str(ugc))) channels.append(str(ugc)) xtra['channels'] = ",".join(channels) jdict = { 'as': ", ".join(actions), 'asl': ", ".join(long_actions), 'hasl': ", ".join(html_long_actions), 'wfo': vtec.office, 'ets': vtec.get_end_string(self), 'svr_special': segment.special_tags_to_text(), 'svs_special': '', 'sts': '', 'action': self.get_action(), 'product': vtec.get_ps_string(), 'url': "%s%s" % (uri, vtec.url(self.valid.year)), } # Include the special bulletin for Tornado Warnings if vtec.phenomena in [ 'TO', ] and vtec.significance == 'W': jdict['svs_special'] = segment.svs_search() if (vtec.begints is not None and vtec.begints > (self.utcnow + datetime.timedelta(hours=1))): jdict['sts'] = ' %s ' % (vtec.get_begin_string(self), ) plain = ( "%(wfo)s %(action)s %(product)s%(svr_special)s" "%(sts)s (%(asl)s) %(ets)s. %(svs_special)s %(url)s") % jdict xtra['twitter'] = ("%(wfo)s %(action)s %(product)s" "%(svr_special)s%(sts)s (%(asl)s) " "%(ets)s") % jdict # 25 is an aggressive reservation for URLs, which may not be needed if len(xtra['twitter']) > (TWEET_CHARS - 25): xtra['twitter'] = ("%(wfo)s %(action)s %(product)s%(sts)s " "(%(as)s) %(ets)s") % jdict if len(xtra['twitter']) > (TWEET_CHARS - 25): xtra['twitter'] = ("%(wfo)s %(action)s %(product)s%(sts)s " "%(ets)s") % jdict xtra['twitter'] += " %(url)s" % jdict html = ("<p>%(wfo)s <a href=\"%(url)s\">%(action)s %(product)s</a>" "%(svr_special)s%(sts)s " "(%(hasl)s) %(ets)s. %(svs_special)s</p>") % jdict return [(" ".join(plain.split()), " ".join(html.split()), xtra)] return msgs
def test_totextstr(self): """ See if we can generate a proper string from a UGCS """ ugcs = [ugc.UGC("DC", "Z", "001"), ugc.UGC("IA", "C", "001"), ugc.UGC("IA", "C", "002")] self.assertEquals(ugc.ugcs_to_text(ugcs), "((IAC001)), ((IAC002)) [IA] and ((DCZ001)) [DC]")
def get_jabbers(self, uri, river_uri=None): """Return a list of triples representing how this goes to social Arguments: uri -- The URL for the VTEC Browser river_uri -- The URL of the River App Returns: [[plain, html, xtra]] -- A list of triples of plain text, html, xtra """ wfo = self.source[1:] if self.skip_con: xtra = { "product_id": self.get_product_id(), "channels": ",".join(self.get_affected_wfos()) + ",FLS" + wfo, "twitter": ("%s issues updated FLS product %s?wfo=%s") % (wfo, river_uri, wfo), } text = ( f"{wfo} has sent an updated FLS product (continued products " "were not reported here). Consult this website for more " f"details. {river_uri}?wfo={wfo}") html = ("<p>%s has sent an updated FLS product " "(continued products were not reported here). Consult " '<a href="%s?wfo=%s">this website</a> for more ' "details.</p>") % (wfo, river_uri, wfo) return [(text, html, xtra)] msgs = [] actions = [] long_actions = [] html_long_actions = [] for segment in self.segments: for vtec in segment.vtec: if vtec.action == "ROU" or vtec.status == "T": continue # CRITICAL: redefine this for each loop as it gets passed by # reference below and is subsequently overwritten otherwise! if self.afos[:3] in ["MWW", "RFW"]: channels = [ "%s%s" % (self.afos[:3], s) for s in self.get_affected_wfos() ] else: channels = self.get_affected_wfos() channels.append(vtec.s2()) channels.append(self.afos) channels.append("%s..." % (self.afos[:3], )) channels.append( f"{vtec.phenomena}.{vtec.significance}.{vtec.office}") for ugc in segment.ugcs: # per state channels candidate = "%s.%s.%s" % ( vtec.phenomena, vtec.significance, ugc.state, ) if candidate not in channels: channels.append(candidate) channels.append( "%s.%s.%s" % (vtec.phenomena, vtec.significance, str(ugc))) channels.append(str(ugc)) xtra = { "product_id": self.get_product_id(), "channels": ",".join(channels), "status": vtec.status, "vtec": vtec.get_id(self.db_year), "ptype": vtec.phenomena, "twitter": "", } long_actions.append( f"{vtec.get_action_string()} {ugcs_to_text(segment.ugcs)}") html_long_actions.append( ("<span style='font-weight: bold;'>" "%s</span> %s") % (vtec.get_action_string(), ugcs_to_text(segment.ugcs))) actions.append("%s %s area%s" % ( vtec.get_action_string(), len(segment.ugcs), "s" if len(segment.ugcs) > 1 else "", )) if segment.giswkt is not None: xtra["category"] = "SBW" xtra["geometry"] = segment.giswkt.replace("SRID=4326;", "") if vtec.endts is not None: xtra["expire"] = vtec.endts.strftime("%Y%m%dT%H:%M:00") # Set up Jabber Dict for stuff to fill in jmsg_dict = { "wfo": vtec.office, "product": vtec.product_string(), "county": ugcs_to_text(segment.ugcs), "sts": " ", "ets": " ", "svr_special": segment.special_tags_to_text(), "svs_special": "", "svs_special_html": "", "year": self.db_year, "phenomena": vtec.phenomena, "eventid": vtec.etn, "significance": vtec.significance, "url": "%s%s" % (uri, vtec.url(self.db_year)), } if segment.hvtec and segment.hvtec[0].nwsli.id != "00000": jmsg_dict["county"] = segment.hvtec[0].nwsli.get_name() if vtec.begints is not None: jmsg_dict["url"] += "_%s" % ( vtec.begints.strftime("%Y-%m-%dT%H:%MZ"), ) if vtec.begints > (self.utcnow + timedelta(hours=1)): jmsg_dict["sts"] = " %s " % ( vtec.get_begin_string(self), ) else: jmsg_dict["url"] += "_%s" % ( self.utcnow.strftime("%Y-%m-%dT%H:%MZ"), ) jmsg_dict["ets"] = vtec.get_end_string(self) # Include the special bulletin for Tornado Warnings if vtec.phenomena == "TO" and vtec.significance == "W": jmsg_dict["svs_special"] = segment.svs_search() jmsg_dict["svs_special_html"] = segment.svs_search() # PDS if segment.is_pds: jmsg_dict["product"] += " (PDS)" channels.append(f"{vtec.phenomena}.PDS") xtra["channels"] += ",%s" % (channels[-1], ) # Emergencies if segment.is_emergency: jmsg_dict["product"] = (jmsg_dict["product"].replace( "Warning", "Emergency").replace(" (PDS)", "")) channels.append(f"{vtec.phenomena}.EMERGENCY") xtra["channels"] += ",%s" % (channels[-1], ) _btext = segment.svs_search() if vtec.phenomena == "FF": jmsg_dict["svs_special"] = _btext jmsg_dict["svs_special_html"] = _btext.replace( "FLASH FLOOD EMERGENCY", ('<span style="color: #FF0000;">' "FLASH FLOOD EMERGENCY</span>"), ) elif vtec.phenomena == "TO": jmsg_dict["svs_special_html"] = _btext.replace( "TORNADO EMERGENCY", ('<span style="color: #FF0000;">' "TORNADO EMERGENCY</span>"), ) else: self.warnings.append( "Segment is_emergency, but not TO,FF phenomena?") plain = ("%(wfo)s %(product)s %(svr_special)s%(sts)s for " "%(county)s %(ets)s %(svs_special)s " "%(url)s") % jmsg_dict html = ('<p>%(wfo)s <a href="%(url)s">%(product)s</a> ' "%(svr_special)s%(sts)s for %(county)s " "%(ets)s %(svs_special_html)s</p>") % jmsg_dict xtra["twitter"] = ( "%(wfo)s %(product)s%(svr_special)s%(sts)sfor %(county)s " "%(ets)s %(url)s") % jmsg_dict # brute force removal of duplicate spaces xtra["twitter"] = " ".join(xtra["twitter"].split()) msgs.append( [" ".join(plain.split()), " ".join(html.split()), xtra]) # If we have a homogeneous product and we have more than one # message, lets try to condense it down, some of the xtra settings # from above will be used here, this is probably bad design if self.is_homogeneous() and len(msgs) > 1: vtec = self.get_first_non_cancel_vtec() if vtec is None: vtec = self.segments[0].vtec[0] segment = self.get_first_non_cancel_segment() if segment is None: segment = self.segments[0] if self.afos[:3] in ["MWW", "RFW"]: channels = [ "%s%s" % (self.afos[:3], s) for s in self.get_affected_wfos() ] else: channels = self.get_affected_wfos() channels.append(vtec.s2()) channels.append(self.afos) channels.append("%s.%s.%s" % (vtec.phenomena, vtec.significance, vtec.office)) # Need to figure out a timestamp to associate with this # consolidated message. Default to utcnow stamp = self.utcnow for seg in self.segments: for v in seg.vtec: if (v.begints is not None and v.begints > stamp and v.status not in ["CAN", "EXP"]): stamp = v.begints for ugc in seg.ugcs: channels.append( "%s.%s.%s" % (vtec.phenomena, vtec.significance, str(ugc))) channels.append(str(ugc)) if any([seg.is_emergency for seg in self.segments]): channels.append(f"{vtec.phenomena}.EMERGENCY") if any([seg.is_pds for seg in self.segments]): channels.append(f"{vtec.phenomena}.PDS") xtra["channels"] = ",".join(channels) jdict = { "as": ", ".join(actions), "asl": ", ".join(long_actions), "hasl": ", ".join(html_long_actions), "wfo": vtec.office, "ets": vtec.get_end_string(self), "svr_special": segment.special_tags_to_text(), "svs_special": "", "sts": "", "action": self.get_action(), "product": vtec.get_ps_string(), "url": "%s%s_%s" % ( uri, vtec.url(self.db_year), stamp.strftime("%Y-%m-%dT%H:%MZ"), ), } # Include the special bulletin for Tornado Warnings if vtec.phenomena in ["TO"] and vtec.significance == "W": jdict["svs_special"] = segment.svs_search() if vtec.begints is not None and vtec.begints > ( self.utcnow + timedelta(hours=1)): jdict["sts"] = " %s " % (vtec.get_begin_string(self), ) plain = ( "%(wfo)s %(action)s %(product)s%(svr_special)s" "%(sts)s (%(asl)s) %(ets)s. %(svs_special)s %(url)s") % jdict xtra["twitter"] = ("%(wfo)s %(action)s %(product)s" "%(svr_special)s%(sts)s (%(asl)s) " "%(ets)s") % jdict # 25 is an aggressive reservation for URLs, which may not be needed if len(xtra["twitter"]) > (TWEET_CHARS - 25): xtra["twitter"] = ("%(wfo)s %(action)s %(product)s%(sts)s " "(%(as)s) %(ets)s") % jdict if len(xtra["twitter"]) > (TWEET_CHARS - 25): xtra["twitter"] = ("%(wfo)s %(action)s %(product)s%(sts)s " "%(ets)s") % jdict xtra["twitter"] += " %(url)s" % jdict html = ('<p>%(wfo)s <a href="%(url)s">%(action)s %(product)s</a>' "%(svr_special)s%(sts)s " "(%(hasl)s) %(ets)s. %(svs_special)s</p>") % jdict return [(" ".join(plain.split()), " ".join(html.split()), xtra)] return msgs
def test_louisana(): """Test that some specific logic works.""" ugcs = [ugc.UGC("LA", "C", i) for i in range(100)] res = ugc.ugcs_to_text(ugcs) ans = "100 parishes in [LA]" assert res == ans