mirror of
https://github.com/ihabunek/toot
synced 2025-02-09 00:28:38 +01:00
Make toot timeline
continuable by pressing Enter
This commit is contained in:
parent
0dfb04e9e3
commit
19cbcd43b2
@ -132,9 +132,9 @@ def test_timeline(mock_get, monkeypatch, capsys):
|
|||||||
'in_reply_to_id': None
|
'in_reply_to_id': None
|
||||||
}])
|
}])
|
||||||
|
|
||||||
console.run_command(app, user, 'timeline', [])
|
console.run_command(app, user, 'timeline', ['--once'])
|
||||||
|
|
||||||
mock_get.assert_called_once_with(app, user, '/api/v1/timelines/home')
|
mock_get.assert_called_once_with(app, user, '/api/v1/timelines/home?limit=10', None)
|
||||||
|
|
||||||
out, err = capsys.readouterr()
|
out, err = capsys.readouterr()
|
||||||
assert "The computer can't tell you the emotional story." in out
|
assert "The computer can't tell you the emotional story." in out
|
||||||
@ -144,6 +144,7 @@ def test_timeline(mock_get, monkeypatch, capsys):
|
|||||||
assert "id: 111111111111111111" in out
|
assert "id: 111111111111111111" in out
|
||||||
assert "[RE]" not in out
|
assert "[RE]" not in out
|
||||||
|
|
||||||
|
|
||||||
@mock.patch('toot.http.get')
|
@mock.patch('toot.http.get')
|
||||||
def test_timeline_with_re(mock_get, monkeypatch, capsys):
|
def test_timeline_with_re(mock_get, monkeypatch, capsys):
|
||||||
mock_get.return_value = MockResponse([{
|
mock_get.return_value = MockResponse([{
|
||||||
@ -158,9 +159,9 @@ def test_timeline_with_re(mock_get, monkeypatch, capsys):
|
|||||||
'in_reply_to_id': '111111111111111110'
|
'in_reply_to_id': '111111111111111110'
|
||||||
}])
|
}])
|
||||||
|
|
||||||
console.run_command(app, user, 'timeline', [])
|
console.run_command(app, user, 'timeline', ['--once'])
|
||||||
|
|
||||||
mock_get.assert_called_once_with(app, user, '/api/v1/timelines/home')
|
mock_get.assert_called_once_with(app, user, '/api/v1/timelines/home?limit=10', None)
|
||||||
|
|
||||||
out, err = capsys.readouterr()
|
out, err = capsys.readouterr()
|
||||||
assert "The computer can't tell you the emotional story." in out
|
assert "The computer can't tell you the emotional story." in out
|
||||||
|
25
toot/api.py
25
toot/api.py
@ -151,26 +151,6 @@ def context(app, user, status_id):
|
|||||||
return http.get(app, user, url).json()
|
return http.get(app, user, url).json()
|
||||||
|
|
||||||
|
|
||||||
def timeline_home(app, user):
|
|
||||||
return http.get(app, user, '/api/v1/timelines/home').json()
|
|
||||||
|
|
||||||
|
|
||||||
def timeline_public(app, user, local=False):
|
|
||||||
params = {'local': str_bool(local)}
|
|
||||||
return http.get(app, user, '/api/v1/timelines/public', params).json()
|
|
||||||
|
|
||||||
|
|
||||||
def timeline_tag(app, user, hashtag, local=False):
|
|
||||||
url = '/api/v1/timelines/tag/{}'.format(quote(hashtag))
|
|
||||||
params = {'local': str_bool(local)}
|
|
||||||
return http.get(app, user, url, params).json()
|
|
||||||
|
|
||||||
|
|
||||||
def timeline_list(app, user, list_id):
|
|
||||||
url = '/api/v1/timelines/list/{}'.format(list_id)
|
|
||||||
return http.get(app, user, url).json()
|
|
||||||
|
|
||||||
|
|
||||||
def get_next_path(headers):
|
def get_next_path(headers):
|
||||||
"""Given timeline response headers, returns the path to the next batch"""
|
"""Given timeline response headers, returns the path to the next batch"""
|
||||||
links = headers.get('Link', '')
|
links = headers.get('Link', '')
|
||||||
@ -212,6 +192,11 @@ def tag_timeline_generator(app, user, hashtag, local=False, limit=20):
|
|||||||
return _timeline_generator(app, user, path, params)
|
return _timeline_generator(app, user, path, params)
|
||||||
|
|
||||||
|
|
||||||
|
def timeline_list_generator(app, user, list_id, limit=20):
|
||||||
|
path = '/api/v1/timelines/list/{}'.format(list_id)
|
||||||
|
return _timeline_generator(app, user, path, {'limit': limit})
|
||||||
|
|
||||||
|
|
||||||
def upload_media(app, user, file):
|
def upload_media(app, user, file):
|
||||||
return http.post(app, user, '/api/v1/media', files={
|
return http.post(app, user, '/api/v1/media', files={
|
||||||
'file': file
|
'file': file
|
||||||
|
@ -16,19 +16,30 @@ def timeline(app, user, args):
|
|||||||
raise ConsoleError("The --local option is only valid alongside --public or --tag.")
|
raise ConsoleError("The --local option is only valid alongside --public or --tag.")
|
||||||
|
|
||||||
if args.public:
|
if args.public:
|
||||||
items = api.timeline_public(app, user, local=args.local)
|
gen = api.public_timeline_generator(app.instance, local=args.local, limit=args.count)
|
||||||
elif args.tag:
|
elif args.tag:
|
||||||
items = api.timeline_tag(app, user, args.tag, local=args.local)
|
gen = api.tag_timeline_generator(app, user, args.tag, local=args.local, limit=args.count)
|
||||||
elif args.list:
|
elif args.list:
|
||||||
items = api.timeline_list(app, user, args.list)
|
gen = api.timeline_list_genertor(app, user, args.list)
|
||||||
else:
|
else:
|
||||||
items = api.timeline_home(app, user)
|
gen = api.home_timeline_generator(app, user, limit=args.count)
|
||||||
|
|
||||||
|
while(True):
|
||||||
|
items = next(gen)
|
||||||
|
|
||||||
if args.reverse:
|
if args.reverse:
|
||||||
items = reversed(items)
|
items = reversed(items)
|
||||||
|
|
||||||
print_timeline(items)
|
print_timeline(items)
|
||||||
|
|
||||||
|
if args.once:
|
||||||
|
break
|
||||||
|
|
||||||
|
char = input("\nContinue? [Y/n] ")
|
||||||
|
if char.lower() == "n":
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
def thread(app, user, args):
|
def thread(app, user, args):
|
||||||
toot = api.single_status(app, user, args.status_id)
|
toot = api.single_status(app, user, args.status_id)
|
||||||
context = api.context(app, user, args.status_id)
|
context = api.context(app, user, args.status_id)
|
||||||
@ -43,6 +54,7 @@ def thread(app, user, args):
|
|||||||
|
|
||||||
print_timeline(thread)
|
print_timeline(thread)
|
||||||
|
|
||||||
|
|
||||||
def curses(app, user, args):
|
def curses(app, user, args):
|
||||||
from toot.ui.app import TimelineApp
|
from toot.ui.app import TimelineApp
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ import os
|
|||||||
import sys
|
import sys
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from argparse import ArgumentParser, FileType
|
from argparse import ArgumentParser, FileType, ArgumentTypeError
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
from toot import config, commands, CLIENT_NAME, CLIENT_WEBSITE, __version__
|
from toot import config, commands, CLIENT_NAME, CLIENT_WEBSITE, __version__
|
||||||
from toot.exceptions import ApiError, ConsoleError
|
from toot.exceptions import ApiError, ConsoleError
|
||||||
@ -21,6 +21,13 @@ def visibility(value):
|
|||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
def timeline_count(value):
|
||||||
|
n = int(value)
|
||||||
|
if not 0 < n <= 20:
|
||||||
|
raise ArgumentTypeError("Number of toots should be between 1 and 20.")
|
||||||
|
return n
|
||||||
|
|
||||||
|
|
||||||
Command = namedtuple("Command", ["name", "description", "require_auth", "arguments"])
|
Command = namedtuple("Command", ["name", "description", "require_auth", "arguments"])
|
||||||
|
|
||||||
|
|
||||||
@ -191,6 +198,16 @@ READ_COMMANDS = [
|
|||||||
"default": False,
|
"default": False,
|
||||||
"help": "Reverse the order of the shown timeline (to new posts at the bottom)",
|
"help": "Reverse the order of the shown timeline (to new posts at the bottom)",
|
||||||
}),
|
}),
|
||||||
|
(["-c", "--count"], {
|
||||||
|
"type": timeline_count,
|
||||||
|
"help": "Number of toots to show per page (1-20, default 10).",
|
||||||
|
"default": 10,
|
||||||
|
}),
|
||||||
|
(["-1", "--once"], {
|
||||||
|
"action": "store_true",
|
||||||
|
"default": False,
|
||||||
|
"help": "Only show the first <count> toots, do not prompt to continue.",
|
||||||
|
}),
|
||||||
],
|
],
|
||||||
require_auth=True,
|
require_auth=True,
|
||||||
),
|
),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user