def _fetch_xsa_data(self): resp = request.get(self.XSA_URL) if resp.status_code != 200: print "Error fetching XSAs: %s" % resp.status_code return {} soup = BeautifulSoup(resp.text) rows = soup.findAll("tr") data = {} for row in rows: children = row.findChildren("td") if not children: continue try: xsa_id = children[0].contents[0].string except: continue try: xsa_link = "".join([self.XSA_URL, children[0].contents[0]["href"]]) except: xsa_link = None try: public_release = children[1].contents[0] except: public_release = None try: title = children[5].contents[0] except: title = None data[xsa_id] = {"id": xsa_id, "link": xsa_link, "public_release": public_release, "title": title} return data
def allergies(self, message, params=None, **kwargs): """Display current allergies in San Antonio, TX (ex: .allergies).""" d = datetime.datetime.now() weekend = d.isoweekday() in (6, 7) if weekend: message.dispatch("Unable to fetch allergy data on weekends.") return today = d.strftime("%Y-%m-%d") url = "http://saallergy.info/day/%s" % today headers = {"accept": "application/json"} response = request.get(url, headers=headers) if response.status_code != 200: return data = response.json() text = "Allergies for %s: " % today for a in data["results"]: text = text + "%s - %s (%s) | " % (a["allergen"], a["level"], a["count"]) text = text.rstrip(" ") text = text.rstrip("|") message.dispatch(text)
def _find_users(self, name): """Find PagerDuty user accounts.""" url = "%s/users?query=%s&include[]=contact_methods" % (self.endpoint, name) req = request.get(url, headers=self.api_headers) if request.ok(req): return req.json()
def _find_issues(self, user_id): """Find all issues for a Redmine user.""" url = "%s/issues.json?assigned_to_id=%s" % (self.redmine_url, user_id) response = request.get(url) if response.status_code != 200: return return response.json()["issues"]
def get_users(self): """Get PagerDuty users and fill the cache.""" url = "%s/api/v1/users" % self.subdomain req = request.get(url, headers=self.api_headers) if request.ok(req): response_json = req.json() return response_json["users"] else: return None
def _find_issues(self, user_id): """Find all issues for a Redmine user.""" url = "%s/issues.json?assigned_to_id=%s" % ( self.redmine_url, user_id) response = request.get(url) if response.status_code != 200: return return response.json()["issues"]
def distance(self, message, params=None, **kwargs): """Display distances (ex: .dist <nick|loc> [to <nick|loc>]).""" maps_api = utils.get_config("GoogleMaps") try: key = maps_api.get("key") except Exception: message.dispatch("No Google Maps API key set.") return parts = params.split(" to ") if not parts: message.dispatch(self.distance.__doc__) return dest_nick = parts[0].strip() if len(parts) > 1: origin_nick = parts[1].strip() else: origin_nick = message.source.split("!")[0] dest = None origin = None for filename in utils.list_files("Wunderground"): nick = filename.split("!")[0] if nick == dest_nick: dest = utils.read_file("Wunderground", filename) if nick == origin_nick: origin = utils.read_file("Wunderground", filename) if not dest: # They passed in a location dest = dest_nick if not origin: # They passed in a location origin = origin_nick origin = _resolve_pws(origin) dest = _resolve_pws(dest) resp = request.get("https://maps.googleapis.com/maps/api" "/directions/json?origin=%s&destination=%s" "&key=%s" % (origin, dest, key)) msg = None if resp.status_code == 200: try: msg = resp.json()["routes"][0]["legs"][0]["distance"]["text"] except IndexError: pass if not msg: msg = "Unable to fetch data from Google Maps." message.dispatch(msg)
def find_incident_id(self): """Finds incident id from the current incident number.""" number = self.get_incident_number() if number is not None: url = "%s/api/v1/incidents/%s" % (self.subdomain, number) req = request.get(url, headers=self.api_headers) if request.ok(req): response_json = req.json() return response_json["id"] return None
def kernel(self, message, params=None, **kwargs): """Retrieve the current kernel version (ex: .kernel)""" url = "https://www.kernel.org/kdist/finger_banner" response = request.get(url) if response.status_code != 200: return r = re.compile("(.* mainline .*)") m = r.search(response.content) kernel = m.group(1).replace(" ", "") message.dispatch(kernel)
def _find_users(self, offset=None): """Find all Redmine users.""" if offset: url = "%s/users.json?limit=100&offset=%d" % ( self.redmine_url, offset) else: url = "%s/users.json?limit=100" % self.redmine_url response = request.get(url) if response.status_code != 200: return return response.json()["users"]
def get_incidents(service_id): """Fetch and return PagerDuty incidents.""" url = "%s/incidents?service_ids[]=%s" % (api_endpoint, service_id) req = request.get(url, headers=api_headers) if not request.ok(req): flask.abort(req.status_code) return flask.render_template( "pagerduty_incidents.html", incidents=req.json()["incidents"], version=version.version_string())
def get_notes(incident_id): """Fetch and return PagerDuty notes.""" url = "%s/incidents/%s/notes" % (api_endpoint, incident_id) req = request.get(url, headers=api_headers) if not request.ok(req): flask.abort(req.status_code) return flask.render_template( "pagerduty_notes.html", notes=req.json()["notes"], version=version.version_string())
def get_services(): """Fetch and return PagerDuty services.""" url = "%s/services?limit=100" % api_endpoint req = request.get(url, headers=api_headers) if not request.ok(req): flask.abort(req.status_code) return flask.render_template( "pagerduty_services.html", services=req.json()["services"], version=version.version_string())
def _find_users(self, offset=None): """Find all Redmine users.""" if offset: url = "%s/users.json?limit=100&offset=%d" % (self.redmine_url, offset) else: url = "%s/users.json?limit=100" % self.redmine_url response = request.get(url) if response.status_code != 200: return return response.json()["users"]
def query(self, message, params=None, **kwargs): """Query an incident (ex: .query <ID>).""" url = "%s/incidents/%s" % (self.endpoint, params) req = request.get(url, headers=self.api_headers) if request.ok(req): incident = req.json()["incident"] summary = incident["summary"] status = incident["status"] link = incident["html_url"] message.dispatch("%s [%s]: %s" % (summary, status, link)) else: message.dispatch("Unable to query incident: %d" % req.status_code) message.dispatch(req.text)
def find_incident_number(self): """Finds incident number from the current incident key.""" key = self.get_incident_key() if key is not None: url = "%s/api/v1/incidents" % self.subdomain params = {"incident_key": key, "sort_by": "created_on:desc"} req = request.get(url, headers=self.api_headers, params=params) if request.ok(req): response_json = req.json() incidents = response_json["incidents"] if len(incidents) > 0: number = incidents[0]["incident_number"] return number return None
def notes(self, message, params=None, **kwargs): """List all notes an incident (ex: .note <ID>).""" url = "%s/incidents/%s/notes" % (self.endpoint, params) req = request.get(url, headers=self.api_headers) if request.ok(req): notes = req.json()["notes"] message.dispatch("There are %d notes." % len(notes)) for note in notes: message.dispatch("%s %s - %s" % (note["created_at"], note["user"]["summary"], note["content"])) else: message.dispatch("Unable to fetch notes: %d" % req.status_code) message.dispatch(req.text)
def oncall(self, message, params=None, **kwargs): """Show who is on call (ex: .oncall).""" url = "%s/oncalls" % self.endpoint req = request.get(url, headers=self.api_headers) if request.ok(req): on_calls = [] for policy in req.json()["oncalls"]: if policy["schedule"]: on_calls.append("%s (%s)" % (policy["schedule"]["summary"], policy["user"]["summary"])) message.dispatch(", ".join(on_calls)) else: message.dispatch("Unable to fetch list: %d" % req.status_code) message.dispatch(req.text)
def allergies(self, message, params=None, **kwargs): """Display current allergies in San Antonio, TX (ex: .allergies).""" url = "http://txallergy.info/api/allergy/today" response = request.get(url) if response.status_code != 200: return text = "Allergies for today: " for a in response.json(): text = text + "%s - %s (%s) | " % (a["allergen"], a["level"], a["count"]) text = text.rstrip(" ") text = text.rstrip("|") message.dispatch(text)
def services(self, message, params=None, **kwargs): """List PagerDuty services (ex: .services).""" url = "%s/services?&include[]=integrations&limit=100" % self.endpoint req = request.get(url, headers=self.api_headers) if request.ok(req): for service in req.json()["services"]: try: integration = service["integrations"][0] integration_key = integration["integration_key"] message.dispatch("%s (%s)" % (service["summary"], integration_key)) except KeyError: continue else: message.dispatch("Unable to fetch services: %d" % req.status_code) message.dispatch(req.text)
def oncall(self, message, params=None, **kwargs): """Show who is on call (ex: .oncall [<group>]).""" url = "%s/api/v1/escalation_policies/on_call" % self.subdomain req = request.get(url, headers=self.api_headers, params={"query": params}) if request.ok(req): response_json = req.json() for policy in response_json["escalation_policies"]: message.dispatch(policy["name"]) for level in policy["on_call"]: message.dispatch("- Level %s: %s <%s>" % ( level["level"], level["user"]["name"], level["user"]["email"])) else: message.dispatch("Unable to fetch list: %d" % req.status_code)
def _find_issue(self, message, issue_id): """Find and display a Redmine issue.""" url = "%s/issues/%s.json" % (self.redmine_url, issue_id) response = request.get(url) if response.status_code != 200: return try: issue = response.json()["issue"] except Exception: return msg = "RM %s #%s: %s [Status: %s, Priority: %s, Assignee: %s]" % ( issue["tracker"]["name"], issue["id"], issue["subject"], issue["status"]["name"], issue["priority"]["name"], issue.get("assigned_to", {}).get("name", "N/A")) url = "https://%s/issues/%s" % (self.redmine_domain, issue["id"]) message.dispatch("%s %s" % (msg, url))
def _find_title(self, message, url): """Find the title of a given URL.""" # NOTE(jk0): Slack does some weird things with URLs. url = url.replace("<", "").replace(">", "").split("|")[0] if not url.startswith(("http://", "https://")): url = "http://" + url try: response = request.get(url) except Exception: return soup = BeautifulSoup(response.content) if soup.head: title = utils.decode_entities(soup.head.title.string) content_type = response.headers.get("Content-Type") message.dispatch("%s (%s)" % (title, content_type)) else: message.dispatch("No title found: %s" % url)
def wikipedia(self, message, params=None, **kwargs): """Search Wikipedia (ex: .wikipedia <query>).""" url = "https://en.wikipedia.org/w/api.php" response = request.get(url, params={ "action": "query", "generator": "allpages", "gaplimit": 4, "gapfrom": params, "format": "json" }) if response.status_code != 200: return pages = response.json()["query"]["pages"] for page in pages.values(): title = page["title"] title = title.replace(" ", "_") message.dispatch("http://en.wikipedia.org/wiki/%s" % title)
def urban(self, message, params=None, **kwargs): """Search Urban Dictionary (ex: .urban <query>).""" url = "http://www.urbandictionary.com/define.php" response = request.get(url, params={"term": params}) if response.status_code != 200: return soup = BeautifulSoup(response.content) try: meaning = soup.find("div", {"class": "meaning"}).text example = soup.find("div", {"class": "example"}).text except AttributeError: message.dispatch("No results found: '%s'" % params) meaning = utils.decode_entities(meaning) example = utils.decode_entities(example) message.dispatch("%s (ex: %s)" % (meaning, example))
def notes(self, message, params=None, **kwargs): """List all notes in current incident.""" number = self.get_incident_number() if number is None: msg = "Could not get incident number for current incident." message.dispatch(msg) return url = "%s/api/v1/incidents/%s/notes" % (self.subdomain, number) req = request.get(url, headers=self.api_headers) if request.ok(req): response_json = req.json() notes = response_json["notes"] message.dispatch("There are %d notes." % len(notes)) for note in notes: message.dispatch("%s %s - %s" % (note["created_at"], note["user"]["name"], note["content"])) else: message.dispatch("Unable to fetch notes: %d" % req.status_code)
def boxoffice(self, message, params=None, **kwargs): """Display top box office movies""" resp = request.get("http://www.rottentomatoes.com") if resp.status_code != 200: message.dispatch("Could not fetch box office results.") return message.dispatch("Top 10 at the Box Office") message.dispatch("=" * 64) soup = BeautifulSoup(resp.text) rows = soup.findAll("table", id="Top-Box-Office")[0].findAll("tr") for row in rows: children = row.findAll("td") try: score = row("span", **{"class": "tMeterScore"})[0].contents[0] title = children[1].find("a").string take = children[2].string.strip() except Exception: pass msg = "%s %s%s" % (score.rjust(3), title.ljust(40), take.rjust(10)) message.dispatch(msg)
def _fetch_xsa_data(self): resp = request.get(self.XSA_URL) if resp.status_code != 200: print "Error fetching XSAs: %s" % resp.status_code return {} soup = BeautifulSoup(resp.text) rows = soup.findAll("tr") data = {} for row in rows: children = row.findChildren("td") if not children: continue try: xsa_id = children[0].contents[0].string except: continue try: xsa_link = "".join( [self.XSA_URL, children[0].contents[0]["href"]]) except: xsa_link = None try: public_release = children[1].contents[0] except: public_release = None try: title = children[5].contents[0] except: title = None data[xsa_id] = { "id": xsa_id, "link": xsa_link, "public_release": public_release, "title": title } return data
def get(self, issue_id): url = "%s/rest/api/latest/issue/%s" % (self.auth_server, issue_id) return request.get(url, verify=False, auth=(self.username, self.password))