root/StormSiren/AlertDevice.py

Revision 189:8190540dae37, 5.4 KB (checked in by cfreeze@…, 22 months ago)

remove extra spaces that were appearing in the area text

  • Property exe set to *
Line 
1#!/usr/bin/env python
2
3"""
4StormSiren
5Copyright (C) 2008  Chris Freeze <cfreeze/cfreeze_com\>
6
7Redistribution and use in source and binary forms, with or without
8modification, are permitted provided that the following conditions
9are met:
10
111. Redistributions of source code must retain the above copyright
12   notice, this list of conditions and the following disclaimer.
132. Redistributions in binary form must reproduce the above copyright
14   notice, this list of conditions and the following disclaimer in the
15   documentation and/or other materials provided with the distribution.
16
17THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27"""
28
29"""
30This is StormSiren a program inspired by the StormSiren application
31written by Roy McManus <slorf/users_sourceforge_net>.  Much like the
32original StormSiren written by Roy McManus <slorf/users_sourceforge_net>,
33this program is a simple script capable of scanning and providing
34notifications of weather bulletins issued by the National
35Weather Service.  StormSiren supports a wide range of paging devices
36and filtering of alert types per alert device.  While inspired by
37StormSiren, StormSiren is a complete rewrite that is capable of using
38the new CAP/XML feeds provided at http://www.weather.gov/alerts/.
39
40For more information there is see the README.TXT file located in the root
41of this directory.
42"""
43
44#GLOBAL START
45import re
46import logging
47import sys
48#GLOBAL END
49
50#LOCAL START
51from WeatherTypes import *
52#LOCAL END
53
54#CODE START
55class AlertDevice(object):
56        def __init__(self, alerts, areas):
57                self.__weather_types = WeatherTypes()
58                self.__areas = {}
59                self.log = logging.getLogger('AlertDevice')
60
61                self.log.setLevel(logging.INFO)
62                self.__parse_weather_types(alerts)
63                self.__parse_areas(areas)
64
65        def __parse_weather_types(self,weather_types):
66                self.log.debug("parsing weather types: -(%s)-" % weather_types)
67                try:
68                        wtypes = weather_types.split(',')
69                except Exception,e:
70                        self.log.error("Unable to weather types in [%s]" % weather_types)
71                        sys.exit(3)
72
73                for w in wtypes:
74                        self.addWeatherTypes(w)
75
76        def __parse_areas(self,areas):
77                self.log.debug("parsing areas: -(%s)-" % areas)
78                try:
79                        locations = areas.split(':')
80                except Exception,e:
81                        self.log.error("Unable to parse area in [%s]" % areas)
82                        sys.exit(3)
83
84                for loc in locations:
85                        self.log.debug("parsing location: -(%s)-" % loc)
86
87                        try:
88                                (spot,state) = loc.split(',')
89                        except Exception,e:
90                                self.log.error("Unable to parse location in [%s]" % areas)
91                                sys.exit(3)
92
93                        if(not self.__areas.has_key(state)):
94                                self.__areas[state] = [spot.lower()]
95                        else:
96                                self.__areas[state].append(spot.lower())
97
98        def __str__(self):
99                str = "AlertDevice:\n"
100                str += "\tWeather Types: %s" % WeatherTypes.toString(self.__weather_types) + "\n"
101                str += "Areas:\n"
102                for state in self.__areas:
103                        str += "\n\tState: %s\n\t\t" % state
104                        str += "\n\t\t".join(self.__areas[state])
105                return str
106
107        def display(self):
108                print self.__str__()
109
110        def send(self,alert):
111                print "Sending Alert: " + alert.id
112
113        def addWeatherTypes(self,wtype):
114                wtype = wtype.lower()
115                if wtype.find("warning") >= 0:
116                        self.__weather_types |= WeatherTypes(WARNING)
117                if wtype.find("watch") >= 0:
118                        self.__weather_types |= WeatherTypes(WATCH)
119                if wtype.find("advisory") >= 0:
120                        self.__weather_types |= WeatherTypes(ADVISORY)
121                if wtype.find("statement") >= 0:
122                        self.__weather_types |= WeatherTypes(STATEMENT)
123                if wtype.find("forecast") >= 0:
124                        self.__weather_types |= WeatherTypes(FORECAST)
125                if wtype.find("alert") >= 0:
126                        self.__weather_types |= WeatherTypes(ALERT)
127
128        def isTypeWanted(self, type):
129                if (self.__weather_types & type):
130                        return True
131                return False
132
133        def isStateWanted(self,state):
134                if(self.__areas.has_key(state)):
135                        return True
136                return False
137
138        def isAreaWanted(self,state,alert_areas):
139                if(self.__areas.has_key(state)):
140                        for area in alert_areas:
141                                self.log.debug("checking if (%s) is in (%s)" % (area.lower(),self.__areas[state]))
142                                if(area.lower() in self.__areas[state]):
143                                        self.log.debug("%s IS IN (%s)" % (area.lower(),self.__areas[state]))
144                                        return True
145                return False
146
147        def isAlertWanted(self,cap_alert):
148                self.log.debug("Testing[%s]: (%s/%i)" % (cap_alert.id, cap_alert.state, cap_alert.type))
149                if(self.isTypeWanted(cap_alert.type) and self.isStateWanted(cap_alert.state)):
150                        self.log.debug("Testing[%s]: type and state match(%s/%i)" % (cap_alert.id, cap_alert.state, cap_alert.type))
151                        if(self.isAreaWanted(cap_alert.state, cap_alert.areas)):
152                                self.log.debug("Alert hit on area[%s/%s]: %s" % (cap_alert.state, cap_alert.id, cap_alert.areas))
153                                return True
154                        else:
155                                self.log.debug("Testing[%s]: alert not in watched area(%s/%s)" % (cap_alert.id, cap_alert.state, cap_alert.areas))
156                else:
157                        self.log.debug("Testing[%s]: Either wrong type or state (%s/%i)" % (cap_alert.id, cap_alert.state, cap_alert.type))
158                return False
159#CODE END
Note: See TracBrowser for help on using the browser.