kopia lustrzana https://github.com/ihabunek/toot
entities
rodzic
4b40f45688
commit
d42394c111
|
@ -203,6 +203,9 @@ class StatusMeta:
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class Status:
|
class Status:
|
||||||
|
"""
|
||||||
|
https://docs.joinmastodon.org/entities/Status/
|
||||||
|
"""
|
||||||
id: str
|
id: str
|
||||||
uri: str
|
uri: str
|
||||||
created_at: datetime
|
created_at: datetime
|
||||||
|
@ -250,14 +253,25 @@ def from_dict(cls: Type[T], data: Dict) -> T:
|
||||||
def _fields():
|
def _fields():
|
||||||
hints = get_type_hints(cls)
|
hints = get_type_hints(cls)
|
||||||
for field in dataclasses.fields(cls):
|
for field in dataclasses.fields(cls):
|
||||||
default = field.default if field.default is not dataclasses.MISSING else None
|
if not field.name.startswith("_"):
|
||||||
field_type = prune_optional(hints[field.name])
|
field_type = prune_optional(hints[field.name])
|
||||||
value = data.get(field.name, default)
|
default_value = get_default_value(field)
|
||||||
|
value = data.get(field.name, default_value)
|
||||||
yield convert(field_type, value)
|
yield convert(field_type, value)
|
||||||
|
|
||||||
return cls(*_fields())
|
return cls(*_fields())
|
||||||
|
|
||||||
|
|
||||||
|
def get_default_value(field):
|
||||||
|
if field.default is not dataclasses.MISSING:
|
||||||
|
return field.default
|
||||||
|
|
||||||
|
if field.default_factory is not dataclasses.MISSING:
|
||||||
|
return field.default_factory()
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
def convert(field_type, value):
|
def convert(field_type, value):
|
||||||
if value is None:
|
if value is None:
|
||||||
return None
|
return None
|
||||||
|
|
|
@ -3,7 +3,7 @@ import sys
|
||||||
import urwid
|
import urwid
|
||||||
import webbrowser
|
import webbrowser
|
||||||
|
|
||||||
from typing import Optional
|
from typing import List, Optional
|
||||||
|
|
||||||
from .entities import Account, Poll, PreviewCard, Status
|
from .entities import Account, Poll, PreviewCard, Status
|
||||||
from .scroll import Scrollable, ScrollBar
|
from .scroll import Scrollable, ScrollBar
|
||||||
|
@ -121,7 +121,7 @@ class Timeline(urwid.Columns):
|
||||||
options = highlight_keys(options, "white_bold", "cyan")
|
options = highlight_keys(options, "white_bold", "cyan")
|
||||||
return urwid.Text(options)
|
return urwid.Text(options)
|
||||||
|
|
||||||
def get_focused_status(self):
|
def get_focused_status(self) -> Optional[Status]:
|
||||||
try:
|
try:
|
||||||
return self.statuses[self.status_list.body.focus]
|
return self.statuses[self.status_list.body.focus]
|
||||||
except TypeError:
|
except TypeError:
|
||||||
|
@ -172,7 +172,7 @@ class Timeline(urwid.Columns):
|
||||||
self._emit("next")
|
self._emit("next")
|
||||||
|
|
||||||
if key in ("a", "A"):
|
if key in ("a", "A"):
|
||||||
self._emit("account", status.original.data['account']['id'])
|
self._emit("account", status.original.account.id)
|
||||||
return
|
return
|
||||||
|
|
||||||
if key in ("b", "B"):
|
if key in ("b", "B"):
|
||||||
|
@ -208,7 +208,7 @@ class Timeline(urwid.Columns):
|
||||||
return
|
return
|
||||||
|
|
||||||
if key in ("s", "S"):
|
if key in ("s", "S"):
|
||||||
status.original.show_sensitive = True
|
status._meta.show_sensitive = True
|
||||||
self.refresh_status_details()
|
self.refresh_status_details()
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -250,26 +250,26 @@ class Timeline(urwid.Columns):
|
||||||
|
|
||||||
return super().keypress(size, key)
|
return super().keypress(size, key)
|
||||||
|
|
||||||
def append_status(self, status):
|
def append_status(self, status: Status):
|
||||||
self.statuses.append(status)
|
self.statuses.append(status)
|
||||||
self.status_list.body.append(self.build_list_item(status))
|
self.status_list.body.append(self.build_list_item(status))
|
||||||
|
|
||||||
def prepend_status(self, status):
|
def prepend_status(self, status: Status):
|
||||||
self.statuses.insert(0, status)
|
self.statuses.insert(0, status)
|
||||||
self.status_list.body.insert(0, self.build_list_item(status))
|
self.status_list.body.insert(0, self.build_list_item(status))
|
||||||
|
|
||||||
def append_statuses(self, statuses):
|
def append_statuses(self, statuses: List[Status]):
|
||||||
for status in statuses:
|
for status in statuses:
|
||||||
self.append_status(status)
|
self.append_status(status)
|
||||||
|
|
||||||
def get_status_index(self, id):
|
def get_status_index(self, id: str) -> int:
|
||||||
# TODO: This is suboptimal, consider a better way
|
# TODO: This is suboptimal, consider a better way
|
||||||
for n, status in enumerate(self.statuses):
|
for n, status in enumerate(self.statuses):
|
||||||
if status.id == id:
|
if status.id == id:
|
||||||
return n
|
return n
|
||||||
raise ValueError("Status with ID {} not found".format(id))
|
raise ValueError("Status with ID {} not found".format(id))
|
||||||
|
|
||||||
def focus_status(self, status):
|
def focus_status(self, status: Status):
|
||||||
index = self.get_status_index(status.id)
|
index = self.get_status_index(status.id)
|
||||||
self.status_list.body.set_focus(index)
|
self.status_list.body.set_focus(index)
|
||||||
|
|
||||||
|
@ -307,9 +307,7 @@ class StatusDetails(urwid.Pile):
|
||||||
if status else ())
|
if status else ())
|
||||||
return super().__init__(widget_list)
|
return super().__init__(widget_list)
|
||||||
|
|
||||||
def content_generator(self, status: Status, reblogged_by: Account):
|
def content_generator(self, status: Status, reblogged_by: Optional[Account]):
|
||||||
meta = status._meta
|
|
||||||
|
|
||||||
if reblogged_by:
|
if reblogged_by:
|
||||||
text = "♺ {} boosted".format(reblogged_by.display_name or reblogged_by.username)
|
text = "♺ {} boosted".format(reblogged_by.display_name or reblogged_by.username)
|
||||||
yield ("pack", urwid.Text(("gray", text)))
|
yield ("pack", urwid.Text(("gray", text)))
|
||||||
|
@ -325,6 +323,8 @@ class StatusDetails(urwid.Pile):
|
||||||
yield ("pack", urwid.Text(status.spoiler_text))
|
yield ("pack", urwid.Text(status.spoiler_text))
|
||||||
yield ("pack", urwid.Divider())
|
yield ("pack", urwid.Divider())
|
||||||
|
|
||||||
|
meta = status._meta
|
||||||
|
|
||||||
# Show content warning
|
# Show content warning
|
||||||
if status.spoiler_text and not meta.show_sensitive:
|
if status.spoiler_text and not meta.show_sensitive:
|
||||||
yield ("pack", urwid.Text(("content_warning", "Marked as sensitive. Press S to view.")))
|
yield ("pack", urwid.Text(("content_warning", "Marked as sensitive. Press S to view.")))
|
||||||
|
@ -373,9 +373,9 @@ class StatusDetails(urwid.Pile):
|
||||||
yield ("pack", urwid.Text([
|
yield ("pack", urwid.Text([
|
||||||
("blue", f"{status.created_at.strftime('%Y-%m-%d %H:%M')} "),
|
("blue", f"{status.created_at.strftime('%Y-%m-%d %H:%M')} "),
|
||||||
("red" if status.bookmarked else "gray", "🠷 "),
|
("red" if status.bookmarked else "gray", "🠷 "),
|
||||||
("gray", f"⤶ {status.data['replies_count']} "),
|
("gray", f"⤶ {status.replies_count} "),
|
||||||
("yellow" if status.reblogged else "gray", f"♺ {status.data['reblogs_count']} "),
|
("yellow" if status.reblogged else "gray", f"♺ {status.reblogs_count} "),
|
||||||
("yellow" if status.favourited else "gray", f"★ {status.data['favourites_count']}"),
|
("yellow" if status.favourited else "gray", f"★ {status.favourites_count}"),
|
||||||
(visibility_color, f" · {visibility}"),
|
(visibility_color, f" · {visibility}"),
|
||||||
("yellow", f" · Translated from {translated_from} " if translated_from else ""),
|
("yellow", f" · Translated from {translated_from} " if translated_from else ""),
|
||||||
("gray", f" · {application_name}" if application_name else ""),
|
("gray", f" · {application_name}" if application_name else ""),
|
||||||
|
|
Ładowanie…
Reference in New Issue