forked from Ninjalama/streamyfin_mirror
240 lines
5.9 KiB
TypeScript
240 lines
5.9 KiB
TypeScript
import { itemRouter } from "@/components/common/TouchableItemRouter";
|
|
import {
|
|
BaseItemDto,
|
|
MediaSourceInfo,
|
|
} from "@jellyfin/sdk/lib/generated-client";
|
|
import axios from "axios";
|
|
import { writeToLog } from "./log";
|
|
import { DownloadedItem } from "@/providers/DownloadProvider";
|
|
import { MMKV } from "react-native-mmkv";
|
|
|
|
interface IJobInput {
|
|
deviceId?: string | null;
|
|
authHeader?: string | null;
|
|
url?: string | null;
|
|
}
|
|
|
|
export interface JobStatus {
|
|
id: string;
|
|
status:
|
|
| "queued"
|
|
| "optimizing"
|
|
| "completed"
|
|
| "failed"
|
|
| "cancelled"
|
|
| "downloading";
|
|
progress: number;
|
|
outputPath: string;
|
|
inputUrl: string;
|
|
deviceId: string;
|
|
itemId: string;
|
|
item: BaseItemDto;
|
|
speed?: number;
|
|
timestamp: Date;
|
|
base64Image?: string;
|
|
}
|
|
|
|
/**
|
|
* Fetches all jobs for a specific device.
|
|
*
|
|
* @param {IGetAllDeviceJobs} params - The parameters for the API request.
|
|
* @param {string} params.deviceId - The ID of the device to fetch jobs for.
|
|
* @param {string} params.authHeader - The authorization header for the API request.
|
|
* @param {string} params.url - The base URL for the API endpoint.
|
|
*
|
|
* @returns {Promise<JobStatus[]>} A promise that resolves to an array of job statuses.
|
|
*
|
|
* @throws {Error} Throws an error if the API request fails or returns a non-200 status code.
|
|
*/
|
|
export async function getAllJobsByDeviceId({
|
|
deviceId,
|
|
authHeader,
|
|
url,
|
|
}: IJobInput): Promise<JobStatus[]> {
|
|
const statusResponse = await axios.get(`${url}all-jobs`, {
|
|
headers: {
|
|
Authorization: authHeader,
|
|
},
|
|
params: {
|
|
deviceId,
|
|
},
|
|
});
|
|
if (statusResponse.status !== 200) {
|
|
console.error(
|
|
statusResponse.status,
|
|
statusResponse.data,
|
|
statusResponse.statusText
|
|
);
|
|
throw new Error("Failed to fetch job status");
|
|
}
|
|
|
|
return statusResponse.data;
|
|
}
|
|
|
|
interface ICancelJob {
|
|
authHeader: string;
|
|
url: string;
|
|
id: string;
|
|
}
|
|
|
|
export async function cancelJobById({
|
|
authHeader,
|
|
url,
|
|
id,
|
|
}: ICancelJob): Promise<boolean> {
|
|
const statusResponse = await axios.delete(`${url}cancel-job/${id}`, {
|
|
headers: {
|
|
Authorization: authHeader,
|
|
},
|
|
});
|
|
if (statusResponse.status !== 200) {
|
|
throw new Error("Failed to cancel process");
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
export async function cancelAllJobs({ authHeader, url, deviceId }: IJobInput) {
|
|
if (!deviceId) return false;
|
|
if (!authHeader) return false;
|
|
if (!url) return false;
|
|
|
|
try {
|
|
await getAllJobsByDeviceId({
|
|
deviceId,
|
|
authHeader,
|
|
url,
|
|
}).then((jobs) => {
|
|
jobs.forEach((job) => {
|
|
cancelJobById({
|
|
authHeader,
|
|
url,
|
|
id: job.id,
|
|
});
|
|
});
|
|
});
|
|
} catch (error) {
|
|
writeToLog("ERROR", "Failed to cancel all jobs", error);
|
|
console.error(error);
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Fetches statistics for a specific device.
|
|
*
|
|
* @param {IJobInput} params - The parameters for the API request.
|
|
* @param {string} params.deviceId - The ID of the device to fetch statistics for.
|
|
* @param {string} params.authHeader - The authorization header for the API request.
|
|
* @param {string} params.url - The base URL for the API endpoint.
|
|
*
|
|
* @returns {Promise<any | null>} A promise that resolves to the statistics data or null if the request fails.
|
|
*
|
|
* @throws {Error} Throws an error if any required parameter is missing.
|
|
*/
|
|
export async function getStatistics({
|
|
authHeader,
|
|
url,
|
|
deviceId,
|
|
}: IJobInput): Promise<any | null> {
|
|
if (!deviceId || !authHeader || !url) {
|
|
return null;
|
|
}
|
|
|
|
try {
|
|
const statusResponse = await axios.get(`${url}statistics`, {
|
|
headers: {
|
|
Authorization: authHeader,
|
|
},
|
|
params: {
|
|
deviceId,
|
|
},
|
|
});
|
|
|
|
return statusResponse.data;
|
|
} catch (error) {
|
|
console.error("Failed to fetch statistics:", error);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Saves the download item info to disk - this data is used temporarily to fetch additional download information
|
|
* in combination with the optimize server. This is used to not have to send all item info to the optimize server.
|
|
*
|
|
* @param {BaseItemDto} item - The item to save.
|
|
* @param {MediaSourceInfo} mediaSource - The media source of the item.
|
|
* @param {string} url - The URL of the item.
|
|
* @return {boolean} A promise that resolves when the item info is saved.
|
|
*/
|
|
export function saveDownloadItemInfoToDiskTmp(
|
|
item: BaseItemDto,
|
|
mediaSource: MediaSourceInfo,
|
|
url: string
|
|
): boolean {
|
|
try {
|
|
const storage = new MMKV();
|
|
|
|
const downloadInfo = JSON.stringify({
|
|
item,
|
|
mediaSource,
|
|
url,
|
|
});
|
|
|
|
storage.set(`tmp_download_info_${item.Id}`, downloadInfo);
|
|
|
|
return true;
|
|
} catch (error) {
|
|
console.error("Failed to save download item info to disk:", error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Retrieves the download item info from disk.
|
|
*
|
|
* @param {string} itemId - The ID of the item to retrieve.
|
|
* @return {{
|
|
* item: BaseItemDto;
|
|
* mediaSource: MediaSourceInfo;
|
|
* url: string;
|
|
* } | null} The retrieved download item info or null if not found.
|
|
*/
|
|
export function getDownloadItemInfoFromDiskTmp(itemId: string): {
|
|
item: BaseItemDto;
|
|
mediaSource: MediaSourceInfo;
|
|
url: string;
|
|
} | null {
|
|
try {
|
|
const storage = new MMKV();
|
|
const rawInfo = storage.getString(`tmp_download_info_${itemId}`);
|
|
|
|
if (rawInfo) {
|
|
return JSON.parse(rawInfo);
|
|
}
|
|
return null;
|
|
} catch (error) {
|
|
console.error("Failed to retrieve download item info from disk:", error);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Deletes the download item info from disk.
|
|
*
|
|
* @param {string} itemId - The ID of the item to delete.
|
|
* @return {boolean} True if the item info was successfully deleted, false otherwise.
|
|
*/
|
|
export function deleteDownloadItemInfoFromDiskTmp(itemId: string): boolean {
|
|
try {
|
|
const storage = new MMKV();
|
|
storage.delete(`tmp_download_info_${itemId}`);
|
|
return true;
|
|
} catch (error) {
|
|
console.error("Failed to delete download item info from disk:", error);
|
|
return false;
|
|
}
|
|
}
|