mirror of
https://github.com/AzuraCast/AzuraCast.git
synced 2024-06-21 16:37:06 +00:00
Show playlist import results on-screen.
This commit is contained in:
parent
acd9b5842f
commit
7a50278938
|
@ -1,6 +1,32 @@
|
|||
<template>
|
||||
<b-modal id="import_modal" ref="modal" :title="langTitle">
|
||||
<b-form class="form" @submit.prevent="doSubmit">
|
||||
<div v-if="results">
|
||||
<p class="card-text">{{ results.message }}</p>
|
||||
|
||||
<b-table-simple striped responsive style="max-height: 300px; overflow-y: scroll;">
|
||||
<b-thead>
|
||||
<b-tr>
|
||||
<b-th class="p-2">
|
||||
<translate key="lang_playlist_results_original">Original Path</translate>
|
||||
<br>
|
||||
<translate key="lang_playlist_results_matched">Matched</translate>
|
||||
</b-th>
|
||||
</b-tr>
|
||||
</b-thead>
|
||||
<b-tbody>
|
||||
<b-tr v-for="row in results.import_results" :key="row.path">
|
||||
<b-td class="p-2 text-monospace" style="overflow-x: auto;">
|
||||
<pre class="mb-0">{{ row.path }}</pre>
|
||||
<pre v-if="row.match" class="mb-0 text-success">{{ row.match }}</pre>
|
||||
<pre v-else class="mb-0 text-danger">
|
||||
<translate key="lang_playlist_results_no_match">No Match</translate>
|
||||
</pre>
|
||||
</b-td>
|
||||
</b-tr>
|
||||
</b-tbody>
|
||||
</b-table-simple>
|
||||
</div>
|
||||
<b-form v-else class="form" @submit.prevent="doSubmit">
|
||||
<b-form-group label-for="import_modal_playlist_file">
|
||||
<template #label>
|
||||
<translate key="lang_form_playlist_file">Select PLS/M3U File to Import</translate>
|
||||
|
@ -17,7 +43,7 @@
|
|||
<b-button variant="default" type="button" @click="close">
|
||||
<translate key="lang_btn_close">Close</translate>
|
||||
</b-button>
|
||||
<b-button variant="primary" type="submit" @click="doSubmit">
|
||||
<b-button v-if="!results" variant="primary" type="submit" @click="doSubmit">
|
||||
<translate key="lang_btn_import">Import from PLS/M3U</translate>
|
||||
</b-button>
|
||||
</template>
|
||||
|
@ -33,7 +59,8 @@ export default {
|
|||
data () {
|
||||
return {
|
||||
importPlaylistUrl: null,
|
||||
playlistFile: null
|
||||
playlistFile: null,
|
||||
results: null,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
|
@ -56,16 +83,17 @@ export default {
|
|||
this.axios.post(this.importPlaylistUrl, formData)
|
||||
).then((resp) => {
|
||||
if (resp.data.success) {
|
||||
this.results = resp.data;
|
||||
|
||||
this.$notifySuccess(resp.data.message);
|
||||
} else {
|
||||
this.$notifyError(resp.data.message);
|
||||
this.close();
|
||||
}
|
||||
}).finally(() => {
|
||||
this.$emit('relist');
|
||||
this.close();
|
||||
});
|
||||
},
|
||||
close () {
|
||||
this.$emit('relist');
|
||||
this.$refs.modal.hide();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,6 +44,8 @@ class ImportAction extends AbstractPlaylistsAction
|
|||
$totalPaths = count($paths);
|
||||
$foundPaths = 0;
|
||||
|
||||
$importResults = [];
|
||||
|
||||
if (!empty($paths)) {
|
||||
$storageLocation = $request->getStation()->getMediaStorageLocation();
|
||||
|
||||
|
@ -75,7 +77,7 @@ class ImportAction extends AbstractPlaylistsAction
|
|||
// Run all paths against the lookup list of hashes.
|
||||
$matches = [];
|
||||
|
||||
foreach ($paths as $path_raw) {
|
||||
$matchFunction = static function ($path_raw) use ($mediaLookup, $basenameLookup) {
|
||||
// De-Windows paths (if applicable)
|
||||
$path_raw = str_replace('\\', '/', $path_raw);
|
||||
|
||||
|
@ -89,15 +91,29 @@ class ImportAction extends AbstractPlaylistsAction
|
|||
for ($i = 2, $iMax = count($pathParts); $i <= $iMax; $i++) {
|
||||
$path = implode('/', array_slice($pathParts, 0 - $i));
|
||||
if (isset($mediaLookup[$path])) {
|
||||
$matches[] = $mediaLookup[$path];
|
||||
continue 2;
|
||||
return [$path, $mediaLookup[$path]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Attempt basename-only matching
|
||||
if (isset($basenameLookup[$basename])) {
|
||||
$matches[] = $basenameLookup[$basename];
|
||||
return [$basename, $basenameLookup[$basename]];
|
||||
}
|
||||
|
||||
return [null, null];
|
||||
};
|
||||
|
||||
foreach ($paths as $path_raw) {
|
||||
[$matchedPath, $match] = $matchFunction($path_raw);
|
||||
|
||||
$importResults[] = [
|
||||
'path' => $path_raw,
|
||||
'match' => $matchedPath,
|
||||
];
|
||||
|
||||
if (null !== $match) {
|
||||
$matches[] = $match;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -105,7 +121,7 @@ class ImportAction extends AbstractPlaylistsAction
|
|||
if (!empty($matches)) {
|
||||
$matchedMediaRaw = $this->em->createQuery(
|
||||
<<<'DQL'
|
||||
SELECT sm
|
||||
SELECT sm
|
||||
FROM App\Entity\StationMedia sm
|
||||
WHERE sm.storage_location = :storageLocation AND sm.id IN (:matched_ids)
|
||||
DQL
|
||||
|
@ -137,13 +153,15 @@ class ImportAction extends AbstractPlaylistsAction
|
|||
}
|
||||
|
||||
return $response->withJson(
|
||||
new Entity\Api\Status(
|
||||
new Entity\Api\StationPlaylistImportResult(
|
||||
true,
|
||||
__(
|
||||
'Playlist successfully imported; %d of %d files were successfully matched.',
|
||||
$foundPaths,
|
||||
$totalPaths
|
||||
)
|
||||
),
|
||||
null,
|
||||
$importResults
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
21
src/Entity/Api/StationPlaylistImportResult.php
Normal file
21
src/Entity/Api/StationPlaylistImportResult.php
Normal file
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Entity\Api;
|
||||
|
||||
class StationPlaylistImportResult extends Status
|
||||
{
|
||||
public array $import_results = [];
|
||||
|
||||
public function __construct(
|
||||
bool $success = true,
|
||||
string $message = 'Changes saved successfully.',
|
||||
?string $formatted_message = null,
|
||||
array $import_results = [],
|
||||
) {
|
||||
parent::__construct($success, $message, $formatted_message);
|
||||
|
||||
$this->import_results = $import_results;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user