Introduction
Introduction Statistics Contact Development Disclaimer Help
Add search command - toot - Unnamed repository; edit this file 'description' to…
Log
Files
Refs
LICENSE
---
commit 64d46955e2b827c406f503cabc1be8b6169e72dd
parent d53849fe4b5c5b3f84a0ffc787d187bb641a51a5
Author: Ivan Habunek <[email protected]>
Date: Sun, 16 Apr 2017 15:07:27 +0200
Add search command
Diffstat:
CHANGELOG.md | 5 +++++
README.rst | 51 +++++++++++++------------------
tests/test_console.py | 34 ++++++++++++++++++++++++++++++-
toot/api.py | 7 +++++++
toot/console.py | 48 ++++++++++++++++++++++++++++---
5 files changed, 110 insertions(+), 35 deletions(-)
---
diff --git a/CHANGELOG.md b/CHANGELOG.md
@@ -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
diff --git a/README.rst b/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=f…
+ :target: https://travis-ci.org/ihabunek/toot
.. image:: https://img.shields.io/badge/author-%40ihabunek-blue.svg?maxAge=360…
:target: https://mastodon.social/@ihabunek
.. image:: https://img.shields.io/github/license/ihabunek/pdf417-py.svg?maxAge…
@@ -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 late…
+ ``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 token…
.. 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`…
diff --git a/tests/test_console.py b/tests/test_console.py
@@ -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_uploa…
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': '[email protected]',
+ '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\…
+ assert "Accounts:" in out
+ assert "\033[32m@thequeen\033[0m Freddy Mercury" in out
+ assert "\033[32m@[email protected]\033[0m Mercury Freddy" in out
diff --git a/toot/api.py b/toot/api.py
@@ -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,
+ })
diff --git a/toot/console.py b/toot/console.py
@@ -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_med…
+from toot.api import create_app, login, post_status, timeline_home, upload_med…
from toot.config import save_user, load_user, load_app, save_app, CONFIG_APP_F…
@@ -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()
You are viewing proxied material from vernunftzentrum.de. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.