mirror of
https://github.com/ihabunek/toot.git
synced 2024-09-22 04:25:55 -04:00
Add search command
This commit is contained in:
parent
d53849fe4b
commit
64d46955e2
@ -1,6 +1,11 @@
|
|||||||
Changelog
|
Changelog
|
||||||
---------
|
---------
|
||||||
|
|
||||||
|
**0.5.0 (2016-04-16)**
|
||||||
|
|
||||||
|
* Add `search` command
|
||||||
|
* Migrate from `optparse` to `argparse`
|
||||||
|
|
||||||
**0.4.0 (2016-04-15)**
|
**0.4.0 (2016-04-15)**
|
||||||
|
|
||||||
* Add `upload` command to post media
|
* 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.
|
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
|
.. image:: https://img.shields.io/badge/author-%40ihabunek-blue.svg?maxAge=3600&style=flat-square
|
||||||
:target: https://mastodon.social/@ihabunek
|
:target: https://mastodon.social/@ihabunek
|
||||||
.. image:: https://img.shields.io/github/license/ihabunek/pdf417-py.svg?maxAge=3600&style=flat-square
|
.. 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
|
pip install toot
|
||||||
|
|
||||||
|
|
||||||
Usage
|
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::
|
.. code-block::
|
||||||
|
|
||||||
@ -51,31 +70,3 @@ And you can logout which will remove the stored access tokens:
|
|||||||
.. code-block::
|
.. code-block::
|
||||||
|
|
||||||
toot logout
|
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
|
import requests
|
||||||
|
|
||||||
from toot import User, App
|
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
|
from tests.utils import MockResponse
|
||||||
|
|
||||||
@ -138,3 +138,35 @@ def test_upload(monkeypatch, capsys):
|
|||||||
out, err = capsys.readouterr()
|
out, err = capsys.readouterr()
|
||||||
assert "Uploading media" in out
|
assert "Uploading media" in out
|
||||||
assert __file__ 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={
|
return _post(app, user, '/api/v1/media', files={
|
||||||
'file': file
|
'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 textwrap import TextWrapper
|
||||||
|
|
||||||
from toot import DEFAULT_INSTANCE
|
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
|
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 logout - log out (delete saved access tokens)")
|
||||||
print(" toot auth - shows currently logged in user and instance")
|
print(" toot auth - shows currently logged in user and instance")
|
||||||
print(" toot post <msg> - toot a new post to your timeline")
|
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(" toot timeline - shows your public timeline")
|
||||||
print("")
|
print("")
|
||||||
print("To get help for each command run:")
|
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']))
|
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):
|
def do_upload(app, user, file):
|
||||||
print("Uploading media: {}".format(green(file.name)))
|
print("Uploading media: {}".format(green(file.name)))
|
||||||
return upload_media(app, user, file)
|
return upload_media(app, user, file)
|
||||||
@ -251,8 +288,8 @@ def run_command(command, args):
|
|||||||
|
|
||||||
# Commands which require user to be logged in
|
# Commands which require user to be logged in
|
||||||
if not app or not user:
|
if not app or not user:
|
||||||
print(red("You are not logged in."))
|
print_error("You are not logged in.")
|
||||||
print(red("Please run `toot login` first."))
|
print_error("Please run `toot login` first.")
|
||||||
return
|
return
|
||||||
|
|
||||||
if command == 'logout':
|
if command == 'logout':
|
||||||
@ -267,7 +304,10 @@ def run_command(command, args):
|
|||||||
if command == 'upload':
|
if command == 'upload':
|
||||||
return cmd_upload(app, user, args)
|
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()
|
print_usage()
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user