def get_github_status(url="https://status.github.com/api/status.json"): # github's status API is cool -- you can get an enumeration of endpoints from: https://status.github.com/api.json # what status/messages are mapped from https://status.github.com/api/messages.json r = http_requests_get_to_dict(url) _resp = {"response": dict(), "headers": dict(), "status": "ok"} _filtered_headers = { "date": r.headers.get("date", ""), "etag": r.headers.get("etag", ""), "status_code": r.headers.get("status_code", 200) } _resp["headers"] = _filtered_headers if not r.error and r.http_2xx: _rjson = loads(r.text) status_string = _rjson.get("status", "").strip() _resp["response"] = status_string if status_string != "good": _resp["status"] = "nok" else: _resp["status"] = "nok" return _resp
def get_github_status(url="https://status.github.com/api/status.json"): # github's status API is cool -- you can get an enumeration of endpoints from: https://status.github.com/api.json # what status/messages are mapped from https://status.github.com/api/messages.json r = http_requests_get_to_dict(url) _resp = { "response": dict(), "headers": dict(), "status": "ok" } _filtered_headers = { "date": r.headers.get("date", ""), "etag": r.headers.get("etag", ""), "status_code": r.headers.get("status_code", 200) } _resp["headers"] = _filtered_headers if not r.error and r.http_2xx: _rjson = loads(r.text) status_string = _rjson.get("status", "").strip() _resp["response"] = status_string if status_string != "good": _resp["status"] = "nok" else: _resp["status"] = "nok" return _resp
def get_constantcontact_status(url="https://status.constantcontact.com/"): # constant contact returns a 403 forbidden when missing headers headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:39.0) Gecko/20100101 Firefox/39.0'} r = http_requests_get_to_dict(url, headers=headers) _resp = { "response": dict(), "headers": dict(), "status": "ok" } _filtered_headers = { "date": r.headers.get("date", ""), "status_code": r.headers.get("status_code", 200) } _resp["headers"] = _filtered_headers # sendgrid uses nested service statuses _resp["response"]["services"] = dict() # not really into this as a list, but will adjust as needed _resp["response"]["outages"] = [] if not r.error and r.http_2xx: _rtxml = html_string(r.text) _body = _rtxml.xpath("//html/body")[0] _content_row = _body.xpath("section[@id='status-content']/article/section[@class='entry-content']/section[@class='row']/main/table[contains(@class, 'table')]") _tbody_rows = _content_row[0].xpath("tbody/tr") _serv_status = {} for _service_row in _tbody_rows: _service_row_td_collection = _service_row.xpath("td") _service_name = _service_row_td_collection[0].text.strip() _service_status = _service_row_td_collection[2].text.strip() if _service_status == "All Systems are Available and Operating Normally": _service_status = "ok" else: _resp["response"]["outages"].append(_service_name) _serv_status[_service_name] = _service_status _resp["response"]["services"] = _serv_status else: _resp["status"] = "nok" return _resp
def get_facebook_status(url="https://www.facebook.com/feeds/api_status.php"): # use the status API https://www.facebook.com/feeds/api_status.php # if the status api is unavailable, look at the page source to pull out the status # be careful not to look post-JS rendering as the DOM is populated from a hidden <code> element r = http_requests_get_to_dict(url) _resp = { "response": dict(), "headers": dict(), "status": "ok" } _filtered_headers = { "date": r.headers.get("date", ""), "expires": r.headers.get("expires", ""), "last-modified": r.headers.get("last-modified", ""), "etag": r.headers.get("etag", ""), "status_code": r.headers.get("status_code", 200), "x-fb-debug": r.headers.get("x-fb-debug", ""), "pragma": r.headers.get("pragma", ""), } _resp["headers"] = _filtered_headers # not really into this as a list, but will adjust as needed _resp["response"]["outages"] = [] _stat_str = '' _stat_int = 0 if not r.error and r.http_2xx: _rjson = loads(r.text) _curr = _rjson.get("current", "") if _curr: _stat_int = _curr.get("health", 0) _stat_str = _curr.get("subject", "").strip() if _stat_str: _resp["response"] = _stat_str # get status info or default to the first one if _stat_int: _resp["status"] = STATUS.get(_stat_int, STATUS[0]) else: _resp["status"] = "nok" return _resp
def get_sendgrid_status(url="http://status.sendgrid.com"): r = http_requests_get_to_dict(url) _resp = {"response": dict(), "headers": dict(), "status": "ok"} _filtered_headers = { "date": r.headers.get("date", ""), "last-modified": r.headers.get("last-modified", ""), "etag": r.headers.get("etag", ""), "x-request-id": r.headers.get("x-request-id", ""), "x-statuspage-version": r.headers.get("x-statuspage-version", ""), "status_code": r.headers.get("status_code", 200) } _resp["headers"] = _filtered_headers # sendgrid uses nested service statuses _resp["response"]["services"] = dict() # not really into this as a list, but will adjust as needed _resp["response"]["outages"] = [] general_page_status_text = '' if not r.error and r.http_2xx: _rtxml = html_string(r.text) _body = _rtxml.xpath("//html/body")[0] _content_div = _body.xpath( "div[contains(@class, 'layout-content')]/div[@class='container']" )[0] # page structure changes when sendgrid is in an outage general_page_status = _content_div.xpath( "div[contains(@class, 'page-status')]/span[contains(@class, 'status')]" ) ongoing_incident_div = _content_div.xpath( "div[contains(@class, 'unresolved-incidents')]") if len(ongoing_incident_div) > 0: for _incident in ongoing_incident_div: _incident_title_div = _incident.xpath( "div[contains(@class, 'unresolved-incident')]/div[contains(@class, 'incident-title')]" ) _incident_text = _incident_title_div[0].xpath( "a[contains(@class, 'actual-title')]")[0].text.strip() _resp["response"]["outages"].append(_incident_text) if len(general_page_status) > 0: general_page_status_text = general_page_status[0].text.strip() if general_page_status_text == 'All Systems Operational': _resp["status"] = "ok" else: _resp["status"] = "nok" # sengrid does a .components-section .components-container, then N- .component-container (note singular) by_service_status_divs = _content_div.xpath( "div[contains(@class, 'components-section')]/div[contains(@class, 'components-container')]/div[contains(@class, 'component-container')]" ) _serv_status = {} for _service in by_service_status_divs: # we have to look into child-components container that is at the same level, e.g. # <div class="component-container"> # <div class="component-inner-container"> # <div class="child-components-container"> -> div.component-inner-container -> [span.name, span.component-status] # # if not, it's simply: # <div class="component-container"> # <div class="component-inner-container"> -> [span.name, span.component-status] _child_components_container = _service.xpath( "div[contains(@class, 'child-components-container')]") # if we have a child container, move our inspection to the scope of that div. otherwise, leave # at the top level for depth searching if len(_child_components_container) > 0: # step back to iter point, get name of the service header and make it into a dict for subitem statuses _service_name = _service.xpath( "div[contains(@class, 'component-inner-container')]/span[contains(@class, 'name')]/span" )[1].text.strip() _resp["response"]["services"][_service_name] = dict() # move our "cursor" to the child components container for searching _cursor = _child_components_container else: # we do not have a child components containiner, so keep the cursor at the loop iter point. _cursor = _service _service_component_containers = _cursor[0].xpath( "div[contains(@class, 'component-inner-container')]") for _service_status in _service_component_containers: _name = _service_status.xpath( "span[@class='name']")[0].text.strip() _status = _service_status.xpath( "span[@class='component-status']")[0].text.strip() if _status == "Operational": _status = "ok" _serv_status[_name] = _status _resp["response"]["services"] = _serv_status else: _resp["status"] = "nok" return _resp
def get_sendgrid_status(url="http://status.sendgrid.com"): r = http_requests_get_to_dict(url) _resp = { "response": dict(), "headers": dict(), "status": "ok" } _filtered_headers = { "date": r.headers.get("date", ""), "last-modified": r.headers.get("last-modified", ""), "etag": r.headers.get("etag", ""), "x-request-id": r.headers.get("x-request-id", ""), "x-statuspage-version": r.headers.get("x-statuspage-version", ""), "status_code": r.headers.get("status_code", 200) } _resp["headers"] = _filtered_headers # sendgrid uses nested service statuses _resp["response"]["services"] = dict() # not really into this as a list, but will adjust as needed _resp["response"]["outages"] = [] general_page_status_text = '' if not r.error and r.http_2xx: _rtxml = html_string(r.text) _body = _rtxml.xpath("//html/body")[0] _content_div = _body.xpath("div[contains(@class, 'layout-content')]/div[@class='container']")[0] # page structure changes when sendgrid is in an outage general_page_status = _content_div.xpath("div[contains(@class, 'page-status')]/span[contains(@class, 'status')]") ongoing_incident_div = _content_div.xpath("div[contains(@class, 'unresolved-incidents')]") if len(ongoing_incident_div) > 0: for _incident in ongoing_incident_div: _incident_title_div = _incident.xpath("div[contains(@class, 'unresolved-incident')]/div[contains(@class, 'incident-title')]") _incident_text = _incident_title_div[0].xpath("a[contains(@class, 'actual-title')]")[0].text.strip() _resp["response"]["outages"].append(_incident_text) if len(general_page_status) > 0: general_page_status_text = general_page_status[0].text.strip() if general_page_status_text == 'All Systems Operational': _resp["status"] = "ok" else: _resp["status"] = "nok" # sengrid does a .components-section .components-container, then N- .component-container (note singular) by_service_status_divs = _content_div.xpath("div[contains(@class, 'components-section')]/div[contains(@class, 'components-container')]/div[contains(@class, 'component-container')]") _serv_status = {} for _service in by_service_status_divs: # we have to look into child-components container that is at the same level, e.g. # <div class="component-container"> # <div class="component-inner-container"> # <div class="child-components-container"> -> div.component-inner-container -> [span.name, span.component-status] # # if not, it's simply: # <div class="component-container"> # <div class="component-inner-container"> -> [span.name, span.component-status] _child_components_container = _service.xpath("div[contains(@class, 'child-components-container')]") # if we have a child container, move our inspection to the scope of that div. otherwise, leave # at the top level for depth searching if len(_child_components_container) > 0: # step back to iter point, get name of the service header and make it into a dict for subitem statuses _service_name = _service.xpath("div[contains(@class, 'component-inner-container')]/span[contains(@class, 'name')]/span")[1].text.strip() _resp["response"]["services"][_service_name] = dict() # move our "cursor" to the child components container for searching _cursor = _child_components_container else: # we do not have a child components containiner, so keep the cursor at the loop iter point. _cursor = _service _service_component_containers = _cursor[0].xpath("div[contains(@class, 'component-inner-container')]") for _service_status in _service_component_containers: _name = _service_status.xpath("span[@class='name']")[0].text.strip() _status = _service_status.xpath("span[@class='component-status']")[0].text.strip() if _status == "Operational": _status = "ok" _serv_status[_name] = _status _resp["response"]["services"] = _serv_status else: _resp["status"] = "nok" return _resp
def get_cloudinary_status(url="http://status.cloudinary.com"): # this is only history -- no "we're fine right now" or enumeration of things that are working. # http://status.cloudinary.com/history.rss # also, as of this writing, there is no standard way to determine the end boundary of an outage, which # makes this generally useless for our purposes. r = http_requests_get_to_dict(url) # response dict - response is data blob to return (e.g. 'Site is normal!'), headers are headers, status is ok/nok _resp = { "response": dict(), "headers": dict(), "status": "ok" } _filtered_headers = { "date": r.headers.get("date", ""), "etag": r.headers.get("etag", ""), "status_code": r.headers.get("status_code", 200) } _resp["headers"] = _filtered_headers if not r.error and r.http_2xx: _rtxml = html_string(r.text) _body = _rtxml.xpath("//html/body")[0] _content_div = _body.xpath("div[contains(@class, 'layout-content')]/div[@class='container']")[0] general_page_status_raw_text = _content_div.xpath("div[contains(@class, 'page-status')]/span[contains(@class, 'status')]")[0].text general_page_status = general_page_status_raw_text.strip() by_service_status_divs = _content_div.xpath("div[contains(@class, 'components-section')]/div[contains(@class, 'components-container')]")[0] _serv_status = {} for _service in by_service_status_divs: _inner_div_group = _service.xpath("div[contains(@class, 'component-inner-container')]") if _inner_div_group: _inner_div_group = _inner_div_group[0] _name = _inner_div_group.xpath("span[@class='name']")[0].text.strip() _status = _inner_div_group.xpath("span[@class='component-status']")[0].text.strip() if _status == "Operational": _status = "ok" else: # statuspage.io nested group? # _service_div_contents = str(_service) _status = "There was an error parsing a response: %s : %s" % (str(_service), _inner_div_group) _serv_status[_name] = _status _resp["response"]["services"] = _serv_status if general_page_status == 'All Systems Operational': _resp["status"] = "ok" else: _resp["status"] = "nok" return _resp
def get_cloudinary_status(url="http://status.cloudinary.com"): # this is only history -- no "we're fine right now" or enumeration of things that are working. # http://status.cloudinary.com/history.rss # also, as of this writing, there is no standard way to determine the end boundary of an outage, which # makes this generally useless for our purposes. r = http_requests_get_to_dict(url) # response dict - response is data blob to return (e.g. 'Site is normal!'), headers are headers, status is ok/nok _resp = {"response": dict(), "headers": dict(), "status": "ok"} _filtered_headers = { "date": r.headers.get("date", ""), "etag": r.headers.get("etag", ""), "status_code": r.headers.get("status_code", 200) } _resp["headers"] = _filtered_headers if not r.error and r.http_2xx: _rtxml = html_string(r.text) _body = _rtxml.xpath("//html/body")[0] _content_div = _body.xpath( "div[contains(@class, 'layout-content')]/div[@class='container']" )[0] general_page_status_raw_text = _content_div.xpath( "div[contains(@class, 'page-status')]/span[contains(@class, 'status')]" )[0].text general_page_status = general_page_status_raw_text.strip() by_service_status_divs = _content_div.xpath( "div[contains(@class, 'components-section')]/div[contains(@class, 'components-container')]" )[0] _serv_status = {} for _service in by_service_status_divs: _inner_div_group = _service.xpath( "div[contains(@class, 'component-inner-container')]") if _inner_div_group: _inner_div_group = _inner_div_group[0] _name = _inner_div_group.xpath( "span[@class='name']")[0].text.strip() _status = _inner_div_group.xpath( "span[@class='component-status']")[0].text.strip() if _status == "Operational": _status = "ok" else: # statuspage.io nested group? # _service_div_contents = str(_service) _status = "There was an error parsing a response: %s : %s" % ( str(_service), _inner_div_group) _serv_status[_name] = _status _resp["response"]["services"] = _serv_status if general_page_status == 'All Systems Operational': _resp["status"] = "ok" else: _resp["status"] = "nok" return _resp