WIP(thirdparty): allow manual trigger of the plugins hook
This commit is contained in:
parent
1e714dd28e
commit
2d0a8676e4
|
@ -9326,6 +9326,36 @@ paths:
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/components/schemas/UploadForOwner'
|
$ref: '#/components/schemas/UploadForOwner'
|
||||||
description: ''
|
description: ''
|
||||||
|
/api/v1/uploads/trigger-download/:
|
||||||
|
post:
|
||||||
|
operationId: create_upload_trigger_download
|
||||||
|
tags:
|
||||||
|
- uploads
|
||||||
|
requestBody:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/UploadForOwnerRequest'
|
||||||
|
application/x-www-form-urlencoded:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/UploadForOwnerRequest'
|
||||||
|
multipart/form-data:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/UploadForOwnerRequest'
|
||||||
|
application/activity+json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/UploadForOwnerRequest'
|
||||||
|
required: true
|
||||||
|
security:
|
||||||
|
- oauth2: []
|
||||||
|
- ApplicationToken: []
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/UploadForOwner'
|
||||||
|
description: ''
|
||||||
/api/v1/users/{username}/:
|
/api/v1/users/{username}/:
|
||||||
put:
|
put:
|
||||||
operationId: update_user
|
operationId: update_user
|
||||||
|
@ -19007,6 +19037,36 @@ paths:
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/components/schemas/UploadForOwner'
|
$ref: '#/components/schemas/UploadForOwner'
|
||||||
description: ''
|
description: ''
|
||||||
|
/api/v2/uploads/trigger-download/:
|
||||||
|
post:
|
||||||
|
operationId: create_upload_trigger_download_2
|
||||||
|
tags:
|
||||||
|
- uploads
|
||||||
|
requestBody:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/UploadForOwnerRequest'
|
||||||
|
application/x-www-form-urlencoded:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/UploadForOwnerRequest'
|
||||||
|
multipart/form-data:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/UploadForOwnerRequest'
|
||||||
|
application/activity+json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/UploadForOwnerRequest'
|
||||||
|
required: true
|
||||||
|
security:
|
||||||
|
- oauth2: []
|
||||||
|
- ApplicationToken: []
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/UploadForOwner'
|
||||||
|
description: ''
|
||||||
/api/v2/users/{username}/:
|
/api/v2/users/{username}/:
|
||||||
put:
|
put:
|
||||||
operationId: update_user_3
|
operationId: update_user_3
|
||||||
|
@ -24767,6 +24827,10 @@ components:
|
||||||
default: pending
|
default: pending
|
||||||
privacy_level:
|
privacy_level:
|
||||||
$ref: '#/components/schemas/LibraryPrivacyLevelEnum'
|
$ref: '#/components/schemas/LibraryPrivacyLevelEnum'
|
||||||
|
third_party_provider:
|
||||||
|
type: string
|
||||||
|
nullable: true
|
||||||
|
maxLength: 100
|
||||||
import_metadata:
|
import_metadata:
|
||||||
$ref: '#/components/schemas/ImportMetadataRequest'
|
$ref: '#/components/schemas/ImportMetadataRequest'
|
||||||
import_reference:
|
import_reference:
|
||||||
|
@ -25908,6 +25972,10 @@ components:
|
||||||
default: pending
|
default: pending
|
||||||
privacy_level:
|
privacy_level:
|
||||||
$ref: '#/components/schemas/LibraryPrivacyLevelEnum'
|
$ref: '#/components/schemas/LibraryPrivacyLevelEnum'
|
||||||
|
third_party_provider:
|
||||||
|
type: string
|
||||||
|
nullable: true
|
||||||
|
maxLength: 100
|
||||||
import_details:
|
import_details:
|
||||||
readOnly: true
|
readOnly: true
|
||||||
import_metadata:
|
import_metadata:
|
||||||
|
@ -25951,6 +26019,10 @@ components:
|
||||||
default: pending
|
default: pending
|
||||||
privacy_level:
|
privacy_level:
|
||||||
$ref: '#/components/schemas/LibraryPrivacyLevelEnum'
|
$ref: '#/components/schemas/LibraryPrivacyLevelEnum'
|
||||||
|
third_party_provider:
|
||||||
|
type: string
|
||||||
|
nullable: true
|
||||||
|
maxLength: 100
|
||||||
import_metadata:
|
import_metadata:
|
||||||
$ref: '#/components/schemas/ImportMetadataRequest'
|
$ref: '#/components/schemas/ImportMetadataRequest'
|
||||||
import_reference:
|
import_reference:
|
||||||
|
|
|
@ -9,5 +9,5 @@ logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@plugins.register_hook(plugins.TRIGGER_THIRD_PARTY_UPLOAD, PLUGIN)
|
@plugins.register_hook(plugins.TRIGGER_THIRD_PARTY_UPLOAD, PLUGIN)
|
||||||
def lauch_download(track, conf={}):
|
def lauch_download(track, actor, conf={}):
|
||||||
tasks.archive_download.delay(track_id=track.pk, conf=conf)
|
tasks.archive_download.delay(track_id=track.pk, conf=conf)
|
||||||
|
|
|
@ -53,7 +53,7 @@ def check_last_third_party_queries(track, count):
|
||||||
check_last_third_party_queries(track, count)
|
check_last_third_party_queries(track, count)
|
||||||
|
|
||||||
|
|
||||||
def create_upload(url, track, files_data):
|
def get_or_create_upload(url, track, files_data):
|
||||||
mimetype = f"audio/{files_data.get('format', 'unknown')}"
|
mimetype = f"audio/{files_data.get('format', 'unknown')}"
|
||||||
duration = files_data.get("mtime", 0)
|
duration = files_data.get("mtime", 0)
|
||||||
filesize = files_data.get("size", 0)
|
filesize = files_data.get("size", 0)
|
||||||
|
@ -64,19 +64,23 @@ def create_upload(url, track, files_data):
|
||||||
actor=actors.get_service_actor(),
|
actor=actors.get_service_actor(),
|
||||||
)
|
)
|
||||||
|
|
||||||
return models.Upload.objects.create(
|
defaults = {
|
||||||
|
"creation_date": timezone.now(),
|
||||||
|
"duration": duration,
|
||||||
|
"size": filesize,
|
||||||
|
"bitrate": bitrate,
|
||||||
|
"import_status": "pending",
|
||||||
|
}
|
||||||
|
upload, created = models.Upload.objects.get_or_create(
|
||||||
|
defaults=defaults,
|
||||||
mimetype=mimetype,
|
mimetype=mimetype,
|
||||||
source=url,
|
source=url,
|
||||||
third_party_provider="archive-dl",
|
third_party_provider="archive-dl",
|
||||||
creation_date=timezone.now(),
|
|
||||||
track=track,
|
track=track,
|
||||||
duration=duration,
|
|
||||||
size=filesize,
|
|
||||||
bitrate=bitrate,
|
|
||||||
library=service_library,
|
library=service_library,
|
||||||
from_activity=None,
|
from_activity=None,
|
||||||
import_status="pending",
|
|
||||||
)
|
)
|
||||||
|
return upload
|
||||||
|
|
||||||
|
|
||||||
@celery.app.task(name="archivedl.archive_download")
|
@celery.app.task(name="archivedl.archive_download")
|
||||||
|
@ -89,9 +93,11 @@ def archive_download(track, conf):
|
||||||
logger.error(e)
|
logger.error(e)
|
||||||
return
|
return
|
||||||
artist_name = utils.get_artist_credit_string(track)
|
artist_name = utils.get_artist_credit_string(track)
|
||||||
|
# a lot of times this don't find anything, archive relies more on albums than tracks
|
||||||
query = f"mediatype:audio AND title:{track.title} AND creator:{artist_name}"
|
query = f"mediatype:audio AND title:{track.title} AND creator:{artist_name}"
|
||||||
with requests.Session() as session:
|
with requests.Session() as session:
|
||||||
url = get_search_url(query, page_size=1, page=1)
|
url = get_search_url(query, page_size=1, page=1)
|
||||||
|
get_or_create_upload(url, track, files_data={})
|
||||||
page_data = fetch_json(url, session)
|
page_data = fetch_json(url, session)
|
||||||
for obj in page_data["response"]["docs"]:
|
for obj in page_data["response"]["docs"]:
|
||||||
logger.info(f"launching download item for {str(obj)}")
|
logger.info(f"launching download item for {str(obj)}")
|
||||||
|
@ -123,7 +129,7 @@ def download_item(
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
url = f"https://archive.org/download/{item_data['identifier']}/{to_download[0]['name']}"
|
url = f"https://archive.org/download/{item_data['identifier']}/{to_download[0]['name']}"
|
||||||
upload = create_upload(url, track, to_download[0])
|
upload = get_or_create_upload(url, track, to_download[0])
|
||||||
try:
|
try:
|
||||||
with tempfile.TemporaryDirectory() as temp_dir:
|
with tempfile.TemporaryDirectory() as temp_dir:
|
||||||
path = os.path.join(temp_dir, to_download[0]["name"])
|
path = os.path.join(temp_dir, to_download[0]["name"])
|
||||||
|
|
|
@ -399,6 +399,7 @@ class UploadSerializer(serializers.ModelSerializer):
|
||||||
"import_date",
|
"import_date",
|
||||||
"import_status",
|
"import_status",
|
||||||
"privacy_level",
|
"privacy_level",
|
||||||
|
"third_party_provider",
|
||||||
]
|
]
|
||||||
|
|
||||||
read_only_fields = [
|
read_only_fields = [
|
||||||
|
|
|
@ -18,6 +18,7 @@ from rest_framework import views, viewsets
|
||||||
from rest_framework.decorators import action
|
from rest_framework.decorators import action
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
|
|
||||||
|
from config import plugins
|
||||||
from funkwhale_api.common import decorators as common_decorators
|
from funkwhale_api.common import decorators as common_decorators
|
||||||
from funkwhale_api.common import permissions as common_permissions
|
from funkwhale_api.common import permissions as common_permissions
|
||||||
from funkwhale_api.common import preferences
|
from funkwhale_api.common import preferences
|
||||||
|
@ -820,6 +821,27 @@ class UploadViewSet(
|
||||||
status=200,
|
status=200,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@action(methods=["post"], detail=False, url_path="trigger-download")
|
||||||
|
def trigger_download(self, request, *args, **kwargs):
|
||||||
|
qs = self.get_queryset()
|
||||||
|
track = models.Track.objects.get(pk=request.data["track"])
|
||||||
|
actor = utils.get_actor_from_request(self.request)
|
||||||
|
tp_upload = models.Upload.objects.filter(
|
||||||
|
track=track, third_party_provider__isnull=False
|
||||||
|
)
|
||||||
|
if tp_upload.exists():
|
||||||
|
return Response(
|
||||||
|
serializers.UploadSerializer(tp_upload.first()).data,
|
||||||
|
status=200,
|
||||||
|
)
|
||||||
|
if not qs.filter(track=track).exists():
|
||||||
|
plugins.trigger_hook(
|
||||||
|
plugins.TRIGGER_THIRD_PARTY_UPLOAD,
|
||||||
|
track=track,
|
||||||
|
actor=actor,
|
||||||
|
)
|
||||||
|
return Response(status=404)
|
||||||
|
|
||||||
@action(methods=["post"], detail=False)
|
@action(methods=["post"], detail=False)
|
||||||
def action(self, request, *args, **kwargs):
|
def action(self, request, *args, **kwargs):
|
||||||
queryset = self.get_queryset()
|
queryset = self.get_queryset()
|
||||||
|
|
|
@ -3,7 +3,7 @@ import type { Track, Artist, Album, Playlist, Library, Channel, Actor } from '~/
|
||||||
import type { components } from '~/generated/types'
|
import type { components } from '~/generated/types'
|
||||||
import type { PlayOptionsProps } from '~/composables/audio/usePlayOptions'
|
import type { PlayOptionsProps } from '~/composables/audio/usePlayOptions'
|
||||||
|
|
||||||
import { computed, ref } from 'vue'
|
import { computed, ref, watch } from 'vue'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
import usePlayOptions from '~/composables/audio/usePlayOptions'
|
import usePlayOptions from '~/composables/audio/usePlayOptions'
|
||||||
import useReport from '~/composables/moderation/useReport'
|
import useReport from '~/composables/moderation/useReport'
|
||||||
|
@ -14,6 +14,7 @@ import Button from '~/components/ui/Button.vue'
|
||||||
import OptionsButton from '~/components/ui/button/Options.vue'
|
import OptionsButton from '~/components/ui/button/Options.vue'
|
||||||
import Popover from '~/components/ui/Popover.vue'
|
import Popover from '~/components/ui/Popover.vue'
|
||||||
import PopoverItem from '~/components/ui/popover/PopoverItem.vue'
|
import PopoverItem from '~/components/ui/popover/PopoverItem.vue'
|
||||||
|
import axios from 'axios'
|
||||||
|
|
||||||
interface Props extends PlayOptionsProps {
|
interface Props extends PlayOptionsProps {
|
||||||
split?: boolean
|
split?: boolean
|
||||||
|
@ -103,10 +104,36 @@ const labels = computed(() => ({
|
||||||
PlaylistUploadGranted: t('components.audio.PlayButton.button.PlaylistUploadGranted'),
|
PlaylistUploadGranted: t('components.audio.PlayButton.button.PlaylistUploadGranted'),
|
||||||
PlaylistUploadPending:t('components.audio.PlayButton.button.PlaylistUploadPending'),
|
PlaylistUploadPending:t('components.audio.PlayButton.button.PlaylistUploadPending'),
|
||||||
PlaylistUploadNotRequest: t('components.audio.PlayButton.button.PlaylistUploadNotRequest'),
|
PlaylistUploadNotRequest: t('components.audio.PlayButton.button.PlaylistUploadNotRequest'),
|
||||||
PlaylistUploadTooltip: t('components.audio.PlayButton.button.PlaylistUploadTooltip')
|
PlaylistUploadTooltip: t('components.audio.PlayButton.button.PlaylistUploadTooltip'),
|
||||||
|
thirdPartyDownload: t('components.audio.PlayButton.button.thirdPartyDownload'),
|
||||||
|
thirdPartyDownloadTooltip: t('components.audio.PlayButton.button.thirdPartyDownload'),
|
||||||
|
thirdPartyDownloadTriggered: t('components.audio.PlayButton.button.thirdPartyDownloadTriggered')
|
||||||
|
|
||||||
}))
|
}))
|
||||||
|
|
||||||
const isOpen = ref(false)
|
const isOpen = ref(false)
|
||||||
|
const uploads = ref<components['schemas']['UploadForOwner'][]>([])
|
||||||
|
|
||||||
|
const thirdPartyUpload = computed(() => {
|
||||||
|
if (uploads.value?.find(upload => 'third_party_provider' in upload)) { return false } else { return true }
|
||||||
|
})
|
||||||
|
|
||||||
|
const triggerThirdPartyHook = async () => {
|
||||||
|
const response = await axios.post(
|
||||||
|
'uploads/trigger-download',
|
||||||
|
{ track: props.track?.id }
|
||||||
|
);
|
||||||
|
|
||||||
|
if (response.status === 404) {
|
||||||
|
uploads.value.push({ third_party_upload: "triggered" });
|
||||||
|
return null;
|
||||||
|
} else if (response.status === 200) {
|
||||||
|
console.log("uploads 400 (response.dat ", response.data)
|
||||||
|
uploads.value.push(response.data)
|
||||||
|
return response.data;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
triggerThirdPartyHook()
|
||||||
|
|
||||||
const playlistLibraryFollowInfo = computed(() => {
|
const playlistLibraryFollowInfo = computed(() => {
|
||||||
const playlist = props.playlist;
|
const playlist = props.playlist;
|
||||||
|
@ -246,7 +273,22 @@ const playlistLibraryFollowInfo = computed(() => {
|
||||||
{{ t('components.audio.PlayButton.button.trackDetails') }}
|
{{ t('components.audio.PlayButton.button.trackDetails') }}
|
||||||
</span>
|
</span>
|
||||||
</PopoverItem>
|
</PopoverItem>
|
||||||
|
<PopoverItem
|
||||||
|
v-if="!playable && thirdPartyUpload"
|
||||||
|
:title="labels.thirdPartyDownloadTooltip"
|
||||||
|
icon="bi-cloud-download"
|
||||||
|
@click.stop.prevent="triggerThirdPartyHook();"
|
||||||
|
>
|
||||||
|
{{ labels.thirdPartyDownload }}
|
||||||
|
</PopoverItem>
|
||||||
|
<PopoverItem
|
||||||
|
v-else-if="!playable && !thirdPartyUpload"
|
||||||
|
:title="labels.thirdPartyDownloadTooltip"
|
||||||
|
:disabled="true"
|
||||||
|
icon="bi-cloud-download"
|
||||||
|
>
|
||||||
|
{{ labels.thirdPartyDownloadTriggered }}
|
||||||
|
</PopoverItem>
|
||||||
<hr v-if="filterableArtist || Object.keys(getReportableObjects({ track, album, artist, playlist, account, channel })).length > 0">
|
<hr v-if="filterableArtist || Object.keys(getReportableObjects({ track, album, artist, playlist, account, channel })).length > 0">
|
||||||
|
|
||||||
<PopoverItem
|
<PopoverItem
|
||||||
|
|
|
@ -228,7 +228,6 @@ export default (props: PlayOptionsProps) => {
|
||||||
return response;
|
return response;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
playable,
|
playable,
|
||||||
filterableArtist,
|
filterableArtist,
|
||||||
|
|
|
@ -2895,6 +2895,22 @@ export interface paths {
|
||||||
patch: operations["partial_update_upload_bulk_update"];
|
patch: operations["partial_update_upload_bulk_update"];
|
||||||
trace?: never;
|
trace?: never;
|
||||||
};
|
};
|
||||||
|
"/api/v1/uploads/trigger-download/": {
|
||||||
|
parameters: {
|
||||||
|
query?: never;
|
||||||
|
header?: never;
|
||||||
|
path?: never;
|
||||||
|
cookie?: never;
|
||||||
|
};
|
||||||
|
get?: never;
|
||||||
|
put?: never;
|
||||||
|
post: operations["create_upload_trigger_download"];
|
||||||
|
delete?: never;
|
||||||
|
options?: never;
|
||||||
|
head?: never;
|
||||||
|
patch?: never;
|
||||||
|
trace?: never;
|
||||||
|
};
|
||||||
"/api/v1/users/{username}/": {
|
"/api/v1/users/{username}/": {
|
||||||
parameters: {
|
parameters: {
|
||||||
query?: never;
|
query?: never;
|
||||||
|
@ -6019,6 +6035,22 @@ export interface paths {
|
||||||
patch: operations["partial_update_upload_bulk_update_2"];
|
patch: operations["partial_update_upload_bulk_update_2"];
|
||||||
trace?: never;
|
trace?: never;
|
||||||
};
|
};
|
||||||
|
"/api/v2/uploads/trigger-download/": {
|
||||||
|
parameters: {
|
||||||
|
query?: never;
|
||||||
|
header?: never;
|
||||||
|
path?: never;
|
||||||
|
cookie?: never;
|
||||||
|
};
|
||||||
|
get?: never;
|
||||||
|
put?: never;
|
||||||
|
post: operations["create_upload_trigger_download_2"];
|
||||||
|
delete?: never;
|
||||||
|
options?: never;
|
||||||
|
head?: never;
|
||||||
|
patch?: never;
|
||||||
|
trace?: never;
|
||||||
|
};
|
||||||
"/api/v2/users/{username}/": {
|
"/api/v2/users/{username}/": {
|
||||||
parameters: {
|
parameters: {
|
||||||
query?: never;
|
query?: never;
|
||||||
|
@ -8472,6 +8504,7 @@ export interface components {
|
||||||
/** @default pending */
|
/** @default pending */
|
||||||
import_status: components["schemas"]["ImportStatusEnum"];
|
import_status: components["schemas"]["ImportStatusEnum"];
|
||||||
privacy_level?: components["schemas"]["LibraryPrivacyLevelEnum"];
|
privacy_level?: components["schemas"]["LibraryPrivacyLevelEnum"];
|
||||||
|
third_party_provider?: string | null;
|
||||||
import_metadata?: components["schemas"]["ImportMetadataRequest"];
|
import_metadata?: components["schemas"]["ImportMetadataRequest"];
|
||||||
import_reference?: string;
|
import_reference?: string;
|
||||||
source?: string | null;
|
source?: string | null;
|
||||||
|
@ -8893,6 +8926,7 @@ export interface components {
|
||||||
/** @default pending */
|
/** @default pending */
|
||||||
import_status: components["schemas"]["ImportStatusEnum"];
|
import_status: components["schemas"]["ImportStatusEnum"];
|
||||||
privacy_level?: components["schemas"]["LibraryPrivacyLevelEnum"];
|
privacy_level?: components["schemas"]["LibraryPrivacyLevelEnum"];
|
||||||
|
third_party_provider?: string | null;
|
||||||
readonly import_details: unknown;
|
readonly import_details: unknown;
|
||||||
import_metadata?: components["schemas"]["ImportMetadata"];
|
import_metadata?: components["schemas"]["ImportMetadata"];
|
||||||
import_reference?: string;
|
import_reference?: string;
|
||||||
|
@ -8907,6 +8941,7 @@ export interface components {
|
||||||
/** @default pending */
|
/** @default pending */
|
||||||
import_status: components["schemas"]["ImportStatusEnum"];
|
import_status: components["schemas"]["ImportStatusEnum"];
|
||||||
privacy_level?: components["schemas"]["LibraryPrivacyLevelEnum"];
|
privacy_level?: components["schemas"]["LibraryPrivacyLevelEnum"];
|
||||||
|
third_party_provider?: string | null;
|
||||||
import_metadata?: components["schemas"]["ImportMetadataRequest"];
|
import_metadata?: components["schemas"]["ImportMetadataRequest"];
|
||||||
import_reference?: string;
|
import_reference?: string;
|
||||||
source?: string | null;
|
source?: string | null;
|
||||||
|
@ -15758,6 +15793,32 @@ export interface operations {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
create_upload_trigger_download: {
|
||||||
|
parameters: {
|
||||||
|
query?: never;
|
||||||
|
header?: never;
|
||||||
|
path?: never;
|
||||||
|
cookie?: never;
|
||||||
|
};
|
||||||
|
requestBody: {
|
||||||
|
content: {
|
||||||
|
"application/json": components["schemas"]["UploadForOwnerRequest"];
|
||||||
|
"application/x-www-form-urlencoded": components["schemas"]["UploadForOwnerRequest"];
|
||||||
|
"multipart/form-data": components["schemas"]["UploadForOwnerRequest"];
|
||||||
|
"application/activity+json": components["schemas"]["UploadForOwnerRequest"];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
responses: {
|
||||||
|
200: {
|
||||||
|
headers: {
|
||||||
|
[name: string]: unknown;
|
||||||
|
};
|
||||||
|
content: {
|
||||||
|
"application/json": components["schemas"]["UploadForOwner"];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
update_user: {
|
update_user: {
|
||||||
parameters: {
|
parameters: {
|
||||||
query?: never;
|
query?: never;
|
||||||
|
@ -22917,6 +22978,32 @@ export interface operations {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
create_upload_trigger_download_2: {
|
||||||
|
parameters: {
|
||||||
|
query?: never;
|
||||||
|
header?: never;
|
||||||
|
path?: never;
|
||||||
|
cookie?: never;
|
||||||
|
};
|
||||||
|
requestBody: {
|
||||||
|
content: {
|
||||||
|
"application/json": components["schemas"]["UploadForOwnerRequest"];
|
||||||
|
"application/x-www-form-urlencoded": components["schemas"]["UploadForOwnerRequest"];
|
||||||
|
"multipart/form-data": components["schemas"]["UploadForOwnerRequest"];
|
||||||
|
"application/activity+json": components["schemas"]["UploadForOwnerRequest"];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
responses: {
|
||||||
|
200: {
|
||||||
|
headers: {
|
||||||
|
[name: string]: unknown;
|
||||||
|
};
|
||||||
|
content: {
|
||||||
|
"application/json": components["schemas"]["UploadForOwner"];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
update_user_3: {
|
update_user_3: {
|
||||||
parameters: {
|
parameters: {
|
||||||
query?: never;
|
query?: never;
|
||||||
|
|
|
@ -492,7 +492,10 @@
|
||||||
"playTracks": "Play tracks",
|
"playTracks": "Play tracks",
|
||||||
"report": "Report…",
|
"report": "Report…",
|
||||||
"startRadio": "Play similar songs",
|
"startRadio": "Play similar songs",
|
||||||
"trackDetails": "Track details"
|
"trackDetails": "Track details",
|
||||||
|
"thirdPartyDownload": "Try to download from third-party service",
|
||||||
|
"thirdPartyDownloadTooltip": "This relies on installed plugins and may not work on all pods.",
|
||||||
|
"thirdPartyDownloadTriggered": "Download triggered, come back later"
|
||||||
},
|
},
|
||||||
"title": {
|
"title": {
|
||||||
"more": "More…",
|
"more": "More…",
|
||||||
|
|
Loading…
Reference in New Issue