root/StormSiren/CapAtom.py

Revision 189:8190540dae37, 7.9 KB (checked in by cfreeze@…, 3 years 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
44import re
45import sys
46import datetime
47import logging
48
49from WeatherTypes import WeatherTypes
50from CapTimezone import CapTimezone
51from CapAlert import CapAlert
52
53class CapAtom(object):
54        def __init__(self,xml,state):
55                self.log = logging.getLogger("CapAtom")
56
57                self.__tag_url = 'id'
58                self.__url_e    = re.compile('(.*)x=(.*)$')
59                self.__url       = ''
60                self.__id        = ''
61
62                self.__tag_area  = 'cap:areaDesc'
63                self.__areas     = []
64                self.__state     = state
65
66                self.__tag_issued  = 'cap:effective'
67                self.__tag_expires = 'cap:expires'
68                self.__tag_updated = 'updated'
69                self.__datetime_e  = re.compile('(\d+)-(\d+)-(\d+)T(\d+):(\d+):(\d+)(\-|\+)(\d+):(\d+)$')
70                self.__issued      = ''
71                self.__expires     = ''
72                self.__updated     = ''
73
74                self.__tag_urgency   = 'cap:urgency'
75                self.__urgency       = ''
76                self.__tag_severity  = 'cap:severity'
77                self.__severity      = ''
78                self.__tag_certainty = 'cap:certainty'
79                self.__certainty     = ''
80
81                self.__tag_title     = 'title'
82                self.__title_e       = re.compile('^(.+) Issued At:.*$')
83                self.__title         = ''
84                self.__matter        = ''
85                self.__event_e       = re.compile('(.*) (\w+)$')
86                self.__type          = WeatherTypes()
87
88                self.__expanded      = False
89                self.__cap_alert     = None
90
91                self.__parse(xml)
92
93        def __trim(self,str):
94                if(str):
95                        str = str.strip()
96                        str = str.replace("\n","")
97
98        def __parse(self,xml):
99                self.__url = self.__getfield(xml,self.__tag_url)
100
101                if(self.__url):
102                        self.__url = self.__url.replace("\n", ' ').strip(' ')
103                        parse_res = self.__url_e.search(self.__url)
104                        if(parse_res != None):
105                                self.__id = parse_res.group(2)
106
107                self.__issued = self.getDateTime(self.__getfield(xml,self.__tag_issued))
108                self.__expires = self.getDateTime(self.__getfield(xml,self.__tag_expires))
109                self.__updated = self.getDateTime(self.__getfield(xml,self.__tag_updated))
110
111                self.__urgency = self.__trim(self.__getfield(xml,self.__tag_urgency))
112                self.__severity = self.__trim(self.__getfield(xml,self.__tag_severity))
113                self.__certainty = self.__trim(self.__getfield(xml,self.__tag_certainty))
114
115                areas = self.__getfield(xml,self.__tag_area)
116                if(areas):
117                        areas = areas.replace("\n",' ')
118                        areas = areas.replace("/", ';')
119                        for area in areas.split(';'):
120                                self.__areas.append(area.strip())
121
122                self.__title = self.__getfield(xml,self.__tag_title)
123                if(self.__title):
124                        parse_res = self.__title_e.search(self.__title.replace("\n", ' '))
125                        if(parse_res):
126                                parse_res = self.__event_e.search(parse_res.group(1))
127                                if(parse_res):
128                                        self.__matter = parse_res.group(1)
129                                        self.__type = WeatherTypes.fromString(parse_res.group(2))
130
131        def getDateTime(self,text):
132                timestamp = None
133                parse_res = self.__datetime_e.search(text)
134                if(parse_res):
135                        timezone = CapTimezone()
136                        timezone.setOffset(int(parse_res.group(8)))
137                        timezone.setSign(parse_res.group(7))
138                        timestamp = datetime.datetime(int(parse_res.group(1)), int(parse_res.group(2)), int(parse_res.group(3)), int(parse_res.group(4)), int(parse_res.group(5)), int(parse_res.group(6)),0,timezone)
139
140                return timestamp
141
142
143        def __getfield(self,xml,tag):
144                val = xml.getElementsByTagName(tag)
145
146                if(val):
147                        return val[0].firstChild.data
148                else:
149                        return ""
150
151        def display(self):
152                print self.__str__()
153
154        def displayFull(self):
155                self.display()
156                print "\tDesc: " + self.description
157
158        def getState(self):
159                return self.__state
160
161        def getIssued(self):
162                if(self.__issued):
163                        return self.__issued.strftime("%a %b %d %Y - %I:%M:%S %p")
164                else:
165                        return None
166
167        def getExpires(self):
168                if(self.__expires):
169                        return self.__expires.strftime("%a %b %d %Y - %I:%M:%S %p")
170                else:
171                        return None
172
173        def getUpdated(self):
174                if(self.__updated):
175                        return self.__updated.strftime("%a %b %d %Y - %I:%M:%S %p")
176                else:
177                        return None
178
179        def getType(self):
180                return self.__type
181
182        def getId(self):
183                return self.__id
184
185        def getAreas(self):
186                return self.__areas
187
188        def getMatter(self):
189                return self.__matter
190
191        def expanded(self):
192                return self.__expanded
193
194        def expand(self,simfetch,proxy):
195                if(not self.__expanded):
196                        self.__expanded = True
197                        self.log.info("Expanding CAP: %s" % self.__id)
198                        self.__cap_alert = CapAlert(self.__url,simfetch,proxy)
199
200        def getDescription(self):
201                if(self.__cap_alert):
202                        return self.__cap_alert.description
203                else:
204                        return None
205
206        def getHeadline(self):
207                if(self.__cap_alert):
208                        return self.__cap_alert.headline
209                else:
210                        return None
211
212        def getUrl(self):
213                return self.__url
214
215        def getUrgency(self):
216                return self.__urgency
217
218        def getSeverity(self):
219                return self.__severity
220
221        def getCertainty(self):
222                return self.__certainty
223
224        id = property(getId,None,None)
225        areas = property(getAreas,None,None)
226        type = property(getType,None,None)
227        state = property(getState,None,None)
228        matter = property(getMatter,None,None)
229        headline = property(getHeadline,None,None)
230        url = property(getUrl,None,None)
231        issued = property(getIssued,None,None)
232        expires = property(getExpires,None,None)
233        updated = property(getUpdated,None,None)
234        urgency = property(getUrgency,None,None)
235        severity = property(getSeverity,None,None)
236        certainty = property(getCertainty,None,None)
237        headline = property(getHeadline,None,None)
238        description = property(getDescription,None,None)
239
240        def __str__(self):
241                str = "\tId: " + self.id + "\n" + \
242                        "\tState: " + self.state + "\n"
243                str += "\tAreas: %s\n" % self.getAreas()
244                if(self.type != None):
245                        str += "\tType: " + WeatherTypes.toString(self.__type) + "\n"
246                if(self.headline != None):
247                        str += "\tHeadline: " + self.headline + "\n"
248                if(self.matter != None):
249                        str += "\tMatter: " + self.matter + "\n"
250                if(self.url != None):
251                        str += "\tURL: " + self.__url + "\n"
252                if(self.issued != None):
253                        str += "\tIssued: " + self.issued + "\n"
254                if(self.expires != None):
255                        str += "\tExpires: " + self.expires + "\n"
256                if(self.updated != None):
257                        str += "\tUpdated: " + self.updated + "\n"
258                if(self.urgency != None):
259                        str += "\tUrgency: " + self.__urgency + "\n"
260                if(self.severity != None):
261                        str += "\tSeverity: " + self.__severity + "\n"
262                if(self.certainty != None):
263                        str += "\tCertainty: " + self.__certainty + "\n"
264                return str
Note: See TracBrowser for help on using the browser.