chore: code review cleanup + bump v0.8.4
- Remove _get_client_for_output() compat shim (replaced by direct _get_client calls) - Remove unused inspect import - Fix redundant branch in constants.get_accept_language() - Add TWITTER_BROWSER docs to README (en + zh) - Update all test monkeypatch signatures - Bump version to 0.8.4
This commit is contained in:
12
README.md
12
README.md
@@ -182,6 +182,12 @@ Browser extraction is recommended — it forwards ALL Twitter cookies (not just
|
|||||||
TWITTER_CHROME_PROFILE="Profile 2" twitter feed
|
TWITTER_CHROME_PROFILE="Profile 2" twitter feed
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**Browser priority:** If you have multiple browsers, set `TWITTER_BROWSER` to try a specific browser first:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
TWITTER_BROWSER=chrome twitter feed # Supported: arc, chrome, edge, firefox, brave
|
||||||
|
```
|
||||||
|
|
||||||
After loading cookies, the CLI performs lightweight verification. Commands that require account access fail fast on clear auth errors (`401/403`).
|
After loading cookies, the CLI performs lightweight verification. Commands that require account access fail fast on clear auth errors (`401/403`).
|
||||||
|
|
||||||
### Proxy Support
|
### Proxy Support
|
||||||
@@ -491,6 +497,12 @@ twitter follow elonmusk --json
|
|||||||
TWITTER_CHROME_PROFILE="Profile 2" twitter feed
|
TWITTER_CHROME_PROFILE="Profile 2" twitter feed
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**浏览器优先级**:如果有多个浏览器,可通过 `TWITTER_BROWSER` 指定优先尝试的浏览器:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
TWITTER_BROWSER=chrome twitter feed # 支持: arc, chrome, edge, firefox, brave
|
||||||
|
```
|
||||||
|
|
||||||
### 代理支持
|
### 代理支持
|
||||||
|
|
||||||
设置 `TWITTER_PROXY` 环境变量即可:
|
设置 `TWITTER_PROXY` 环境变量即可:
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "twitter-cli"
|
name = "twitter-cli"
|
||||||
version = "0.8.3"
|
version = "0.8.4"
|
||||||
description = "A CLI for Twitter/X — feed, bookmarks, and user timeline in terminal"
|
description = "A CLI for Twitter/X — feed, bookmarks, and user timeline in terminal"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
license = "Apache-2.0"
|
license = "Apache-2.0"
|
||||||
|
|||||||
@@ -19,22 +19,12 @@ def test_cli_user_command_works_with_client_factory(monkeypatch) -> None:
|
|||||||
def fetch_user(self, screen_name: str) -> UserProfile:
|
def fetch_user(self, screen_name: str) -> UserProfile:
|
||||||
return UserProfile(id="1", name="Alice", screen_name=screen_name)
|
return UserProfile(id="1", name="Alice", screen_name=screen_name)
|
||||||
|
|
||||||
monkeypatch.setattr("twitter_cli.cli._get_client", lambda config=None: FakeClient())
|
monkeypatch.setattr("twitter_cli.cli._get_client", lambda config=None, quiet=False: FakeClient())
|
||||||
runner = CliRunner()
|
runner = CliRunner()
|
||||||
result = runner.invoke(cli, ["user", "alice"])
|
result = runner.invoke(cli, ["user", "alice"])
|
||||||
assert result.exit_code == 0
|
assert result.exit_code == 0
|
||||||
|
|
||||||
|
|
||||||
def test_get_client_for_output_does_not_swallow_real_type_error(monkeypatch) -> None:
|
|
||||||
def _broken_get_client(config=None, quiet=False):
|
|
||||||
raise TypeError("real bug")
|
|
||||||
|
|
||||||
monkeypatch.setattr("twitter_cli.cli._get_client", _broken_get_client)
|
|
||||||
|
|
||||||
with pytest.raises(TypeError, match="real bug"):
|
|
||||||
from twitter_cli.cli import _get_client_for_output
|
|
||||||
|
|
||||||
_get_client_for_output({})
|
|
||||||
|
|
||||||
|
|
||||||
def test_cli_feed_json_input_path(tmp_path, tweet_factory) -> None:
|
def test_cli_feed_json_input_path(tmp_path, tweet_factory) -> None:
|
||||||
@@ -102,7 +92,7 @@ def test_print_tweet_table_full_text_shows_untruncated_text(tweet_factory) -> No
|
|||||||
def test_cli_commands_wrap_client_creation_errors(monkeypatch, args) -> None:
|
def test_cli_commands_wrap_client_creation_errors(monkeypatch, args) -> None:
|
||||||
monkeypatch.setattr(
|
monkeypatch.setattr(
|
||||||
"twitter_cli.cli._get_client",
|
"twitter_cli.cli._get_client",
|
||||||
lambda config=None: (_ for _ in ()).throw(RuntimeError("boom")),
|
lambda config=None, quiet=False: (_ for _ in ()).throw(RuntimeError("boom")),
|
||||||
)
|
)
|
||||||
runner = CliRunner()
|
runner = CliRunner()
|
||||||
|
|
||||||
@@ -117,7 +107,7 @@ def test_cli_user_error_yaml(monkeypatch) -> None:
|
|||||||
monkeypatch.setenv("OUTPUT", "auto")
|
monkeypatch.setenv("OUTPUT", "auto")
|
||||||
monkeypatch.setattr(
|
monkeypatch.setattr(
|
||||||
"twitter_cli.cli._get_client",
|
"twitter_cli.cli._get_client",
|
||||||
lambda config=None: (_ for _ in ()).throw(RuntimeError("User not found")),
|
lambda config=None, quiet=False: (_ for _ in ()).throw(RuntimeError("User not found")),
|
||||||
)
|
)
|
||||||
runner = CliRunner()
|
runner = CliRunner()
|
||||||
|
|
||||||
@@ -136,7 +126,7 @@ def test_cli_tweet_accepts_shared_url_with_query(monkeypatch) -> None:
|
|||||||
assert max_count == 50
|
assert max_count == 50
|
||||||
return []
|
return []
|
||||||
|
|
||||||
monkeypatch.setattr("twitter_cli.cli._get_client", lambda config=None: FakeClient())
|
monkeypatch.setattr("twitter_cli.cli._get_client", lambda config=None, quiet=False: FakeClient())
|
||||||
monkeypatch.setattr(
|
monkeypatch.setattr(
|
||||||
"twitter_cli.cli.load_config",
|
"twitter_cli.cli.load_config",
|
||||||
lambda: {"fetch": {"count": 50}, "filter": {}, "rateLimit": {}},
|
lambda: {"fetch": {"count": 50}, "filter": {}, "rateLimit": {}},
|
||||||
@@ -162,7 +152,7 @@ def test_cli_article_accepts_article_url_and_json(monkeypatch) -> None:
|
|||||||
article_text="Hello\n\n## Section",
|
article_text="Hello\n\n## Section",
|
||||||
)
|
)
|
||||||
|
|
||||||
monkeypatch.setattr("twitter_cli.cli._get_client", lambda config=None: FakeClient())
|
monkeypatch.setattr("twitter_cli.cli._get_client", lambda config=None, quiet=False: FakeClient())
|
||||||
monkeypatch.setattr(
|
monkeypatch.setattr(
|
||||||
"twitter_cli.cli.load_config",
|
"twitter_cli.cli.load_config",
|
||||||
lambda: {"fetch": {"count": 50}, "filter": {}, "rateLimit": {}},
|
lambda: {"fetch": {"count": 50}, "filter": {}, "rateLimit": {}},
|
||||||
@@ -195,7 +185,7 @@ def test_cli_article_markdown_output_and_save(monkeypatch, tmp_path) -> None:
|
|||||||
assert tweet_id == "12345"
|
assert tweet_id == "12345"
|
||||||
return article
|
return article
|
||||||
|
|
||||||
monkeypatch.setattr("twitter_cli.cli._get_client", lambda config=None: FakeClient())
|
monkeypatch.setattr("twitter_cli.cli._get_client", lambda config=None, quiet=False: FakeClient())
|
||||||
monkeypatch.setattr("twitter_cli.cli.load_config", lambda: {})
|
monkeypatch.setattr("twitter_cli.cli.load_config", lambda: {})
|
||||||
output_path = tmp_path / "article.md"
|
output_path = tmp_path / "article.md"
|
||||||
runner = CliRunner()
|
runner = CliRunner()
|
||||||
@@ -227,7 +217,7 @@ def test_cli_article_markdown_overrides_auto_structured_output(monkeypatch) -> N
|
|||||||
return article
|
return article
|
||||||
|
|
||||||
monkeypatch.setenv("OUTPUT", "auto")
|
monkeypatch.setenv("OUTPUT", "auto")
|
||||||
monkeypatch.setattr("twitter_cli.cli._get_client", lambda config=None: FakeClient())
|
monkeypatch.setattr("twitter_cli.cli._get_client", lambda config=None, quiet=False: FakeClient())
|
||||||
monkeypatch.setattr("twitter_cli.cli.load_config", lambda: {})
|
monkeypatch.setattr("twitter_cli.cli.load_config", lambda: {})
|
||||||
runner = CliRunner()
|
runner = CliRunner()
|
||||||
|
|
||||||
@@ -254,7 +244,7 @@ def test_cli_bookmark_alias_works(monkeypatch) -> None:
|
|||||||
calls.append(tweet_id)
|
calls.append(tweet_id)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
monkeypatch.setattr("twitter_cli.cli._get_client", lambda config=None: FakeClient())
|
monkeypatch.setattr("twitter_cli.cli._get_client", lambda config=None, quiet=False: FakeClient())
|
||||||
runner = CliRunner()
|
runner = CliRunner()
|
||||||
|
|
||||||
result = runner.invoke(cli, ["bookmark", "123"])
|
result = runner.invoke(cli, ["bookmark", "123"])
|
||||||
@@ -270,7 +260,7 @@ def test_cli_whoami_command(monkeypatch) -> None:
|
|||||||
def fetch_me(self) -> UserProfile:
|
def fetch_me(self) -> UserProfile:
|
||||||
return UserProfile(id="42", name="Test User", screen_name="testuser")
|
return UserProfile(id="42", name="Test User", screen_name="testuser")
|
||||||
|
|
||||||
monkeypatch.setattr("twitter_cli.cli._get_client", lambda config=None: FakeClient())
|
monkeypatch.setattr("twitter_cli.cli._get_client", lambda config=None, quiet=False: FakeClient())
|
||||||
runner = CliRunner()
|
runner = CliRunner()
|
||||||
|
|
||||||
result = runner.invoke(cli, ["whoami"])
|
result = runner.invoke(cli, ["whoami"])
|
||||||
@@ -289,7 +279,7 @@ def test_cli_whoami_auto_yaml(monkeypatch) -> None:
|
|||||||
return UserProfile(id="42", name="Test User", screen_name="testuser")
|
return UserProfile(id="42", name="Test User", screen_name="testuser")
|
||||||
|
|
||||||
monkeypatch.setenv("OUTPUT", "auto")
|
monkeypatch.setenv("OUTPUT", "auto")
|
||||||
monkeypatch.setattr("twitter_cli.cli._get_client", lambda config=None: FakeClient())
|
monkeypatch.setattr("twitter_cli.cli._get_client", lambda config=None, quiet=False: FakeClient())
|
||||||
runner = CliRunner()
|
runner = CliRunner()
|
||||||
|
|
||||||
result = runner.invoke(cli, ["whoami"])
|
result = runner.invoke(cli, ["whoami"])
|
||||||
@@ -307,7 +297,7 @@ def test_cli_status_auto_yaml(monkeypatch) -> None:
|
|||||||
return UserProfile(id="42", name="Test User", screen_name="testuser")
|
return UserProfile(id="42", name="Test User", screen_name="testuser")
|
||||||
|
|
||||||
monkeypatch.setenv("OUTPUT", "auto")
|
monkeypatch.setenv("OUTPUT", "auto")
|
||||||
monkeypatch.setattr("twitter_cli.cli._get_client", lambda config=None: FakeClient())
|
monkeypatch.setattr("twitter_cli.cli._get_client", lambda config=None, quiet=False: FakeClient())
|
||||||
runner = CliRunner()
|
runner = CliRunner()
|
||||||
|
|
||||||
result = runner.invoke(cli, ["status"])
|
result = runner.invoke(cli, ["status"])
|
||||||
@@ -328,7 +318,7 @@ def test_cli_reply_command(monkeypatch) -> None:
|
|||||||
calls.append({"text": text, "reply_to_id": reply_to_id})
|
calls.append({"text": text, "reply_to_id": reply_to_id})
|
||||||
return "999"
|
return "999"
|
||||||
|
|
||||||
monkeypatch.setattr("twitter_cli.cli._get_client", lambda config=None: FakeClient())
|
monkeypatch.setattr("twitter_cli.cli._get_client", lambda config=None, quiet=False: FakeClient())
|
||||||
runner = CliRunner()
|
runner = CliRunner()
|
||||||
|
|
||||||
result = runner.invoke(cli, ["reply", "12345", "Nice tweet!"])
|
result = runner.invoke(cli, ["reply", "12345", "Nice tweet!"])
|
||||||
@@ -345,7 +335,7 @@ def test_cli_quote_command(monkeypatch) -> None:
|
|||||||
calls.append({"tweet_id": tweet_id, "text": text})
|
calls.append({"tweet_id": tweet_id, "text": text})
|
||||||
return "888"
|
return "888"
|
||||||
|
|
||||||
monkeypatch.setattr("twitter_cli.cli._get_client", lambda config=None: FakeClient())
|
monkeypatch.setattr("twitter_cli.cli._get_client", lambda config=None, quiet=False: FakeClient())
|
||||||
runner = CliRunner()
|
runner = CliRunner()
|
||||||
|
|
||||||
result = runner.invoke(cli, ["quote", "12345", "Interesting!"])
|
result = runner.invoke(cli, ["quote", "12345", "Interesting!"])
|
||||||
@@ -361,7 +351,7 @@ def test_cli_post_json_output(monkeypatch) -> None:
|
|||||||
assert reply_to_id is None
|
assert reply_to_id is None
|
||||||
return "999"
|
return "999"
|
||||||
|
|
||||||
monkeypatch.setattr("twitter_cli.cli._get_client", lambda config=None: FakeClient())
|
monkeypatch.setattr("twitter_cli.cli._get_client", lambda config=None, quiet=False: FakeClient())
|
||||||
runner = CliRunner()
|
runner = CliRunner()
|
||||||
|
|
||||||
result = runner.invoke(cli, ["post", "hello", "--json"])
|
result = runner.invoke(cli, ["post", "hello", "--json"])
|
||||||
@@ -378,7 +368,7 @@ def test_cli_like_yaml_output(monkeypatch) -> None:
|
|||||||
assert tweet_id == "123"
|
assert tweet_id == "123"
|
||||||
return True
|
return True
|
||||||
|
|
||||||
monkeypatch.setattr("twitter_cli.cli._get_client", lambda config=None: FakeClient())
|
monkeypatch.setattr("twitter_cli.cli._get_client", lambda config=None, quiet=False: FakeClient())
|
||||||
runner = CliRunner()
|
runner = CliRunner()
|
||||||
|
|
||||||
result = runner.invoke(cli, ["like", "123", "--yaml"])
|
result = runner.invoke(cli, ["like", "123", "--yaml"])
|
||||||
@@ -399,7 +389,7 @@ def test_cli_follow_json_output(monkeypatch) -> None:
|
|||||||
assert user_id == "42"
|
assert user_id == "42"
|
||||||
return True
|
return True
|
||||||
|
|
||||||
monkeypatch.setattr("twitter_cli.cli._get_client", lambda config=None: FakeClient())
|
monkeypatch.setattr("twitter_cli.cli._get_client", lambda config=None, quiet=False: FakeClient())
|
||||||
runner = CliRunner()
|
runner = CliRunner()
|
||||||
|
|
||||||
result = runner.invoke(cli, ["follow", "alice", "--json"])
|
result = runner.invoke(cli, ["follow", "alice", "--json"])
|
||||||
@@ -421,7 +411,7 @@ def test_cli_follow_command(monkeypatch) -> None:
|
|||||||
actions.append(("follow", user_id))
|
actions.append(("follow", user_id))
|
||||||
return True
|
return True
|
||||||
|
|
||||||
monkeypatch.setattr("twitter_cli.cli._get_client", lambda config=None: FakeClient())
|
monkeypatch.setattr("twitter_cli.cli._get_client", lambda config=None, quiet=False: FakeClient())
|
||||||
runner = CliRunner()
|
runner = CliRunner()
|
||||||
|
|
||||||
result = runner.invoke(cli, ["follow", "alice"])
|
result = runner.invoke(cli, ["follow", "alice"])
|
||||||
@@ -440,7 +430,7 @@ def test_cli_unfollow_command(monkeypatch) -> None:
|
|||||||
actions.append(("unfollow", user_id))
|
actions.append(("unfollow", user_id))
|
||||||
return True
|
return True
|
||||||
|
|
||||||
monkeypatch.setattr("twitter_cli.cli._get_client", lambda config=None: FakeClient())
|
monkeypatch.setattr("twitter_cli.cli._get_client", lambda config=None, quiet=False: FakeClient())
|
||||||
runner = CliRunner()
|
runner = CliRunner()
|
||||||
|
|
||||||
result = runner.invoke(cli, ["unfollow", "alice"])
|
result = runner.invoke(cli, ["unfollow", "alice"])
|
||||||
@@ -457,7 +447,7 @@ def test_cli_search_advanced_options(monkeypatch) -> None:
|
|||||||
captured["product"] = product
|
captured["product"] = product
|
||||||
return []
|
return []
|
||||||
|
|
||||||
monkeypatch.setattr("twitter_cli.cli._get_client", lambda config=None: FakeClient())
|
monkeypatch.setattr("twitter_cli.cli._get_client", lambda config=None, quiet=False: FakeClient())
|
||||||
monkeypatch.setattr(
|
monkeypatch.setattr(
|
||||||
"twitter_cli.cli.load_config",
|
"twitter_cli.cli.load_config",
|
||||||
lambda: {"fetch": {"count": 50}, "filter": {}, "rateLimit": {}},
|
lambda: {"fetch": {"count": 50}, "filter": {}, "rateLimit": {}},
|
||||||
@@ -492,7 +482,7 @@ def test_cli_search_operators_only_no_query(monkeypatch) -> None:
|
|||||||
captured["query"] = query
|
captured["query"] = query
|
||||||
return []
|
return []
|
||||||
|
|
||||||
monkeypatch.setattr("twitter_cli.cli._get_client", lambda config=None: FakeClient())
|
monkeypatch.setattr("twitter_cli.cli._get_client", lambda config=None, quiet=False: FakeClient())
|
||||||
monkeypatch.setattr(
|
monkeypatch.setattr(
|
||||||
"twitter_cli.cli.load_config",
|
"twitter_cli.cli.load_config",
|
||||||
lambda: {"fetch": {"count": 50}, "filter": {}, "rateLimit": {}},
|
lambda: {"fetch": {"count": 50}, "filter": {}, "rateLimit": {}},
|
||||||
@@ -513,7 +503,7 @@ def test_cli_search_empty_query_no_options() -> None:
|
|||||||
|
|
||||||
|
|
||||||
def test_cli_search_invalid_date_rejected(monkeypatch) -> None:
|
def test_cli_search_invalid_date_rejected(monkeypatch) -> None:
|
||||||
monkeypatch.setattr("twitter_cli.cli._get_client", lambda config=None: None)
|
monkeypatch.setattr("twitter_cli.cli._get_client", lambda config=None, quiet=False: None)
|
||||||
runner = CliRunner()
|
runner = CliRunner()
|
||||||
|
|
||||||
result = runner.invoke(cli, ["search", "python", "--since", "not-a-date"])
|
result = runner.invoke(cli, ["search", "python", "--since", "not-a-date"])
|
||||||
@@ -522,7 +512,7 @@ def test_cli_search_invalid_date_rejected(monkeypatch) -> None:
|
|||||||
|
|
||||||
|
|
||||||
def test_cli_search_rejects_reversed_date_range(monkeypatch) -> None:
|
def test_cli_search_rejects_reversed_date_range(monkeypatch) -> None:
|
||||||
monkeypatch.setattr("twitter_cli.cli._get_client", lambda config=None: None)
|
monkeypatch.setattr("twitter_cli.cli._get_client", lambda config=None, quiet=False: None)
|
||||||
runner = CliRunner()
|
runner = CliRunner()
|
||||||
|
|
||||||
result = runner.invoke(cli, ["search", "python", "--since", "2026-03-02", "--until", "2026-03-01"])
|
result = runner.invoke(cli, ["search", "python", "--since", "2026-03-02", "--until", "2026-03-01"])
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ from __future__ import annotations
|
|||||||
|
|
||||||
import logging
|
import logging
|
||||||
import re
|
import re
|
||||||
import inspect
|
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
import urllib.parse
|
import urllib.parse
|
||||||
@@ -153,17 +152,7 @@ def _get_client(config=None, quiet=False):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def _get_client_for_output(config=None, quiet=False):
|
|
||||||
# type: (Optional[Dict[str, Any]], bool) -> TwitterClient
|
|
||||||
"""Call _get_client while staying compatible with monkeypatched legacy signatures."""
|
|
||||||
try:
|
|
||||||
signature = inspect.signature(_get_client)
|
|
||||||
except (TypeError, ValueError):
|
|
||||||
signature = None
|
|
||||||
|
|
||||||
if signature and "quiet" in signature.parameters:
|
|
||||||
return _get_client(config, quiet=quiet)
|
|
||||||
return _get_client(config)
|
|
||||||
|
|
||||||
|
|
||||||
def _exit_with_error(exc):
|
def _exit_with_error(exc):
|
||||||
@@ -417,7 +406,7 @@ def feed(ctx, feed_type, max_count, as_json, as_yaml, input_file, output_file, d
|
|||||||
console.print(" Loaded %d tweets" % len(tweets))
|
console.print(" Loaded %d tweets" % len(tweets))
|
||||||
else:
|
else:
|
||||||
fetch_count = _resolve_configured_count(config, max_count)
|
fetch_count = _resolve_configured_count(config, max_count)
|
||||||
client = _get_client_for_output(config, quiet=not rich_output)
|
client = _get_client(config, quiet=not rich_output)
|
||||||
label = "following feed" if feed_type == "following" else "home timeline"
|
label = "following feed" if feed_type == "following" else "home timeline"
|
||||||
if rich_output:
|
if rich_output:
|
||||||
console.print("📡 Fetching %s (%d tweets)...\n" % (label, fetch_count))
|
console.print("📡 Fetching %s (%d tweets)...\n" % (label, fetch_count))
|
||||||
@@ -507,7 +496,7 @@ def user(screen_name, as_json, as_yaml):
|
|||||||
config = load_config()
|
config = load_config()
|
||||||
try:
|
try:
|
||||||
rich_output = use_rich_output(as_json=as_json, as_yaml=as_yaml)
|
rich_output = use_rich_output(as_json=as_json, as_yaml=as_yaml)
|
||||||
client = _get_client_for_output(config, quiet=not rich_output)
|
client = _get_client(config, quiet=not rich_output)
|
||||||
if rich_output:
|
if rich_output:
|
||||||
console.print("👤 Fetching user @%s..." % screen_name)
|
console.print("👤 Fetching user @%s..." % screen_name)
|
||||||
profile = client.fetch_user(screen_name)
|
profile = client.fetch_user(screen_name)
|
||||||
@@ -534,7 +523,7 @@ def user_posts(ctx, screen_name, max_count, as_json, as_yaml, output_file, full_
|
|||||||
config = load_config()
|
config = load_config()
|
||||||
def _run():
|
def _run():
|
||||||
rich_output = use_rich_output(as_json=as_json, as_yaml=as_yaml, compact=compact)
|
rich_output = use_rich_output(as_json=as_json, as_yaml=as_yaml, compact=compact)
|
||||||
client = _get_client_for_output(config, quiet=not rich_output)
|
client = _get_client(config, quiet=not rich_output)
|
||||||
if rich_output:
|
if rich_output:
|
||||||
console.print("👤 Fetching @%s's profile..." % screen_name)
|
console.print("👤 Fetching @%s's profile..." % screen_name)
|
||||||
profile = client.fetch_user(screen_name)
|
profile = client.fetch_user(screen_name)
|
||||||
@@ -619,7 +608,7 @@ def search(ctx, query, product, from_user, to_user, lang, since, until, has, exc
|
|||||||
config = load_config()
|
config = load_config()
|
||||||
def _run():
|
def _run():
|
||||||
rich_output = use_rich_output(as_json=as_json, as_yaml=as_yaml, compact=compact)
|
rich_output = use_rich_output(as_json=as_json, as_yaml=as_yaml, compact=compact)
|
||||||
client = _get_client_for_output(config, quiet=not rich_output)
|
client = _get_client(config, quiet=not rich_output)
|
||||||
_fetch_and_display(
|
_fetch_and_display(
|
||||||
lambda count: client.fetch_search(composed_query, count, product),
|
lambda count: client.fetch_search(composed_query, count, product),
|
||||||
"'%s' (%s)" % (composed_query, product), "🔍", max_count, as_json, as_yaml, output_file, do_filter, config,
|
"'%s' (%s)" % (composed_query, product), "🔍", max_count, as_json, as_yaml, output_file, do_filter, config,
|
||||||
@@ -648,7 +637,7 @@ def likes(ctx, screen_name, max_count, as_json, as_yaml, output_file, do_filter,
|
|||||||
config = load_config()
|
config = load_config()
|
||||||
def _run():
|
def _run():
|
||||||
rich_output = use_rich_output(as_json=as_json, as_yaml=as_yaml, compact=compact)
|
rich_output = use_rich_output(as_json=as_json, as_yaml=as_yaml, compact=compact)
|
||||||
client = _get_client_for_output(config, quiet=not rich_output)
|
client = _get_client(config, quiet=not rich_output)
|
||||||
if rich_output:
|
if rich_output:
|
||||||
console.print("👤 Fetching @%s's profile..." % screen_name)
|
console.print("👤 Fetching @%s's profile..." % screen_name)
|
||||||
profile = client.fetch_user(screen_name)
|
profile = client.fetch_user(screen_name)
|
||||||
@@ -694,7 +683,7 @@ def tweet(ctx, tweet_id, max_count, full_text, as_json, as_yaml):
|
|||||||
config = load_config()
|
config = load_config()
|
||||||
rich_output = use_rich_output(as_json=as_json, as_yaml=as_yaml, compact=compact)
|
rich_output = use_rich_output(as_json=as_json, as_yaml=as_yaml, compact=compact)
|
||||||
try:
|
try:
|
||||||
client = _get_client_for_output(config, quiet=not rich_output)
|
client = _get_client(config, quiet=not rich_output)
|
||||||
if rich_output:
|
if rich_output:
|
||||||
console.print("🐦 Fetching tweet %s...\n" % tweet_id)
|
console.print("🐦 Fetching tweet %s...\n" % tweet_id)
|
||||||
start = time.time()
|
start = time.time()
|
||||||
@@ -758,7 +747,7 @@ def show(ctx, index, max_count, full_text, output_file, as_json, as_yaml):
|
|||||||
config = load_config()
|
config = load_config()
|
||||||
rich_output = use_rich_output(as_json=as_json, as_yaml=as_yaml, compact=compact)
|
rich_output = use_rich_output(as_json=as_json, as_yaml=as_yaml, compact=compact)
|
||||||
try:
|
try:
|
||||||
client = _get_client_for_output(config, quiet=not rich_output)
|
client = _get_client(config, quiet=not rich_output)
|
||||||
if rich_output:
|
if rich_output:
|
||||||
console.print("🐦 Fetching tweet #%d (id: %s)...\n" % (index, tweet_id))
|
console.print("🐦 Fetching tweet #%d (id: %s)...\n" % (index, tweet_id))
|
||||||
start = time.time()
|
start = time.time()
|
||||||
@@ -796,7 +785,7 @@ def article(ctx, tweet_id, as_json, as_yaml, as_markdown, output_file):
|
|||||||
config = load_config()
|
config = load_config()
|
||||||
rich_output = use_rich_output(as_json=as_json, as_yaml=as_yaml, compact=False) and not as_markdown
|
rich_output = use_rich_output(as_json=as_json, as_yaml=as_yaml, compact=False) and not as_markdown
|
||||||
try:
|
try:
|
||||||
client = _get_client_for_output(config, quiet=not rich_output)
|
client = _get_client(config, quiet=not rich_output)
|
||||||
if rich_output:
|
if rich_output:
|
||||||
console.print("📰 Fetching article %s...\n" % tweet_id)
|
console.print("📰 Fetching article %s...\n" % tweet_id)
|
||||||
start = time.time()
|
start = time.time()
|
||||||
@@ -856,7 +845,7 @@ def followers(screen_name, max_count, as_json, as_yaml):
|
|||||||
config = load_config()
|
config = load_config()
|
||||||
try:
|
try:
|
||||||
rich_output = use_rich_output(as_json=as_json, as_yaml=as_yaml)
|
rich_output = use_rich_output(as_json=as_json, as_yaml=as_yaml)
|
||||||
client = _get_client_for_output(config, quiet=not rich_output)
|
client = _get_client(config, quiet=not rich_output)
|
||||||
if rich_output:
|
if rich_output:
|
||||||
console.print("👤 Fetching @%s's profile..." % screen_name)
|
console.print("👤 Fetching @%s's profile..." % screen_name)
|
||||||
profile = client.fetch_user(screen_name)
|
profile = client.fetch_user(screen_name)
|
||||||
@@ -889,7 +878,7 @@ def following(screen_name, max_count, as_json, as_yaml):
|
|||||||
config = load_config()
|
config = load_config()
|
||||||
try:
|
try:
|
||||||
rich_output = use_rich_output(as_json=as_json, as_yaml=as_yaml)
|
rich_output = use_rich_output(as_json=as_json, as_yaml=as_yaml)
|
||||||
client = _get_client_for_output(config, quiet=not rich_output)
|
client = _get_client(config, quiet=not rich_output)
|
||||||
if rich_output:
|
if rich_output:
|
||||||
console.print("👤 Fetching @%s's profile..." % screen_name)
|
console.print("👤 Fetching @%s's profile..." % screen_name)
|
||||||
profile = client.fetch_user(screen_name)
|
profile = client.fetch_user(screen_name)
|
||||||
@@ -1062,7 +1051,7 @@ def status(as_json, as_yaml):
|
|||||||
config = load_config()
|
config = load_config()
|
||||||
try:
|
try:
|
||||||
rich_output = use_rich_output(as_json=as_json, as_yaml=as_yaml)
|
rich_output = use_rich_output(as_json=as_json, as_yaml=as_yaml)
|
||||||
client = _get_client_for_output(config, quiet=not rich_output)
|
client = _get_client(config, quiet=not rich_output)
|
||||||
profile = client.fetch_me()
|
profile = client.fetch_me()
|
||||||
except RuntimeError as exc:
|
except RuntimeError as exc:
|
||||||
payload = error_payload("not_authenticated", str(exc))
|
payload = error_payload("not_authenticated", str(exc))
|
||||||
@@ -1087,7 +1076,7 @@ def whoami(as_json, as_yaml):
|
|||||||
config = load_config()
|
config = load_config()
|
||||||
try:
|
try:
|
||||||
rich_output = use_rich_output(as_json=as_json, as_yaml=as_yaml)
|
rich_output = use_rich_output(as_json=as_json, as_yaml=as_yaml)
|
||||||
client = _get_client_for_output(config, quiet=not rich_output)
|
client = _get_client(config, quiet=not rich_output)
|
||||||
if rich_output:
|
if rich_output:
|
||||||
console.print("👤 Fetching current user...")
|
console.print("👤 Fetching current user...")
|
||||||
profile = client.fetch_me()
|
profile = client.fetch_me()
|
||||||
|
|||||||
@@ -76,8 +76,6 @@ def get_accept_language():
|
|||||||
# type: () -> str
|
# type: () -> str
|
||||||
tag = _get_locale_tag()
|
tag = _get_locale_tag()
|
||||||
language = tag.split("-", 1)[0] or "en"
|
language = tag.split("-", 1)[0] or "en"
|
||||||
if tag == language:
|
|
||||||
return "%s,%s;q=0.9,en;q=0.8" % (tag, language)
|
|
||||||
return "%s,%s;q=0.9,en;q=0.8" % (tag, language)
|
return "%s,%s;q=0.9,en;q=0.8" % (tag, language)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
2
uv.lock
generated
2
uv.lock
generated
@@ -609,7 +609,7 @@ wheels = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "twitter-cli"
|
name = "twitter-cli"
|
||||||
version = "0.8.3"
|
version = "0.8.4"
|
||||||
source = { editable = "." }
|
source = { editable = "." }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "beautifulsoup4" },
|
{ name = "beautifulsoup4" },
|
||||||
|
|||||||
Reference in New Issue
Block a user