Enable providing media thumbnails

issue #301
This commit is contained in:
Ivan Habunek 2023-03-03 11:42:43 +01:00
parent 14a286ef0d
commit e26cb52fd7
No known key found for this signature in database
GPG Key ID: F5F0623FF5EBCB3D
3 changed files with 52 additions and 13 deletions

View File

@ -1,11 +1,13 @@
import mimetypes
from os import path
import re
import uuid
from typing import List
from typing import BinaryIO, List, Optional
from urllib.parse import urlparse, urlencode, quote
from toot import http, CLIENT_NAME, CLIENT_WEBSITE
from toot.exceptions import AuthenticationError
from toot import App, User, http, CLIENT_NAME, CLIENT_WEBSITE
from toot.exceptions import AuthenticationError, ConsoleError
from toot.utils import drop_empty_values, str_bool, str_bool_nullable
SCOPES = 'read write follow'
@ -347,11 +349,40 @@ def anon_tag_timeline_generator(instance, hashtag, local=False, limit=20):
return _anon_timeline_generator(instance, path, params)
def upload_media(app, user, file, description=None):
return http.post(app, user, '/api/v2/media',
data={'description': description},
files={'file': file}
).json()
def upload_media(
app: App,
user: User,
media: BinaryIO,
description: Optional[str] = None,
thumbnail: Optional[BinaryIO] = None,
):
data = drop_empty_values({"description": description})
# NB: Documentation says that "file" should provide a mime-type which we
# don't do currently, but it works.
files = drop_empty_values({
"file": media,
"thumbnail": _add_mime_type(thumbnail)
})
return http.post(app, user, "/api/v2/media", data=data, files=files).json()
def _add_mime_type(file):
if file is None:
return None
# TODO: mimetypes uses the file extension to guess the mime type which is
# not always good enough (e.g. files without extension). python-magic could
# be used instead but it requires adding it as a dependency.
mime_type = mimetypes.guess_type(file.name)
if not mime_type:
raise ConsoleError(f"Unable guess mime type of '{file.name}'. "
"Ensure the file has the desired extension.")
filename = path.basename(file.name)
return (filename, file, mime_type)
def search(app, user, query, resolve=False, type=None):

View File

@ -142,14 +142,16 @@ def _get_scheduled_at(scheduled_at, scheduled_in):
def _upload_media(app, user, args):
# Match media to corresponding description and upload
# Match media to corresponding description and thumbnail
media = args.media or []
descriptions = args.description or []
thumbnails = args.thumbnail or []
uploaded_media = []
for idx, file in enumerate(media):
description = descriptions[idx].strip() if idx < len(descriptions) else None
result = _do_upload(app, user, file, description)
thumbnail = thumbnails[idx] if idx < len(thumbnails) else None
result = _do_upload(app, user, file, description, thumbnail)
uploaded_media.append(result)
return [m["id"] for m in uploaded_media]
@ -297,7 +299,7 @@ def activate(app, user, args):
def upload(app, user, args):
response = _do_upload(app, user, args.file, args.description)
response = _do_upload(app, user, args.file, args.description, None)
msg = "Successfully uploaded media ID <yellow>{}</yellow>, type '<yellow>{}</yellow>'"
@ -312,9 +314,9 @@ def search(app, user, args):
print_search_results(response)
def _do_upload(app, user, file, description):
def _do_upload(app, user, file, description, thumbnail):
print_out("Uploading media: <green>{}</green>".format(file.name))
return api.upload_media(app, user, file, description=description)
return api.upload_media(app, user, file, description=description, thumbnail=thumbnail)
def _find_account(app, user, account_name):

View File

@ -482,6 +482,12 @@ POST_COMMANDS = [
"help": "plain-text description of the media for accessibility "
"purposes, one per attached media"
}),
(["--thumbnail"], {
"action": "append",
"type": FileType("rb"),
"help": "path to an image file to serve as media thumbnail, "
"one per attached media"
}),
visibility_arg,
(["-s", "--sensitive"], {
"action": 'store_true',