diff --git a/tests/test_console.py b/tests/test_console.py index 53bb5e6..f9478ae 100644 --- a/tests/test_console.py +++ b/tests/test_console.py @@ -132,9 +132,9 @@ def test_timeline(mock_get, monkeypatch, capsys): '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() 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 "[RE]" not in out + @mock.patch('toot.http.get') def test_timeline_with_re(mock_get, monkeypatch, capsys): mock_get.return_value = MockResponse([{ @@ -158,9 +159,9 @@ def test_timeline_with_re(mock_get, monkeypatch, capsys): '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() assert "The computer can't tell you the emotional story." in out diff --git a/toot/api.py b/toot/api.py index 1684bac..b9865c4 100644 --- a/toot/api.py +++ b/toot/api.py @@ -151,26 +151,6 @@ def context(app, user, status_id): 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): """Given timeline response headers, returns the path to the next batch""" 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) +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): return http.post(app, user, '/api/v1/media', files={ 'file': file diff --git a/toot/commands.py b/toot/commands.py index bd2d51f..e74ee8e 100644 --- a/toot/commands.py +++ b/toot/commands.py @@ -16,18 +16,29 @@ def timeline(app, user, args): raise ConsoleError("The --local option is only valid alongside --public or --tag.") 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: - 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: - items = api.timeline_list(app, user, args.list) + gen = api.timeline_list_genertor(app, user, args.list) else: - items = api.timeline_home(app, user) + gen = api.home_timeline_generator(app, user, limit=args.count) - if args.reverse: - items = reversed(items) + while(True): + items = next(gen) + + if args.reverse: + items = reversed(items) + + print_timeline(items) + + if args.once: + break + + char = input("\nContinue? [Y/n] ") + if char.lower() == "n": + break - print_timeline(items) def thread(app, user, args): toot = api.single_status(app, user, args.status_id) @@ -43,6 +54,7 @@ def thread(app, user, args): print_timeline(thread) + def curses(app, user, args): from toot.ui.app import TimelineApp diff --git a/toot/console.py b/toot/console.py index 385299e..0689bfb 100644 --- a/toot/console.py +++ b/toot/console.py @@ -4,7 +4,7 @@ import os import sys import logging -from argparse import ArgumentParser, FileType +from argparse import ArgumentParser, FileType, ArgumentTypeError from collections import namedtuple from toot import config, commands, CLIENT_NAME, CLIENT_WEBSITE, __version__ from toot.exceptions import ApiError, ConsoleError @@ -21,6 +21,13 @@ def visibility(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"]) @@ -191,6 +198,16 @@ READ_COMMANDS = [ "default": False, "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 toots, do not prompt to continue.", + }), ], require_auth=True, ),