start implementing download select episodes for tv series (to be tested) + run black and eslint

This commit is contained in:
Francesco Grazioso 2024-05-11 12:50:11 +02:00
parent dd4089ed0e
commit 077bb1afd2
5 changed files with 84 additions and 29 deletions

View File

@ -57,6 +57,7 @@ class SearchView(viewsets.ViewSet):
try: try:
match self.type_media: match self.type_media:
case "TV": case "TV":
def stream_episodes(): def stream_episodes():
self.site_version, self.domain = get_version_and_domain() self.site_version, self.domain = get_version_and_domain()
@ -74,32 +75,43 @@ class SearchView(viewsets.ViewSet):
for i_season in range(1, seasons_count + 1): for i_season in range(1, seasons_count + 1):
video_source.obj_episode_manager.clear() video_source.obj_episode_manager.clear()
video_source.collect_title_season(i_season) video_source.collect_title_season(i_season)
episodes_count = video_source.obj_episode_manager.get_length() episodes_count = (
video_source.obj_episode_manager.get_length()
)
episodes[i_season] = {} episodes[i_season] = {}
for i_episode in range(1, episodes_count + 1): for i_episode in range(1, episodes_count + 1):
episode = video_source.obj_episode_manager.episodes[ episode = video_source.obj_episode_manager.episodes[
i_episode - 1 i_episode - 1
] ]
episodes[i_season][i_episode] = episode.__dict__ episodes[i_season][i_episode] = episode.__dict__
yield f'{json.dumps({"episodes": episodes})}\n\n' yield f'{json.dumps({"episodes": episodes})}\n\n'
response = StreamingHttpResponse(stream_episodes(), content_type='text/event-stream') response = StreamingHttpResponse(
stream_episodes(), content_type="text/event-stream"
)
return response return response
case "TV_ANIME": case "TV_ANIME":
def stream_episodes(): def stream_episodes():
episodes_downloader = EpisodeDownloader(self.media_id, self.media_slug) episodes_downloader = EpisodeDownloader(
self.media_id, self.media_slug
)
episoded_count = episodes_downloader.get_count_episodes() episoded_count = episodes_downloader.get_count_episodes()
for i in range(1, episoded_count + 1): for i in range(1, episoded_count + 1):
episode_info = episodes_downloader.get_info_episode(index_ep=i) episode_info = episodes_downloader.get_info_episode(
index_ep=i
)
episode_info["episode_id"] = i episode_info["episode_id"] = i
episode_info["episode_total"] = episoded_count episode_info["episode_total"] = episoded_count
print(f"Getting episode {i} of {episoded_count} info...") print(f"Getting episode {i} of {episoded_count} info...")
yield f'{json.dumps(episode_info)}\n\n' yield f"{json.dumps(episode_info)}\n\n"
response = StreamingHttpResponse(stream_episodes(), content_type='text/event-stream') response = StreamingHttpResponse(
stream_episodes(), content_type="text/event-stream"
)
return response return response
except Exception as e: except Exception as e:
@ -120,6 +132,7 @@ class DownloadView(viewsets.ViewSet):
self.media_slug = request.data.get("media_slug") self.media_slug = request.data.get("media_slug")
self.type_media = request.data.get("type_media").upper() self.type_media = request.data.get("type_media").upper()
self.download_id = request.data.get("download_id") self.download_id = request.data.get("download_id")
self.tv_series_episode_id = request.data.get("tv_series_episode_id")
if self.type_media in ["TV", "MOVIE"]: if self.type_media in ["TV", "MOVIE"]:
self.site_version, self.domain = get_version_and_domain() self.site_version, self.domain = get_version_and_domain()

View File

@ -1,8 +1,8 @@
import axios from 'axios'; import axios from "axios";
import type { AxiosResponse } from 'axios'; import type { AxiosResponse } from "axios";
import type {DownloadResponse, MediaItemResponse} from '@/api/interfaces'; import type { DownloadResponse, MediaItemResponse } from "@/api/interfaces";
const BASE_URL = 'http://localhost:8000/api'; const BASE_URL = "http://localhost:8000/api";
const api = axios.create({ const api = axios.create({
baseURL: BASE_URL, baseURL: BASE_URL,
@ -16,32 +16,57 @@ async function post<T>(url: string, data: any): Promise<AxiosResponse<T>> {
return api.post(url, data); return api.post(url, data);
} }
export default function search(query: string, type: string): Promise<AxiosResponse<MediaItemResponse>> { export default function search(
query: string,
type: string
): Promise<AxiosResponse<MediaItemResponse>> {
return get(`/search?search_terms=${query}&type=${type}`); return get(`/search?search_terms=${query}&type=${type}`);
} }
export async function getEpisodesInfo(mediaId: number, mediaSlug: string, mediaType: string): Promise<Response> { export async function getEpisodesInfo(
mediaId: number,
mediaSlug: string,
mediaType: string
): Promise<Response> {
const url = `/search/get_episodes_info?media_id=${mediaId}&media_slug=${mediaSlug}&type_media=${mediaType}`; const url = `/search/get_episodes_info?media_id=${mediaId}&media_slug=${mediaSlug}&type_media=${mediaType}`;
return fetch(`${BASE_URL}${url}`, { return fetch(`${BASE_URL}${url}`, {
method: 'GET', method: "GET",
headers: { headers: {
'Content-Type': 'text/event-stream', "Content-Type": "text/event-stream",
}, },
}); });
} }
async function downloadMedia(mediaId: number, mediaSlug: string, mediaType: string, downloadId?: number): Promise<AxiosResponse<DownloadResponse>> { async function downloadMedia(
mediaId: number,
mediaSlug: string,
mediaType: string,
downloadId?: number,
tvSeriesEpisodeId?: number
): Promise<AxiosResponse<DownloadResponse>> {
const url = `/download/`; const url = `/download/`;
const data = { const data = {
media_id: mediaId, media_id: mediaId,
media_slug: mediaSlug, media_slug: mediaSlug,
type_media: mediaType, type_media: mediaType,
download_id: downloadId, download_id: downloadId,
tv_series_episode_id: tvSeriesEpisodeId,
}; };
return post(url, data); return post(url, data);
} }
export const downloadFilm = (mediaId: number, mediaSlug: string) => downloadMedia(mediaId, mediaSlug, 'MOVIE'); export const downloadFilm = (mediaId: number, mediaSlug: string) =>
export const downloadTvSeries = (mediaId: number, mediaSlug: string, downloadId: number) => downloadMedia(mediaId, mediaSlug, 'TV', downloadId); downloadMedia(mediaId, mediaSlug, "MOVIE");
export const downloadAnimeFilm = (mediaId: number, mediaSlug: string) => downloadMedia(mediaId, mediaSlug, 'OVA'); export const downloadTvSeries = (
export const downloadAnimeSeries = (mediaId: number, mediaSlug: string, downloadId: number) => downloadMedia(mediaId, mediaSlug, 'TV_ANIME', downloadId); mediaId: number,
mediaSlug: string,
downloadId: number,
tvSeriesEpisodeId?: number
) => downloadMedia(mediaId, mediaSlug, "TV", downloadId, tvSeriesEpisodeId);
export const downloadAnimeFilm = (mediaId: number, mediaSlug: string) =>
downloadMedia(mediaId, mediaSlug, "OVA");
export const downloadAnimeSeries = (
mediaId: number,
mediaSlug: string,
downloadId: number
) => downloadMedia(mediaId, mediaSlug, "TV_ANIME", downloadId);

View File

@ -45,6 +45,7 @@ export interface Episode {
season_id: number; // TV Show exclusive season_id: number; // TV Show exclusive
created_by: any; // TV Show exclusive created_by: any; // TV Show exclusive
updated_at: string; // TV Show exclusive updated_at: string; // TV Show exclusive
season_index: number; // TV Show exclusive
} }
export interface Season { export interface Season {

View File

@ -1,5 +1,5 @@
import {downloadAnimeFilm, downloadAnimeSeries, downloadFilm, downloadTvSeries} from "@/api/api"; import {downloadAnimeFilm, downloadAnimeSeries, downloadFilm, downloadTvSeries} from "@/api/api";
import type {DownloadResponse, Episode, MediaItem} from "@/api/interfaces"; import type {DownloadResponse, Episode, MediaItem, Season} from "@/api/interfaces";
export const handleTVDownload = async (tvShowEpisodes: any[], item: MediaItem) => { export const handleTVDownload = async (tvShowEpisodes: any[], item: MediaItem) => {
alertDownload(); alertDownload();
@ -10,6 +10,15 @@ export const handleTVDownload = async (tvShowEpisodes: any[], item: MediaItem) =
} }
}; };
export const handleTVEpisodesDownload = async (episodes: Episode[], item: MediaItem) => {
alertDownload();
for (const episode of episodes) {
const i = episodes.indexOf(episode);
const res = (await downloadTvSeries(item.id, item.slug, episode.season_index + 1, i)).data;
handleDownloadError(res);
}
}
export const handleMovieDownload = async (item: MediaItem) => { export const handleMovieDownload = async (item: MediaItem) => {
alertDownload(); alertDownload();
const res = (await downloadFilm(item.id, item.slug)).data; const res = (await downloadFilm(item.id, item.slug)).data;

View File

@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import { useRoute } from 'vue-router' import { useRoute } from 'vue-router'
import type {Episode, MediaItem, SeasonResponse} from "@/api/interfaces"; import type {Episode, MediaItem, Season, SeasonResponse} from "@/api/interfaces";
import { onMounted, ref } from "vue"; import { onMounted, ref } from "vue";
import { getEpisodesInfo } from "@/api/api"; import { getEpisodesInfo } from "@/api/api";
import { import {
@ -9,7 +9,7 @@ import {
handleOVADownload, handleOVADownload,
handleTVAnimeDownload, handleTVAnimeDownload,
handleTvAnimeEpisodesDownload, handleTvAnimeEpisodesDownload,
handleTVDownload handleTVDownload, handleTVEpisodesDownload
} from "@/api/utils"; } from "@/api/utils";
const route = useRoute() const route = useRoute()
@ -64,10 +64,13 @@ const toggleEpisodeSelection = () => {
selectedEpisodes.value = [] selectedEpisodes.value = []
} }
const toggleEpisodeSelect = (episode: Episode) => { const toggleEpisodeSelect = (episode: Episode, seasonNumber?: number) => {
if (selectedEpisodes.value.includes(episode)) { if (selectedEpisodes.value.includes(episode)) {
selectedEpisodes.value = selectedEpisodes.value.filter(e => e !== episode) selectedEpisodes.value = selectedEpisodes.value.filter(e => e !== episode)
} else { } else {
if (seasonNumber) {
episode.season_index = seasonNumber
}
selectedEpisodes.value.push(episode) selectedEpisodes.value.push(episode)
} }
} }
@ -76,7 +79,7 @@ const downloadSelectedEpisodes = async () => {
try { try {
switch (item.type) { switch (item.type) {
case 'TV': case 'TV':
// await handleTVDownload(selectedEpisodes.value, item); await handleTVEpisodesDownload(selectedEpisodes.value, item);
case 'TV_ANIME': case 'TV_ANIME':
await handleTvAnimeEpisodesDownload(selectedEpisodes.value, item); await handleTvAnimeEpisodesDownload(selectedEpisodes.value, item);
break; break;
@ -167,10 +170,14 @@ const downloadAllItems = async () => {
<div v-else-if="item.type == 'TV'" v-for="(season, index) in tvShowEpisodes" class="season-item"> <div v-else-if="item.type == 'TV'" v-for="(season, index) in tvShowEpisodes" class="season-item">
<div class="season-title">Stagione {{ index + 1 }}</div> <div class="season-title">Stagione {{ index + 1 }}</div>
<div class="episode-container"> <div class="episode-container">
<div v-for="episode in season" :key="episode.id" class="episode-item"> <div v-for="episode in season" :key="episode.id">
<div class="episode-title"> <div class="episode-item"
Episodio {{ episode.number }} - :style="{ backgroundColor: selectedEpisodes.includes(episode) ? '#42b883' : '#333' }"
{{episode.name.slice(0, 40) + (episode.name.length > 39 ? '...' : '')}} @click="selectingEpisodes ? toggleEpisodeSelect(episode, index) : null">
<div class="episode-title">
Episodio {{ episode.number }} -
{{episode.name.slice(0, 40) + (episode.name.length > 39 ? '...' : '')}}
</div>
</div> </div>
</div> </div>
</div> </div>