feat (be podcast): fe connected to be, trying to download podcast episode, save it in cc_files and updating podcast_episodes
This commit is contained in:
parent
2fcde13ef5
commit
2dae6e07e7
10 changed files with 183 additions and 41 deletions
|
@ -7,6 +7,7 @@ use App\Helpers\LengthFormatter;
|
|||
use App\Lib\RabbitMQSender;
|
||||
use App\Models\File;
|
||||
use App\Models\TrackType;
|
||||
use App\Models\User;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
@ -48,10 +49,16 @@ class FileController extends Controller
|
|||
|
||||
$user = Auth::user();
|
||||
|
||||
$apiKey = $request->header('php-auth-user');
|
||||
|
||||
//Accept request only from logged-in users
|
||||
if (!$user) {
|
||||
if ($apiKey != 'some_secret_api_key') {
|
||||
throw new \Exception("You must be logged in");
|
||||
}
|
||||
//ToDo: check how to work in Legacy, getting user in this way is quite horrible
|
||||
$user = User::where('type','=','P')->orderBy('id','ASC')->first();
|
||||
}
|
||||
|
||||
//Mime type list: https://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types
|
||||
$request->validate([
|
||||
|
|
|
@ -53,12 +53,13 @@ class PodcastController extends Controller
|
|||
return $xml->channel;
|
||||
}
|
||||
|
||||
public function getEpisodes(Request $request)
|
||||
{
|
||||
public function loadPodcastDataFromXml(Request $request) {
|
||||
$xml = simplexml_load_file($request->url, null, LIBXML_NOCDATA);
|
||||
$xmlArray = (array) $xml->channel;
|
||||
//episodes are stored in `item` array
|
||||
return $xmlArray['item'];
|
||||
return json_encode([
|
||||
'podcast' => $xmlArray,
|
||||
'episodes' => $xmlArray['item']
|
||||
]);
|
||||
}
|
||||
|
||||
protected function save(Request $request)
|
||||
|
|
|
@ -38,6 +38,17 @@ class PodcastEpisodeController extends Controller
|
|||
}
|
||||
}
|
||||
|
||||
public function test(Request $request) {
|
||||
if(isset($request->file)) {
|
||||
$file = (new FileController())->store($request);
|
||||
$file = json_decode($file);
|
||||
$episode = PodcastEpisode::where('file_id','=',null)
|
||||
->where('episode_title','=', $file->track_title)->firstOrFail();
|
||||
$episode->fill(['file_id' => $file->id])->save();
|
||||
}
|
||||
return $request;
|
||||
}
|
||||
|
||||
private function downloadPodcastEpisode(Request $request) {
|
||||
$request->validate([
|
||||
'podcast_id' => 'required',
|
||||
|
|
|
@ -14,6 +14,7 @@ podcastStore.loadPodcast(basePodcast());
|
|||
const { items, listData, headers, selected, loading, search, getItems, editItem, deleteItem } = podcast_page();
|
||||
const url = ref('');
|
||||
const itemEdited = ref(basePodcast());
|
||||
const episodes = ref([]);
|
||||
const bulk = ref(false);
|
||||
const dialog = reactive({
|
||||
open: false,
|
||||
|
@ -21,6 +22,7 @@ const dialog = reactive({
|
|||
title: '',
|
||||
text: ''
|
||||
});
|
||||
const dialogLoading = ref(false);
|
||||
|
||||
const openDialog = (type, title = '', text = '', bulk = false) => {
|
||||
dialog.open = true
|
||||
|
@ -47,12 +49,22 @@ const confirm = (confirm, bulk) => {
|
|||
}
|
||||
}
|
||||
|
||||
const confirmAdd = (confirm) => {
|
||||
const confirmAdd = async (confirm) => {
|
||||
if (confirm) {
|
||||
podcastStore.updateField({key: 'url', value: url});
|
||||
console.log(podcastStore);
|
||||
dialogLoading.value = true;
|
||||
await axios.get('/rss_podcast_load', {
|
||||
params: {
|
||||
url: url.value,
|
||||
}
|
||||
}).then(res => {
|
||||
podcastStore.updateField({key: 'title', value: res.data.podcast.title});
|
||||
podcastStore.updateField({key: 'url', value: url});
|
||||
podcastStore.currentPodcastEpisodes = res.data.episodes;
|
||||
//episodes.value = res.data.episodes;
|
||||
closeDialog();
|
||||
dialogLoading.value = false;
|
||||
})
|
||||
}
|
||||
closeDialog()
|
||||
}
|
||||
|
||||
const edit = (item) => {
|
||||
|
@ -60,42 +72,46 @@ const edit = (item) => {
|
|||
}
|
||||
|
||||
const cancel = (item) => {
|
||||
bulk.value = Array.isArray(item)
|
||||
itemEdited.value = item
|
||||
bulk.value = Array.isArray(item);
|
||||
itemEdited.value = item;
|
||||
openDialog(
|
||||
'delete',
|
||||
'Cancella',
|
||||
bulk.value ? 'Vuoi cancellare i podcast selezionati?' : 'Vuoi cancellare il podcast selezionato?'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
const confirmDelete = (confirm, bulk) => {
|
||||
if (confirm) {
|
||||
if (!bulk) {
|
||||
deleteItem(itemEdited.value.id)
|
||||
deleteItem(itemEdited.value.id);
|
||||
} else {
|
||||
itemEdited.value.forEach(el => {
|
||||
deleteItem(el.id)
|
||||
deleteItem(el.id);
|
||||
})
|
||||
}
|
||||
}
|
||||
closeDialog()
|
||||
closeDialog();
|
||||
}
|
||||
|
||||
const closeDialog = () => {
|
||||
dialog.open = false
|
||||
dialog.open = false;
|
||||
itemEdited.value = basePodcast();
|
||||
}
|
||||
|
||||
const updateSearch = (text) => {
|
||||
search.value = text
|
||||
search.value = text;
|
||||
}
|
||||
|
||||
const resetItemEdited = () => {
|
||||
podcastStore.currentPodcast = basePodcast();
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<PodcastEditor
|
||||
v-if="podcastStore.currentPodcast.url != '' && podcastStore.currentPodcast.url != null"
|
||||
@go-back="podcastStore.currentPodcast = basePodcast()"
|
||||
@go-back="resetItemEdited"
|
||||
/>
|
||||
<Table
|
||||
v-else
|
||||
|
@ -126,6 +142,7 @@ const updateSearch = (text) => {
|
|||
:bulk="bulk"
|
||||
@confirm="confirm"
|
||||
@after-leave="closeDialog"
|
||||
:loading="dialogLoading"
|
||||
>
|
||||
<VTextField
|
||||
label="Feed RSS"
|
||||
|
|
|
@ -3,33 +3,98 @@ import {useAuthStore} from "@/stores/auth.store.ts";
|
|||
import {usePodcastStore} from "@/stores/podcast.store.ts";
|
||||
import {podcast} from "@models/podcast/podcast.ts";
|
||||
import {podcast_episode_page} from "@/composables/content/podcastEpisode_page.ts";
|
||||
import {ref, watch} from "vue";
|
||||
import {onBeforeMount, reactive, ref, watch} from "vue";
|
||||
import axios from "axios";
|
||||
import ConfirmDelete from "@partials/dialogs/ConfirmDelete.vue";
|
||||
import {podcast_page} from "@/composables/content/podcast_page.ts";
|
||||
|
||||
const auth = useAuthStore();
|
||||
|
||||
const emit = defineEmits([
|
||||
'saveItem'
|
||||
'saveItem',
|
||||
'goBack'
|
||||
])
|
||||
|
||||
const podcastStore = usePodcastStore();
|
||||
const item = podcastStore.currentPodcast;
|
||||
|
||||
const { items, headers, loading, downloadEpisode, getItems } = podcast_episode_page(item.url);
|
||||
|
||||
const podcast_id = ref(item.id);
|
||||
console.log(item)
|
||||
|
||||
const podcastFields = podcast(item);
|
||||
const { items, headers, loading, downloadingEpisode, downloadEpisode } = podcast_episode_page(item.id, item.url);
|
||||
console.log(podcastFields())
|
||||
const { editItem } = podcast_page();
|
||||
|
||||
const episodes = ref([]);
|
||||
|
||||
const disabledSaveButton = ref(false)
|
||||
|
||||
const dialog = reactive({
|
||||
open: false,
|
||||
type: '',
|
||||
title: '',
|
||||
text: '',
|
||||
item: null
|
||||
})
|
||||
|
||||
const openDialog = (type, title = '', text = '', item = null) => {
|
||||
dialog.open = true
|
||||
dialog.type = type
|
||||
dialog.title = title
|
||||
dialog.text = text
|
||||
dialog.item = item
|
||||
}
|
||||
|
||||
const closeDialog = () => {
|
||||
dialog.open = false
|
||||
}
|
||||
|
||||
const checkError = (field, model) => {
|
||||
if (field.required) {
|
||||
// const error = field.required && (model === '' || model === null)
|
||||
// // disabledSaveButton.value = error
|
||||
// return error
|
||||
const error = field.required && (model === '' || model === null)
|
||||
disabledSaveButton.value = error
|
||||
return error
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
const checkDownload = (item) => {
|
||||
if (podcast_id.value > 0) {
|
||||
downloadEpisode(podcast_id.value, item);
|
||||
} else {
|
||||
openDialog(
|
||||
'save',
|
||||
'Salvataggio necessario',
|
||||
'Per procedere con il download dell\'episodio è necessario salvare il podcast. Confermi?',
|
||||
item
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const confirmSave = (confirm, bulk, row) => {
|
||||
console.log(confirm, row)
|
||||
if (confirm) {
|
||||
save(row);
|
||||
}
|
||||
closeDialog();
|
||||
}
|
||||
|
||||
const save = (row) => {
|
||||
console.log(row)
|
||||
// const errors
|
||||
editItem(item).then(res => {
|
||||
podcastStore.loadPodcast(res.podcast);
|
||||
podcast_id.value = res.podcast.id;
|
||||
console.log(podcast_id.value);
|
||||
//Check if row is effectively a podcast episode object using his `title` property
|
||||
if (row.title) {
|
||||
downloadEpisode(podcast_id.value, row);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
watch(items, (newItems, oldItems) => {
|
||||
console.log(newItems, oldItems)
|
||||
if (item.id > 0) {
|
||||
|
@ -54,6 +119,10 @@ watch(items, (newItems, oldItems) => {
|
|||
episodes.value = newItems;
|
||||
}, {deep: true});
|
||||
|
||||
onBeforeMount(() => {
|
||||
getItems().then(title => podcastStore.updateField({'title': title}));
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@ -66,7 +135,6 @@ watch(items, (newItems, oldItems) => {
|
|||
:value="field.value ? field.value : field.type == 'checkbox' ? true : null"
|
||||
:disabled="field.disabled"
|
||||
@update:modelValue="checkError(field, item[key])"
|
||||
@update-property="updateProperty"
|
||||
:error="checkError(field, item[key])"
|
||||
rows="2"
|
||||
:items="field.items"
|
||||
|
@ -100,7 +168,6 @@ watch(items, (newItems, oldItems) => {
|
|||
{{ item.short_description }}
|
||||
</template>
|
||||
<template v-slot:item.imported="{ item }">
|
||||
{{item.imported}}
|
||||
<v-icon
|
||||
class="me-2 spinning"
|
||||
size="small"
|
||||
|
@ -119,7 +186,7 @@ watch(items, (newItems, oldItems) => {
|
|||
class="me-2 text-center"
|
||||
size="small"
|
||||
v-else
|
||||
@click="downloadEpisode(item)"
|
||||
@click="checkDownload(item)"
|
||||
>
|
||||
mdi-download-box
|
||||
</v-icon>
|
||||
|
@ -127,6 +194,17 @@ watch(items, (newItems, oldItems) => {
|
|||
</VDataTable>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-dialog v-model="dialog.open">
|
||||
<ConfirmDelete
|
||||
v-if="dialog.type === 'save'"
|
||||
:title="dialog.title"
|
||||
:text="dialog.text"
|
||||
:bulk="false"
|
||||
:item="dialog.item"
|
||||
@confirm="confirmSave"
|
||||
@after-leave="closeDialog"
|
||||
/>
|
||||
</v-dialog>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
|
|
@ -2,10 +2,26 @@
|
|||
const props = defineProps({
|
||||
title: String,
|
||||
text: String,
|
||||
bulk: Boolean
|
||||
confirm_text: {
|
||||
type: String,
|
||||
required: false
|
||||
},
|
||||
cancel_text: {
|
||||
type: String,
|
||||
required: false
|
||||
},
|
||||
item: {
|
||||
type: Object,
|
||||
required: false
|
||||
},
|
||||
bulk: Boolean,
|
||||
loading: {
|
||||
type: Boolean,
|
||||
required: false
|
||||
},
|
||||
})
|
||||
|
||||
console.log(props.bulk)
|
||||
console.log(props.loading)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@ -20,7 +36,8 @@ console.log(props.bulk)
|
|||
<v-card-actions>
|
||||
<v-btn
|
||||
color="primary"
|
||||
@click="$emit('confirm',true, props.bulk)"
|
||||
@click="$emit('confirm',true, props.bulk, item)"
|
||||
:loading="loading"
|
||||
>Conferma</v-btn>
|
||||
<v-btn
|
||||
color="accent"
|
||||
|
|
|
@ -70,7 +70,7 @@ export const deletePodcast = async (podcastIds: Number[]) => {
|
|||
|
||||
export function podcast(item) {
|
||||
const visibleFields = {
|
||||
name: {
|
||||
title: {
|
||||
title: 'Nome del podcast',
|
||||
required: true,
|
||||
disabled: false
|
||||
|
|
|
@ -2,8 +2,9 @@ import {reactive, ref} from "vue";
|
|||
import axios, {type AxiosResponse} from "axios";
|
||||
import {type PodcastEpisode, PodcastEpisodeTableHeader} from "@models/podcast/podcastEpisode.ts";
|
||||
import {DateTime} from "luxon";
|
||||
import {usePodcastStore} from "@/stores/podcast.store.ts";
|
||||
|
||||
export function podcast_episode_page(podcast_id: Number, url: String) {
|
||||
export function podcast_episode_page(url: String) {
|
||||
const items = ref([]);
|
||||
const loading = ref(false);
|
||||
const listData = reactive({
|
||||
|
@ -37,15 +38,20 @@ export function podcast_episode_page(podcast_id: Number, url: String) {
|
|||
|
||||
const getItems = async () => {
|
||||
loading.value = true;
|
||||
console.log(url)
|
||||
return await axios.get(`/rss_podcast_episodes`, {
|
||||
return await axios.get(`/rss_podcast_load`, {
|
||||
params: {
|
||||
podcast_id: podcast_id,
|
||||
url: url
|
||||
}
|
||||
}).then( async (podcastEpisodesList: AxiosResponse) => {
|
||||
// console.log(podcastEpisodesList, podcast_id);
|
||||
const episodes = podcastEpisodesList.data;
|
||||
console.log(podcastEpisodesList);
|
||||
// const podcastStore = usePodcastStore();
|
||||
// podcastStore.updateField({
|
||||
// 'title': podcastEpisodesList.data.podcast.title,
|
||||
// 'language': podcastEpisodesList.data.podcast.language,
|
||||
// 'link': podcastEpisodesList.data.podcast.link
|
||||
// })
|
||||
const episodes = podcastEpisodesList.data.episodes;
|
||||
|
||||
items.value = await episodes.map(element => {
|
||||
element.imported = -1;
|
||||
element.short_description = '';
|
||||
|
@ -59,7 +65,9 @@ export function podcast_episode_page(podcast_id: Number, url: String) {
|
|||
});
|
||||
return element;
|
||||
});
|
||||
|
||||
loading.value = false;
|
||||
return podcastEpisodesList.data.podcast.title;
|
||||
}).catch((error: Error) => {
|
||||
console.log("Error: " + error);
|
||||
});
|
||||
|
@ -67,7 +75,7 @@ export function podcast_episode_page(podcast_id: Number, url: String) {
|
|||
|
||||
}
|
||||
|
||||
const downloadEpisode = async (item) => {
|
||||
const downloadEpisode = async (podcast_id, item) => {
|
||||
console.log(item.enclosure["@attributes"].url)
|
||||
return await axios.post('/podcast_episode', {
|
||||
podcast_id: podcast_id,
|
||||
|
@ -80,7 +88,8 @@ export function podcast_episode_page(podcast_id: Number, url: String) {
|
|||
console.log("Error: "+error);
|
||||
});
|
||||
}
|
||||
|
||||
getItems();
|
||||
|
||||
return { items, listData, headers, loading, downloadingEpisode, downloadEpisode }
|
||||
return { items, listData, headers, loading, downloadingEpisode, getItems, downloadEpisode }
|
||||
}
|
|
@ -5,7 +5,7 @@ import type {PodcastEpisode} from "@models/podcast/podcastEpisode.ts";
|
|||
export const usePodcastStore = defineStore('podcast', {
|
||||
state: () => ({
|
||||
currentPodcast: {} as Podcast,
|
||||
currentPodcastEpisodes: {} as PodcastEpisode,
|
||||
currentPodcastEpisodes: {} as PodcastEpisode[],
|
||||
}),
|
||||
actions: {
|
||||
loadPodcast(podcastData: Podcast) {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<?php
|
||||
|
||||
use App\Http\Controllers\FileController;
|
||||
use App\Http\Controllers\PodcastEpisodeController;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Controllers\TestControllerXdebug;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
@ -17,3 +18,4 @@ use Illuminate\Support\Facades\Route;
|
|||
*/
|
||||
|
||||
Route::middleware('parsejson')->put('/media/{id}', [FileController::class, 'update'])->name('media.update');
|
||||
Route::post('/media', [PodcastEpisodeController::class, 'test'])->name('media.podcast');
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue