Simplify access to reblogged status data

Adds two properties to `Status` entity:
* `reblog` - contains the reblogged Status or None if not a reblog
* `original`- contains the reblogged Status or self if not a reblog

Anywhere where you wish to show a reblogged status's property when it's
a reblog, or the base status proprety if not a reblog, use
`status.original.<property>`.
pull/132/head
Ivan Habunek 2019-09-22 12:13:40 +02:00
rodzic bc6e43376a
commit 35e03a13b1
3 zmienionych plików z 75 dodań i 35 usunięć

Wyświetl plik

@ -226,7 +226,7 @@ class TUI(urwid.Frame):
# This is pretty fast, so it's probably ok to block while context is # This is pretty fast, so it's probably ok to block while context is
# loaded, can be made async later if needed # loaded, can be made async later if needed
context = api.context(self.app, self.user, status.id) context = api.context(self.app, self.user, status.original.id)
ancestors = [self.make_status(s) for s in context["ancestors"]] ancestors = [self.make_status(s) for s in context["ancestors"]]
descendants = [self.make_status(s) for s in context["descendants"]] descendants = [self.make_status(s) for s in context["descendants"]]
statuses = ancestors + [status] + descendants statuses = ancestors + [status] + descendants
@ -337,7 +337,7 @@ class TUI(urwid.Frame):
promise.add_done_callback(lambda *args: self.close_overlay()) promise.add_done_callback(lambda *args: self.close_overlay())
def show_media(self, status): def show_media(self, status):
urls = [m["url"] for m in status.data["media_attachments"]] urls = [m["url"] for m in status.original.data["media_attachments"]]
if urls: if urls:
show_media(urls) show_media(urls)

Wyświetl plik

@ -2,7 +2,6 @@ from collections import namedtuple
from .utils import parse_datetime from .utils import parse_datetime
Author = namedtuple("Author", ["account", "display_name"]) Author = namedtuple("Author", ["account", "display_name"])
@ -11,8 +10,33 @@ class Status:
A wrapper around the Status entity data fetched from Mastodon. A wrapper around the Status entity data fetched from Mastodon.
https://github.com/tootsuite/documentation/blob/master/Using-the-API/API.md#status https://github.com/tootsuite/documentation/blob/master/Using-the-API/API.md#status
Attributes
----------
reblog : Status or None
The reblogged status if it exists.
original : Status
If a reblog, the reblogged status, otherwise self.
""" """
def __init__(self, data, is_mine, default_instance): def __init__(self, data, is_mine, default_instance):
"""
Parameters
----------
data : dict
Status data as received from Mastodon.
https://docs.joinmastodon.org/api/entities/#status
is_mine : bool
Whether the status was created by the logged in user.
default_instance : str
The domain of the instance into which the user is logged in. Used to
create fully qualified account names for users on the same instance.
Mastodon only populates the name, not the domain.
"""
self.data = data self.data = data
self.is_mine = is_mine self.is_mine = is_mine
self.default_instance = default_instance self.default_instance = default_instance
@ -20,34 +44,40 @@ class Status:
# This can be toggled by the user # This can be toggled by the user
self.show_sensitive = False self.show_sensitive = False
# TODO: make Status immutable? # TODO: clean up
self.id = self.data["id"] self.id = self.data["id"]
self.display_name = self.data["account"]["display_name"] self.account = self._get_account()
self.account = self.get_account()
self.created_at = parse_datetime(data["created_at"]) self.created_at = parse_datetime(data["created_at"])
self.author = self.get_author() self.author = self._get_author()
self.favourited = data.get("favourited", False) self.favourited = data.get("favourited", False)
self.reblogged = data.get("reblogged", False) self.reblogged = data.get("reblogged", False)
self.in_reply_to = data.get("in_reply_to_id") self.in_reply_to = data.get("in_reply_to_id")
self.url = data.get("url")
self.mentions = data.get("mentions")
self.reblog = self._get_reblog()
self.reblog = reblog = data.get("reblog") @property
self.url = reblog.get("url") if reblog else data.get("url") def original(self):
return self.reblog or self
self.mentions = data["mentions"] def _get_reblog(self):
def get_author(self):
# Show the author, not the persopn who reblogged
data = self.data["reblog"] or self.data
acct = data['account']['acct']
acct = acct if "@" in acct else "{}@{}".format(acct, self.default_instance)
return Author(acct, data['account']['display_name'])
def get_account(self):
reblog = self.data.get("reblog") reblog = self.data.get("reblog")
account = reblog['account'] if reblog else self.data['account'] if not reblog:
acct = account['acct'] return None
reblog_is_mine = self.is_mine and (
self.data["account"]["acct"] == reblog["account"]["acct"]
)
return Status(reblog, reblog_is_mine, self.default_instance)
def _get_author(self):
acct = self.data['account']['acct']
acct = acct if "@" in acct else "{}@{}".format(acct, self.default_instance)
return Author(acct, self.data['account']['display_name'])
def _get_account(self):
acct = self.data['account']['acct']
return acct if "@" in acct else "{}@{}".format(acct, self.default_instance) return acct if "@" in acct else "{}@{}".format(acct, self.default_instance)
def __repr__(self): def __repr__(self):
return "<Status id={}>".format(self.id) return "<Status id={} account={}>".format(self.id, self.account)

Wyświetl plik

@ -136,7 +136,7 @@ class Timeline(urwid.Columns):
return return
if key in ("s", "S"): if key in ("s", "S"):
status.show_sensitive = True status.original.show_sensitive = True
self.refresh_status_details() self.refresh_status_details()
return return
@ -149,8 +149,8 @@ class Timeline(urwid.Columns):
return return
if key in ("v", "V"): if key in ("v", "V"):
if status.url: if status.original.url:
webbrowser.open(status.url) webbrowser.open(status.original.url)
return return
return super().keypress(size, key) return super().keypress(size, key)
@ -204,14 +204,24 @@ class Timeline(urwid.Columns):
class StatusDetails(urwid.Pile): class StatusDetails(urwid.Pile):
def __init__(self, status, in_thread): def __init__(self, status, in_thread):
"""
Parameters
----------
status : Status
The status to render.
in_thread : bool
Whether the status is rendered from a thread status list.
"""
self.in_thread = in_thread self.in_thread = in_thread
widget_list = list(self.content_generator(status)) reblogged_by = status.author if status.reblog else None
widget_list = list(self.content_generator(status.original, reblogged_by))
return super().__init__(widget_list) return super().__init__(widget_list)
def content_generator(self, status): def content_generator(self, status, reblogged_by):
if status.data["reblog"]: if reblogged_by:
boosted_by = status.data["account"]["display_name"] text = "{} boosted".format(reblogged_by.display_name)
yield ("pack", urwid.Text(("gray", "{} boosted".format(boosted_by)))) yield ("pack", urwid.Text(("gray", text)))
yield ("pack", urwid.AttrMap(urwid.Divider("-"), "gray")) yield ("pack", urwid.AttrMap(urwid.Divider("-"), "gray"))
if status.author.display_name: if status.author.display_name:
@ -315,10 +325,10 @@ class StatusDetails(urwid.Pile):
class StatusListItem(SelectableColumns): class StatusListItem(SelectableColumns):
def __init__(self, status): def __init__(self, status):
created_at = status.created_at.strftime("%Y-%m-%d %H:%M") created_at = status.created_at.strftime("%Y-%m-%d %H:%M")
favourited = ("yellow", "") if status.favourited else " " favourited = ("yellow", "") if status.original.favourited else " "
reblogged = ("yellow", "") if status.reblogged else " " reblogged = ("yellow", "") if status.original.reblogged else " "
is_reblog = ("cyan", "") if status.reblog else " " is_reblog = ("cyan", "") if status.reblog else " "
is_reply = ("cyan", "") if status.in_reply_to else " " is_reply = ("cyan", "") if status.original.in_reply_to else " "
return super().__init__([ return super().__init__([
("pack", SelectableText(("blue", created_at), wrap="clip")), ("pack", SelectableText(("blue", created_at), wrap="clip")),
@ -327,7 +337,7 @@ class StatusListItem(SelectableColumns):
("pack", urwid.Text(" ")), ("pack", urwid.Text(" ")),
("pack", urwid.Text(reblogged)), ("pack", urwid.Text(reblogged)),
("pack", urwid.Text(" ")), ("pack", urwid.Text(" ")),
urwid.Text(("green", status.account), wrap="clip"), urwid.Text(("green", status.original.account), wrap="clip"),
("pack", urwid.Text(is_reply)), ("pack", urwid.Text(is_reply)),
("pack", urwid.Text(is_reblog)), ("pack", urwid.Text(is_reblog)),
("pack", urwid.Text(" ")), ("pack", urwid.Text(" ")),