def start_output(self) -> None: if self.resource: uri = self.resource.request.uri or "" req_headers = self.resource.request.headers else: uri = "" req_headers = [] extra_title = " <span class='save'>" if self.kw.get("is_saved", None): extra_title += " saved " if self.resource and self.resource.check_name != "default": extra_title += "%s response" % e_html(self.resource.check_name) extra_title += "</span>" if self.kw.get("is_blank", None): extra_body_class = "blank" else: extra_body_class = "" if self.kw.get("descend", False): descend = "&descend=True" else: descend = "" self.output( html_header.__doc__ % { "static": self.config["static_root"], "version": __version__, "html_uri": e_html(uri), "js_uri": e_js(uri), "js_req_hdrs": ", ".join([ '["%s", "%s"]' % (e_js(n), e_js(v)) for n, v in req_headers ]), "config": json.dumps( { "redbot_uri": uri, "redbot_req_hdrs": req_headers, "redbot_version": __version__, }, ensure_ascii=True, ).replace("<", "\\u003c"), "extra_js": self.format_extra(".js"), "test_id": self.kw.get("test_id", ""), "extra_title": extra_title, "extra_body_class": extra_body_class, "descend": descend, })
def format_problems(self) -> str: out = ['<br /><h2>Notes</h2><ol>'] for m in self.problems: out.append("""\ <li class='%s %s note' name='msgid-%s'><span>%s</span></li>""" % (m.level.value, e_html(m.subject), id(m), e_html(m.show_summary(self.lang)))) self.hidden_text.append( ("msgid-%s" % id(m), m.show_text(self.lang))) out.append("</ol>\n") return nl.join(out)
def start_output(self) -> None: if self.resource: uri = self.resource.request.uri or "" req_headers = self.resource.request.headers else: uri = "" req_headers = [] extra_title = " <span class='save'>" if self.kw.get('is_saved', None): extra_title += " saved " if self.resource and self.resource.check_name != "default": extra_title += "%s response" % e_html(self.resource.check_name) extra_title += "</span>" if self.kw.get('is_blank', None): extra_body_class = "blank" else: extra_body_class = "" if self.kw.get('descend', False): descend = "&descend=True" else: descend = '' self.output( html_header.__doc__ % { 'static': self.config["static_root"], 'version': __version__, 'html_uri': e_html(uri), 'js_uri': e_js(uri), 'js_req_hdrs': ", ".join([ '["%s", "%s"]' % (e_js(n), e_js(v)) for n, v in req_headers ]), 'config': json.dumps( { 'redbot_uri': uri, 'redbot_req_hdrs': req_headers, 'redbot_version': __version__ }, ensure_ascii=True).replace('<', '\\u003c'), 'extra_js': self.format_extra('.js'), 'test_id': self.kw.get('test_id', ""), 'extra_title': extra_title, 'extra_body_class': extra_body_class, 'descend': descend })
def format_response(self, response: HttpResponse) -> str: "Return the HTTP response line and headers as HTML" offset = 0 headers = [] for (name, value) in response.headers: offset += 1 headers.append(self.format_header(name, value, offset)) return " <span class='status'>HTTP/%s %s %s</span>\n" % ( e_html(response.version), e_html(response.status_code), e_html(response.status_phrase)) + nl.join(headers)
def format_problems(self) -> str: out = ['<br /><h2>Notes</h2><ol>'] for m in self.problems: out.append("""\ <li class='%s %s note' name='msgid-%s'><span>%s</span></li>""" % ( m.level.value, e_html(m.subject), id(m), e_html(m.show_summary(self.lang)))) self.hidden_text.append(("msgid-%s" % id(m), m.show_text(self.lang))) out.append("</ol>\n") return nl.join(out)
def format_response(self, response: HttpResponse) -> str: "Return the HTTP response line and headers as HTML" offset = 0 headers = [] for (name, value) in response.headers: offset += 1 headers.append(self.format_header(name, value, offset)) return " <span class='status'>HTTP/%s %s %s</span>\n" % ( e_html(response.version), e_html(response.status_code), e_html(response.status_phrase)) + nl.join(headers)
def format_header(self, name: str, value: str, offset: int) -> str: "Return an individual HTML header as HTML" token_name = "header-%s" % name.lower() header_desc = HeaderProcessor.find_header_handler(name).description if header_desc and token_name not in [i[0] for i in self.hidden_text]: html_desc = markdown(header_desc % {'field_name': name}, output_format="html5") self.hidden_text.append((token_name, html_desc)) return """\ <span data-offset='%s' data-name='%s' class='hdr'>%s:%s</span>""" % ( offset, e_html(name.lower()), e_html(name), self.header_presenter.Show(name, value))
def format_header(self, name: str, value: str, offset: int) -> str: "Return an individual HTML header as HTML" token_name = "header-%s" % name.lower() header_desc = HeaderProcessor.find_header_handler(name).description if header_desc and token_name not in [i[0] for i in self.hidden_text]: html_desc = markdown(header_desc % {'field_name': name}, output_format="html5") self.hidden_text.append((token_name, html_desc)) return """\ <span data-offset='%s' data-name='%s' class='hdr'>%s:%s</span>""" % ( offset, e_html(name.lower()), e_html(name), self.header_presenter.Show(name, value))
def format_body_sample(self, resource: HttpResource) -> str: """show the stored body sample""" if resource.response.status_code == "206": sample = resource.response.payload else: sample = resource.response.decoded_sample try: uni_sample = sample.decode(resource.response.character_encoding, "ignore") except (TypeError, LookupError): uni_sample = sample.decode('utf-8', 'replace') safe_sample = e_html(uni_sample) message = "" if hasattr(resource, "links"): for tag, link_set in list(resource.links.items()): for link in link_set: try: link = urljoin(resource.response.base_uri, link) except ValueError: pass # we're not interested in raising these upstream def link_to(matchobj: Match) -> str: return r"%s<a href='?%s' class='nocode'>%s</a>%s" % ( matchobj.group(1), self.req_qs(link, use_stored=False), e_html(link), matchobj.group(1)) safe_sample = re.sub(r"('|")%s\1" % re.escape(link), link_to, safe_sample) if not resource.response.decoded_sample_complete: message = "<p class='btw'>REDbot isn't showing the whole body, because it's so big!</p>" return """<pre class="prettyprint">%s</pre>\n%s""" % (safe_sample, message)
def link_to(matchobj: Match) -> str: return r"%s<a href='?%s' class='nocode'>%s</a>%s" % ( matchobj.group(1), self.req_qs(link, use_stored=False), e_html(link), matchobj.group(1), )
def format_body_sample(self, resource: HttpResource) -> str: """show the stored body sample""" if resource.response.status_code == "206": sample = resource.response.payload else: sample = resource.response.decoded_sample try: uni_sample = sample.decode(resource.response.character_encoding, "ignore") except (TypeError, LookupError): uni_sample = sample.decode("utf-8", "replace") safe_sample = e_html(uni_sample) message = "" if hasattr(resource, "links"): for tag, link_set in list(resource.links.items()): for link in link_set: try: link = urljoin(resource.response.base_uri, link) except ValueError: continue # we're not interested in raising these upstream def link_to(matchobj: Match) -> str: return r"%s<a href='?%s' class='nocode'>%s</a>%s" % ( matchobj.group(1), self.req_qs(link, use_stored=False), e_html(link), matchobj.group(1), ) safe_sample = re.sub(r"('|")%s\1" % re.escape(link), link_to, safe_sample) if not resource.response.decoded_sample_complete: message = "<p class='btw'>REDbot isn't showing the whole body, because it's so big!</p>" return """<pre class="prettyprint">%s</pre>\n%s""" % (safe_sample, message)
def format_category(self, category: categories, resource: HttpResource) -> str: """ For a given category, return all of the non-detail notes in it as an HTML list. """ notes = [note for note in resource.notes if note.category == category] if not notes: return nl out = [] # banner, possibly with links to subreqs out.append("<h3>%s\n" % category.value) if isinstance(resource, HttpResource) and category in self.note_responses: for check_name in self.note_responses[category]: if not resource.subreqs[check_name].fetch_started: continue out.append( '<span class="req_link"> (<a href="?%s">%s response</a>' % (self.req_qs(check_name=check_name), check_name)) smsgs = [ note for note in getattr(resource.subreqs[check_name], "notes", []) if note.level in [levels.BAD] and note not in notes ] # notes.extend(smsgs) if len(smsgs) == 1: out.append(" - %i problem\n" % len(smsgs)) elif smsgs: out.append(" - %i problems\n" % len(smsgs)) out.append(")</span>\n") out.append("</h3>\n") out.append("<ul>\n") for note in notes: out.append("""\ <li class='%s note' data-subject='%s' data-name='noteid-%s'> <span>%s</span> </li>""" % ( note.level.value, e_html(note.subject), id(note), e_html(note.show_summary(self.lang)), )) self.hidden_text.append( ("noteid-%s" % id(note), note.show_text(self.lang))) out.append("</ul>\n") return nl.join(out)
def BARE_URI(self, name: str, value: str) -> str: "Present a bare URI header value" value = value.rstrip() svalue = value.lstrip() space = len(value) - len(svalue) return "%s<a href=\"?%s\">%s</a>" % ( " " * space, self.formatter.req_qs( svalue, use_stored=False), self.I(e_html(svalue), len(name)))
def status(self, message: str) -> None: "Update the status bar of the browser" self.output(""" <script> <!-- %3.3f $('#red_status').text("%s"); --> </script> """ % (thor.time() - self.start, e_html(message)))
def show_text(self, lang: str) -> str: """ Show the HTML text for the message as a Unicode string. The resulting string is already HTML-encoded. """ return markdown(self.text % dict( [(k, e_html(str(v))) for k, v in list(self.vars.items())] ), output_format="html5")
def status(self, message: str) -> None: "Update the status bar of the browser" self.output(""" <script> <!-- %3.3f $('#red_status').text("%s"); --> </script> """ % (thor.time() - self.start, e_html(message)))
def BARE_URI(self, name: str, value: str) -> str: "Present a bare URI header value" value = value.rstrip() svalue = value.lstrip() space = len(value) - len(svalue) return "%s<a href=\"?%s\">%s</a>" % ( " " * space, self.formatter.req_qs(svalue, use_stored=False), self.I(e_html(svalue), len(name)))
def Show(self, name: str, value: str) -> str: """ Return the given header name/value pair after presentation processing. """ name = name.lower() name_token = name.replace("-", "_") if name_token[0] != "_" and hasattr(self, name_token): return getattr(self, name_token)(name, value) return self.I(e_html(value), len(name))
def Show(self, name: str, value: str) -> str: """ Return the given header name/value pair after presentation processing. """ name = name.lower() name_token = name.replace('-', '_') if name_token[0] != "_" and hasattr(self, name_token): return getattr(self, name_token)(name, value) return self.I(e_html(value), len(name))
def start_output(self) -> None: if self.resource: uri = self.resource.request.uri or "" req_headers = self.resource.request.headers else: uri = "" req_headers = [] extra_title = " <span class='save'>" if self.kw.get('is_saved', None): extra_title += " saved " if self.resource and self.resource.check_name != "default": extra_title += "%s response" % e_html(self.resource.check_name) extra_title += "</span>" if self.kw.get('is_blank', None): extra_body_class = "blank" else: extra_body_class = "" if self.kw.get('descend', False): descend = "&descend=True" else: descend = '' self.output(html_header.__doc__ % { 'static': self.config["static_root"], 'version': __version__, 'html_uri': e_html(uri), 'js_uri': e_js(uri), 'js_req_hdrs': ", ".join(['["%s", "%s"]' % ( e_js(n), e_js(v)) for n, v in req_headers]), 'config': json.dumps({ 'redbot_uri': uri, 'redbot_req_hdrs': req_headers, 'redbot_version': __version__ }, ensure_ascii=True).replace('<', '\\u003c'), 'extra_js': self.format_extra('.js'), 'test_id': self.kw.get('test_id', ""), 'extra_title': extra_title, 'extra_body_class': extra_body_class, 'descend': descend })
def format_category(self, category: categories, resource: HttpResource) -> str: """ For a given category, return all of the non-detail notes in it as an HTML list. """ notes = [note for note in resource.notes if note.category == category] if not notes: return nl out = [] # banner, possibly with links to subreqs out.append("<h3>%s\n" % category.value) if isinstance(resource, HttpResource) and category in self.note_responses: for check_name in self.note_responses[category]: if not resource.subreqs[check_name].fetch_started: continue out.append('<span class="req_link"> (<a href="?%s">%s response</a>' % \ (self.req_qs(check_name=check_name), check_name)) smsgs = [note for note in getattr(resource.subreqs[check_name], "notes", []) if \ note.level in [levels.BAD] and note not in notes] # notes.extend(smsgs) if len(smsgs) == 1: out.append(" - %i problem\n" % len(smsgs)) elif smsgs: out.append(" - %i problems\n" % len(smsgs)) out.append(')</span>\n') out.append("</h3>\n") out.append("<ul>\n") for note in notes: out.append("""\ <li class='%s note' data-subject='%s' data-name='noteid-%s'> <span>%s</span> </li>""" % ( note.level.value, e_html(note.subject), id(note), e_html(note.show_summary(self.lang)))) self.hidden_text.append(("noteid-%s" % id(note), note.show_text(self.lang))) out.append("</ul>\n") return nl.join(out)
def format_footer(self) -> str: "page footer" return """\ <br /> <div class="footer"> <p class="navigation"> <a href="https://REDbot.org/about/">about</a> | <script type="text/javascript"> document.write('<a href="#help" id="help"><strong>help</strong></a> |') </script> <a href="https://twitter.com/redbotorg"><img class="twitterlogo" src="%(static_root)s/icon/twitter.png"/></a> | <span class="help">Drag the bookmarklet to your bookmark bar - it makes checking easy!</span> <a href="javascript:location%%20=%%20'%(baseuri)s?uri='+encodeURIComponent(location);%%20void%%200" title="drag me to your toolbar to use REDbot any time.">REDbot</a> bookmarklet </p> </div> """ % {'baseuri': e_html(self.config['ui_uri']), 'static_root': self.config["static_root"]}
def format_footer(self) -> str: "page footer" return """\ <br /> <div class="footer"> <p class="navigation"> <a href="https://REDbot.org/about/">about</a> | <script type="text/javascript"> document.write('<a href="#help" id="help"><strong>help</strong></a> |') </script> <a href="https://twitter.com/redbotorg"><img class="twitterlogo" src="%(static_root)s/icon/twitter.png"/></a> | <span class="help">Drag the bookmarklet to your bookmark bar - it makes checking easy!</span> <a href="javascript:location%%20=%%20'%(baseuri)s?uri='+encodeURIComponent(location);%%20void%%200" title="drag me to your toolbar to use REDbot any time.">REDbot</a> bookmarklet </p> </div> """ % { "baseuri": e_html(self.config["ui_uri"]), "static_root": self.config["static_root"], }
def format_droid(self, resource: HttpResource) -> str: out = ['<tr class="droid %s">'] m = 50 ct = resource.response.parsed_headers.get('content-type', [""]) if ct[0][:6] == 'image/': cl = " class='preview'" else: cl = "" if len(resource.request.uri) > m: out.append("""\ <td class="uri"> <a href="%s" title="%s"%s>%s<span class="fade1">%s</span><span class="fade2">%s</span><span class="fade3">%s</span> </a> </td>""" % ( "?%s" % self.req_qs(resource.request.uri, use_stored=False), e_html(resource.request.uri), cl, e_html(resource.request.uri[:m-2]), e_html(resource.request.uri[m-2]), e_html(resource.request.uri[m-1]), e_html(resource.request.uri[m]))) else: out.append( '<td class="uri"><a href="%s" title="%s"%s>%s</a></td>' % ( "?%s" % self.req_qs(resource.request.uri, use_stored=False), e_html(resource.request.uri), cl, e_html(resource.request.uri))) if resource.response.complete: if resource.response.status_code in ['301', '302', '303', '307', '308'] and \ 'location' in resource.response.parsed_headers: out.append( '<td><a href="?descend=True&%s">%s</a></td>' % ( self.req_qs(resource.response.parsed_headers['location'], use_stored=False), resource.response.status_code)) elif resource.response.status_code in ['400', '404', '410']: out.append('<td class="bad">%s</td>' % ( resource.response.status_code)) else: out.append('<td>%s</td>' % resource.response.status_code) # pconn out.append(self.format_size(resource.response.payload_len)) out.append(self.format_yes_no(resource.response.store_shared)) out.append(self.format_yes_no(resource.response.store_private)) out.append(self.format_time(resource.response.age)) out.append(self.format_time(resource.response.freshness_lifetime)) out.append(self.format_yes_no(resource.ims_support)) out.append(self.format_yes_no(resource.inm_support)) if resource.gzip_support: out.append("<td>%s%%</td>" % resource.gzip_savings) else: out.append(self.format_yes_no(resource.gzip_support)) out.append(self.format_yes_no(resource.partial_support)) problems = [m for m in resource.notes if m.level in [levels.WARN, levels.BAD]] out.append("<td>") pr_enum = [] # type: List[int] for problem in problems: if problem not in self.problems: self.problems.append(problem) pr_enum.append(self.problems.index(problem)) # add the problem number to the <tr> so we can highlight out[0] = out[0] % " ".join(["%d" % p for p in pr_enum]) # append the actual problem numbers to the final <td> for p in pr_enum: n = self.problems[p] out.append("<span class='prob_num'>" \ " %s <span class='hidden'>%s</span></span>" % ( p + 1, e_html(n.show_summary(self.lang)))) else: if resource.response.http_error is None: err = "response incomplete" else: err = resource.response.http_error.desc or 'unknown problem' out.append('<td colspan="11">%s' % err) out.append("</td>") out.append('</tr>') return nl.join(out)
def link_to(matchobj: Match) -> str: return r"%s<a href='?%s' class='nocode'>%s</a>%s" % ( matchobj.group(1), self.req_qs(link, use_stored=False), e_html(link), matchobj.group(1))
def format_droid(self, resource: HttpResource) -> str: out = ['<tr class="droid %s">'] m = 50 ct = resource.response.parsed_headers.get("content-type", [""]) if ct[0][:6] == "image/": cl = " class='preview'" else: cl = "" if len(resource.request.uri) > m: out.append("""\ <td class="uri"> <a href="%s" title="%s"%s>%s<span class="fade1">%s</span><span class="fade2">%s</span><span class="fade3">%s</span> </a> </td>""" % ( "?%s" % self.req_qs(resource.request.uri, use_stored=False), e_html(resource.request.uri), cl, e_html(resource.request.uri[:m - 2]), e_html(resource.request.uri[m - 2]), e_html(resource.request.uri[m - 1]), e_html(resource.request.uri[m]), )) else: out.append( '<td class="uri"><a href="%s" title="%s"%s>%s</a></td>' % ( "?%s" % self.req_qs(resource.request.uri, use_stored=False), e_html(resource.request.uri), cl, e_html(resource.request.uri), )) if resource.response.complete: if (resource.response.status_code in ["301", "302", "303", "307", "308"] and "location" in resource.response.parsed_headers): out.append('<td><a href="?descend=True&%s">%s</a></td>' % ( self.req_qs( resource.response.parsed_headers["location"], use_stored=False, ), resource.response.status_code, )) elif resource.response.status_code in ["400", "404", "410"]: out.append('<td class="bad">%s</td>' % (resource.response.status_code)) else: out.append("<td>%s</td>" % resource.response.status_code) # pconn out.append(self.format_size(resource.response.payload_len)) out.append(self.format_yes_no(resource.response.store_shared)) out.append(self.format_yes_no(resource.response.store_private)) out.append(self.format_time(resource.response.age)) out.append(self.format_time(resource.response.freshness_lifetime)) out.append(self.format_yes_no(resource.ims_support)) out.append(self.format_yes_no(resource.inm_support)) if resource.gzip_support: out.append("<td>%s%%</td>" % resource.gzip_savings) else: out.append(self.format_yes_no(resource.gzip_support)) out.append(self.format_yes_no(resource.partial_support)) problems = [ m for m in resource.notes if m.level in [levels.WARN, levels.BAD] ] out.append("<td>") pr_enum = [] # type: List[int] for problem in problems: if problem not in self.problems: self.problems.append(problem) pr_enum.append(self.problems.index(problem)) # add the problem number to the <tr> so we can highlight out[0] = out[0] % " ".join(["%d" % p for p in pr_enum]) # append the actual problem numbers to the final <td> for p in pr_enum: n = self.problems[p] out.append("<span class='prob_num'>" " %s <span class='hidden'>%s</span></span>" % (p + 1, e_html(n.show_summary(self.lang)))) else: if resource.response.http_error is None: err = "response incomplete" else: err = resource.response.http_error.desc or "unknown problem" out.append('<td colspan="11">%s' % err) out.append("</td>") out.append("</tr>") return nl.join(out)