mirror of
https://github.com/ihabunek/toot
synced 2025-02-02 12:26:51 +01:00
Add search command
This commit is contained in:
parent
d53849fe4b
commit
64d46955e2
@ -1,6 +1,11 @@
|
||||
Changelog
|
||||
---------
|
||||
|
||||
**0.5.0 (2016-04-16)**
|
||||
|
||||
* Add `search` command
|
||||
* Migrate from `optparse` to `argparse`
|
||||
|
||||
**0.4.0 (2016-04-15)**
|
||||
|
||||
* Add `upload` command to post media
|
||||
|
51
README.rst
51
README.rst
@ -4,6 +4,8 @@ Toot - Mastodon CLI interface
|
||||
|
||||
Interact with Mastodon social networks from the command line.
|
||||
|
||||
.. image:: https://img.shields.io/travis/ihabunek/toot.svg?maxAge=3600&style=flat-square
|
||||
:target: https://travis-ci.org/ihabunek/toot
|
||||
.. image:: https://img.shields.io/badge/author-%40ihabunek-blue.svg?maxAge=3600&style=flat-square
|
||||
:target: https://mastodon.social/@ihabunek
|
||||
.. image:: https://img.shields.io/github/license/ihabunek/pdf417-py.svg?maxAge=3600&style=flat-square
|
||||
@ -21,11 +23,28 @@ Install using pip:
|
||||
|
||||
pip install toot
|
||||
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
Firstly, you will need to login to a Mastodon instance:
|
||||
Running ``toot`` displays a list of available commands.
|
||||
|
||||
Running ``toot <command> -h`` shows the documentation for the given command.
|
||||
|
||||
=================== ===============================================================
|
||||
Command Description
|
||||
=================== ===============================================================
|
||||
``toot login`` Log into a Mastodon instance, saves access keys for later use.
|
||||
``toot logout`` Log out, deletes stored access keys.
|
||||
``toot auth`` Display current login details.
|
||||
``toot post`` Post a status to your timeline.
|
||||
``toot search`` Search for accounts or hashtags.
|
||||
``toot timeline`` Display recent items in your public timeline.
|
||||
=================== ===============================================================
|
||||
|
||||
Authentication
|
||||
--------------
|
||||
|
||||
Before tooting, you need to login to a Mastodon instance:
|
||||
|
||||
.. code-block::
|
||||
|
||||
@ -51,31 +70,3 @@ And you can logout which will remove the stored access tokens:
|
||||
.. code-block::
|
||||
|
||||
toot logout
|
||||
|
||||
Show timeline
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
To show recent items in your public timeline:
|
||||
|
||||
.. code-block::
|
||||
|
||||
toot timeline
|
||||
|
||||
Post status
|
||||
~~~~~~~~~~~
|
||||
|
||||
To post a new status to your timeline:
|
||||
|
||||
.. code-block::
|
||||
|
||||
toot post "Hello world!"
|
||||
|
||||
Optionally attach an image or video to the status:
|
||||
|
||||
toot post "Hello world!" --media=path/to/world.jpg
|
||||
|
||||
To set post visibility:
|
||||
|
||||
toot post "Hello world!" --visibility=unlisted
|
||||
|
||||
Possible visibility values are: ``public`` (default), ``unlisted``, ``private``, ``direct``. They are documented `here <https://github.com/tootsuite/documentation/blob/aa20089756c8cf9ff5a52fb35ad1a9472f10970c/Using-Mastodon/User-guide.md#toot-privacy>`_.
|
||||
|
@ -3,7 +3,7 @@ import pytest
|
||||
import requests
|
||||
|
||||
from toot import User, App
|
||||
from toot.console import print_usage, cmd_post_status, cmd_timeline, cmd_upload
|
||||
from toot.console import print_usage, cmd_post_status, cmd_timeline, cmd_upload, cmd_search
|
||||
|
||||
from tests.utils import MockResponse
|
||||
|
||||
@ -138,3 +138,35 @@ def test_upload(monkeypatch, capsys):
|
||||
out, err = capsys.readouterr()
|
||||
assert "Uploading media" in out
|
||||
assert __file__ in out
|
||||
|
||||
|
||||
def test_search(monkeypatch, capsys):
|
||||
def mock_get(url, params, headers=None):
|
||||
assert url == 'https://habunek.com/api/v1/search'
|
||||
assert headers == {'Authorization': 'Bearer xxx'}
|
||||
assert params == {
|
||||
'q': 'freddy',
|
||||
'resolve': False,
|
||||
}
|
||||
|
||||
return MockResponse({
|
||||
'hashtags': ['foo', 'bar', 'baz'],
|
||||
'accounts': [{
|
||||
'acct': 'thequeen',
|
||||
'display_name': 'Freddy Mercury'
|
||||
}, {
|
||||
'acct': 'thequeen@other.instance',
|
||||
'display_name': 'Mercury Freddy'
|
||||
}],
|
||||
'statuses': [],
|
||||
})
|
||||
|
||||
monkeypatch.setattr(requests, 'get', mock_get)
|
||||
|
||||
cmd_search(app, user, ['freddy'])
|
||||
|
||||
out, err = capsys.readouterr()
|
||||
assert "Hashtags:\n\033[32m#foo\033[0m, \033[32m#bar\033[0m, \033[32m#baz\033[0m" in out
|
||||
assert "Accounts:" in out
|
||||
assert "\033[32m@thequeen\033[0m Freddy Mercury" in out
|
||||
assert "\033[32m@thequeen@other.instance\033[0m Mercury Freddy" in out
|
||||
|
@ -108,3 +108,10 @@ def upload_media(app, user, file):
|
||||
return _post(app, user, '/api/v1/media', files={
|
||||
'file': file
|
||||
})
|
||||
|
||||
|
||||
def search(app, user, query, resolve):
|
||||
return _get(app, user, '/api/v1/search', {
|
||||
'q': query,
|
||||
'resolve': resolve,
|
||||
})
|
||||
|
@ -16,7 +16,7 @@ from argparse import ArgumentParser, FileType
|
||||
from textwrap import TextWrapper
|
||||
|
||||
from toot import DEFAULT_INSTANCE
|
||||
from toot.api import create_app, login, post_status, timeline_home, upload_media
|
||||
from toot.api import create_app, login, post_status, timeline_home, upload_media, search
|
||||
from toot.config import save_user, load_user, load_app, save_app, CONFIG_APP_FILE, CONFIG_USER_FILE
|
||||
|
||||
|
||||
@ -84,6 +84,7 @@ def print_usage():
|
||||
print(" toot logout - log out (delete saved access tokens)")
|
||||
print(" toot auth - shows currently logged in user and instance")
|
||||
print(" toot post <msg> - toot a new post to your timeline")
|
||||
print(" toot search - search for accounts or hashtags")
|
||||
print(" toot timeline - shows your public timeline")
|
||||
print("")
|
||||
print("To get help for each command run:")
|
||||
@ -233,6 +234,42 @@ def cmd_upload(app, user, args):
|
||||
print("Text URL: " + green(response['text_url']))
|
||||
|
||||
|
||||
def _print_accounts(accounts):
|
||||
if not accounts:
|
||||
return
|
||||
|
||||
print("\nAccounts:")
|
||||
for account in accounts:
|
||||
acct = green("@{}".format(account['acct']))
|
||||
display_name = account['display_name']
|
||||
print("* {} {}".format(acct, display_name))
|
||||
|
||||
|
||||
def _print_hashtags(hashtags):
|
||||
if not hashtags:
|
||||
return
|
||||
|
||||
print("\nHashtags:")
|
||||
print(", ".join([green("#" + t) for t in hashtags]))
|
||||
|
||||
|
||||
def cmd_search(app, user, args):
|
||||
parser = ArgumentParser(prog="toot serach",
|
||||
description="Search for content",
|
||||
epilog="https://github.com/ihabunek/toot")
|
||||
|
||||
parser.add_argument("query", help="The search query")
|
||||
parser.add_argument("-r", "--resolve", action='store_true', default=False,
|
||||
help="Whether to resolve non-local accounts")
|
||||
|
||||
args = parser.parse_args(args)
|
||||
|
||||
response = search(app, user, args.query, args.resolve)
|
||||
|
||||
_print_accounts(response['accounts'])
|
||||
_print_hashtags(response['hashtags'])
|
||||
|
||||
|
||||
def do_upload(app, user, file):
|
||||
print("Uploading media: {}".format(green(file.name)))
|
||||
return upload_media(app, user, file)
|
||||
@ -251,8 +288,8 @@ def run_command(command, args):
|
||||
|
||||
# Commands which require user to be logged in
|
||||
if not app or not user:
|
||||
print(red("You are not logged in."))
|
||||
print(red("Please run `toot login` first."))
|
||||
print_error("You are not logged in.")
|
||||
print_error("Please run `toot login` first.")
|
||||
return
|
||||
|
||||
if command == 'logout':
|
||||
@ -267,7 +304,10 @@ def run_command(command, args):
|
||||
if command == 'upload':
|
||||
return cmd_upload(app, user, args)
|
||||
|
||||
print(red("Unknown command '{}'\n".format(command)))
|
||||
if command == 'search':
|
||||
return cmd_search(app, user, args)
|
||||
|
||||
print_error("Unknown command '{}'\n".format(command))
|
||||
print_usage()
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user