Introduction
Introduction Statistics Contact Development Disclaimer Help
console.py - toot - Unnamed repository; edit this file 'description' to name th…
Log
Files
Refs
LICENSE
---
console.py (9208B)
---
1 # -*- coding: utf-8 -*-
2
3 import os
4 import sys
5 import logging
6
7 from argparse import ArgumentParser, FileType
8 from collections import namedtuple
9 from toot import config, commands, CLIENT_NAME, CLIENT_WEBSITE
10 from toot.exceptions import ApiError, ConsoleError
11 from toot.output import print_out, print_err
12
13 VISIBILITY_CHOICES = ['public', 'unlisted', 'private', 'direct']
14
15
16 def visibility(value):
17 """Validates the visibilty parameter"""
18 if value not in VISIBILITY_CHOICES:
19 raise ValueError("Invalid visibility value")
20
21 return value
22
23
24 Command = namedtuple("Command", ["name", "description", "require_auth", …
25
26
27 common_args = [
28 (["--no-color"], {
29 "help": "don't use ANSI colors in output",
30 "action": 'store_true',
31 "default": False,
32 }),
33 (["--debug"], {
34 "help": "show debug log in console",
35 "action": 'store_true',
36 "default": False,
37 })
38 ]
39
40 account_arg = (["account"], {
41 "help": "account name, e.g. '[email protected]'",
42 })
43
44 instance_arg = (["-i", "--instance"], {
45 "type": str,
46 "help": 'mastodon instance to log into e.g. "mastodon.social"',
47 })
48
49 email_arg = (["-e", "--email"], {
50 "type": str,
51 "help": 'email address to log in with',
52 })
53
54
55 AUTH_COMMANDS = [
56 Command(
57 name="login",
58 description="Log in from the console, does NOT support two facto…
59 arguments=[instance_arg, email_arg],
60 require_auth=False,
61 ),
62 Command(
63 name="login_browser",
64 description="Log in using your browser, supports regular and two…
65 arguments=[instance_arg],
66 require_auth=False,
67 ),
68 Command(
69 name="activate",
70 description="Switch between logged in accounts.",
71 arguments=[account_arg],
72 require_auth=False,
73 ),
74 Command(
75 name="logout",
76 description="Log out, delete stored access keys",
77 arguments=[account_arg],
78 require_auth=False,
79 ),
80 Command(
81 name="auth",
82 description="Show logged in accounts and instances",
83 arguments=[],
84 require_auth=False,
85 ),
86 ]
87
88 READ_COMMANDS = [
89 Command(
90 name="whoami",
91 description="Display logged in user details",
92 arguments=[],
93 require_auth=True,
94 ),
95 Command(
96 name="whois",
97 description="Display account details",
98 arguments=[
99 (["account"], {
100 "help": "account name or numeric ID"
101 }),
102 ],
103 require_auth=True,
104 ),
105 Command(
106 name="instance",
107 description="Display instance details",
108 arguments=[
109 (["instance"], {
110 "help": "instance domain (e.g. 'mastodon.social') or bla…
111 "nargs": "?",
112 }),
113
114 ],
115 require_auth=False,
116 ),
117 Command(
118 name="search",
119 description="Search for users or hashtags",
120 arguments=[
121 (["query"], {
122 "help": "the search query",
123 }),
124 (["-r", "--resolve"], {
125 "action": 'store_true',
126 "default": False,
127 "help": "Resolve non-local accounts",
128 }),
129 ],
130 require_auth=True,
131 ),
132 Command(
133 name="timeline",
134 description="Show recent items in your public timeline",
135 arguments=[
136 (["tag"], {
137 "help" : "Search for a tag",
138 "nargs" : "?",
139 }),
140 ],
141 require_auth=True,
142 ),
143 Command(
144 name="curses",
145 description="An experimental timeline app (doesn't work on Windo…
146 arguments=[
147 (["-p", "--public"], {
148 "action": 'store_true',
149 "default": False,
150 "help": "Resolve non-local accounts",
151 }),
152 (["-i", "--instance"], {
153 "type": str,
154 "help": 'instance from which to read (for public timelin…
155 })
156 ],
157 require_auth=False,
158 ),
159 ]
160
161 POST_COMMANDS = [
162 Command(
163 name="post",
164 description="Post a status text to your timeline",
165 arguments=[
166 (["text"], {
167 "help": "The status text to post.",
168 "nargs": "?",
169 }),
170 (["-m", "--media"], {
171 "type": FileType('rb'),
172 "help": "path to the media file to attach"
173 }),
174 (["-v", "--visibility"], {
175 "type": visibility,
176 "default": "public",
177 "help": 'post visibility, one of: %s' % ", ".join(VISIBI…
178 })
179 ],
180 require_auth=True,
181 ),
182 Command(
183 name="upload",
184 description="Upload an image or video file",
185 arguments=[
186 (["file"], {
187 "help": "Path to the file to upload",
188 "type": FileType('rb')
189 })
190 ],
191 require_auth=True,
192 ),
193 ]
194
195 ACCOUNTS_COMMANDS = [
196 Command(
197 name="follow",
198 description="Follow an account",
199 arguments=[
200 account_arg,
201 ],
202 require_auth=True,
203 ),
204 Command(
205 name="unfollow",
206 description="Unfollow an account",
207 arguments=[
208 account_arg,
209 ],
210 require_auth=True,
211 ),
212 Command(
213 name="mute",
214 description="Mute an account",
215 arguments=[
216 account_arg,
217 ],
218 require_auth=True,
219 ),
220 Command(
221 name="unmute",
222 description="Unmute an account",
223 arguments=[
224 account_arg,
225 ],
226 require_auth=True,
227 ),
228 Command(
229 name="block",
230 description="Block an account",
231 arguments=[
232 account_arg,
233 ],
234 require_auth=True,
235 ),
236 Command(
237 name="unblock",
238 description="Unblock an account",
239 arguments=[
240 account_arg,
241 ],
242 require_auth=True,
243 ),
244 ]
245
246 COMMANDS = AUTH_COMMANDS + READ_COMMANDS + POST_COMMANDS + ACCOUNTS_COMM…
247
248
249 def print_usage():
250 max_name_len = max(len(command.name) for command in COMMANDS)
251
252 groups = [
253 ("Authentication", AUTH_COMMANDS),
254 ("Read", READ_COMMANDS),
255 ("Post", POST_COMMANDS),
256 ("Accounts", ACCOUNTS_COMMANDS),
257 ]
258
259 print_out("<green>{}</green>".format(CLIENT_NAME))
260
261 for name, cmds in groups:
262 print_out("")
263 print_out(name + ":")
264
265 for cmd in cmds:
266 cmd_name = cmd.name.ljust(max_name_len + 2)
267 print_out(" <yellow>toot {}</yellow> {}".format(cmd_name, c…
268
269 print_out("")
270 print_out("To get help for each command run:")
271 print_out(" <yellow>toot <command> --help</yellow>")
272 print_out("")
273 print_out("<green>{}</green>".format(CLIENT_WEBSITE))
274
275
276 def get_argument_parser(name, command):
277 parser = ArgumentParser(
278 prog='toot %s' % name,
279 description=command.description,
280 epilog=CLIENT_WEBSITE)
281
282 for args, kwargs in command.arguments + common_args:
283 parser.add_argument(*args, **kwargs)
284
285 # If the command requires auth, give an option to select account
286 if command.require_auth:
287 parser.add_argument("-u", "--using", help="the account to use, o…
288
289 return parser
290
291
292 def run_command(app, user, name, args):
293 command = next((c for c in COMMANDS if c.name == name), None)
294
295 if not command:
296 print_err("Unknown command '{}'\n".format(name))
297 print_usage()
298 return
299
300 parser = get_argument_parser(name, command)
301 parsed_args = parser.parse_args(args)
302
303 # Override the active account if 'using' option is given
304 if command.require_auth and parsed_args.using:
305 user, app = config.get_user_app(parsed_args.using)
306 if not user or not app:
307 raise ConsoleError("User '{}' not found".format(parsed_args.…
308
309 if command.require_auth and (not user or not app):
310 print_err("This command requires that you are logged in.")
311 print_err("Please run `toot login` first.")
312 return
313
314 fn = commands.__dict__.get(name)
315
316 if not fn:
317 raise NotImplementedError("Command '{}' does not have an impleme…
318
319 return fn(app, user, parsed_args)
320
321
322 def main():
323 # Enable debug logging if --debug is in args
324 if "--debug" in sys.argv:
325 filename = os.getenv("TOOT_LOG_FILE")
326 logging.basicConfig(level=logging.DEBUG, filename=filename)
327
328 # If something is piped in, append it to commandline arguments
329 if not sys.stdin.isatty():
330 stdin = sys.stdin.read()
331 if stdin:
332 sys.argv.append(stdin)
333
334 command_name = sys.argv[1] if len(sys.argv) > 1 else None
335 args = sys.argv[2:]
336
337 if not command_name:
338 return print_usage()
339
340 user, app = config.get_active_user_app()
341
342 try:
343 run_command(app, user, command_name, args)
344 except ConsoleError as e:
345 print_err(str(e))
346 sys.exit(1)
347 except ApiError as e:
348 print_err(str(e))
349 sys.exit(1)
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.