mirror of
https://github.com/Arrowar/StreamingCommunity.git
synced 2025-06-07 20:15:24 +00:00
start implementing download select episodes for tv series (to be tested) + run black and eslint
This commit is contained in:
parent
e3c165c520
commit
ca4d9ddb31
@ -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()
|
||||||
|
@ -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);
|
||||||
|
@ -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 {
|
||||||
|
@ -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;
|
||||||
|
@ -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>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user