kopia lustrzana https://github.com/ihabunek/toot
rodzic
840b2fd476
commit
d21cad892c
|
@ -1,11 +1,13 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
from toot import api, config
|
from toot import api, config
|
||||||
from toot.auth import login_interactive, login_browser_interactive, create_app_interactive
|
from toot.auth import login_interactive, login_browser_interactive, create_app_interactive
|
||||||
from toot.exceptions import ConsoleError, NotFoundError
|
from toot.exceptions import ConsoleError, NotFoundError
|
||||||
from toot.output import (print_out, print_instance, print_account,
|
from toot.output import (print_out, print_instance, print_account,
|
||||||
print_search_results, print_timeline, print_notifications)
|
print_search_results, print_timeline, print_notifications)
|
||||||
from toot.utils import assert_domain_exists, multiline_input, EOF_KEY
|
from toot.utils import assert_domain_exists, editor_input, multiline_input, EOF_KEY
|
||||||
|
|
||||||
|
|
||||||
def get_timeline_generator(app, user, args):
|
def get_timeline_generator(app, user, args):
|
||||||
|
@ -76,9 +78,17 @@ def curses(app, user, args):
|
||||||
|
|
||||||
|
|
||||||
def post(app, user, args):
|
def post(app, user, args):
|
||||||
|
# TODO: this might be achievable, explore options
|
||||||
|
if args.editor and not sys.stdin.isatty():
|
||||||
|
raise ConsoleError("Cannot run editor if not in tty.")
|
||||||
|
|
||||||
if args.media and len(args.media) > 4:
|
if args.media and len(args.media) > 4:
|
||||||
raise ConsoleError("Cannot attach more than 4 files.")
|
raise ConsoleError("Cannot attach more than 4 files.")
|
||||||
|
|
||||||
|
# Read any text that might be piped to stdin
|
||||||
|
if not args.text and not sys.stdin.isatty():
|
||||||
|
args.text = sys.stdin.read().rstrip()
|
||||||
|
|
||||||
if args.media:
|
if args.media:
|
||||||
media = [_do_upload(app, user, file) for file in args.media]
|
media = [_do_upload(app, user, file) for file in args.media]
|
||||||
media_ids = [m["id"] for m in media]
|
media_ids = [m["id"] for m in media]
|
||||||
|
@ -89,7 +99,9 @@ def post(app, user, args):
|
||||||
if media and not args.text:
|
if media and not args.text:
|
||||||
args.text = "\n".join(m['text_url'] for m in media)
|
args.text = "\n".join(m['text_url'] for m in media)
|
||||||
|
|
||||||
if not args.text:
|
if args.editor:
|
||||||
|
args.text = editor_input(args.editor, args.text)
|
||||||
|
elif not args.text:
|
||||||
print_out("Write or paste your toot. Press <yellow>{}</yellow> to post it.".format(EOF_KEY))
|
print_out("Write or paste your toot. Press <yellow>{}</yellow> to post it.".format(EOF_KEY))
|
||||||
args.text = multiline_input()
|
args.text = multiline_input()
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import logging
|
import logging
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
import sys
|
||||||
|
|
||||||
from argparse import ArgumentParser, FileType, ArgumentTypeError
|
from argparse import ArgumentParser, FileType, ArgumentTypeError
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
@ -39,6 +40,21 @@ def timeline_count(value):
|
||||||
return n
|
return n
|
||||||
|
|
||||||
|
|
||||||
|
def editor(value):
|
||||||
|
if not value:
|
||||||
|
raise ArgumentTypeError(
|
||||||
|
"Editor not specified in --editor option and $EDITOR environment "
|
||||||
|
"variable not set."
|
||||||
|
)
|
||||||
|
|
||||||
|
# Check editor executable exists
|
||||||
|
exe = shutil.which(value)
|
||||||
|
if not exe:
|
||||||
|
raise ArgumentTypeError(f"Editor `{value}` not found")
|
||||||
|
|
||||||
|
return exe
|
||||||
|
|
||||||
|
|
||||||
Command = namedtuple("Command", ["name", "description", "require_auth", "arguments"])
|
Command = namedtuple("Command", ["name", "description", "require_auth", "arguments"])
|
||||||
|
|
||||||
|
|
||||||
|
@ -298,6 +314,13 @@ POST_COMMANDS = [
|
||||||
"type": language,
|
"type": language,
|
||||||
"help": "ISO 639-2 language code of the toot, to skip automatic detection",
|
"help": "ISO 639-2 language code of the toot, to skip automatic detection",
|
||||||
}),
|
}),
|
||||||
|
(["-e", "--editor"], {
|
||||||
|
"type": editor,
|
||||||
|
"nargs": "?",
|
||||||
|
"const": os.getenv("EDITOR", ""), # option given without value
|
||||||
|
"help": "Specify an editor to compose your toot, "
|
||||||
|
"defaults to editor defined in $EDITOR env variable.",
|
||||||
|
}),
|
||||||
],
|
],
|
||||||
require_auth=True,
|
require_auth=True,
|
||||||
),
|
),
|
||||||
|
@ -500,12 +523,6 @@ def main():
|
||||||
filename = os.getenv("TOOT_LOG_FILE")
|
filename = os.getenv("TOOT_LOG_FILE")
|
||||||
logging.basicConfig(level=logging.DEBUG, filename=filename)
|
logging.basicConfig(level=logging.DEBUG, filename=filename)
|
||||||
|
|
||||||
# If something is piped in, append it to commandline arguments
|
|
||||||
if not sys.stdin.isatty():
|
|
||||||
stdin = sys.stdin.read()
|
|
||||||
if stdin:
|
|
||||||
sys.argv.append(stdin)
|
|
||||||
|
|
||||||
command_name = sys.argv[1] if len(sys.argv) > 1 else None
|
command_name = sys.argv[1] if len(sys.argv) > 1 else None
|
||||||
args = sys.argv[2:]
|
args = sys.argv[2:]
|
||||||
|
|
||||||
|
@ -519,5 +536,5 @@ def main():
|
||||||
except (ConsoleError, ApiError) as e:
|
except (ConsoleError, ApiError) as e:
|
||||||
print_err(str(e))
|
print_err(str(e))
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
except KeyboardInterrupt as e:
|
except KeyboardInterrupt:
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import socket
|
import socket
|
||||||
|
import subprocess
|
||||||
|
import tempfile
|
||||||
import unicodedata
|
import unicodedata
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
|
@ -88,3 +90,27 @@ def multiline_input():
|
||||||
break
|
break
|
||||||
|
|
||||||
return "\n".join(lines).strip()
|
return "\n".join(lines).strip()
|
||||||
|
|
||||||
|
|
||||||
|
EDITOR_INPUT_INSTRUCTIONS = """
|
||||||
|
# Please enter your toot. Lines starting with '#' will be ignored, and an empty
|
||||||
|
# message aborts the post.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def editor_input(editor, initial_text):
|
||||||
|
"""Lets user input text using an editor."""
|
||||||
|
initial_text = (initial_text or "") + EDITOR_INPUT_INSTRUCTIONS
|
||||||
|
|
||||||
|
with tempfile.NamedTemporaryFile() as f:
|
||||||
|
f.write(initial_text.encode())
|
||||||
|
f.flush()
|
||||||
|
|
||||||
|
subprocess.run([editor, f.name])
|
||||||
|
|
||||||
|
f.seek(0)
|
||||||
|
text = f.read().decode()
|
||||||
|
|
||||||
|
lines = text.strip().splitlines()
|
||||||
|
lines = (l for l in lines if not l.startswith("#"))
|
||||||
|
return "\n".join(lines)
|
||||||
|
|
Ładowanie…
Reference in New Issue