remove urwid from contentviews (wip)

This commit is contained in:
Maximilian Hils 2015-09-04 17:07:14 +02:00
parent cc2a6a3919
commit 018c693dee

View File

@ -2,18 +2,18 @@ from __future__ import absolute_import
import cStringIO import cStringIO
import json import json
import logging import logging
import subprocess
import traceback
import lxml.html import lxml.html
import lxml.etree import lxml.etree
from PIL import Image from PIL import Image
from PIL.ExifTags import TAGS from PIL.ExifTags import TAGS
import subprocess
import traceback
import urwid import urwid
import html2text import html2text
import netlib.utils import netlib.utils
from netlib import odict, encoding from netlib import odict, encoding
from . import utils from . import utils
from .contrib import jsbeautifier from .contrib import jsbeautifier
from .contrib.wbxml.ASCommandResponse import ASCommandResponse from .contrib.wbxml.ASCommandResponse import ASCommandResponse
@ -37,16 +37,54 @@ else:
cssutils.ser.prefs.validOnly = False cssutils.ser.prefs.validOnly = False
VIEW_CUTOFF = 1024 * 50 VIEW_CUTOFF = 1024 * 50
KEY_MAX = 30
def format_keyvals(lst, key="key", val="text", indent=0): def format_dict(d):
raise NotImplementedError() """
Transforms the given dictionary into a list of
("key", key )
("value", value)
tuples, where key is padded to a uniform width.
"""
max_key_len = max(len(k) for k in d.keys())
max_key_len = min(max_key_len, KEY_MAX)
for key, value in d.items():
key += ":"
key = key.ljust(max_key_len + 2)
yield (
("key", key),
("value", value)
)
def format_text(content, limit):
"""
Transforms the given content into
"""
content = netlib.utils.cleanBin(content)
for line in content[:limit].splitlines():
yield ("text", line)
for msg in trailer(content, limit):
yield msg
def trailer(content, limit):
bytes_removed = len(content) - limit
if bytes_removed > 0:
yield (
"cutoff",
"... {} of data not shown.".format(netlib.utils.pretty_size(bytes_removed))
)
"""
def _view_text(content, total, limit): def _view_text(content, total, limit):
""" ""
Generates a body for a chunk of text. Generates a body for a chunk of text.
""" ""
txt = [] txt = []
for i in netlib.utils.cleanBin(content).splitlines(): for i in netlib.utils.cleanBin(content).splitlines():
txt.append( txt.append(
@ -69,9 +107,19 @@ def trailer(clen, txt, limit):
] ]
) )
) )
"""
class ViewAuto: class View:
name = None
prompt = ()
content_types = []
def __call__(self, hdrs, content, limit):
raise NotImplementedError()
class ViewAuto(View):
name = "Auto" name = "Auto"
prompt = ("auto", "a") prompt = ("auto", "a")
content_types = [] content_types = []
@ -84,40 +132,40 @@ class ViewAuto:
if ct in content_types_map: if ct in content_types_map:
return content_types_map[ct][0](hdrs, content, limit) return content_types_map[ct][0](hdrs, content, limit)
elif utils.isXML(content): elif utils.isXML(content):
return get("XML")(hdrs, content, limit) return ViewXML(hdrs, content, limit)
return get("Raw")(hdrs, content, limit) return ViewRaw(hdrs, content, limit)
class ViewRaw: class ViewRaw(View):
name = "Raw" name = "Raw"
prompt = ("raw", "r") prompt = ("raw", "r")
content_types = [] content_types = []
def __call__(self, hdrs, content, limit): def __call__(self, hdrs, content, limit):
txt = _view_text(content[:limit], len(content), limit) return "Raw", format_text(content, limit)
return "Raw", txt
class ViewHex: class ViewHex(View):
name = "Hex" name = "Hex"
prompt = ("hex", "e") prompt = ("hex", "e")
content_types = [] content_types = []
def __call__(self, hdrs, content, limit): @staticmethod
txt = [] def _format(content, limit):
for offset, hexa, s in netlib.utils.hexdump(content[:limit]): for offset, hexa, s in netlib.utils.hexdump(content[:limit]):
txt.append(urwid.Text([ yield (
("offset", offset), ("offset", offset + " "),
" ", ("text", hexa + " "),
("text", hexa),
" ",
("text", s), ("text", s),
])) )
trailer(len(content), txt, limit) for msg in trailer(content, limit):
return "Hex", txt yield msg
def __call__(self, hdrs, content, limit):
return "Hex", self._format(content, limit)
class ViewXML: class ViewXML(View):
name = "XML" name = "XML"
prompt = ("xml", "x") prompt = ("xml", "x")
content_types = ["text/xml"] content_types = ["text/xml"]
@ -153,37 +201,20 @@ class ViewXML:
pretty_print=True, pretty_print=True,
xml_declaration=True, xml_declaration=True,
doctype=doctype or None, doctype=doctype or None,
encoding = docinfo.encoding encoding=docinfo.encoding
) )
txt = [] return "XML-like data", format_text(s, limit)
for i in s[:limit].strip().split("\n"):
txt.append(
urwid.Text(("text", i)),
)
trailer(len(content), txt, limit)
return "XML-like data", txt
class ViewJSON: class ViewJSON(View):
name = "JSON" name = "JSON"
prompt = ("json", "s") prompt = ("json", "s")
content_types = ["application/json"] content_types = ["application/json"]
def __call__(self, hdrs, content, limit): def __call__(self, hdrs, content, limit):
lines = utils.pretty_json(content) pretty_json = utils.pretty_json(content)
if lines: return "JSON", format_text(pretty_json, limit)
txt = []
sofar = 0
for i in lines:
sofar += len(i)
txt.append(
urwid.Text(("text", i)),
)
if sofar > limit:
break
trailer(sum(len(i) for i in lines), txt, limit)
return "JSON", txt
class ViewHTML: class ViewHTML:
@ -204,7 +235,7 @@ class ViewHTML:
pretty_print=True, pretty_print=True,
doctype=docinfo.doctype doctype=docinfo.doctype
) )
return "HTML", _view_text(s[:limit], len(s), limit) return "HTML", format_text(s, limit)
class ViewHTMLOutline: class ViewHTMLOutline:
@ -232,8 +263,8 @@ class ViewURLEncoded:
if lines: if lines:
body = format_keyvals( body = format_keyvals(
[(k + ":", v) for (k, v) in lines], [(k + ":", v) for (k, v) in lines],
key = "header", key="header",
val = "text" val="text"
) )
return "URLEncoded form", body return "URLEncoded form", body
@ -251,8 +282,8 @@ class ViewMultipart:
] ]
r.extend(format_keyvals( r.extend(format_keyvals(
v, v,
key = "header", key="header",
val = "text" val="text"
)) ))
return "Multipart form", r return "Multipart form", r
@ -266,6 +297,7 @@ if pyamf:
data = input.readObject() data = input.readObject()
self["data"] = data self["data"] = data
def pyamf_class_loader(s): def pyamf_class_loader(s):
for i in pyamf.CLASS_LOADERS: for i in pyamf.CLASS_LOADERS:
if i != pyamf_class_loader: if i != pyamf_class_loader:
@ -274,8 +306,10 @@ if pyamf:
return v return v
return DummyObject return DummyObject
pyamf.register_class_loader(pyamf_class_loader) pyamf.register_class_loader(pyamf_class_loader)
class ViewAMF: class ViewAMF:
name = "AMF" name = "AMF"
prompt = ("amf", "f") prompt = ("amf", "f")
@ -401,8 +435,8 @@ class ViewImage:
) )
fmt = format_keyvals( fmt = format_keyvals(
clean, clean,
key = "header", key="header",
val = "text" val="text"
) )
return "%s image" % img.format, fmt return "%s image" % img.format, fmt
@ -468,6 +502,7 @@ class ViewWBXML:
except: except:
return None return None
views = [ views = [
ViewAuto(), ViewAuto(),
ViewRaw(), ViewRaw(),
@ -495,7 +530,6 @@ for i in views:
l = content_types_map.setdefault(ct, []) l = content_types_map.setdefault(ct, [])
l.append(i) l.append(i)
view_prompts = [i.prompt for i in views] view_prompts = [i.prompt for i in views]