Merge pull request #87 from yitsushi/add-toot-id-on-timeline

Status ID + thread view
pull/88/head
Ivan Habunek 2019-01-21 18:14:36 +01:00 zatwierdzone przez GitHub
commit 131a8096c2
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
5 zmienionych plików z 131 dodań i 0 usunięć

Wyświetl plik

@ -121,6 +121,7 @@ def test_delete(mock_delete, capsys):
@mock.patch('toot.http.get')
def test_timeline(mock_get, monkeypatch, capsys):
mock_get.return_value = MockResponse([{
'id': '111111111111111111',
'account': {
'display_name': 'Frank Zappa',
'username': 'fz'
@ -128,6 +129,7 @@ def test_timeline(mock_get, monkeypatch, capsys):
'created_at': '2017-04-12T15:53:18.174Z',
'content': "<p>The computer can&apos;t tell you the emotional story. It can give you the exact mathematical design, but what's missing is the eyebrows.</p>",
'reblog': None,
'in_reply_to_id': None
}])
console.run_command(app, user, 'timeline', [])
@ -139,7 +141,94 @@ def test_timeline(mock_get, monkeypatch, capsys):
assert "but what's missing is the eyebrows." in out
assert "Frank Zappa" in out
assert "@fz" in out
assert "id: 111111111111111111" in out
assert "[RE]" not in out
@mock.patch('toot.http.get')
def test_timeline_with_re(mock_get, monkeypatch, capsys):
mock_get.return_value = MockResponse([{
'id': '111111111111111111',
'account': {
'display_name': 'Frank Zappa',
'username': 'fz'
},
'created_at': '2017-04-12T15:53:18.174Z',
'content': "<p>The computer can&apos;t tell you the emotional story. It can give you the exact mathematical design, but what's missing is the eyebrows.</p>",
'reblog': None,
'in_reply_to_id': '111111111111111110'
}])
console.run_command(app, user, 'timeline', [])
mock_get.assert_called_once_with(app, user, '/api/v1/timelines/home')
out, err = capsys.readouterr()
assert "The computer can't tell you the emotional story." in out
assert "but what's missing is the eyebrows." in out
assert "Frank Zappa" in out
assert "@fz" in out
assert "id: 111111111111111111" in out
assert "[RE]" in out
@mock.patch('toot.http.get')
def test_thread(mock_get, monkeypatch, capsys):
mock_get.side_effect = [
MockResponse({
'id': '111111111111111111',
'account': {
'display_name': 'Frank Zappa',
'username': 'fz'
},
'created_at': '2017-04-12T15:53:18.174Z',
'content': "my response in the middle",
'reblog': None,
'in_reply_to_id': '111111111111111110'
}),
MockResponse({
'ancestors': [{
'id': '111111111111111110',
'account': {
'display_name': 'Frank Zappa',
'username': 'fz'
},
'created_at': '2017-04-12T15:53:18.174Z',
'content': "original content",
'reblog': None,
'in_reply_to_id': None}],
'descendants': [{
'id': '111111111111111112',
'account': {
'display_name': 'Frank Zappa',
'username': 'fz'
},
'created_at': '2017-04-12T15:53:18.174Z',
'content': "response message",
'reblog': None,
'in_reply_to_id': '111111111111111111'}],
}),
]
console.run_command(app, user, 'thread', ['111111111111111111'])
calls = [
mock.call(app, user, '/api/v1/statuses/111111111111111111'),
mock.call(app, user, '/api/v1/statuses/111111111111111111/context'),
]
mock_get.assert_has_calls(calls, any_order=False)
out, err = capsys.readouterr()
# Display order
assert out.index('original content') < out.index('my response in the middle')
assert out.index('my response in the middle') < out.index('response message')
assert "original content" in out
assert "my response in the middle" in out
assert "response message" in out
assert "Frank Zappa" in out
assert "@fz" in out
assert "id: 111111111111111111" in out
assert "[RE]" in out
@mock.patch('toot.http.post')
def test_upload(mock_post, capsys):

Wyświetl plik

@ -144,6 +144,12 @@ def unpin(app, user, status_id):
return _status_action(app, user, status_id, 'unpin')
def context(app, user, status_id):
url = '/api/v1/statuses/{}/context'.format(status_id)
return http.get(app, user, url).json()
def timeline_home(app, user):
return http.get(app, user, '/api/v1/timelines/home').json()
@ -245,6 +251,12 @@ def verify_credentials(app, user):
return http.get(app, user, '/api/v1/accounts/verify_credentials').json()
def single_status(app, user, status_id):
url = '/api/v1/statuses/{}'.format(status_id)
return http.get(app, user, url).json()
def get_notifications(app, user):
return http.get(app, user, '/api/v1/notifications').json()

Wyświetl plik

@ -29,6 +29,19 @@ def timeline(app, user, args):
print_timeline(items)
def thread(app, user, args):
toot = api.single_status(app, user, args.status_id)
context = api.context(app, user, args.status_id)
thread = []
for item in context['ancestors']:
thread.append(item)
thread.append(toot)
for item in context['descendants']:
thread.append(item)
print_timeline(thread)
def curses(app, user, args):
from toot.ui.app import TimelineApp

Wyświetl plik

@ -154,6 +154,16 @@ READ_COMMANDS = [
],
require_auth=True,
),
Command(
name="thread",
description="Show toot thread items",
arguments=[
(["status_id"], {
"help": "Show thread for toot.",
}),
],
require_auth=True,
),
Command(
name="timeline",
description="Show recent items in a timeline (home by default)",

Wyświetl plik

@ -137,6 +137,11 @@ def print_timeline(items):
if item['reblogged']:
left_column.append("Reblogged @{}".format(item['reblogged']))
if item['reply_to_toot'] is not None:
left_column.append('[RE]')
left_column.append("id: {}".format(item['id']))
right_column = wrap_text(item['text'], 80)
return zip_longest(left_column, right_column, fillvalue="")
@ -153,10 +158,12 @@ def print_timeline(items):
time = datetime.strptime(item['created_at'], "%Y-%m-%dT%H:%M:%S.%fZ")
return {
"id": item['id'],
"account": item['account'],
"text": text,
"time": time,
"reblogged": reblogged,
"reply_to_toot": item['in_reply_to_id']
}
print_out("" * 31 + "" + "" * 88)