Rework status content wrapping
This commit is contained in:
parent
f816c6adfe
commit
47b6a830a1
58
toot/app.py
58
toot/app.py
|
@ -3,12 +3,12 @@ from __future__ import unicode_literals
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
import curses
|
import curses
|
||||||
import re
|
|
||||||
import webbrowser
|
import webbrowser
|
||||||
|
|
||||||
from bs4 import BeautifulSoup
|
|
||||||
from textwrap import wrap
|
from textwrap import wrap
|
||||||
|
|
||||||
|
from toot.utils import format_content
|
||||||
|
|
||||||
|
|
||||||
class Color:
|
class Color:
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -167,14 +167,13 @@ class TimelineApp:
|
||||||
window.addstr(offset + 2, 2, date, color)
|
window.addstr(offset + 2, 2, date, color)
|
||||||
window.addstr(offset + 3, 2, time, color)
|
window.addstr(offset + 3, 2, time, color)
|
||||||
|
|
||||||
window.addstr(offset + 2, 15, status['author']['acct'], color)
|
window.addstr(offset + 2, 15, status['account']['acct'], color)
|
||||||
window.addstr(offset + 3, 15, status['author']['display_name'], color)
|
window.addstr(offset + 3, 15, status['account']['display_name'], color)
|
||||||
|
|
||||||
window.addstr(offset + 4, 1, '─' * (width - 2))
|
window.addstr(offset + 4, 1, '─' * (width - 2))
|
||||||
|
|
||||||
window.refresh(0, 0, 2, 0, curses.LINES - 4, self.left_width)
|
window.refresh(0, 0, 2, 0, curses.LINES - 4, self.left_width)
|
||||||
|
|
||||||
|
|
||||||
def draw_statuses(self, window):
|
def draw_statuses(self, window):
|
||||||
for index, status in enumerate(self.statuses):
|
for index, status in enumerate(self.statuses):
|
||||||
offset = 3 * index - 1
|
offset = 3 * index - 1
|
||||||
|
@ -185,22 +184,30 @@ class TimelineApp:
|
||||||
window.erase()
|
window.erase()
|
||||||
window.box()
|
window.box()
|
||||||
|
|
||||||
acct = status['author']['acct']
|
acct = status['account']['acct']
|
||||||
name = status['author']['display_name']
|
name = status['account']['display_name']
|
||||||
|
|
||||||
window.addstr(1, 2, "@" + acct, Color.green())
|
window.addstr(1, 2, "@" + acct, Color.green())
|
||||||
window.addstr(2, 2, name, Color.yellow())
|
window.addstr(2, 2, name, Color.yellow())
|
||||||
|
|
||||||
|
y = 4
|
||||||
text_width = self.right_width - 4
|
text_width = self.right_width - 4
|
||||||
|
|
||||||
y = 4
|
|
||||||
for line in status['lines']:
|
for line in status['lines']:
|
||||||
for wrapped in wrap(line, text_width):
|
wrapped_lines = wrap(line, text_width) if line else ['']
|
||||||
window.addstr(y, 2, wrapped.ljust(text_width))
|
for wrapped_line in wrapped_lines:
|
||||||
y += 1
|
window.addstr(y, 2, wrapped_line.ljust(text_width))
|
||||||
y += 1
|
y = y + 1
|
||||||
|
|
||||||
window.addstr(y, 2, '─' * text_width)
|
if status['media_attachments']:
|
||||||
|
y += 1
|
||||||
|
for attachment in status['media_attachments']:
|
||||||
|
url = attachment['text_url'] or attachment['url']
|
||||||
|
for line in wrap(url, text_width):
|
||||||
|
window.addstr(y, 2, line)
|
||||||
|
y += 1
|
||||||
|
|
||||||
|
window.addstr(y, 1, '-' * (text_width + 2))
|
||||||
y += 1
|
y += 1
|
||||||
|
|
||||||
window.addstr(y, 2, status['url'])
|
window.addstr(y, 2, status['url'])
|
||||||
|
@ -217,20 +224,20 @@ class TimelineApp:
|
||||||
|
|
||||||
|
|
||||||
def parse_status(status):
|
def parse_status(status):
|
||||||
content = status['reblog']['content'] if status['reblog'] else status['content']
|
_status = status.get('reblog') or status
|
||||||
account = parse_account(status['reblog']['account'] if status['reblog'] else status['account'])
|
account = parse_account(_status['account'])
|
||||||
boosted_by = parse_account(status['account']) if status['reblog'] else None
|
lines = list(format_content(_status['content']))
|
||||||
|
|
||||||
lines = parse_html(content)
|
|
||||||
|
|
||||||
created_at = status['created_at'][:19].split('T')
|
created_at = status['created_at'][:19].split('T')
|
||||||
|
boosted_by = parse_account(status['account']) if status['reblog'] else None
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'author': account,
|
'account': account,
|
||||||
'boosted_by': boosted_by,
|
'boosted_by': boosted_by,
|
||||||
'lines': lines,
|
|
||||||
'url': status['url'],
|
|
||||||
'created_at': created_at,
|
'created_at': created_at,
|
||||||
|
'lines': lines,
|
||||||
|
'media_attachments': _status['media_attachments'],
|
||||||
|
'url': status['url'],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -240,12 +247,3 @@ def parse_account(account):
|
||||||
'acct': account['acct'],
|
'acct': account['acct'],
|
||||||
'display_name': account['display_name'],
|
'display_name': account['display_name'],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def parse_html(html):
|
|
||||||
"""Attempt to convert html to plain text while keeping line breaks"""
|
|
||||||
return [
|
|
||||||
BeautifulSoup(l, "html.parser").get_text().replace(''', "'")
|
|
||||||
for l in re.split("</?p[^>]*>", html)
|
|
||||||
if l
|
|
||||||
]
|
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
|
import re
|
||||||
|
|
||||||
|
from bs4 import BeautifulSoup
|
||||||
|
|
||||||
|
|
||||||
|
def get_text(html):
|
||||||
|
"""Converts html to text, strips all tags."""
|
||||||
|
return BeautifulSoup(html, "html.parser").get_text().replace(''', "'")
|
||||||
|
|
||||||
|
|
||||||
|
def parse_html(html):
|
||||||
|
"""Attempt to convert html to plain text while keeping line breaks.
|
||||||
|
Returns a list of paragraphs, each being a list of lines.
|
||||||
|
"""
|
||||||
|
paragraphs = re.split("</?p[^>]*>", html)
|
||||||
|
|
||||||
|
# Convert <br>s to line breaks and remove empty paragraphs
|
||||||
|
paragraphs = [re.split("<br */?>", p) for p in paragraphs if p]
|
||||||
|
|
||||||
|
# Convert each line in each paragraph to plain text:
|
||||||
|
return [[get_text(l) for l in p] for p in paragraphs]
|
||||||
|
|
||||||
|
|
||||||
|
def format_content(content):
|
||||||
|
"""Given a Status contents in HTML, converts it into lines of plain text.
|
||||||
|
|
||||||
|
Returns a generator yielding lines of content.
|
||||||
|
"""
|
||||||
|
|
||||||
|
paragraphs = parse_html(content)
|
||||||
|
|
||||||
|
first = True
|
||||||
|
|
||||||
|
for paragraph in paragraphs:
|
||||||
|
if not first:
|
||||||
|
yield ""
|
||||||
|
|
||||||
|
for line in paragraph:
|
||||||
|
yield line
|
||||||
|
|
||||||
|
first = False
|
Loading…
Reference in New Issue