Changeset 1:71959f6ade4f

Show
Ignore:
Timestamp:
04/15/08 01:41:43 (4 years ago)
Author:
chris
Branch:
unix
Message:

saving before doing major mods to use the cap file instead of rss

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • bin/scripts/StormXmlSiren.py

    r0 r1  
    4949year = time.strftime("%Y", time.localtime(time.time())) 
    5050 
     51APPNAME = "StormXmlSiren" 
     52 
    5153class wItem: 
    5254  def __init__(self,item): 
     55    self.types      = {  
     56                         'Forecast'  : 2, 
     57                         'Statement' : 4, 
     58                         'Advisory'  : 8, 
     59                         'Watch'     : 16, 
     60                         'Warning'   : 32 
     61                       } 
     62 
    5363    self.tag_title  = 'title' 
    5464    self.tag_link   = 'link' 
    5565    self.tag_desc   = 'description' 
    56     self.title_e = re.compile('(.*) (\w+) - (.*) \((.*)\)$') 
    57     self.desc_e = re.compile('(.*)\nIssued At:\s+(.*)T(.*)\nExpired At:\s+(.*)T(.*)\n.*$') 
    58     self.title = '' 
    59     self.state = '' 
    60     self.county = '' 
    61     self.type = '' 
    62     self.link  = '' 
    63     self.desc  = '' 
    64     self.county  = '' 
    65     self.issued = '' 
    66     self.expires = '' 
     66    self.title_e    = re.compile('(.*) (\w+) - (.*) \((.*)\)$') 
     67    self.desc_e     = re.compile('(.*)\nIssued At:\s+(.*)T(.*)\nExpired At:\s+(.*)T(.*)\n.*$') 
     68    self.title      = '' 
     69    self.state      = '' 
     70    self.county     = '' 
     71    self.type       = '' 
     72    self.link       = '' 
     73    self.desc       = '' 
     74    self.county     = '' 
     75    self.issued     = '' 
     76    self.expires    = '' 
     77 
    6778    self.parse(item) 
     79 
     80  def typestr(self,type): 
     81    for tk in self.types.keys(): 
     82      if self.types[tk] == type: 
     83        return tk 
    6884 
    6985  def parse(self,item): 
     
    7389 
    7490    parse_res = self.title_e.search(self.title) 
    75     self.type  = parse_res.group(1) 
    76     self.subtype = parse_res.group(2) 
     91    self.matter = parse_res.group(1) 
     92    self.type   = self.types[parse_res.group(2)] 
    7793    self.county = parse_res.group(3) 
    7894    self.state  = parse_res.group(4) 
     
    86102      print "\tState: " + self.state 
    87103      print "\tCounty: " + self.county 
    88       print "\tType: " + self.type 
    89       print "\tSubType: " + self.subtype 
     104      print "\tType: " + self.typestr(self.type) 
     105      print "\tMatter: " + self.matter 
    90106      print "\tLink: " + self.link 
    91107      print "\tIssued: " + self.issued 
     
    94110 
    95111  def isForecast(self): 
    96     if self.subtype == "Forecast": 
     112    if self.type & self.types["Forecast"]: 
    97113      return 1 
    98114 
    99115  def isStatement(self): 
    100     if self.subtype == "Statement": 
     116    if self.type & self.types["Statement"]: 
    101117      return 1 
    102118 
    103119  def isAdvisory(self): 
    104     if self.subtype == "Advisory": 
     120    if self.type & self.types["Advisory"]: 
    105121      return 1 
    106122 
    107123  def isWatch(self): 
    108     if self.subtype == "Watch": 
     124    if self.type & self.types["Watch"]: 
    109125      return 1 
    110126 
    111127  def isWarning(self): 
    112     if self.subtype == "Warning": 
     128    if self.type & self.types["Warning"]: 
    113129      return 1 
    114130 
    115131 
    116132class xmlWeather: 
    117   def __init__(self,state): 
     133  def __init__(self,state,counties): 
    118134    self.data       = '' 
    119135    self.dom        = [] 
    120136    self.baseurl    = 'http://www.weather.gov/alerts/' 
    121137    self.namespace  = 'http://purl.org/dc/elements/1.1/' 
    122     self.url        = self.baseurl + string.lower(state) + ".rss"  
    123     self.counties   = [] 
     138    self.url        = self.baseurl + string.lower(state) + ".cap"  
     139    self.counties   = counties  
    124140    self.tag_county = 'item' 
    125141    self.forecasts  = [] 
     
    132148    try: 
    133149      print "Fetching: " + self.url 
    134       self.dom = minidom.parse(urllib.urlopen(self.url)) 
     150      #self.dom = minidom.parse(urllib.urlopen(self.url)) 
     151      self.dom = minidom.parse("tn.cap") 
    135152    except IOError: 
    136153      # No net connection available, exit. 
     
    158175    for w in self.warnings: 
    159176      w.show() 
     177    print "County mask" 
     178    for c in self.counties: 
     179      print "\t" + c 
    160180 
    161181  def parse(self): 
    162182      for item in self.dom.getElementsByTagName(self.tag_county): 
    163183        wi = wItem(item) 
    164         if wi.isForecast(): 
    165           self.forecasts.append(wi) 
    166         elif wi.isStatement(): 
    167           self.statements.append(wi) 
    168         elif wi.isAdvisory(): 
    169           self.advisories.append(wi) 
    170         elif wi.isWatch(): 
    171           self.watches.append(wi) 
    172         elif wi.isWarning(): 
    173           self.warnings.append(wi) 
    174         else: 
    175           print "Unknown type: " + wi.title 
    176  
    177       self.show() 
    178  
     184        if self.desired(wi.county): 
     185          wi.show() 
     186          if wi.isForecast(): 
     187            self.forecasts.append(wi) 
     188          elif wi.isStatement(): 
     189            self.statements.append(wi) 
     190          elif wi.isAdvisory(): 
     191            self.advisories.append(wi) 
     192          elif wi.isWatch(): 
     193            self.watches.append(wi) 
     194          elif wi.isWarning(): 
     195            self.warnings.append(wi) 
     196          else: 
     197            print "Unknown type: " + wi.title 
     198 
     199 
     200  def desired(self,county): 
     201    for c in self.counties: 
     202      if county == c: 
     203        return 1 
     204    return 0 
    179205 
    180206# Define a class for alert data 
     
    221247 
    222248 
    223 # Program configuration information 
    224 if os.name == 'posix': 
    225   home_dir     = os.environ.get('HOME') 
    226   config_dir   = home_dir + '/.StormSiren' 
    227 elif os.name == 'os2': 
    228   home_dir     = os.environ.get('HOME') 
    229   config_dir   = home_dir + '/StormSiren' 
    230 elif os.name == 'nt': 
    231   home_dir     = os.environ.get('USERPROFILE') # NT/2K/XP 
    232   if home_dir == None: 
    233     home_dir = os.environ.get('WINDIR') # 95/98/ME 
    234   config_dir   = home_dir + '/Application Data/StormSiren' 
    235  
    236 if not os.path.exists(config_dir): 
    237   os.mkdir(config_dir) 
    238  
    239 config_file  = os.path.normpath(config_dir + '/StormSiren.conf') 
    240 log_file     = os.path.normpath(config_dir + '/StormSiren.log') 
    241 state_file   = os.path.normpath(config_dir + '/StormSiren.state') 
    242249log_buffer   = [] 
    243250interactive_copyright = """ 
     
    249256""" 
    250257 
    251 # URLs to the National Weather Service data for Minnesota. 
    252 iwin_url     = 'http://iwin.nws.noaa.gov/iwin/' 
    253 watch_url    = '/watches.html' 
    254 warn_url     = '/allwarnings.html' 
    255 urls         = [] 
    256  
    257 # Load user configuration file 
    258 states              = [] 
    259 cities              = [] 
    260 counties            = [] 
    261 device_id           = '' 
    262 notification_system = '' 
    263 email_address       = '' 
    264 smtp_server         = '' 
    265 smtp_port           = 0 
    266 smtp_user           = '' 
    267 smtp_pass           = '' 
    268 alert_level         = 2 
    269 debug_level         = 0 
    270 devices             = {} 
    271  
    272 # Try to open user configuration file 
    273 try: 
    274   conf_f = open(config_file, 'r') 
    275   config_contents = conf_f.readlines()  
    276   conf_f.close() 
    277  
    278 # Parse config file data 
    279   for i in range(len(config_contents)): 
    280     chk_comment   = string.count(config_contents[i][0:1], '#') 
    281     chk_states    = string.count(string.lower(config_contents[i]), 'states: ') 
    282     chk_cities    = string.count(string.lower(config_contents[i]), 'cities: ') 
    283     chk_counties  = string.count(string.lower(config_contents[i]), 'counties: ') 
    284     chk_device    = string.count(string.lower(config_contents[i]), 'device: ') 
    285     chk_email     = string.count(string.lower(config_contents[i]), 'email: ') 
    286     chk_smtp      = string.count(string.lower(config_contents[i]), 'smtp: ') 
    287     chk_smtpport  = string.count(string.lower(config_contents[i]), 'smtp_port: ') 
    288     chk_smtpuser  = string.count(string.lower(config_contents[i]), 'smtp_user: ') 
    289     chk_smtppass  = string.count(string.lower(config_contents[i]), 'smtp_pass: ') 
    290     chk_alert     = string.count(string.lower(config_contents[i]), 'alert: ') 
    291     chk_debug     = string.count(string.lower(config_contents[i]), 'debug: ') 
    292  
    293     if chk_comment: 
    294       continue 
    295     if chk_states: 
    296       xstates = string.split(config_contents[i][7:], ',') 
    297       for j in range(len(xstates)): 
    298         states.append(string.strip(xstates[j])) 
    299     if chk_counties: 
    300       xcounties = string.split(config_contents[i][9:], ',') 
    301       for j in range(len(xcounties)): 
    302         counties.append(string.strip(xcounties[j])) 
    303     if chk_cities: 
    304       xcities = string.split(config_contents[i][7:], ',') 
    305       for j in range(len(xcities)): 
    306         cities.append(string.strip(xcities[j])) 
    307     if chk_device: 
    308       device_info = string.split(string.strip(config_contents[i][7:])) 
    309       devices[device_info[0]] = device_info[1] 
    310     if chk_email: 
    311       email_address = string.strip(config_contents[i][6:]) 
    312     if chk_smtp: 
    313       smtp_server = string.strip(config_contents[i][5:]) 
    314     if chk_smtpport: 
    315       smtp_port = string.strip(config_contents[i][10:]) 
     258class config: 
     259  def __init__(self): 
     260    self.states              = [] 
     261    self.cities              = [] 
     262    self.counties            = [] 
     263    self.device_id           = '' 
     264    self.notification_system = '' 
     265    self.email_address       = '' 
     266    self.smtp_server         = '' 
     267    self.smtp_port           = 0 
     268    self.smtp_user           = '' 
     269    self.smtp_pass           = '' 
     270    self.alert_level         = 2 
     271    self.debug_level         = 0 
     272    self.devices             = {} 
     273    self.configfile          = '' 
     274    self.home_dir            = '' 
     275 
     276    # Program configuration information 
     277    if os.name == 'posix': 
     278      self.home_dir     = os.environ.get('HOME') 
     279      self.config_dir   = self.home_dir + '/.' + APPNAME 
     280    elif os.name == 'os2': 
     281      self.home_dir     = os.environ.get('HOME') 
     282      config_dir   = self.home_dir + '/' + APPNAME 
     283    elif os.name == 'nt': 
     284      self.home_dir     = os.environ.get('USERPROFILE') # NT/2K/XP 
     285      if self.home_dir == None: 
     286        self.home_dir = os.environ.get('WINDIR') # 95/98/ME 
     287      self.config_dir   = self.home_dir + '/Application Data/' + APPNAME 
     288 
     289    if not os.path.exists(self.config_dir): 
     290      os.mkdir(self.config_dir) 
     291 
     292    self.config_file  = os.path.normpath(self.config_dir + '/' + APPNAME + '.conf') 
     293    self.log_file     = os.path.normpath(self.config_dir + '/' + APPNAME + '.log') 
     294    self.state_file   = os.path.normpath(self.config_dir + '/' + APPNAME + '.state') 
     295 
     296    self.open() 
     297 
     298  def loaderror(self,text): 
     299    print '*ERROR* - ' + text 
     300    print 'You may want to remove the file' + self.config_file 
     301    print 'and then rerun ' + APPNAME + '.py to regenerate it.' 
     302 
     303  def open(self): 
     304    if os.path.exists(self.config_file): 
     305      print "here" 
     306      self.load() 
    316307    else: 
    317       smtp_port = "25" # default SMTP port 
    318     if chk_smtpuser: 
    319       smtp_user = string.strip(config_contents[i][10:]) 
    320     if chk_smtppass: 
    321       smtp_pass = string.strip(config_contents[i][10:]) 
    322     if chk_alert: 
    323       alert_level = int(string.strip(config_contents[i][6:])) 
    324     if chk_debug: 
    325       debug_level = int(string.strip(config_contents[i][6:])) 
    326        
    327 # Validate configuration file.  Lecture user if missing directives. 
    328   error_string = '' 
    329   if not devices: 
    330     error_string = 'No notification device specified.' 
    331   elif not states: 
    332     error_string = 'State or states not specified.' 
    333   elif not counties: 
    334     error_string = 'Counties not specified.' 
    335  
    336 #  if string.lower(notification_system) == 'smtp': 
    337   elif not email_address: 
    338     error_string = 'Return e-mail address not specified.' 
    339   elif not smtp_server: 
    340     error_string = 'SMTP gateway not specified.' 
    341  
    342   if error_string: 
    343     print '*ERROR* - ' + error_string 
    344     print 'You may want to remove the file' + config_file 
    345     print 'and then rerun StormSiren.py to regenerate it.' 
    346     sys.exit(1) 
    347  
    348 # If config file doesn't exist, build one for them! 
    349 except IOError: 
     308      self.create() 
     309 
     310  def load(self): 
     311    # Try to open user configuration file 
     312    try: 
     313      conf_f = open(self.config_file, 'r') 
     314      config_contents = conf_f.readlines()  
     315      conf_f.close() 
     316 
     317    # Parse config file data 
     318      for i in range(len(config_contents)): 
     319        chk_comment   = string.count(config_contents[i][0:1], '#') 
     320        chk_states    = string.count(string.lower(config_contents[i]), 'states: ') 
     321        chk_cities    = string.count(string.lower(config_contents[i]), 'cities: ') 
     322        chk_counties  = string.count(string.lower(config_contents[i]), 'counties: ') 
     323        chk_device    = string.count(string.lower(config_contents[i]), 'device: ') 
     324        chk_email     = string.count(string.lower(config_contents[i]), 'email: ') 
     325        chk_smtp      = string.count(string.lower(config_contents[i]), 'smtp: ') 
     326        chk_smtpport  = string.count(string.lower(config_contents[i]), 'smtp_port: ') 
     327        chk_smtpuser  = string.count(string.lower(config_contents[i]), 'smtp_user: ') 
     328        chk_smtppass  = string.count(string.lower(config_contents[i]), 'smtp_pass: ') 
     329        chk_alert     = string.count(string.lower(config_contents[i]), 'alert: ') 
     330        chk_debug     = string.count(string.lower(config_contents[i]), 'debug: ') 
     331 
     332        if chk_comment: 
     333          continue 
     334        if chk_states: 
     335          xstates = string.split(config_contents[i][7:], ',') 
     336          for j in range(len(xstates)): 
     337            self.states.append(string.strip(xstates[j])) 
     338        if chk_counties: 
     339          xcounties = string.split(config_contents[i][9:], ',') 
     340          for j in range(len(xcounties)): 
     341            self.counties.append(string.strip(xcounties[j])) 
     342        if chk_cities: 
     343          xcities = string.split(config_contents[i][7:], ',') 
     344          for j in range(len(xcities)): 
     345            self.cities.append(string.strip(xcities[j])) 
     346        if chk_device: 
     347          device_info = string.split(string.strip(config_contents[i][7:])) 
     348          self.devices[device_info[0]] = device_info[1] 
     349        if chk_email: 
     350          self.email_address = string.strip(config_contents[i][6:]) 
     351        if chk_smtp: 
     352          self.smtp_server = string.strip(config_contents[i][5:]) 
     353        if chk_smtpport: 
     354          self.smtp_port = string.strip(config_contents[i][10:]) 
     355        else: 
     356          self.smtp_port = "25" # default SMTP port 
     357        if chk_smtpuser: 
     358          self.smtp_user = string.strip(config_contents[i][10:]) 
     359        if chk_smtppass: 
     360          self.smtp_pass = string.strip(config_contents[i][10:]) 
     361        if chk_alert: 
     362          self.alert_level = int(string.strip(config_contents[i][6:])) 
     363        if chk_debug: 
     364          self.debug_level = int(string.strip(config_contents[i][6:])) 
     365           
     366    # Validate configuration file.  Lecture user if missing directives. 
     367      error_string = '' 
     368      if not self.devices: 
     369        error_string = 'No notification device specified.' 
     370      elif not self.states: 
     371        error_string = 'State or states not specified.' 
     372      elif not self.counties: 
     373        error_string = 'Counties not specified.' 
     374 
     375    #  if string.lower(notification_system) == 'smtp': 
     376      elif not self.email_address: 
     377        error_string = 'Return e-mail address not specified.' 
     378      elif not self.smtp_server: 
     379        error_string = 'SMTP gateway not specified.' 
     380 
     381      if error_string: 
     382        loaderror(error_string) 
     383        sys.exit(1) 
     384 
     385    except IOError: 
     386      loaderror('') 
     387      sys.exit(1) 
     388 
     389  def create(self): 
     390    # If config file doesn't exist, build one for them! 
     391      print interactive_copyright 
     392      print """ 
     393    Welcome to the StormSiren configuration wizard. 
     394 
     395    This program scans the severe weather bulletins issued by the National Weather 
     396    Weather Service and sends alerts in the form of text messages to your pager, 
     397    wireless phone and/or electronic mailbox.   
     398      """ 
     399 
     400      device_selection = 4 
     401      while device_selection: 
     402        print "Select a Notification Method." 
     403        print "1.  Mobile Phone/Pager with an e-mail address" 
     404        print "2.  Regular Internet E-Mail address" 
     405        print "3.  MythTv IP address" 
     406        print "Enter the number of the notification method to use.  Enter a " 
     407        print "zero (0) if you are all done entering devices." 
     408        print "Method? ", 
     409         
     410        try: 
     411          device_selection = int(raw_input()) 
     412          print " " 
     413        except ValueError: 
     414          print "\nSorry, that response didn't make sense.\n" 
     415          device_selection = 4 
     416          continue 
     417 
     418        if device_selection == 0: 
     419          break 
     420        elif device_selection == 1: 
     421          notification_system = 'sms' 
     422          print "What is the e-mail address of your phone/pager? " 
     423        elif device_selection == 2: 
     424          notification_system = 'email' 
     425          print "What is your e-mail address? " 
     426        elif device_selection == 3: 
     427          notification_system = 'mythtv' 
     428          print "What is your MythTv\'s IP address? " 
     429        else: 
     430          print "\nI don't recognize that option, please try again." 
     431          device_selection = 4 
     432          continue 
     433        device_id = raw_input() 
     434        self.devices[device_id] = notification_system 
     435        print " " 
     436 
     437      print "What state do you live in or wish to monitor?  You can enter multiple " 
     438      print "states, separated by commas.  Please use the two letter postal " 
     439      print "abbrevion." 
     440      print "States? ", 
     441      self.states = raw_input() 
     442      print "\nOn which counties would you like to be alerted regarding severe " 
     443      print "weather watches and warnings?  You can enter multiple counties, " 
     444      print "separated by commas."   
     445      print "Counties? ", 
     446      self.counties = raw_input() 
     447      print "\nYou can also opt to have specific cities appear in the alert if " 
     448      print "those cities are listed in the NWS bulletins.  Enter multiple cities " 
     449      print "by separating them by commas." 
     450      print "Cities? ", 
     451      self.cities = raw_input() 
     452      print "\nWhat is your e-mail address?  This is needed for setting the " 
     453      print "originator address for the message?" 
     454      print "E-Mail? ", 
     455      self.email = raw_input() 
     456      print "\nWhat SMTP server do you use for outbound mail? " 
     457      print "SMTP server? ", 
     458      self.smtp = raw_input() 
     459      print "\nWhat is the port number used by your SMTP server? [default 25]" 
     460      print "SMTP port? ", 
     461      a_port = raw_input() 
     462      if a_port: 
     463        self.smtp_port = a_port 
     464      else: 
     465        self.smtp_port = "25" 
     466      print "\nAUTHENTICATED SMTP OPTION - ONLY REQUIRED IF YOUR ISP/MAIL SERVER" 
     467      print "REQUIRES AUTHENTICATION FOR SENDING OUTBOUND E-MAIL" 
     468      print "*** Note that your outbound SMTP password will be stored in the " 
     469      print "StormSiren configuration file.  It is not recommended that you run" 
     470      print "StormSiren using authenticated SMTP on a public/shared computer" 
     471      print "Does your ISP require authentication for sending outbound mail? [y/n]" 
     472      a_auth = string.lower(string.strip(raw_input())) 
     473      if a_auth == "y": 
     474          print "\nWhat is your outbound e-mail username? " 
     475          self.smtp_user = raw_input() 
     476          print "\nWhat is your outbound e-mail password? " 
     477          self.smtp_pass = raw_input() 
     478      print "\nWhat types of alerts would you like to receive? " 
     479      print "1.  Warnings only (imminent severe weather threat)" 
     480      print "2.  Warnings and watches (approaching or potential threat)" 
     481      print "3.  Advisories and warnings and watches" 
     482      print "4.  Statements and Advisories and warnings and watches" 
     483      print "5.  Forecasts and Statements and Advisories and warnings and watches" 
     484      print "Alert Level? ", 
     485      alert_level = raw_input() 
     486      print "\nWould you like any debugging information written to the screen " 
     487      print "or to a logfile? " 
     488      print "0.  No logging" 
     489      print "1.  Write to " + self.log_file 
     490      print "2.  Write to computer screen (stdout)" 
     491      print "Debug Level? ", 
     492      debug_level = raw_input() 
     493      print "\nThanks.  Writing configuration file to " + self.config_file 
     494      conf_f = open(self.config_file, 'w') 
     495      conf_f.write("# Autogenerated Storm configuration file\n") 
     496      conf_f.write("STATES: " + str(self.states) + "\n") 
     497      conf_f.write("COUNTIES: " + str(self.counties) + "\n") 
     498      conf_f.write("CITIES: " + str(self.cities) + "\n") 
     499      conf_f.write("EMAIL: " + self.email + "\n") 
     500      conf_f.write("SMTP: " + self.smtp + "\n") 
     501      conf_f.write("SMTP_PORT: " + self.smtp_port + "\n") 
     502      if smtp_user: 
     503          conf_f.write("SMTP_USER: " + self.smtp_user + "\n") 
     504          conf_f.write("SMTP_PASS: " + self.smtp_pass + "\n") 
     505      devkeys = self.devices.keys() 
     506      for i in range(len(devkeys)): 
     507        conf_f.write("device: " + devkeys[i] + " " + self.devices[devkeys[i]] + "\n") 
     508      conf_f.write("ALERT: " + self.alert_level + "\n") 
     509      conf_f.write("DEBUG: " + self.debug_level + "\n") 
     510      conf_f.close() 
     511      sys.exit() 
     512 
     513#MAIN 
     514conf = config() 
     515 
     516# Initialize Alarm Info 
     517if conf.debug_level >= 2: 
    350518  print interactive_copyright 
    351   print """ 
    352 Welcome to the StormSiren configuration wizard. 
    353  
    354 This program scans the severe weather bulletins issued by the National Weather 
    355 Weather Service and sends alerts in the form of text messages to your pager, 
    356 wireless phone and/or electronic mailbox.   
    357   """ 
    358  
    359   device_selection = 4 
    360   while device_selection: 
    361     print "Select a Notification Method." 
    362     print "1.  Mobile Phone/Pager with an e-mail address" 
    363     print "2.  Regular Internet E-Mail address" 
    364     print "3.  MythTv IP address" 
    365     print "Enter the number of the notification method to use.  Enter a " 
    366     print "zero (0) if you are all done entering devices." 
    367     print "Method? ", 
    368      
    369     try: 
    370       device_selection = int(raw_input()) 
    371       print " " 
    372     except ValueError: 
    373       print "\nSorry, that response didn't make sense.\n" 
    374       device_selection = 4 
    375       continue 
    376  
    377     if device_selection == 0: 
    378       break 
    379     elif device_selection == 1: 
    380       notification_system = 'sms' 
    381       print "What is the e-mail address of your phone/pager? " 
    382     elif device_selection == 2: 
    383       notification_system = 'email' 
    384       print "What is your e-mail address? " 
    385     elif device_selection == 3: 
    386       notification_system = 'mythtv' 
    387       print "What is your MythTv\'s IP address? " 
    388     else: 
    389       print "\nI don't recognize that option, please try again." 
    390       device_selection = 4 
    391       continue 
    392     device_id = raw_input() 
    393     devices[device_id] = notification_system 
    394     print " " 
    395  
    396   print "What state do you live in or wish to monitor?  You can enter multiple " 
    397   print "states, separated by commas.  Please use the two letter postal " 
    398   print "abbrevion." 
    399   print "States? ", 
    400   states = raw_input() 
    401   print "\nOn which counties would you like to be alerted regarding severe " 
    402   print "weather watches and warnings?  You can enter multiple counties, " 
    403   print "separated by commas."   
    404   print "Counties? ", 
    405   counties = raw_input() 
    406   print "\nYou can also opt to have specific cities appear in the alert if " 
    407   print "those cities are listed in the NWS bulletins.  Enter multiple cities " 
    408   print "by separating them by commas." 
    409   print "Cities? ", 
    410   cities = raw_input() 
    411   print "\nWhat is your e-mail address?  This is needed for setting the " 
    412   print "originator address for the message?" 
    413   print "E-Mail? ", 
    414   email = raw_input() 
    415   print "\nWhat SMTP server do you use for outbound mail? " 
    416   print "SMTP server? ", 
    417   smtp = raw_input() 
    418   print "\nWhat is the port number used by your SMTP server? [default 25]" 
    419   print "SMTP port? ", 
    420   a_port = raw_input() 
    421   if a_port: 
    422     smtp_port = a_port 
    423   else: 
    424     smtp_port = "25" 
    425   print "\nAUTHENTICATED SMTP OPTION - ONLY REQUIRED IF YOUR ISP/MAIL SERVER" 
    426   print "REQUIRES AUTHENTICATION FOR SENDING OUTBOUND E-MAIL" 
    427   print "*** Note that your outbound SMTP password will be stored in the " 
    428   print "StormSiren configuration file.  It is not recommended that you run" 
    429   print "StormSiren using authenticated SMTP on a public/shared computer" 
    430   print "Does your ISP require authentication for sending outbound mail? [y/n]" 
    431   a_auth = string.lower(string.strip(raw_input())) 
    432   if a_auth == "y": 
    433       print "\nWhat is your outbound e-mail username? " 
    434       smtp_user = raw_input() 
    435       print "\nWhat is your outbound e-mail password? " 
    436       smtp_pass = raw_input() 
    437   print "\nWhat types of alerts would you like to receive? " 
    438   print "1.  Warnings only (imminent severe weather threat)" 
    439   print "2.  Warnings and watches (approaching or potential threat)" 
    440   print "Alert Level? ", 
    441   alert_level = raw_input() 
    442   print "\nWould you like any debugging information written to the screen " 
    443   print "or to a logfile? " 
    444   print "0.  No logging" 
    445   print "1.  Write to " + log_file 
    446   print "2.  Write to computer screen (stdout)" 
    447   print "Debug Level? ", 
    448   debug_level = raw_input() 
    449   print "\nThanks.  Writing configuration file to " + config_file 
    450   conf_f = open(config_file, 'w') 
    451   conf_f.write("# Autogenerated Storm configuration file\n") 
    452   conf_f.write("STATES: " + str(states) + "\n") 
    453   conf_f.write("COUNTIES: " + str(counties) + "\n") 
    454   conf_f.write("CITIES: " + str(cities) + "\n") 
    455   conf_f.write("EMAIL: " + email + "\n") 
    456   conf_f.write("SMTP: " + smtp + "\n") 
    457   conf_f.write("SMTP_PORT: " + smtp_port + "\n") 
    458   if smtp_user: 
    459       conf_f.write("SMTP_USER: " + smtp_user + "\n") 
    460       conf_f.write("SMTP_PASS: " + smtp_pass + "\n") 
    461   devkeys = devices.keys() 
    462   for i in range(len(devkeys)): 
    463     conf_f.write("device: " + devkeys[i] + " " + devices[devkeys[i]] + "\n") 
    464   conf_f.write("ALERT: " + alert_level + "\n") 
    465   conf_f.write("DEBUG: " + debug_level + "\n") 
    466   conf_f.close() 
    467   sys.exit() 
    468  
    469 # Initialize Alarm Info 
    470 if debug_level >= 2: 
    471   print interactive_copyright 
     519 
    472520alarms       = [] 
    473521state_exists = 0 
    474522new_state    = [] 
    475523page_queue   = [] 
    476 weather_data = [] 
     524weather = [] 
    477525 
    478526# Note program initialization 
    479 if debug_level >= 2: 
    480   print "StormSiren initiated" 
     527if conf.debug_level >= 2: 
     528  print APPNAME + " initiated" 
    481529 
    482530# Build list of xmlWeather objects 
    483 for i in range(len(states)): 
     531for state in conf.states: 
    484532#HERE 
    485   xw = xmlWeather(states[i]) 
     533  xw = xmlWeather(state,conf.counties) 
    486534  xw.fetch() 
    487535  xw.parse() 
    488   weather_data.append(xw) 
    489  
    490 sys.exit()  
    491 print """ 
    492 # Developer Mode, read data from local saved file on disk 
    493 if debug_level == 9: 
    494   print "...fetching test data from local disk..." 
    495   testwatch = open(config_dir + '/testwatch.txt') 
    496   testwatch_data = testwatch.readlines() 
    497   testwatch.close() 
    498   weather_data = weather_data + testwatch_data 
    499  
     536  weather.append(xw) 
     537 
     538alert_data = [] 
     539 
     540alert_page = urllib.urlopen() 
     541alert_data.append(alert_page) 
     542alert_page.close() 
     543 
     544""" 
    500545# Initialize some flags and counters 
    501546pre          = 0 
     
    521566watch_counties   = re.compile("(INCLUDES|^IN\s+|^...IN\s+)") 
    522567 
     568""" 
    523569# Parse watch data that we retrieved from the NWS 
    524 for i in range(len(weather_data)): 
    525   pre_on      = string.count(string.upper(weather_data[i]), '<PRE>') 
    526   pre_off     = string.count(string.upper(weather_data[i]), '</PRE>') 
     570for i in range(len(alert_data)): 
     571  pre_on      = string.count(string.upper(alert_data[i]), '<PRE>') 
     572  pre_off     = string.count(string.upper(alert_data[i]), '</PRE>') 
    527573 
    528574# The preformatted tags appear to consistently indicate the beginning of each 
     
    532578    pre = 1 
    533579    wx = wxalert() 
    534     wx.bulletin.append(weather_data[i][9:]) 
     580    wx.bulletin.append(alert_data[i][9:]) 
    535581#000 
    536582#WUUS55 KABQ 110255 
    537583#SVRABQ 
    538     verify_string = string.upper(string.strip(weather_data[i])) 
     584    verify_string = string.upper(string.strip(alert_data[i])) 
    539585    verify_string.strip() 
    540586    verify_substring = verify_string.replace("<PRE>", "") 
    541587    if verify_substring: 
    542         wx.prestring = weather_data[i] 
     588        wx.prestring = alert_data[i] 
    543589    else: 
    544         wx.prestring = weather_data[i+3] 
    545 #    wx.prestring  = weather_data[i] 
     590        wx.prestring = alert_data[i+3] 
     591#    wx.prestring  = alert_data[i] 
    546592    watch_count = watch_count + 1 
    547593    continue 
     
    569615# expression matches. 
    570616  if pre: 
    571     wx.bulletin.append(weather_data[i]) 
    572     cities_on   = string.count(weather_data[i], 'SOME CITIES INCLUDED IN THE WATCH ARE...') 
    573     cities_on   = cities_on + string.count(weather_data[i], 'THIS INCLUDES THE CITIES OF') 
    574     counties_on = watch_counties.search(weather_data[i]) 
    575     eas_warning_on = splat_warn_pat.search(weather_data[i]) 
    576     eas_locations_on = string.count(weather_data[i], 'SOME LOCATIONS AFFECTED BY THIS') 
     617    wx.bulletin.append(alert_data[i]) 
     618    cities_on   = string.count(alert_data[i], 'SOME CITIES INCLUDED IN THE WATCH ARE...') 
     619    cities_on   = cities_on + string.count(alert_data[i], 'THIS INCLUDES THE CITIES OF') 
     620    counties_on = watch_counties.search(alert_data[i]) 
     621    eas_warning_on = splat_warn_pat.search(alert_data[i]) 
     622    eas_locations_on = string.count(alert_data[i], 'SOME LOCATIONS AFFECTED BY THIS') 
    577623     
    578624# Parse the included cities section 
     
    599645    if city: 
    600646        for j in range(len(cities)): 
    601           if string.count(weather_data[i], string.upper(cities[j])): 
     647          if string.count(alert_data[i], string.upper(cities[j])): 
    602648            wx.cities = wx.cities + string.upper(cities[j]) + ' '  
    603649# Match for county 
    604650    elif cnty: 
    605651        for j in range(len(counties)): 
    606           if string.count(weather_data[i], string.upper(counties[j])): 
     652          if string.count(alert_data[i], string.upper(counties[j])): 
    607653            wx.counties = wx.counties + string.upper(counties[j]) + ' ' 
    608654# Warning cities 
    609655    if eas_city: 
    610656        for j in range(len(cities)): 
    611           if string.count(weather_data[i], string.upper(cities[j])): 
     657          if string.count(alert_data[i], string.upper(cities[j])): 
    612658            wx.cities = wx.cities + string.upper(cities[j]) + ' '  
    613659# Match for counties in warnings 
    614660    elif eas_cnty: 
    615         eas_cnty_test = county_pattern.search(weather_data[i]) 
     661        eas_cnty_test = county_pattern.search(alert_data[i]) 
    616662        if eas_cnty_test: 
    617663          for j in range(len(counties)): 
     
    622668# This is the main part of the bulletin 
    623669    else: 
    624       watch_info  = watch_info_e.search(weather_data[i]) 
    625       watch_time  = watch_time_e.search(weather_data[i]) 
    626       watch_expir = watch_expir_e.search(weather_data[i]) 
    627       eas_until   = splat_until.search(weather_data[i]) 
    628       eas_at      = splat_at.search(weather_data[i]) 
     670      watch_info  = watch_info_e.search(alert_data[i]) 
     671      watch_time  = watch_time_e.search(alert_data[i]) 
     672      watch_expir = watch_expir_e.search(alert_data[i]) 
     673      eas_until   = splat_until.search(alert_data[i]) 
     674      eas_at      = splat_at.search(alert_data[i]) 
    629675      if watch_info: 
    630676        wx.id = year + '_' + string.strip(watch_info.group(2)) 
     
    723769# Create mail server object 
    724770    msg_headers = 'From: ' + email_address + '\n' 
    725     msg_headers = msg_headers + 'Subject: StormSiren Alert\n' 
    726     msg_headers = msg_headers + 'X-Mailer: StormSiren ' + __version__ + '\n\n' 
     771    msg_headers = msg_headers + 'Subject: ' + APPNAME + ' Alert\n' 
     772    msg_headers = msg_headers + 'X-Mailer: ' APPNAME + __version__ + '\n\n' 
    727773     
    728774    if sms_recp: 
     
    785831for i in range(len(log_buffer)):   
    786832  if debug_level == 1: 
    787     logw.write("StormSiren " + now + ": " + log_buffer[i] + "\n") 
     833    logw.write(APPNAME + " " + now + ": " + log_buffer[i] + "\n") 
    788834  elif debug_level > 1: 
    789835    print log_buffer[i]