Rework status content wrapping

This commit is contained in:
Ivan Habunek 2017-04-24 16:25:34 +02:00
parent f816c6adfe
commit 47b6a830a1
No known key found for this signature in database
GPG Key ID: CDBD63C43A30BB95
2 changed files with 73 additions and 30 deletions

View File

@ -3,12 +3,12 @@ from __future__ import unicode_literals
from __future__ import print_function
import curses
import re
import webbrowser
from bs4 import BeautifulSoup
from textwrap import wrap
from toot.utils import format_content
class Color:
@staticmethod
@ -167,14 +167,13 @@ class TimelineApp:
window.addstr(offset + 2, 2, date, color)
window.addstr(offset + 3, 2, time, color)
window.addstr(offset + 2, 15, status['author']['acct'], color)
window.addstr(offset + 3, 15, status['author']['display_name'], color)
window.addstr(offset + 2, 15, status['account']['acct'], color)
window.addstr(offset + 3, 15, status['account']['display_name'], color)
window.addstr(offset + 4, 1, '' * (width - 2))
window.refresh(0, 0, 2, 0, curses.LINES - 4, self.left_width)
def draw_statuses(self, window):
for index, status in enumerate(self.statuses):
offset = 3 * index - 1
@ -185,22 +184,30 @@ class TimelineApp:
window.erase()
window.box()
acct = status['author']['acct']
name = status['author']['display_name']
acct = status['account']['acct']
name = status['account']['display_name']
window.addstr(1, 2, "@" + acct, Color.green())
window.addstr(2, 2, name, Color.yellow())
y = 4
text_width = self.right_width - 4
y = 4
for line in status['lines']:
for wrapped in wrap(line, text_width):
window.addstr(y, 2, wrapped.ljust(text_width))
y += 1
y += 1
wrapped_lines = wrap(line, text_width) if line else ['']
for wrapped_line in wrapped_lines:
window.addstr(y, 2, wrapped_line.ljust(text_width))
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
window.addstr(y, 2, status['url'])
@ -217,20 +224,20 @@ class TimelineApp:
def parse_status(status):
content = status['reblog']['content'] if status['reblog'] else status['content']
account = parse_account(status['reblog']['account'] if status['reblog'] else status['account'])
boosted_by = parse_account(status['account']) if status['reblog'] else None
lines = parse_html(content)
_status = status.get('reblog') or status
account = parse_account(_status['account'])
lines = list(format_content(_status['content']))
created_at = status['created_at'][:19].split('T')
boosted_by = parse_account(status['account']) if status['reblog'] else None
return {
'author': account,
'account': account,
'boosted_by': boosted_by,
'lines': lines,
'url': status['url'],
'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'],
'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
]

45
toot/utils.py Normal file
View File

@ -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('&apos;', "'")
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