From 9d501a75428fe79f241df89e0227038202ae5eb1 Mon Sep 17 00:00:00 2001 From: Ayush Sehrawat <69469790+AyushSehrawat@users.noreply.github.com> Date: Wed, 6 Nov 2024 17:16:04 +0000 Subject: [PATCH 1/3] feat: add upload logs button --- src/lib/client/schemas.gen.ts | 91 ++++++++++++++++++++++++-- src/lib/client/services.gen.ts | 13 +++- src/lib/client/types.gen.ts | 36 ++++++++-- src/routes/settings/about/+page.svelte | 47 +++++++++++++ 4 files changed, 174 insertions(+), 13 deletions(-) diff --git a/src/lib/client/schemas.gen.ts b/src/lib/client/schemas.gen.ts index 8a39e15..63850d6 100644 --- a/src/lib/client/schemas.gen.ts +++ b/src/lib/client/schemas.gen.ts @@ -32,7 +32,7 @@ export const AppModelSchema = { version: { type: 'string', title: 'Version', - default: '0.16.2' + default: '0.18.0' }, api_key: { type: 'string', @@ -44,6 +44,11 @@ export const AppModelSchema = { title: 'Debug', default: true }, + debug_database: { + type: 'boolean', + title: 'Debug Database', + default: false + }, log: { type: 'boolean', title: 'Log', @@ -159,6 +164,13 @@ export const AppModelSchema = { fetch_trending: false, most_watched_count: 10, most_watched_period: 'weekly', + oauth: { + access_token: '', + oauth_client_id: '', + oauth_client_secret: '', + oauth_redirect_uri: '', + refresh_token: '' + }, popular_count: 10, trending_count: 10, update_interval: 86400, @@ -786,7 +798,14 @@ export const ContentModelSchema = { popular_count: 10, fetch_most_watched: false, most_watched_period: 'weekly', - most_watched_count: 10 + most_watched_count: 10, + oauth: { + access_token: '', + oauth_client_id: '', + oauth_client_secret: '', + oauth_redirect_uri: '', + refresh_token: '' + } } } }, @@ -2276,7 +2295,7 @@ export const RemoveResponseSchema = { }, ids: { items: { - type: 'integer' + type: 'string' }, type: 'array', title: 'Ids' @@ -2295,7 +2314,7 @@ export const ResetResponseSchema = { }, ids: { items: { - type: 'integer' + type: 'string' }, type: 'array', title: 'Ids' @@ -2314,7 +2333,7 @@ export const RetryResponseSchema = { }, ids: { items: { - type: 'integer' + type: 'string' }, type: 'array', title: 'Ids' @@ -2916,6 +2935,16 @@ export const TraktModelSchema = { type: 'integer', title: 'Most Watched Count', default: 10 + }, + oauth: { + '$ref': '#/components/schemas/TraktOauthModel', + default: { + oauth_client_id: '', + oauth_client_secret: '', + oauth_redirect_uri: '', + access_token: '', + refresh_token: '' + } } }, type: 'object', @@ -2934,6 +2963,38 @@ export const TraktOAuthInitiateResponseSchema = { title: 'TraktOAuthInitiateResponse' } as const; +export const TraktOauthModelSchema = { + properties: { + oauth_client_id: { + type: 'string', + title: 'Oauth Client Id', + default: '' + }, + oauth_client_secret: { + type: 'string', + title: 'Oauth Client Secret', + default: '' + }, + oauth_redirect_uri: { + type: 'string', + title: 'Oauth Redirect Uri', + default: '' + }, + access_token: { + type: 'string', + title: 'Access Token', + default: '' + }, + refresh_token: { + type: 'string', + title: 'Refresh Token', + default: '' + } + }, + type: 'object', + title: 'TraktOauthModel' +} as const; + export const UpdateAttributesResponseSchema = { properties: { message: { @@ -2982,6 +3043,26 @@ export const UpdatersModelSchema = { title: 'UpdatersModel' } as const; +export const UploadLogsResponseSchema = { + properties: { + success: { + type: 'boolean', + title: 'Success' + }, + url: { + type: 'string', + maxLength: 2083, + minLength: 1, + format: 'uri', + title: 'Url', + description: 'URL to the uploaded log file. 50M Filesize limit. 180 day retention.' + } + }, + type: 'object', + required: ['success', 'url'], + title: 'UploadLogsResponse' +} as const; + export const ValidationErrorSchema = { properties: { loc: { diff --git a/src/lib/client/services.gen.ts b/src/lib/client/services.gen.ts index 8a14d13..2e9394e 100644 --- a/src/lib/client/services.gen.ts +++ b/src/lib/client/services.gen.ts @@ -1,7 +1,7 @@ // This file is auto-generated by @hey-api/openapi-ts import { createClient, createConfig, type Options } from '@hey-api/client-fetch'; -import type { RootError, RootResponse2, HealthError, HealthResponse, RdError, RdResponse, GenerateapikeyError, GenerateapikeyResponse, TorboxError, TorboxResponse, ServicesError, ServicesResponse, TraktOauthInitiateError, TraktOauthInitiateResponse, TraktOauthCallbackData, TraktOauthCallbackError, TraktOauthCallbackResponse, StatsError, StatsResponse2, LogsError, LogsResponse, EventsError, EventsResponse, MountError, MountResponse, OverseerrApiV1WebhookOverseerrPostError, OverseerrApiV1WebhookOverseerrPostResponse, GetStatesError, GetStatesResponse, GetItemsData, GetItemsError, GetItemsResponse, AddItemsData, AddItemsError, AddItemsResponse, GetItemData, GetItemError, GetItemResponse, GetItemsByImdbIdsData, GetItemsByImdbIdsError, GetItemsByImdbIdsResponse, ResetItemsData, ResetItemsError, ResetItemsResponse, RetryItemsData, RetryItemsError, RetryItemsResponse, RemoveItemData, RemoveItemError, RemoveItemResponse, GetItemStreamsApiV1ItemsItemIdStreamsGetData, GetItemStreamsApiV1ItemsItemIdStreamsGetError, GetItemStreamsApiV1ItemsItemIdStreamsGetResponse, BlacklistStreamApiV1ItemsItemIdStreamsStreamIdBlacklistPostData, BlacklistStreamApiV1ItemsItemIdStreamsStreamIdBlacklistPostError, BlacklistStreamApiV1ItemsItemIdStreamsStreamIdBlacklistPostResponse, UnblacklistStreamApiV1ItemsItemIdStreamsStreamIdUnblacklistPostData, UnblacklistStreamApiV1ItemsItemIdStreamsStreamIdUnblacklistPostError, UnblacklistStreamApiV1ItemsItemIdStreamsStreamIdUnblacklistPostResponse, ScrapeItemData, ScrapeItemError, ScrapeItemResponse2, StartManualSessionApiV1ScrapeScrapeStartSessionPostData, StartManualSessionApiV1ScrapeScrapeStartSessionPostError, StartManualSessionApiV1ScrapeScrapeStartSessionPostResponse, ManualSelectData, ManualSelectError, ManualSelectResponse, ManualUpdateAttributesData, ManualUpdateAttributesError, ManualUpdateAttributesResponse, AbortManualSessionApiV1ScrapeScrapeAbortSessionSessionIdPostData, AbortManualSessionApiV1ScrapeScrapeAbortSessionSessionIdPostError, AbortManualSessionApiV1ScrapeScrapeAbortSessionSessionIdPostResponse, CompleteManualSessionData, CompleteManualSessionError, CompleteManualSessionResponse, GetSettingsSchemaError, GetSettingsSchemaResponse, LoadSettingsError, LoadSettingsResponse, SaveSettingsError, SaveSettingsResponse, GetAllSettingsError, GetAllSettingsResponse, GetSettingsData, GetSettingsError, GetSettingsResponse, SetAllSettingsData, SetAllSettingsError, SetAllSettingsResponse, SetSettingsData, SetSettingsError, SetSettingsResponse, GetEventTypesApiV1StreamEventTypesGetError, GetEventTypesApiV1StreamEventTypesGetResponse, StreamEventsApiV1StreamEventTypeGetData, StreamEventsApiV1StreamEventTypeGetError, StreamEventsApiV1StreamEventTypeGetResponse } from './types.gen'; +import type { RootError, RootResponse2, HealthError, HealthResponse, RdError, RdResponse, GenerateapikeyError, GenerateapikeyResponse, TorboxError, TorboxResponse, ServicesError, ServicesResponse, TraktOauthInitiateError, TraktOauthInitiateResponse, TraktOauthCallbackData, TraktOauthCallbackError, TraktOauthCallbackResponse, StatsError, StatsResponse2, LogsError, LogsResponse, EventsError, EventsResponse, MountError, MountResponse, UploadLogsError, UploadLogsResponse2, OverseerrApiV1WebhookOverseerrPostError, OverseerrApiV1WebhookOverseerrPostResponse, GetStatesError, GetStatesResponse, GetItemsData, GetItemsError, GetItemsResponse, AddItemsData, AddItemsError, AddItemsResponse, GetItemData, GetItemError, GetItemResponse, GetItemsByImdbIdsData, GetItemsByImdbIdsError, GetItemsByImdbIdsResponse, ResetItemsData, ResetItemsError, ResetItemsResponse, RetryItemsData, RetryItemsError, RetryItemsResponse, RemoveItemData, RemoveItemError, RemoveItemResponse, GetItemStreamsApiV1ItemsItemIdStreamsGetData, GetItemStreamsApiV1ItemsItemIdStreamsGetError, GetItemStreamsApiV1ItemsItemIdStreamsGetResponse, BlacklistStreamApiV1ItemsItemIdStreamsStreamIdBlacklistPostData, BlacklistStreamApiV1ItemsItemIdStreamsStreamIdBlacklistPostError, BlacklistStreamApiV1ItemsItemIdStreamsStreamIdBlacklistPostResponse, UnblacklistStreamApiV1ItemsItemIdStreamsStreamIdUnblacklistPostData, UnblacklistStreamApiV1ItemsItemIdStreamsStreamIdUnblacklistPostError, UnblacklistStreamApiV1ItemsItemIdStreamsStreamIdUnblacklistPostResponse, ScrapeItemData, ScrapeItemError, ScrapeItemResponse2, StartManualSessionApiV1ScrapeScrapeStartSessionPostData, StartManualSessionApiV1ScrapeScrapeStartSessionPostError, StartManualSessionApiV1ScrapeScrapeStartSessionPostResponse, ManualSelectData, ManualSelectError, ManualSelectResponse, ManualUpdateAttributesData, ManualUpdateAttributesError, ManualUpdateAttributesResponse, AbortManualSessionApiV1ScrapeScrapeAbortSessionSessionIdPostData, AbortManualSessionApiV1ScrapeScrapeAbortSessionSessionIdPostError, AbortManualSessionApiV1ScrapeScrapeAbortSessionSessionIdPostResponse, CompleteManualSessionData, CompleteManualSessionError, CompleteManualSessionResponse, GetSettingsSchemaError, GetSettingsSchemaResponse, LoadSettingsError, LoadSettingsResponse, SaveSettingsError, SaveSettingsResponse, GetAllSettingsError, GetAllSettingsResponse, GetSettingsData, GetSettingsError, GetSettingsResponse, SetAllSettingsData, SetAllSettingsError, SetAllSettingsResponse, SetSettingsData, SetSettingsError, SetSettingsResponse, GetEventTypesApiV1StreamEventTypesGetError, GetEventTypesApiV1StreamEventTypesGetResponse, StreamEventsApiV1StreamEventTypeGetData, StreamEventsApiV1StreamEventTypeGetError, StreamEventsApiV1StreamEventTypeGetResponse } from './types.gen'; export const client = createClient(createConfig()); @@ -127,6 +127,17 @@ export class DefaultService { }); } + /** + * Upload Logs + * Upload the latest log file to paste.c-net.org + */ + public static uploadLogs(options?: Options) { + return (options?.client ?? client).post({ + ...options, + url: '/api/v1/upload_logs' + }); + } + /** * Overseerr * Webhook for Overseerr diff --git a/src/lib/client/types.gen.ts b/src/lib/client/types.gen.ts index 6d8d15a..1398875 100644 --- a/src/lib/client/types.gen.ts +++ b/src/lib/client/types.gen.ts @@ -11,6 +11,7 @@ export type AppModel = { version?: string; api_key?: string; debug?: boolean; + debug_database?: boolean; log?: boolean; force_refresh?: boolean; map_metadata?: boolean; @@ -337,17 +338,17 @@ export type RealDebridModel = { export type RemoveResponse = { message: string; - ids: Array<(number)>; + ids: Array<(string)>; }; export type ResetResponse = { message: string; - ids: Array<(number)>; + ids: Array<(string)>; }; export type RetryResponse = { message: string; - ids: Array<(number)>; + ids: Array<(string)>; }; export type RootResponse = { @@ -515,12 +516,21 @@ export type TraktModel = { fetch_most_watched?: boolean; most_watched_period?: string; most_watched_count?: number; + oauth?: TraktOauthModel; }; export type TraktOAuthInitiateResponse = { auth_url: string; }; +export type TraktOauthModel = { + oauth_client_id?: string; + oauth_client_secret?: string; + oauth_redirect_uri?: string; + access_token?: string; + refresh_token?: string; +}; + export type UpdateAttributesResponse = { message: string; }; @@ -532,6 +542,14 @@ export type UpdatersModel = { emby?: EmbyLibraryModel; }; +export type UploadLogsResponse = { + success: boolean; + /** + * URL to the uploaded log file. 50M Filesize limit. 180 day retention. + */ + url: string; +}; + export type ValidationError = { loc: Array<(string | number)>; msg: string; @@ -608,6 +626,10 @@ export type MountResponse = ({ export type MountError = (unknown); +export type UploadLogsResponse2 = (UploadLogsResponse); + +export type UploadLogsError = (unknown); + export type OverseerrApiV1WebhookOverseerrPostResponse = ({ [key: string]: unknown; }); @@ -647,7 +669,7 @@ export type AddItemsError = (unknown | HTTPValidationError); export type GetItemData = { path: { - id: number; + id: string; }; query?: { use_tmdb_id?: (boolean | null); @@ -704,7 +726,7 @@ export type RemoveItemError = (unknown | HTTPValidationError); export type GetItemStreamsApiV1ItemsItemIdStreamsGetData = { path: { - item_id: number; + item_id: string; }; }; @@ -714,7 +736,7 @@ export type GetItemStreamsApiV1ItemsItemIdStreamsGetError = (unknown | HTTPValid export type BlacklistStreamApiV1ItemsItemIdStreamsStreamIdBlacklistPostData = { path: { - item_id: number; + item_id: string; stream_id: number; }; }; @@ -725,7 +747,7 @@ export type BlacklistStreamApiV1ItemsItemIdStreamsStreamIdBlacklistPostError = ( export type UnblacklistStreamApiV1ItemsItemIdStreamsStreamIdUnblacklistPostData = { path: { - item_id: number; + item_id: string; stream_id: number; }; }; diff --git a/src/routes/settings/about/+page.svelte b/src/routes/settings/about/+page.svelte index 5e2ca40..56f85d6 100644 --- a/src/routes/settings/about/+page.svelte +++ b/src/routes/settings/about/+page.svelte @@ -5,6 +5,9 @@ import { Button } from '$lib/components/ui/button'; import { Loader2, MoveUpRight } from 'lucide-svelte'; import { toast } from 'svelte-sonner'; + import * as Tooltip from '$lib/components/ui/tooltip'; + import * as AlertDialog from '$lib/components/ui/alert-dialog'; + import { DefaultService } from '$lib/client'; export let data: PageData; @@ -80,6 +83,17 @@ toast.success('You are running the latest frontend version.'); } } + + async function uploadLogs() { + const response = await DefaultService.uploadLogs(); + + if (!response.error) { + navigator.clipboard.writeText(String(response?.data?.url)); + toast.success('Logs uploaded successfully and link copied to clipboard'); + } else { + toast.error('Failed to upload logs'); + } + } @@ -176,6 +190,39 @@ {/each} +
+ + + + + + + +

Upload logs of upto 50MB and 100 days retention

+
+
+
+ + + Are you absolutely sure? + + This action will upload your recent logs to paste.c-net.org and provide you with a link to share with the community. + + + + Cancel + Continue + + +
+

Contributors

From d2cc15d2c8a4e10f7219abbed6b3307753a23f63 Mon Sep 17 00:00:00 2001 From: Ayush Sehrawat <69469790+AyushSehrawat@users.noreply.github.com> Date: Wed, 6 Nov 2024 17:24:37 +0000 Subject: [PATCH 2/3] fix: svelte-check errors --- src/lib/tmdb.ts | 6 +++--- src/routes/[type=mediaType]/[id]/+page.ts | 4 ++-- src/routes/[type=mediaType]/[id]/[season]/+page.ts | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/lib/tmdb.ts b/src/lib/tmdb.ts index d2387e8..4dff71c 100644 --- a/src/lib/tmdb.ts +++ b/src/lib/tmdb.ts @@ -115,7 +115,7 @@ export async function getMovieDetails( fetch: any, language: string = 'en-US', append_to_response: string | null = null, - movieId: number + movieId: string ) { const params = { language, append_to_response }; const queryString = dictToQueryString(params); @@ -190,7 +190,7 @@ export async function getTVDetails( fetch: any, language: string = 'en-US', append_to_response: string | null = null, - tvId: number + tvId: string ) { const params = { language, append_to_response }; const queryString = dictToQueryString(params); @@ -209,7 +209,7 @@ export async function getTVSeasonDetails( fetch: any, language: string = 'en-US', append_to_response: string | null = null, - tvId: number, + tvId: string, seasonNumber: number ) { const params = { language, append_to_response }; diff --git a/src/routes/[type=mediaType]/[id]/+page.ts b/src/routes/[type=mediaType]/[id]/+page.ts index 50b222f..43848c1 100644 --- a/src/routes/[type=mediaType]/[id]/+page.ts +++ b/src/routes/[type=mediaType]/[id]/+page.ts @@ -5,7 +5,7 @@ import type { RivenItem } from '$lib/types'; export const load = (async ({ fetch, params }) => { const type = params.type; - const id = Number(params.id); + const id = String(params.id); const { data } = await ItemsService.getItem({ path: { @@ -16,7 +16,7 @@ export const load = (async ({ fetch, params }) => { } }); - async function getDetails(type: string, id: number) { + async function getDetails(type: string, id: string) { switch (type) { case 'movie': // TODO: Remove the ones that are not needed in future diff --git a/src/routes/[type=mediaType]/[id]/[season]/+page.ts b/src/routes/[type=mediaType]/[id]/[season]/+page.ts index 680d9c7..6626b1a 100644 --- a/src/routes/[type=mediaType]/[id]/[season]/+page.ts +++ b/src/routes/[type=mediaType]/[id]/[season]/+page.ts @@ -6,23 +6,23 @@ import { ItemsService } from '$lib/client'; export const load = (async ({ fetch, params }) => { const type = params.type; - const id = Number(params.id); + const id = String(params.id); const season = Number(params.season); if (type === 'movie') { error(404, 'No seasons or episodes for movies'); } - async function getDetails(tvID: number, seasonNumber: number) { + async function getDetails(tvID: string, seasonNumber: number) { return await getTVSeasonDetails(fetch, 'en-US', null, tvID, seasonNumber); } // not using parent data since it will be fetched again with useless data - async function mediaDetails(tvID: number) { + async function mediaDetails(tvID: string) { return await getTVDetails(fetch, 'en-US', null, tvID); } - async function getMediaItemDetails(tvID: number): Promise { + async function getMediaItemDetails(tvID: string): Promise { const { data } = await ItemsService.getItem({ path: { id: tvID From 2af21a0713d076ddb52ebad1884429150f993043 Mon Sep 17 00:00:00 2001 From: Ayush Sehrawat <69469790+AyushSehrawat@users.noreply.github.com> Date: Wed, 6 Nov 2024 17:37:10 +0000 Subject: [PATCH 3/3] fix: svelte-check errors --- src/lib/tmdb.ts | 2 +- src/routes/[type=mediaType]/[id]/credits/+page.ts | 6 +++--- src/routes/settings/about/+page.svelte | 12 +++++++++--- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/lib/tmdb.ts b/src/lib/tmdb.ts index 4dff71c..5d7b309 100644 --- a/src/lib/tmdb.ts +++ b/src/lib/tmdb.ts @@ -393,7 +393,7 @@ export async function getCredits( // eslint-disable-next-line @typescript-eslint/no-explicit-any fetch: any, language: string = 'en-US', - mediaId: number, + mediaId: string, mediaType: string ) { const params = { language }; diff --git a/src/routes/[type=mediaType]/[id]/credits/+page.ts b/src/routes/[type=mediaType]/[id]/credits/+page.ts index 559f41a..24d8a40 100644 --- a/src/routes/[type=mediaType]/[id]/credits/+page.ts +++ b/src/routes/[type=mediaType]/[id]/credits/+page.ts @@ -2,14 +2,14 @@ import type { PageLoad } from './$types'; import { getCredits, getMovieDetails, getTVDetails } from '$lib/tmdb'; export const load = (async ({ fetch, params }) => { - const id = Number(params.id); + const id = String(params.id); const mediaType = params.type; - async function getDetails(id: number, mediaType: string) { + async function getDetails(id: string, mediaType: string) { return await getCredits(fetch, 'en-US', id, mediaType); } - async function getMedia(id: number, mediaType: string) { + async function getMedia(id: string, mediaType: string) { switch (mediaType) { case 'movie': return await getMovieDetails(fetch, 'en-US', '', id); diff --git a/src/routes/settings/about/+page.svelte b/src/routes/settings/about/+page.svelte index 56f85d6..7b7442a 100644 --- a/src/routes/settings/about/+page.svelte +++ b/src/routes/settings/about/+page.svelte @@ -91,7 +91,7 @@ navigator.clipboard.writeText(String(response?.data?.url)); toast.success('Logs uploaded successfully and link copied to clipboard'); } else { - toast.error('Failed to upload logs'); + toast.error(`Failed to upload logs: ${response.error}`); } } @@ -195,12 +195,18 @@ - -

Upload logs of upto 50MB and 100 days retention

+

Upload logs of upto 50MB and 180 days retention