-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #76 from networktocode/release-v2.0.0
Release v2.0.0
- Loading branch information
Showing
23 changed files
with
956 additions
and
96 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
"""AquaComms parser.""" | ||
import logging | ||
import re | ||
from datetime import datetime | ||
|
||
from circuit_maintenance_parser.parser import EmailSubjectParser, Html, Impact, CircuitImpact, Status | ||
|
||
# pylint: disable=too-many-nested-blocks, too-many-branches | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
class SubjectParserAquaComms1(EmailSubjectParser): | ||
"""Parser for Seaborn subject string, email type 1.""" | ||
|
||
def parse_subject(self, subject): | ||
"""Parse subject of email file. | ||
Subject: Aqua Comms Planned Outage Work ISSUE=111111 PROJ=999 | ||
""" | ||
data = {} | ||
search = re.search(r"ISSUE=([0-9]+).PROJ=([0-9]+)", subject) | ||
if search: | ||
data["maintenance_id"] = search.group(1) | ||
data["account"] = search.group(2) | ||
return [data] | ||
|
||
|
||
class HtmlParserAquaComms1(Html): | ||
"""Notifications Parser for AquaComms notifications.""" | ||
|
||
def parse_html(self, soup): | ||
"""Execute parsing.""" | ||
data = {} | ||
self.parse_tables(soup.find_all("table"), data) | ||
return [data] | ||
|
||
@staticmethod | ||
def get_tr_value(element): | ||
"""Remove new lines and split key to value.""" | ||
return element.text.replace("\n", "").split(": ")[1].strip() | ||
|
||
def parse_tables(self, tables, data): | ||
"""Parse HTML tables. | ||
<table> | ||
<tbody> | ||
<tr> | ||
<td><font>Ticket Number:</font></td> | ||
<td><font>11111</font></td> | ||
</tr> | ||
<tr> | ||
<td><font>Scheduled Start Date & Time:</font></td> | ||
<td><font>22:00 12/10/2020 GMT</font></td> | ||
</tr> | ||
<tr> | ||
<td><font>Scheduled End Date & Time:</font></td> | ||
<td><font>22:00 12/10/2020 GMT</font></td> | ||
</tr> | ||
... | ||
</tbody> | ||
</table> | ||
""" | ||
for table in tables: | ||
for tr_element in table.find_all("tr"): | ||
if "ticket number" in tr_element.text.lower(): | ||
data["maintenance_id"] = self.get_tr_value(tr_element) | ||
elif "update" in tr_element.text.lower(): | ||
data["summary"] = tr_element.text.replace("\n", "").split(" - ")[1] | ||
elif "scheduled start date" in tr_element.text.lower(): | ||
data["start"] = self.dt2ts(datetime.strptime(self.get_tr_value(tr_element), "%H:%M %d/%m/%Y %Z")) | ||
elif "scheduled end date" in tr_element.text.lower(): | ||
data["end"] = self.dt2ts(datetime.strptime(self.get_tr_value(tr_element), "%H:%M %d/%m/%Y %Z")) | ||
elif "service id" in tr_element.text.lower(): | ||
data["circuits"] = [ | ||
CircuitImpact(circuit_id=self.get_tr_value(tr_element), impact=Impact("OUTAGE")) | ||
] | ||
data["status"] = Status.CONFIRMED |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
"""Sparkle parser.""" | ||
import logging | ||
from dateutil import parser | ||
|
||
from circuit_maintenance_parser.errors import ParserError | ||
from circuit_maintenance_parser.parser import CircuitImpact, Html, Impact, Status | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
class HtmlParserSparkle1(Html): | ||
"""Notifications HTML Parser 1 for Sparkle notifications. | ||
Example: | ||
<table> | ||
<tbody> | ||
<tr> | ||
<td><p></p>Maintenance ID</td> | ||
<td><p></p>1111 / 2222</td> | ||
</tr> | ||
<tr> | ||
<td><p></p>Start Date/Time (UTC) Day 1</td> | ||
<td><p></p>08/10/2021 03:00 UTC</td> | ||
</tr> | ||
<tr> | ||
<td><p></p>End Date/Time (UTC) Day 1</td> | ||
<td><p></p>08/10/2021 11:00 UTC</td> | ||
</tr> | ||
<tr> | ||
<td><p></p>Start Date/Time (UTC) Day 2</td> | ||
<td><p></p>08/11/2021 03:00 UTC</td> | ||
</tr> | ||
<tr> | ||
<td><p></p>End Date/Time (UTC) Day 2</td> | ||
<td><p></p>08/11/2021 11:00 UTC</td> | ||
</tr> | ||
... | ||
</tbody> | ||
</table> | ||
""" | ||
|
||
def parse_html(self, soup): | ||
"""Execute parsing.""" | ||
data = {} | ||
try: | ||
return self.parse_tables(soup.find_all("table"), data) | ||
except Exception as exc: | ||
raise ParserError from exc | ||
|
||
def clean_string(self, string): | ||
"""Remove hex characters and new lines.""" | ||
return self.remove_hex_characters(string.replace("\n", "")).strip() | ||
|
||
@staticmethod | ||
def set_all_tickets(tickets, attribute, value): | ||
"""Set the same value for all notifications.""" | ||
for ticket in tickets: | ||
ticket[attribute] = value | ||
|
||
def parse_tables(self, tables, data_base): | ||
"""Parse HTML tables.""" | ||
data = [] | ||
for table in tables: | ||
tr_elements = table.find_all("tr") | ||
for idx, tr_element in enumerate(tr_elements): | ||
td_elements = tr_element.find_all("td") | ||
if "sparkle ticket number" in td_elements[0].text.lower(): | ||
tickets = self.clean_string(td_elements[1].text).split("/ ") | ||
for ticket_id in tickets: | ||
ticket = data_base.copy() | ||
ticket["maintenance_id"] = ticket_id | ||
if "start date/time" in tr_elements[idx + 1].text.lower(): | ||
start = self.clean_string(tr_elements[idx + 1].find_all("td")[1].text) | ||
ticket["start"] = self.dt2ts(parser.parse(start)) | ||
else: | ||
raise ParserError("Unable to find start time for ticket " + ticket_id) | ||
if "end date/time" in tr_elements[idx + 2].text.lower(): | ||
end = self.clean_string(tr_elements[idx + 2].find_all("td")[1].text) | ||
ticket["end"] = self.dt2ts(parser.parse(end)) | ||
else: | ||
raise ParserError("Unable to find end time for ticket " + ticket_id) | ||
idx += 2 | ||
data.append(ticket) | ||
elif "circuits involved" in td_elements[0].text.lower(): | ||
self.set_all_tickets( | ||
data, | ||
"circuits", | ||
[CircuitImpact(impact=Impact.OUTAGE, circuit_id=self.clean_line(td_elements[1].text))], | ||
) | ||
elif "description of work" in td_elements[0].text.lower(): | ||
self.set_all_tickets(data, "summary", self.clean_string(td_elements[1].text)) | ||
self.set_all_tickets(data, "status", Status.CONFIRMED) | ||
self.set_all_tickets(data, "account", "Not Available") | ||
return data |
Oops, something went wrong.