Skip to content

Commit

Permalink
Simplify access to reblogged status data
Browse files Browse the repository at this point in the history
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>`.
  • Loading branch information
ihabunek committed Sep 22, 2019
1 parent bc6e433 commit 35e03a1
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 33 deletions.
4 changes: 2 additions & 2 deletions toot/tui/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ def _close(*args):

# This is pretty fast, so it's probably ok to block while context is
# 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"]]
descendants = [self.make_status(s) for s in context["descendants"]]
statuses = ancestors + [status] + descendants
Expand Down Expand Up @@ -337,7 +337,7 @@ def goto_tag_timeline(self, tag, local):
promise.add_done_callback(lambda *args: self.close_overlay())

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:
show_media(urls)

Expand Down
68 changes: 49 additions & 19 deletions toot/tui/entities.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

from .utils import parse_datetime


Author = namedtuple("Author", ["account", "display_name"])


Expand All @@ -11,43 +10,74 @@ class Status:
A wrapper around the Status entity data fetched from Mastodon.
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):
"""
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.is_mine = is_mine
self.default_instance = default_instance

# This can be toggled by the user
self.show_sensitive = False

# TODO: make Status immutable?

# TODO: clean up
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.author = self.get_author()
self.author = self._get_author()
self.favourited = data.get("favourited", False)
self.reblogged = data.get("reblogged", False)
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")
self.url = reblog.get("url") if reblog else data.get("url")
@property
def original(self):
return self.reblog or self

self.mentions = data["mentions"]
def _get_reblog(self):
reblog = self.data.get("reblog")
if not reblog:
return None

def get_author(self):
# Show the author, not the persopn who reblogged
data = self.data["reblog"] or self.data
acct = data['account']['acct']
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, data['account']['display_name'])
return Author(acct, self.data['account']['display_name'])

def get_account(self):
reblog = self.data.get("reblog")
account = reblog['account'] if reblog else self.data['account']
acct = account['acct']
def _get_account(self):
acct = self.data['account']['acct']
return acct if "@" in acct else "{}@{}".format(acct, self.default_instance)

def __repr__(self):
return "<Status id={}>".format(self.id)
return "<Status id={} account={}>".format(self.id, self.account)
34 changes: 22 additions & 12 deletions toot/tui/timeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ def keypress(self, size, key):
return

if key in ("s", "S"):
status.show_sensitive = True
status.original.show_sensitive = True
self.refresh_status_details()
return

Expand All @@ -149,8 +149,8 @@ def keypress(self, size, key):
return

if key in ("v", "V"):
if status.url:
webbrowser.open(status.url)
if status.original.url:
webbrowser.open(status.original.url)
return

return super().keypress(size, key)
Expand Down Expand Up @@ -204,14 +204,24 @@ def remove_status(self, status):

class StatusDetails(urwid.Pile):
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
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)

def content_generator(self, status):
if status.data["reblog"]:
boosted_by = status.data["account"]["display_name"]
yield ("pack", urwid.Text(("gray", "♺ {} boosted".format(boosted_by))))
def content_generator(self, status, reblogged_by):
if reblogged_by:
text = "♺ {} boosted".format(reblogged_by.display_name)
yield ("pack", urwid.Text(("gray", text)))
yield ("pack", urwid.AttrMap(urwid.Divider("-"), "gray"))

if status.author.display_name:
Expand Down Expand Up @@ -315,10 +325,10 @@ def poll_generator(self, poll):
class StatusListItem(SelectableColumns):
def __init__(self, status):
created_at = status.created_at.strftime("%Y-%m-%d %H:%M")
favourited = ("yellow", "★") if status.favourited else " "
reblogged = ("yellow", "♺") if status.reblogged else " "
favourited = ("yellow", "★") if status.original.favourited else " "
reblogged = ("yellow", "♺") if status.original.reblogged 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__([
("pack", SelectableText(("blue", created_at), wrap="clip")),
Expand All @@ -327,7 +337,7 @@ def __init__(self, status):
("pack", urwid.Text(" ")),
("pack", urwid.Text(reblogged)),
("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_reblog)),
("pack", urwid.Text(" ")),
Expand Down

0 comments on commit 35e03a1

Please sign in to comment.