diff --git a/server/src/api/channelsApi.ts b/server/src/api/channelsApi.ts index 0675f8bc..def62036 100644 --- a/server/src/api/channelsApi.ts +++ b/server/src/api/channelsApi.ts @@ -1,3 +1,12 @@ +import { ProgramConverter } from '@/db/converters/ProgramConverter.ts'; +import { dbChannelToApiChannel } from '@/db/converters/channelConverters.ts'; +import { GlobalScheduler } from '@/services/Scheduler.ts'; +import { UpdateXmlTvTask } from '@/tasks/UpdateXmlTvTask.js'; +import { OpenDateTimeRange } from '@/types/OpenDateTimeRange.js'; +import { RouterPluginAsyncCallback } from '@/types/serverType.js'; +import { attempt } from '@/util/index.js'; +import { LoggerFactory } from '@/util/logging/LoggerFactory.js'; +import { timeNamedAsync } from '@/util/perf.js'; import { scheduleTimeSlots } from '@tunarr/shared'; import { BasicIdParamSchema, @@ -26,15 +35,6 @@ import { sortBy, } from 'lodash-es'; import z from 'zod'; -import { dbChannelToApiChannel } from '../dao/converters/channelConverters.js'; -import { ProgramConverter } from '../dao/converters/programConverters.js'; -import { GlobalScheduler } from '../services/scheduler.js'; -import { UpdateXmlTvTask } from '../tasks/UpdateXmlTvTask.js'; -import { OpenDateTimeRange } from '../types/OpenDateTimeRange.js'; -import { RouterPluginAsyncCallback } from '../types/serverType.js'; -import { attempt } from '../util/index.js'; -import { LoggerFactory } from '../util/logging/LoggerFactory.js'; -import { timeNamedAsync } from '../util/perf.js'; dayjs.extend(duration); @@ -270,7 +270,7 @@ export const channelsApi: RouterPluginAsyncCallback = async (fastify) => { const externalIdsByProgramId = groupBy(externalIds, 'programUuid'); return res.send( map(channel.programs, (program) => - converter.directEntityToContentProgramSync( + converter.programDaoToContentProgram( program, externalIdsByProgramId[program.uuid] ?? [], ), @@ -405,7 +405,7 @@ export const channelsApi: RouterPluginAsyncCallback = async (fastify) => { const fallbacks = await req.serverCtx.channelDB.getChannelFallbackPrograms(req.params.id); const converted = map(fallbacks, (p) => - req.serverCtx.programConverter.directEntityToContentProgramSync(p, []), + req.serverCtx.programConverter.programDaoToContentProgram(p, []), ); return res.send(converted); }, diff --git a/server/src/api/customShowsApi.ts b/server/src/api/customShowsApi.ts index d0996003..e85b5bd6 100644 --- a/server/src/api/customShowsApi.ts +++ b/server/src/api/customShowsApi.ts @@ -1,3 +1,5 @@ +import { RouterPluginAsyncCallback } from '@/types/serverType.js'; +import { LoggerFactory } from '@/util/logging/LoggerFactory.js'; import { CreateCustomShowRequestSchema, IdPathParamSchema, @@ -6,8 +8,6 @@ import { import { CustomProgramSchema, CustomShowSchema } from '@tunarr/types/schemas'; import { isNil, isNull, map, sumBy } from 'lodash-es'; import { z } from 'zod'; -import { RouterPluginAsyncCallback } from '../types/serverType.js'; -import { LoggerFactory } from '../util/logging/LoggerFactory.js'; // eslint-disable-next-line @typescript-eslint/require-await export const customShowsApiV2: RouterPluginAsyncCallback = async (fastify) => { diff --git a/server/src/api/debug/debugJellyfinApi.ts b/server/src/api/debug/debugJellyfinApi.ts index 5c4c56b4..33aab836 100644 --- a/server/src/api/debug/debugJellyfinApi.ts +++ b/server/src/api/debug/debugJellyfinApi.ts @@ -1,9 +1,9 @@ +import { JellyfinApiClient } from '@/external/jellyfin/JellyfinApiClient.ts'; +import { JellyfinItemFinder } from '@/external/jellyfin/JellyfinItemFinder.ts'; +import { RouterPluginAsyncCallback } from '@/types/serverType.ts'; +import { Nilable } from '@/types/util.ts'; import { isNil } from 'lodash-es'; import { z } from 'zod'; -import { JellyfinApiClient } from '../../external/jellyfin/JellyfinApiClient.ts'; -import { JellyfinItemFinder } from '../../external/jellyfin/JellyfinItemFinder.ts'; -import { RouterPluginAsyncCallback } from '../../types/serverType.ts'; -import { Nilable } from '../../types/util.ts'; export const DebugJellyfinApiRouter: RouterPluginAsyncCallback = async ( fastify, diff --git a/server/src/api/debug/debugStreamApi.ts b/server/src/api/debug/debugStreamApi.ts index 4e4124cb..a14d88b3 100644 --- a/server/src/api/debug/debugStreamApi.ts +++ b/server/src/api/debug/debugStreamApi.ts @@ -1,23 +1,20 @@ +import { getDatabase } from '@/db/DBAccess.ts'; +import { createOfflineStreamLineupItem } from '@/db/derived_types/StreamLineup.ts'; +import { AllChannelTableKeys, Channel } from '@/db/schema/Channel.ts'; +import { ProgramDao, ProgramType } from '@/db/schema/Program.ts'; +import { MpegTsOutputFormat } from '@/ffmpeg/builder/constants.ts'; +import { serverContext } from '@/serverContext.ts'; +import { OfflineProgramStream } from '@/stream/OfflinePlayer.ts'; +import { PlayerContext } from '@/stream/PlayerStreamContext.ts'; +import { ProgramStream } from '@/stream/ProgramStream.ts'; +import { JellyfinProgramStream } from '@/stream/jellyfin/JellyfinProgramStream.ts'; +import { PlexProgramStream } from '@/stream/plex/PlexProgramStream.ts'; +import { TruthyQueryParam } from '@/types/schemas.ts'; +import { RouterPluginAsyncCallback } from '@/types/serverType.ts'; import { jsonObjectFrom } from 'kysely/helpers/sqlite'; import { first, isNumber, isUndefined, nth, random } from 'lodash-es'; import { PassThrough } from 'stream'; import { z } from 'zod'; -import { createOfflineStreamLineupItem } from '../../dao/derived_types/StreamLineup.ts'; -import { directDbAccess } from '../../dao/direct/directDbAccess.ts'; -import { - AllChannelTableKeys, - Channel, -} from '../../dao/direct/schema/Channel.ts'; -import { Program, ProgramType } from '../../dao/direct/schema/Program.ts'; -import { MpegTsOutputFormat } from '../../ffmpeg/builder/constants.ts'; -import { serverContext } from '../../serverContext.ts'; -import { OfflineProgramStream } from '../../stream/OfflinePlayer.ts'; -import { PlayerContext } from '../../stream/PlayerStreamContext.ts'; -import { ProgramStream } from '../../stream/ProgramStream.ts'; -import { JellyfinProgramStream } from '../../stream/jellyfin/JellyfinProgramStream.ts'; -import { PlexProgramStream } from '../../stream/plex/PlexProgramStream.ts'; -import { TruthyQueryParam } from '../../types/schemas.ts'; -import { RouterPluginAsyncCallback } from '../../types/serverType.ts'; export const debugStreamApiRouter: RouterPluginAsyncCallback = async ( fastify, @@ -34,7 +31,7 @@ export const debugStreamApiRouter: RouterPluginAsyncCallback = async ( }, }, async (req, res) => { - const channel = await directDbAccess() + const channel = await getDatabase() .selectFrom('channel') .selectAll() .executeTakeFirstOrThrow(); @@ -72,7 +69,7 @@ export const debugStreamApiRouter: RouterPluginAsyncCallback = async ( }, }, async (req, res) => { - const channel = await directDbAccess() + const channel = await getDatabase() .selectFrom('channel') .selectAll() .executeTakeFirstOrThrow(); @@ -96,7 +93,7 @@ export const debugStreamApiRouter: RouterPluginAsyncCallback = async ( ); fastify.get('/streams/random', async (_, res) => { - const program = await directDbAccess() + const program = await getDatabase() .selectFrom('program') .orderBy((ob) => ob.fn('random')) .where('type', '=', ProgramType.Episode) @@ -104,7 +101,7 @@ export const debugStreamApiRouter: RouterPluginAsyncCallback = async ( .selectAll() .executeTakeFirstOrThrow(); - const channels = await directDbAccess() + const channels = await getDatabase() .selectFrom('channelPrograms') .where('programUuid', '=', program.uuid) .select((eb) => @@ -156,7 +153,7 @@ export const debugStreamApiRouter: RouterPluginAsyncCallback = async ( ? random(program.duration / 1000, true) : req.query.start; - const channels = await directDbAccess() + const channels = await getDatabase() .selectFrom('channelPrograms') .where('programUuid', '=', program.uuid) .select((eb) => @@ -191,7 +188,7 @@ export const debugStreamApiRouter: RouterPluginAsyncCallback = async ( ); async function initStream( - program: Program, + program: ProgramDao, channel: Channel, startTime: number = 0, useNewPipeline: boolean = false, diff --git a/server/src/api/debugApi.ts b/server/src/api/debugApi.ts index 1e4d0a54..d2ea541f 100644 --- a/server/src/api/debugApi.ts +++ b/server/src/api/debugApi.ts @@ -1,4 +1,7 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ +import { getDatabase } from '@/db/DBAccess.ts'; +import { ArchiveDatabaseBackup } from '@/db/backup/ArchiveDatabaseBackup.ts'; +import { MediaSourceType } from '@/db/schema/MediaSource.ts'; import { ChannelLineupQuery } from '@tunarr/types/api'; import { ChannelLineupSchema } from '@tunarr/types/schemas'; import dayjs from 'dayjs'; @@ -6,18 +9,15 @@ import { jsonArrayFrom } from 'kysely/helpers/sqlite'; import { map, reject, some } from 'lodash-es'; import os from 'node:os'; import z from 'zod'; -import { ArchiveDatabaseBackup } from '../dao/backup/ArchiveDatabaseBackup.js'; -import { directDbAccess } from '../dao/direct/directDbAccess.js'; -import { MediaSourceType } from '../dao/direct/schema/MediaSource.ts'; -import { LineupCreator } from '../services/dynamic_channels/LineupCreator.js'; -import { PlexTaskQueue } from '../tasks/TaskQueue.js'; -import { SavePlexProgramExternalIdsTask } from '../tasks/plex/SavePlexProgramExternalIdsTask.js'; -import { DateTimeRange } from '../types/DateTimeRange.js'; -import { OpenDateTimeRange } from '../types/OpenDateTimeRange.js'; -import { RouterPluginAsyncCallback } from '../types/serverType.js'; -import { enumValues } from '../util/enumUtil.js'; -import { ifDefined } from '../util/index.js'; +import { LineupCreator } from '@/services/dynamic_channels/LineupCreator.js'; +import { PlexTaskQueue } from '@/tasks/TaskQueue.js'; +import { SavePlexProgramExternalIdsTask } from '@/tasks/plex/SavePlexProgramExternalIdsTask.js'; +import { DateTimeRange } from '@/types/DateTimeRange.js'; +import { OpenDateTimeRange } from '@/types/OpenDateTimeRange.js'; +import { RouterPluginAsyncCallback } from '@/types/serverType.js'; +import { enumValues } from '@/util/enumUtil.js'; +import { ifDefined } from '@/util/index.js'; import { DebugJellyfinApiRouter } from './debug/debugJellyfinApi.js'; import { debugStreamApiRouter } from './debug/debugStreamApi.js'; @@ -282,7 +282,7 @@ export const debugApi: RouterPluginAsyncCallback = async (fastify) => { _req.query.id, ))!; - const knownProgramIds = await directDbAccess() + const knownProgramIds = await getDatabase() .selectFrom('programExternalId as p1') .where(({ eb, and }) => and([ diff --git a/server/src/api/ffmpegSettingsApi.ts b/server/src/api/ffmpegSettingsApi.ts index da665d85..770362c8 100644 --- a/server/src/api/ffmpegSettingsApi.ts +++ b/server/src/api/ffmpegSettingsApi.ts @@ -1,12 +1,12 @@ +import { serverOptions } from '@/globals.js'; +import { RouterPluginCallback } from '@/types/serverType.js'; +import { firstDefined } from '@/util/index.js'; +import { LoggerFactory } from '@/util/logging/LoggerFactory.js'; +import { sanitizeForExec } from '@/util/strings.js'; import { defaultFfmpegSettings } from '@tunarr/types'; import { FfmpegSettingsSchema } from '@tunarr/types/schemas'; import { isError, merge, omit } from 'lodash-es'; import { z } from 'zod'; -import { serverOptions } from '../globals.js'; -import { RouterPluginCallback } from '../types/serverType.js'; -import { firstDefined } from '../util/index.js'; -import { LoggerFactory } from '../util/logging/LoggerFactory.js'; -import { sanitizeForExec } from '../util/strings.js'; export const ffmpegSettingsRouter: RouterPluginCallback = ( fastify, diff --git a/server/src/api/fillerListsApi.ts b/server/src/api/fillerListsApi.ts index 9c6bd1ab..2c4f731c 100644 --- a/server/src/api/fillerListsApi.ts +++ b/server/src/api/fillerListsApi.ts @@ -1,3 +1,4 @@ +import { RouterPluginAsyncCallback } from '@/types/serverType.js'; import { CreateFillerListRequestSchema, IdPathParamSchema, @@ -9,7 +10,6 @@ import { } from '@tunarr/types/schemas'; import { isNil, map } from 'lodash-es'; import { z } from 'zod'; -import { RouterPluginAsyncCallback } from '../types/serverType.js'; // We can't use the built-in zod brand because we have our own custom // tagged type. diff --git a/server/src/api/guideApi.ts b/server/src/api/guideApi.ts index 6041ad51..426f08a4 100644 --- a/server/src/api/guideApi.ts +++ b/server/src/api/guideApi.ts @@ -1,10 +1,10 @@ +import { DateTimeRange } from '@/types/DateTimeRange.js'; +import { RouterPluginCallback } from '@/types/serverType.js'; +import { groupByUniq } from '@/util/index.js'; +import { LoggerFactory } from '@/util/logging/LoggerFactory.js'; import { ChannelLineupSchema } from '@tunarr/types/schemas'; import { isNull } from 'lodash-es'; import { z } from 'zod'; -import { DateTimeRange } from '../types/DateTimeRange.js'; -import { RouterPluginCallback } from '../types/serverType.js'; -import { groupByUniq } from '../util/index.js'; -import { LoggerFactory } from '../util/logging/LoggerFactory.js'; export const guideRouter: RouterPluginCallback = (fastify, _opts, done) => { const logger = LoggerFactory.child({ diff --git a/server/src/api/hdhrApi.ts b/server/src/api/hdhrApi.ts index 35bf017b..5994ce03 100644 --- a/server/src/api/hdhrApi.ts +++ b/server/src/api/hdhrApi.ts @@ -1,6 +1,6 @@ +import { LoggerFactory } from '@/util/logging/LoggerFactory.ts'; import { FastifyPluginAsync } from 'fastify'; import { z } from 'zod'; -import { LoggerFactory } from '../util/logging/LoggerFactory.ts'; const HdhrLineupSchema = z.object({ GuideNumber: z.string(), diff --git a/server/src/api/hdhrSettingsApi.ts b/server/src/api/hdhrSettingsApi.ts index 3ae60f6b..372b1a52 100644 --- a/server/src/api/hdhrSettingsApi.ts +++ b/server/src/api/hdhrSettingsApi.ts @@ -1,11 +1,11 @@ +import { RouterPluginCallback } from '@/types/serverType.js'; +import { firstDefined } from '@/util/index.js'; +import { LoggerFactory } from '@/util/logging/LoggerFactory.js'; import { HdhrSettings } from '@tunarr/types'; import { BaseErrorSchema } from '@tunarr/types/api'; import { HdhrSettingsSchema } from '@tunarr/types/schemas'; import { isError } from 'lodash-es'; import { DeepWritable } from 'ts-essentials'; -import { RouterPluginCallback } from '../types/serverType.js'; -import { firstDefined } from '../util/index.js'; -import { LoggerFactory } from '../util/logging/LoggerFactory.js'; export const hdhrSettingsRouter: RouterPluginCallback = ( fastify, diff --git a/server/src/api/index.ts b/server/src/api/index.ts index c992f9cd..04b085d0 100644 --- a/server/src/api/index.ts +++ b/server/src/api/index.ts @@ -1,17 +1,19 @@ +import { MediaSourceType } from '@/db/schema/MediaSource.ts'; +import { MediaSourceApiFactory } from '@/external/MediaSourceApiFactory.js'; +import { FFMPEGInfo } from '@/ffmpeg/ffmpegInfo.js'; +import { serverOptions } from '@/globals.js'; +import { GlobalScheduler } from '@/services/Scheduler.ts'; +import { UpdateXmlTvTask } from '@/tasks/UpdateXmlTvTask.js'; +import { RouterPluginAsyncCallback } from '@/types/serverType.js'; +import { fileExists } from '@/util/fsUtil.js'; +import { LoggerFactory } from '@/util/logging/LoggerFactory.js'; +import { getTunarrVersion } from '@/util/version.js'; import { VersionApiResponseSchema } from '@tunarr/types/api'; import { fileTypeFromStream } from 'file-type'; import { createReadStream, promises as fsPromises } from 'fs'; import { isEmpty, isError, isNil } from 'lodash-es'; import path from 'path'; import { z } from 'zod'; -import { MediaSourceType } from '../dao/direct/schema/MediaSource.ts'; -import { MediaSourceApiFactory } from '../external/MediaSourceApiFactory.js'; -import { FFMPEGInfo } from '../ffmpeg/ffmpegInfo.js'; -import { serverOptions } from '../globals.js'; -import { GlobalScheduler } from '../services/scheduler.js'; -import { UpdateXmlTvTask } from '../tasks/UpdateXmlTvTask.js'; -import { RouterPluginAsyncCallback } from '../types/serverType.js'; -import { fileExists } from '../util/fsUtil.js'; import { isEdgeBuild, isNonEmptyString, @@ -19,8 +21,6 @@ import { run, tunarrBuild, } from '../util/index.js'; -import { LoggerFactory } from '../util/logging/LoggerFactory.js'; -import { getTunarrVersion } from '../util/version.js'; import { channelsApi } from './channelsApi.js'; import { customShowsApiV2 } from './customShowsApi.js'; import { debugApi } from './debugApi.js'; diff --git a/server/src/api/jellyfinApi.ts b/server/src/api/jellyfinApi.ts index 84097630..9ccc5c28 100644 --- a/server/src/api/jellyfinApi.ts +++ b/server/src/api/jellyfinApi.ts @@ -1,3 +1,9 @@ +import { MediaSource, MediaSourceType } from '@/db/schema/MediaSource.ts'; +import { isQueryError } from '@/external/BaseApiClient.js'; +import { MediaSourceApiFactory } from '@/external/MediaSourceApiFactory.js'; +import { JellyfinApiClient } from '@/external/jellyfin/JellyfinApiClient.js'; +import { TruthyQueryParam } from '@/types/schemas.js'; +import { isDefined, nullToUndefined } from '@/util/index.js'; import { JellyfinLoginRequest } from '@tunarr/types/api'; import { JellyfinCollectionType, @@ -10,17 +16,10 @@ import { import { FastifyReply } from 'fastify/types/reply.js'; import { filter, isEmpty, isNil, uniq } from 'lodash-es'; import { z } from 'zod'; -import { MediaSource } from '../dao/direct/schema/MediaSource.js'; -import { MediaSourceType } from '../dao/direct/schema/MediaSource.ts'; -import { isQueryError } from '../external/BaseApiClient.js'; -import { MediaSourceApiFactory } from '../external/MediaSourceApiFactory.js'; -import { JellyfinApiClient } from '../external/jellyfin/JellyfinApiClient.js'; -import { TruthyQueryParam } from '../types/schemas.js'; import { RouterPluginCallback, ZodFastifyRequest, } from '../types/serverType.js'; -import { isDefined, nullToUndefined } from '../util/index.js'; const mediaSourceParams = z.object({ mediaSourceId: z.string(), diff --git a/server/src/api/mediaSourceApi.ts b/server/src/api/mediaSourceApi.ts index 860ffe6a..29ff27d3 100644 --- a/server/src/api/mediaSourceApi.ts +++ b/server/src/api/mediaSourceApi.ts @@ -1,3 +1,13 @@ +import { MediaSourceType } from '@/db/schema/MediaSource.ts'; +import { MediaSourceApiFactory } from '@/external/MediaSourceApiFactory.js'; +import { JellyfinApiClient } from '@/external/jellyfin/JellyfinApiClient.js'; +import { PlexApiClient } from '@/external/plex/PlexApiClient.js'; +import { GlobalScheduler } from '@/services/Scheduler.ts'; +import { UpdateXmlTvTask } from '@/tasks/UpdateXmlTvTask.js'; +import { RouterPluginAsyncCallback } from '@/types/serverType.js'; +import { firstDefined, nullToUndefined, wait } from '@/util/index.js'; +import { LoggerFactory } from '@/util/logging/LoggerFactory.js'; +import { numberToBoolean } from '@/util/sqliteUtil.ts'; import { MediaSourceSettings, tag } from '@tunarr/types'; import { BaseErrorSchema, @@ -9,16 +19,6 @@ import { MediaSourceSettingsSchema } from '@tunarr/types/schemas'; import { isError, isNil, isObject, map } from 'lodash-es'; import { match } from 'ts-pattern'; import z from 'zod'; -import { MediaSourceType } from '../dao/direct/schema/MediaSource.ts'; -import { numberToBoolean } from '../dao/sqliteUtil.js'; -import { MediaSourceApiFactory } from '../external/MediaSourceApiFactory.js'; -import { JellyfinApiClient } from '../external/jellyfin/JellyfinApiClient.js'; -import { PlexApiClient } from '../external/plex/PlexApiClient.js'; -import { GlobalScheduler } from '../services/scheduler.js'; -import { UpdateXmlTvTask } from '../tasks/UpdateXmlTvTask.js'; -import { RouterPluginAsyncCallback } from '../types/serverType.js'; -import { firstDefined, nullToUndefined, wait } from '../util/index.js'; -import { LoggerFactory } from '../util/logging/LoggerFactory.js'; export const mediaSourceRouter: RouterPluginAsyncCallback = async ( fastify, diff --git a/server/src/api/metadataApi.ts b/server/src/api/metadataApi.ts index 18d11b20..514739cb 100644 --- a/server/src/api/metadataApi.ts +++ b/server/src/api/metadataApi.ts @@ -1,3 +1,7 @@ +import { MediaSourceApiFactory } from '@/external/MediaSourceApiFactory.ts'; +import { TruthyQueryParam } from '@/types/schemas.ts'; +import { RouterPluginAsyncCallback } from '@/types/serverType.ts'; +import { isNonEmptyString } from '@/util/index.ts'; import axios, { AxiosHeaders } from 'axios'; import { createHash } from 'crypto'; import dayjs from 'dayjs'; @@ -17,11 +21,7 @@ import { z } from 'zod'; import { ProgramSourceType, programSourceTypeFromString, -} from '../dao/custom_types/ProgramSourceType.ts'; -import { MediaSourceApiFactory } from '../external/MediaSourceApiFactory.ts'; -import { TruthyQueryParam } from '../types/schemas.ts'; -import { RouterPluginAsyncCallback } from '../types/serverType.ts'; -import { isNonEmptyString } from '../util/index.ts'; +} from '../db/custom_types/ProgramSourceType.ts'; const externalIdSchema = z .string() diff --git a/server/src/api/plexSettingsApi.ts b/server/src/api/plexSettingsApi.ts index 9eabefd3..c4c5d56c 100644 --- a/server/src/api/plexSettingsApi.ts +++ b/server/src/api/plexSettingsApi.ts @@ -1,11 +1,11 @@ +import { RouterPluginCallback } from '@/types/serverType.js'; +import { firstDefined } from '@/util/index.js'; +import { LoggerFactory } from '@/util/logging/LoggerFactory.js'; import { PlexStreamSettings, defaultPlexStreamSettings } from '@tunarr/types'; import { PlexStreamSettingsSchema } from '@tunarr/types/schemas'; import { isError } from 'lodash-es'; import { DeepWritable } from 'ts-essentials'; import { z } from 'zod'; -import { RouterPluginCallback } from '../types/serverType.js'; -import { firstDefined } from '../util/index.js'; -import { LoggerFactory } from '../util/logging/LoggerFactory.js'; export const plexSettingsRouter: RouterPluginCallback = ( fastify, diff --git a/server/src/api/programmingApi.ts b/server/src/api/programmingApi.ts index 6e2a2cc9..fb7d8bdf 100644 --- a/server/src/api/programmingApi.ts +++ b/server/src/api/programmingApi.ts @@ -1,3 +1,14 @@ +import { getDatabase } from '@/db/DBAccess.ts'; +import { ProgramExternalIdType } from '@/db/custom_types/ProgramExternalIdType.ts'; +import { MediaSource } from '@/db/schema/MediaSource.ts'; +import { ProgramType } from '@/db/schema/Program.ts'; +import { ProgramGroupingType } from '@/db/schema/ProgramGrouping.ts'; +import { JellyfinApiClient } from '@/external/jellyfin/JellyfinApiClient.js'; +import { PlexApiClient } from '@/external/plex/PlexApiClient.js'; +import { TruthyQueryParam } from '@/types/schemas.js'; +import { RouterPluginAsyncCallback } from '@/types/serverType.js'; +import { ifDefined, isNonEmptyString } from '@/util/index.js'; +import { LoggerFactory } from '@/util/logging/LoggerFactory.js'; import { BasicIdParamSchema } from '@tunarr/types/api'; import { ContentProgramSchema } from '@tunarr/types/schemas'; import axios, { AxiosHeaders, isAxiosError } from 'axios'; @@ -16,26 +27,15 @@ import { } from 'lodash-es'; import stream from 'stream'; import z from 'zod'; -import { ProgramExternalIdType } from '../dao/custom_types/ProgramExternalIdType.js'; import { ProgramSourceType, programSourceTypeFromString, -} from '../dao/custom_types/ProgramSourceType.js'; -import { directDbAccess } from '../dao/direct/directDbAccess.js'; +} from '../db/custom_types/ProgramSourceType.ts'; import { AllProgramFields, AllProgramGroupingFields, selectProgramsBuilder, -} from '../dao/direct/programQueryHelpers.js'; -import { MediaSource } from '../dao/direct/schema/MediaSource.js'; -import { ProgramType } from '../dao/direct/schema/Program.ts'; -import { ProgramGroupingType } from '../dao/direct/schema/ProgramGrouping.ts'; -import { JellyfinApiClient } from '../external/jellyfin/JellyfinApiClient.js'; -import { PlexApiClient } from '../external/plex/PlexApiClient.js'; -import { TruthyQueryParam } from '../types/schemas.js'; -import { RouterPluginAsyncCallback } from '../types/serverType.js'; -import { ifDefined, isNonEmptyString } from '../util/index.js'; -import { LoggerFactory } from '../util/logging/LoggerFactory.js'; +} from '../db/programQueryHelpers.ts'; const LookupExternalProgrammingSchema = z.object({ externalId: z @@ -76,7 +76,7 @@ export const programmingApi: RouterPluginAsyncCallback = async (fastify) => { }, async (req, res) => { return res.send( - req.serverCtx.programConverter.directEntityToContentProgramSync( + req.serverCtx.programConverter.programDaoToContentProgram( await selectProgramsBuilder({ joins: { tvSeason: true, @@ -454,7 +454,7 @@ export const programmingApi: RouterPluginAsyncCallback = async (fastify) => { }, }, async (req, res) => { - const result = await directDbAccess() + const result = await getDatabase() .selectFrom('programGrouping') .selectAll() .where('programGrouping.uuid', '=', req.params.id) @@ -510,7 +510,7 @@ export const programmingApi: RouterPluginAsyncCallback = async (fastify) => { }, }, async (req, res) => { - const result = await directDbAccess() + const result = await getDatabase() .selectFrom('programGrouping') .selectAll() .where('programGrouping.uuid', '=', req.params.id) @@ -542,7 +542,7 @@ export const programmingApi: RouterPluginAsyncCallback = async (fastify) => { }, }, async (req, res) => { - const result = await directDbAccess() + const result = await getDatabase() .selectFrom('programGrouping') .selectAll() .where('programGrouping.showUuid', '=', req.params.id) diff --git a/server/src/api/sessionApi.ts b/server/src/api/sessionApi.ts index 774800e3..1142145e 100644 --- a/server/src/api/sessionApi.ts +++ b/server/src/api/sessionApi.ts @@ -1,10 +1,10 @@ +import { SessionType } from '@/stream/Session.ts'; +import { SessionKey } from '@/stream/SessionManager.ts'; +import { RouterPluginAsyncCallback } from '@/types/serverType.ts'; +import { run } from '@/util/index.ts'; import { ChannelSessionsResponseSchema } from '@tunarr/types/api'; import { isEmpty, isNil, isNumber, map } from 'lodash-es'; import z from 'zod'; -import { SessionType } from '../stream/Session.ts'; -import { SessionKey } from '../stream/SessionManager.ts'; -import { RouterPluginAsyncCallback } from '../types/serverType.ts'; -import { run } from '../util/index.ts'; // eslint-disable-next-line @typescript-eslint/require-await export const sessionApiRouter: RouterPluginAsyncCallback = async (fastify) => { diff --git a/server/src/api/streamApi.ts b/server/src/api/streamApi.ts index 94dfd701..6f2f34c7 100644 --- a/server/src/api/streamApi.ts +++ b/server/src/api/streamApi.ts @@ -1,3 +1,12 @@ +import { Channel } from '@/db/schema/Channel.ts'; +import { defaultConcatOptions } from '@/ffmpeg/ffmpeg.ts'; +import { BaseHlsSession } from '@/stream/hls/BaseHlsSession.ts'; +import { Result } from '@/types/result.ts'; +import { TruthyQueryParam } from '@/types/schemas.ts'; +import { RouterPluginAsyncCallback } from '@/types/serverType.ts'; +import { Maybe } from '@/types/util.ts'; +import { LoggerFactory } from '@/util/logging/LoggerFactory.ts'; +import { makeLocalUrl } from '@/util/serverUtil.ts'; import fastifyStatic from '@fastify/static'; import { StreamConnectionDetails } from '@tunarr/types/api'; import { ChannelStreamModeSchema } from '@tunarr/types/schemas'; @@ -9,15 +18,6 @@ import { join } from 'node:path'; import { PassThrough } from 'stream'; import { v4 } from 'uuid'; import z from 'zod'; -import { Channel } from '../dao/direct/schema/Channel.ts'; -import { defaultConcatOptions } from '../ffmpeg/ffmpeg.ts'; -import { BaseHlsSession } from '../stream/hls/BaseHlsSession.ts'; -import { Result } from '../types/result.ts'; -import { TruthyQueryParam } from '../types/schemas.ts'; -import { RouterPluginAsyncCallback } from '../types/serverType.ts'; -import { Maybe } from '../types/util.ts'; -import { LoggerFactory } from '../util/logging/LoggerFactory.ts'; -import { makeLocalUrl } from '../util/serverUtil.ts'; // eslint-disable-next-line @typescript-eslint/require-await export const streamApi: RouterPluginAsyncCallback = async (fastify) => { diff --git a/server/src/api/systemApi.ts b/server/src/api/systemApi.ts index 1e47ed80..a20ce2b4 100644 --- a/server/src/api/systemApi.ts +++ b/server/src/api/systemApi.ts @@ -1,3 +1,10 @@ +import { serverOptions } from '@/globals.js'; +import { scheduleBackupJobs } from '@/services/Scheduler.ts'; +import { FixersByName } from '@/tasks/fixers/index.js'; +import { RouterPluginAsyncCallback } from '@/types/serverType.js'; +import { getDefaultLogLevel } from '@/util/defaults.js'; +import { ifDefined } from '@/util/index.js'; +import { getEnvironmentLogLevel } from '@/util/logging/LoggerFactory.js'; import { LoggingSettings, SystemSettings } from '@tunarr/types'; import { SystemSettingsResponse, @@ -9,13 +16,6 @@ import { BackupSettings, BackupSettingsSchema } from '@tunarr/types/schemas'; import { isUndefined } from 'lodash-es'; import { DeepReadonly, Writable } from 'ts-essentials'; import { z } from 'zod'; -import { serverOptions } from '../globals.js'; -import { scheduleBackupJobs } from '../services/scheduler.js'; -import { FixersByName } from '../tasks/fixers/index.js'; -import { RouterPluginAsyncCallback } from '../types/serverType.js'; -import { getDefaultLogLevel } from '../util/defaults.js'; -import { ifDefined } from '../util/index.js'; -import { getEnvironmentLogLevel } from '../util/logging/LoggerFactory.js'; export const systemApiRouter: RouterPluginAsyncCallback = async ( fastify, diff --git a/server/src/api/tasksApi.ts b/server/src/api/tasksApi.ts index f35f0c9a..ee4499c0 100644 --- a/server/src/api/tasksApi.ts +++ b/server/src/api/tasksApi.ts @@ -1,11 +1,11 @@ +import { GlobalScheduler } from '@/services/Scheduler.ts'; +import { RouterPluginAsyncCallback } from '@/types/serverType.js'; +import { LoggerFactory } from '@/util/logging/LoggerFactory.js'; import { BaseErrorSchema } from '@tunarr/types/api'; import { TaskSchema } from '@tunarr/types/schemas'; import dayjs from 'dayjs'; import { compact, isEmpty, isNil, map } from 'lodash-es'; import { z } from 'zod'; -import { GlobalScheduler } from '../services/scheduler.js'; -import { RouterPluginAsyncCallback } from '../types/serverType.js'; -import { LoggerFactory } from '../util/logging/LoggerFactory.js'; // eslint-disable-next-line @typescript-eslint/require-await export const tasksApiRouter: RouterPluginAsyncCallback = async (fastify) => { diff --git a/server/src/api/videoApi.ts b/server/src/api/videoApi.ts index bc2119f3..19ee4269 100644 --- a/server/src/api/videoApi.ts +++ b/server/src/api/videoApi.ts @@ -1,15 +1,15 @@ +import { FfmpegText } from '@/ffmpeg/ffmpegText.js'; +import { VideoStream } from '@/stream/VideoStream.js'; +import { TruthyQueryParam } from '@/types/schemas.js'; +import { RouterPluginAsyncCallback } from '@/types/serverType.js'; +import { LoggerFactory } from '@/util/logging/LoggerFactory.js'; +import { makeLocalUrl } from '@/util/serverUtil.js'; import { ChannelStreamModeSchema } from '@tunarr/types/schemas'; import dayjs from 'dayjs'; import { isNil, isNumber } from 'lodash-es'; import * as fsSync from 'node:fs'; import { Readable } from 'stream'; import { z } from 'zod'; -import { FfmpegText } from '../ffmpeg/ffmpegText.js'; -import { VideoStream } from '../stream/VideoStream.js'; -import { TruthyQueryParam } from '../types/schemas.js'; -import { RouterPluginAsyncCallback } from '../types/serverType.js'; -import { LoggerFactory } from '../util/logging/LoggerFactory.js'; -import { makeLocalUrl } from '../util/serverUtil.js'; const FfmpegPlaylistQuerySchema = z.object({ channel: z.string().uuid(), diff --git a/server/src/api/xmltvSettingsApi.ts b/server/src/api/xmltvSettingsApi.ts index f8933b76..f7294879 100644 --- a/server/src/api/xmltvSettingsApi.ts +++ b/server/src/api/xmltvSettingsApi.ts @@ -1,15 +1,15 @@ +import { defaultXmlTvSettings } from '@/db/SettingsDB.ts'; +import { serverOptions } from '@/globals.js'; +import { GlobalScheduler } from '@/services/Scheduler.ts'; +import { UpdateXmlTvTask } from '@/tasks/UpdateXmlTvTask.js'; +import { RouterPluginCallback } from '@/types/serverType.js'; +import { firstDefined } from '@/util/index.js'; +import { LoggerFactory } from '@/util/logging/LoggerFactory.js'; import { XmlTvSettings } from '@tunarr/types'; import { BaseErrorSchema } from '@tunarr/types/api'; import { XmlTvSettingsSchema } from '@tunarr/types/schemas'; import { isError } from 'lodash-es'; import { z } from 'zod'; -import { defaultXmlTvSettings } from '../dao/settings.js'; -import { serverOptions } from '../globals.js'; -import { GlobalScheduler } from '../services/scheduler.js'; -import { UpdateXmlTvTask } from '../tasks/UpdateXmlTvTask.js'; -import { RouterPluginCallback } from '../types/serverType.js'; -import { firstDefined } from '../util/index.js'; -import { LoggerFactory } from '../util/logging/LoggerFactory.js'; export const xmlTvSettingsRouter: RouterPluginCallback = ( fastify, diff --git a/server/src/bootstrap.ts b/server/src/bootstrap.ts index f6bc5e44..6d0b4b2d 100644 --- a/server/src/bootstrap.ts +++ b/server/src/bootstrap.ts @@ -3,10 +3,10 @@ import fs from 'node:fs/promises'; import path from 'path'; import { DeepPartial } from 'ts-essentials'; import { - initDirectDbAccess, + initDatabaseAccess, syncMigrationTablesIfNecessary, -} from './dao/direct/directDbAccess.ts'; -import { SettingsFile, getSettings } from './dao/settings.js'; +} from './db/DBAccess.ts'; +import { SettingsFile, getSettings } from './db/SettingsDB.ts'; import { globalOptions } from './globals.js'; import { copyDirectoryContents, fileExists } from './util/fsUtil.js'; import { LoggerFactory, RootLogger } from './util/logging/LoggerFactory.js'; @@ -63,7 +63,7 @@ export async function bootstrapTunarr( initialSettings?: DeepPartial, ) { await initDbDirectories(); - initDirectDbAccess(path.join(globalOptions().databaseDirectory, 'db.db')); + initDatabaseAccess(path.join(globalOptions().databaseDirectory, 'db.db')); await syncMigrationTablesIfNecessary(); const settingsDb = getSettings(undefined, initialSettings); LoggerFactory.initialize(settingsDb); diff --git a/server/src/cli/RunServerCommand.ts b/server/src/cli/RunServerCommand.ts index 805197d0..0e99cb20 100644 --- a/server/src/cli/RunServerCommand.ts +++ b/server/src/cli/RunServerCommand.ts @@ -1,11 +1,11 @@ +import { setServerOptions } from '@/globals.ts'; +import { initServer } from '@/server.ts'; +import { TruthyQueryParam } from '@/types/schemas.ts'; +import { getDefaultServerPort } from '@/util/defaults.ts'; +import { isNonEmptyString, isProduction } from '@/util/index.ts'; +import { getTunarrVersion } from '@/util/version.ts'; import chalk from 'chalk'; import { ArgumentsCamelCase, CommandModule } from 'yargs'; -import { setServerOptions } from '../globals.ts'; -import { initServer } from '../server.ts'; -import { TruthyQueryParam } from '../types/schemas.ts'; -import { getDefaultServerPort } from '../util/defaults.ts'; -import { isNonEmptyString, isProduction } from '../util/index.ts'; -import { getTunarrVersion } from '../util/version.ts'; import { GlobalArgsType } from './types.ts'; export type ServerArgsType = GlobalArgsType & { diff --git a/server/src/cli/legacyMigrateCommand.ts b/server/src/cli/legacyMigrateCommand.ts index abaedd32..2996aaca 100644 --- a/server/src/cli/legacyMigrateCommand.ts +++ b/server/src/cli/legacyMigrateCommand.ts @@ -1,9 +1,10 @@ +import { getSettings } from '@/db/SettingsDB.ts'; +import { LegacyDbMigrator } from '@/migration/legacy_migration/legacyDbMigration.ts'; import { isArray, isString } from 'lodash-es'; import { existsSync } from 'node:fs'; import path from 'node:path'; import { CommandModule } from 'yargs'; -import { LegacyDbMigrator } from '../dao/legacy_migration/legacyDbMigration.ts'; -import { getSettings } from '../dao/settings.ts'; +import { GlobalArgsType } from './types.ts'; type LegacyMigrateCommandArgs = { legacy_path: string; @@ -22,40 +23,42 @@ const MigratableEntities = [ 'cached-images', ]; -export const LegacyMigrateCommand: CommandModule<{}, LegacyMigrateCommandArgs> = - { - command: 'legacy-migrate', - describe: 'Migrate from the legacy .dizquetv database', - builder: { - legacy_path: { - type: 'string', - default: path.join(process.cwd(), '.dizquetv'), - coerce(arg: string) { - if (!existsSync(arg)) { - throw new Error(`No directory found at ${arg}`); - } - return arg; - }, - }, - entities: { - type: 'array', - choices: MigratableEntities, - coerce(arg) { - if (isArray(arg)) { - return arg as string[]; - } else if (isString(arg)) { - return arg.split(','); - } else { - throw new Error('Bad arg'); - } - }, +export const LegacyMigrateCommand: CommandModule< + GlobalArgsType, + LegacyMigrateCommandArgs +> = { + command: 'legacy-migrate', + describe: 'Migrate from the legacy .dizquetv database', + builder: { + legacy_path: { + type: 'string', + default: path.join(process.cwd(), '.dizquetv'), + coerce(arg: string) { + if (!existsSync(arg)) { + throw new Error(`No directory found at ${arg}`); + } + return arg; }, }, - handler: async (argv) => { - console.log('Migrating DB from legacy schema...'); - return await new LegacyDbMigrator( - getSettings(), - argv.legacy_path, - ).migrateFromLegacyDb(argv.entities); + entities: { + type: 'array', + choices: MigratableEntities, + coerce(arg) { + if (isArray(arg)) { + return arg as string[]; + } else if (isString(arg)) { + return arg.split(','); + } else { + throw new Error('Bad arg'); + } + }, }, - }; + }, + handler: async (argv) => { + console.log('Migrating DB from legacy schema...'); + return await new LegacyDbMigrator( + getSettings(), + argv.legacy_path, + ).migrateFromLegacyDb(argv.entities); + }, +}; diff --git a/server/src/cli/runFixerCommand.ts b/server/src/cli/runFixerCommand.ts index ebb061c7..f6f140f2 100644 --- a/server/src/cli/runFixerCommand.ts +++ b/server/src/cli/runFixerCommand.ts @@ -1,7 +1,7 @@ +import { FixersByName } from '@/tasks/fixers/index.ts'; +import { isNonEmptyString } from '@/util/index.ts'; import { keys } from 'lodash-es'; import { CommandModule } from 'yargs'; -import { FixersByName } from '../tasks/fixers/index.ts'; -import { isNonEmptyString } from '../util/index.ts'; import { GlobalArgsType } from './types.ts'; type RunFixerCommandArgs = { diff --git a/server/src/cli/settings/settingsUpdateCommand.ts b/server/src/cli/settings/settingsUpdateCommand.ts index 92a82f15..89152f98 100644 --- a/server/src/cli/settings/settingsUpdateCommand.ts +++ b/server/src/cli/settings/settingsUpdateCommand.ts @@ -1,6 +1,6 @@ +import { SettingsSchema, getSettings } from '@/db/SettingsDB.ts'; import { merge } from 'lodash-es'; import { CommandModule } from 'yargs'; -import { SettingsSchema, getSettings } from '../../dao/settings.ts'; type SettingsUpdateCommandArgs = { pretty: boolean; diff --git a/server/src/cli/settings/settingsViewCommand.ts b/server/src/cli/settings/settingsViewCommand.ts index a6aec7d1..5dbac881 100644 --- a/server/src/cli/settings/settingsViewCommand.ts +++ b/server/src/cli/settings/settingsViewCommand.ts @@ -1,6 +1,6 @@ +import { getSettings } from '@/db/SettingsDB.ts'; import { at, isArray, isEmpty } from 'lodash-es'; import { CommandModule } from 'yargs'; -import { getSettings } from '../../dao/settings.ts'; type SettingsViewCommandArgs = { pretty: boolean; diff --git a/server/src/cli/types.ts b/server/src/cli/types.ts index c752740e..e28894f4 100644 --- a/server/src/cli/types.ts +++ b/server/src/cli/types.ts @@ -1,4 +1,4 @@ -import { LogLevels } from '../util/logging/LoggerFactory.ts'; +import { LogLevels } from '@/util/logging/LoggerFactory.ts'; export type GlobalArgsType = { log_level: LogLevels; diff --git a/server/src/dao/channelDb.ts b/server/src/db/ChannelDB.ts similarity index 94% rename from server/src/dao/channelDb.ts rename to server/src/db/ChannelDB.ts index c63511c4..bf6f8e6b 100644 --- a/server/src/dao/channelDb.ts +++ b/server/src/db/ChannelDB.ts @@ -1,3 +1,15 @@ +import { globalOptions } from '@/globals.ts'; +import { serverContext } from '@/serverContext.ts'; +import { ChannelNotFoundError } from '@/types/errors.ts'; +import { typedProperty } from '@/types/path.ts'; +import { Result } from '@/types/result.ts'; +import { MarkNullable, Maybe } from '@/types/util.ts'; +import { asyncPool } from '@/util/asyncPool.ts'; +import { fileExists } from '@/util/fsUtil.ts'; +import { LoggerFactory } from '@/util/logging/LoggerFactory.ts'; +import { MutexMap } from '@/util/mutexMap.ts'; +import { Timer } from '@/util/perf.ts'; +import { booleanToNumber } from '@/util/sqliteUtil.ts'; import { scheduleRandomSlots, scheduleTimeSlots } from '@tunarr/shared'; import { forProgramType, seq } from '@tunarr/shared/util'; import { @@ -45,15 +57,6 @@ import { join } from 'path'; import { MarkOptional, MarkRequired } from 'ts-essentials'; import { match } from 'ts-pattern'; import { v4 } from 'uuid'; -import { ChannelWithPrograms as RawChannelWithPrograms } from '../dao/direct/derivedTypes.js'; -import { globalOptions } from '../globals.js'; -import { serverContext } from '../serverContext.js'; -import { ChannelNotFoundError } from '../types/errors.js'; -import { typedProperty } from '../types/path.js'; -import { Result } from '../types/result.js'; -import { MarkNullable, Maybe } from '../types/util.js'; -import { asyncPool } from '../util/asyncPool.js'; -import { fileExists } from '../util/fsUtil.js'; import { groupByFunc, groupByUniqProp, @@ -61,12 +64,11 @@ import { isNonEmptyString, mapReduceAsyncSeq, run, -} from '../util/index.js'; -import { LoggerFactory } from '../util/logging/LoggerFactory.js'; -import { MutexMap } from '../util/mutexMap.js'; -import { Timer } from '../util/perf.js'; -import { SchemaBackedDbAdapter } from './SchemaBackedDbAdapter.js'; -import { ProgramConverter } from './converters/programConverters.js'; +} from '../util/index.ts'; +import { getDatabase } from './DBAccess.ts'; +import { ProgramDB } from './ProgramDB.ts'; +import { SchemaBackedDbAdapter } from './SchemaBackedJsonDBAdapter.ts'; +import { ProgramConverter } from './converters/ProgramConverter.ts'; import { ContentItem, CurrentLineupSchemaVersion, @@ -77,8 +79,7 @@ import { isContentItem, isOfflineItem, isRedirectItem, -} from './derived_types/Lineup.js'; -import { directDbAccess } from './direct/directDbAccess.js'; +} from './derived_types/Lineup.ts'; import { MinimalProgramGroupingFields, withFallbackPrograms, @@ -87,18 +88,17 @@ import { withTrackArtist, withTvSeason, withTvShow, -} from './direct/programQueryHelpers.js'; +} from './programQueryHelpers.ts'; import { ChannelUpdate, NewChannel, NewChannelFillerShow, NewChannelProgram, Channel as RawChannel, -} from './direct/schema/Channel.js'; -import { programExternalIdString } from './direct/schema/Program.js'; -import { ChannelTranscodingSettings } from './direct/schema/base.ts'; -import { ProgramDB } from './programDB.js'; -import { booleanToNumber } from './sqliteUtil.js'; +} from './schema/Channel.ts'; +import { programExternalIdString } from './schema/Program.ts'; +import { ChannelTranscodingSettings } from './schema/base.ts'; +import { ChannelWithPrograms as RawChannelWithPrograms } from './schema/derivedTypes.js'; dayjs.extend(duration); @@ -253,7 +253,7 @@ export class ChannelDB { constructor(private programDB: ProgramDB = new ProgramDB()) {} async channelExists(channelId: string) { - const channel = await directDbAccess() + const channel = await getDatabase() .selectFrom('channel') .where('channel.uuid', '=', channelId) .select('uuid') @@ -262,7 +262,7 @@ export class ChannelDB { } getChannel(id: string | number, includeFiller: boolean = false) { - return directDbAccess() + return getDatabase() .selectFrom('channel') .$if(isString(id), (eb) => eb.where('channel.uuid', '=', id as string)) .$if(isNumber(id), (eb) => eb.where('channel.number', '=', id as number)) @@ -288,7 +288,7 @@ export class ChannelDB { getChannelAndPrograms( uuid: string, ): Promise { - return directDbAccess() + return getDatabase() .selectFrom('channel') .selectAll(['channel']) .where('channel.uuid', '=', uuid) @@ -334,7 +334,7 @@ export class ChannelDB { } getChannelProgramExternalIds(uuid: string) { - return directDbAccess() + return getDatabase() .selectFrom('channelPrograms') .where('channelUuid', '=', uuid) .innerJoin( @@ -347,7 +347,7 @@ export class ChannelDB { } async getChannelFallbackPrograms(uuid: string) { - const result = await directDbAccess() + const result = await getDatabase() .selectFrom('channelFallback') .where('channelFallback.channelUuid', '=', uuid) .select(withFallbackPrograms) @@ -364,7 +364,7 @@ export class ChannelDB { ); } - const channel = await directDbAccess() + const channel = await getDatabase() .transaction() .execute(async (tx) => { const channel = await tx @@ -447,7 +447,7 @@ export class ChannelDB { } } - await directDbAccess() + await getDatabase() .transaction() .execute(async (tx) => { await tx @@ -501,7 +501,7 @@ export class ChannelDB { } async updateChannelStartTime(id: string, newTime: number) { - return directDbAccess() + return getDatabase() .updateTable('channel') .where('channel.uuid', '=', id) .set('startTime', newTime) @@ -517,7 +517,7 @@ export class ChannelDB { await this.markLineupFileForDeletion(channelId); marked = true; - await directDbAccess() + await getDatabase() .deleteFrom('channel') .where('uuid', '=', channelId) .limit(1) @@ -559,7 +559,7 @@ export class ChannelDB { } getAllChannels(pageParams?: PageParams) { - return directDbAccess() + return getDatabase() .selectFrom('channel') .selectAll() .orderBy('channel.number asc') @@ -578,7 +578,7 @@ export class ChannelDB { } async getAllChannelsAndPrograms(): Promise { - return await directDbAccess() + return await getDatabase() .selectFrom('channel') .selectAll(['channel']) .leftJoin( @@ -602,7 +602,7 @@ export class ChannelDB { } async updateLineup(id: string, req: UpdateChannelProgrammingRequest) { - const channel = await directDbAccess() + const channel = await getDatabase() .selectFrom('channel') .selectAll() .where('channel.uuid', '=', id) @@ -627,7 +627,7 @@ export class ChannelDB { lineup: readonly LineupItem[], startTime: number, ) => { - return await directDbAccess() + return await getDatabase() .transaction() .execute(async (tx) => { console.log('in here'); @@ -829,7 +829,7 @@ export class ChannelDB { const allIds = uniq(map(filter(lineup, isContentItem), 'id')); - return await directDbAccess() + return await getDatabase() .transaction() .execute(async (tx) => { // await tx @@ -1008,7 +1008,7 @@ export class ChannelDB { const contentItems = filter(pagedLineup, isContentItem); const directPrograms = await this.timer.timeAsync('direct', () => - directDbAccess() + getDatabase() .selectFrom('channelPrograms') .where('channelUuid', '=', channelId) .innerJoin('program', 'channelPrograms.programUuid', 'program.uuid') @@ -1041,11 +1041,10 @@ export class ChannelDB { return; } - const converted = - this.#programConverter.directEntityToContentProgramSync( - program, - externalIdsByProgramId[program.uuid] ?? [], - ); + const converted = this.#programConverter.programDaoToContentProgram( + program, + externalIdsByProgramId[program.uuid] ?? [], + ); ret[converted.id!] = converted; }); @@ -1235,7 +1234,7 @@ export class ChannelDB { channel: RawChannelWithPrograms, lineup: LineupItem[], ): Promise<{ lineup: ChannelProgram[]; offsets: number[] }> { - const allChannels = await directDbAccess() + const allChannels = await getDatabase() .selectFrom('channel') .select(['channel.uuid', 'channel.number', 'channel.name']) .execute(); @@ -1253,13 +1252,13 @@ export class ChannelDB { if (!fullProgram) { return null; } - return this.#programConverter.directEntityToContentProgramSync( + return this.#programConverter.programDaoToContentProgram( fullProgram, fullProgram.externalIds ?? [], ); }) .otherwise((item) => - this.#programConverter.directLineupItemToChannelProgram( + this.#programConverter.lineupItemToChannelProgram( channel, item, allChannels, @@ -1302,7 +1301,7 @@ export class ChannelDB { )) { customShowIndexes[customShowId] = {}; - const results = await directDbAccess() + const results = await getDatabase() .selectFrom('customShowContent') .select(['customShowContent.contentUuid', 'customShowContent.index']) .where('customShowContent.contentUuid', 'in', map(items, 'id')) @@ -1318,7 +1317,7 @@ export class ChannelDB { customShowIndexes[customShowId] = byItemId; } - const allChannels = await directDbAccess() + const allChannels = await getDatabase() .selectFrom('channel') .select(['uuid', 'name', 'number']) .execute(); @@ -1328,10 +1327,7 @@ export class ChannelDB { const programs = seq.collect(lineup, (item) => { let p: CondensedChannelProgram | null = null; if (isOfflineItem(item)) { - p = this.#programConverter.directOfflineLineupItemToProgram( - channel, - item, - ); + p = this.#programConverter.offlineLineupItemToProgram(channel, item); } else if (isRedirectItem(item)) { if (channelsById[item.channel]) { p = this.#programConverter.redirectLineupItemToProgram( diff --git a/server/src/dao/customShowDb.ts b/server/src/db/CustomShowDB.ts similarity index 85% rename from server/src/dao/customShowDb.ts rename to server/src/db/CustomShowDB.ts index a9e19ca4..57211c65 100644 --- a/server/src/dao/customShowDb.ts +++ b/server/src/db/CustomShowDB.ts @@ -1,3 +1,4 @@ +import { isNonEmptyString } from '@/util/index.ts'; import { CustomProgram } from '@tunarr/types'; import { CreateCustomShowRequest, @@ -6,20 +7,16 @@ import { import dayjs from 'dayjs'; import { filter, isNil, map } from 'lodash-es'; import { v4 } from 'uuid'; -import { isNonEmptyString } from '../util/index.js'; -import { ProgramConverter } from './converters/programConverters.js'; -import { directDbAccess } from './direct/directDbAccess.js'; +import { getDatabase } from './DBAccess.ts'; +import { ProgramDB } from './ProgramDB.ts'; +import { ProgramConverter } from './converters/ProgramConverter.ts'; +import { createPendingProgramIndexMap } from './programHelpers.ts'; import { AllProgramJoins, withCustomShowPrograms, -} from './direct/programQueryHelpers.js'; -import { - NewCustomShow, - NewCustomShowContent, -} from './direct/schema/CustomShow.js'; -import { programExternalIdString } from './direct/schema/Program.js'; -import { ProgramDB } from './programDB.js'; -import { createPendingProgramIndexMap } from './programHelpers.js'; +} from './programQueryHelpers.ts'; +import { NewCustomShow, NewCustomShowContent } from './schema/CustomShow.ts'; +import { programExternalIdString } from './schema/Program.ts'; export class CustomShowDB { #programConverter: ProgramConverter = new ProgramConverter(); @@ -27,7 +24,7 @@ export class CustomShowDB { constructor(private programDB: ProgramDB = new ProgramDB()) {} async getShow(id: string) { - return directDbAccess() + return getDatabase() .selectFrom('customShow') .selectAll() .where('customShow.uuid', '=', id) @@ -40,7 +37,7 @@ export class CustomShowDB { } async getShowPrograms(id: string): Promise { - const programs = await directDbAccess() + const programs = await getDatabase() .selectFrom('customShow') .where('customShow.uuid', '=', id) .select((eb) => withCustomShowPrograms(eb, { joins: AllProgramJoins })) @@ -50,7 +47,7 @@ export class CustomShowDB { type: 'custom' as const, persisted: true, duration: csc.duration, - program: this.#programConverter.directEntityToContentProgramSync(csc, []), + program: this.#programConverter.programDaoToContentProgram(csc, []), customShowId: id, index: csc.index, id: csc.uuid, @@ -98,7 +95,7 @@ export class CustomShowDB { }) satisfies NewCustomShowContent, ); - await directDbAccess() + await getDatabase() .transaction() .execute(async (tx) => { await tx @@ -113,7 +110,7 @@ export class CustomShowDB { } if (updateRequest.name) { - await directDbAccess() + await getDatabase() .updateTable('customShow') .where('uuid', '=', show.uuid) .limit(1) @@ -143,7 +140,7 @@ export class CustomShowDB { createRequest.programs, ); - await directDbAccess().insertInto('customShow').values(show).execute(); + await getDatabase().insertInto('customShow').values(show).execute(); const persistedCustomShowContent = map( persisted, @@ -164,7 +161,7 @@ export class CustomShowDB { }) satisfies NewCustomShowContent, ); - await directDbAccess() + await getDatabase() .insertInto('customShowContent') .values([...persistedCustomShowContent, ...newCustomShowContent]) .execute(); @@ -178,7 +175,7 @@ export class CustomShowDB { return false; } - await directDbAccess() + await getDatabase() .transaction() .execute(async (tx) => { // TODO: Do this deletion in the DB with foreign keys. @@ -200,7 +197,7 @@ export class CustomShowDB { } async getAllShowIds() { - return directDbAccess() + return getDatabase() .selectFrom('customShow') .select('uuid') .execute() @@ -208,11 +205,11 @@ export class CustomShowDB { } getAllShows() { - return directDbAccess().selectFrom('customShow').selectAll().execute(); + return getDatabase().selectFrom('customShow').selectAll().execute(); } async getAllShowsInfo() { - const showsAndContentCount = await directDbAccess() + const showsAndContentCount = await getDatabase() .selectFrom('customShow') .selectAll('customShow') .innerJoin( diff --git a/server/src/dao/direct/directDbAccess.ts b/server/src/db/DBAccess.ts similarity index 89% rename from server/src/dao/direct/directDbAccess.ts rename to server/src/db/DBAccess.ts index 067cf24c..9e250233 100644 --- a/server/src/dao/direct/directDbAccess.ts +++ b/server/src/db/DBAccess.ts @@ -1,3 +1,5 @@ +import { attempt } from '@/util/index.ts'; +import { LoggerFactory } from '@/util/logging/LoggerFactory.ts'; import Sqlite from 'better-sqlite3'; import dayjs from 'dayjs'; import { @@ -8,12 +10,10 @@ import { SqliteDialect, } from 'kysely'; import { findIndex, isError, last, map, once, slice } from 'lodash-es'; -import { attempt } from '../../util/index.ts'; -import { LoggerFactory } from '../../util/logging/LoggerFactory.ts'; import { DirectMigrationProvider, LegacyMigrationNameToNewMigrationName, -} from '../migrations/DirectMigrationProvider.ts'; +} from '../migration/DirectMigrationProvider.ts'; import { DB } from './schema/db.ts'; const MigrationTableName = 'migrations'; @@ -23,7 +23,7 @@ let _directDbAccess: Kysely; const logger = once(() => LoggerFactory.child({ className: 'DirectDBAccess' })); -export const initDirectDbAccess = once((dbName: string) => { +export const initDatabaseAccess = once((dbName: string) => { _directDbAccess = new Kysely({ dialect: new SqliteDialect({ database: new Sqlite(dbName, { @@ -58,11 +58,11 @@ export const initDirectDbAccess = once((dbName: string) => { }); }); -export const directDbAccess = () => _directDbAccess; +export const getDatabase = () => _directDbAccess; function getMigrator() { return new Migrator({ - db: directDbAccess(), + db: getDatabase(), provider: new DirectMigrationProvider(), migrationTableName: MigrationTableName, migrationLockTableName: MigrationLockTableName, @@ -70,7 +70,7 @@ function getMigrator() { } export async function syncMigrationTablesIfNecessary() { - const tables = await directDbAccess().introspection.getTables({ + const tables = await getDatabase().introspection.getTables({ withInternalKyselyTables: true, }); @@ -93,7 +93,7 @@ export async function syncMigrationTablesIfNecessary() { await migrator.migrateUp(); const result = await attempt(async () => { - const previouslyRunLegacyMigrations = await directDbAccess() + const previouslyRunLegacyMigrations = await getDatabase() .selectFrom('mikroOrmMigrations') .selectAll() .orderBy('id asc') @@ -139,7 +139,7 @@ export async function syncMigrationTablesIfNecessary() { logger().debug('Fast-forwarding migrations: %O', newMigrationRows); // eslint-disable-next-line @typescript-eslint/no-explicit-any - await (directDbAccess() as Kysely) + await (getDatabase() as Kysely) .insertInto(MigrationTableName) .values(newMigrationRows) .execute(); @@ -149,11 +149,11 @@ export async function syncMigrationTablesIfNecessary() { // Try to reset state so we can try again on the next run if (isError(result)) { await migrator.migrateDown(); - await directDbAccess() + await getDatabase() .schema.dropTable(MigrationTableName) .ifExists() .execute(); - await directDbAccess() + await getDatabase() .schema.dropTable(MigrationLockTableName) .ifExists() .execute(); diff --git a/server/src/dao/fillerDB.ts b/server/src/db/FillerListDB.ts similarity index 88% rename from server/src/dao/fillerDB.ts rename to server/src/db/FillerListDB.ts index f3d187c1..fd52c5cc 100644 --- a/server/src/dao/fillerDB.ts +++ b/server/src/db/FillerListDB.ts @@ -1,3 +1,5 @@ +import { ChannelCache } from '@/stream/ChannelCache.ts'; +import { isNonEmptyString } from '@/util/index.ts'; import { CreateFillerListRequest, UpdateFillerListRequest, @@ -23,21 +25,16 @@ import { values, } from 'lodash-es'; import { v4 } from 'uuid'; -import { ChannelCache } from '../stream/ChannelCache.js'; -import { isNonEmptyString } from '../util/index.js'; -import { ProgramConverter } from './converters/programConverters.js'; -import { ChannelFillerShowWithContent } from './direct/derivedTypes.js'; -import { directDbAccess } from './direct/directDbAccess.js'; -import { withFillerPrograms } from './direct/programQueryHelpers.js'; -import { ChannelFillerShow } from './direct/schema/Channel.ts'; -import { - NewFillerShow, - NewFillerShowContent, -} from './direct/schema/FillerShow.js'; -import { programExternalIdString } from './direct/schema/Program.js'; -import { DB } from './direct/schema/db.js'; -import { ProgramDB } from './programDB.js'; -import { createPendingProgramIndexMap } from './programHelpers.js'; +import { getDatabase } from './DBAccess.ts'; +import { ProgramDB } from './ProgramDB.ts'; +import { ProgramConverter } from './converters/ProgramConverter.ts'; +import { createPendingProgramIndexMap } from './programHelpers.ts'; +import { withFillerPrograms } from './programQueryHelpers.ts'; +import { ChannelFillerShow } from './schema/Channel.ts'; +import { NewFillerShow, NewFillerShowContent } from './schema/FillerShow.ts'; +import { programExternalIdString } from './schema/Program.ts'; +import { DB } from './schema/db.ts'; +import { ChannelFillerShowWithContent } from './schema/derivedTypes.js'; export class FillerDB { #programConverter: ProgramConverter = new ProgramConverter(); @@ -48,7 +45,7 @@ export class FillerDB { ) {} getFiller(id: string) { - return directDbAccess() + return getDatabase() .selectFrom('fillerShow') .where('uuid', '=', id) .selectAll() @@ -96,7 +93,7 @@ export class FillerDB { }) satisfies NewFillerShowContent, ); - await directDbAccess() + await getDatabase() .transaction() .execute(async (tx) => { await tx @@ -111,7 +108,7 @@ export class FillerDB { } if (updateRequest.name) { - await directDbAccess() + await getDatabase() .updateTable('fillerShow') .where('uuid', '=', filler.uuid) .set({ name: updateRequest.name }) @@ -140,7 +137,7 @@ export class FillerDB { createRequest.programs, ); - await directDbAccess().insertInto('fillerShow').values(filler).execute(); + await getDatabase().insertInto('fillerShow').values(filler).execute(); const persistedFillerShowContent = map( persisted, @@ -161,7 +158,7 @@ export class FillerDB { }) satisfies NewFillerShowContent, ); - await directDbAccess() + await getDatabase() .insertInto('fillerShowContent') .values([...persistedFillerShowContent, ...newFillerShowContent]) .execute(); @@ -171,7 +168,7 @@ export class FillerDB { // Returns all channels a given filler list is a part of async getFillerChannels(id: string) { - return directDbAccess() + return getDatabase() .selectFrom('channelFillerShow') .where('channelFillerShow.fillerShowUuid', '=', id) .innerJoin('channel', 'channel.uuid', 'channelFillerShow.channelUuid') @@ -180,7 +177,7 @@ export class FillerDB { } async deleteFiller(id: string): Promise { - await directDbAccess() + await getDatabase() .transaction() .execute(async (tx) => { const relevantChannelFillers = await tx @@ -291,7 +288,7 @@ export class FillerDB { // Specifically cast these down for now because our TaggedType type is not portable async getAllFillerIds(): Promise { - const ids = await directDbAccess() + const ids = await getDatabase() .selectFrom('fillerShow') .select(['uuid']) .execute(); @@ -299,7 +296,7 @@ export class FillerDB { } async getAllFillers() { - return await directDbAccess() + return await getDatabase() .selectFrom('fillerShow') .selectAll() .select((eb) => @@ -319,7 +316,7 @@ export class FillerDB { } async getFillerPrograms(id: string) { - const programs = await directDbAccess() + const programs = await getDatabase() .selectFrom('fillerShow') .where('fillerShow.uuid', '=', id) .select((eb) => @@ -335,14 +332,14 @@ export class FillerDB { .executeTakeFirst(); return map(programs?.fillerContent, (program) => - this.#programConverter.directEntityToContentProgramSync(program, []), + this.#programConverter.programDaoToContentProgram(program, []), ); } async getFillersFromChannel( channelId: string, ): Promise { - return directDbAccess() + return getDatabase() .selectFrom('channelFillerShow') .where('channelFillerShow.channelUuid', '=', channelId) .innerJoin( diff --git a/server/src/dao/InMemoryCachedDbAdapter.ts b/server/src/db/InMemoryCachedDbAdapter.ts similarity index 100% rename from server/src/dao/InMemoryCachedDbAdapter.ts rename to server/src/db/InMemoryCachedDbAdapter.ts diff --git a/server/src/dao/programDB.ts b/server/src/db/ProgramDB.ts similarity index 93% rename from server/src/dao/programDB.ts rename to server/src/db/ProgramDB.ts index ac76cb7e..627eded7 100644 --- a/server/src/dao/programDB.ts +++ b/server/src/db/ProgramDB.ts @@ -1,3 +1,13 @@ +import { GlobalScheduler } from '@/services/Scheduler.ts'; +import { ReconcileProgramDurationsTask } from '@/tasks/ReconcileProgramDurationsTask.ts'; +import { AnonymousTask } from '@/tasks/Task.ts'; +import { JellyfinTaskQueue, PlexTaskQueue } from '@/tasks/TaskQueue.ts'; +import { SaveJellyfinProgramExternalIdsTask } from '@/tasks/jellyfin/SaveJellyfinProgramExternalIdsTask.ts'; +import { SavePlexProgramExternalIdsTask } from '@/tasks/plex/SavePlexProgramExternalIdsTask.ts'; +import { Maybe } from '@/types/util.ts'; +import { devAssert } from '@/util/debug.ts'; +import { LoggerFactory } from '@/util/logging/LoggerFactory.ts'; +import { Timer } from '@/util/perf.ts'; import { createExternalId } from '@tunarr/shared'; import { seq } from '@tunarr/shared/util'; import { @@ -36,36 +46,23 @@ import { import { MarkOptional, MarkRequired } from 'ts-essentials'; import { P, match } from 'ts-pattern'; import { v4 } from 'uuid'; -import { GlobalScheduler } from '../services/scheduler.js'; -import { ReconcileProgramDurationsTask } from '../tasks/ReconcileProgramDurationsTask.js'; -import { AnonymousTask } from '../tasks/Task.js'; -import { JellyfinTaskQueue, PlexTaskQueue } from '../tasks/TaskQueue.js'; -import { SaveJellyfinProgramExternalIdsTask } from '../tasks/jellyfin/SaveJellyfinProgramExternalIdsTask.js'; -import { SavePlexProgramExternalIdsTask } from '../tasks/plex/SavePlexProgramExternalIdsTask.js'; -import { Maybe } from '../types/util.ts'; -import { devAssert } from '../util/debug.js'; import { flatMapAsyncSeq, groupByUniq, groupByUniqProp, isNonEmptyString, mapToObj, -} from '../util/index.js'; -import { LoggerFactory } from '../util/logging/LoggerFactory.js'; -import { Timer } from '../util/perf.js'; -import { ProgramGroupingMinter } from './converters/ProgramGroupingMinter.js'; -import { ProgramMinterFactory } from './converters/ProgramMinter.js'; -import { ProgramConverter } from './converters/programConverters.js'; -import { ProgramExternalIdType } from './custom_types/ProgramExternalIdType.js'; +} from '../util/index.ts'; +import { getDatabase } from './DBAccess.ts'; +import { ProgramConverter } from './converters/ProgramConverter.ts'; +import { ProgramGroupingMinter } from './converters/ProgramGroupingMinter.ts'; +import { ProgramMinterFactory } from './converters/ProgramMinter.ts'; +import { ProgramExternalIdType } from './custom_types/ProgramExternalIdType.ts'; import { ProgramSourceType, programSourceTypeFromString, -} from './custom_types/ProgramSourceType.js'; -import { - ProgramGroupingWithExternalIds, - ProgramWithRelations, -} from './direct/derivedTypes.js'; -import { directDbAccess } from './direct/directDbAccess.js'; +} from './custom_types/ProgramSourceType.ts'; +import { upsertRawProgramExternalIds } from './programExternalIdHelpers.ts'; import { AllProgramJoins, ProgramUpsertFields, @@ -77,24 +74,29 @@ import { withTrackArtist, withTvSeason, withTvShow, -} from './direct/programQueryHelpers.js'; +} from './programQueryHelpers.ts'; import { - NewProgram as NewRawProgram, - Program as RawProgram, + NewProgramDao as NewRawProgram, + ProgramType, + ProgramDao as RawProgram, programExternalIdString, -} from './direct/schema/Program.js'; -import { ProgramType } from './direct/schema/Program.ts'; +} from './schema/Program.ts'; import { NewProgramExternalId, NewProgramExternalId as NewRawProgramExternalId, + ProgramExternalId, ProgramExternalIdKeys, -} from './direct/schema/ProgramExternalId.js'; -import { ProgramExternalId } from './direct/schema/ProgramExternalId.ts'; -import { NewProgramGrouping } from './direct/schema/ProgramGrouping.js'; -import { ProgramGroupingType } from './direct/schema/ProgramGrouping.ts'; -import { NewProgramGroupingExternalId } from './direct/schema/ProgramGroupingExternalId.js'; -import { DB } from './direct/schema/db.js'; -import { upsertRawProgramExternalIds } from './programExternalIdHelpers.js'; +} from './schema/ProgramExternalId.ts'; +import { + NewProgramGrouping, + ProgramGroupingType, +} from './schema/ProgramGrouping.ts'; +import { NewProgramGroupingExternalId } from './schema/ProgramGroupingExternalId.ts'; +import { DB } from './schema/db.ts'; +import { + ProgramDaoWithRelations, + ProgramGroupingWithExternalIds, +} from './schema/derivedTypes.js'; type ValidatedContentProgram = MarkRequired< ContentProgram, @@ -123,7 +125,7 @@ export class ProgramDB { private timer = new Timer(this.logger); async getProgramById(id: string) { - return directDbAccess() + return getDatabase() .selectFrom('program') .selectAll() .select((eb) => withProgramExternalIds(eb, ProgramExternalIdKeys)) @@ -135,7 +137,7 @@ export class ProgramDB { id: string, externalIdTypes?: ProgramExternalIdType[], ) { - return await directDbAccess() + return await getDatabase() .selectFrom('programExternalId') .selectAll() .where('programExternalId.programUuid', '=', id) @@ -146,7 +148,7 @@ export class ProgramDB { } async getShowIdFromTitle(title: string) { - const matchedGrouping = await directDbAccess() + const matchedGrouping = await getDatabase() .selectFrom('programGrouping') .select('uuid') .where('title', '=', title) @@ -157,7 +159,7 @@ export class ProgramDB { } async updateProgramDuration(programId: string, duration: number) { - return await directDbAccess() + return await getDatabase() .updateTable('program') .where('uuid', '=', programId) .set({ @@ -169,10 +171,10 @@ export class ProgramDB { async getProgramsByIds( ids: string[], batchSize: number = 500, - ): Promise { - const results: ProgramWithRelations[] = []; + ): Promise { + const results: ProgramDaoWithRelations[] = []; for (const idChunk of chunk(ids, batchSize)) { - const res = await directDbAccess() + const res = await getDatabase() .selectFrom('program') .selectAll() .select(withTrackAlbum) @@ -188,7 +190,7 @@ export class ProgramDB { } async getProgramGrouping(id: string) { - return directDbAccess() + return getDatabase() .selectFrom('programGrouping') .selectAll() .select(withProgramGroupingExternalIds) @@ -208,7 +210,7 @@ export class ProgramDB { // It would be better if we didn'thave to do this in two queries... if (p) { - const eids = await directDbAccess() + const eids = await getDatabase() .selectFrom('programGroupingExternalId') .where('groupUuid', '=', p.uuid) .selectAll() @@ -226,10 +228,10 @@ export class ProgramDB { const converter = new ProgramConverter(); const allIds = [...ids]; - const programsByExternalIds: ProgramWithRelations[] = []; + const programsByExternalIds: ProgramDaoWithRelations[] = []; for (const idChunk of chunk(allIds, 200)) { programsByExternalIds.push( - ...(await directDbAccess() + ...(await getDatabase() .selectFrom('programExternalId') .select((eb) => withProgramByExternalId(eb, { joins: AllProgramJoins }), @@ -256,7 +258,7 @@ export class ProgramDB { return groupByUniq( map(programsByExternalIds, (program) => - converter.directEntityToContentProgramSync( + converter.programDaoToContentProgram( program, program.externalIds ?? [], ), @@ -276,7 +278,7 @@ export class ProgramDB { const externalIds = await flatMapAsyncSeq( chunk([...ids], chunkSize), (idChunk) => { - return directDbAccess() + return getDatabase() .selectFrom('programExternalId') .selectAll() .where((eb) => @@ -321,7 +323,7 @@ export class ProgramDB { 'directFilePath' | 'externalFilePath' >, ) { - const existingRatingKey = await directDbAccess() + const existingRatingKey = await getDatabase() .selectFrom('programExternalId') .selectAll() .where((eb) => @@ -335,7 +337,7 @@ export class ProgramDB { if (isNil(existingRatingKey)) { const now = +dayjs(); - return await directDbAccess() + return await getDatabase() .insertInto('programExternalId') .values({ uuid: v4(), @@ -349,7 +351,7 @@ export class ProgramDB { .returningAll() .executeTakeFirstOrThrow(); } else { - await directDbAccess() + await getDatabase() .updateTable('programExternalId') .set({ externalKey: details.externalKey, @@ -366,7 +368,7 @@ export class ProgramDB { ) .where('uuid', '=', existingRatingKey.uuid) .executeTakeFirst(); - return await directDbAccess() + return await getDatabase() .selectFrom('programExternalId') .selectAll() .where('uuid', '=', existingRatingKey.uuid) @@ -379,7 +381,7 @@ export class ProgramDB { newExternalId: NewProgramExternalId, oldExternalId?: ProgramExternalId, ) { - await directDbAccess() + await getDatabase() .transaction() .execute(async (tx) => { if (oldExternalId) { @@ -563,7 +565,7 @@ export class ProgramDB { await this.timer.timeAsync('programUpsert', async () => { for (const c of chunk(programsToPersist, programUpsertBatchSize)) { upsertedPrograms.push( - ...(await directDbAccess() + ...(await getDatabase() .transaction() .execute((tx) => tx @@ -800,7 +802,7 @@ export class ProgramDB { const existingGroupings = await this.timer.timeAsync( `selecting grouping external ids (${allGroupingKeys.length})`, () => - directDbAccess() + getDatabase() .selectFrom('programGroupingExternalId') .where((eb) => { return eb.and([ @@ -991,7 +993,7 @@ export class ProgramDB { if (!isEmpty(groupings)) { await this.timer.timeAsync('upsert program_groupings', () => - directDbAccess() + getDatabase() .transaction() .execute((tx) => tx @@ -1004,7 +1006,7 @@ export class ProgramDB { if (!isEmpty(externalIds)) { await this.timer.timeAsync('upsert program_grouping external ids', () => - directDbAccess() + getDatabase() .transaction() .execute((tx) => tx @@ -1020,7 +1022,7 @@ export class ProgramDB { if (hasUpdates) { // Surprisingly it's faster to do these all at once... await this.timer.timeAsync('update program relations', () => - directDbAccess() + getDatabase() .transaction() .execute(async (tx) => { // const allProgramIds = flatMap(values(updatesByType), (set) => [ diff --git a/server/src/dao/SchemaBackedDbAdapter.ts b/server/src/db/SchemaBackedJsonDBAdapter.ts similarity index 93% rename from server/src/dao/SchemaBackedDbAdapter.ts rename to server/src/db/SchemaBackedJsonDBAdapter.ts index fcacbdd5..9ad02030 100644 --- a/server/src/dao/SchemaBackedDbAdapter.ts +++ b/server/src/db/SchemaBackedJsonDBAdapter.ts @@ -1,11 +1,11 @@ +import { Nullable } from '@/types/util.ts'; +import { isProduction } from '@/util/index.ts'; +import { LoggerFactory } from '@/util/logging/LoggerFactory.ts'; import { merge } from 'lodash-es'; import { Adapter } from 'lowdb'; import { TextFile } from 'lowdb/node'; import { PathLike } from 'node:fs'; import { z } from 'zod'; -import { Nullable } from '../types/util.ts'; -import { isProduction } from '../util/index.ts'; -import { LoggerFactory } from '../util/logging/LoggerFactory.ts'; export class SchemaBackedDbAdapter> implements Adapter diff --git a/server/src/dao/settings.ts b/server/src/db/SettingsDB.ts similarity index 94% rename from server/src/dao/settings.ts rename to server/src/db/SettingsDB.ts index 9daa495a..10e864e7 100644 --- a/server/src/dao/settings.ts +++ b/server/src/db/SettingsDB.ts @@ -1,3 +1,7 @@ +import { globalOptions } from '@/globals.ts'; +import { TypedEventEmitter } from '@/types/eventEmitter.ts'; +import { isProduction } from '@/util/index.ts'; +import { Logger, LoggerFactory } from '@/util/logging/LoggerFactory.ts'; import { FfmpegSettings, HdhrSettings, @@ -26,16 +30,12 @@ import path from 'path'; import { DeepPartial, DeepReadonly } from 'ts-essentials'; import { v4 as uuidv4 } from 'uuid'; import { z } from 'zod'; -import { globalOptions } from '../globals.js'; -import { TypedEventEmitter } from '../types/eventEmitter.js'; import { getDefaultLogDirectory, getDefaultLogLevel, -} from '../util/defaults.js'; -import { isProduction } from '../util/index.js'; -import { Logger, LoggerFactory } from '../util/logging/LoggerFactory.js'; -import { SchemaBackedDbAdapter } from './SchemaBackedDbAdapter.js'; -import { SyncSchemaBackedDbAdapter } from './SyncSchemaBackedDbAdapter.js'; +} from '../util/defaults.ts'; +import { SchemaBackedDbAdapter } from './SchemaBackedJsonDBAdapter.ts'; +import { SyncSchemaBackedDbAdapter } from './SyncSchemaBackedJSONDBAdapter.ts'; // Version 1 -> 2: slot show ids changed to be the program_grouping ID // rather than the show name. diff --git a/server/src/dao/SyncSchemaBackedDbAdapter.ts b/server/src/db/SyncSchemaBackedJSONDBAdapter.ts similarity index 93% rename from server/src/dao/SyncSchemaBackedDbAdapter.ts rename to server/src/db/SyncSchemaBackedJSONDBAdapter.ts index ab3df756..622727b2 100644 --- a/server/src/dao/SyncSchemaBackedDbAdapter.ts +++ b/server/src/db/SyncSchemaBackedJSONDBAdapter.ts @@ -1,11 +1,11 @@ +import { Nullable } from '@/types/util.ts'; +import { isProduction } from '@/util/index.ts'; +import { LoggerFactory } from '@/util/logging/LoggerFactory.ts'; import { merge } from 'lodash-es'; import { SyncAdapter } from 'lowdb'; import { TextFileSync } from 'lowdb/node'; import { PathLike } from 'node:fs'; import { z } from 'zod'; -import { Nullable } from '../types/util.ts'; -import { isProduction } from '../util/index.ts'; -import { LoggerFactory } from '../util/logging/LoggerFactory.ts'; export class SyncSchemaBackedDbAdapter> implements SyncAdapter diff --git a/server/src/dao/backup/ArchiveDatabaseBackup.ts b/server/src/db/backup/ArchiveDatabaseBackup.ts similarity index 94% rename from server/src/dao/backup/ArchiveDatabaseBackup.ts rename to server/src/db/backup/ArchiveDatabaseBackup.ts index afad1f02..6d88327c 100644 --- a/server/src/dao/backup/ArchiveDatabaseBackup.ts +++ b/server/src/db/backup/ArchiveDatabaseBackup.ts @@ -1,3 +1,9 @@ +import { SettingsDB } from '@/db/SettingsDB.ts'; +import { asyncPool } from '@/util/asyncPool.ts'; +import { getDatabasePath } from '@/util/databaseDirectoryUtil.ts'; +import { fileExists } from '@/util/fsUtil.ts'; +import { isDocker } from '@/util/isDocker.ts'; +import { LoggerFactory } from '@/util/logging/LoggerFactory.ts'; import { FileBackupOutput } from '@tunarr/types/schemas'; import archiver from 'archiver'; import dayjs from 'dayjs'; @@ -6,12 +12,6 @@ import { createWriteStream } from 'node:fs'; import fs from 'node:fs/promises'; import os from 'node:os'; import path from 'node:path'; -import { asyncPool } from '../../util/asyncPool.ts'; -import { fileExists } from '../../util/fsUtil.js'; -import { isDocker } from '../../util/isDocker.js'; -import { LoggerFactory } from '../../util/logging/LoggerFactory.ts'; -import { getDatabasePath } from '../databaseDirectoryUtil.ts'; -import { SettingsDB } from '../settings.ts'; import { BackupResult, DatabaseBackup } from './DatabaseBackup.ts'; import { SqliteDatabaseBackup } from './SqliteDatabaseBackup.ts'; diff --git a/server/src/dao/backup/DatabaseBackup.ts b/server/src/db/backup/DatabaseBackup.ts similarity index 88% rename from server/src/dao/backup/DatabaseBackup.ts rename to server/src/db/backup/DatabaseBackup.ts index 855f4f3e..905d67f3 100644 --- a/server/src/dao/backup/DatabaseBackup.ts +++ b/server/src/db/backup/DatabaseBackup.ts @@ -1,4 +1,4 @@ -import { SettingsDB } from '../settings.ts'; +import { SettingsDB } from '@/db/SettingsDB.ts'; export type SuccessfulBackupResult = { type: 'success'; diff --git a/server/src/dao/backup/DatabaseBackupStrategy.ts b/server/src/db/backup/DatabaseBackupStrategy.ts similarity index 100% rename from server/src/dao/backup/DatabaseBackupStrategy.ts rename to server/src/db/backup/DatabaseBackupStrategy.ts diff --git a/server/src/dao/backup/SqliteDatabaseBackup.ts b/server/src/db/backup/SqliteDatabaseBackup.ts similarity index 85% rename from server/src/dao/backup/SqliteDatabaseBackup.ts rename to server/src/db/backup/SqliteDatabaseBackup.ts index 8b139d4c..ec807b8d 100644 --- a/server/src/dao/backup/SqliteDatabaseBackup.ts +++ b/server/src/db/backup/SqliteDatabaseBackup.ts @@ -1,6 +1,6 @@ +import { dbOptions } from '@/globals.ts'; +import { LoggerFactory } from '@/util/logging/LoggerFactory.ts'; import BetterSqlite3 from 'better-sqlite3'; -import { dbOptions } from '../../globals.ts'; -import { LoggerFactory } from '../../util/logging/LoggerFactory.ts'; export class SqliteDatabaseBackup { #logger = LoggerFactory.child({ className: SqliteDatabaseBackup.name }); diff --git a/server/src/dao/channelDb.test.ts b/server/src/db/channelDb.test.ts similarity index 86% rename from server/src/dao/channelDb.test.ts rename to server/src/db/channelDb.test.ts index 41ab6060..dbd91a57 100644 --- a/server/src/dao/channelDb.test.ts +++ b/server/src/db/channelDb.test.ts @@ -1,7 +1,7 @@ +import { setGlobalOptions } from '@/globals.ts'; import fs from 'fs/promises'; import { join } from 'path'; import temp from 'temp'; -import { setGlobalOptions } from '../globals.js'; beforeAll(async () => { temp.track(); diff --git a/server/src/dao/converters/programConverters.ts b/server/src/db/converters/ProgramConverter.ts similarity index 77% rename from server/src/dao/converters/programConverters.ts rename to server/src/db/converters/ProgramConverter.ts index 1f701c43..67d6cf16 100644 --- a/server/src/dao/converters/programConverters.ts +++ b/server/src/db/converters/ProgramConverter.ts @@ -1,3 +1,8 @@ +import { getDatabase } from '@/db/DBAccess.ts'; +import { ProgramType } from '@/db/schema/Program.ts'; +import { MinimalProgramExternalId } from '@/db/schema/ProgramExternalId.ts'; +import { isNonEmptyString, nullToUndefined } from '@/util/index.ts'; +import { LoggerFactory } from '@/util/logging/LoggerFactory.ts'; import { seq } from '@tunarr/shared/util'; import { ChannelProgram, @@ -12,25 +17,18 @@ import { import { find, isNil, omitBy } from 'lodash-es'; import { DeepPartial, MarkRequired } from 'ts-essentials'; import { isPromise } from 'util/types'; -import { isNonEmptyString, nullToUndefined } from '../../util/index.js'; -import { LoggerFactory } from '../../util/logging/LoggerFactory.js'; import { LineupItem, OfflineItem, RedirectItem, isOfflineItem, isRedirectItem, -} from '../derived_types/Lineup.js'; +} from '../derived_types/Lineup.ts'; import { + ChannelWithPrograms, ChannelWithRelations, - ProgramWithRelations, - ChannelWithRelations as RawChannel, - ChannelWithPrograms as RawChannelWithPrograms, - ProgramWithRelations as RawProgram, -} from '../direct/derivedTypes.js'; -import { directDbAccess } from '../direct/directDbAccess.js'; -import { ProgramType } from '../direct/schema/Program.ts'; -import { MinimalProgramExternalId } from '../direct/schema/ProgramExternalId.js'; + ProgramDaoWithRelations, +} from '../schema/derivedTypes.js'; /** * Converts DB types to API types @@ -41,26 +39,26 @@ export class ProgramConverter { className: ProgramConverter.name, }); - directLineupItemToChannelProgram( + lineupItemToChannelProgram( channel: ChannelWithRelations, item: LineupItem, channelReferences: MarkRequired< - DeepPartial, + DeepPartial, 'uuid' | 'number' | 'name' >[], // TODO fix this up... - preMaterializedProgram?: ProgramWithRelations, + preMaterializedProgram?: ProgramDaoWithRelations, ): ChannelProgram | null; - directLineupItemToChannelProgram( - channel: RawChannelWithPrograms, + lineupItemToChannelProgram( + channel: ChannelWithPrograms, item: LineupItem, channelReferences: MarkRequired< - DeepPartial, + DeepPartial, 'uuid' | 'number' | 'name' >[], // TODO fix this up... - preMaterializedProgram?: ProgramWithRelations, + preMaterializedProgram?: ProgramDaoWithRelations, ): ChannelProgram | null { if (isOfflineItem(item)) { - return this.directOfflineLineupItemToProgram(channel, item); + return this.offlineLineupItemToProgram(channel, item); } else if (isRedirectItem(item)) { const redirectChannel = find(channelReferences, { uuid: item.channel }); if (isNil(redirectChannel)) { @@ -69,12 +67,12 @@ export class ProgramConverter { channel.uuid, item.channel, ); - return this.directOfflineLineupItemToProgram(channel, { + return this.offlineLineupItemToProgram(channel, { type: 'offline', durationMs: item.durationMs, }); } - return this.directRedirectLineupItemToProgram(item, redirectChannel); + return this.redirectLineupItemToProgram(item, redirectChannel); } else { const program = preMaterializedProgram && preMaterializedProgram.uuid === item.id @@ -84,15 +82,15 @@ export class ProgramConverter { return null; } - return this.directEntityToContentProgramSync( + return this.programDaoToContentProgram( program, program.externalIds ?? [], // TODO fill in external IDs here ); } } - directEntityToContentProgramSync( - program: RawProgram, + programDaoToContentProgram( + program: ProgramDaoWithRelations, externalIds: MinimalProgramExternalId[], ): ContentProgram { let extraFields: Partial = {}; @@ -151,8 +149,8 @@ export class ProgramConverter { }; } - directOfflineLineupItemToProgram( - channel: RawChannel, + offlineLineupItemToProgram( + channel: ChannelWithRelations, program: OfflineItem, persisted: boolean = true, ): FlexProgram { @@ -166,14 +164,17 @@ export class ProgramConverter { redirectLineupItemToProgram( item: RedirectItem, - channel: MarkRequired, 'name' | 'number'>, + channel: MarkRequired, 'name' | 'number'>, ): RedirectProgram; redirectLineupItemToProgram( item: RedirectItem, - channel?: MarkRequired, 'name' | 'number'>, + channel?: MarkRequired< + DeepPartial, + 'name' | 'number' + >, ): Promise | RedirectProgram { const loadedChannel = isNil(channel) - ? directDbAccess() + ? getDatabase() .selectFrom('channel') .select(['uuid', 'number', 'name']) .where('uuid', '=', item.channel) @@ -186,23 +187,9 @@ export class ProgramConverter { } } - directRedirectLineupItemToProgram( - item: RedirectItem, - channel: MarkRequired, 'uuid' | 'number' | 'name'>, - ): RedirectProgram { - return { - persisted: true, - type: 'redirect', - channel: item.channel, - channelName: channel.name, - channelNumber: channel.number, - duration: item.durationMs, - }; - } - private toRedirectChannelInternal( item: RedirectItem, - channel: MarkRequired, 'name' | 'number'>, + channel: MarkRequired, 'name' | 'number'>, ): RedirectProgram { return { persisted: true, diff --git a/server/src/dao/converters/ProgramGroupingMinter.ts b/server/src/db/converters/ProgramGroupingMinter.ts similarity index 96% rename from server/src/dao/converters/ProgramGroupingMinter.ts rename to server/src/db/converters/ProgramGroupingMinter.ts index e339d259..027e3030 100644 --- a/server/src/dao/converters/ProgramGroupingMinter.ts +++ b/server/src/db/converters/ProgramGroupingMinter.ts @@ -1,3 +1,6 @@ +import { ProgramExternalIdType } from '@/db/custom_types/ProgramExternalIdType.ts'; +import type { NewProgramGroupingExternalId } from '@/db/schema/ProgramGroupingExternalId.ts'; +import { isNonEmptyString } from '@/util/index.ts'; import { JellyfinItem } from '@tunarr/types/jellyfin'; import { PlexEpisode, PlexMusicTrack } from '@tunarr/types/plex'; import { ContentProgramOriginalProgram } from '@tunarr/types/schemas'; @@ -5,13 +8,10 @@ import dayjs from 'dayjs'; import { find } from 'lodash-es'; import { P, match } from 'ts-pattern'; import { v4 } from 'uuid'; -import { isNonEmptyString } from '../../util/index.ts'; -import { ProgramExternalIdType } from '../custom_types/ProgramExternalIdType.ts'; import { ProgramGroupingType, type NewProgramGrouping, -} from '../direct/schema/ProgramGrouping.ts'; -import type { NewProgramGroupingExternalId } from '../direct/schema/ProgramGroupingExternalId.d.ts'; +} from '../schema/ProgramGrouping.ts'; type MintedProgramGrouping = { grouping: NewProgramGrouping; diff --git a/server/src/dao/converters/ProgramMinter.ts b/server/src/db/converters/ProgramMinter.ts similarity index 96% rename from server/src/dao/converters/ProgramMinter.ts rename to server/src/db/converters/ProgramMinter.ts index 1e702301..eb808c25 100644 --- a/server/src/dao/converters/ProgramMinter.ts +++ b/server/src/db/converters/ProgramMinter.ts @@ -1,3 +1,6 @@ +import { ProgramSourceType } from '@/db/custom_types/ProgramSourceType.ts'; +import { NewProgramExternalId } from '@/db/schema/ProgramExternalId.ts'; +import { parsePlexGuid } from '@/util/externalIds.ts'; import { JellyfinItem } from '@tunarr/types/jellyfin'; import { PlexEpisode, @@ -10,17 +13,14 @@ import dayjs from 'dayjs'; import { compact, find, first, isError, isNil, map } from 'lodash-es'; import { P, match } from 'ts-pattern'; import { v4 } from 'uuid'; -import { parsePlexGuid } from '../../util/externalIds.js'; import { ProgramExternalIdType, programExternalIdTypeFromJellyfinProvider, -} from '../custom_types/ProgramExternalIdType.js'; -import { ProgramSourceType } from '../custom_types/ProgramSourceType.js'; +} from '../custom_types/ProgramExternalIdType.ts'; import { - NewProgram as NewRawProgram, + NewProgramDao as NewRawProgram, ProgramType, -} from '../direct/schema/Program.js'; -import { NewProgramExternalId } from '../direct/schema/ProgramExternalId.js'; +} from '../schema/Program.ts'; /** * Generates Program DB entities for Plex media diff --git a/server/src/dao/converters/channelConverters.ts b/server/src/db/converters/channelConverters.ts similarity index 89% rename from server/src/dao/converters/channelConverters.ts rename to server/src/db/converters/channelConverters.ts index 77b7ad15..0ae9c021 100644 --- a/server/src/dao/converters/channelConverters.ts +++ b/server/src/db/converters/channelConverters.ts @@ -1,12 +1,12 @@ +import { DefaultChannelIcon } from '@/db/schema/base.ts'; +import { ChannelAndLineup } from '@/types/internal.ts'; import { Channel } from '@tunarr/types'; import { filter } from 'lodash-es'; -import { ChannelAndLineup } from '../../types/internal.js'; import { isDefined, nilToUndefined, nullToUndefined, -} from '../../util/index.js'; -import { DefaultChannelIcon } from '../direct/schema/base.ts'; +} from '../../util/index.ts'; export const dbChannelToApiChannel = ({ channel, diff --git a/server/src/dao/custom_types/ProgramExternalIdType.ts b/server/src/db/custom_types/ProgramExternalIdType.ts similarity index 89% rename from server/src/dao/custom_types/ProgramExternalIdType.ts rename to server/src/db/custom_types/ProgramExternalIdType.ts index 5718fa99..8ccfbe7e 100644 --- a/server/src/dao/custom_types/ProgramExternalIdType.ts +++ b/server/src/db/custom_types/ProgramExternalIdType.ts @@ -1,7 +1,7 @@ +import { MediaSourceType } from '@/db/schema/MediaSource.ts'; +import { enumKeys } from '@/util/enumUtil.ts'; import { ExternalIdType } from '@tunarr/types/schemas'; -import { enumKeys } from '../../util/enumUtil.js'; -import { MediaSourceType } from '../direct/schema/MediaSource.ts'; -import { ProgramSourceType } from './ProgramSourceType.js'; +import { ProgramSourceType } from './ProgramSourceType.ts'; export enum ProgramExternalIdType { PLEX = 'plex', diff --git a/server/src/dao/custom_types/ProgramSourceType.ts b/server/src/db/custom_types/ProgramSourceType.ts similarity index 87% rename from server/src/dao/custom_types/ProgramSourceType.ts rename to server/src/db/custom_types/ProgramSourceType.ts index 020713dd..1798389b 100644 --- a/server/src/dao/custom_types/ProgramSourceType.ts +++ b/server/src/db/custom_types/ProgramSourceType.ts @@ -1,5 +1,5 @@ -import { enumKeys } from '../../util/enumUtil.js'; -import { MediaSourceType } from '../direct/schema/MediaSource.ts'; +import { MediaSourceType } from '@/db/schema/MediaSource.ts'; +import { enumKeys } from '@/util/enumUtil.ts'; export enum ProgramSourceType { PLEX = 'plex', diff --git a/server/src/dao/derived_types/Lineup.ts b/server/src/db/derived_types/Lineup.ts similarity index 100% rename from server/src/dao/derived_types/Lineup.ts rename to server/src/db/derived_types/Lineup.ts diff --git a/server/src/dao/derived_types/StreamLineup.ts b/server/src/db/derived_types/StreamLineup.ts similarity index 98% rename from server/src/dao/derived_types/StreamLineup.ts rename to server/src/db/derived_types/StreamLineup.ts index 907633dd..fa12a2a1 100644 --- a/server/src/dao/derived_types/StreamLineup.ts +++ b/server/src/db/derived_types/StreamLineup.ts @@ -2,8 +2,8 @@ // but contain a bit more context and are used during an // active streaming session +import { MediaSourceType } from '@/db/schema/MediaSource.ts'; import { z } from 'zod'; -import { MediaSourceType } from '../direct/schema/MediaSource.ts'; const baseStreamLineupItemSchema = z.object({ originalTimestamp: z.number().nonnegative().optional(), diff --git a/server/src/dao/mediaSourceDB.ts b/server/src/db/mediaSourceDB.ts similarity index 92% rename from server/src/dao/mediaSourceDB.ts rename to server/src/db/mediaSourceDB.ts index 838660be..3ab44631 100644 --- a/server/src/dao/mediaSourceDB.ts +++ b/server/src/db/mediaSourceDB.ts @@ -1,3 +1,5 @@ +import { Maybe } from '@/types/util.ts'; +import { groupByUniqProp, isNonEmptyString } from '@/util/index.ts'; import { InsertMediaSourceRequest, UpdateMediaSourceRequest, @@ -15,18 +17,16 @@ import { trimEnd, } from 'lodash-es'; import { v4 } from 'uuid'; -import { Maybe } from '../types/util.js'; -import { groupByUniqProp, isNonEmptyString } from '../util/index.js'; -import { ChannelDB } from './channelDb.js'; +import { ChannelDB } from './ChannelDB.ts'; -import { directDbAccess } from './direct/directDbAccess.js'; +import { booleanToNumber } from '@/util/sqliteUtil.ts'; +import { getDatabase } from './DBAccess.ts'; import { withProgramChannels, withProgramCustomShows, withProgramFillerShows, -} from './direct/programQueryHelpers.js'; -import { MediaSource, MediaSourceType } from './direct/schema/MediaSource.js'; -import { booleanToNumber } from './sqliteUtil.js'; +} from './programQueryHelpers.ts'; +import { MediaSource, MediaSourceType } from './schema/MediaSource.ts'; type Report = { type: 'channel' | 'custom-show' | 'filler'; @@ -45,11 +45,11 @@ export class MediaSourceDB { } async getAll(): Promise { - return directDbAccess().selectFrom('mediaSource').selectAll().execute(); + return getDatabase().selectFrom('mediaSource').selectAll().execute(); } async getById(id: string) { - return directDbAccess() + return getDatabase() .selectFrom('mediaSource') .selectAll() .where('mediaSource.uuid', '=', id) @@ -57,7 +57,7 @@ export class MediaSourceDB { } async getByName(name: string) { - return directDbAccess() + return getDatabase() .selectFrom('mediaSource') .selectAll() .where('mediaSource.name', '=', name) @@ -73,7 +73,7 @@ export class MediaSourceDB { type: MediaSourceType, nameOrId?: string, ): Promise> { - const found = await directDbAccess() + const found = await getDatabase() .selectFrom('mediaSource') .selectAll() .where('mediaSource.type', '=', type) @@ -98,7 +98,7 @@ export class MediaSourceDB { sourceType: MediaSourceType, nameOrClientId: string, ): Promise> { - return directDbAccess() + return getDatabase() .selectFrom('mediaSource') .selectAll() .where((eb) => @@ -119,7 +119,7 @@ export class MediaSourceDB { throw new Error(`MediaSource not found: ${id}`); } - await directDbAccess() + await getDatabase() .deleteFrom('mediaSource') .where('uuid', '=', id) .limit(1) @@ -152,7 +152,7 @@ export class MediaSourceDB { const sendChannelUpdates = server.type === 'plex' ? server.sendChannelUpdates ?? false : false; - await directDbAccess() + await getDatabase() .updateTable('mediaSource') .set({ name: server.name, @@ -177,14 +177,14 @@ export class MediaSourceDB { server.type === 'plex' ? server.sendGuideUpdates ?? false : false; const sendChannelUpdates = server.type === 'plex' ? server.sendChannelUpdates ?? false : false; - const index = await directDbAccess() + const index = await getDatabase() .selectFrom('mediaSource') .select((eb) => eb.fn.count('uuid').as('count')) .executeTakeFirst() .then((_) => _?.count ?? 0); const now = +dayjs(); - const newServer = await directDbAccess() + const newServer = await getDatabase() .insertInto('mediaSource') .values({ ...server, @@ -246,7 +246,7 @@ export class MediaSourceDB { // 2. use program_external_id table // 3. not delete programs if they still have another reference via // the external id table (program that exists on 2 servers) - const allPrograms = await directDbAccess() + const allPrograms = await getDatabase() .selectFrom('program') .selectAll() .where('sourceType', '=', serverType) @@ -296,7 +296,7 @@ export class MediaSourceDB { if (!isUpdate) { // Remove all associations of this program // TODO: See if we can just get this automatically with foreign keys... - await directDbAccess() + await getDatabase() .transaction() .execute(async (tx) => { for (const programChunk of chunk(allPrograms, 500)) { diff --git a/server/src/dao/programExternalIdHelpers.ts b/server/src/db/programExternalIdHelpers.ts similarity index 91% rename from server/src/dao/programExternalIdHelpers.ts rename to server/src/db/programExternalIdHelpers.ts index cb383391..ee0f2374 100644 --- a/server/src/dao/programExternalIdHelpers.ts +++ b/server/src/db/programExternalIdHelpers.ts @@ -1,9 +1,9 @@ +import { mapAsyncSeq } from '@/util/index.ts'; +import { LoggerFactory } from '@/util/logging/LoggerFactory.ts'; import { isValidSingleExternalIdType } from '@tunarr/types/schemas'; import { chunk, flatten, isEmpty, isUndefined, partition } from 'lodash-es'; -import { mapAsyncSeq } from '../util/index.ts'; -import { LoggerFactory } from '../util/logging/LoggerFactory.ts'; -import { directDbAccess } from './direct/directDbAccess.ts'; -import { NewProgramExternalId as NewRawProgramExternalId } from './direct/schema/ProgramExternalId.ts'; +import { getDatabase } from './DBAccess.ts'; +import { NewProgramExternalId as NewRawProgramExternalId } from './schema/ProgramExternalId.ts'; export const upsertRawProgramExternalIds = async ( externalIds: NewRawProgramExternalId[], @@ -25,7 +25,7 @@ export const upsertRawProgramExternalIds = async ( let singleIdPromise: Promise<{ uuid: string }[]>; if (!isEmpty(singles)) { singleIdPromise = mapAsyncSeq(chunk(singles, chunkSize), (singleChunk) => { - return directDbAccess() + return getDatabase() .transaction() .execute((tx) => tx @@ -53,7 +53,7 @@ export const upsertRawProgramExternalIds = async ( let multiIdPromise: Promise<{ uuid: string }[]>; if (!isEmpty(multiples)) { multiIdPromise = mapAsyncSeq(chunk(multiples, chunkSize), (multiChunk) => { - return directDbAccess() + return getDatabase() .transaction() .execute((tx) => tx diff --git a/server/src/dao/programHelpers.ts b/server/src/db/programHelpers.ts similarity index 95% rename from server/src/dao/programHelpers.ts rename to server/src/db/programHelpers.ts index 5a2617df..ea8507ff 100644 --- a/server/src/dao/programHelpers.ts +++ b/server/src/db/programHelpers.ts @@ -1,3 +1,4 @@ +import { isNonEmptyString } from '@/util/index.ts'; import { createExternalId } from '@tunarr/shared'; import { ContentProgram, @@ -6,7 +7,6 @@ import { isCustomProgram, } from '@tunarr/types'; import { reduce } from 'lodash-es'; -import { isNonEmptyString } from '../util/index.js'; // Takes a listing of programs and makes a mapping of a unique identifier, // which may differ when a program is persisted or not, to the original diff --git a/server/src/dao/direct/programQueryHelpers.ts b/server/src/db/programQueryHelpers.ts similarity index 98% rename from server/src/dao/direct/programQueryHelpers.ts rename to server/src/db/programQueryHelpers.ts index 5d82f0bc..0e688d46 100644 --- a/server/src/dao/direct/programQueryHelpers.ts +++ b/server/src/db/programQueryHelpers.ts @@ -7,18 +7,18 @@ import { import { jsonArrayFrom, jsonObjectFrom } from 'kysely/helpers/sqlite'; import { isBoolean, isEmpty, keys, merge, reduce } from 'lodash-es'; import { DeepPartial, DeepRequired, StrictExclude } from 'ts-essentials'; -import { directDbAccess } from './directDbAccess.js'; -import type { FillerShowTable as RawFillerShow } from './schema/FillerShow.d.ts'; +import { getDatabase } from './DBAccess.ts'; +import type { FillerShowTable as RawFillerShow } from './schema/FillerShow.js'; import { ProgramType, ProgramTable as RawProgram } from './schema/Program.ts'; import { ProgramExternalId, ProgramExternalIdFieldsWithAlias, -} from './schema/ProgramExternalId.js'; -import type { ProgramGroupingTable as RawProgramGrouping } from './schema/ProgramGrouping.d.ts'; +} from './schema/ProgramExternalId.ts'; +import type { ProgramGroupingTable as RawProgramGrouping } from './schema/ProgramGrouping.ts'; import { ProgramGroupingExternalId, ProgramGroupingExternalIdFieldsWithAlias, -} from './schema/ProgramGroupingExternalId.js'; +} from './schema/ProgramGroupingExternalId.ts'; import type { DB } from './schema/db.ts'; type ProgramGroupingFields = @@ -322,7 +322,7 @@ export function selectProgramsBuilder( defaultWithProgramOptions, optOverides, ); - return directDbAccess() + return getDatabase() .selectFrom('program') .select(opts.fields) .$if(!!opts.joins.trackAlbum, (qb) => diff --git a/server/src/dao/direct/schema/CachedImage.d.ts b/server/src/db/schema/CachedImage.d.ts similarity index 100% rename from server/src/dao/direct/schema/CachedImage.d.ts rename to server/src/db/schema/CachedImage.d.ts diff --git a/server/src/dao/direct/schema/Channel.ts b/server/src/db/schema/Channel.ts similarity index 100% rename from server/src/dao/direct/schema/Channel.ts rename to server/src/db/schema/Channel.ts diff --git a/server/src/dao/direct/schema/CustomShow.d.ts b/server/src/db/schema/CustomShow.d.ts similarity index 100% rename from server/src/dao/direct/schema/CustomShow.d.ts rename to server/src/db/schema/CustomShow.d.ts diff --git a/server/src/dao/direct/schema/FillerShow.d.ts b/server/src/db/schema/FillerShow.d.ts similarity index 100% rename from server/src/dao/direct/schema/FillerShow.d.ts rename to server/src/db/schema/FillerShow.d.ts diff --git a/server/src/dao/direct/schema/MediaSource.ts b/server/src/db/schema/MediaSource.ts similarity index 100% rename from server/src/dao/direct/schema/MediaSource.ts rename to server/src/db/schema/MediaSource.ts diff --git a/server/src/dao/direct/schema/MikroOrmMigrations.d.ts b/server/src/db/schema/MikroOrmMigrations.d.ts similarity index 100% rename from server/src/dao/direct/schema/MikroOrmMigrations.d.ts rename to server/src/db/schema/MikroOrmMigrations.d.ts diff --git a/server/src/dao/direct/schema/Program.ts b/server/src/db/schema/Program.ts similarity index 86% rename from server/src/dao/direct/schema/Program.ts rename to server/src/db/schema/Program.ts index e4b43957..5db4f934 100644 --- a/server/src/dao/direct/schema/Program.ts +++ b/server/src/db/schema/Program.ts @@ -43,10 +43,10 @@ export interface ProgramTable extends WithCreatedAt, WithUpdatedAt, WithUuid { year: number | null; } -export type Program = Selectable; -export type NewProgram = Insertable; -export type ProgramUpdate = Updateable; +export type ProgramDao = Selectable; +export type NewProgramDao = Insertable; +export type ProgramDaoUpdate = Updateable; -export function programExternalIdString(p: Program | NewProgram) { +export function programExternalIdString(p: ProgramDao | NewProgramDao) { return createExternalId(p.sourceType, p.externalSourceId, p.externalKey); } diff --git a/server/src/dao/direct/schema/ProgramExternalId.ts b/server/src/db/schema/ProgramExternalId.ts similarity index 100% rename from server/src/dao/direct/schema/ProgramExternalId.ts rename to server/src/db/schema/ProgramExternalId.ts diff --git a/server/src/dao/direct/schema/ProgramGrouping.ts b/server/src/db/schema/ProgramGrouping.ts similarity index 100% rename from server/src/dao/direct/schema/ProgramGrouping.ts rename to server/src/db/schema/ProgramGrouping.ts diff --git a/server/src/dao/direct/schema/ProgramGroupingExternalId.ts b/server/src/db/schema/ProgramGroupingExternalId.ts similarity index 100% rename from server/src/dao/direct/schema/ProgramGroupingExternalId.ts rename to server/src/db/schema/ProgramGroupingExternalId.ts diff --git a/server/src/dao/direct/schema/base.ts b/server/src/db/schema/base.ts similarity index 100% rename from server/src/dao/direct/schema/base.ts rename to server/src/db/schema/base.ts diff --git a/server/src/dao/direct/schema/db.ts b/server/src/db/schema/db.ts similarity index 73% rename from server/src/dao/direct/schema/db.ts rename to server/src/db/schema/db.ts index f24efe9c..a69d7910 100644 --- a/server/src/dao/direct/schema/db.ts +++ b/server/src/db/schema/db.ts @@ -1,4 +1,4 @@ -import type { CachedImageTable } from './CachedImage.d.ts'; +import type { CachedImageTable } from './CachedImage.js'; import { ChannelCustomShowsTable, ChannelFallbackTable, @@ -6,20 +6,14 @@ import { ChannelProgramsTable, ChannelTable, } from './Channel.ts'; -import type { - CustomShowContentTable, - CustomShowTable, -} from './CustomShow.d.ts'; -import type { - FillerShowContentTable, - FillerShowTable, -} from './FillerShow.d.ts'; -import type { MediaSourceTable } from './MediaSource.d.ts'; +import type { CustomShowContentTable, CustomShowTable } from './CustomShow.js'; +import type { FillerShowContentTable, FillerShowTable } from './FillerShow.js'; +import type { MediaSourceTable } from './MediaSource.ts'; import { MikroOrmMigrationsTable } from './MikroOrmMigrations.js'; import { ProgramTable } from './Program.ts'; -import type { ProgramExternalIdTable } from './ProgramExternalId.d.ts'; -import type { ProgramGroupingTable } from './ProgramGrouping.d.ts'; -import type { ProgramGroupingExternalIdTable } from './ProgramGroupingExternalId.d.ts'; +import type { ProgramExternalIdTable } from './ProgramExternalId.ts'; +import type { ProgramGroupingTable } from './ProgramGrouping.ts'; +import type { ProgramGroupingExternalIdTable } from './ProgramGroupingExternalId.ts'; export interface DB { cachedImage: CachedImageTable; diff --git a/server/src/dao/direct/derivedTypes.d.ts b/server/src/db/schema/derivedTypes.d.ts similarity index 70% rename from server/src/dao/direct/derivedTypes.d.ts rename to server/src/db/schema/derivedTypes.d.ts index 2c232b37..4476f38e 100644 --- a/server/src/dao/direct/derivedTypes.d.ts +++ b/server/src/db/schema/derivedTypes.d.ts @@ -1,14 +1,13 @@ +import { MarkNonNullable } from '@/types/util.ts'; import type { DeepNullable, MarkRequired } from 'ts-essentials'; -import { MarkNonNullable } from '../../types/util.ts'; -import { Channel, ChannelFillerShow } from './schema/Channel.ts'; -import { FillerShow } from './schema/FillerShow.js'; +import { Channel, ChannelFillerShow } from './Channel.ts'; +import { FillerShow } from './FillerShow.ts'; +import { ProgramDao } from './Program.ts'; +import { MinimalProgramExternalId } from './ProgramExternalId.ts'; +import { ProgramGrouping } from './ProgramGrouping.ts'; +import { ProgramGroupingExternalId } from './ProgramGroupingExternalId.ts'; -import { Program } from './schema/Program.ts'; -import { MinimalProgramExternalId } from './schema/ProgramExternalId.ts'; -import { ProgramGrouping } from './schema/ProgramGrouping.ts'; -import { ProgramGroupingExternalId } from './schema/ProgramGroupingExternalId.ts'; - -export type ProgramWithRelations = Program & { +export type ProgramDaoWithRelations = ProgramDao & { tvShow?: DeepNullable> | null; tvSeason?: DeepNullable> | null; trackArtist?: DeepNullable> | null; @@ -31,8 +30,8 @@ export type ProgramWithRelations = Program & { // }; export type ChannelWithRelations = Channel & { - programs?: ProgramWithRelations[]; - fillerContent?: ProgramWithRelations[]; + programs?: ProgramDaoWithRelations[]; + fillerContent?: ProgramDaoWithRelations[]; fillerShows?: ChannelFillerShow[]; }; @@ -46,7 +45,7 @@ export type ChannelWithPrograms = MarkRequired< export type ChannelFillerShowWithRelations = ChannelFillerShow & { fillerShow: MarkNonNullable, 'uuid'>; - fillerContent?: ProgramWithRelations[]; + fillerContent?: ProgramDaoWithRelations[]; }; export type ChannelFillerShowWithContent = MarkRequired< @@ -54,7 +53,7 @@ export type ChannelFillerShowWithContent = MarkRequired< 'fillerContent' >; -export type ProgramWithExternalIds = Program & { +export type ProgramWithExternalIds = ProgramDao & { externalIds: MinimalProgramExternalId[]; }; diff --git a/server/src/dao/tests/ProgramExternalId.test.ts b/server/src/db/tests/ProgramExternalId.test.ts similarity index 88% rename from server/src/dao/tests/ProgramExternalId.test.ts rename to server/src/db/tests/ProgramExternalId.test.ts index 7acfc9ae..cf342799 100644 --- a/server/src/dao/tests/ProgramExternalId.test.ts +++ b/server/src/db/tests/ProgramExternalId.test.ts @@ -1,5 +1,5 @@ -import { ProgramExternalIdType } from '../custom_types/ProgramExternalIdType'; -import { ProgramExternalId } from '../entities/ProgramExternalId'; +import { ProgramExternalIdType } from '@/custom_types/ProgramExternalIdType.ts'; +import { ProgramExternalId } from '@/entities/ProgramExternalId.ts'; test('should convert single IDs', () => { const eid = new ProgramExternalId(); diff --git a/server/src/dao/tests/README.md b/server/src/db/tests/README.md similarity index 100% rename from server/src/dao/tests/README.md rename to server/src/db/tests/README.md diff --git a/server/src/external/BaseApiClient.ts b/server/src/external/BaseApiClient.ts index c4fb9cdb..a39dca3c 100644 --- a/server/src/external/BaseApiClient.ts +++ b/server/src/external/BaseApiClient.ts @@ -1,3 +1,7 @@ +import { Maybe, Try } from '@/types/util.js'; +import { configureAxiosLogging } from '@/util/axios.js'; +import { isDefined } from '@/util/index.js'; +import { Logger, LoggerFactory } from '@/util/logging/LoggerFactory.js'; import axios, { AxiosHeaderValue, AxiosInstance, @@ -7,10 +11,6 @@ import axios, { } from 'axios'; import { isError, isString } from 'lodash-es'; import { z } from 'zod'; -import { Maybe, Try } from '../types/util.js'; -import { configureAxiosLogging } from '../util/axios.js'; -import { isDefined } from '../util/index.js'; -import { Logger, LoggerFactory } from '../util/logging/LoggerFactory.js'; export type ApiClientOptions = { name?: string; diff --git a/server/src/external/MediaSourceApiFactory.ts b/server/src/external/MediaSourceApiFactory.ts index 46369da1..f5223de1 100644 --- a/server/src/external/MediaSourceApiFactory.ts +++ b/server/src/external/MediaSourceApiFactory.ts @@ -1,13 +1,13 @@ +import { ChannelDB } from '@/db/ChannelDB.ts'; +import { SettingsDB, getSettings } from '@/db/SettingsDB.ts'; +import { MediaSourceDB } from '@/db/mediaSourceDB.ts'; +import { MediaSourceType } from '@/db/schema/MediaSource.ts'; +import { Maybe } from '@/types/util.js'; +import { isDefined } from '@/util/index.js'; +import { LoggerFactory } from '@/util/logging/LoggerFactory.js'; import { FindChild } from '@tunarr/types'; import { forEach, isBoolean, isEmpty, isNil, isUndefined } from 'lodash-es'; import NodeCache from 'node-cache'; -import { ChannelDB } from '../dao/channelDb.js'; -import { MediaSourceType } from '../dao/direct/schema/MediaSource.ts'; -import { MediaSourceDB } from '../dao/mediaSourceDB.js'; -import { SettingsDB, getSettings } from '../dao/settings.js'; -import { Maybe } from '../types/util.js'; -import { isDefined } from '../util/index.js'; -import { LoggerFactory } from '../util/logging/LoggerFactory.js'; import { BaseApiClient, RemoteMediaSourceOptions } from './BaseApiClient.js'; import { JellyfinApiClient, diff --git a/server/src/external/jellyfin/JellyfinApiClient.ts b/server/src/external/jellyfin/JellyfinApiClient.ts index bc8d7e27..ea73fea9 100644 --- a/server/src/external/jellyfin/JellyfinApiClient.ts +++ b/server/src/external/jellyfin/JellyfinApiClient.ts @@ -1,3 +1,7 @@ +import { Maybe, Nilable } from '@/types/util.ts'; +import { isNonEmptyString } from '@/util/index.js'; +import { LoggerFactory } from '@/util/logging/LoggerFactory.ts'; +import { getTunarrVersion } from '@/util/version.js'; import { JellyfinAuthenticationResult, JellyfinItem, @@ -27,10 +31,6 @@ import { } from 'lodash-es'; import { v4 } from 'uuid'; import { z } from 'zod'; -import { Maybe, Nilable } from '../../types/util.ts'; -import { isNonEmptyString } from '../../util/index.js'; -import { LoggerFactory } from '../../util/logging/LoggerFactory.ts'; -import { getTunarrVersion } from '../../util/version.js'; import { BaseApiClient, QueryErrorResult, diff --git a/server/src/external/jellyfin/JellyfinItemFinder.test.ts b/server/src/external/jellyfin/JellyfinItemFinder.test.ts index 9fbdfca2..2cb70bf3 100644 --- a/server/src/external/jellyfin/JellyfinItemFinder.test.ts +++ b/server/src/external/jellyfin/JellyfinItemFinder.test.ts @@ -1,12 +1,12 @@ +import { ProgramDB } from '@/db/ProgramDB.ts'; import { - initDirectDbAccess, + initDatabaseAccess, syncMigrationTablesIfNecessary, -} from '../../dao/direct/directDbAccess.ts'; -import { ProgramDB } from '../../dao/programDB.ts'; +} from '../../db/DBAccess.ts'; import { JellyfinItemFinder } from './JellyfinItemFinder.ts'; beforeAll(async () => { - initDirectDbAccess(':memory:'); + initDatabaseAccess(':memory:'); await syncMigrationTablesIfNecessary(); }); diff --git a/server/src/external/jellyfin/JellyfinItemFinder.ts b/server/src/external/jellyfin/JellyfinItemFinder.ts index 8027d73b..d8c2a1a0 100644 --- a/server/src/external/jellyfin/JellyfinItemFinder.ts +++ b/server/src/external/jellyfin/JellyfinItemFinder.ts @@ -1,22 +1,22 @@ +import { ProgramDB } from '@/db/ProgramDB.ts'; +import { ProgramMinterFactory } from '@/db/converters/ProgramMinter.ts'; +import { ProgramType } from '@/db/schema/Program.ts'; +import { ProgramWithExternalIds } from '@/db/schema/derivedTypes.js'; +import { isQueryError } from '@/external/BaseApiClient.ts'; +import { MediaSourceApiFactory } from '@/external/MediaSourceApiFactory.ts'; +import { GlobalScheduler } from '@/services/Scheduler.ts'; +import { ReconcileProgramDurationsTask } from '@/tasks/ReconcileProgramDurationsTask.ts'; +import { Maybe } from '@/types/util.ts'; +import { groupByUniq, isDefined } from '@/util/index.ts'; +import { LoggerFactory } from '@/util/logging/LoggerFactory.ts'; import { JellyfinItem, JellyfinItemKind } from '@tunarr/types/jellyfin'; import dayjs from 'dayjs'; import { find, isUndefined, some } from 'lodash-es'; import { match } from 'ts-pattern'; -import { ProgramMinterFactory } from '../../dao/converters/ProgramMinter.ts'; import { ProgramExternalIdType, programExternalIdTypeFromJellyfinProvider, -} from '../../dao/custom_types/ProgramExternalIdType.ts'; -import { ProgramWithExternalIds } from '../../dao/direct/derivedTypes.js'; -import { ProgramType } from '../../dao/direct/schema/Program.ts'; -import { ProgramDB } from '../../dao/programDB.ts'; -import { GlobalScheduler } from '../../services/scheduler.ts'; -import { ReconcileProgramDurationsTask } from '../../tasks/ReconcileProgramDurationsTask.ts'; -import { Maybe } from '../../types/util.ts'; -import { groupByUniq, isDefined } from '../../util/index.ts'; -import { LoggerFactory } from '../../util/logging/LoggerFactory.ts'; -import { isQueryError } from '../BaseApiClient.ts'; -import { MediaSourceApiFactory } from '../MediaSourceApiFactory.ts'; +} from '../../db/custom_types/ProgramExternalIdType.ts'; import { JellyfinGetItemsQuery } from './JellyfinApiClient.ts'; export class JellyfinItemFinder { diff --git a/server/src/external/plex/PlexApiClient.ts b/server/src/external/plex/PlexApiClient.ts index 5cb9fd81..e86b6c69 100644 --- a/server/src/external/plex/PlexApiClient.ts +++ b/server/src/external/plex/PlexApiClient.ts @@ -1,3 +1,6 @@ +import { Maybe, Nilable } from '@/types/util.js'; +import { getChannelId } from '@/util/channels.js'; +import { isSuccess } from '@/util/index.js'; import { PlexDvr, PlexDvrsResponse, @@ -28,9 +31,6 @@ import { PlexMediaContainer, PlexMediaContainerResponse, } from '../../types/plexApiTypes.js'; -import { Maybe, Nilable } from '../../types/util.js'; -import { getChannelId } from '../../util/channels.js'; -import { isSuccess } from '../../util/index.js'; import { BaseApiClient, QueryErrorResult, diff --git a/server/src/external/plex/PlexQueryCache.ts b/server/src/external/plex/PlexQueryCache.ts index 541687a8..6c413fc8 100644 --- a/server/src/external/plex/PlexQueryCache.ts +++ b/server/src/external/plex/PlexQueryCache.ts @@ -1,6 +1,10 @@ +import { + QueryResult, + isQueryError, + isQuerySuccess, +} from '@/external/BaseApiClient.js'; +import { isDefined } from '@/util/index.js'; import NodeCache from 'node-cache'; -import { isDefined } from '../../util/index.js'; -import { QueryResult, isQueryError, isQuerySuccess } from '../BaseApiClient.js'; export class PlexQueryCache { #cache: NodeCache; diff --git a/server/src/ffmpeg/FfmpegPlaybackParamsCalculator.ts b/server/src/ffmpeg/FfmpegPlaybackParamsCalculator.ts index a64e20a2..28a224ce 100644 --- a/server/src/ffmpeg/FfmpegPlaybackParamsCalculator.ts +++ b/server/src/ffmpeg/FfmpegPlaybackParamsCalculator.ts @@ -1,8 +1,8 @@ +import { StreamDetails, VideoStreamDetails } from '@/stream/types.ts'; +import { gcd } from '@/util/index.ts'; import { FfmpegSettings, Resolution } from '@tunarr/types'; import { isNil, round } from 'lodash-es'; import { DeepReadonly } from 'ts-essentials'; -import { StreamDetails, VideoStreamDetails } from '../stream/types.ts'; -import { gcd } from '../util/index.ts'; import { OutputFormat } from './builder/constants.ts'; import { PixelFormat, diff --git a/server/src/ffmpeg/FfmpegProcess.ts b/server/src/ffmpeg/FfmpegProcess.ts index a118b061..6975e0e9 100644 --- a/server/src/ffmpeg/FfmpegProcess.ts +++ b/server/src/ffmpeg/FfmpegProcess.ts @@ -1,3 +1,8 @@ +import { SettingsDB, getSettings } from '@/db/SettingsDB.ts'; +import { TypedEventEmitter } from '@/types/eventEmitter.js'; +import { Maybe, Nullable } from '@/types/util.js'; +import { isDefined, isWindows } from '@/util/index.js'; +import { LoggerFactory } from '@/util/logging/LoggerFactory.js'; import { FfmpegSettings } from '@tunarr/types'; import { FfmpegNumericLogLevels } from '@tunarr/types/schemas'; import { isNull, isUndefined } from 'lodash-es'; @@ -6,11 +11,6 @@ import events from 'node:events'; import os from 'node:os'; import path from 'node:path'; import stream from 'node:stream'; -import { SettingsDB, getSettings } from '../dao/settings.js'; -import { TypedEventEmitter } from '../types/eventEmitter.js'; -import { Maybe, Nullable } from '../types/util.js'; -import { isDefined, isWindows } from '../util/index.js'; -import { LoggerFactory } from '../util/logging/LoggerFactory.js'; export type FfmpegEvents = { // Emitted when the process ended with a code === 0, i.e. it exited diff --git a/server/src/ffmpeg/FfmpegStreamFactory.ts b/server/src/ffmpeg/FfmpegStreamFactory.ts index 415b5022..75dceb3a 100644 --- a/server/src/ffmpeg/FfmpegStreamFactory.ts +++ b/server/src/ffmpeg/FfmpegStreamFactory.ts @@ -1,13 +1,13 @@ +import { Channel } from '@/db/schema/Channel.ts'; +import { HttpStreamSource } from '@/stream/types.ts'; +import { Maybe, Nullable } from '@/types/util.ts'; +import { isDefined, isLinux, isNonEmptyString } from '@/util/index.ts'; +import { makeLocalUrl } from '@/util/serverUtil.ts'; import { FfmpegSettings } from '@tunarr/types'; import dayjs from 'dayjs'; import { Duration } from 'dayjs/plugin/duration.js'; import { isUndefined } from 'lodash-es'; import { DeepReadonly } from 'ts-essentials'; -import { Channel } from '../dao/direct/schema/Channel.ts'; -import { HttpStreamSource } from '../stream/types.ts'; -import { Maybe, Nullable } from '../types/util.ts'; -import { isDefined, isLinux, isNonEmptyString } from '../util/index.ts'; -import { makeLocalUrl } from '../util/serverUtil.ts'; import { FfmpegPlaybackParamsCalculator } from './FfmpegPlaybackParamsCalculator.ts'; import { FfmpegProcess } from './FfmpegProcess.ts'; import { FfmpegTranscodeSession } from './FfmpegTrancodeSession.ts'; diff --git a/server/src/ffmpeg/FfmpegTrancodeSession.ts b/server/src/ffmpeg/FfmpegTrancodeSession.ts index 54c44d4b..d61c2c5b 100644 --- a/server/src/ffmpeg/FfmpegTrancodeSession.ts +++ b/server/src/ffmpeg/FfmpegTrancodeSession.ts @@ -1,11 +1,11 @@ +import { TypedEventEmitter } from '@/types/eventEmitter.js'; +import { Nullable } from '@/types/util.js'; +import { LoggerFactory } from '@/util/logging/LoggerFactory.js'; import { Dayjs } from 'dayjs'; import { Duration } from 'dayjs/plugin/duration.js'; import { isUndefined } from 'lodash-es'; import events from 'node:events'; import { PassThrough } from 'node:stream'; -import { TypedEventEmitter } from '../types/eventEmitter.js'; -import { Nullable } from '../types/util.js'; -import { LoggerFactory } from '../util/logging/LoggerFactory.js'; import { FfmpegEvents, FfmpegProcess } from './FfmpegProcess.js'; enum State { diff --git a/server/src/ffmpeg/GetLastPtsDuration.test.ts b/server/src/ffmpeg/GetLastPtsDuration.test.ts index 809210d8..d9fde17f 100644 --- a/server/src/ffmpeg/GetLastPtsDuration.test.ts +++ b/server/src/ffmpeg/GetLastPtsDuration.test.ts @@ -1,4 +1,4 @@ -import { SettingsDB } from '../dao/settings.js'; +import { SettingsDB } from '@/db/SettingsDB.ts'; import { getFakeSettingsDb, setTestGlobalOptions, diff --git a/server/src/ffmpeg/GetLastPtsDuration.ts b/server/src/ffmpeg/GetLastPtsDuration.ts index fb4fe3a6..6a5946a0 100644 --- a/server/src/ffmpeg/GetLastPtsDuration.ts +++ b/server/src/ffmpeg/GetLastPtsDuration.ts @@ -1,9 +1,9 @@ +import { SettingsDB, getSettings } from '@/db/SettingsDB.ts'; +import { Result } from '@/types/result.js'; +import { isNonEmptyString } from '@/util/index.js'; +import { NewLineTransformStream } from '@/util/streams.js'; import { spawn } from 'child_process'; import { Writable } from 'stream'; -import { SettingsDB, getSettings } from '../dao/settings.js'; -import { Result } from '../types/result.js'; -import { isNonEmptyString } from '../util/index.js'; -import { NewLineTransformStream } from '../util/streams.js'; export type PtsAndDuration = { pts: number; diff --git a/server/src/ffmpeg/builder/FfmpegCommandGenerator.test.ts b/server/src/ffmpeg/builder/FfmpegCommandGenerator.test.ts index daace338..48b44d23 100644 --- a/server/src/ffmpeg/builder/FfmpegCommandGenerator.test.ts +++ b/server/src/ffmpeg/builder/FfmpegCommandGenerator.test.ts @@ -1,6 +1,6 @@ +import { bootstrapTunarr } from '@/ffmpeg/builder/bootstrap.ts'; +import { setGlobalOptions } from '@/globals.ts'; import tmp from 'tmp'; -import { bootstrapTunarr } from '../../bootstrap.ts'; -import { setGlobalOptions } from '../../globals.ts'; import { FfmpegCommandGenerator } from './FfmpegCommandGenerator.ts'; import { AudioStream, StillImageStream, VideoStream } from './MediaStream.ts'; import { VideoFormats } from './constants.ts'; diff --git a/server/src/ffmpeg/builder/FfmpegCommandGenerator.ts b/server/src/ffmpeg/builder/FfmpegCommandGenerator.ts index 273e79b3..5cc35087 100644 --- a/server/src/ffmpeg/builder/FfmpegCommandGenerator.ts +++ b/server/src/ffmpeg/builder/FfmpegCommandGenerator.ts @@ -1,7 +1,7 @@ +import { Nullable } from '@/types/util.ts'; +import { ifDefined } from '@/util/index.ts'; import { filter, findIndex, first, flatMap, partition } from 'lodash-es'; import { Dictionary } from 'ts-essentials'; -import { Nullable } from '../../types/util.ts'; -import { ifDefined } from '../../util/index.ts'; import { BaseEncoder } from './encoder/BaseEncoder.ts'; import { ComplexFilter } from './filter/ComplexFilter.ts'; import { AudioInputSource } from './input/AudioInputSource.ts'; diff --git a/server/src/ffmpeg/builder/MediaStream.ts b/server/src/ffmpeg/builder/MediaStream.ts index 0c876511..62c863db 100644 --- a/server/src/ffmpeg/builder/MediaStream.ts +++ b/server/src/ffmpeg/builder/MediaStream.ts @@ -1,6 +1,6 @@ +import { ExcludeByValueType, Nullable } from '@/types/util.ts'; import { isNull, merge } from 'lodash-es'; import { AnyFunction, MarkOptional } from 'ts-essentials'; -import { ExcludeByValueType, Nullable } from '../../types/util.ts'; import { PixelFormat } from './format/PixelFormat.ts'; import { DataProps, FrameSize, StreamKind } from './types.ts'; diff --git a/server/src/ffmpeg/builder/capabilities/BaseFfmpegHardwareCapabilities.ts b/server/src/ffmpeg/builder/capabilities/BaseFfmpegHardwareCapabilities.ts index 7c942ec2..3330e7bd 100644 --- a/server/src/ffmpeg/builder/capabilities/BaseFfmpegHardwareCapabilities.ts +++ b/server/src/ffmpeg/builder/capabilities/BaseFfmpegHardwareCapabilities.ts @@ -1,8 +1,8 @@ -import { Maybe, Nilable } from '../../../types/util.ts'; -import { VideoStream } from '../MediaStream.ts'; -import { PixelFormat } from '../format/PixelFormat.ts'; -import { FrameState } from '../state/FrameState.ts'; -import { RateControlMode } from '../types.ts'; +import { VideoStream } from '@/ffmpeg/builder/MediaStream.ts'; +import { PixelFormat } from '@/ffmpeg/builder/format/PixelFormat.ts'; +import { FrameState } from '@/ffmpeg/builder/state/FrameState.ts'; +import { RateControlMode } from '@/ffmpeg/builder/types.ts'; +import { Maybe, Nilable } from '@/types/util.ts'; import { NvidiaHardwareCapabilities } from './NvidiaHardwareCapabilities.ts'; export abstract class BaseFfmpegHardwareCapabilities { diff --git a/server/src/ffmpeg/builder/capabilities/DefaultHardwareCapabilities.ts b/server/src/ffmpeg/builder/capabilities/DefaultHardwareCapabilities.ts index e96f4b39..2fbfc2a9 100644 --- a/server/src/ffmpeg/builder/capabilities/DefaultHardwareCapabilities.ts +++ b/server/src/ffmpeg/builder/capabilities/DefaultHardwareCapabilities.ts @@ -1,6 +1,6 @@ -import { Maybe } from '../../../types/util.ts'; -import { VideoFormats } from '../constants.ts'; -import { PixelFormat } from '../format/PixelFormat.ts'; +import { VideoFormats } from '@/ffmpeg/builder/constants.ts'; +import { PixelFormat } from '@/ffmpeg/builder/format/PixelFormat.ts'; +import { Maybe } from '@/types/util.ts'; import { BaseFfmpegHardwareCapabilities } from './BaseFfmpegHardwareCapabilities.ts'; export class DefaultHardwareCapabilities extends BaseFfmpegHardwareCapabilities { diff --git a/server/src/ffmpeg/builder/capabilities/FfmpegCapabilities.ts b/server/src/ffmpeg/builder/capabilities/FfmpegCapabilities.ts index f1982d17..22bf7109 100644 --- a/server/src/ffmpeg/builder/capabilities/FfmpegCapabilities.ts +++ b/server/src/ffmpeg/builder/capabilities/FfmpegCapabilities.ts @@ -1,4 +1,4 @@ -import { FfmpegEncoder } from '../../ffmpegInfo.ts'; +import { FfmpegEncoder } from '@/ffmpeg/ffmpegInfo.ts'; export class FfmpegCapabilities { constructor( diff --git a/server/src/ffmpeg/builder/capabilities/NvidiaHardwareCapabilities.ts b/server/src/ffmpeg/builder/capabilities/NvidiaHardwareCapabilities.ts index 9c1b41be..a5689f3b 100644 --- a/server/src/ffmpeg/builder/capabilities/NvidiaHardwareCapabilities.ts +++ b/server/src/ffmpeg/builder/capabilities/NvidiaHardwareCapabilities.ts @@ -1,6 +1,6 @@ -import { Maybe } from '../../../types/util.ts'; -import { VideoFormats } from '../constants.ts'; -import { PixelFormat } from '../format/PixelFormat.ts'; +import { VideoFormats } from '@/ffmpeg/builder/constants.ts'; +import { PixelFormat } from '@/ffmpeg/builder/format/PixelFormat.ts'; +import { Maybe } from '@/types/util.ts'; import { BaseFfmpegHardwareCapabilities } from './BaseFfmpegHardwareCapabilities.ts'; const MaxwellGm206Models = new Set([ diff --git a/server/src/ffmpeg/builder/capabilities/VaapiHardwareCapabilities.ts b/server/src/ffmpeg/builder/capabilities/VaapiHardwareCapabilities.ts index ce35287b..63391822 100644 --- a/server/src/ffmpeg/builder/capabilities/VaapiHardwareCapabilities.ts +++ b/server/src/ffmpeg/builder/capabilities/VaapiHardwareCapabilities.ts @@ -1,10 +1,10 @@ +import { VideoFormats } from '@/ffmpeg/builder/constants.ts'; +import { PixelFormat } from '@/ffmpeg/builder/format/PixelFormat.ts'; +import { RateControlMode } from '@/ffmpeg/builder/types.ts'; +import { Maybe } from '@/types/util.ts'; +import { isDefined } from '@/util/index.ts'; import { find, isEmpty, some, split } from 'lodash-es'; import { P, match } from 'ts-pattern'; -import { Maybe } from '../../../types/util.ts'; -import { isDefined } from '../../../util/index.ts'; -import { VideoFormats } from '../constants.ts'; -import { PixelFormat } from '../format/PixelFormat.ts'; -import { RateControlMode } from '../types.ts'; import { BaseFfmpegHardwareCapabilities } from './BaseFfmpegHardwareCapabilities.ts'; export const VaapiEntrypoint = { diff --git a/server/src/ffmpeg/builder/constants.ts b/server/src/ffmpeg/builder/constants.ts index f6602daa..f878c14e 100644 --- a/server/src/ffmpeg/builder/constants.ts +++ b/server/src/ffmpeg/builder/constants.ts @@ -1,4 +1,4 @@ -import { HlsOptions, MpegDashOptions } from '../ffmpeg.ts'; +import { HlsOptions, MpegDashOptions } from '@/ffmpeg/ffmpeg.ts'; export const VideoFormats = { Hevc: 'hevc', diff --git a/server/src/ffmpeg/builder/decoder/BaseDecoder.ts b/server/src/ffmpeg/builder/decoder/BaseDecoder.ts index c1ba5b37..affc0766 100644 --- a/server/src/ffmpeg/builder/decoder/BaseDecoder.ts +++ b/server/src/ffmpeg/builder/decoder/BaseDecoder.ts @@ -1,7 +1,7 @@ +import { InputSource } from '@/ffmpeg/builder/input/InputSource.ts'; +import { FrameState } from '@/ffmpeg/builder/state/FrameState.ts'; +import { FrameDataLocation } from '@/ffmpeg/builder/types.ts'; import { first, isNil } from 'lodash-es'; -import { InputSource } from '../input/InputSource.ts'; -import { FrameState } from '../state/FrameState.ts'; -import { FrameDataLocation } from '../types.ts'; import { Decoder } from './Decoder.ts'; export abstract class BaseDecoder extends Decoder { diff --git a/server/src/ffmpeg/builder/decoder/Decoder.ts b/server/src/ffmpeg/builder/decoder/Decoder.ts index 7f054afc..6dcd191f 100644 --- a/server/src/ffmpeg/builder/decoder/Decoder.ts +++ b/server/src/ffmpeg/builder/decoder/Decoder.ts @@ -1,4 +1,4 @@ -import { InputOption } from '../options/input/InputOption.ts'; +import { InputOption } from '@/ffmpeg/builder/options/input/InputOption.ts'; export abstract class Decoder extends InputOption { abstract readonly name: string; diff --git a/server/src/ffmpeg/builder/decoder/DecoderFactory.ts b/server/src/ffmpeg/builder/decoder/DecoderFactory.ts index 7325d7e2..4df7c3d5 100644 --- a/server/src/ffmpeg/builder/decoder/DecoderFactory.ts +++ b/server/src/ffmpeg/builder/decoder/DecoderFactory.ts @@ -1,6 +1,6 @@ -import { VideoStream } from '../MediaStream.ts'; -import { VideoFormats } from '../constants.ts'; -import { HardwareAccelerationMode } from '../types.ts'; +import { VideoStream } from '@/ffmpeg/builder/MediaStream.ts'; +import { VideoFormats } from '@/ffmpeg/builder/constants.ts'; +import { HardwareAccelerationMode } from '@/ffmpeg/builder/types.ts'; import { H264Decoder, ImplicitDecoder } from './SoftwareDecoder.ts'; import { NvidiaH264Decoder, diff --git a/server/src/ffmpeg/builder/decoder/SoftwareDecoder.ts b/server/src/ffmpeg/builder/decoder/SoftwareDecoder.ts index 44991965..40f1e9f1 100644 --- a/server/src/ffmpeg/builder/decoder/SoftwareDecoder.ts +++ b/server/src/ffmpeg/builder/decoder/SoftwareDecoder.ts @@ -1,5 +1,5 @@ -import { InputSource } from '../input/InputSource.ts'; -import { FrameDataLocation } from '../types.ts'; +import { InputSource } from '@/ffmpeg/builder/input/InputSource.ts'; +import { FrameDataLocation } from '@/ffmpeg/builder/types.ts'; import { BaseDecoder } from './BaseDecoder.ts'; abstract class SoftwareDecoder extends BaseDecoder { diff --git a/server/src/ffmpeg/builder/decoder/nvidia/NvidiaDecoders.ts b/server/src/ffmpeg/builder/decoder/nvidia/NvidiaDecoders.ts index bd89723c..d3ad12d3 100644 --- a/server/src/ffmpeg/builder/decoder/nvidia/NvidiaDecoders.ts +++ b/server/src/ffmpeg/builder/decoder/nvidia/NvidiaDecoders.ts @@ -1,7 +1,10 @@ -import { FfmpegPixelFormats } from '../../format/PixelFormat.ts'; -import { InputSource } from '../../input/InputSource.ts'; -import { FrameDataLocation, HardwareAccelerationMode } from '../../types.ts'; -import { BaseDecoder } from '../BaseDecoder.ts'; +import { BaseDecoder } from '@/ffmpeg/builder/decoder/BaseDecoder.ts'; +import { FfmpegPixelFormats } from '@/ffmpeg/builder/format/PixelFormat.ts'; +import { InputSource } from '@/ffmpeg/builder/input/InputSource.ts'; +import { + FrameDataLocation, + HardwareAccelerationMode, +} from '@/ffmpeg/builder/types.ts'; export abstract class NvidiaDecoder extends BaseDecoder { protected outputFrameDataLocation: FrameDataLocation; diff --git a/server/src/ffmpeg/builder/decoder/qsv/QsvDecoders.ts b/server/src/ffmpeg/builder/decoder/qsv/QsvDecoders.ts index 2a50397f..3212ba47 100644 --- a/server/src/ffmpeg/builder/decoder/qsv/QsvDecoders.ts +++ b/server/src/ffmpeg/builder/decoder/qsv/QsvDecoders.ts @@ -1,5 +1,5 @@ -import { FrameDataLocation } from '../../types.ts'; -import { BaseDecoder } from '../BaseDecoder.ts'; +import { BaseDecoder } from '@/ffmpeg/builder/decoder/BaseDecoder.ts'; +import { FrameDataLocation } from '@/ffmpeg/builder/types.ts'; abstract class QsvDecoder extends BaseDecoder { protected outputFrameDataLocation: FrameDataLocation = 'hardware'; diff --git a/server/src/ffmpeg/builder/decoder/vaapi/VaapiDecoder.ts b/server/src/ffmpeg/builder/decoder/vaapi/VaapiDecoder.ts index 0931dfc7..113a6efe 100644 --- a/server/src/ffmpeg/builder/decoder/vaapi/VaapiDecoder.ts +++ b/server/src/ffmpeg/builder/decoder/vaapi/VaapiDecoder.ts @@ -1,6 +1,9 @@ -import { PixelFormatNv12, PixelFormatVaapi } from '../../format/PixelFormat.ts'; -import { FrameState } from '../../state/FrameState.ts'; -import { BaseDecoder } from '../BaseDecoder.ts'; +import { BaseDecoder } from '@/ffmpeg/builder/decoder/BaseDecoder.ts'; +import { + PixelFormatNv12, + PixelFormatVaapi, +} from '@/ffmpeg/builder/format/PixelFormat.ts'; +import { FrameState } from '@/ffmpeg/builder/state/FrameState.ts'; export class VaapiDecoder extends BaseDecoder { readonly name: string = 'implicit_vaapi'; diff --git a/server/src/ffmpeg/builder/decoder/videotoolbox/VideoToolboxDecoder.ts b/server/src/ffmpeg/builder/decoder/videotoolbox/VideoToolboxDecoder.ts index a4f8728a..d6f07620 100644 --- a/server/src/ffmpeg/builder/decoder/videotoolbox/VideoToolboxDecoder.ts +++ b/server/src/ffmpeg/builder/decoder/videotoolbox/VideoToolboxDecoder.ts @@ -1,4 +1,4 @@ -import { BaseDecoder } from '../BaseDecoder.ts'; +import { BaseDecoder } from '@/ffmpeg/builder/decoder/BaseDecoder.ts'; export class VideoToolboxDecoder extends BaseDecoder { readonly name: string = 'implicit_videotoolbox'; diff --git a/server/src/ffmpeg/builder/encoder/BaseEncoder.ts b/server/src/ffmpeg/builder/encoder/BaseEncoder.ts index f363ff94..3a745e1d 100644 --- a/server/src/ffmpeg/builder/encoder/BaseEncoder.ts +++ b/server/src/ffmpeg/builder/encoder/BaseEncoder.ts @@ -1,7 +1,7 @@ +import { FrameState } from '@/ffmpeg/builder/state/FrameState.ts'; +import { StreamKinds } from '@/ffmpeg/builder/types.ts'; import { TupleToUnion } from '@tunarr/types'; import { isEmpty } from 'lodash-es'; -import { FrameState } from '../state/FrameState.ts'; -import { StreamKinds } from '../types.ts'; import { Encoder } from './Encoder.ts'; export abstract class BaseEncoder implements Encoder { diff --git a/server/src/ffmpeg/builder/encoder/Encoder.ts b/server/src/ffmpeg/builder/encoder/Encoder.ts index ed5a4103..970558e4 100644 --- a/server/src/ffmpeg/builder/encoder/Encoder.ts +++ b/server/src/ffmpeg/builder/encoder/Encoder.ts @@ -1,5 +1,5 @@ -import { OutputOption } from '../options/OutputOption.ts'; -import { StreamKind } from '../types.ts'; +import { OutputOption } from '@/ffmpeg/builder/options/OutputOption.ts'; +import { StreamKind } from '@/ffmpeg/builder/types.ts'; export abstract class Encoder extends OutputOption { name: string; diff --git a/server/src/ffmpeg/builder/encoder/SoftwareVideoEncoders.ts b/server/src/ffmpeg/builder/encoder/SoftwareVideoEncoders.ts index 42351907..34ae245f 100644 --- a/server/src/ffmpeg/builder/encoder/SoftwareVideoEncoders.ts +++ b/server/src/ffmpeg/builder/encoder/SoftwareVideoEncoders.ts @@ -1,8 +1,8 @@ -import { Nullable } from '../../../types/util.ts'; -import { isNonEmptyString } from '../../../util/index.ts'; -import { VideoFormats } from '../constants.js'; -import { HardwareDownloadFilter } from '../filter/HardwareDownloadFilter.ts'; -import { FrameState } from '../state/FrameState.js'; +import { VideoFormats } from '@/ffmpeg/builder/constants.js'; +import { HardwareDownloadFilter } from '@/ffmpeg/builder/filter/HardwareDownloadFilter.ts'; +import { FrameState } from '@/ffmpeg/builder/state/FrameState.js'; +import { Nullable } from '@/types/util.ts'; +import { isNonEmptyString } from '@/util/index.ts'; import { VideoEncoder } from './BaseEncoder.js'; export class Libx265Encoder extends VideoEncoder { diff --git a/server/src/ffmpeg/builder/encoder/audio/PcmS16LeAudioEncoder.ts b/server/src/ffmpeg/builder/encoder/audio/PcmS16LeAudioEncoder.ts index 5f92ddfd..023adc6a 100644 --- a/server/src/ffmpeg/builder/encoder/audio/PcmS16LeAudioEncoder.ts +++ b/server/src/ffmpeg/builder/encoder/audio/PcmS16LeAudioEncoder.ts @@ -1,4 +1,4 @@ -import { AudioEncoder } from '../BaseEncoder.ts'; +import { AudioEncoder } from '@/ffmpeg/builder/encoder/BaseEncoder.ts'; export class PcmS16LeAudioEncoder extends AudioEncoder { constructor() { diff --git a/server/src/ffmpeg/builder/encoder/nvidia/NvidiaEncoders.ts b/server/src/ffmpeg/builder/encoder/nvidia/NvidiaEncoders.ts index 45c6231c..a641a96a 100644 --- a/server/src/ffmpeg/builder/encoder/nvidia/NvidiaEncoders.ts +++ b/server/src/ffmpeg/builder/encoder/nvidia/NvidiaEncoders.ts @@ -1,7 +1,7 @@ -import { Nullable } from '../../../../types/util.ts'; -import { isNonEmptyString } from '../../../../util/index.ts'; -import { VideoFormats } from '../../constants.ts'; -import { VideoEncoder } from '../BaseEncoder.ts'; +import { VideoFormats } from '@/ffmpeg/builder/constants.ts'; +import { VideoEncoder } from '@/ffmpeg/builder/encoder/BaseEncoder.ts'; +import { Nullable } from '@/types/util.ts'; +import { isNonEmptyString } from '@/util/index.ts'; export class NvidiaHevcEncoder extends VideoEncoder { protected videoFormat: string = VideoFormats.Hevc; diff --git a/server/src/ffmpeg/builder/encoder/qsv/QsvEncoders.ts b/server/src/ffmpeg/builder/encoder/qsv/QsvEncoders.ts index b035b87d..778c7283 100644 --- a/server/src/ffmpeg/builder/encoder/qsv/QsvEncoders.ts +++ b/server/src/ffmpeg/builder/encoder/qsv/QsvEncoders.ts @@ -1,7 +1,7 @@ -import { Nullable } from '../../../../types/util.ts'; -import { isNonEmptyString } from '../../../../util/index.ts'; -import { VideoFormats } from '../../constants.ts'; -import { VideoEncoder } from '../BaseEncoder.ts'; +import { VideoFormats } from '@/ffmpeg/builder/constants.ts'; +import { VideoEncoder } from '@/ffmpeg/builder/encoder/BaseEncoder.ts'; +import { Nullable } from '@/types/util.ts'; +import { isNonEmptyString } from '@/util/index.ts'; abstract class QsvEncoder extends VideoEncoder { protected constructor(name: string) { diff --git a/server/src/ffmpeg/builder/encoder/vaapi/VaapiEncoders.ts b/server/src/ffmpeg/builder/encoder/vaapi/VaapiEncoders.ts index afb7cbf8..9ad2ff60 100644 --- a/server/src/ffmpeg/builder/encoder/vaapi/VaapiEncoders.ts +++ b/server/src/ffmpeg/builder/encoder/vaapi/VaapiEncoders.ts @@ -1,9 +1,9 @@ -import { Maybe } from '../../../../types/util.ts'; -import { isNonEmptyString } from '../../../../util/index.ts'; -import { VideoFormats } from '../../constants.ts'; -import { FrameState } from '../../state/FrameState.ts'; -import { RateControlMode } from '../../types.ts'; -import { VideoEncoder } from '../BaseEncoder.ts'; +import { VideoFormats } from '@/ffmpeg/builder/constants.ts'; +import { VideoEncoder } from '@/ffmpeg/builder/encoder/BaseEncoder.ts'; +import { FrameState } from '@/ffmpeg/builder/state/FrameState.ts'; +import { RateControlMode } from '@/ffmpeg/builder/types.ts'; +import { Maybe } from '@/types/util.ts'; +import { isNonEmptyString } from '@/util/index.ts'; abstract class VaapiEncoder extends VideoEncoder { protected constructor( diff --git a/server/src/ffmpeg/builder/encoder/videotoolbox/VideoToolboxEncoders.ts b/server/src/ffmpeg/builder/encoder/videotoolbox/VideoToolboxEncoders.ts index da782099..8e359b31 100644 --- a/server/src/ffmpeg/builder/encoder/videotoolbox/VideoToolboxEncoders.ts +++ b/server/src/ffmpeg/builder/encoder/videotoolbox/VideoToolboxEncoders.ts @@ -1,9 +1,9 @@ -import { Nullable } from '../../../../types/util.ts'; -import { isNonEmptyString } from '../../../../util/index.ts'; -import { VideoFormats } from '../../constants.ts'; -import { FrameState } from '../../state/FrameState.ts'; -import { FrameDataLocation } from '../../types.ts'; -import { VideoEncoder } from '../BaseEncoder.ts'; +import { VideoFormats } from '@/ffmpeg/builder/constants.ts'; +import { VideoEncoder } from '@/ffmpeg/builder/encoder/BaseEncoder.ts'; +import { FrameState } from '@/ffmpeg/builder/state/FrameState.ts'; +import { FrameDataLocation } from '@/ffmpeg/builder/types.ts'; +import { Nullable } from '@/types/util.ts'; +import { isNonEmptyString } from '@/util/index.ts'; export class VideoToolboxHevcEncoder extends VideoEncoder { constructor(private bitDepth: number) { diff --git a/server/src/ffmpeg/builder/filter/ComplexFilter.ts b/server/src/ffmpeg/builder/filter/ComplexFilter.ts index d1cc0a1f..89dc3acd 100644 --- a/server/src/ffmpeg/builder/filter/ComplexFilter.ts +++ b/server/src/ffmpeg/builder/filter/ComplexFilter.ts @@ -1,11 +1,11 @@ +import { AudioInputSource } from '@/ffmpeg/builder/input/AudioInputSource.ts'; +import { VideoInputSource } from '@/ffmpeg/builder/input/VideoInputSource.ts'; +import { WatermarkInputSource } from '@/ffmpeg/builder/input/WatermarkInputSource.ts'; +import { FrameState } from '@/ffmpeg/builder/state/FrameState.js'; +import { Nullable } from '@/types/util.ts'; +import { ifDefined, isNonEmptyString } from '@/util/index.ts'; import { seq } from '@tunarr/shared/util'; import { filter, forEach, isNull, some } from 'lodash-es'; -import { Nullable } from '../../../types/util.ts'; -import { ifDefined, isNonEmptyString } from '../../../util/index.ts'; -import { AudioInputSource } from '../input/AudioInputSource.ts'; -import { VideoInputSource } from '../input/VideoInputSource.ts'; -import { WatermarkInputSource } from '../input/WatermarkInputSource.ts'; -import { FrameState } from '../state/FrameState.js'; import { FilterOptionPipelineStep, HasFilterOption, diff --git a/server/src/ffmpeg/builder/filter/DeinterlaceFilter.ts b/server/src/ffmpeg/builder/filter/DeinterlaceFilter.ts index 11e7521f..8a9c2906 100644 --- a/server/src/ffmpeg/builder/filter/DeinterlaceFilter.ts +++ b/server/src/ffmpeg/builder/filter/DeinterlaceFilter.ts @@ -1,5 +1,5 @@ -import { FfmpegState } from '../state/FfmpegState.ts'; -import { FrameState } from '../state/FrameState.ts'; +import { FfmpegState } from '@/ffmpeg/builder/state/FfmpegState.ts'; +import { FrameState } from '@/ffmpeg/builder/state/FrameState.ts'; import { FilterOption } from './FilterOption.ts'; export class DeinterlaceFilter extends FilterOption { diff --git a/server/src/ffmpeg/builder/filter/FilterChain.ts b/server/src/ffmpeg/builder/filter/FilterChain.ts index a8a5c6fc..42c51910 100644 --- a/server/src/ffmpeg/builder/filter/FilterChain.ts +++ b/server/src/ffmpeg/builder/filter/FilterChain.ts @@ -1,4 +1,4 @@ -import { HasFilterOption } from '../types/PipelineStep.ts'; +import { HasFilterOption } from '@/ffmpeg/builder/types/PipelineStep.ts'; import { FilterOption } from './FilterOption.ts'; export class FilterChain { diff --git a/server/src/ffmpeg/builder/filter/FilterOption.ts b/server/src/ffmpeg/builder/filter/FilterOption.ts index 6f1ab363..9dfc6c16 100644 --- a/server/src/ffmpeg/builder/filter/FilterOption.ts +++ b/server/src/ffmpeg/builder/filter/FilterOption.ts @@ -1,4 +1,4 @@ -import { FrameState } from '../state/FrameState.ts'; +import { FrameState } from '@/ffmpeg/builder/state/FrameState.ts'; import { FilterOptionPipelineStep, HasFilterOption, diff --git a/server/src/ffmpeg/builder/filter/HardwareDownloadFilter.ts b/server/src/ffmpeg/builder/filter/HardwareDownloadFilter.ts index b79dfaa6..4edc9fc3 100644 --- a/server/src/ffmpeg/builder/filter/HardwareDownloadFilter.ts +++ b/server/src/ffmpeg/builder/filter/HardwareDownloadFilter.ts @@ -1,9 +1,9 @@ -import { isNonEmptyString } from '../../../util/index.ts'; +import { FrameState } from '@/ffmpeg/builder/state/FrameState.ts'; +import { isNonEmptyString } from '@/util/index.ts'; import { FfmpegPixelFormats, KnownPixelFormats, } from '../format/PixelFormat.ts'; -import { FrameState } from '../state/FrameState.ts'; import { FilterOption } from './FilterOption.ts'; export class HardwareDownloadFilter extends FilterOption { diff --git a/server/src/ffmpeg/builder/filter/PadFilter.ts b/server/src/ffmpeg/builder/filter/PadFilter.ts index bf09f310..a6281278 100644 --- a/server/src/ffmpeg/builder/filter/PadFilter.ts +++ b/server/src/ffmpeg/builder/filter/PadFilter.ts @@ -1,6 +1,6 @@ -import { PixelFormatVaapi } from '../format/PixelFormat.ts'; -import { FrameState } from '../state/FrameState.ts'; -import { FrameDataLocation, FrameSize } from '../types.ts'; +import { PixelFormatVaapi } from '@/ffmpeg/builder/format/PixelFormat.ts'; +import { FrameState } from '@/ffmpeg/builder/state/FrameState.ts'; +import { FrameDataLocation, FrameSize } from '@/ffmpeg/builder/types.ts'; import { FilterOption } from './FilterOption.ts'; export class PadFilter extends FilterOption { diff --git a/server/src/ffmpeg/builder/filter/PipelineFilterStep.ts b/server/src/ffmpeg/builder/filter/PipelineFilterStep.ts index 68ce3ec7..c5ed5d58 100644 --- a/server/src/ffmpeg/builder/filter/PipelineFilterStep.ts +++ b/server/src/ffmpeg/builder/filter/PipelineFilterStep.ts @@ -1,4 +1,4 @@ -import { IPipelineStep } from '../types/PipelineStep.ts'; +import { IPipelineStep } from '@/ffmpeg/builder/types/PipelineStep.ts'; export interface PipelineFilterStep extends IPipelineStep { filter: string; diff --git a/server/src/ffmpeg/builder/filter/PixelFormatFilter.ts b/server/src/ffmpeg/builder/filter/PixelFormatFilter.ts index 45797c7b..030e854e 100644 --- a/server/src/ffmpeg/builder/filter/PixelFormatFilter.ts +++ b/server/src/ffmpeg/builder/filter/PixelFormatFilter.ts @@ -1,5 +1,5 @@ -import { PixelFormat } from '../format/PixelFormat.ts'; -import { FrameState } from '../state/FrameState.ts'; +import { PixelFormat } from '@/ffmpeg/builder/format/PixelFormat.ts'; +import { FrameState } from '@/ffmpeg/builder/state/FrameState.ts'; import { FilterOption } from './FilterOption.ts'; export class PixelFormatFilter extends FilterOption { diff --git a/server/src/ffmpeg/builder/filter/ScaleFilter.ts b/server/src/ffmpeg/builder/filter/ScaleFilter.ts index 4e1f6d37..89d226a6 100644 --- a/server/src/ffmpeg/builder/filter/ScaleFilter.ts +++ b/server/src/ffmpeg/builder/filter/ScaleFilter.ts @@ -1,6 +1,6 @@ -import { FfmpegState } from '../state/FfmpegState.ts'; -import { FrameState } from '../state/FrameState.ts'; -import { FrameSize } from '../types.ts'; +import { FfmpegState } from '@/ffmpeg/builder/state/FfmpegState.ts'; +import { FrameState } from '@/ffmpeg/builder/state/FrameState.ts'; +import { FrameSize } from '@/ffmpeg/builder/types.ts'; import { FilterOption } from './FilterOption.ts'; export class ScaleFilter extends FilterOption { diff --git a/server/src/ffmpeg/builder/filter/TitleTextFilter.ts b/server/src/ffmpeg/builder/filter/TitleTextFilter.ts index f989d8b3..3e11fa3e 100644 --- a/server/src/ffmpeg/builder/filter/TitleTextFilter.ts +++ b/server/src/ffmpeg/builder/filter/TitleTextFilter.ts @@ -1,5 +1,5 @@ -import { serverOptions } from '../../../globals.ts'; -import { FrameSize } from '../types.ts'; +import { FrameSize } from '@/ffmpeg/builder/types.ts'; +import { serverOptions } from '@/globals.ts'; import { FilterOption } from './FilterOption.ts'; export class TitleTextFilter extends FilterOption { diff --git a/server/src/ffmpeg/builder/filter/nvidia/FormatCudaFilter.ts b/server/src/ffmpeg/builder/filter/nvidia/FormatCudaFilter.ts index 4d458071..2f2c51b4 100644 --- a/server/src/ffmpeg/builder/filter/nvidia/FormatCudaFilter.ts +++ b/server/src/ffmpeg/builder/filter/nvidia/FormatCudaFilter.ts @@ -1,6 +1,6 @@ -import { PixelFormat } from '../../format/PixelFormat.ts'; -import { FrameState } from '../../state/FrameState.ts'; -import { FilterOption } from '../FilterOption.ts'; +import { FilterOption } from '@/ffmpeg/builder/filter/FilterOption.ts'; +import { PixelFormat } from '@/ffmpeg/builder/format/PixelFormat.ts'; +import { FrameState } from '@/ffmpeg/builder/state/FrameState.ts'; export class FormatCudaFilter extends FilterOption { public affectsFrameState: boolean = true; diff --git a/server/src/ffmpeg/builder/filter/nvidia/HardwareDownloadCudaFilter.ts b/server/src/ffmpeg/builder/filter/nvidia/HardwareDownloadCudaFilter.ts index 3b03e2d4..d54fe5ca 100644 --- a/server/src/ffmpeg/builder/filter/nvidia/HardwareDownloadCudaFilter.ts +++ b/server/src/ffmpeg/builder/filter/nvidia/HardwareDownloadCudaFilter.ts @@ -1,9 +1,12 @@ +import { FilterOption } from '@/ffmpeg/builder/filter/FilterOption.ts'; +import { + FfmpegPixelFormats, + PixelFormat, +} from '@/ffmpeg/builder/format/PixelFormat.ts'; +import { FrameState } from '@/ffmpeg/builder/state/FrameState.ts'; +import { Nullable } from '@/types/util.ts'; +import { isNonEmptyString } from '@/util/index.ts'; import { isNull } from 'lodash-es'; -import { Nullable } from '../../../../types/util.ts'; -import { isNonEmptyString } from '../../../../util/index.ts'; -import { FfmpegPixelFormats, PixelFormat } from '../../format/PixelFormat.ts'; -import { FrameState } from '../../state/FrameState.ts'; -import { FilterOption } from '../FilterOption.ts'; export class HardwareDownloadCudaFilter extends FilterOption { public affectsFrameState: boolean = true; diff --git a/server/src/ffmpeg/builder/filter/nvidia/HardwareUploadCudaFilter.ts b/server/src/ffmpeg/builder/filter/nvidia/HardwareUploadCudaFilter.ts index 311b49df..33bcf6fe 100644 --- a/server/src/ffmpeg/builder/filter/nvidia/HardwareUploadCudaFilter.ts +++ b/server/src/ffmpeg/builder/filter/nvidia/HardwareUploadCudaFilter.ts @@ -1,5 +1,5 @@ -import { FrameState } from '../../state/FrameState.ts'; -import { FilterOption } from '../FilterOption.ts'; +import { FilterOption } from '@/ffmpeg/builder/filter/FilterOption.ts'; +import { FrameState } from '@/ffmpeg/builder/state/FrameState.ts'; export class HardwareUploadCudaFilter extends FilterOption { public affectsFrameState: boolean = true; diff --git a/server/src/ffmpeg/builder/filter/nvidia/OverlayWatermarkCudaFilter.ts b/server/src/ffmpeg/builder/filter/nvidia/OverlayWatermarkCudaFilter.ts index 7d63e063..02473b81 100644 --- a/server/src/ffmpeg/builder/filter/nvidia/OverlayWatermarkCudaFilter.ts +++ b/server/src/ffmpeg/builder/filter/nvidia/OverlayWatermarkCudaFilter.ts @@ -1,8 +1,8 @@ +import { OverlayWatermarkFilter } from '@/ffmpeg/builder/filter/watermark/OverlayWatermarkFilter.ts'; +import { PixelFormatUnknown } from '@/ffmpeg/builder/format/PixelFormat.ts'; +import { FrameState } from '@/ffmpeg/builder/state/FrameState.ts'; +import { FrameSize } from '@/ffmpeg/builder/types.ts'; import { Watermark } from '@tunarr/types'; -import { PixelFormatUnknown } from '../../format/PixelFormat.ts'; -import { FrameState } from '../../state/FrameState.ts'; -import { FrameSize } from '../../types.ts'; -import { OverlayWatermarkFilter } from '../watermark/OverlayWatermarkFilter.ts'; export class OverlayWatermarkCudaFilter extends OverlayWatermarkFilter { public affectsFrameState: boolean = true; diff --git a/server/src/ffmpeg/builder/filter/nvidia/ScaleCudaFilter.ts b/server/src/ffmpeg/builder/filter/nvidia/ScaleCudaFilter.ts index 91c9a23e..6ed243a0 100644 --- a/server/src/ffmpeg/builder/filter/nvidia/ScaleCudaFilter.ts +++ b/server/src/ffmpeg/builder/filter/nvidia/ScaleCudaFilter.ts @@ -1,7 +1,7 @@ +import { FilterOption } from '@/ffmpeg/builder/filter/FilterOption.ts'; +import { FrameState } from '@/ffmpeg/builder/state/FrameState.ts'; +import { FrameDataLocation, FrameSize } from '@/ffmpeg/builder/types.ts'; import { isEmpty, isNil } from 'lodash-es'; -import { FrameState } from '../../state/FrameState.ts'; -import { FrameDataLocation, FrameSize } from '../../types.ts'; -import { FilterOption } from '../FilterOption.ts'; export class ScaleCudaFilter extends FilterOption { readonly filter: string; diff --git a/server/src/ffmpeg/builder/filter/nvidia/YadifCudaFilter.ts b/server/src/ffmpeg/builder/filter/nvidia/YadifCudaFilter.ts index 26a9d11b..26e53d49 100644 --- a/server/src/ffmpeg/builder/filter/nvidia/YadifCudaFilter.ts +++ b/server/src/ffmpeg/builder/filter/nvidia/YadifCudaFilter.ts @@ -1,5 +1,5 @@ -import { FrameState } from '../../state/FrameState.ts'; -import { FilterOption } from '../FilterOption.ts'; +import { FilterOption } from '@/ffmpeg/builder/filter/FilterOption.ts'; +import { FrameState } from '@/ffmpeg/builder/state/FrameState.ts'; export class YadifCudaFilter extends FilterOption { readonly filter: string; diff --git a/server/src/ffmpeg/builder/filter/qsv/DeinterlaceQsvFilter.ts b/server/src/ffmpeg/builder/filter/qsv/DeinterlaceQsvFilter.ts index 8710cd28..3431da6e 100644 --- a/server/src/ffmpeg/builder/filter/qsv/DeinterlaceQsvFilter.ts +++ b/server/src/ffmpeg/builder/filter/qsv/DeinterlaceQsvFilter.ts @@ -1,5 +1,5 @@ -import { FrameState } from '../../state/FrameState.ts'; -import { FilterOption } from '../FilterOption.ts'; +import { FilterOption } from '@/ffmpeg/builder/filter/FilterOption.ts'; +import { FrameState } from '@/ffmpeg/builder/state/FrameState.ts'; export class DeinterlaceQsvFilter extends FilterOption { readonly filter: string; diff --git a/server/src/ffmpeg/builder/filter/qsv/HardwareUploadQsvFilter.ts b/server/src/ffmpeg/builder/filter/qsv/HardwareUploadQsvFilter.ts index f3c87512..fdee1eea 100644 --- a/server/src/ffmpeg/builder/filter/qsv/HardwareUploadQsvFilter.ts +++ b/server/src/ffmpeg/builder/filter/qsv/HardwareUploadQsvFilter.ts @@ -1,6 +1,6 @@ -import { FrameState } from '../../state/FrameState.ts'; -import { FrameDataLocation } from '../../types.ts'; -import { FilterOption } from '../FilterOption.ts'; +import { FilterOption } from '@/ffmpeg/builder/filter/FilterOption.ts'; +import { FrameState } from '@/ffmpeg/builder/state/FrameState.ts'; +import { FrameDataLocation } from '@/ffmpeg/builder/types.ts'; export class HardwareUploadQsvFilter extends FilterOption { constructor(private extraHardwareFrames?: number) { diff --git a/server/src/ffmpeg/builder/filter/qsv/ScaleQsvFilter.ts b/server/src/ffmpeg/builder/filter/qsv/ScaleQsvFilter.ts index df5cea1b..a5ab5213 100644 --- a/server/src/ffmpeg/builder/filter/qsv/ScaleQsvFilter.ts +++ b/server/src/ffmpeg/builder/filter/qsv/ScaleQsvFilter.ts @@ -1,8 +1,8 @@ -import { isNonEmptyString } from '../../../../util/index.ts'; -import { VideoStream } from '../../MediaStream.ts'; -import { FrameState } from '../../state/FrameState.ts'; -import { FrameDataLocation, FrameSize } from '../../types.ts'; -import { FilterOption } from '../FilterOption.ts'; +import { FilterOption } from '@/ffmpeg/builder/filter/FilterOption.ts'; +import { VideoStream } from '@/ffmpeg/builder/MediaStream.ts'; +import { FrameState } from '@/ffmpeg/builder/state/FrameState.ts'; +import { FrameDataLocation, FrameSize } from '@/ffmpeg/builder/types.ts'; +import { isNonEmptyString } from '@/util/index.ts'; export class ScaleQsvFilter extends FilterOption { readonly filter: string; diff --git a/server/src/ffmpeg/builder/filter/vaapi/DeinterlaceVaapiFilter.ts b/server/src/ffmpeg/builder/filter/vaapi/DeinterlaceVaapiFilter.ts index b1d5bf35..af443d91 100644 --- a/server/src/ffmpeg/builder/filter/vaapi/DeinterlaceVaapiFilter.ts +++ b/server/src/ffmpeg/builder/filter/vaapi/DeinterlaceVaapiFilter.ts @@ -1,5 +1,5 @@ -import { FrameState } from '../../state/FrameState.ts'; -import { FilterOption } from '../FilterOption.ts'; +import { FilterOption } from '@/ffmpeg/builder/filter/FilterOption.ts'; +import { FrameState } from '@/ffmpeg/builder/state/FrameState.ts'; export class DeinterlaceVaapiFilter extends FilterOption { public get filter(): string { diff --git a/server/src/ffmpeg/builder/filter/vaapi/HardwareUploadVaapiFilter.ts b/server/src/ffmpeg/builder/filter/vaapi/HardwareUploadVaapiFilter.ts index fce4678d..887515bb 100644 --- a/server/src/ffmpeg/builder/filter/vaapi/HardwareUploadVaapiFilter.ts +++ b/server/src/ffmpeg/builder/filter/vaapi/HardwareUploadVaapiFilter.ts @@ -1,6 +1,6 @@ -import { FrameState } from '../../state/FrameState.ts'; -import { FrameDataLocation } from '../../types.ts'; -import { FilterOption } from '../FilterOption.ts'; +import { FilterOption } from '@/ffmpeg/builder/filter/FilterOption.ts'; +import { FrameState } from '@/ffmpeg/builder/state/FrameState.ts'; +import { FrameDataLocation } from '@/ffmpeg/builder/types.ts'; export class HardwareUploadVaapiFilter extends FilterOption { constructor( diff --git a/server/src/ffmpeg/builder/filter/vaapi/ScaleVaapiFilter.ts b/server/src/ffmpeg/builder/filter/vaapi/ScaleVaapiFilter.ts index a0098156..a304c776 100644 --- a/server/src/ffmpeg/builder/filter/vaapi/ScaleVaapiFilter.ts +++ b/server/src/ffmpeg/builder/filter/vaapi/ScaleVaapiFilter.ts @@ -1,7 +1,7 @@ -import { isNonEmptyString } from '../../../../util/index.ts'; -import { FrameState } from '../../state/FrameState.ts'; -import { FrameSize } from '../../types.ts'; -import { FilterOption } from '../FilterOption.ts'; +import { FilterOption } from '@/ffmpeg/builder/filter/FilterOption.ts'; +import { FrameState } from '@/ffmpeg/builder/state/FrameState.ts'; +import { FrameSize } from '@/ffmpeg/builder/types.ts'; +import { isNonEmptyString } from '@/util/index.ts'; export class ScaleVaapiFilter extends FilterOption { constructor( diff --git a/server/src/ffmpeg/builder/filter/vaapi/VaapiFormatFilter.ts b/server/src/ffmpeg/builder/filter/vaapi/VaapiFormatFilter.ts index ed7bbe52..539085b2 100644 --- a/server/src/ffmpeg/builder/filter/vaapi/VaapiFormatFilter.ts +++ b/server/src/ffmpeg/builder/filter/vaapi/VaapiFormatFilter.ts @@ -1,6 +1,6 @@ -import { PixelFormat } from '../../format/PixelFormat.ts'; -import { FrameState } from '../../state/FrameState.ts'; -import { FilterOption } from '../FilterOption.ts'; +import { FilterOption } from '@/ffmpeg/builder/filter/FilterOption.ts'; +import { PixelFormat } from '@/ffmpeg/builder/format/PixelFormat.ts'; +import { FrameState } from '@/ffmpeg/builder/state/FrameState.ts'; export class VaapiFormatFilter extends FilterOption { constructor(private pixelFormat: PixelFormat) { diff --git a/server/src/ffmpeg/builder/filter/videotoolbox/VideoToolboxHardwareAccelerationOption.ts b/server/src/ffmpeg/builder/filter/videotoolbox/VideoToolboxHardwareAccelerationOption.ts index a46b966d..d428f80e 100644 --- a/server/src/ffmpeg/builder/filter/videotoolbox/VideoToolboxHardwareAccelerationOption.ts +++ b/server/src/ffmpeg/builder/filter/videotoolbox/VideoToolboxHardwareAccelerationOption.ts @@ -1,4 +1,4 @@ -import { GlobalOption } from '../../options/GlobalOption.ts'; +import { GlobalOption } from '@/ffmpeg/builder/options/GlobalOption.ts'; export class VideoToolboxHardwareAccelerationOption extends GlobalOption { options(): string[] { diff --git a/server/src/ffmpeg/builder/filter/watermark/OverlayWatermarkFilter.ts b/server/src/ffmpeg/builder/filter/watermark/OverlayWatermarkFilter.ts index 8399aba3..7ef37a82 100644 --- a/server/src/ffmpeg/builder/filter/watermark/OverlayWatermarkFilter.ts +++ b/server/src/ffmpeg/builder/filter/watermark/OverlayWatermarkFilter.ts @@ -1,8 +1,8 @@ +import { FilterOption } from '@/ffmpeg/builder/filter/FilterOption.ts'; +import { PixelFormat } from '@/ffmpeg/builder/format/PixelFormat.js'; +import { FrameState } from '@/ffmpeg/builder/state/FrameState.js'; +import { FrameSize } from '@/ffmpeg/builder/types.js'; import { Watermark } from '@tunarr/types'; -import { PixelFormat } from '../../format/PixelFormat.js'; -import { FrameState } from '../../state/FrameState.js'; -import { FrameSize } from '../../types.js'; -import { FilterOption } from '../FilterOption.ts'; export class OverlayWatermarkFilter extends FilterOption { public readonly affectsFrameState: boolean = true; diff --git a/server/src/ffmpeg/builder/filter/watermark/WatermarkOpacityFilter.ts b/server/src/ffmpeg/builder/filter/watermark/WatermarkOpacityFilter.ts index d2e4f13b..ef19cc29 100644 --- a/server/src/ffmpeg/builder/filter/watermark/WatermarkOpacityFilter.ts +++ b/server/src/ffmpeg/builder/filter/watermark/WatermarkOpacityFilter.ts @@ -1,6 +1,6 @@ +import { FilterOption } from '@/ffmpeg/builder/filter/FilterOption.ts'; import { Watermark } from '@tunarr/types'; import { round } from 'lodash-es'; -import { FilterOption } from '../FilterOption.ts'; export class WatermarkOpacityFilter extends FilterOption { constructor(private watermark: Watermark) { diff --git a/server/src/ffmpeg/builder/filter/watermark/WatermarkScaleFilter.ts b/server/src/ffmpeg/builder/filter/watermark/WatermarkScaleFilter.ts index 76149338..b4b45830 100644 --- a/server/src/ffmpeg/builder/filter/watermark/WatermarkScaleFilter.ts +++ b/server/src/ffmpeg/builder/filter/watermark/WatermarkScaleFilter.ts @@ -1,6 +1,6 @@ +import { FilterOption } from '@/ffmpeg/builder/filter/FilterOption.ts'; +import { FrameSize } from '@/ffmpeg/builder/types.ts'; import { Watermark } from '@tunarr/types'; -import { FrameSize } from '../../types.ts'; -import { FilterOption } from '../FilterOption.ts'; export class WatermarkScaleFilter extends FilterOption { constructor( diff --git a/server/src/ffmpeg/builder/format/PixelFormat.ts b/server/src/ffmpeg/builder/format/PixelFormat.ts index 3465c4c3..df6676e1 100644 --- a/server/src/ffmpeg/builder/format/PixelFormat.ts +++ b/server/src/ffmpeg/builder/format/PixelFormat.ts @@ -1,4 +1,4 @@ -import { Maybe } from '../../../types/util.ts'; +import { Maybe } from '@/types/util.ts'; export interface Equatable { equals(other: T): boolean; diff --git a/server/src/ffmpeg/builder/input/AudioInputSource.ts b/server/src/ffmpeg/builder/input/AudioInputSource.ts index fc8559f7..fe4ffcd0 100644 --- a/server/src/ffmpeg/builder/input/AudioInputSource.ts +++ b/server/src/ffmpeg/builder/input/AudioInputSource.ts @@ -1,9 +1,9 @@ -import { FilterStreamSource } from '../../../stream/types.ts'; -import { AudioStream } from '../MediaStream.ts'; -import { SineWaveGeneratorFilter } from '../filter/SineWaveGeneratorFilter.ts'; -import { LavfiInputOption } from '../options/input/LavfiInputOption.ts'; -import { AudioState } from '../state/AudioState.ts'; -import { HasFilterOption } from '../types/PipelineStep.ts'; +import { AudioStream } from '@/ffmpeg/builder/MediaStream.ts'; +import { SineWaveGeneratorFilter } from '@/ffmpeg/builder/filter/SineWaveGeneratorFilter.ts'; +import { LavfiInputOption } from '@/ffmpeg/builder/options/input/LavfiInputOption.ts'; +import { AudioState } from '@/ffmpeg/builder/state/AudioState.ts'; +import { HasFilterOption } from '@/ffmpeg/builder/types/PipelineStep.ts'; +import { FilterStreamSource } from '@/stream/types.ts'; import { InputSource, InputSourceContinuity, diff --git a/server/src/ffmpeg/builder/input/ConcatInputSource.ts b/server/src/ffmpeg/builder/input/ConcatInputSource.ts index 422c5862..92188669 100644 --- a/server/src/ffmpeg/builder/input/ConcatInputSource.ts +++ b/server/src/ffmpeg/builder/input/ConcatInputSource.ts @@ -1,5 +1,5 @@ -import { VideoStream } from '../MediaStream.ts'; -import { FrameSize } from '../types.ts'; +import { VideoStream } from '@/ffmpeg/builder/MediaStream.ts'; +import { FrameSize } from '@/ffmpeg/builder/types.ts'; import { InputSource, InputSourceContinuity, diff --git a/server/src/ffmpeg/builder/input/InputSource.ts b/server/src/ffmpeg/builder/input/InputSource.ts index 56158d2d..3a666f16 100644 --- a/server/src/ffmpeg/builder/input/InputSource.ts +++ b/server/src/ffmpeg/builder/input/InputSource.ts @@ -1,13 +1,13 @@ +import { MediaStream } from '@/ffmpeg/builder/MediaStream.ts'; +import { HttpHeadersInputOption } from '@/ffmpeg/builder/options/input/HttpHeadersInputOption.ts'; +import { InputOption } from '@/ffmpeg/builder/options/input/InputOption.ts'; +import { HasFilterOption } from '@/ffmpeg/builder/types/PipelineStep.ts'; import { flatMap } from 'lodash-es'; import { FileStreamSource, FilterStreamSource, HttpStreamSource, } from '../../../stream/types.ts'; -import { MediaStream } from '../MediaStream.ts'; -import { HttpHeadersInputOption } from '../options/input/HttpHeadersInputOption.ts'; -import { InputOption } from '../options/input/InputOption.ts'; -import { HasFilterOption } from '../types/PipelineStep.ts'; import { VideoInputSource } from './VideoInputSource.ts'; export type InputSourceType = 'video' | 'audio'; diff --git a/server/src/ffmpeg/builder/input/LavfiVideoInputSource.ts b/server/src/ffmpeg/builder/input/LavfiVideoInputSource.ts index a89862bd..8326ffe3 100644 --- a/server/src/ffmpeg/builder/input/LavfiVideoInputSource.ts +++ b/server/src/ffmpeg/builder/input/LavfiVideoInputSource.ts @@ -1,11 +1,11 @@ -import { FilterStreamSource } from '../../../stream/types.ts'; -import { VideoStream } from '../MediaStream.ts'; -import { StaticFilter } from '../filter/StaticFilter.ts'; -import { TitleTextFilter } from '../filter/TitleTextFilter.ts'; -import { PixelFormatUnknown } from '../format/PixelFormat.ts'; -import { LavfiInputOption } from '../options/input/LavfiInputOption.ts'; -import { FrameSize } from '../types.ts'; -import { HasFilterOption } from '../types/PipelineStep.ts'; +import { VideoStream } from '@/ffmpeg/builder/MediaStream.ts'; +import { StaticFilter } from '@/ffmpeg/builder/filter/StaticFilter.ts'; +import { TitleTextFilter } from '@/ffmpeg/builder/filter/TitleTextFilter.ts'; +import { PixelFormatUnknown } from '@/ffmpeg/builder/format/PixelFormat.ts'; +import { LavfiInputOption } from '@/ffmpeg/builder/options/input/LavfiInputOption.ts'; +import { FrameSize } from '@/ffmpeg/builder/types.ts'; +import { HasFilterOption } from '@/ffmpeg/builder/types/PipelineStep.ts'; +import { FilterStreamSource } from '@/stream/types.ts'; import { VideoInputSource } from './VideoInputSource.ts'; export class LavfiVideoInputSource extends VideoInputSource { diff --git a/server/src/ffmpeg/builder/input/VideoInputSource.ts b/server/src/ffmpeg/builder/input/VideoInputSource.ts index 3fc2958e..a74603df 100644 --- a/server/src/ffmpeg/builder/input/VideoInputSource.ts +++ b/server/src/ffmpeg/builder/input/VideoInputSource.ts @@ -1,4 +1,4 @@ -import { VideoStream } from '../MediaStream.ts'; +import { VideoStream } from '@/ffmpeg/builder/MediaStream.ts'; import { InputSource, InputSourceContinuity, diff --git a/server/src/ffmpeg/builder/input/WatermarkInputSource.ts b/server/src/ffmpeg/builder/input/WatermarkInputSource.ts index a035c2e5..6d51bd50 100644 --- a/server/src/ffmpeg/builder/input/WatermarkInputSource.ts +++ b/server/src/ffmpeg/builder/input/WatermarkInputSource.ts @@ -1,5 +1,5 @@ +import { StillImageStream } from '@/ffmpeg/builder/MediaStream.ts'; import { Watermark } from '@tunarr/types'; -import { StillImageStream } from '../MediaStream.ts'; import { StreamSource } from './InputSource.ts'; import { VideoInputSource } from './VideoInputSource.ts'; diff --git a/server/src/ffmpeg/builder/options/EnvironmentVariables.ts b/server/src/ffmpeg/builder/options/EnvironmentVariables.ts index 93591e54..fe0fa469 100644 --- a/server/src/ffmpeg/builder/options/EnvironmentVariables.ts +++ b/server/src/ffmpeg/builder/options/EnvironmentVariables.ts @@ -1,5 +1,5 @@ +import { EnvironmentVariablePipelineStep } from '@/ffmpeg/builder/types/PipelineStep.ts'; import { Dictionary } from 'ts-essentials'; -import { EnvironmentVariablePipelineStep } from '../types/PipelineStep.ts'; export abstract class EnvironmentVariable implements EnvironmentVariablePipelineStep diff --git a/server/src/ffmpeg/builder/options/GlobalOption.ts b/server/src/ffmpeg/builder/options/GlobalOption.ts index 1e6d253b..06dec82c 100644 --- a/server/src/ffmpeg/builder/options/GlobalOption.ts +++ b/server/src/ffmpeg/builder/options/GlobalOption.ts @@ -1,6 +1,6 @@ +import { FrameState } from '@/ffmpeg/builder/state/FrameState.js'; +import { GlobalOptionPipelineStep } from '@/ffmpeg/builder/types/PipelineStep.ts'; import { isString } from 'lodash-es'; -import { FrameState } from '../state/FrameState.js'; -import { GlobalOptionPipelineStep } from '../types/PipelineStep.ts'; export abstract class GlobalOption implements GlobalOptionPipelineStep { readonly type = 'global'; diff --git a/server/src/ffmpeg/builder/options/HlsOutputFormat.ts b/server/src/ffmpeg/builder/options/HlsOutputFormat.ts index a179c294..6890588d 100644 --- a/server/src/ffmpeg/builder/options/HlsOutputFormat.ts +++ b/server/src/ffmpeg/builder/options/HlsOutputFormat.ts @@ -1,7 +1,7 @@ +import { FrameState } from '@/ffmpeg/builder/state/FrameState.ts'; +import { Maybe } from '@/types/util.ts'; +import { isNonEmptyString } from '@/util/index.ts'; import { nth } from 'lodash-es'; -import { Maybe } from '../../../types/util.ts'; -import { isNonEmptyString } from '../../../util/index.ts'; -import { FrameState } from '../state/FrameState.ts'; import { OutputOption } from './OutputOption.ts'; export class HlsOutputFormat extends OutputOption { diff --git a/server/src/ffmpeg/builder/options/OutputOption.ts b/server/src/ffmpeg/builder/options/OutputOption.ts index 1efd896f..263dec48 100644 --- a/server/src/ffmpeg/builder/options/OutputOption.ts +++ b/server/src/ffmpeg/builder/options/OutputOption.ts @@ -1,7 +1,7 @@ +import { PixelFormat } from '@/ffmpeg/builder/format/PixelFormat.ts'; +import { FrameState } from '@/ffmpeg/builder/state/FrameState.ts'; +import { OutputOptionPipelineStep } from '@/ffmpeg/builder/types/PipelineStep.ts'; import { isString } from 'lodash-es'; -import { PixelFormat } from '../format/PixelFormat.ts'; -import { FrameState } from '../state/FrameState.ts'; -import { OutputOptionPipelineStep } from '../types/PipelineStep.ts'; export abstract class OutputOption implements OutputOptionPipelineStep { readonly type = 'output'; diff --git a/server/src/ffmpeg/builder/options/hardwareAcceleration/NvidiaOptions.ts b/server/src/ffmpeg/builder/options/hardwareAcceleration/NvidiaOptions.ts index acf03cc7..76d7a3be 100644 --- a/server/src/ffmpeg/builder/options/hardwareAcceleration/NvidiaOptions.ts +++ b/server/src/ffmpeg/builder/options/hardwareAcceleration/NvidiaOptions.ts @@ -1,4 +1,4 @@ -import { ConstantGlobalOption } from '../GlobalOption.ts'; +import { ConstantGlobalOption } from '@/ffmpeg/builder/options/GlobalOption.ts'; export class CudaHardwareAccelerationOption extends ConstantGlobalOption { constructor() { diff --git a/server/src/ffmpeg/builder/options/hardwareAcceleration/QsvOptions.ts b/server/src/ffmpeg/builder/options/hardwareAcceleration/QsvOptions.ts index 23a0a915..8c796230 100644 --- a/server/src/ffmpeg/builder/options/hardwareAcceleration/QsvOptions.ts +++ b/server/src/ffmpeg/builder/options/hardwareAcceleration/QsvOptions.ts @@ -1,7 +1,7 @@ +import { GlobalOption } from '@/ffmpeg/builder/options/GlobalOption.ts'; +import { Nullable } from '@/types/util.ts'; +import { isNonEmptyString } from '@/util/index.ts'; import os from 'node:os'; -import { Nullable } from '../../../../types/util.ts'; -import { isNonEmptyString } from '../../../../util/index.ts'; -import { GlobalOption } from '../GlobalOption.ts'; export class QsvHardwareAccelerationOption extends GlobalOption { constructor(private qsvDevice: Nullable) { diff --git a/server/src/ffmpeg/builder/options/hardwareAcceleration/VaapiOptions.ts b/server/src/ffmpeg/builder/options/hardwareAcceleration/VaapiOptions.ts index c74c9b13..47792753 100644 --- a/server/src/ffmpeg/builder/options/hardwareAcceleration/VaapiOptions.ts +++ b/server/src/ffmpeg/builder/options/hardwareAcceleration/VaapiOptions.ts @@ -1,5 +1,5 @@ -import { FrameState } from '../../state/FrameState.ts'; -import { GlobalOption } from '../GlobalOption.ts'; +import { GlobalOption } from '@/ffmpeg/builder/options/GlobalOption.ts'; +import { FrameState } from '@/ffmpeg/builder/state/FrameState.ts'; export class VaapiHardwareAccelerationOption extends GlobalOption { constructor( diff --git a/server/src/ffmpeg/builder/options/input/ConcatHttpReconnectOptions.ts b/server/src/ffmpeg/builder/options/input/ConcatHttpReconnectOptions.ts index 906a5bd3..3ad1ef07 100644 --- a/server/src/ffmpeg/builder/options/input/ConcatHttpReconnectOptions.ts +++ b/server/src/ffmpeg/builder/options/input/ConcatHttpReconnectOptions.ts @@ -1,6 +1,6 @@ -import { MediaStream } from '../../MediaStream.ts'; -import { InputSource } from '../../input/InputSource.ts'; -import { InputOption } from './InputOption.ts'; +import { MediaStream } from '@/ffmpeg/builder/MediaStream.ts'; +import { InputSource } from '@/ffmpeg/builder/input/InputSource.ts'; +import { InputOption } from '@/ffmpeg/builder/options/input/InputOption.ts'; export class ConcatHttpReconnectOptions extends InputOption { appliesToInput(input: InputSource): boolean { diff --git a/server/src/ffmpeg/builder/options/input/ConcatInputFormatOption.ts b/server/src/ffmpeg/builder/options/input/ConcatInputFormatOption.ts index 3e35d051..e77dd85e 100644 --- a/server/src/ffmpeg/builder/options/input/ConcatInputFormatOption.ts +++ b/server/src/ffmpeg/builder/options/input/ConcatInputFormatOption.ts @@ -1,6 +1,6 @@ -import { MediaStream } from '../../MediaStream.ts'; -import { ConcatInputSource } from '../../input/ConcatInputSource.ts'; -import { InputSource } from '../../input/InputSource.ts'; +import { MediaStream } from '@/ffmpeg/builder/MediaStream.ts'; +import { ConcatInputSource } from '@/ffmpeg/builder/input/ConcatInputSource.ts'; +import { InputSource } from '@/ffmpeg/builder/input/InputSource.ts'; import { InputOption } from './InputOption.ts'; export class ConcatInputFormatOption extends InputOption { diff --git a/server/src/ffmpeg/builder/options/input/DoNotIgnoreLoopInputOption.ts b/server/src/ffmpeg/builder/options/input/DoNotIgnoreLoopInputOption.ts index 66fcf492..ea4ac1f5 100644 --- a/server/src/ffmpeg/builder/options/input/DoNotIgnoreLoopInputOption.ts +++ b/server/src/ffmpeg/builder/options/input/DoNotIgnoreLoopInputOption.ts @@ -1,5 +1,5 @@ +import { InputSource } from '@/ffmpeg/builder/input/InputSource.ts'; import { every } from 'lodash-es'; -import { InputSource } from '../../input/InputSource.ts'; import { InputOption } from './InputOption.ts'; export class DoNotIgnoreLoopInputOption extends InputOption { diff --git a/server/src/ffmpeg/builder/options/input/HttpHeadersInputOption.ts b/server/src/ffmpeg/builder/options/input/HttpHeadersInputOption.ts index e7797225..5c3b7b3a 100644 --- a/server/src/ffmpeg/builder/options/input/HttpHeadersInputOption.ts +++ b/server/src/ffmpeg/builder/options/input/HttpHeadersInputOption.ts @@ -1,6 +1,6 @@ +import { MediaStream } from '@/ffmpeg/builder/MediaStream.ts'; +import { InputSource } from '@/ffmpeg/builder/input/InputSource.ts'; import { isEmpty } from 'lodash-es'; -import { MediaStream } from '../../MediaStream.ts'; -import { InputSource } from '../../input/InputSource.ts'; import { InputOption } from './InputOption.ts'; export class HttpHeadersInputOption extends InputOption { diff --git a/server/src/ffmpeg/builder/options/input/HttpReconnectOptions.ts b/server/src/ffmpeg/builder/options/input/HttpReconnectOptions.ts index 83b0c2d3..c9009635 100644 --- a/server/src/ffmpeg/builder/options/input/HttpReconnectOptions.ts +++ b/server/src/ffmpeg/builder/options/input/HttpReconnectOptions.ts @@ -1,5 +1,5 @@ -import { MediaStream } from '../../MediaStream.ts'; -import { InputSource } from '../../input/InputSource.ts'; +import { MediaStream } from '@/ffmpeg/builder/MediaStream.ts'; +import { InputSource } from '@/ffmpeg/builder/input/InputSource.ts'; import { InputOption } from './InputOption.ts'; export class HttpReconnectOptions extends InputOption { diff --git a/server/src/ffmpeg/builder/options/input/InfiniteLoopInputOption.ts b/server/src/ffmpeg/builder/options/input/InfiniteLoopInputOption.ts index 1c61cdb6..23530d38 100644 --- a/server/src/ffmpeg/builder/options/input/InfiniteLoopInputOption.ts +++ b/server/src/ffmpeg/builder/options/input/InfiniteLoopInputOption.ts @@ -1,6 +1,6 @@ +import { InputSource } from '@/ffmpeg/builder/input/InputSource.ts'; +import { FrameState } from '@/ffmpeg/builder/state/FrameState.ts'; import { some } from 'lodash-es'; -import { InputSource } from '../../input/InputSource.ts'; -import { FrameState } from '../../state/FrameState.ts'; import { InputOption } from './InputOption.ts'; // TODO: Figure out how to model output options here ... this option diff --git a/server/src/ffmpeg/builder/options/input/InputOption.ts b/server/src/ffmpeg/builder/options/input/InputOption.ts index 3c726297..7f76c7b3 100644 --- a/server/src/ffmpeg/builder/options/input/InputOption.ts +++ b/server/src/ffmpeg/builder/options/input/InputOption.ts @@ -1,6 +1,6 @@ -import { InputSource } from '../../input/InputSource.ts'; -import { FrameState } from '../../state/FrameState.ts'; -import { InputOptionPipelineStep } from '../../types/PipelineStep.ts'; +import { InputSource } from '@/ffmpeg/builder/input/InputSource.ts'; +import { FrameState } from '@/ffmpeg/builder/state/FrameState.ts'; +import { InputOptionPipelineStep } from '@/ffmpeg/builder/types/PipelineStep.ts'; export abstract class InputOption implements InputOptionPipelineStep { readonly type = 'input'; diff --git a/server/src/ffmpeg/builder/options/input/LavfiInputOption.ts b/server/src/ffmpeg/builder/options/input/LavfiInputOption.ts index a5fbdb2d..8265c067 100644 --- a/server/src/ffmpeg/builder/options/input/LavfiInputOption.ts +++ b/server/src/ffmpeg/builder/options/input/LavfiInputOption.ts @@ -1,5 +1,5 @@ -import { MediaStream } from '../../MediaStream.ts'; -import { InputSource } from '../../input/InputSource.ts'; +import { MediaStream } from '@/ffmpeg/builder/MediaStream.ts'; +import { InputSource } from '@/ffmpeg/builder/input/InputSource.ts'; import { InputOption } from './InputOption.ts'; export class LavfiInputOption extends InputOption { diff --git a/server/src/ffmpeg/builder/options/input/ReadrateInputOption.ts b/server/src/ffmpeg/builder/options/input/ReadrateInputOption.ts index ee284e7a..c6f38a23 100644 --- a/server/src/ffmpeg/builder/options/input/ReadrateInputOption.ts +++ b/server/src/ffmpeg/builder/options/input/ReadrateInputOption.ts @@ -1,11 +1,11 @@ +import { MediaStream } from '@/ffmpeg/builder/MediaStream.ts'; +import { FfmpegCapabilities } from '@/ffmpeg/builder/capabilities/FfmpegCapabilities.ts'; +import { NullAudioInputSource } from '@/ffmpeg/builder/input/AudioInputSource.ts'; +import { ConcatInputSource } from '@/ffmpeg/builder/input/ConcatInputSource.ts'; +import { InputSource } from '@/ffmpeg/builder/input/InputSource.ts'; +import { KnownFfmpegOptions } from '@/ffmpeg/builder/options/KnownFfmpegOptions.ts'; +import { FrameState } from '@/ffmpeg/builder/state/FrameState.ts'; import { every } from 'lodash-es'; -import { MediaStream } from '../../MediaStream.ts'; -import { FfmpegCapabilities } from '../../capabilities/FfmpegCapabilities.ts'; -import { NullAudioInputSource } from '../../input/AudioInputSource.ts'; -import { ConcatInputSource } from '../../input/ConcatInputSource.ts'; -import { InputSource } from '../../input/InputSource.ts'; -import { FrameState } from '../../state/FrameState.ts'; -import { KnownFfmpegOptions } from '../KnownFfmpegOptions.ts'; import { InputOption } from './InputOption.ts'; export class ReadrateInputOption extends InputOption { diff --git a/server/src/ffmpeg/builder/options/input/UserAgentInputOption.ts b/server/src/ffmpeg/builder/options/input/UserAgentInputOption.ts index 294baf73..90e66b3f 100644 --- a/server/src/ffmpeg/builder/options/input/UserAgentInputOption.ts +++ b/server/src/ffmpeg/builder/options/input/UserAgentInputOption.ts @@ -1,5 +1,5 @@ -import { MediaStream } from '../../MediaStream.ts'; -import { InputSource } from '../../input/InputSource.ts'; +import { MediaStream } from '@/ffmpeg/builder/MediaStream.ts'; +import { InputSource } from '@/ffmpeg/builder/input/InputSource.ts'; import { InputOption } from './InputOption.ts'; export class UserAgentInputOption extends InputOption { diff --git a/server/src/ffmpeg/builder/pipeline/BasePipelineBuilder.ts b/server/src/ffmpeg/builder/pipeline/BasePipelineBuilder.ts index 633253c3..5ab425c3 100644 --- a/server/src/ffmpeg/builder/pipeline/BasePipelineBuilder.ts +++ b/server/src/ffmpeg/builder/pipeline/BasePipelineBuilder.ts @@ -1,26 +1,61 @@ +import { AudioStream, VideoStream } from '@/ffmpeg/builder/MediaStream.ts'; +import { FfmpegCapabilities } from '@/ffmpeg/builder/capabilities/FfmpegCapabilities.ts'; +import { Decoder } from '@/ffmpeg/builder/decoder/Decoder.ts'; +import { DecoderFactory } from '@/ffmpeg/builder/decoder/DecoderFactory.ts'; +import { + AudioEncoder, + VideoEncoder, +} from '@/ffmpeg/builder/encoder/BaseEncoder.ts'; +import { Encoder } from '@/ffmpeg/builder/encoder/Encoder.ts'; +import { AudioPadFilter } from '@/ffmpeg/builder/filter/AudioPadFilter.ts'; +import { AudioFirstPtsFilter } from '@/ffmpeg/builder/filter/AudioResampleFilter.ts'; +import { ComplexFilter } from '@/ffmpeg/builder/filter/ComplexFilter.ts'; +import { FilterChain } from '@/ffmpeg/builder/filter/FilterChain.ts'; +import { LoopFilter } from '@/ffmpeg/builder/filter/LoopFilter.ts'; +import { RealtimeFilter } from '@/ffmpeg/builder/filter/RealtimeFilter.ts'; +import { AudioInputSource } from '@/ffmpeg/builder/input/AudioInputSource.ts'; +import { ConcatInputSource } from '@/ffmpeg/builder/input/ConcatInputSource.ts'; +import { VideoInputSource } from '@/ffmpeg/builder/input/VideoInputSource.ts'; +import { WatermarkInputSource } from '@/ffmpeg/builder/input/WatermarkInputSource.ts'; +import { HlsConcatOutputFormat } from '@/ffmpeg/builder/options/HlsConcatOutputFormat.ts'; +import { HlsOutputFormat } from '@/ffmpeg/builder/options/HlsOutputFormat.ts'; +import { LogLevelOption } from '@/ffmpeg/builder/options/LogLevelOption.ts'; +import { NoStatsOption } from '@/ffmpeg/builder/options/NoStatsOption.ts'; +import { ConcatHttpReconnectOptions } from '@/ffmpeg/builder/options/input/ConcatHttpReconnectOptions.ts'; +import { ConcatInputFormatOption } from '@/ffmpeg/builder/options/input/ConcatInputFormatOption.ts'; +import { HttpReconnectOptions } from '@/ffmpeg/builder/options/input/HttpReconnectOptions.ts'; +import { InfiniteLoopInputOption } from '@/ffmpeg/builder/options/input/InfiniteLoopInputOption.ts'; +import { ReadrateInputOption } from '@/ffmpeg/builder/options/input/ReadrateInputOption.ts'; +import { StreamSeekInputOption } from '@/ffmpeg/builder/options/input/StreamSeekInputOption.ts'; +import { UserAgentInputOption } from '@/ffmpeg/builder/options/input/UserAgentInputOption.ts'; +import { AudioState } from '@/ffmpeg/builder/state/AudioState.ts'; +import { FfmpegState } from '@/ffmpeg/builder/state/FfmpegState.ts'; +import { FrameState } from '@/ffmpeg/builder/state/FrameState.ts'; +import { + FrameDataLocation, + HardwareAccelerationMode, +} from '@/ffmpeg/builder/types.ts'; +import { + IPipelineStep, + PipelineStep, +} from '@/ffmpeg/builder/types/PipelineStep.ts'; +import { Nilable, Nullable } from '@/types/util.ts'; +import { ifDefined, isNonEmptyString } from '@/util/index.ts'; +import { Logger, LoggerFactory } from '@/util/logging/LoggerFactory.ts'; +import { getTunarrVersion } from '@/util/version.ts'; import { find, first, isNil, isNull, isUndefined } from 'lodash-es'; import { MarkRequired } from 'ts-essentials'; import { P, match } from 'ts-pattern'; -import { Nilable, Nullable } from '../../../types/util.ts'; -import { ifDefined, isNonEmptyString } from '../../../util/index.ts'; -import { Logger, LoggerFactory } from '../../../util/logging/LoggerFactory.ts'; -import { getTunarrVersion } from '../../../util/version.ts'; -import { AudioStream, VideoStream } from '../MediaStream.ts'; -import { FfmpegCapabilities } from '../capabilities/FfmpegCapabilities.ts'; import { OutputFormatTypes, OutputLocation, VideoFormats, } from '../constants.ts'; -import { Decoder } from '../decoder/Decoder.ts'; -import { DecoderFactory } from '../decoder/DecoderFactory.ts'; -import { AudioEncoder, VideoEncoder } from '../encoder/BaseEncoder.ts'; import { CopyAllEncoder, CopyAudioEncoder, CopyVideoEncoder, } from '../encoder/CopyEncoders.ts'; -import { Encoder } from '../encoder/Encoder.ts'; import { ImplicitVideoEncoder, LibKvazaarEncoder, @@ -29,16 +64,6 @@ import { Libx265Encoder, RawVideoEncoder, } from '../encoder/SoftwareVideoEncoders.ts'; -import { AudioPadFilter } from '../filter/AudioPadFilter.ts'; -import { AudioFirstPtsFilter } from '../filter/AudioResampleFilter.ts'; -import { ComplexFilter } from '../filter/ComplexFilter.ts'; -import { FilterChain } from '../filter/FilterChain.ts'; -import { LoopFilter } from '../filter/LoopFilter.ts'; -import { RealtimeFilter } from '../filter/RealtimeFilter.ts'; -import { AudioInputSource } from '../input/AudioInputSource.ts'; -import { ConcatInputSource } from '../input/ConcatInputSource.ts'; -import { VideoInputSource } from '../input/VideoInputSource.ts'; -import { WatermarkInputSource } from '../input/WatermarkInputSource.ts'; import { AudioBitrateOutputOption, AudioBufferSizeOutputOption, @@ -51,10 +76,6 @@ import { StandardFormatFlags, ThreadCountOption, } from '../options/GlobalOption.ts'; -import { HlsConcatOutputFormat } from '../options/HlsConcatOutputFormat.ts'; -import { HlsOutputFormat } from '../options/HlsOutputFormat.ts'; -import { LogLevelOption } from '../options/LogLevelOption.ts'; -import { NoStatsOption } from '../options/NoStatsOption.ts'; import { ClosedGopOutputOption, DoNotMapMetadataOutputOption, @@ -77,18 +98,6 @@ import { VideoBufferSizeOutputOption, VideoTrackTimescaleOutputOption, } from '../options/OutputOption.ts'; -import { ConcatHttpReconnectOptions } from '../options/input/ConcatHttpReconnectOptions.ts'; -import { ConcatInputFormatOption } from '../options/input/ConcatInputFormatOption.ts'; -import { HttpReconnectOptions } from '../options/input/HttpReconnectOptions.ts'; -import { InfiniteLoopInputOption } from '../options/input/InfiniteLoopInputOption.ts'; -import { ReadrateInputOption } from '../options/input/ReadrateInputOption.ts'; -import { StreamSeekInputOption } from '../options/input/StreamSeekInputOption.ts'; -import { UserAgentInputOption } from '../options/input/UserAgentInputOption.ts'; -import { AudioState } from '../state/AudioState.ts'; -import { FfmpegState } from '../state/FfmpegState.ts'; -import { FrameState } from '../state/FrameState.ts'; -import { FrameDataLocation, HardwareAccelerationMode } from '../types.ts'; -import { IPipelineStep, PipelineStep } from '../types/PipelineStep.ts'; import { Pipeline } from './Pipeline.ts'; import { PipelineBuilder } from './PipelineBuilder.ts'; diff --git a/server/src/ffmpeg/builder/pipeline/Pipeline.ts b/server/src/ffmpeg/builder/pipeline/Pipeline.ts index 230c4fe5..09319612 100644 --- a/server/src/ffmpeg/builder/pipeline/Pipeline.ts +++ b/server/src/ffmpeg/builder/pipeline/Pipeline.ts @@ -1,6 +1,6 @@ +import { FfmpegCommandGenerator } from '@/ffmpeg/builder/FfmpegCommandGenerator.ts'; +import { PipelineStep } from '@/ffmpeg/builder/types/PipelineStep.ts'; import { Dictionary } from 'ts-essentials'; -import { FfmpegCommandGenerator } from '../FfmpegCommandGenerator.ts'; -import { PipelineStep } from '../types/PipelineStep.ts'; import { PipelineInputs } from './PipelineInputs.ts'; /** diff --git a/server/src/ffmpeg/builder/pipeline/PipelineBuilder.ts b/server/src/ffmpeg/builder/pipeline/PipelineBuilder.ts index 5b0012ea..76e3e7dd 100644 --- a/server/src/ffmpeg/builder/pipeline/PipelineBuilder.ts +++ b/server/src/ffmpeg/builder/pipeline/PipelineBuilder.ts @@ -1,7 +1,7 @@ -import { Nullable } from '../../../types/util.ts'; -import { ConcatInputSource } from '../input/ConcatInputSource.ts'; -import { FfmpegState } from '../state/FfmpegState.ts'; -import { FrameState } from '../state/FrameState.ts'; +import { ConcatInputSource } from '@/ffmpeg/builder/input/ConcatInputSource.ts'; +import { FfmpegState } from '@/ffmpeg/builder/state/FfmpegState.ts'; +import { FrameState } from '@/ffmpeg/builder/state/FrameState.ts'; +import { Nullable } from '@/types/util.ts'; import { Pipeline } from './Pipeline.ts'; export interface PipelineBuilder { diff --git a/server/src/ffmpeg/builder/pipeline/PipelineBuilderFactory.ts b/server/src/ffmpeg/builder/pipeline/PipelineBuilderFactory.ts index faab1900..ba7e950f 100644 --- a/server/src/ffmpeg/builder/pipeline/PipelineBuilderFactory.ts +++ b/server/src/ffmpeg/builder/pipeline/PipelineBuilderFactory.ts @@ -1,14 +1,14 @@ +import { SettingsDB, getSettings } from '@/db/SettingsDB.ts'; +import { AudioInputSource } from '@/ffmpeg/builder/input/AudioInputSource.ts'; +import { ConcatInputSource } from '@/ffmpeg/builder/input/ConcatInputSource.ts'; +import { VideoInputSource } from '@/ffmpeg/builder/input/VideoInputSource.ts'; +import { WatermarkInputSource } from '@/ffmpeg/builder/input/WatermarkInputSource.ts'; +import { HardwareAccelerationMode } from '@/ffmpeg/builder/types.ts'; +import { FFMPEGInfo } from '@/ffmpeg/ffmpegInfo.ts'; +import { Nullable } from '@/types/util.ts'; import { FfmpegSettings } from '@tunarr/types'; import { isNull, isUndefined } from 'lodash-es'; import { DeepReadonly } from 'ts-essentials'; -import { SettingsDB, getSettings } from '../../../dao/settings.ts'; -import { Nullable } from '../../../types/util.ts'; -import { FFMPEGInfo } from '../../ffmpegInfo.ts'; -import { AudioInputSource } from '../input/AudioInputSource.ts'; -import { ConcatInputSource } from '../input/ConcatInputSource.ts'; -import { VideoInputSource } from '../input/VideoInputSource.ts'; -import { WatermarkInputSource } from '../input/WatermarkInputSource.ts'; -import { HardwareAccelerationMode } from '../types.ts'; import { PipelineBuilder } from './PipelineBuilder.js'; import { NvidiaPipelineBuilder } from './hardware/NvidiaPipelineBuilder.ts'; import { QsvPipelineBuilder } from './hardware/QsvPipelineBuilder.ts'; diff --git a/server/src/ffmpeg/builder/pipeline/PipelineInputs.ts b/server/src/ffmpeg/builder/pipeline/PipelineInputs.ts index 2c90db07..e458d289 100644 --- a/server/src/ffmpeg/builder/pipeline/PipelineInputs.ts +++ b/server/src/ffmpeg/builder/pipeline/PipelineInputs.ts @@ -1,8 +1,8 @@ -import { Nullable } from '../../../types/util.ts'; -import { AudioInputSource } from '../input/AudioInputSource.ts'; -import { ConcatInputSource } from '../input/ConcatInputSource.ts'; -import { VideoInputSource } from '../input/VideoInputSource.ts'; -import { WatermarkInputSource } from '../input/WatermarkInputSource.ts'; +import { AudioInputSource } from '@/ffmpeg/builder/input/AudioInputSource.ts'; +import { ConcatInputSource } from '@/ffmpeg/builder/input/ConcatInputSource.ts'; +import { VideoInputSource } from '@/ffmpeg/builder/input/VideoInputSource.ts'; +import { WatermarkInputSource } from '@/ffmpeg/builder/input/WatermarkInputSource.ts'; +import { Nullable } from '@/types/util.ts'; export type PipelineInputs = { videoInput: Nullable; diff --git a/server/src/ffmpeg/builder/pipeline/hardware/NvidiaPipelineBuilder.ts b/server/src/ffmpeg/builder/pipeline/hardware/NvidiaPipelineBuilder.ts index 563b134f..2f466e1b 100644 --- a/server/src/ffmpeg/builder/pipeline/hardware/NvidiaPipelineBuilder.ts +++ b/server/src/ffmpeg/builder/pipeline/hardware/NvidiaPipelineBuilder.ts @@ -1,43 +1,49 @@ +import { BaseFfmpegHardwareCapabilities } from '@/ffmpeg/builder/capabilities/BaseFfmpegHardwareCapabilities.ts'; +import { FfmpegCapabilities } from '@/ffmpeg/builder/capabilities/FfmpegCapabilities.ts'; +import { OutputFormatTypes, VideoFormats } from '@/ffmpeg/builder/constants.ts'; +import { Decoder } from '@/ffmpeg/builder/decoder/Decoder.ts'; +import { DecoderFactory } from '@/ffmpeg/builder/decoder/DecoderFactory.ts'; +import { + BaseEncoder, + VideoEncoder, +} from '@/ffmpeg/builder/encoder/BaseEncoder.ts'; +import { DeinterlaceFilter } from '@/ffmpeg/builder/filter/DeinterlaceFilter.ts'; +import { FilterOption } from '@/ffmpeg/builder/filter/FilterOption.ts'; +import { PadFilter } from '@/ffmpeg/builder/filter/PadFilter.ts'; +import { PixelFormatFilter } from '@/ffmpeg/builder/filter/PixelFormatFilter.ts'; +import { ScaleFilter } from '@/ffmpeg/builder/filter/ScaleFilter.ts'; +import { FormatCudaFilter } from '@/ffmpeg/builder/filter/nvidia/FormatCudaFilter.ts'; +import { HardwareDownloadCudaFilter } from '@/ffmpeg/builder/filter/nvidia/HardwareDownloadCudaFilter.ts'; +import { HardwareUploadCudaFilter } from '@/ffmpeg/builder/filter/nvidia/HardwareUploadCudaFilter.ts'; +import { OverlayWatermarkCudaFilter } from '@/ffmpeg/builder/filter/nvidia/OverlayWatermarkCudaFilter.ts'; +import { ScaleCudaFilter } from '@/ffmpeg/builder/filter/nvidia/ScaleCudaFilter.ts'; +import { YadifCudaFilter } from '@/ffmpeg/builder/filter/nvidia/YadifCudaFilter.ts'; +import { OverlayWatermarkFilter } from '@/ffmpeg/builder/filter/watermark/OverlayWatermarkFilter.ts'; +import { AudioInputSource } from '@/ffmpeg/builder/input/AudioInputSource.ts'; +import { ConcatInputSource } from '@/ffmpeg/builder/input/ConcatInputSource.ts'; +import { VideoInputSource } from '@/ffmpeg/builder/input/VideoInputSource.ts'; +import { WatermarkInputSource } from '@/ffmpeg/builder/input/WatermarkInputSource.ts'; +import { PixelFormatOutputOption } from '@/ffmpeg/builder/options/OutputOption.ts'; +import { CudaHardwareAccelerationOption } from '@/ffmpeg/builder/options/hardwareAcceleration/NvidiaOptions.ts'; +import { isVideoPipelineContext } from '@/ffmpeg/builder/pipeline/BasePipelineBuilder.ts'; +import { SoftwarePipelineBuilder } from '@/ffmpeg/builder/pipeline/software/SoftwarePipelineBuilder.ts'; +import { FrameState } from '@/ffmpeg/builder/state/FrameState.ts'; +import { + FrameDataLocation, + HardwareAccelerationMode, +} from '@/ffmpeg/builder/types.ts'; +import { Nullable } from '@/types/util.ts'; +import { isNonEmptyString } from '@/util/index.ts'; import { isNil, isNull, reject, some } from 'lodash-es'; -import { Nullable } from '../../../../types/util.ts'; -import { isNonEmptyString } from '../../../../util/index.ts'; -import { BaseFfmpegHardwareCapabilities } from '../../capabilities/BaseFfmpegHardwareCapabilities.ts'; -import { FfmpegCapabilities } from '../../capabilities/FfmpegCapabilities.ts'; -import { OutputFormatTypes, VideoFormats } from '../../constants.ts'; -import { Decoder } from '../../decoder/Decoder.ts'; -import { DecoderFactory } from '../../decoder/DecoderFactory.ts'; -import { BaseEncoder, VideoEncoder } from '../../encoder/BaseEncoder.ts'; import { NvidiaH264Encoder, NvidiaHevcEncoder, } from '../../encoder/nvidia/NvidiaEncoders.ts'; -import { DeinterlaceFilter } from '../../filter/DeinterlaceFilter.ts'; -import { FilterOption } from '../../filter/FilterOption.ts'; -import { PadFilter } from '../../filter/PadFilter.ts'; -import { PixelFormatFilter } from '../../filter/PixelFormatFilter.ts'; -import { ScaleFilter } from '../../filter/ScaleFilter.ts'; -import { FormatCudaFilter } from '../../filter/nvidia/FormatCudaFilter.ts'; -import { HardwareDownloadCudaFilter } from '../../filter/nvidia/HardwareDownloadCudaFilter.ts'; -import { HardwareUploadCudaFilter } from '../../filter/nvidia/HardwareUploadCudaFilter.ts'; -import { OverlayWatermarkCudaFilter } from '../../filter/nvidia/OverlayWatermarkCudaFilter.ts'; -import { ScaleCudaFilter } from '../../filter/nvidia/ScaleCudaFilter.ts'; -import { YadifCudaFilter } from '../../filter/nvidia/YadifCudaFilter.ts'; -import { OverlayWatermarkFilter } from '../../filter/watermark/OverlayWatermarkFilter.ts'; import { PixelFormatNv12, PixelFormatYuv420P, PixelFormatYuva420P, } from '../../format/PixelFormat.ts'; -import { AudioInputSource } from '../../input/AudioInputSource.ts'; -import { ConcatInputSource } from '../../input/ConcatInputSource.ts'; -import { VideoInputSource } from '../../input/VideoInputSource.ts'; -import { WatermarkInputSource } from '../../input/WatermarkInputSource.ts'; -import { PixelFormatOutputOption } from '../../options/OutputOption.ts'; -import { CudaHardwareAccelerationOption } from '../../options/hardwareAcceleration/NvidiaOptions.ts'; -import { FrameState } from '../../state/FrameState.ts'; -import { FrameDataLocation, HardwareAccelerationMode } from '../../types.ts'; -import { isVideoPipelineContext } from '../BasePipelineBuilder.ts'; -import { SoftwarePipelineBuilder } from '../software/SoftwarePipelineBuilder.ts'; export class NvidiaPipelineBuilder extends SoftwarePipelineBuilder { constructor( diff --git a/server/src/ffmpeg/builder/pipeline/hardware/QsvPipelineBuilder.ts b/server/src/ffmpeg/builder/pipeline/hardware/QsvPipelineBuilder.ts index 33840053..a42424fb 100644 --- a/server/src/ffmpeg/builder/pipeline/hardware/QsvPipelineBuilder.ts +++ b/server/src/ffmpeg/builder/pipeline/hardware/QsvPipelineBuilder.ts @@ -1,25 +1,25 @@ +import { VideoFormats } from '@/ffmpeg/builder/constants.ts'; +import { Decoder } from '@/ffmpeg/builder/decoder/Decoder.ts'; +import { DecoderFactory } from '@/ffmpeg/builder/decoder/DecoderFactory.ts'; +import { Encoder } from '@/ffmpeg/builder/encoder/Encoder.ts'; +import { DeinterlaceFilter } from '@/ffmpeg/builder/filter/DeinterlaceFilter.ts'; +import { FilterOption } from '@/ffmpeg/builder/filter/FilterOption.ts'; +import { ScaleFilter } from '@/ffmpeg/builder/filter/ScaleFilter.ts'; +import { DeinterlaceQsvFilter } from '@/ffmpeg/builder/filter/qsv/DeinterlaceQsvFilter.ts'; +import { ScaleQsvFilter } from '@/ffmpeg/builder/filter/qsv/ScaleQsvFilter.ts'; +import { QsvHardwareAccelerationOption } from '@/ffmpeg/builder/options/hardwareAcceleration/QsvOptions.ts'; +import { isVideoPipelineContext } from '@/ffmpeg/builder/pipeline/BasePipelineBuilder.ts'; +import { SoftwarePipelineBuilder } from '@/ffmpeg/builder/pipeline/software/SoftwarePipelineBuilder.ts'; +import { FrameState } from '@/ffmpeg/builder/state/FrameState.ts'; +import { HardwareAccelerationMode } from '@/ffmpeg/builder/types.ts'; +import { Nullable } from '@/types/util.ts'; +import { isNonEmptyString } from '@/util/index.ts'; import { isNull } from 'lodash-es'; -import { Nullable } from '../../../../types/util.ts'; -import { isNonEmptyString } from '../../../../util/index.ts'; -import { VideoFormats } from '../../constants.ts'; -import { Decoder } from '../../decoder/Decoder.ts'; -import { DecoderFactory } from '../../decoder/DecoderFactory.ts'; -import { Encoder } from '../../encoder/Encoder.ts'; import { H264QsvEncoder, HevcQsvEncoder, Mpeg2QsvEncoder, } from '../../encoder/qsv/QsvEncoders.ts'; -import { DeinterlaceFilter } from '../../filter/DeinterlaceFilter.ts'; -import { FilterOption } from '../../filter/FilterOption.ts'; -import { ScaleFilter } from '../../filter/ScaleFilter.ts'; -import { DeinterlaceQsvFilter } from '../../filter/qsv/DeinterlaceQsvFilter.ts'; -import { ScaleQsvFilter } from '../../filter/qsv/ScaleQsvFilter.ts'; -import { QsvHardwareAccelerationOption } from '../../options/hardwareAcceleration/QsvOptions.ts'; -import { FrameState } from '../../state/FrameState.ts'; -import { HardwareAccelerationMode } from '../../types.ts'; -import { isVideoPipelineContext } from '../BasePipelineBuilder.ts'; -import { SoftwarePipelineBuilder } from '../software/SoftwarePipelineBuilder.ts'; export class QsvPipelineBuilder extends SoftwarePipelineBuilder { protected setHardwareAccelState(): void { diff --git a/server/src/ffmpeg/builder/pipeline/hardware/VaapiPipelineBuilder.ts b/server/src/ffmpeg/builder/pipeline/hardware/VaapiPipelineBuilder.ts index 5d35d0e5..b221a896 100644 --- a/server/src/ffmpeg/builder/pipeline/hardware/VaapiPipelineBuilder.ts +++ b/server/src/ffmpeg/builder/pipeline/hardware/VaapiPipelineBuilder.ts @@ -1,31 +1,42 @@ +import { BaseFfmpegHardwareCapabilities } from '@/ffmpeg/builder/capabilities/BaseFfmpegHardwareCapabilities.ts'; +import { FfmpegCapabilities } from '@/ffmpeg/builder/capabilities/FfmpegCapabilities.ts'; +import { OutputFormatTypes, VideoFormats } from '@/ffmpeg/builder/constants.ts'; +import { Decoder } from '@/ffmpeg/builder/decoder/Decoder.ts'; +import { VaapiDecoder } from '@/ffmpeg/builder/decoder/vaapi/VaapiDecoder.ts'; +import { Encoder } from '@/ffmpeg/builder/encoder/Encoder.ts'; +import { DeinterlaceFilter } from '@/ffmpeg/builder/filter/DeinterlaceFilter.ts'; +import { FilterOption } from '@/ffmpeg/builder/filter/FilterOption.ts'; +import { HardwareDownloadFilter } from '@/ffmpeg/builder/filter/HardwareDownloadFilter.ts'; +import { PadFilter } from '@/ffmpeg/builder/filter/PadFilter.ts'; +import { PixelFormatFilter } from '@/ffmpeg/builder/filter/PixelFormatFilter.ts'; +import { ScaleFilter } from '@/ffmpeg/builder/filter/ScaleFilter.ts'; +import { DeinterlaceVaapiFilter } from '@/ffmpeg/builder/filter/vaapi/DeinterlaceVaapiFilter.ts'; +import { HardwareUploadVaapiFilter } from '@/ffmpeg/builder/filter/vaapi/HardwareUploadVaapiFilter.ts'; +import { ScaleVaapiFilter } from '@/ffmpeg/builder/filter/vaapi/ScaleVaapiFilter.ts'; +import { VaapiFormatFilter } from '@/ffmpeg/builder/filter/vaapi/VaapiFormatFilter.ts'; +import { OverlayWatermarkFilter } from '@/ffmpeg/builder/filter/watermark/OverlayWatermarkFilter.ts'; +import { WatermarkOpacityFilter } from '@/ffmpeg/builder/filter/watermark/WatermarkOpacityFilter.ts'; +import { WatermarkScaleFilter } from '@/ffmpeg/builder/filter/watermark/WatermarkScaleFilter.ts'; +import { AudioInputSource } from '@/ffmpeg/builder/input/AudioInputSource.ts'; +import { ConcatInputSource } from '@/ffmpeg/builder/input/ConcatInputSource.ts'; +import { VideoInputSource } from '@/ffmpeg/builder/input/VideoInputSource.ts'; +import { WatermarkInputSource } from '@/ffmpeg/builder/input/WatermarkInputSource.ts'; +import { VaapiDriverEnvironmentVariable } from '@/ffmpeg/builder/options/EnvironmentVariables.ts'; +import { VaapiHardwareAccelerationOption } from '@/ffmpeg/builder/options/hardwareAcceleration/VaapiOptions.ts'; +import { DoNotIgnoreLoopInputOption } from '@/ffmpeg/builder/options/input/DoNotIgnoreLoopInputOption.ts'; +import { InfiniteLoopInputOption } from '@/ffmpeg/builder/options/input/InfiniteLoopInputOption.ts'; +import { isVideoPipelineContext } from '@/ffmpeg/builder/pipeline/BasePipelineBuilder.ts'; +import { SoftwarePipelineBuilder } from '@/ffmpeg/builder/pipeline/software/SoftwarePipelineBuilder.ts'; +import { FrameState } from '@/ffmpeg/builder/state/FrameState.ts'; +import { Nullable } from '@/types/util.ts'; +import { isDefined, isNonEmptyString } from '@/util/index.ts'; import { every, filter, head, inRange, isUndefined } from 'lodash-es'; import { P, match } from 'ts-pattern'; -import { Nullable } from '../../../../types/util.ts'; -import { isDefined, isNonEmptyString } from '../../../../util/index.ts'; -import { BaseFfmpegHardwareCapabilities } from '../../capabilities/BaseFfmpegHardwareCapabilities.ts'; -import { FfmpegCapabilities } from '../../capabilities/FfmpegCapabilities.ts'; -import { OutputFormatTypes, VideoFormats } from '../../constants.ts'; -import { Decoder } from '../../decoder/Decoder.ts'; -import { VaapiDecoder } from '../../decoder/vaapi/VaapiDecoder.ts'; -import { Encoder } from '../../encoder/Encoder.ts'; import { H264VaapiEncoder, HevcVaapiEncoder, Mpeg2VaapiEncoder, } from '../../encoder/vaapi/VaapiEncoders.ts'; -import { DeinterlaceFilter } from '../../filter/DeinterlaceFilter.ts'; -import { FilterOption } from '../../filter/FilterOption.ts'; -import { HardwareDownloadFilter } from '../../filter/HardwareDownloadFilter.ts'; -import { PadFilter } from '../../filter/PadFilter.ts'; -import { PixelFormatFilter } from '../../filter/PixelFormatFilter.ts'; -import { ScaleFilter } from '../../filter/ScaleFilter.ts'; -import { DeinterlaceVaapiFilter } from '../../filter/vaapi/DeinterlaceVaapiFilter.ts'; -import { HardwareUploadVaapiFilter } from '../../filter/vaapi/HardwareUploadVaapiFilter.ts'; -import { ScaleVaapiFilter } from '../../filter/vaapi/ScaleVaapiFilter.ts'; -import { VaapiFormatFilter } from '../../filter/vaapi/VaapiFormatFilter.ts'; -import { OverlayWatermarkFilter } from '../../filter/watermark/OverlayWatermarkFilter.ts'; -import { WatermarkOpacityFilter } from '../../filter/watermark/WatermarkOpacityFilter.ts'; -import { WatermarkScaleFilter } from '../../filter/watermark/WatermarkScaleFilter.ts'; import { FfmpegPixelFormats, KnownPixelFormats, @@ -33,26 +44,15 @@ import { PixelFormatYuva420P, PixelFormats, } from '../../format/PixelFormat.ts'; -import { AudioInputSource } from '../../input/AudioInputSource.ts'; -import { ConcatInputSource } from '../../input/ConcatInputSource.ts'; -import { VideoInputSource } from '../../input/VideoInputSource.ts'; -import { WatermarkInputSource } from '../../input/WatermarkInputSource.ts'; -import { VaapiDriverEnvironmentVariable } from '../../options/EnvironmentVariables.ts'; import { NoAutoScaleOutputOption, PixelFormatOutputOption, } from '../../options/OutputOption.ts'; -import { VaapiHardwareAccelerationOption } from '../../options/hardwareAcceleration/VaapiOptions.ts'; -import { DoNotIgnoreLoopInputOption } from '../../options/input/DoNotIgnoreLoopInputOption.ts'; -import { InfiniteLoopInputOption } from '../../options/input/InfiniteLoopInputOption.ts'; -import { FrameState } from '../../state/FrameState.ts'; import { FrameDataLocation, HardwareAccelerationMode, RateControlMode, } from '../../types.ts'; -import { isVideoPipelineContext } from '../BasePipelineBuilder.ts'; -import { SoftwarePipelineBuilder } from '../software/SoftwarePipelineBuilder.ts'; export class VaapiPipelineBuilder extends SoftwarePipelineBuilder { constructor( diff --git a/server/src/ffmpeg/builder/pipeline/hardware/VideoToolboxPipelineBuilder.ts b/server/src/ffmpeg/builder/pipeline/hardware/VideoToolboxPipelineBuilder.ts index 18b2bc0a..048ea442 100644 --- a/server/src/ffmpeg/builder/pipeline/hardware/VideoToolboxPipelineBuilder.ts +++ b/server/src/ffmpeg/builder/pipeline/hardware/VideoToolboxPipelineBuilder.ts @@ -1,25 +1,25 @@ +import { BaseFfmpegHardwareCapabilities } from '@/ffmpeg/builder/capabilities/BaseFfmpegHardwareCapabilities.ts'; +import { FfmpegCapabilities } from '@/ffmpeg/builder/capabilities/FfmpegCapabilities.ts'; +import { VideoFormats } from '@/ffmpeg/builder/constants.ts'; +import { Decoder } from '@/ffmpeg/builder/decoder/Decoder.ts'; +import { VideoToolboxDecoder } from '@/ffmpeg/builder/decoder/videotoolbox/VideoToolboxDecoder.ts'; +import { FilterOption } from '@/ffmpeg/builder/filter/FilterOption.ts'; +import { VideoToolboxHardwareAccelerationOption } from '@/ffmpeg/builder/filter/videotoolbox/VideoToolboxHardwareAccelerationOption.ts'; +import { AudioInputSource } from '@/ffmpeg/builder/input/AudioInputSource.ts'; +import { ConcatInputSource } from '@/ffmpeg/builder/input/ConcatInputSource.ts'; +import { VideoInputSource } from '@/ffmpeg/builder/input/VideoInputSource.ts'; +import { WatermarkInputSource } from '@/ffmpeg/builder/input/WatermarkInputSource.ts'; +import { PixelFormatOutputOption } from '@/ffmpeg/builder/options/OutputOption.ts'; +import { isVideoPipelineContext } from '@/ffmpeg/builder/pipeline/BasePipelineBuilder.ts'; +import { SoftwarePipelineBuilder } from '@/ffmpeg/builder/pipeline/software/SoftwarePipelineBuilder.ts'; +import { FrameState } from '@/ffmpeg/builder/state/FrameState.ts'; +import { HardwareAccelerationMode } from '@/ffmpeg/builder/types.ts'; +import { Nullable } from '@/types/util.ts'; import { match } from 'ts-pattern'; -import { Nullable } from '../../../../types/util.ts'; -import { BaseFfmpegHardwareCapabilities } from '../../capabilities/BaseFfmpegHardwareCapabilities.ts'; -import { FfmpegCapabilities } from '../../capabilities/FfmpegCapabilities.ts'; -import { VideoFormats } from '../../constants.ts'; -import { Decoder } from '../../decoder/Decoder.ts'; -import { VideoToolboxDecoder } from '../../decoder/videotoolbox/VideoToolboxDecoder.ts'; import { VideoToolboxH264Encoder, VideoToolboxHevcEncoder, } from '../../encoder/videotoolbox/VideoToolboxEncoders.ts'; -import { FilterOption } from '../../filter/FilterOption.ts'; -import { VideoToolboxHardwareAccelerationOption } from '../../filter/videotoolbox/VideoToolboxHardwareAccelerationOption.ts'; -import { AudioInputSource } from '../../input/AudioInputSource.ts'; -import { ConcatInputSource } from '../../input/ConcatInputSource.ts'; -import { VideoInputSource } from '../../input/VideoInputSource.ts'; -import { WatermarkInputSource } from '../../input/WatermarkInputSource.ts'; -import { PixelFormatOutputOption } from '../../options/OutputOption.ts'; -import { FrameState } from '../../state/FrameState.ts'; -import { HardwareAccelerationMode } from '../../types.ts'; -import { isVideoPipelineContext } from '../BasePipelineBuilder.ts'; -import { SoftwarePipelineBuilder } from '../software/SoftwarePipelineBuilder.ts'; export class VideoToolboxPipelineBuilder extends SoftwarePipelineBuilder { constructor( diff --git a/server/src/ffmpeg/builder/pipeline/software/SoftwarePipelineBuilder.test.ts b/server/src/ffmpeg/builder/pipeline/software/SoftwarePipelineBuilder.test.ts index abbcd444..139a8b9f 100644 --- a/server/src/ffmpeg/builder/pipeline/software/SoftwarePipelineBuilder.test.ts +++ b/server/src/ffmpeg/builder/pipeline/software/SoftwarePipelineBuilder.test.ts @@ -1,10 +1,10 @@ -import { AudioStream, VideoStream } from '../../MediaStream.ts'; -import { VideoFormats } from '../../constants.ts'; -import { PixelFormat } from '../../format/PixelFormat.ts'; -import { AudioInputSource } from '../../input/AudioInputSource.ts'; -import { AudioState } from '../../state/AudioState.ts'; -import { FrameState } from '../../state/FrameState.ts'; -import { FrameSize } from '../../types.ts'; +import { AudioStream, VideoStream } from '@/ffmpeg/builder/MediaStream.ts'; +import { VideoFormats } from '@/ffmpeg/builder/constants.ts'; +import { PixelFormat } from '@/ffmpeg/builder/format/PixelFormat.ts'; +import { AudioInputSource } from '@/ffmpeg/builder/input/AudioInputSource.ts'; +import { AudioState } from '@/ffmpeg/builder/state/AudioState.ts'; +import { FrameState } from '@/ffmpeg/builder/state/FrameState.ts'; +import { FrameSize } from '@/ffmpeg/builder/types.ts'; describe('SoftwarePipelineBuilder', () => { test('build args', () => { diff --git a/server/src/ffmpeg/builder/pipeline/software/SoftwarePipelineBuilder.ts b/server/src/ffmpeg/builder/pipeline/software/SoftwarePipelineBuilder.ts index 9f582d5d..37ddb65a 100644 --- a/server/src/ffmpeg/builder/pipeline/software/SoftwarePipelineBuilder.ts +++ b/server/src/ffmpeg/builder/pipeline/software/SoftwarePipelineBuilder.ts @@ -1,14 +1,14 @@ +import { VideoFormats } from '@/ffmpeg/builder/constants.ts'; +import { Encoder } from '@/ffmpeg/builder/encoder/Encoder.ts'; +import { DeinterlaceFilter } from '@/ffmpeg/builder/filter/DeinterlaceFilter.ts'; +import { FilterOption } from '@/ffmpeg/builder/filter/FilterOption.ts'; +import { PadFilter } from '@/ffmpeg/builder/filter/PadFilter.ts'; +import { ScaleFilter } from '@/ffmpeg/builder/filter/ScaleFilter.ts'; +import { OverlayWatermarkFilter } from '@/ffmpeg/builder/filter/watermark/OverlayWatermarkFilter.ts'; +import { PixelFormatYuv420P } from '@/ffmpeg/builder/format/PixelFormat.ts'; +import { PixelFormatOutputOption } from '@/ffmpeg/builder/options/OutputOption.ts'; +import { FrameState } from '@/ffmpeg/builder/state/FrameState.ts'; import { filter, isNull, some } from 'lodash-es'; -import { VideoFormats } from '../../constants.ts'; -import { Encoder } from '../../encoder/Encoder.ts'; -import { DeinterlaceFilter } from '../../filter/DeinterlaceFilter.ts'; -import { FilterOption } from '../../filter/FilterOption.ts'; -import { PadFilter } from '../../filter/PadFilter.ts'; -import { ScaleFilter } from '../../filter/ScaleFilter.ts'; -import { OverlayWatermarkFilter } from '../../filter/watermark/OverlayWatermarkFilter.ts'; -import { PixelFormatYuv420P } from '../../format/PixelFormat.ts'; -import { PixelFormatOutputOption } from '../../options/OutputOption.ts'; -import { FrameState } from '../../state/FrameState.ts'; import { BasePipelineBuilder, isVideoPipelineContext, diff --git a/server/src/ffmpeg/builder/state/AudioState.ts b/server/src/ffmpeg/builder/state/AudioState.ts index b07d0eea..35405adb 100644 --- a/server/src/ffmpeg/builder/state/AudioState.ts +++ b/server/src/ffmpeg/builder/state/AudioState.ts @@ -1,5 +1,5 @@ +import { ExcludeByValueType, Nullable } from '@/types/util.ts'; import { AnyFunction } from 'ts-essentials'; -import { ExcludeByValueType, Nullable } from '../../../types/util.ts'; export type AudioStateFields = ExcludeByValueType; diff --git a/server/src/ffmpeg/builder/state/FfmpegState.ts b/server/src/ffmpeg/builder/state/FfmpegState.ts index 73ba0de4..92af7e56 100644 --- a/server/src/ffmpeg/builder/state/FfmpegState.ts +++ b/server/src/ffmpeg/builder/state/FfmpegState.ts @@ -1,16 +1,16 @@ +import { DataProps, HardwareAccelerationMode } from '@/ffmpeg/builder/types.ts'; +import { FfmpegVersionResult } from '@/ffmpeg/ffmpegInfo.ts'; +import { Maybe, Nullable } from '@/types/util.ts'; import { FfmpegLogLevel } from '@tunarr/types/schemas'; import { isNil, merge } from 'lodash-es'; import path from 'path'; import { MarkRequired } from 'ts-essentials'; -import { Maybe, Nullable } from '../../../types/util.ts'; -import { FfmpegVersionResult } from '../../ffmpegInfo.ts'; import { MpegTsOutputFormat, OutputFormat, OutputFormatTypes, OutputLocation, } from '../constants.ts'; -import { DataProps, HardwareAccelerationMode } from '../types.ts'; export const DefaultFfmpegState: Partial> = { threadCount: null, diff --git a/server/src/ffmpeg/builder/state/FrameState.ts b/server/src/ffmpeg/builder/state/FrameState.ts index a3a3b689..a9e926f8 100644 --- a/server/src/ffmpeg/builder/state/FrameState.ts +++ b/server/src/ffmpeg/builder/state/FrameState.ts @@ -1,8 +1,12 @@ +import { PixelFormat } from '@/ffmpeg/builder/format/PixelFormat.ts'; +import { + DataProps, + FrameDataLocation, + FrameSize, +} from '@/ffmpeg/builder/types.ts'; +import { Nullable } from '@/types/util.ts'; import { merge } from 'lodash-es'; import { MarkOptional } from 'ts-essentials'; -import { Nullable } from '../../../types/util.ts'; -import { PixelFormat } from '../format/PixelFormat.ts'; -import { DataProps, FrameDataLocation, FrameSize } from '../types.ts'; type FrameStateFields = DataProps; diff --git a/server/src/ffmpeg/builder/types.ts b/server/src/ffmpeg/builder/types.ts index d20e479b..e8066184 100644 --- a/server/src/ffmpeg/builder/types.ts +++ b/server/src/ffmpeg/builder/types.ts @@ -1,6 +1,6 @@ +import { ExcludeByValueType, TupleToUnion } from '@/types/util.ts'; import { Resolution } from '@tunarr/types'; import { AnyFunction } from 'ts-essentials'; -import { ExcludeByValueType, TupleToUnion } from '../../types/util.ts'; export type DataProps = ExcludeByValueType; diff --git a/server/src/ffmpeg/builder/types/PipelineStep.ts b/server/src/ffmpeg/builder/types/PipelineStep.ts index 357ad58e..47fa6511 100644 --- a/server/src/ffmpeg/builder/types/PipelineStep.ts +++ b/server/src/ffmpeg/builder/types/PipelineStep.ts @@ -1,6 +1,6 @@ +import { InputSource } from '@/ffmpeg/builder/input/InputSource.ts'; +import { FrameState } from '@/ffmpeg/builder/state/FrameState.ts'; import { Dictionary } from 'ts-essentials'; -import { InputSource } from '../input/InputSource.ts'; -import { FrameState } from '../state/FrameState.ts'; export type PipelineStepType = | 'global' diff --git a/server/src/ffmpeg/ffmpeg.ts b/server/src/ffmpeg/ffmpeg.ts index dbdcfbdc..aa7f5de7 100644 --- a/server/src/ffmpeg/ffmpeg.ts +++ b/server/src/ffmpeg/ffmpeg.ts @@ -1,3 +1,11 @@ +import { Channel } from '@/db/schema/Channel.ts'; +import { serverOptions } from '@/globals.js'; +import { ConcatSessionType } from '@/stream/Session.js'; +import { Maybe, Nullable } from '@/types/util.js'; +import { gcd } from '@/util/index.ts'; +import { Logger, LoggerFactory } from '@/util/logging/LoggerFactory.js'; +import { makeLocalUrl } from '@/util/serverUtil.js'; +import { getTunarrVersion } from '@/util/version.js'; import { ChannelStreamMode, FfmpegSettings, @@ -13,9 +21,6 @@ import { Duration } from 'dayjs/plugin/duration.js'; import { first, isEmpty, isNil, isUndefined, merge, round } from 'lodash-es'; import path from 'path'; import { DeepReadonly, DeepRequired } from 'ts-essentials'; -import { Channel } from '../dao/direct/schema/Channel.ts'; -import { serverOptions } from '../globals.js'; -import { ConcatSessionType } from '../stream/Session.js'; import { ErrorStreamSource, OfflineStreamSource, @@ -23,17 +28,12 @@ import { StreamSource, getPixelFormatForStream, } from '../stream/types.js'; -import { Maybe, Nullable } from '../types/util.js'; import { isDefined, isLinux, isNonEmptyString, isSuccess, } from '../util/index.js'; -import { gcd } from '../util/index.ts'; -import { Logger, LoggerFactory } from '../util/logging/LoggerFactory.js'; -import { makeLocalUrl } from '../util/serverUtil.js'; -import { getTunarrVersion } from '../util/version.js'; import { FfmpegProcess } from './FfmpegProcess.js'; import { FfmpegTranscodeSession } from './FfmpegTrancodeSession.js'; import { diff --git a/server/src/ffmpeg/ffmpegBase.ts b/server/src/ffmpeg/ffmpegBase.ts index 2a36d96c..043375b4 100644 --- a/server/src/ffmpeg/ffmpegBase.ts +++ b/server/src/ffmpeg/ffmpegBase.ts @@ -1,7 +1,7 @@ +import { Maybe } from '@/types/util.ts'; import { ChannelStreamMode } from '@tunarr/types'; import { Duration } from 'dayjs/plugin/duration.js'; import { DeepReadonly } from 'ts-essentials'; -import { Maybe } from '../types/util.ts'; import { FfmpegTranscodeSession } from './FfmpegTrancodeSession.ts'; import { OutputFormat } from './builder/constants.ts'; import { ConcatOptions, StreamSessionOptions } from './ffmpeg.ts'; diff --git a/server/src/ffmpeg/ffmpegInfo.ts b/server/src/ffmpeg/ffmpegInfo.ts index 6e539852..3a8b6521 100644 --- a/server/src/ffmpeg/ffmpegInfo.ts +++ b/server/src/ffmpeg/ffmpegInfo.ts @@ -1,3 +1,10 @@ +import { Result } from '@/types/result.ts'; +import { Nullable } from '@/types/util.js'; +import { cacheGetOrSet } from '@/util/cache.js'; +import dayjs from '@/util/dayjs.js'; +import { fileExists } from '@/util/fsUtil.js'; +import { LoggerFactory } from '@/util/logging/LoggerFactory.ts'; +import { sanitizeForExec } from '@/util/strings.js'; import { seq } from '@tunarr/shared/util'; import { FfmpegSettings } from '@tunarr/types'; import { ExecOptions, exec } from 'child_process'; @@ -18,19 +25,12 @@ import { import NodeCache from 'node-cache'; import PQueue from 'p-queue'; import { format } from 'util'; -import { Result } from '../types/result.ts'; -import { Nullable } from '../types/util.js'; -import { cacheGetOrSet } from '../util/cache.js'; -import dayjs from '../util/dayjs.js'; -import { fileExists } from '../util/fsUtil.js'; import { attempt, isLinux, isNonEmptyString, parseIntOrNull, } from '../util/index.ts'; -import { LoggerFactory } from '../util/logging/LoggerFactory.ts'; -import { sanitizeForExec } from '../util/strings.js'; import { BaseFfmpegHardwareCapabilities } from './builder/capabilities/BaseFfmpegHardwareCapabilities.ts'; import { DefaultHardwareCapabilities } from './builder/capabilities/DefaultHardwareCapabilities.js'; import { FfmpegCapabilities } from './builder/capabilities/FfmpegCapabilities.ts'; diff --git a/server/src/ffmpeg/ffmpegText.ts b/server/src/ffmpeg/ffmpegText.ts index 72081d6e..833f088a 100644 --- a/server/src/ffmpeg/ffmpegText.ts +++ b/server/src/ffmpeg/ffmpegText.ts @@ -1,8 +1,8 @@ +import { globalOptions } from '@/globals.js'; +import { FfmpegSettings } from '@tunarr/types'; import { ChildProcessWithoutNullStreams, spawn } from 'child_process'; import events from 'events'; -import { globalOptions } from '../globals.js'; import { DeepReadonly } from 'ts-essentials'; -import { FfmpegSettings } from '@tunarr/types'; export class FfmpegText extends events.EventEmitter { private args: string[]; diff --git a/server/src/index.ts b/server/src/index.ts index 7b09527c..a85815d1 100644 --- a/server/src/index.ts +++ b/server/src/index.ts @@ -1,19 +1,19 @@ /* eslint-disable @typescript-eslint/no-floating-promises */ +import { bootstrapTunarr } from '@/bootstrap.ts'; +import { commands } from '@/cli/index.ts'; +import { setGlobalOptions } from '@/globals.ts'; +import { + getDefaultDatabaseDirectory, + getDefaultLogLevel, +} from '@/util/defaults.ts'; +import { LogLevels, ValidLogLevels } from '@/util/logging/LoggerFactory.ts'; +import { getTunarrVersion } from '@/util/version.ts'; import { dayjsMod } from '@tunarr/shared/util'; import dayjs from 'dayjs'; import duration from 'dayjs/plugin/duration.js'; import { fileURLToPath } from 'node:url'; import { hideBin } from 'yargs/helpers'; import yargs from 'yargs/yargs'; -import { bootstrapTunarr } from './bootstrap.ts'; -import { commands } from './cli/index.js'; -import { setGlobalOptions } from './globals.js'; -import { - getDefaultDatabaseDirectory, - getDefaultLogLevel, -} from './util/defaults.js'; -import { LogLevels, ValidLogLevels } from './util/logging/LoggerFactory.ts'; -import { getTunarrVersion } from './util/version.js'; // Extend this here once so we don't have to worry about // it elsewhere in the app. diff --git a/server/src/dao/migrations/DirectMigrationProvider.ts b/server/src/migration/DirectMigrationProvider.ts similarity index 100% rename from server/src/dao/migrations/DirectMigrationProvider.ts rename to server/src/migration/DirectMigrationProvider.ts diff --git a/server/src/dao/migrations/Migration.ts b/server/src/migration/Migration.ts similarity index 100% rename from server/src/dao/migrations/Migration.ts rename to server/src/migration/Migration.ts diff --git a/server/src/dao/migrations/db/LegacyMigration0.ts b/server/src/migration/db/LegacyMigration0.ts similarity index 100% rename from server/src/dao/migrations/db/LegacyMigration0.ts rename to server/src/migration/db/LegacyMigration0.ts diff --git a/server/src/dao/migrations/db/LegacyMigration1.ts b/server/src/migration/db/LegacyMigration1.ts similarity index 100% rename from server/src/dao/migrations/db/LegacyMigration1.ts rename to server/src/migration/db/LegacyMigration1.ts diff --git a/server/src/dao/migrations/db/LegacyMigration10.ts b/server/src/migration/db/LegacyMigration10.ts similarity index 100% rename from server/src/dao/migrations/db/LegacyMigration10.ts rename to server/src/migration/db/LegacyMigration10.ts diff --git a/server/src/dao/migrations/db/LegacyMigration11.ts b/server/src/migration/db/LegacyMigration11.ts similarity index 99% rename from server/src/dao/migrations/db/LegacyMigration11.ts rename to server/src/migration/db/LegacyMigration11.ts index b994b5e4..0ebfa29e 100644 --- a/server/src/dao/migrations/db/LegacyMigration11.ts +++ b/server/src/migration/db/LegacyMigration11.ts @@ -4,7 +4,7 @@ import { WithCreatedAt, WithUpdatedAt, WithUuid, -} from '../../direct/schema/base.ts'; +} from '../../db/schema/base.ts'; interface CurrentProgramExternalIdTable extends WithUuid, diff --git a/server/src/dao/migrations/db/LegacyMigration12.ts b/server/src/migration/db/LegacyMigration12.ts similarity index 99% rename from server/src/dao/migrations/db/LegacyMigration12.ts rename to server/src/migration/db/LegacyMigration12.ts index ed6af9a8..26505e1d 100644 --- a/server/src/dao/migrations/db/LegacyMigration12.ts +++ b/server/src/migration/db/LegacyMigration12.ts @@ -4,7 +4,7 @@ import { WithCreatedAt, WithUpdatedAt, WithUuid, -} from '../../direct/schema/base.ts'; +} from '../../db/schema/base.ts'; interface CurrentProgramExternalIdTable extends WithUuid, diff --git a/server/src/dao/migrations/db/LegacyMigration13.ts b/server/src/migration/db/LegacyMigration13.ts similarity index 100% rename from server/src/dao/migrations/db/LegacyMigration13.ts rename to server/src/migration/db/LegacyMigration13.ts diff --git a/server/src/dao/migrations/db/LegacyMigration14.ts b/server/src/migration/db/LegacyMigration14.ts similarity index 99% rename from server/src/dao/migrations/db/LegacyMigration14.ts rename to server/src/migration/db/LegacyMigration14.ts index 000bc969..b5edbdff 100644 --- a/server/src/dao/migrations/db/LegacyMigration14.ts +++ b/server/src/migration/db/LegacyMigration14.ts @@ -1,12 +1,12 @@ +import { MediaSourceType } from '@/db/schema/MediaSource.ts'; +import { ProgramGroupingType } from '@/db/schema/ProgramGrouping.ts'; import { CompiledQuery, Kysely, sql } from 'kysely'; -import { MediaSourceType } from '../../direct/schema/MediaSource.ts'; -import { ProgramGroupingType } from '../../direct/schema/ProgramGrouping.ts'; import { ProgramExternalIdSourceType, WithCreatedAt, WithUpdatedAt, WithUuid, -} from '../../direct/schema/base.ts'; +} from '../../db/schema/base.ts'; interface ProgramGroupingInMigration extends WithUuid, diff --git a/server/src/dao/migrations/db/LegacyMigration15.ts b/server/src/migration/db/LegacyMigration15.ts similarity index 100% rename from server/src/dao/migrations/db/LegacyMigration15.ts rename to server/src/migration/db/LegacyMigration15.ts diff --git a/server/src/dao/migrations/db/LegacyMigration16.ts b/server/src/migration/db/LegacyMigration16.ts similarity index 100% rename from server/src/dao/migrations/db/LegacyMigration16.ts rename to server/src/migration/db/LegacyMigration16.ts diff --git a/server/src/dao/migrations/db/LegacyMigration2.ts b/server/src/migration/db/LegacyMigration2.ts similarity index 100% rename from server/src/dao/migrations/db/LegacyMigration2.ts rename to server/src/migration/db/LegacyMigration2.ts diff --git a/server/src/dao/migrations/db/LegacyMigration3.ts b/server/src/migration/db/LegacyMigration3.ts similarity index 100% rename from server/src/dao/migrations/db/LegacyMigration3.ts rename to server/src/migration/db/LegacyMigration3.ts diff --git a/server/src/dao/migrations/db/LegacyMigration4.ts b/server/src/migration/db/LegacyMigration4.ts similarity index 100% rename from server/src/dao/migrations/db/LegacyMigration4.ts rename to server/src/migration/db/LegacyMigration4.ts diff --git a/server/src/dao/migrations/db/LegacyMigration5.ts b/server/src/migration/db/LegacyMigration5.ts similarity index 100% rename from server/src/dao/migrations/db/LegacyMigration5.ts rename to server/src/migration/db/LegacyMigration5.ts diff --git a/server/src/dao/migrations/db/LegacyMigration6.ts b/server/src/migration/db/LegacyMigration6.ts similarity index 87% rename from server/src/dao/migrations/db/LegacyMigration6.ts rename to server/src/migration/db/LegacyMigration6.ts index 46851414..4b4f8c56 100644 --- a/server/src/dao/migrations/db/LegacyMigration6.ts +++ b/server/src/migration/db/LegacyMigration6.ts @@ -1,5 +1,5 @@ +import { DB } from '@/db/schema/db.ts'; import { Kysely, Migration } from 'kysely'; -import { DB } from '../../direct/schema/db.ts'; export default { async up(db: Kysely): Promise { diff --git a/server/src/dao/migrations/db/LegacyMigration7.ts b/server/src/migration/db/LegacyMigration7.ts similarity index 100% rename from server/src/dao/migrations/db/LegacyMigration7.ts rename to server/src/migration/db/LegacyMigration7.ts diff --git a/server/src/dao/migrations/db/LegacyMigration8.ts b/server/src/migration/db/LegacyMigration8.ts similarity index 100% rename from server/src/dao/migrations/db/LegacyMigration8.ts rename to server/src/migration/db/LegacyMigration8.ts diff --git a/server/src/dao/migrations/db/LegacyMigration9.ts b/server/src/migration/db/LegacyMigration9.ts similarity index 100% rename from server/src/dao/migrations/db/LegacyMigration9.ts rename to server/src/migration/db/LegacyMigration9.ts diff --git a/server/src/dao/migrations/db/Migration1730806741.ts b/server/src/migration/db/Migration1730806741.ts similarity index 96% rename from server/src/dao/migrations/db/Migration1730806741.ts rename to server/src/migration/db/Migration1730806741.ts index 0d9390da..ff8ffa2f 100644 --- a/server/src/dao/migrations/db/Migration1730806741.ts +++ b/server/src/migration/db/Migration1730806741.ts @@ -1,5 +1,5 @@ +import { ChannelFillerShowTable } from '@/db/schema/Channel.ts'; import { CompiledQuery, Kysely, Migration } from 'kysely'; -import { ChannelFillerShowTable } from '../../direct/schema/Channel.ts'; type DBTemp = { channelFillerShowTmp: ChannelFillerShowTable; diff --git a/server/src/dao/migrations/db/Migration1731982492.ts b/server/src/migration/db/Migration1731982492.ts similarity index 97% rename from server/src/dao/migrations/db/Migration1731982492.ts rename to server/src/migration/db/Migration1731982492.ts index 2d459c07..1352acab 100644 --- a/server/src/dao/migrations/db/Migration1731982492.ts +++ b/server/src/migration/db/Migration1731982492.ts @@ -1,5 +1,5 @@ +import { CustomShowContent } from '@/db/schema/CustomShow.js'; import { CompiledQuery, Kysely, Migration } from 'kysely'; -import { CustomShowContent } from '../../direct/schema/CustomShow.js'; type DBTemp = { customShowContentTmp: CustomShowContent; diff --git a/server/src/dao/migrations/db/util.ts b/server/src/migration/db/util.ts similarity index 100% rename from server/src/dao/migrations/db/util.ts rename to server/src/migration/db/util.ts diff --git a/server/src/dao/legacy_migration/LegacyChannelMigrator.ts b/server/src/migration/legacy_migration/LegacyChannelMigrator.ts similarity index 93% rename from server/src/dao/legacy_migration/LegacyChannelMigrator.ts rename to server/src/migration/legacy_migration/LegacyChannelMigrator.ts index dbee947b..db838fd6 100644 --- a/server/src/dao/legacy_migration/LegacyChannelMigrator.ts +++ b/server/src/migration/legacy_migration/LegacyChannelMigrator.ts @@ -1,3 +1,14 @@ +import { ChannelDB } from '@/db/ChannelDB.ts'; +import { CustomShowDB } from '@/db/CustomShowDB.ts'; +import { getDatabase } from '@/db/DBAccess.ts'; +import { ProgramDB } from '@/db/ProgramDB.ts'; +import { ProgramUpsertFields } from '@/db/programQueryHelpers.ts'; +import { Channel, NewChannelFillerShow } from '@/db/schema/Channel.ts'; +import { ProgramDao } from '@/db/schema/Program.ts'; +import { ChannelNotFoundError } from '@/types/errors.ts'; +import { Maybe } from '@/types/util.ts'; +import { LoggerFactory } from '@/util/logging/LoggerFactory.ts'; +import { booleanToNumber } from '@/util/sqliteUtil.ts'; import { seq } from '@tunarr/shared/util'; import { Channel as ApiChannel, @@ -23,8 +34,20 @@ import { import fs from 'node:fs/promises'; import path from 'path'; import { v4 } from 'uuid'; -import { ChannelNotFoundError } from '../../types/errors.js'; -import { Maybe } from '../../types/util.js'; +import { + ContentItem, + CurrentLineupSchemaVersion, + Lineup, + LineupItem, + OfflineItem, + RedirectItem, +} from '../../db/derived_types/Lineup.ts'; +import { + ChannelIcon, + ChannelOfflineSettings, + ChannelTranscodingSettings, + ChannelWatermark, +} from '../../db/schema/base.ts'; import { emptyStringToUndefined, groupByUniq, @@ -33,30 +56,7 @@ import { mapAsyncSeq, mapToObj, run, -} from '../../util/index.js'; -import { LoggerFactory } from '../../util/logging/LoggerFactory.js'; -import { ChannelDB } from '../channelDb.js'; -import { CustomShowDB } from '../customShowDb.js'; -import { - ContentItem, - CurrentLineupSchemaVersion, - Lineup, - LineupItem, - OfflineItem, - RedirectItem, -} from '../derived_types/Lineup.js'; -import { directDbAccess } from '../direct/directDbAccess.js'; -import { ProgramUpsertFields } from '../direct/programQueryHelpers.js'; -import { Channel, NewChannelFillerShow } from '../direct/schema/Channel.js'; -import { Program } from '../direct/schema/Program.js'; -import { ChannelIcon } from '../direct/schema/base.js'; -import { - ChannelOfflineSettings, - ChannelTranscodingSettings, - ChannelWatermark, -} from '../direct/schema/base.ts'; -import { ProgramDB } from '../programDB.js'; -import { booleanToNumber } from '../sqliteUtil.js'; +} from '../../util/index.ts'; import { JSONArray, JSONObject, @@ -64,7 +64,7 @@ import { createProgramEntity, tryParseResolution, uniqueProgramId, -} from './migrationUtil.js'; +} from './migrationUtil.ts'; const validPositions = [ 'bottom-left', @@ -101,7 +101,7 @@ export class LegacyChannelMigrator { async createLineup( rawPrograms: LegacyProgram[], - dbProgramById: Record, + dbProgramById: Record, ): Promise { const channels = await this.channelDB.getAllChannels(); const channelIdsByNumber = groupByUniqPropAndMap( @@ -190,10 +190,10 @@ export class LegacyChannelMigrator { programEntities.length, ); - const upsertedPrograms: Program[] = []; + const upsertedPrograms: ProgramDao[] = []; for (const c of chunk(programEntities, 100)) { upsertedPrograms.push( - ...(await directDbAccess() + ...(await getDatabase() .transaction() .execute((tx) => tx @@ -238,7 +238,7 @@ export class LegacyChannelMigrator { } this.logger.debug('Saving channel %s', channelEntity.uuid); - await directDbAccess() + await getDatabase() .transaction() .execute(async (tx) => { await tx @@ -397,7 +397,7 @@ export class LegacyChannelMigrator { if (existingEntity) { channelEntity = existingEntity; - directDbAccess() + getDatabase() .updateTable('channel') .where('channel.uuid', '=', existingEntity.uuid) .limit(1) @@ -429,7 +429,7 @@ export class LegacyChannelMigrator { }); } else { const now = +dayjs(); - channelEntity = await directDbAccess() + channelEntity = await getDatabase() .insertInto('channel') .values({ uuid: v4(), @@ -472,11 +472,11 @@ export class LegacyChannelMigrator { // }); // Init programs, we may have already inserted some - await directDbAccess() + await getDatabase() .deleteFrom('channelPrograms') .where('channelUuid', '=', channelEntity.uuid) .execute(); - await directDbAccess() + await getDatabase() .deleteFrom('channelCustomShows') .where('channelUuid', '=', channelEntity.uuid) .execute(); @@ -519,7 +519,7 @@ export class LegacyChannelMigrator { } satisfies NewChannelFillerShow; }); - await directDbAccess() + await getDatabase() .insertInto('channelFillerShow') .values(relations) .onConflict((oc) => oc.doNothing()) diff --git a/server/src/dao/legacy_migration/legacyDbMigration.test.ts b/server/src/migration/legacy_migration/legacyDbMigration.test.ts similarity index 85% rename from server/src/dao/legacy_migration/legacyDbMigration.test.ts rename to server/src/migration/legacy_migration/legacyDbMigration.test.ts index 16e0ebf7..827bb057 100644 --- a/server/src/dao/legacy_migration/legacyDbMigration.test.ts +++ b/server/src/migration/legacy_migration/legacyDbMigration.test.ts @@ -1,15 +1,15 @@ -import { test, describe, beforeAll, afterAll } from 'vitest'; +import { Channel } from '@/entities/Channel.ts'; +import { CustomShow } from '@/entities/CustomShow.ts'; +import dbConfig from '@/mikro-orm.prod.config.js'; import { MikroORM, RequestContext } from '@mikro-orm/better-sqlite'; -import dbConfig from '../../../mikro-orm.prod.config.js'; -import { migrateChannel, migratePrograms } from './LegacyChannelMigrator.js'; +import fs from 'node:fs/promises'; import { dirname, join, resolve } from 'node:path'; import { fileURLToPath } from 'node:url'; -import { Channel } from '../entities/Channel.js'; -import tmp from 'tmp-promise'; -import fs from 'node:fs/promises'; import { inspect } from 'node:util'; -import { migrateCustomShows } from './libraryMigrator.js'; -import { CustomShow } from '../entities/CustomShow.js'; +import tmp from 'tmp-promise'; +import { afterAll, beforeAll, describe, test } from 'vitest'; +import { migrateChannel, migratePrograms } from './LegacyChannelMigrator.ts'; +import { migrateCustomShows } from './libraryMigrator.ts'; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); diff --git a/server/src/dao/legacy_migration/legacyDbMigration.ts b/server/src/migration/legacy_migration/legacyDbMigration.ts similarity index 95% rename from server/src/dao/legacy_migration/legacyDbMigration.ts rename to server/src/migration/legacy_migration/legacyDbMigration.ts index 926ce315..bb5926a6 100644 --- a/server/src/dao/legacy_migration/legacyDbMigration.ts +++ b/server/src/migration/legacy_migration/legacyDbMigration.ts @@ -1,3 +1,14 @@ +import { getDatabase } from '@/db/DBAccess.ts'; +import { NewCachedImage } from '@/db/schema/CachedImage.ts'; +import { MediaSourceApiFactory } from '@/external/MediaSourceApiFactory.ts'; +import { globalOptions } from '@/globals.ts'; +import { serverContext } from '@/serverContext.ts'; +import { GlobalScheduler } from '@/services/Scheduler.ts'; +import { AnonymousTask } from '@/tasks/Task.ts'; +import { Maybe } from '@/types/util.ts'; +import { attempt } from '@/util/index.ts'; +import { LoggerFactory } from '@/util/logging/LoggerFactory.ts'; +import { booleanToNumber } from '@/util/sqliteUtil.ts'; import { FfmpegSettings, PlexServerSettings, @@ -34,35 +45,28 @@ import { import path, { dirname, join } from 'path'; import { v4 } from 'uuid'; import { z } from 'zod'; -import { MediaSourceApiFactory } from '../../external/MediaSourceApiFactory.js'; -import { globalOptions } from '../../globals.js'; -import { serverContext } from '../../serverContext.js'; -import { GlobalScheduler } from '../../services/scheduler.js'; -import { AnonymousTask } from '../../tasks/Task.js'; -import { Maybe } from '../../types/util.js'; -import { attempt } from '../../util/index.js'; -import { LoggerFactory } from '../../util/logging/LoggerFactory.js'; -import { directDbAccess } from '../direct/directDbAccess.js'; -import { NewCachedImage } from '../direct/schema/CachedImage.js'; +import { + Settings, + SettingsDB, + defaultXmlTvSettings, +} from '../../db/SettingsDB.ts'; import { MediaSourceType, NewMediaSource, -} from '../direct/schema/MediaSource.js'; -import { Settings, SettingsDB, defaultXmlTvSettings } from '../settings.js'; -import { booleanToNumber } from '../sqliteUtil.js'; +} from '../../db/schema/MediaSource.ts'; import { LegacyChannelMigrator, LegacyProgram, -} from './LegacyChannelMigrator.js'; -import { LegacyLibraryMigrator } from './libraryMigrator.js'; -import { LegacyMetadataBackfiller } from './metadataBackfill.js'; +} from './LegacyChannelMigrator.ts'; +import { LegacyLibraryMigrator } from './libraryMigrator.ts'; +import { LegacyMetadataBackfiller } from './metadataBackfill.ts'; import { JSONArray, JSONObject, JSONValue, tryParseResolution, tryStringSplitOrDefault, -} from './migrationUtil.js'; +} from './migrationUtil.ts'; // Mapping from the old web UI const maxAudioChannelsOptions = [ @@ -357,7 +361,7 @@ export class LegacyDbMigrator { } } - await directDbAccess() + await getDatabase() .insertInto('mediaSource') .values(entities) .onConflict((oc) => oc.columns(['name', 'uri']).doNothing()) @@ -615,7 +619,7 @@ export class LegacyDbMigrator { newCacheImages.push({ url, hash, mimeType }); } - return directDbAccess() + return getDatabase() .insertInto('cachedImage') .values(newCacheImages) .onConflict((oc) => diff --git a/server/src/dao/legacy_migration/libraryMigrator.ts b/server/src/migration/legacy_migration/libraryMigrator.ts similarity index 90% rename from server/src/dao/legacy_migration/libraryMigrator.ts rename to server/src/migration/legacy_migration/libraryMigrator.ts index a1376714..7ce2f87b 100644 --- a/server/src/dao/legacy_migration/libraryMigrator.ts +++ b/server/src/migration/legacy_migration/libraryMigrator.ts @@ -1,3 +1,7 @@ +import { getDatabase } from '@/db/DBAccess.ts'; +import { NewCustomShowContent } from '@/db/schema/CustomShow.ts'; +import { NewFillerShowContent } from '@/db/schema/FillerShow.ts'; +import { LoggerFactory } from '@/util/logging/LoggerFactory.ts'; import { seq } from '@tunarr/shared/util'; import dayjs from 'dayjs'; import fs from 'fs/promises'; @@ -15,30 +19,26 @@ import { uniqBy, } from 'lodash-es'; import path from 'path'; +import { + ProgramUpsertFields, + withCustomShowPrograms, + withFillerPrograms, +} from '../../db/programQueryHelpers.ts'; import { groupByUniq, groupByUniqProp, isNonEmptyString, mapAsyncSeq, mapToObj, -} from '../../util/index.js'; -import { LoggerFactory } from '../../util/logging/LoggerFactory.js'; -import { directDbAccess } from '../direct/directDbAccess.js'; -import { - ProgramUpsertFields, - withCustomShowPrograms, - withFillerPrograms, -} from '../direct/programQueryHelpers.js'; -import { NewCustomShowContent } from '../direct/schema/CustomShow.js'; -import { NewFillerShowContent } from '../direct/schema/FillerShow.js'; -import { CustomShow } from './legacyDbMigration.js'; +} from '../../util/index.ts'; +import { CustomShow } from './legacyDbMigration.ts'; import { JSONArray, JSONObject, convertRawProgram, createProgramEntity, uniqueProgramId, -} from './migrationUtil.js'; +} from './migrationUtil.ts'; // Migrates flex and custom shows export class LegacyLibraryMigrator { @@ -114,7 +114,7 @@ export class LegacyLibraryMigrator { }[] = []; for (const c of chunk(programEntities, 100)) { upsertedPrograms.push( - ...(await directDbAccess() + ...(await getDatabase() .transaction() .execute((tx) => tx @@ -155,7 +155,7 @@ export class LegacyLibraryMigrator { await mapAsyncSeq(newCustomShows, async (customShow) => { if (type === 'custom-shows') { - const existing = await directDbAccess() + const existing = await getDatabase() .selectFrom('customShow') .selectAll() .where('customShow.uuid', '=', customShow.id) @@ -164,7 +164,7 @@ export class LegacyLibraryMigrator { const entity = existing ?? - (await directDbAccess() + (await getDatabase() .insertInto('customShow') .values({ uuid: customShow.id, @@ -175,7 +175,7 @@ export class LegacyLibraryMigrator { .returningAll() .executeTakeFirstOrThrow()); - await directDbAccess() + await getDatabase() .deleteFrom('customShowContent') .where('customShowContent.customShowUuid', '=', entity.uuid) .execute(); @@ -207,7 +207,7 @@ export class LegacyLibraryMigrator { }) satisfies NewCustomShowContent, ); - await directDbAccess() + await getDatabase() .transaction() .execute(async (tx) => { for (const contentChunk of chunk(csContent, 50)) { @@ -225,7 +225,7 @@ export class LegacyLibraryMigrator { } }); } else { - const existing = await directDbAccess() + const existing = await getDatabase() .selectFrom('fillerShow') .selectAll() .where('fillerShow.uuid', '=', customShow.id) @@ -234,7 +234,7 @@ export class LegacyLibraryMigrator { const entity = existing ?? - (await directDbAccess() + (await getDatabase() .insertInto('fillerShow') .values({ uuid: customShow.id, @@ -245,7 +245,7 @@ export class LegacyLibraryMigrator { .returningAll() .executeTakeFirstOrThrow()); - await directDbAccess() + await getDatabase() .deleteFrom('customShowContent') .where('customShowContent.customShowUuid', '=', entity.uuid) .execute(); @@ -267,7 +267,7 @@ export class LegacyLibraryMigrator { }) satisfies NewFillerShowContent, ); - await directDbAccess() + await getDatabase() .transaction() .execute(async (tx) => { for (const contentChunk of chunk(entities, 50)) { diff --git a/server/src/dao/legacy_migration/metadataBackfill.ts b/server/src/migration/legacy_migration/metadataBackfill.ts similarity index 93% rename from server/src/dao/legacy_migration/metadataBackfill.ts rename to server/src/migration/legacy_migration/metadataBackfill.ts index 0c1e0bab..6a05eff6 100644 --- a/server/src/dao/legacy_migration/metadataBackfill.ts +++ b/server/src/migration/legacy_migration/metadataBackfill.ts @@ -1,5 +1,17 @@ // This should be run after all regular entities have been migrated +import { ChannelDB } from '@/db/ChannelDB.ts'; +import { getDatabase } from '@/db/DBAccess.ts'; +import { ProgramDB } from '@/db/ProgramDB.ts'; +import { ProgramExternalIdType } from '@/db/custom_types/ProgramExternalIdType.ts'; +import { ProgramSourceType } from '@/db/custom_types/ProgramSourceType.ts'; +import { MediaSourceDB } from '@/db/mediaSourceDB.ts'; +import { ProgramDao, ProgramType } from '@/db/schema/Program.ts'; +import { NewProgramGroupingExternalId } from '@/db/schema/ProgramGroupingExternalId.ts'; +import { MediaSourceApiFactory } from '@/external/MediaSourceApiFactory.ts'; +import { PlexApiClient } from '@/external/plex/PlexApiClient.ts'; +import { isNonEmptyString, wait } from '@/util/index.ts'; +import { LoggerFactory } from '@/util/logging/LoggerFactory.ts'; import { PlexEpisodeView, PlexLibraryMusic, @@ -14,23 +26,10 @@ import { import dayjs from 'dayjs'; import { first, groupBy, isNil, isUndefined, keys } from 'lodash-es'; import { v4 } from 'uuid'; -import { MediaSourceApiFactory } from '../../external/MediaSourceApiFactory.ts'; -import { PlexApiClient } from '../../external/plex/PlexApiClient.ts'; -import { isNonEmptyString, wait } from '../../util/index.ts'; -import { LoggerFactory } from '../../util/logging/LoggerFactory.ts'; -import { ChannelDB } from '../channelDb.ts'; -import { ProgramExternalIdType } from '../custom_types/ProgramExternalIdType.ts'; -import { ProgramSourceType } from '../custom_types/ProgramSourceType.ts'; -import { directDbAccess } from '../direct/directDbAccess.js'; -import { Program } from '../direct/schema/Program.js'; -import { ProgramType } from '../direct/schema/Program.ts'; import { NewProgramGrouping, ProgramGroupingType, -} from '../direct/schema/ProgramGrouping.ts'; -import { NewProgramGroupingExternalId } from '../direct/schema/ProgramGroupingExternalId.ts'; -import { MediaSourceDB } from '../mediaSourceDB.ts'; -import { ProgramDB } from '../programDB.js'; +} from '../../db/schema/ProgramGrouping.ts'; export class LegacyMetadataBackfiller { private logger = LoggerFactory.child({ @@ -45,7 +44,7 @@ export class LegacyMetadataBackfiller { // It requires valid PlexServerSettings, program metadata, etc async backfillParentMetadata() { - const missingProgramAncestors = await directDbAccess() + const missingProgramAncestors = await getDatabase() .selectFrom('program') .selectAll() .where((eb) => { @@ -97,7 +96,7 @@ export class LegacyMetadataBackfiller { private async handleProgramsMissingAncestors( serverName: string, - programs: Program[], + programs: ProgramDao[], ) { const server = await this.mediaSourceDB.getByName(serverName); if (isNil(server)) { @@ -136,7 +135,7 @@ export class LegacyMetadataBackfiller { if (existingGrandparent) { this.logger.trace('Using existing grandparent grouping!'); updatedGrandparent = true; - await directDbAccess() + await getDatabase() .updateTable('program') .set({ tvShowUuid: @@ -166,7 +165,7 @@ export class LegacyMetadataBackfiller { if (existingParent) { this.logger.trace('Using existing parent!'); updatedParent = true; - await directDbAccess() + await getDatabase() .updateTable('program') .set({ seasonUuid: @@ -275,7 +274,7 @@ export class LegacyMetadataBackfiller { if (seasonAndRef) { const [season, externalId] = seasonAndRef; parentRatingKeyToUUID[episode.parentRatingKey] = season.uuid; - await directDbAccess() + await getDatabase() .transaction() .execute(async (tx) => { const groupingId = await tx @@ -288,7 +287,7 @@ export class LegacyMetadataBackfiller { .values(externalId) .executeTakeFirst(); if (groupingId) { - await directDbAccess() + await getDatabase() .updateTable('program') .where('uuid', '=', uuid) .set({ seasonUuid: groupingId?.uuid }) @@ -297,7 +296,7 @@ export class LegacyMetadataBackfiller { }); } } else { - await directDbAccess() + await getDatabase() .updateTable('program') .where('uuid', '=', uuid) .set({ @@ -342,7 +341,7 @@ export class LegacyMetadataBackfiller { const [show, externalId] = showAndRef; grandparentRatingKeyToUUID[episode.grandparentRatingKey] = show.uuid; - await directDbAccess() + await getDatabase() .transaction() .execute(async (tx) => { const groupingId = await tx @@ -355,7 +354,7 @@ export class LegacyMetadataBackfiller { .values(externalId) .executeTakeFirst(); if (groupingId) { - await directDbAccess() + await getDatabase() .updateTable('program') .where('uuid', '=', uuid) .set({ tvShowUuid: groupingId?.uuid }) @@ -364,7 +363,7 @@ export class LegacyMetadataBackfiller { }); } } else { - await directDbAccess() + await getDatabase() .updateTable('program') .where('uuid', '=', uuid) .set({ @@ -455,7 +454,7 @@ export class LegacyMetadataBackfiller { if (albumAndref) { const [album, externalId] = albumAndref; parentRatingKeyToUUID[track.parentRatingKey] = album.uuid; - await directDbAccess() + await getDatabase() .transaction() .execute(async (tx) => { const groupingId = await tx @@ -469,7 +468,7 @@ export class LegacyMetadataBackfiller { .executeTakeFirst(); if (groupingId) { - await directDbAccess() + await getDatabase() .updateTable('program') .where('uuid', '=', uuid) .set({ albumUuid: groupingId?.uuid }) @@ -478,7 +477,7 @@ export class LegacyMetadataBackfiller { }); } } else { - await directDbAccess() + await getDatabase() .updateTable('program') .where('uuid', '=', uuid) .set({ @@ -521,7 +520,7 @@ export class LegacyMetadataBackfiller { grandparentRatingKeyToUUID[track.grandparentRatingKey] = artist.uuid; - await directDbAccess() + await getDatabase() .transaction() .execute(async (tx) => { const groupingId = await tx @@ -534,7 +533,7 @@ export class LegacyMetadataBackfiller { .values(externalId) .executeTakeFirst(); if (groupingId) { - await directDbAccess() + await getDatabase() .updateTable('program') .where('uuid', '=', uuid) .set({ artistUuid: groupingId?.uuid }) @@ -543,7 +542,7 @@ export class LegacyMetadataBackfiller { }); } } else { - await directDbAccess() + await getDatabase() .updateTable('program') .where('uuid', '=', uuid) .set({ @@ -637,7 +636,7 @@ export class LegacyMetadataBackfiller { externalKey: string, type: ProgramGroupingType, ) { - return directDbAccess() + return getDatabase() .selectFrom('programGroupingExternalId') .selectAll() .where((eb) => diff --git a/server/src/dao/legacy_migration/migrationUtil.ts b/server/src/migration/legacy_migration/migrationUtil.ts similarity index 91% rename from server/src/dao/legacy_migration/migrationUtil.ts rename to server/src/migration/legacy_migration/migrationUtil.ts index 02240ab2..f724cc37 100644 --- a/server/src/dao/legacy_migration/migrationUtil.ts +++ b/server/src/migration/legacy_migration/migrationUtil.ts @@ -1,15 +1,15 @@ +import { ProgramSourceType } from '@/db/custom_types/ProgramSourceType.ts'; +import { Maybe } from '@/types/util.ts'; +import { isNonEmptyString } from '@/util/index.ts'; import { ProgramType, Resolution } from '@tunarr/types'; import dayjs from 'dayjs'; import { every, isNaN, isUndefined, parseInt } from 'lodash-es'; import { v4 } from 'uuid'; -import { Maybe } from '../../types/util.js'; -import { isNonEmptyString } from '../../util/index.js'; -import { ProgramSourceType } from '../custom_types/ProgramSourceType.js'; import { ProgramType as DBProgramType, - NewProgram, -} from '../direct/schema/Program.ts'; -import { LegacyProgram } from './LegacyChannelMigrator.js'; + NewProgramDao, +} from '../../db/schema/Program.ts'; +import { LegacyProgram } from './LegacyChannelMigrator.ts'; // JSON representation for easier parsing of legacy db files export interface JSONArray extends Array {} @@ -103,7 +103,7 @@ export function convertRawProgram(program: JSONObject): LegacyProgram { export function createProgramEntity( program: LegacyProgram, -): NewProgram | undefined { +): NewProgramDao | undefined { const now = +dayjs(); if ( ['movie', 'episode', 'track'].includes(program.type ?? '') && @@ -133,7 +133,7 @@ export function createProgramEntity( originalAirDate: program.date, rating: program.rating, year: program.year, - } satisfies NewProgram; + } satisfies NewProgramDao; } return; diff --git a/server/src/dao/migrations/lineups/ChannelLineupMigration.ts b/server/src/migration/lineups/ChannelLineupMigration.ts similarity index 61% rename from server/src/dao/migrations/lineups/ChannelLineupMigration.ts rename to server/src/migration/lineups/ChannelLineupMigration.ts index f289d0eb..05de19ca 100644 --- a/server/src/dao/migrations/lineups/ChannelLineupMigration.ts +++ b/server/src/migration/lineups/ChannelLineupMigration.ts @@ -1,7 +1,7 @@ -import { ChannelDB } from '../../channelDb.ts'; -import { Lineup } from '../../derived_types/Lineup.ts'; -import { ProgramDB } from '../../programDB.ts'; -import { Migration } from '../Migration.ts'; +import { ChannelDB } from '@/db/ChannelDB.ts'; +import { Lineup } from '@/db/derived_types/Lineup.ts'; +import { ProgramDB } from '@/db/ProgramDB.ts'; +import { Migration } from '@/migration/Migration.ts'; export abstract class ChannelLineupMigration< From extends number, diff --git a/server/src/dao/ChannelLineupMigrator.ts b/server/src/migration/lineups/ChannelLineupMigrator.ts similarity index 85% rename from server/src/dao/ChannelLineupMigrator.ts rename to server/src/migration/lineups/ChannelLineupMigrator.ts index b9f6a637..64c4c2b5 100644 --- a/server/src/dao/ChannelLineupMigrator.ts +++ b/server/src/migration/lineups/ChannelLineupMigrator.ts @@ -1,10 +1,13 @@ +import { ChannelDB } from '@/db/ChannelDB.ts'; +import { ProgramDB } from '@/db/ProgramDB.ts'; +import { LoggerFactory } from '@/util/logging/LoggerFactory.ts'; import { findIndex, map } from 'lodash-es'; -import { LoggerFactory } from '../util/logging/LoggerFactory.ts'; -import { ChannelDB } from './channelDb.ts'; -import { CurrentLineupSchemaVersion, Lineup } from './derived_types/Lineup.ts'; -import { ChannelLineupMigration } from './migrations/lineups/ChannelLineupMigration.ts'; -import { SlotShowIdMigration } from './migrations/lineups/SlotShowIdMigration.ts'; -import { ProgramDB } from './programDB.ts'; +import { + CurrentLineupSchemaVersion, + Lineup, +} from '../../db/derived_types/Lineup.ts'; +import { ChannelLineupMigration } from './ChannelLineupMigration.ts'; +import { SlotShowIdMigration } from './SlotShowIdMigration.ts'; type MigrationFactory = ( channelDB: ChannelDB, diff --git a/server/src/dao/migrations/lineups/SlotShowIdMigration.ts b/server/src/migration/lineups/SlotShowIdMigration.ts similarity index 90% rename from server/src/dao/migrations/lineups/SlotShowIdMigration.ts rename to server/src/migration/lineups/SlotShowIdMigration.ts index 8beaef56..7daf37ac 100644 --- a/server/src/dao/migrations/lineups/SlotShowIdMigration.ts +++ b/server/src/migration/lineups/SlotShowIdMigration.ts @@ -1,9 +1,9 @@ +import { Lineup } from '@/db/derived_types/Lineup.ts'; +import { LoggerFactory } from '@/util/logging/LoggerFactory.ts'; import { ShowProgrammingRandomSlot, ShowProgrammingTimeSlot, } from '@tunarr/types/api'; -import { LoggerFactory } from '../../../util/logging/LoggerFactory.ts'; -import { Lineup } from '../../derived_types/Lineup.ts'; import { ChannelLineupMigration } from './ChannelLineupMigration.ts'; export class SlotShowIdMigration extends ChannelLineupMigration<0, 1> { diff --git a/server/src/server.ts b/server/src/server.ts index b444308c..adf2b639 100644 --- a/server/src/server.ts +++ b/server/src/server.ts @@ -27,26 +27,26 @@ import { HdhrApiRouter } from './api/hdhrApi.js'; import { apiRouter } from './api/index.js'; import { streamApi } from './api/streamApi.js'; import { videoApiRouter } from './api/videoApi.js'; -import { ChannelLineupMigrator } from './dao/ChannelLineupMigrator.js'; -import { LegacyDbMigrator } from './dao/legacy_migration/legacyDbMigration.js'; -import { getSettings } from './dao/settings.js'; +import { getSettings } from './db/SettingsDB.ts'; import { FFMPEGInfo } from './ffmpeg/ffmpegInfo.js'; import { ServerOptions, initializeSingletons, serverOptions, } from './globals.js'; +import { LegacyDbMigrator } from './migration/legacy_migration/legacyDbMigration.ts'; +import { ChannelLineupMigrator } from './migration/lineups/ChannelLineupMigrator.ts'; import { ServerContext, ServerRequestContext, serverContext, } from './serverContext.js'; +import { GlobalScheduler, scheduleJobs } from './services/Scheduler.ts'; import { FfmpegDebugLoggingHealthCheck } from './services/health_checks/FfmpegDebugLoggingHealthCheck.js'; import { FfmpegVersionHealthCheck } from './services/health_checks/FfmpegVersionHealthCheck.js'; import { HardwareAccelerationHealthCheck } from './services/health_checks/HardwareAccelerationHealthCheck.js'; import { MissingProgramAssociationsHealthCheck } from './services/health_checks/MissingProgramAssociationsHealthCheck.js'; import { MissingSeasonNumbersHealthCheck } from './services/health_checks/MissingSeasonNumbersHealthCheck.js'; -import { GlobalScheduler, scheduleJobs } from './services/scheduler.js'; import { initPersistentStreamCache } from './stream/ChannelCache.js'; import { UpdateXmlTvTask } from './tasks/UpdateXmlTvTask.js'; import { runFixers } from './tasks/fixers/index.js'; diff --git a/server/src/serverContext.ts b/server/src/serverContext.ts index 8830002d..d18f8bbf 100644 --- a/server/src/serverContext.ts +++ b/server/src/serverContext.ts @@ -1,23 +1,23 @@ import { AsyncLocalStorage } from 'async_hooks'; import { isUndefined, once } from 'lodash-es'; import path from 'path'; -import { XmlTvWriter } from './XmlTvWriter.js'; -import { ChannelDB } from './dao/channelDb.js'; -import { ProgramConverter } from './dao/converters/programConverters.js'; -import { CustomShowDB } from './dao/customShowDb.js'; -import { FillerDB } from './dao/fillerDB.js'; -import { MediaSourceDB } from './dao/mediaSourceDB.js'; -import { ProgramDB } from './dao/programDB.js'; -import { SettingsDB, getSettings } from './dao/settings.js'; +import { ChannelDB } from './db/ChannelDB.ts'; +import { CustomShowDB } from './db/CustomShowDB.ts'; +import { FillerDB } from './db/FillerListDB.ts'; +import { ProgramDB } from './db/ProgramDB.ts'; +import { SettingsDB, getSettings } from './db/SettingsDB.ts'; +import { ProgramConverter } from './db/converters/ProgramConverter.ts'; +import { MediaSourceDB } from './db/mediaSourceDB.ts'; import { serverOptions } from './globals.js'; -import { HdhrService } from './hdhr.js'; +import { EventService } from './services/EventService.ts'; +import { FileCacheService } from './services/FileCacheService.ts'; +import { HdhrService } from './services/HDHRService.ts'; import { HealthCheckService } from './services/HealthCheckService.js'; +import { M3uService } from './services/M3UService.ts'; import { OnDemandChannelService } from './services/OnDemandChannelService.js'; +import { TVGuideService } from './services/TvGuideService.ts'; +import { XmlTvWriter } from './services/XmlTvWriter.ts'; import { CacheImageService } from './services/cacheImageService.js'; -import { EventService } from './services/eventService.js'; -import { FileCacheService } from './services/fileCacheService.js'; -import { M3uService } from './services/m3uService.js'; -import { TVGuideService } from './services/tvGuideService.js'; import { ChannelCache } from './stream/ChannelCache.js'; import { SessionManager } from './stream/SessionManager.js'; import { StreamProgramCalculator } from './stream/StreamProgramCalculator.js'; diff --git a/server/src/services/eventService.ts b/server/src/services/EventService.ts similarity index 95% rename from server/src/services/eventService.ts rename to server/src/services/EventService.ts index 66e7bfe6..78df9ca8 100644 --- a/server/src/services/eventService.ts +++ b/server/src/services/EventService.ts @@ -1,11 +1,11 @@ +import { TypedEventEmitter } from '@/types/eventEmitter.js'; +import { LoggerFactory } from '@/util/logging/LoggerFactory.js'; import { TunarrEvent } from '@tunarr/types'; import EventEmitter from 'events'; import { FastifyInstance } from 'fastify'; import { isString } from 'lodash-es'; import { Readable } from 'stream'; import { v4 } from 'uuid'; -import { TypedEventEmitter } from '../types/eventEmitter.js'; -import { LoggerFactory } from '../util/logging/LoggerFactory.js'; type Events = { close: () => void; diff --git a/server/src/services/fileCacheService.ts b/server/src/services/FileCacheService.ts similarity index 91% rename from server/src/services/fileCacheService.ts rename to server/src/services/FileCacheService.ts index 1def7652..067c411d 100644 --- a/server/src/services/fileCacheService.ts +++ b/server/src/services/FileCacheService.ts @@ -1,9 +1,9 @@ +import { serverOptions } from '@/globals.ts'; +import { fileExists } from '@/util/fsUtil.js'; +import { LoggerFactory } from '@/util/logging/LoggerFactory.js'; import { promises as fs } from 'fs'; import NodeCache from 'node-cache'; import path from 'path'; -import { serverOptions } from '../globals.ts'; -import { fileExists } from '../util/fsUtil.js'; -import { LoggerFactory } from '../util/logging/LoggerFactory.js'; /** * Store files in cache diff --git a/server/src/services/FillerPicker.ts b/server/src/services/FillerPicker.ts index 3ab1d8ce..266c037f 100644 --- a/server/src/services/FillerPicker.ts +++ b/server/src/services/FillerPicker.ts @@ -1,13 +1,13 @@ +import { Channel } from '@/db/schema/Channel.ts'; +import { ChannelCache } from '@/stream/ChannelCache.ts'; +import { Maybe, Nullable } from '@/types/util.ts'; +import { random } from '@/util/random.ts'; import constants from '@tunarr/shared/constants'; import { isEmpty, isNil, isUndefined } from 'lodash-es'; import { ChannelFillerShowWithContent, - ProgramWithRelations, -} from '../dao/direct/derivedTypes.ts'; -import { Channel } from '../dao/direct/schema/Channel.ts'; -import { ChannelCache } from '../stream/ChannelCache.ts'; -import { Maybe, Nullable } from '../types/util.ts'; -import { random } from '../util/random.ts'; + ProgramDaoWithRelations, +} from '../db/schema/derivedTypes.js'; const DefaultFillerCooldownMillis = 30 * 60 * 1000; const OneDayMillis = 7 * 24 * 60 * 60 * 1000; @@ -26,7 +26,7 @@ export class FillerPicker { maxDuration: number, ): { fillerId: Nullable; - filler: Nullable; + filler: Nullable; minimumWait: number; } { if (isEmpty(fillers)) { @@ -37,7 +37,7 @@ export class FillerPicker { }; } - let pick1: Maybe; + let pick1: Maybe; const t0 = new Date().getTime(); let minimumWait = 1000000000; diff --git a/server/src/hdhr.ts b/server/src/services/HDHRService.ts similarity index 95% rename from server/src/hdhr.ts rename to server/src/services/HDHRService.ts index aae21ffa..7ffdf442 100644 --- a/server/src/hdhr.ts +++ b/server/src/services/HDHRService.ts @@ -1,6 +1,6 @@ +import { SettingsDB } from '@/db/SettingsDB.ts'; +import { serverOptions } from '@/globals.js'; import { Server as SSDP } from 'node-ssdp'; -import { SettingsDB } from './dao/settings.js'; -import { serverOptions } from './globals.js'; export class HdhrService { private db: SettingsDB; diff --git a/server/src/services/HealthCheckService.ts b/server/src/services/HealthCheckService.ts index c7d85ffa..76114fa4 100644 --- a/server/src/services/HealthCheckService.ts +++ b/server/src/services/HealthCheckService.ts @@ -1,6 +1,6 @@ +import { mapToObj } from '@/util/index.ts'; +import { LoggerFactory } from '@/util/logging/LoggerFactory.ts'; import { difference, keys, map, reduce, values } from 'lodash-es'; -import { mapToObj } from '../util/index.ts'; -import { LoggerFactory } from '../util/logging/LoggerFactory.ts'; import { HealthCheck, HealthCheckResult, diff --git a/server/src/services/m3uService.ts b/server/src/services/M3UService.ts similarity index 89% rename from server/src/services/m3uService.ts rename to server/src/services/M3UService.ts index c1e837f7..ffbc76e8 100644 --- a/server/src/services/m3uService.ts +++ b/server/src/services/M3UService.ts @@ -1,11 +1,11 @@ +import { ChannelDB } from '@/db/ChannelDB.ts'; +import { getChannelId } from '@/util/channels.js'; +import { devAssert } from '@/util/debug.js'; +import { attempt, isDefined, isNonEmptyString } from '@/util/index.js'; +import { LoggerFactory } from '@/util/logging/LoggerFactory.js'; import { Mutex } from 'async-mutex'; import { isError, sortBy } from 'lodash-es'; -import { ChannelDB } from '../dao/channelDb.js'; -import { getChannelId } from '../util/channels.js'; -import { devAssert } from '../util/debug.js'; -import { attempt, isDefined, isNonEmptyString } from '../util/index.js'; -import { LoggerFactory } from '../util/logging/LoggerFactory.js'; -import { FileCacheService } from './fileCacheService.js'; +import { FileCacheService } from './FileCacheService.ts'; /** * Manager and Generate M3U content diff --git a/server/src/services/OnDemandChannelService.ts b/server/src/services/OnDemandChannelService.ts index dba0c7e9..def22136 100644 --- a/server/src/services/OnDemandChannelService.ts +++ b/server/src/services/OnDemandChannelService.ts @@ -1,8 +1,8 @@ +import { ChannelDB } from '@/db/ChannelDB.ts'; +import { LoggerFactory } from '@/util/logging/LoggerFactory.js'; +import { MutexMap } from '@/util/mutexMap.js'; import dayjs from 'dayjs'; import { isNull, isUndefined } from 'lodash-es'; -import { ChannelDB } from '../dao/channelDb.js'; -import { LoggerFactory } from '../util/logging/LoggerFactory.js'; -import { MutexMap } from '../util/mutexMap.js'; export class OnDemandChannelService { #logger = LoggerFactory.child({ className: this.constructor.name }); diff --git a/server/src/services/PlexItemEnumerator.ts b/server/src/services/PlexItemEnumerator.ts index 4bd1a7a8..f78cfa54 100644 --- a/server/src/services/PlexItemEnumerator.ts +++ b/server/src/services/PlexItemEnumerator.ts @@ -1,3 +1,10 @@ +import { ProgramDB } from '@/db/ProgramDB.ts'; +import { PlexApiClient } from '@/external/plex/PlexApiClient.ts'; +import { typedProperty } from '@/types/path.ts'; +import { asyncPool, unfurlPool } from '@/util/asyncPool.ts'; +import { flatMapAsyncSeq, wait } from '@/util/index.js'; +import { Logger, LoggerFactory } from '@/util/logging/LoggerFactory.ts'; +import { Timer } from '@/util/perf.ts'; import { createExternalId } from '@tunarr/shared'; import { PlexChildMediaViewType, @@ -8,13 +15,6 @@ import { isTerminalItem, } from '@tunarr/types/plex'; import { flatten, isNil, map, uniqBy } from 'lodash-es'; -import { ProgramDB } from '../dao/programDB.ts'; -import { PlexApiClient } from '../external/plex/PlexApiClient.ts'; -import { typedProperty } from '../types/path.ts'; -import { asyncPool, unfurlPool } from '../util/asyncPool.ts'; -import { flatMapAsyncSeq, wait } from '../util/index.js'; -import { Logger, LoggerFactory } from '../util/logging/LoggerFactory.ts'; -import { Timer } from '../util/perf.ts'; export type EnrichedPlexTerminalMedia = PlexTerminalMedia & { id?: string; diff --git a/server/src/services/scheduler.ts b/server/src/services/Scheduler.ts similarity index 86% rename from server/src/services/scheduler.ts rename to server/src/services/Scheduler.ts index f661cdaf..44e3f418 100644 --- a/server/src/services/scheduler.ts +++ b/server/src/services/Scheduler.ts @@ -1,3 +1,17 @@ +import { ServerContext } from '@/serverContext.js'; +import { BackupTask } from '@/tasks/BackupTask.js'; +import { CleanupSessionsTask } from '@/tasks/CleanupSessionsTask.js'; +import { OnDemandChannelStateTask } from '@/tasks/OnDemandChannelStateTask.js'; +import { OneOffTask } from '@/tasks/OneOffTask.js'; +import { ReconcileProgramDurationsTask } from '@/tasks/ReconcileProgramDurationsTask.js'; +import { ScheduleDynamicChannelsTask } from '@/tasks/ScheduleDynamicChannelsTask.js'; +import { ScheduledTask } from '@/tasks/ScheduledTask.js'; +import { Task, TaskId } from '@/tasks/Task.js'; +import { UpdateXmlTvTask } from '@/tasks/UpdateXmlTvTask.js'; +import { typedProperty } from '@/types/path.js'; +import { Maybe } from '@/types/util.js'; +import { LoggerFactory } from '@/util/logging/LoggerFactory.js'; +import { parseEveryScheduleRule } from '@/util/schedulingUtil.js'; import type { Tag } from '@tunarr/types'; import { BackupSettings } from '@tunarr/types/schemas'; import dayjs, { type Dayjs } from 'dayjs'; @@ -12,20 +26,6 @@ import { } from 'lodash-es'; import { DeepReadonly } from 'ts-essentials'; import { v4 } from 'uuid'; -import { ServerContext } from '../serverContext.js'; -import { BackupTask } from '../tasks/BackupTask.js'; -import { CleanupSessionsTask } from '../tasks/CleanupSessionsTask.js'; -import { OnDemandChannelStateTask } from '../tasks/OnDemandChannelStateTask.js'; -import { OneOffTask } from '../tasks/OneOffTask.js'; -import { ReconcileProgramDurationsTask } from '../tasks/ReconcileProgramDurationsTask.js'; -import { ScheduleDynamicChannelsTask } from '../tasks/ScheduleDynamicChannelsTask.js'; -import { ScheduledTask } from '../tasks/ScheduledTask.js'; -import { Task, TaskId } from '../tasks/Task.js'; -import { UpdateXmlTvTask } from '../tasks/UpdateXmlTvTask.js'; -import { typedProperty } from '../types/path.js'; -import { Maybe } from '../types/util.js'; -import { LoggerFactory } from '../util/logging/LoggerFactory.js'; -import { parseEveryScheduleRule } from '../util/schedulingUtil.js'; const { isDayjs } = dayjs; diff --git a/server/src/services/tvGuideService.ts b/server/src/services/TvGuideService.ts similarity index 96% rename from server/src/services/tvGuideService.ts rename to server/src/services/TvGuideService.ts index a81ed4c0..474845d5 100644 --- a/server/src/services/tvGuideService.ts +++ b/server/src/services/TvGuideService.ts @@ -1,3 +1,13 @@ +import { ChannelDB } from '@/db/ChannelDB.ts'; +import { ProgramDB } from '@/db/ProgramDB.ts'; +import { ProgramConverter } from '@/db/converters/ProgramConverter.ts'; +import { Lineup, LineupItem } from '@/db/derived_types/Lineup.ts'; +import { OpenDateTimeRange } from '@/types/OpenDateTimeRange.ts'; +import { Maybe } from '@/types/util.ts'; +import { binarySearchRange } from '@/util/binarySearch.ts'; +import { LoggerFactory } from '@/util/logging/LoggerFactory.ts'; +import { Timer } from '@/util/perf.ts'; +import { makeLocalUrl } from '@/util/serverUtil.ts'; import constants from '@tunarr/shared/constants'; import { seq } from '@tunarr/shared/util'; import { @@ -32,29 +42,19 @@ import { import * as syncRetry from 'retry'; import { match } from 'ts-pattern'; import { v4 } from 'uuid'; -import { XmlTvWriter } from '../XmlTvWriter.js'; -import { ChannelDB } from '../dao/channelDb.js'; -import { ProgramConverter } from '../dao/converters/programConverters.js'; -import { Lineup, LineupItem } from '../dao/derived_types/Lineup.js'; import { ChannelWithPrograms, ChannelWithRelations, ChannelWithPrograms as RawChannel, -} from '../dao/direct/derivedTypes.js'; -import { ProgramDB } from '../dao/programDB.js'; -import { OpenDateTimeRange } from '../types/OpenDateTimeRange.js'; -import { Maybe } from '../types/util.js'; -import { binarySearchRange } from '../util/binarySearch.js'; +} from '../db/schema/derivedTypes.js'; import { deepCopy, groupByUniqProp, isNonEmptyString, wait, -} from '../util/index.js'; -import { LoggerFactory } from '../util/logging/LoggerFactory.js'; -import { Timer } from '../util/perf.js'; -import { makeLocalUrl } from '../util/serverUtil.js'; -import { EventService } from './eventService.js'; +} from '../util/index.ts'; +import { EventService } from './EventService.ts'; +import { XmlTvWriter } from './XmlTvWriter.ts'; dayjs.extend(duration); @@ -920,7 +920,7 @@ export class TVGuideService { return this.guideItemToProgram( channel, program, - this.programConverter.directLineupItemToChannelProgram( + this.programConverter.lineupItemToChannelProgram( channel, program.lineupItem, allChannels, @@ -947,7 +947,7 @@ export class TVGuideService { } as const; if (isNull(materializedItem)) { - materializedItem = this.programConverter.directOfflineLineupItemToProgram( + materializedItem = this.programConverter.offlineLineupItemToProgram( channel, { type: 'offline', durationMs: guideItem.lineupItem.durationMs }, ); @@ -998,7 +998,7 @@ export class TVGuideService { return this.guideItemToProgram( channel, currentProgram, - this.programConverter.directLineupItemToChannelProgram( + this.programConverter.lineupItemToChannelProgram( channel, currentProgram.lineupItem, allChannels, diff --git a/server/src/XmlTvWriter.ts b/server/src/services/XmlTvWriter.ts similarity index 95% rename from server/src/XmlTvWriter.ts rename to server/src/services/XmlTvWriter.ts index 8f1cebaf..0c5db921 100644 --- a/server/src/XmlTvWriter.ts +++ b/server/src/services/XmlTvWriter.ts @@ -1,3 +1,8 @@ +import { SettingsDB, getSettings } from '@/db/SettingsDB.ts'; +import { Channel } from '@/db/schema/Channel.ts'; +import { getChannelId } from '@/util/channels.js'; +import { isNonEmptyString } from '@/util/index.ts'; +import { LoggerFactory } from '@/util/logging/LoggerFactory.ts'; import { writeXmltv, type XmltvChannel, @@ -8,11 +13,6 @@ import { Mutex } from 'async-mutex'; import { writeFile } from 'fs/promises'; import { escape, flatMap, isNil, map, round } from 'lodash-es'; import { match } from 'ts-pattern'; -import { Channel } from './dao/direct/schema/Channel.ts'; -import { SettingsDB, getSettings } from './dao/settings.ts'; -import { getChannelId } from './util/channels.js'; -import { isNonEmptyString } from './util/index.ts'; -import { LoggerFactory } from './util/logging/LoggerFactory.ts'; const lock = new Mutex(); diff --git a/server/src/services/cacheImageService.ts b/server/src/services/cacheImageService.ts index 6cd65f80..4664e040 100644 --- a/server/src/services/cacheImageService.ts +++ b/server/src/services/cacheImageService.ts @@ -1,13 +1,13 @@ +import { getDatabase } from '@/db/DBAccess.ts'; +import { CachedImage } from '@/db/schema/CachedImage.ts'; +import { LoggerFactory } from '@/util/logging/LoggerFactory.js'; import axios, { AxiosHeaders, AxiosRequestConfig } from 'axios'; import crypto from 'crypto'; import { FastifyReply, FastifyRequest } from 'fastify'; import { createWriteStream, promises as fs } from 'fs'; import { isString, isUndefined } from 'lodash-es'; import stream from 'stream'; -import { directDbAccess } from '../dao/direct/directDbAccess.js'; -import { CachedImage } from '../dao/direct/schema/CachedImage.js'; -import { LoggerFactory } from '../util/logging/LoggerFactory.js'; -import { FileCacheService } from './fileCacheService.js'; +import { FileCacheService } from './FileCacheService.ts'; /** * Manager a cache in disk for external images. @@ -41,7 +41,7 @@ export class CacheImageService { res: FastifyReply, ) { try { - const imgItem = await directDbAccess() + const imgItem = await getDatabase() .selectFrom('cachedImage') .where('hash', '=', req.params.hash) .selectAll() @@ -65,7 +65,7 @@ export class CacheImageService { } async getOrDownloadImage(hash: string) { - const imgItem = await directDbAccess() + const imgItem = await getDatabase() .selectFrom('cachedImage') .where('hash', '=', hash) .selectAll() @@ -103,7 +103,7 @@ export class CacheImageService { const mimeType = (response.headers as AxiosHeaders).get('content-type'); if (!isUndefined(mimeType) && isString(mimeType)) { this.logger.debug('Got image file with mimeType ' + mimeType); - await directDbAccess() + await getDatabase() .insertInto('cachedImage') .values({ ...cachedImage, @@ -154,7 +154,7 @@ export class CacheImageService { .createHash('md5') .update(imageUrl) .digest('base64'); - await directDbAccess() + await getDatabase() .insertInto('cachedImage') .values({ hash: encodedUrl, diff --git a/server/src/services/dynamic_channels/CollapseOfflineTimeOperator.test.ts b/server/src/services/dynamic_channels/CollapseOfflineTimeOperator.test.ts index 6a8ecd9b..1ef1114e 100644 --- a/server/src/services/dynamic_channels/CollapseOfflineTimeOperator.test.ts +++ b/server/src/services/dynamic_channels/CollapseOfflineTimeOperator.test.ts @@ -1,5 +1,5 @@ +import { LineupItem } from '@/db/derived_types/Lineup.ts'; import { map, random, range, sumBy } from 'lodash-es'; -import { LineupItem } from '../../dao/derived_types/Lineup.js'; import { collapseOfflineTime } from './CollapseOfflineTimeOperator.js'; describe('CollapseOfflineTimeOperator', () => { diff --git a/server/src/services/dynamic_channels/CollapseOfflineTimeOperator.ts b/server/src/services/dynamic_channels/CollapseOfflineTimeOperator.ts index 9330443a..abe23a0c 100644 --- a/server/src/services/dynamic_channels/CollapseOfflineTimeOperator.ts +++ b/server/src/services/dynamic_channels/CollapseOfflineTimeOperator.ts @@ -1,6 +1,6 @@ -import { ChannelAndLineup } from '../../types/internal.js'; -import { Lineup, LineupItem } from '../../dao/derived_types/Lineup.js'; -import { Func } from '../../types/func.js'; +import { Lineup, LineupItem } from '@/db/derived_types/Lineup.ts'; +import { Func } from '@/types/func.js'; +import { ChannelAndLineup } from '@/types/internal.js'; export function collapseOfflineTime(lineup: Lineup): Promise { const newLineup: LineupItem[] = []; diff --git a/server/src/services/dynamic_channels/ContentSourceUpdater.ts b/server/src/services/dynamic_channels/ContentSourceUpdater.ts index 1fb3c778..0bb4053b 100644 --- a/server/src/services/dynamic_channels/ContentSourceUpdater.ts +++ b/server/src/services/dynamic_channels/ContentSourceUpdater.ts @@ -1,6 +1,6 @@ +import { Channel } from '@/db/schema/Channel.ts'; import { DynamicContentConfigSource } from '@tunarr/types/api'; import { Mutex, withTimeout } from 'async-mutex'; -import { Channel } from '../../dao/direct/schema/Channel.ts'; const locks: Record = { plex: new Mutex(), diff --git a/server/src/services/dynamic_channels/ContentSourceUpdaterFactory.ts b/server/src/services/dynamic_channels/ContentSourceUpdaterFactory.ts index 54caf4e1..da2ede06 100644 --- a/server/src/services/dynamic_channels/ContentSourceUpdaterFactory.ts +++ b/server/src/services/dynamic_channels/ContentSourceUpdaterFactory.ts @@ -1,5 +1,5 @@ +import { Channel } from '@/db/schema/Channel.ts'; import { DynamicContentConfigSource } from '@tunarr/types/api'; -import { Channel } from '../../dao/direct/schema/Channel.ts'; import { ContentSourceUpdater } from './ContentSourceUpdater.ts'; import { PlexContentSourceUpdater } from './PlexContentSourceUpdater.ts'; diff --git a/server/src/services/dynamic_channels/IntermediateOperator.ts b/server/src/services/dynamic_channels/IntermediateOperator.ts index 7a0358f8..865d77b6 100644 --- a/server/src/services/dynamic_channels/IntermediateOperator.ts +++ b/server/src/services/dynamic_channels/IntermediateOperator.ts @@ -1,6 +1,6 @@ +import { NamedFunc } from '@/types/func.ts'; +import { ChannelAndLineup } from '@/types/internal.js'; import { last, reduce } from 'lodash-es'; -import { NamedFunc } from '../../types/func.ts'; -import { ChannelAndLineup } from '../../types/internal.js'; function fix(channelAndLineup: ChannelAndLineup): Promise { const { channel, lineup } = channelAndLineup; diff --git a/server/src/services/dynamic_channels/LineupCreator.ts b/server/src/services/dynamic_channels/LineupCreator.ts index c306bbbb..9de60564 100644 --- a/server/src/services/dynamic_channels/LineupCreator.ts +++ b/server/src/services/dynamic_channels/LineupCreator.ts @@ -1,3 +1,10 @@ +import { ChannelDB } from '@/db/ChannelDB.ts'; +import { getDatabase } from '@/db/DBAccess.ts'; +import { Lineup, isContentItem } from '@/db/derived_types/Lineup.ts'; +import { Func } from '@/types/func.js'; +import { ChannelAndLineup } from '@/types/internal.js'; +import { asyncPool } from '@/util/asyncPool.js'; +import { LoggerFactory } from '@/util/logging/LoggerFactory.js'; import { SchedulingOperation } from '@tunarr/types/api'; import { compact, @@ -8,19 +15,12 @@ import { reject, sortBy, } from 'lodash-es'; -import { ChannelDB } from '../../dao/channelDb.js'; -import { Lineup, isContentItem } from '../../dao/derived_types/Lineup.js'; -import { directDbAccess } from '../../dao/direct/directDbAccess.js'; -import { Func } from '../../types/func.js'; -import { ChannelAndLineup } from '../../types/internal.js'; -import { asyncPool } from '../../util/asyncPool.js'; import { asyncFlow, groupByUniqProp, intersperse, isDefined, } from '../../util/index.js'; -import { LoggerFactory } from '../../util/logging/LoggerFactory.js'; import { CollapseOfflineTimeOperator } from './CollapseOfflineTimeOperator.js'; import { IntermediateOperator } from './IntermediateOperator.js'; import { @@ -162,7 +162,7 @@ export class LineupCreator { ); return async ({ channel, lineup }) => { - const db = directDbAccess(); + const db = getDatabase(); const programs = await db .selectFrom('program') .where( diff --git a/server/src/services/dynamic_channels/LineupCreatorContext.ts b/server/src/services/dynamic_channels/LineupCreatorContext.ts index 98e57ae7..223054cd 100644 --- a/server/src/services/dynamic_channels/LineupCreatorContext.ts +++ b/server/src/services/dynamic_channels/LineupCreatorContext.ts @@ -1,10 +1,10 @@ +import { ProgramDao } from '@/db/schema/Program.ts'; import { isUndefined } from 'lodash-es'; import { AsyncLocalStorage } from 'node:async_hooks'; -import { Program } from '../../dao/direct/schema/Program.ts'; export interface LineupBuilderContext { channelId: string; - programById: Record; + programById: Record; } export class LineupCreatorContext { diff --git a/server/src/services/dynamic_channels/PadProgramsSchedulingOperator.ts b/server/src/services/dynamic_channels/PadProgramsSchedulingOperator.ts index 8b62f09c..94da056a 100644 --- a/server/src/services/dynamic_channels/PadProgramsSchedulingOperator.ts +++ b/server/src/services/dynamic_channels/PadProgramsSchedulingOperator.ts @@ -1,3 +1,7 @@ +import { LineupItem } from '@/db/derived_types/Lineup.ts'; +import { Channel } from '@/db/schema/Channel.ts'; +import { ChannelAndLineup } from '@/types/internal.js'; +import { scale } from '@/util/index.ts'; import { AddPaddingOperation } from '@tunarr/types/api'; import dayjs from 'dayjs'; import { @@ -9,10 +13,6 @@ import { reject, sortBy, } from 'lodash-es'; -import { LineupItem } from '../../dao/derived_types/Lineup.ts'; -import { Channel } from '../../dao/direct/schema/Channel.ts'; -import { ChannelAndLineup } from '../../types/internal.js'; -import { scale } from '../../util/index.ts'; import { SchedulingOperator } from './SchedulingOperator.ts'; export class PadProgramsSchedulingOperator extends SchedulingOperator { diff --git a/server/src/services/dynamic_channels/PlexContentSourceUpdater.ts b/server/src/services/dynamic_channels/PlexContentSourceUpdater.ts index 1282f1aa..e08ec43e 100644 --- a/server/src/services/dynamic_channels/PlexContentSourceUpdater.ts +++ b/server/src/services/dynamic_channels/PlexContentSourceUpdater.ts @@ -1,17 +1,17 @@ +import { ChannelDB } from '@/db/ChannelDB.ts'; +import { ProgramDB } from '@/db/ProgramDB.ts'; +import { PendingProgram } from '@/db/derived_types/Lineup.ts'; +import { MediaSourceDB } from '@/db/mediaSourceDB.ts'; +import { Channel } from '@/db/schema/Channel.ts'; +import { PlexApiClient } from '@/external/plex/PlexApiClient.js'; +import { Logger, LoggerFactory } from '@/util/logging/LoggerFactory.js'; +import { Timer } from '@/util/perf.js'; import { createExternalId } from '@tunarr/shared'; import { buildPlexFilterKey } from '@tunarr/shared/util'; import { ContentProgram } from '@tunarr/types'; import { DynamicContentConfigPlexSource } from '@tunarr/types/api'; import { PlexLibraryListing } from '@tunarr/types/plex'; import { isNil, map } from 'lodash-es'; -import { ChannelDB } from '../../dao/channelDb.js'; -import { PendingProgram } from '../../dao/derived_types/Lineup.js'; -import { Channel } from '../../dao/direct/schema/Channel.js'; -import { MediaSourceDB } from '../../dao/mediaSourceDB.js'; -import { ProgramDB } from '../../dao/programDB.js'; -import { PlexApiClient } from '../../external/plex/PlexApiClient.js'; -import { Logger, LoggerFactory } from '../../util/logging/LoggerFactory.js'; -import { Timer } from '../../util/perf.js'; import { EnrichedPlexTerminalMedia, PlexItemEnumerator, diff --git a/server/src/services/dynamic_channels/RandomSortOperator.ts b/server/src/services/dynamic_channels/RandomSortOperator.ts index fc7b6dc7..928db1a5 100644 --- a/server/src/services/dynamic_channels/RandomSortOperator.ts +++ b/server/src/services/dynamic_channels/RandomSortOperator.ts @@ -1,6 +1,6 @@ +import { ChannelAndLineup } from '@/types/internal.js'; +import { random } from '@/util/random.ts'; import { RandomSortOrderOperation } from '@tunarr/types/api'; -import { ChannelAndLineup } from '../../types/internal.js'; -import { random } from '../../util/random.ts'; import { SchedulingOperator } from './SchedulingOperator.ts'; export class RandomSortOperator extends SchedulingOperator { diff --git a/server/src/services/dynamic_channels/ReleaseDateSortOperator.ts b/server/src/services/dynamic_channels/ReleaseDateSortOperator.ts index e22466f1..d5c7d1b3 100644 --- a/server/src/services/dynamic_channels/ReleaseDateSortOperator.ts +++ b/server/src/services/dynamic_channels/ReleaseDateSortOperator.ts @@ -1,7 +1,7 @@ +import { isContentItem } from '@/db/derived_types/Lineup.ts'; +import { ChannelAndLineup } from '@/types/internal.js'; import { ReleaseDateSortOrderOperation } from '@tunarr/types/api'; import { filter, isNull, sortBy } from 'lodash-es'; -import { isContentItem } from '../../dao/derived_types/Lineup.ts'; -import { ChannelAndLineup } from '../../types/internal.js'; import { LineupCreatorContext } from './LineupCreatorContext.ts'; import { SchedulingOperator } from './SchedulingOperator.ts'; diff --git a/server/src/services/dynamic_channels/ScheduledRedirectOperator.test.ts b/server/src/services/dynamic_channels/ScheduledRedirectOperator.test.ts index a2a12d02..5643d347 100644 --- a/server/src/services/dynamic_channels/ScheduledRedirectOperator.test.ts +++ b/server/src/services/dynamic_channels/ScheduledRedirectOperator.test.ts @@ -1,10 +1,10 @@ +import { initOrm } from '@/dao/dataSource'; +import { Lineup, LineupItem } from '@/dao/derived_types/Lineup'; +import { Channel } from '@/dao/entities/Channel'; +import { initTestDb } from '@/tests/testDb'; +import { asyncFlow } from '@/util'; import dayjs from 'dayjs'; import { initial, last, map, range, reduce } from 'lodash-es'; -import { initTestDb } from '../../../tests/testDb'; -import { initOrm } from '../../dao/dataSource'; -import { Lineup, LineupItem } from '../../dao/derived_types/Lineup'; -import { Channel } from '../../dao/entities/Channel'; -import { asyncFlow } from '../../util'; import { IntermediateOperator } from './IntermediateOperator'; import { ScheduledRedirectOperator } from './ScheduledRedirectOperator'; diff --git a/server/src/services/dynamic_channels/ScheduledRedirectOperator.ts b/server/src/services/dynamic_channels/ScheduledRedirectOperator.ts index 3084efc5..5b3d2814 100644 --- a/server/src/services/dynamic_channels/ScheduledRedirectOperator.ts +++ b/server/src/services/dynamic_channels/ScheduledRedirectOperator.ts @@ -1,9 +1,9 @@ +import { LineupItem } from '@/db/derived_types/Lineup.ts'; +import { ChannelAndLineup } from '@/types/internal.js'; +import { binarySearchRange } from '@/util/binarySearch.ts'; import { ScheduledRedirectOperation } from '@tunarr/types/api'; import dayjs from 'dayjs'; import { isNull } from 'lodash-es'; -import { LineupItem } from '../../dao/derived_types/Lineup.ts'; -import { ChannelAndLineup } from '../../types/internal.js'; -import { binarySearchRange } from '../../util/binarySearch.ts'; import { SchedulingOperator } from './SchedulingOperator.ts'; export class ScheduledRedirectOperator extends SchedulingOperator { diff --git a/server/src/services/dynamic_channels/SchedulingOperator.ts b/server/src/services/dynamic_channels/SchedulingOperator.ts index 256c4003..7f37e840 100644 --- a/server/src/services/dynamic_channels/SchedulingOperator.ts +++ b/server/src/services/dynamic_channels/SchedulingOperator.ts @@ -1,5 +1,5 @@ +import { ChannelAndLineup } from '@/types/internal.js'; import { SchedulingOperation } from '@tunarr/types/api'; -import { ChannelAndLineup } from '../../types/internal.js'; // A SchedulingOperator takes a set of lineup items // and returns a set of lineup items. The operator diff --git a/server/src/services/health_checks/FfmpegDebugLoggingHealthCheck.ts b/server/src/services/health_checks/FfmpegDebugLoggingHealthCheck.ts index 8b787abc..2eecf053 100644 --- a/server/src/services/health_checks/FfmpegDebugLoggingHealthCheck.ts +++ b/server/src/services/health_checks/FfmpegDebugLoggingHealthCheck.ts @@ -1,5 +1,5 @@ +import { SettingsDB, getSettings } from '@/db/SettingsDB.ts'; import { FfmpegNumericLogLevels } from '@tunarr/types/schemas'; -import { SettingsDB, getSettings } from '../../dao/settings.ts'; import { HealthCheck, HealthCheckResult, diff --git a/server/src/services/health_checks/FfmpegVersionHealthCheck.ts b/server/src/services/health_checks/FfmpegVersionHealthCheck.ts index 6097cc18..06a2056e 100644 --- a/server/src/services/health_checks/FfmpegVersionHealthCheck.ts +++ b/server/src/services/health_checks/FfmpegVersionHealthCheck.ts @@ -1,8 +1,8 @@ +import { SettingsDB, getSettings } from '@/db/SettingsDB.ts'; +import { FFMPEGInfo, FfmpegVersionResult } from '@/ffmpeg/ffmpegInfo.ts'; +import { fileExists } from '@/util/fsUtil.ts'; import { every, isNil, some } from 'lodash-es'; import { P, match } from 'ts-pattern'; -import { SettingsDB, getSettings } from '../../dao/settings.ts'; -import { FFMPEGInfo, FfmpegVersionResult } from '../../ffmpeg/ffmpegInfo.ts'; -import { fileExists } from '../../util/fsUtil.ts'; import { HealthCheck, HealthCheckResult, diff --git a/server/src/services/health_checks/HardwareAccelerationHealthCheck.ts b/server/src/services/health_checks/HardwareAccelerationHealthCheck.ts index 8f8665f4..dce984ac 100644 --- a/server/src/services/health_checks/HardwareAccelerationHealthCheck.ts +++ b/server/src/services/health_checks/HardwareAccelerationHealthCheck.ts @@ -1,7 +1,7 @@ +import { SettingsDB, getSettings } from '@/db/SettingsDB.ts'; +import { FFMPEGInfo } from '@/ffmpeg/ffmpegInfo.ts'; import { SupportedHardwareAccels } from '@tunarr/types/schemas'; import { intersection, isEmpty, reject } from 'lodash-es'; -import { SettingsDB, getSettings } from '../../dao/settings.ts'; -import { FFMPEGInfo } from '../../ffmpeg/ffmpegInfo.ts'; import { HealthCheck, HealthCheckResult, diff --git a/server/src/services/health_checks/MissingProgramAssociationsHealthCheck.ts b/server/src/services/health_checks/MissingProgramAssociationsHealthCheck.ts index 97be2345..a599579a 100644 --- a/server/src/services/health_checks/MissingProgramAssociationsHealthCheck.ts +++ b/server/src/services/health_checks/MissingProgramAssociationsHealthCheck.ts @@ -1,6 +1,6 @@ +import { getDatabase } from '@/db/DBAccess.ts'; import { find } from 'lodash-es'; import { P, match } from 'ts-pattern'; -import { directDbAccess } from '../../dao/direct/directDbAccess.ts'; import { HealthCheck, HealthCheckResult, @@ -12,7 +12,7 @@ export class MissingProgramAssociationsHealthCheck implements HealthCheck { readonly id: string = this.constructor.name; async getStatus(): Promise { - const missingParents = await directDbAccess() + const missingParents = await getDatabase() .selectFrom('program') .select((eb) => ['type', eb.fn.count('uuid').as('count')]) .where((eb) => diff --git a/server/src/services/health_checks/MissingSeasonNumbersHealthCheck.ts b/server/src/services/health_checks/MissingSeasonNumbersHealthCheck.ts index 96a56545..494cb63d 100644 --- a/server/src/services/health_checks/MissingSeasonNumbersHealthCheck.ts +++ b/server/src/services/health_checks/MissingSeasonNumbersHealthCheck.ts @@ -1,6 +1,6 @@ -import { directDbAccess } from '../../dao/direct/directDbAccess.ts'; -import { ProgramType } from '../../dao/direct/schema/Program.ts'; -import { ProgramGroupingType } from '../../dao/direct/schema/ProgramGrouping.ts'; +import { getDatabase } from '@/db/DBAccess.ts'; +import { ProgramType } from '@/db/schema/Program.ts'; +import { ProgramGroupingType } from '@/db/schema/ProgramGrouping.ts'; import { HealthCheck, HealthCheckResult, @@ -11,14 +11,14 @@ export class MissingSeasonNumbersHealthCheck implements HealthCheck { readonly id = 'MissingSeasonNumbers'; async getStatus(): Promise { - const missingFromProgramTable = await directDbAccess() + const missingFromProgramTable = await getDatabase() .selectFrom('program') .select((eb) => eb.fn.count('uuid').as('count')) .where('type', '=', ProgramType.Episode) .where((eb) => eb.or([eb('seasonNumber', 'is', null)])) .executeTakeFirst(); - const missingFromGroupingTable = await directDbAccess() + const missingFromGroupingTable = await getDatabase() .selectFrom('programGrouping') .select((eb) => eb.fn.count('uuid').as('count')) .where('type', '=', ProgramGroupingType.Season) diff --git a/server/src/stream/ChannelCache.ts b/server/src/stream/ChannelCache.ts index 82fdbb77..e9e7b2f3 100644 --- a/server/src/stream/ChannelCache.ts +++ b/server/src/stream/ChannelCache.ts @@ -1,16 +1,16 @@ +import { InMemoryCachedDbAdapter } from '@/db/InMemoryCachedDbAdapter.ts'; +import { SchemaBackedDbAdapter } from '@/db/SchemaBackedJsonDBAdapter.ts'; +import { globalOptions } from '@/globals.js'; import constants from '@tunarr/shared/constants'; import { isNil, isUndefined } from 'lodash-es'; +import { Low } from 'lowdb'; +import { join } from 'node:path'; import { z } from 'zod'; import { StreamLineupItem, StreamLineupItemSchema, isCommercialLineupItem, -} from '../dao/derived_types/StreamLineup.js'; -import { SchemaBackedDbAdapter } from '../dao/SchemaBackedDbAdapter.js'; -import { join } from 'node:path'; -import { Low } from 'lowdb'; -import { globalOptions } from '../globals.js'; -import { InMemoryCachedDbAdapter } from '../dao/InMemoryCachedDbAdapter.js'; +} from '../db/derived_types/StreamLineup.ts'; const SLACK = constants.SLACK; diff --git a/server/src/stream/ConcatSession.ts b/server/src/stream/ConcatSession.ts index 90e975e3..715c416b 100644 --- a/server/src/stream/ConcatSession.ts +++ b/server/src/stream/ConcatSession.ts @@ -1,7 +1,7 @@ +import { Channel } from '@/db/schema/Channel.ts'; +import { FfmpegTranscodeSession } from '@/ffmpeg/FfmpegTrancodeSession.js'; +import { ConcatOptions } from '@/ffmpeg/ffmpeg.js'; import { isEmpty } from 'lodash-es'; -import { Channel } from '../dao/direct/schema/Channel.ts'; -import { FfmpegTranscodeSession } from '../ffmpeg/FfmpegTrancodeSession.js'; -import { ConcatOptions } from '../ffmpeg/ffmpeg.js'; import { ConcatStream } from './ConcatStream.ts'; import { DirectStreamSession } from './DirectStreamSession.js'; import { ConcatSessionType, SessionOptions } from './Session.js'; diff --git a/server/src/stream/ConcatStream.ts b/server/src/stream/ConcatStream.ts index 7ce580b6..ad6226bd 100644 --- a/server/src/stream/ConcatStream.ts +++ b/server/src/stream/ConcatStream.ts @@ -1,11 +1,11 @@ +import { SettingsDB, getSettings } from '@/db/SettingsDB.ts'; +import { Channel } from '@/db/schema/Channel.ts'; +import { FfmpegStreamFactory } from '@/ffmpeg/FfmpegStreamFactory.ts'; +import { FfmpegTranscodeSession } from '@/ffmpeg/FfmpegTrancodeSession.ts'; +import { ConcatOptions, FFMPEG } from '@/ffmpeg/ffmpeg.ts'; +import { makeFfmpegPlaylistUrl, makeLocalUrl } from '@/util/serverUtil.js'; import { ChannelStreamMode, FfmpegSettings } from '@tunarr/types'; import { initial } from 'lodash-es'; -import { Channel } from '../dao/direct/schema/Channel.ts'; -import { SettingsDB, getSettings } from '../dao/settings.ts'; -import { FfmpegStreamFactory } from '../ffmpeg/FfmpegStreamFactory.ts'; -import { FfmpegTranscodeSession } from '../ffmpeg/FfmpegTrancodeSession.ts'; -import { ConcatOptions, FFMPEG } from '../ffmpeg/ffmpeg.ts'; -import { makeFfmpegPlaylistUrl, makeLocalUrl } from '../util/serverUtil.js'; type ConcatStreamOptions = { parentProcessType: 'hls' | 'direct'; diff --git a/server/src/stream/ConcatWrapperStream.ts b/server/src/stream/ConcatWrapperStream.ts index 7ad73d0e..76976a0e 100644 --- a/server/src/stream/ConcatWrapperStream.ts +++ b/server/src/stream/ConcatWrapperStream.ts @@ -1,11 +1,11 @@ +import { SettingsDB, getSettings } from '@/db/SettingsDB.ts'; +import { Channel } from '@/db/schema/Channel.ts'; +import { FfmpegStreamFactory } from '@/ffmpeg/FfmpegStreamFactory.ts'; +import { FfmpegTranscodeSession } from '@/ffmpeg/FfmpegTrancodeSession.js'; +import { ConcatOptions, FFMPEG } from '@/ffmpeg/ffmpeg.js'; +import { makeLocalUrl } from '@/util/serverUtil.js'; import { ChannelStreamMode, FfmpegSettings } from '@tunarr/types'; import { StrictExtract } from 'ts-essentials'; -import { Channel } from '../dao/direct/schema/Channel.ts'; -import { SettingsDB, getSettings } from '../dao/settings.js'; -import { FfmpegStreamFactory } from '../ffmpeg/FfmpegStreamFactory.ts'; -import { FfmpegTranscodeSession } from '../ffmpeg/FfmpegTrancodeSession.js'; -import { ConcatOptions, FFMPEG } from '../ffmpeg/ffmpeg.js'; -import { makeLocalUrl } from '../util/serverUtil.js'; type ConcatStreamOptions = { childStreamMode: StrictExtract; diff --git a/server/src/stream/ConnectionTracker.ts b/server/src/stream/ConnectionTracker.ts index f59d04d4..949e0e00 100644 --- a/server/src/stream/ConnectionTracker.ts +++ b/server/src/stream/ConnectionTracker.ts @@ -1,9 +1,9 @@ +import { TypedEventEmitter } from '@/types/eventEmitter.ts'; +import { Logger, LoggerFactory } from '@/util/logging/LoggerFactory.ts'; import { StreamConnectionDetails } from '@tunarr/types/api'; import dayjs from 'dayjs'; import events from 'events'; import { isEmpty, isUndefined, keys } from 'lodash-es'; -import { TypedEventEmitter } from '../types/eventEmitter.ts'; -import { Logger, LoggerFactory } from '../util/logging/LoggerFactory.ts'; type ConnectionTrackerEvents = { cleanup: () => void; diff --git a/server/src/stream/DirectStreamSession.ts b/server/src/stream/DirectStreamSession.ts index e3ce1805..24ab6f61 100644 --- a/server/src/stream/DirectStreamSession.ts +++ b/server/src/stream/DirectStreamSession.ts @@ -1,7 +1,7 @@ +import { Channel } from '@/db/schema/Channel.ts'; +import { FfmpegTranscodeSession } from '@/ffmpeg/FfmpegTrancodeSession.js'; import { once, round } from 'lodash-es'; import { Readable } from 'node:stream'; -import { Channel } from '../dao/direct/schema/Channel.ts'; -import { FfmpegTranscodeSession } from '../ffmpeg/FfmpegTrancodeSession.js'; import { Session, SessionOptions } from './Session.js'; /** diff --git a/server/src/stream/OfflinePlayer.ts b/server/src/stream/OfflinePlayer.ts index c2a1fd13..47f8d5c7 100644 --- a/server/src/stream/OfflinePlayer.ts +++ b/server/src/stream/OfflinePlayer.ts @@ -1,13 +1,13 @@ +import { SettingsDB, getSettings } from '@/db/SettingsDB.ts'; +import { FfmpegStreamFactory } from '@/ffmpeg/FfmpegStreamFactory.ts'; +import { FfmpegTranscodeSession } from '@/ffmpeg/FfmpegTrancodeSession.js'; +import { OutputFormat } from '@/ffmpeg/builder/constants.ts'; +import { FFMPEG, StreamOptions } from '@/ffmpeg/ffmpeg.js'; +import { Result } from '@/types/result.js'; +import { LoggerFactory } from '@/util/logging/LoggerFactory.js'; +import { makeLocalUrl } from '@/util/serverUtil.js'; import dayjs from 'dayjs'; import { isError, isUndefined } from 'lodash-es'; -import { SettingsDB, getSettings } from '../dao/settings.js'; -import { FfmpegStreamFactory } from '../ffmpeg/FfmpegStreamFactory.ts'; -import { FfmpegTranscodeSession } from '../ffmpeg/FfmpegTrancodeSession.js'; -import { OutputFormat } from '../ffmpeg/builder/constants.ts'; -import { FFMPEG, StreamOptions } from '../ffmpeg/ffmpeg.js'; -import { Result } from '../types/result.js'; -import { LoggerFactory } from '../util/logging/LoggerFactory.js'; -import { makeLocalUrl } from '../util/serverUtil.js'; import { PlayerContext } from './PlayerStreamContext.js'; import { ProgramStream } from './ProgramStream.js'; diff --git a/server/src/stream/PlayerStreamContext.ts b/server/src/stream/PlayerStreamContext.ts index 07b3f7c0..5de10970 100644 --- a/server/src/stream/PlayerStreamContext.ts +++ b/server/src/stream/PlayerStreamContext.ts @@ -1,5 +1,5 @@ -import { StreamLineupItem } from '../dao/derived_types/StreamLineup.ts'; -import { Channel } from '../dao/direct/schema/Channel.ts'; +import { StreamLineupItem } from '@/db/derived_types/StreamLineup.ts'; +import { Channel } from '@/db/schema/Channel.ts'; import { GetCurrentLineupItemRequest } from './StreamProgramCalculator.ts'; export class PlayerContext { diff --git a/server/src/stream/ProgramStream.ts b/server/src/stream/ProgramStream.ts index df64d89d..9b77dfab 100644 --- a/server/src/stream/ProgramStream.ts +++ b/server/src/stream/ProgramStream.ts @@ -1,24 +1,24 @@ +import { SettingsDB, getSettings } from '@/db/SettingsDB.ts'; +import { FfmpegTranscodeSession } from '@/ffmpeg/FfmpegTrancodeSession.js'; +import { OutputFormat } from '@/ffmpeg/builder/constants.ts'; +import { FFMPEG, StreamOptions } from '@/ffmpeg/ffmpeg.js'; +import { serverContext } from '@/serverContext.js'; +import { TypedEventEmitter } from '@/types/eventEmitter.js'; +import { Result } from '@/types/result.js'; +import { Maybe } from '@/types/util.js'; +import { LoggerFactory } from '@/util/logging/LoggerFactory.js'; +import { makeLocalUrl } from '@/util/serverUtil.js'; import { Watermark } from '@tunarr/types'; import dayjs from 'dayjs'; import events from 'events'; import { isUndefined } from 'lodash-es'; import { PassThrough } from 'stream'; -import { SettingsDB, getSettings } from '../dao/settings.js'; -import { FfmpegTranscodeSession } from '../ffmpeg/FfmpegTrancodeSession.js'; -import { OutputFormat } from '../ffmpeg/builder/constants.ts'; -import { FFMPEG, StreamOptions } from '../ffmpeg/ffmpeg.js'; -import { serverContext } from '../serverContext.js'; -import { TypedEventEmitter } from '../types/eventEmitter.js'; -import { Result } from '../types/result.js'; -import { Maybe } from '../types/util.js'; import { attempt, isDefined, isNonEmptyString, isSuccess, } from '../util/index.js'; -import { LoggerFactory } from '../util/logging/LoggerFactory.js'; -import { makeLocalUrl } from '../util/serverUtil.js'; import { PlayerContext } from './PlayerStreamContext.js'; type ProgramStreamEvents = { diff --git a/server/src/stream/ProgramStreamFactory.ts b/server/src/stream/ProgramStreamFactory.ts index 9cc7fb45..3a31bf8d 100644 --- a/server/src/stream/ProgramStreamFactory.ts +++ b/server/src/stream/ProgramStreamFactory.ts @@ -1,7 +1,7 @@ -import { MediaSourceType } from '../dao/direct/schema/MediaSource.ts'; -import { SettingsDB, getSettings } from '../dao/settings.js'; -import { NutOutputFormat, OutputFormat } from '../ffmpeg/builder/constants.ts'; -import { LoggerFactory } from '../util/logging/LoggerFactory.js'; +import { SettingsDB, getSettings } from '@/db/SettingsDB.ts'; +import { MediaSourceType } from '@/db/schema/MediaSource.ts'; +import { NutOutputFormat, OutputFormat } from '@/ffmpeg/builder/constants.ts'; +import { LoggerFactory } from '@/util/logging/LoggerFactory.js'; import { OfflineProgramStream } from './OfflinePlayer.js'; import { PlayerContext } from './PlayerStreamContext.js'; import { ProgramStream } from './ProgramStream.js'; diff --git a/server/src/stream/Session.ts b/server/src/stream/Session.ts index a874a9da..9b2e4d33 100644 --- a/server/src/stream/Session.ts +++ b/server/src/stream/Session.ts @@ -1,3 +1,8 @@ +import { Channel } from '@/db/schema/Channel.ts'; +import { TypedEventEmitter } from '@/types/eventEmitter.ts'; +import { Result } from '@/types/result.js'; +import { Maybe } from '@/types/util.js'; +import { Logger, LoggerFactory } from '@/util/logging/LoggerFactory.ts'; import { ChannelStreamMode } from '@tunarr/types'; import { StreamConnectionDetails } from '@tunarr/types/api'; import { Mutex } from 'async-mutex'; @@ -6,11 +11,6 @@ import { forEach, isEmpty, keys, partition } from 'lodash-es'; import events from 'node:events'; import { StrictExtract } from 'ts-essentials'; import { v4 } from 'uuid'; -import { Channel } from '../dao/direct/schema/Channel.ts'; -import { TypedEventEmitter } from '../types/eventEmitter.ts'; -import { Result } from '../types/result.js'; -import { Maybe } from '../types/util.js'; -import { Logger, LoggerFactory } from '../util/logging/LoggerFactory.ts'; import { ConnectionTracker } from './ConnectionTracker.ts'; const ConcatSessionSuffix = '_concat'; diff --git a/server/src/stream/SessionManager.ts b/server/src/stream/SessionManager.ts index 8b2c77f4..f6ba0162 100644 --- a/server/src/stream/SessionManager.ts +++ b/server/src/stream/SessionManager.ts @@ -1,3 +1,9 @@ +import { ChannelDB } from '@/db/ChannelDB.ts'; +import { Channel } from '@/db/schema/Channel.ts'; +import { Result } from '@/types/result.js'; +import { Maybe } from '@/types/util.js'; +import { LoggerFactory } from '@/util/logging/LoggerFactory.js'; +import { MutexMap } from '@/util/mutexMap.js'; import { compact, filter, @@ -7,17 +13,11 @@ import { maxBy, values, } from 'lodash-es'; -import { ChannelDB } from '../dao/channelDb.js'; -import { Channel } from '../dao/direct/schema/Channel.js'; import { ChannelNotFoundError, GenericError, TypedError, } from '../types/errors.js'; -import { Result } from '../types/result.js'; -import { Maybe } from '../types/util.js'; -import { LoggerFactory } from '../util/logging/LoggerFactory.js'; -import { MutexMap } from '../util/mutexMap.js'; import { ConcatSession, ConcatSessionOptions } from './ConcatSession.js'; import { ConcatSessionType, HlsConcatSessionType, Session } from './Session.js'; import { HlsSession, HlsSessionOptions } from './hls/HlsSession.js'; @@ -26,11 +26,11 @@ import { HlsSlowerSessionOptions, } from './hls/HlsSlowerSession.js'; +import { OnDemandChannelService } from '@/services/OnDemandChannelService.js'; +import { ifDefined } from '@/util/index.js'; import { ChannelStreamMode } from '@tunarr/types'; import { StreamConnectionDetails } from '@tunarr/types/api'; import dayjs from 'dayjs'; -import { OnDemandChannelService } from '../services/OnDemandChannelService.js'; -import { ifDefined } from '../util/index.js'; import { SessionType } from './Session.js'; export type SessionKey = `${string}_${SessionType}`; diff --git a/server/src/stream/StreamProgramCalculator.ts b/server/src/stream/StreamProgramCalculator.ts index 9509303b..c911bb80 100644 --- a/server/src/stream/StreamProgramCalculator.ts +++ b/server/src/stream/StreamProgramCalculator.ts @@ -1,38 +1,38 @@ +import { ChannelDB } from '@/db/ChannelDB.ts'; +import { FillerDB } from '@/db/FillerListDB.ts'; +import { ProgramDB } from '@/db/ProgramDB.ts'; +import { ProgramExternalIdType } from '@/db/custom_types/ProgramExternalIdType.ts'; +import { Channel } from '@/db/schema/Channel.ts'; +import { MediaSourceType } from '@/db/schema/MediaSource.ts'; +import { ProgramDao as RawProgram } from '@/db/schema/Program.ts'; +import type { ProgramDaoWithRelations as RawProgramEntity } from '@/db/schema/derivedTypes.js'; +import { FillerPicker } from '@/services/FillerPicker.js'; +import { Result } from '@/types/result.js'; +import { Maybe, Nullable } from '@/types/util.js'; +import { binarySearchRange } from '@/util/binarySearch.js'; +import { LoggerFactory } from '@/util/logging/LoggerFactory.js'; import constants from '@tunarr/shared/constants'; import dayjs from 'dayjs'; import { first, isEmpty, isNil, isNull, isUndefined, nth } from 'lodash-es'; import { StrictExclude } from 'ts-essentials'; import { z } from 'zod'; -import { ChannelDB } from '../dao/channelDb.js'; -import { ProgramExternalIdType } from '../dao/custom_types/ProgramExternalIdType.js'; import { Lineup, isContentItem, isOfflineItem, -} from '../dao/derived_types/Lineup.js'; +} from '../db/derived_types/Lineup.ts'; import { EnrichedLineupItem, ProgramStreamLineupItem, RedirectStreamLineupItem, StreamLineupItem, createOfflineStreamLineupItem, -} from '../dao/derived_types/StreamLineup.js'; -import type { ProgramWithRelations as RawProgramEntity } from '../dao/direct/derivedTypes.d.ts'; -import { Channel } from '../dao/direct/schema/Channel.js'; -import { MediaSourceType } from '../dao/direct/schema/MediaSource.ts'; -import { Program as RawProgram } from '../dao/direct/schema/Program.js'; -import { FillerDB } from '../dao/fillerDB.js'; -import { ProgramDB } from '../dao/programDB.js'; -import { FillerPicker } from '../services/FillerPicker.js'; -import { Result } from '../types/result.js'; -import { Maybe, Nullable } from '../types/util.js'; -import { binarySearchRange } from '../util/binarySearch.js'; +} from '../db/derived_types/StreamLineup.ts'; import { isNonEmptyString, nullToUndefined, zipWithIndex, } from '../util/index.js'; -import { LoggerFactory } from '../util/logging/LoggerFactory.js'; import { ChannelCache } from './ChannelCache.js'; import { wereThereTooManyAttempts } from './StreamThrottler.js'; diff --git a/server/src/stream/StreamThrottler.ts b/server/src/stream/StreamThrottler.ts index 349341b5..6cf70014 100644 --- a/server/src/stream/StreamThrottler.ts +++ b/server/src/stream/StreamThrottler.ts @@ -1,8 +1,8 @@ +import { StreamLineupItem } from '@/db/derived_types/StreamLineup.ts'; +import { Maybe } from '@/types/util.ts'; import constants from '@tunarr/shared/constants'; import { isUndefined } from 'lodash-es'; import util from 'node:util'; -import { StreamLineupItem } from '../dao/derived_types/StreamLineup.ts'; -import { Maybe } from '../types/util.ts'; type CacheEntry = { t0: number; diff --git a/server/src/stream/VideoStream.ts b/server/src/stream/VideoStream.ts index b0c663e9..ff400082 100644 --- a/server/src/stream/VideoStream.ts +++ b/server/src/stream/VideoStream.ts @@ -1,10 +1,10 @@ +import { getServerContext, serverContext } from '@/serverContext.ts'; +import { Result } from '@/types/result.ts'; +import { fileExists } from '@/util/fsUtil.js'; +import { LoggerFactory } from '@/util/logging/LoggerFactory.ts'; import { ChannelStreamMode } from '@tunarr/types'; import { isNil, once } from 'lodash-es'; import { PassThrough, Readable } from 'node:stream'; -import { getServerContext, serverContext } from '../serverContext.ts'; -import { Result } from '../types/result.ts'; -import { fileExists } from '../util/fsUtil.js'; -import { LoggerFactory } from '../util/logging/LoggerFactory.ts'; import { PlayerContext } from './PlayerStreamContext.ts'; import { ProgramStream } from './ProgramStream.js'; import { ProgramStreamFactory } from './ProgramStreamFactory.js'; diff --git a/server/src/stream/hls/BaseHlsSession.ts b/server/src/stream/hls/BaseHlsSession.ts index fb2b0b1b..b98ec7c6 100644 --- a/server/src/stream/hls/BaseHlsSession.ts +++ b/server/src/stream/hls/BaseHlsSession.ts @@ -1,12 +1,12 @@ +import { Channel } from '@/db/schema/Channel.ts'; +import { Session, SessionOptions } from '@/stream/Session.ts'; +import { Result } from '@/types/result.ts'; +import { isNodeError } from '@/util/index.ts'; import retry from 'async-retry'; import dayjs, { Dayjs } from 'dayjs'; import { filter, isError, isString, map, some } from 'lodash-es'; import fs from 'node:fs/promises'; import path, { basename, extname } from 'node:path'; -import { Channel } from '../../dao/direct/schema/Channel.ts'; -import { Result } from '../../types/result.ts'; -import { isNodeError } from '../../util/index.ts'; -import { Session, SessionOptions } from '../Session.ts'; export abstract class BaseHlsSession< HlsSessionOptsT extends BaseHlsSessionOptions = BaseHlsSessionOptions, diff --git a/server/src/stream/hls/HlsPlaylistMutator.ts b/server/src/stream/hls/HlsPlaylistMutator.ts index 014bbe9d..0438ce1f 100644 --- a/server/src/stream/hls/HlsPlaylistMutator.ts +++ b/server/src/stream/hls/HlsPlaylistMutator.ts @@ -1,3 +1,4 @@ +import { isNonEmptyString } from '@/util/index.ts'; import dayjs, { Dayjs } from 'dayjs'; import { dropWhile, @@ -12,7 +13,6 @@ import { takeRight, trimEnd, } from 'lodash-es'; -import { isNonEmptyString } from '../../util/index.ts'; export class HlsPlaylistMutator { trimPlaylistWithDiscontinuity( diff --git a/server/src/stream/hls/HlsSession.ts b/server/src/stream/hls/HlsSession.ts index 70c18895..220a79f0 100644 --- a/server/src/stream/hls/HlsSession.ts +++ b/server/src/stream/hls/HlsSession.ts @@ -1,23 +1,23 @@ +import { ChannelDB } from '@/db/ChannelDB.ts'; +import { getSettings } from '@/db/SettingsDB.ts'; +import { Channel } from '@/db/schema/Channel.ts'; +import { FfmpegTranscodeSession } from '@/ffmpeg/FfmpegTrancodeSession.ts'; +import { GetLastPtsDurationTask } from '@/ffmpeg/GetLastPtsDuration.ts'; +import { HlsOutputFormat } from '@/ffmpeg/builder/constants.ts'; +import { serverContext } from '@/serverContext.ts'; +import { OnDemandChannelService } from '@/services/OnDemandChannelService.ts'; +import { PlayerContext } from '@/stream/PlayerStreamContext.ts'; +import { ProgramStreamFactory } from '@/stream/ProgramStreamFactory.ts'; +import { StreamProgramCalculator } from '@/stream/StreamProgramCalculator.ts'; +import { Result } from '@/types/result.ts'; +import { Maybe } from '@/types/util.ts'; +import { fileExists } from '@/util/fsUtil.ts'; +import { wait } from '@/util/index.ts'; import { seq } from '@tunarr/shared/util'; import dayjs, { Dayjs } from 'dayjs'; import { filter, isEmpty, last, sortBy } from 'lodash-es'; import fs from 'node:fs/promises'; import path, { extname } from 'node:path'; -import { ChannelDB } from '../../dao/channelDb.ts'; -import { Channel } from '../../dao/direct/schema/Channel.ts'; -import { getSettings } from '../../dao/settings.ts'; -import { FfmpegTranscodeSession } from '../../ffmpeg/FfmpegTrancodeSession.ts'; -import { GetLastPtsDurationTask } from '../../ffmpeg/GetLastPtsDuration.ts'; -import { HlsOutputFormat } from '../../ffmpeg/builder/constants.ts'; -import { serverContext } from '../../serverContext.ts'; -import { OnDemandChannelService } from '../../services/OnDemandChannelService.ts'; -import { Result } from '../../types/result.ts'; -import { Maybe } from '../../types/util.ts'; -import { fileExists } from '../../util/fsUtil.ts'; -import { wait } from '../../util/index.ts'; -import { PlayerContext } from '../PlayerStreamContext.ts'; -import { ProgramStreamFactory } from '../ProgramStreamFactory.ts'; -import { StreamProgramCalculator } from '../StreamProgramCalculator.ts'; import { BaseHlsSession, BaseHlsSessionOptions } from './BaseHlsSession.ts'; import { HlsPlaylistMutator } from './HlsPlaylistMutator.ts'; diff --git a/server/src/stream/hls/HlsSlowerSession.ts b/server/src/stream/hls/HlsSlowerSession.ts index b9f24cd3..c87384c5 100644 --- a/server/src/stream/hls/HlsSlowerSession.ts +++ b/server/src/stream/hls/HlsSlowerSession.ts @@ -1,23 +1,23 @@ +import { getSettings } from '@/db/SettingsDB.ts'; +import { Channel } from '@/db/schema/Channel.ts'; +import { FfmpegTranscodeSession } from '@/ffmpeg/FfmpegTrancodeSession.ts'; +import { FFMPEG, defaultHlsOptions } from '@/ffmpeg/ffmpeg.ts'; +import { serverContext } from '@/serverContext.ts'; +import { ProgramStream } from '@/stream/ProgramStream.ts'; +import { ProgramStreamFactory } from '@/stream/ProgramStreamFactory.ts'; +import { StreamProgramCalculator } from '@/stream/StreamProgramCalculator.ts'; +import { Result } from '@/types/result.ts'; +import { makeFfmpegPlaylistUrl } from '@/util/serverUtil.ts'; import dayjs from 'dayjs'; import { StrictOmit } from 'ts-essentials'; -import { Channel } from '../../dao/direct/schema/Channel.ts'; -import { getSettings } from '../../dao/settings.ts'; -import { FfmpegTranscodeSession } from '../../ffmpeg/FfmpegTrancodeSession.ts'; import { HlsOutputFormat, NutOutputFormat, } from '../../ffmpeg/builder/constants.ts'; -import { FFMPEG, defaultHlsOptions } from '../../ffmpeg/ffmpeg.ts'; -import { serverContext } from '../../serverContext.ts'; -import { Result } from '../../types/result.ts'; -import { makeFfmpegPlaylistUrl } from '../../util/serverUtil.ts'; import { GetPlayerContextRequest, PlayerContext, } from '../PlayerStreamContext.ts'; -import { ProgramStream } from '../ProgramStream.ts'; -import { ProgramStreamFactory } from '../ProgramStreamFactory.ts'; -import { StreamProgramCalculator } from '../StreamProgramCalculator.ts'; import { BaseHlsSession, BaseHlsSessionOptions } from './BaseHlsSession.ts'; export type HlsSlowerSessionOptions = BaseHlsSessionOptions & { diff --git a/server/src/stream/jellyfin/JellyfinProgramStream.ts b/server/src/stream/jellyfin/JellyfinProgramStream.ts index 068b4861..3624db02 100644 --- a/server/src/stream/jellyfin/JellyfinProgramStream.ts +++ b/server/src/stream/jellyfin/JellyfinProgramStream.ts @@ -1,20 +1,20 @@ +import { ChannelDB } from '@/db/ChannelDB.ts'; +import { SettingsDB, getSettings } from '@/db/SettingsDB.ts'; +import { isContentBackedLineupIteam } from '@/db/derived_types/StreamLineup.ts'; +import { MediaSourceDB } from '@/db/mediaSourceDB.ts'; +import { MediaSourceType } from '@/db/schema/MediaSource.ts'; +import { FfmpegTranscodeSession } from '@/ffmpeg/FfmpegTrancodeSession.js'; +import { OutputFormat } from '@/ffmpeg/builder/constants.ts'; +import { FFMPEG } from '@/ffmpeg/ffmpeg.js'; +import { PlayerContext } from '@/stream/PlayerStreamContext.js'; +import { ProgramStream } from '@/stream/ProgramStream.js'; +import { UpdateJellyfinPlayStatusScheduledTask } from '@/tasks/jellyfin/UpdateJellyfinPlayStatusTask.js'; +import { Result } from '@/types/result.js'; +import { Maybe, Nullable } from '@/types/util.js'; +import { ifDefined } from '@/util/index.js'; +import { LoggerFactory } from '@/util/logging/LoggerFactory.js'; import dayjs from 'dayjs'; import { isNil, isNull, isUndefined } from 'lodash-es'; -import { ChannelDB } from '../../dao/channelDb.js'; -import { isContentBackedLineupIteam } from '../../dao/derived_types/StreamLineup.js'; -import { MediaSourceType } from '../../dao/direct/schema/MediaSource.ts'; -import { MediaSourceDB } from '../../dao/mediaSourceDB.js'; -import { SettingsDB, getSettings } from '../../dao/settings.js'; -import { FfmpegTranscodeSession } from '../../ffmpeg/FfmpegTrancodeSession.js'; -import { OutputFormat } from '../../ffmpeg/builder/constants.ts'; -import { FFMPEG } from '../../ffmpeg/ffmpeg.js'; -import { UpdateJellyfinPlayStatusScheduledTask } from '../../tasks/jellyfin/UpdateJellyfinPlayStatusTask.js'; -import { Result } from '../../types/result.js'; -import { Maybe, Nullable } from '../../types/util.js'; -import { ifDefined } from '../../util/index.js'; -import { LoggerFactory } from '../../util/logging/LoggerFactory.js'; -import { PlayerContext } from '../PlayerStreamContext.js'; -import { ProgramStream } from '../ProgramStream.js'; import { JellyfinStreamDetails } from './JellyfinStreamDetails.js'; export class JellyfinProgramStream extends ProgramStream { diff --git a/server/src/stream/jellyfin/JellyfinStreamDetails.ts b/server/src/stream/jellyfin/JellyfinStreamDetails.ts index d2301dc3..6c25c9eb 100644 --- a/server/src/stream/jellyfin/JellyfinStreamDetails.ts +++ b/server/src/stream/jellyfin/JellyfinStreamDetails.ts @@ -1,3 +1,16 @@ +import { ProgramDB } from '@/db/ProgramDB.ts'; +import { SettingsDB } from '@/db/SettingsDB.ts'; +import { ContentBackedStreamLineupItem } from '@/db/derived_types/StreamLineup.ts'; +import { MediaSourceTable } from '@/db/schema/MediaSource.ts'; +import { ProgramType } from '@/db/schema/Program.ts'; +import { isQueryError } from '@/external/BaseApiClient.js'; +import { MediaSourceApiFactory } from '@/external/MediaSourceApiFactory.js'; +import { JellyfinApiClient } from '@/external/jellyfin/JellyfinApiClient.js'; +import { JellyfinItemFinder } from '@/external/jellyfin/JellyfinItemFinder.ts'; +import { Maybe, Nullable } from '@/types/util.js'; +import { fileExists } from '@/util/fsUtil.js'; +import { Logger, LoggerFactory } from '@/util/logging/LoggerFactory.js'; +import { makeLocalUrl } from '@/util/serverUtil.js'; import { JellyfinItem } from '@tunarr/types/jellyfin'; import { Selectable } from 'kysely'; import { @@ -16,25 +29,12 @@ import { trimStart, } from 'lodash-es'; import { NonEmptyArray } from 'ts-essentials'; -import { ContentBackedStreamLineupItem } from '../../dao/derived_types/StreamLineup.js'; -import { MediaSourceTable } from '../../dao/direct/schema/MediaSource.js'; -import { ProgramType } from '../../dao/direct/schema/Program.ts'; -import { ProgramDB } from '../../dao/programDB.ts'; -import { SettingsDB } from '../../dao/settings.js'; -import { isQueryError } from '../../external/BaseApiClient.js'; -import { MediaSourceApiFactory } from '../../external/MediaSourceApiFactory.js'; -import { JellyfinApiClient } from '../../external/jellyfin/JellyfinApiClient.js'; -import { JellyfinItemFinder } from '../../external/jellyfin/JellyfinItemFinder.ts'; -import { Maybe, Nullable } from '../../types/util.js'; -import { fileExists } from '../../util/fsUtil.js'; import { ifDefined, isDefined, isNonEmptyString, nullToUndefined, } from '../../util/index.js'; -import { Logger, LoggerFactory } from '../../util/logging/LoggerFactory.js'; -import { makeLocalUrl } from '../../util/serverUtil.js'; import { AudioStreamDetails, HttpStreamSource, diff --git a/server/src/stream/plex/PlexProgramStream.ts b/server/src/stream/plex/PlexProgramStream.ts index 1d561023..e45277d3 100644 --- a/server/src/stream/plex/PlexProgramStream.ts +++ b/server/src/stream/plex/PlexProgramStream.ts @@ -1,22 +1,22 @@ +import { ChannelDB } from '@/db/ChannelDB.ts'; +import { SettingsDB, getSettings } from '@/db/SettingsDB.ts'; +import { isContentBackedLineupIteam } from '@/db/derived_types/StreamLineup.ts'; +import { MediaSourceDB } from '@/db/mediaSourceDB.ts'; +import { MediaSourceType } from '@/db/schema/MediaSource.ts'; +import { FfmpegStreamFactory } from '@/ffmpeg/FfmpegStreamFactory.ts'; +import { FfmpegTranscodeSession } from '@/ffmpeg/FfmpegTrancodeSession.js'; +import { OutputFormat } from '@/ffmpeg/builder/constants.ts'; +import { FFMPEG, StreamOptions } from '@/ffmpeg/ffmpeg.js'; +import { GlobalScheduler } from '@/services/Scheduler.ts'; +import { PlayerContext } from '@/stream/PlayerStreamContext.js'; +import { ProgramStream } from '@/stream/ProgramStream.js'; +import { UpdatePlexPlayStatusScheduledTask } from '@/tasks/plex/UpdatePlexPlayStatusTask.js'; +import { Result } from '@/types/result.js'; +import { Maybe } from '@/types/util.js'; +import { ifDefined } from '@/util/index.js'; +import { LoggerFactory } from '@/util/logging/LoggerFactory.js'; import dayjs from 'dayjs'; import { isNil, isNull, isUndefined } from 'lodash-es'; -import { ChannelDB } from '../../dao/channelDb.js'; -import { isContentBackedLineupIteam } from '../../dao/derived_types/StreamLineup.js'; -import { MediaSourceType } from '../../dao/direct/schema/MediaSource.ts'; -import { MediaSourceDB } from '../../dao/mediaSourceDB.js'; -import { SettingsDB, getSettings } from '../../dao/settings.js'; -import { FfmpegStreamFactory } from '../../ffmpeg/FfmpegStreamFactory.ts'; -import { FfmpegTranscodeSession } from '../../ffmpeg/FfmpegTrancodeSession.js'; -import { OutputFormat } from '../../ffmpeg/builder/constants.ts'; -import { FFMPEG, StreamOptions } from '../../ffmpeg/ffmpeg.js'; -import { GlobalScheduler } from '../../services/scheduler.js'; -import { UpdatePlexPlayStatusScheduledTask } from '../../tasks/plex/UpdatePlexPlayStatusTask.js'; -import { Result } from '../../types/result.js'; -import { Maybe } from '../../types/util.js'; -import { ifDefined } from '../../util/index.js'; -import { LoggerFactory } from '../../util/logging/LoggerFactory.js'; -import { PlayerContext } from '../PlayerStreamContext.js'; -import { ProgramStream } from '../ProgramStream.js'; import { PlexStreamDetails } from './PlexStreamDetails.js'; export class PlexProgramStream extends ProgramStream { diff --git a/server/src/stream/plex/PlexStreamDetails.ts b/server/src/stream/plex/PlexStreamDetails.ts index e19738fa..2fa294f0 100644 --- a/server/src/stream/plex/PlexStreamDetails.ts +++ b/server/src/stream/plex/PlexStreamDetails.ts @@ -1,3 +1,16 @@ +import { ProgramDB } from '@/db/ProgramDB.ts'; +import { SettingsDB, getSettings } from '@/db/SettingsDB.ts'; +import { ProgramExternalIdType } from '@/db/custom_types/ProgramExternalIdType.ts'; +import { ContentBackedStreamLineupItem } from '@/db/derived_types/StreamLineup.ts'; +import type { MediaSourceTable } from '@/db/schema/MediaSource.ts'; +import { isQueryError, isQuerySuccess } from '@/external/BaseApiClient.js'; +import { MediaSourceApiFactory } from '@/external/MediaSourceApiFactory.ts'; +import { PlexApiClient } from '@/external/plex/PlexApiClient.ts'; +import { Maybe, Nullable } from '@/types/util.ts'; +import { fileExists } from '@/util/fsUtil.ts'; +import { attempt, isNonEmptyString } from '@/util/index.ts'; +import { Logger, LoggerFactory } from '@/util/logging/LoggerFactory.ts'; +import { makeLocalUrl } from '@/util/serverUtil.js'; import { PlexEpisode, PlexMediaAudioStream, @@ -23,19 +36,6 @@ import { trimEnd, } from 'lodash-es'; import { NonEmptyArray } from 'ts-essentials'; -import { ProgramExternalIdType } from '../../dao/custom_types/ProgramExternalIdType.ts'; -import { ContentBackedStreamLineupItem } from '../../dao/derived_types/StreamLineup.js'; -import type { MediaSourceTable } from '../../dao/direct/schema/MediaSource.d.ts'; -import { ProgramDB } from '../../dao/programDB.ts'; -import { SettingsDB, getSettings } from '../../dao/settings.js'; -import { isQueryError, isQuerySuccess } from '../../external/BaseApiClient.js'; -import { MediaSourceApiFactory } from '../../external/MediaSourceApiFactory.ts'; -import { PlexApiClient } from '../../external/plex/PlexApiClient.ts'; -import { Maybe, Nullable } from '../../types/util.ts'; -import { fileExists } from '../../util/fsUtil.ts'; -import { attempt, isNonEmptyString } from '../../util/index.ts'; -import { Logger, LoggerFactory } from '../../util/logging/LoggerFactory.ts'; -import { makeLocalUrl } from '../../util/serverUtil.js'; import { AudioStreamDetails, HttpStreamSource, diff --git a/server/src/stream/types.ts b/server/src/stream/types.ts index bcca93e9..53b89f89 100644 --- a/server/src/stream/types.ts +++ b/server/src/stream/types.ts @@ -1,3 +1,5 @@ +import { Nullable } from '@/types/util.ts'; +import { isNonEmptyString } from '@/util/index.ts'; import { Duration } from 'dayjs/plugin/duration.js'; import { first, isNull, isUndefined } from 'lodash-es'; import { Dictionary } from 'ts-essentials'; @@ -8,8 +10,6 @@ import { PixelFormatYuv420P, PixelFormatYuv420P10Le, } from '../ffmpeg/builder/format/PixelFormat.ts'; -import { Nullable } from '../types/util.ts'; -import { isNonEmptyString } from '../util/index.ts'; export type StreamDetails = { duration?: Duration; diff --git a/server/src/tasks/BackupTask.ts b/server/src/tasks/BackupTask.ts index 50ef364b..d60267f9 100644 --- a/server/src/tasks/BackupTask.ts +++ b/server/src/tasks/BackupTask.ts @@ -1,9 +1,9 @@ +import { getSettings } from '@/db/SettingsDB.ts'; +import { ArchiveDatabaseBackup } from '@/db/backup/ArchiveDatabaseBackup.ts'; import { Tag } from '@tunarr/types'; import { BackupConfiguration } from '@tunarr/types/schemas'; import { partition } from 'lodash-es'; import { DeepReadonly } from 'ts-essentials'; -import { ArchiveDatabaseBackup } from '../dao/backup/ArchiveDatabaseBackup.ts'; -import { getSettings } from '../dao/settings.ts'; import { Task, TaskId } from './Task.ts'; export class BackupTask extends Task { diff --git a/server/src/tasks/CleanupSessionsTask.ts b/server/src/tasks/CleanupSessionsTask.ts index 729be458..9dc098f8 100644 --- a/server/src/tasks/CleanupSessionsTask.ts +++ b/server/src/tasks/CleanupSessionsTask.ts @@ -1,5 +1,5 @@ -import { serverContext } from '../serverContext.js'; -import { Maybe } from '../types/util.js'; +import { serverContext } from '@/serverContext.js'; +import { Maybe } from '@/types/util.js'; import { Task, TaskId } from './Task.js'; export class CleanupSessionsTask extends Task { diff --git a/server/src/tasks/OnDemandChannelStateTask.ts b/server/src/tasks/OnDemandChannelStateTask.ts index 86b77fdd..ea2daa1f 100644 --- a/server/src/tasks/OnDemandChannelStateTask.ts +++ b/server/src/tasks/OnDemandChannelStateTask.ts @@ -1,9 +1,9 @@ +import { ChannelDB } from '@/db/ChannelDB.ts'; +import { serverContext } from '@/serverContext.ts'; +import { OnDemandChannelService } from '@/services/OnDemandChannelService.ts'; import { Tag } from '@tunarr/types'; import dayjs from 'dayjs'; import { every, values } from 'lodash-es'; -import { ChannelDB } from '../dao/channelDb.ts'; -import { serverContext } from '../serverContext.ts'; -import { OnDemandChannelService } from '../services/OnDemandChannelService.ts'; import { Task, TaskId } from './Task.ts'; /** diff --git a/server/src/tasks/ReconcileProgramDurationsTask.ts b/server/src/tasks/ReconcileProgramDurationsTask.ts index 48fbc650..0945630c 100644 --- a/server/src/tasks/ReconcileProgramDurationsTask.ts +++ b/server/src/tasks/ReconcileProgramDurationsTask.ts @@ -1,3 +1,7 @@ +import { ChannelDB } from '@/db/ChannelDB.ts'; +import { getDatabase } from '@/db/DBAccess.ts'; +import { isContentItem } from '@/db/derived_types/Lineup.ts'; +import { flatMapAsyncSeq, isNonEmptyString } from '@/util/index.ts'; import { chunk, differenceWith, @@ -8,10 +12,6 @@ import { map, uniqBy, } from 'lodash-es'; -import { ChannelDB } from '../dao/channelDb.ts'; -import { isContentItem } from '../dao/derived_types/Lineup.ts'; -import { directDbAccess } from '../dao/direct/directDbAccess.js'; -import { flatMapAsyncSeq, isNonEmptyString } from '../util/index.ts'; import { Task } from './Task.ts'; // This task is fired off whenever programs are updated. It goes through @@ -59,7 +59,7 @@ export class ReconcileProgramDurationsTask extends Task { const missingPrograms = await flatMapAsyncSeq( chunk(missingKeys, 200), (items) => - directDbAccess() + getDatabase() .selectFrom('program') .select(['uuid', 'duration']) .where('uuid', 'in', map(items, 'id')) diff --git a/server/src/tasks/ScheduleDynamicChannelsTask.ts b/server/src/tasks/ScheduleDynamicChannelsTask.ts index 5c325f9c..0d3424d9 100644 --- a/server/src/tasks/ScheduleDynamicChannelsTask.ts +++ b/server/src/tasks/ScheduleDynamicChannelsTask.ts @@ -1,10 +1,10 @@ +import { ChannelDB } from '@/db/ChannelDB.ts'; +import { Channel } from '@/db/schema/Channel.ts'; +import { GlobalScheduler } from '@/services/Scheduler.ts'; +import { ContentSourceUpdaterFactory } from '@/services/dynamic_channels/ContentSourceUpdaterFactory.ts'; +import { Maybe } from '@/types/util.ts'; import { DynamicContentConfigSource } from '@tunarr/types/api'; import { filter } from 'lodash-es'; -import { ChannelDB } from '../dao/channelDb.ts'; -import { Channel } from '../dao/direct/schema/Channel.ts'; -import { ContentSourceUpdaterFactory } from '../services/dynamic_channels/ContentSourceUpdaterFactory.ts'; -import { GlobalScheduler } from '../services/scheduler.ts'; -import { Maybe } from '../types/util.ts'; import { ScheduledTask } from './ScheduledTask.ts'; import { Task, TaskId } from './Task.ts'; diff --git a/server/src/tasks/ScheduledTask.ts b/server/src/tasks/ScheduledTask.ts index c769cc45..0dd300c7 100644 --- a/server/src/tasks/ScheduledTask.ts +++ b/server/src/tasks/ScheduledTask.ts @@ -1,8 +1,8 @@ +import { Maybe } from '@/types/util.js'; +import { Logger, LoggerFactory } from '@/util/logging/LoggerFactory.js'; import dayjs from 'dayjs'; import { isDate } from 'lodash-es'; import schedule, { RecurrenceRule } from 'node-schedule'; -import { Maybe } from '../types/util.js'; -import { Logger, LoggerFactory } from '../util/logging/LoggerFactory.js'; import { Task } from './Task.js'; type ScheduleRule = RecurrenceRule | Date | string | number; diff --git a/server/src/tasks/Task.ts b/server/src/tasks/Task.ts index 4d8b762a..07b92bd3 100644 --- a/server/src/tasks/Task.ts +++ b/server/src/tasks/Task.ts @@ -1,7 +1,7 @@ +import { Maybe } from '@/types/util.js'; +import { isNonEmptyString } from '@/util/index.js'; import type { Tag } from '@tunarr/types'; import { isError, isString, round } from 'lodash-es'; -import { Maybe } from '../types/util.js'; -import { isNonEmptyString } from '../util/index.js'; import { LogLevels, Logger, diff --git a/server/src/tasks/TaskQueue.ts b/server/src/tasks/TaskQueue.ts index 881bee17..aab548b5 100644 --- a/server/src/tasks/TaskQueue.ts +++ b/server/src/tasks/TaskQueue.ts @@ -1,7 +1,7 @@ +import { Maybe } from '@/types/util.js'; +import { Logger, LoggerFactory } from '@/util/logging/LoggerFactory.js'; import PQueue, { Options, Queue, QueueAddOptions } from 'p-queue'; import { v4 } from 'uuid'; -import { Maybe } from '../types/util.js'; -import { Logger, LoggerFactory } from '../util/logging/LoggerFactory.js'; import { AnonymousTask, Task } from './Task.js'; export class TaskQueue { diff --git a/server/src/tasks/UpdateXmlTvTask.ts b/server/src/tasks/UpdateXmlTvTask.ts index 3b3bc57d..b38b0e49 100644 --- a/server/src/tasks/UpdateXmlTvTask.ts +++ b/server/src/tasks/UpdateXmlTvTask.ts @@ -1,18 +1,18 @@ +import { ChannelDB } from '@/db/ChannelDB.ts'; +import { SettingsDB, defaultXmlTvSettings } from '@/db/SettingsDB.ts'; +import { MediaSourceDB } from '@/db/mediaSourceDB.ts'; +import { PlexApiClient } from '@/external/plex/PlexApiClient.js'; +import { globalOptions } from '@/globals.js'; +import { ServerContext } from '@/serverContext.js'; +import { TVGuideService } from '@/services/TvGuideService.ts'; +import { LineupCreator } from '@/services/dynamic_channels/LineupCreator.js'; +import { Maybe } from '@/types/util.js'; +import { fileExists } from '@/util/fsUtil.js'; +import { mapAsyncSeq } from '@/util/index.js'; +import { LoggerFactory } from '@/util/logging/LoggerFactory.js'; import type { Tag } from '@tunarr/types'; import { PlexDvr } from '@tunarr/types/plex'; import dayjs from 'dayjs'; -import { ChannelDB } from '../dao/channelDb.js'; -import { MediaSourceDB } from '../dao/mediaSourceDB.js'; -import { SettingsDB, defaultXmlTvSettings } from '../dao/settings.js'; -import { PlexApiClient } from '../external/plex/PlexApiClient.js'; -import { globalOptions } from '../globals.js'; -import { ServerContext } from '../serverContext.js'; -import { LineupCreator } from '../services/dynamic_channels/LineupCreator.js'; -import { TVGuideService } from '../services/tvGuideService.js'; -import { Maybe } from '../types/util.js'; -import { fileExists } from '../util/fsUtil.js'; -import { mapAsyncSeq } from '../util/index.js'; -import { LoggerFactory } from '../util/logging/LoggerFactory.js'; import { Task } from './Task.js'; export class UpdateXmlTvTask extends Task { diff --git a/server/src/tasks/fixers/BackfillProgramExternalIds.ts b/server/src/tasks/fixers/BackfillProgramExternalIds.ts index dae524c2..1a5700e4 100644 --- a/server/src/tasks/fixers/BackfillProgramExternalIds.ts +++ b/server/src/tasks/fixers/BackfillProgramExternalIds.ts @@ -1,3 +1,16 @@ +import { getDatabase } from '@/db/DBAccess.ts'; +import { ProgramExternalIdType } from '@/db/custom_types/ProgramExternalIdType.ts'; +import { ProgramSourceType } from '@/db/custom_types/ProgramSourceType.ts'; +import { upsertRawProgramExternalIds } from '@/db/programExternalIdHelpers.ts'; +import { withProgramExternalIds } from '@/db/programQueryHelpers.ts'; +import { ProgramDao } from '@/db/schema/Program.ts'; +import { NewProgramExternalId } from '@/db/schema/ProgramExternalId.ts'; +import { isQueryError } from '@/external/BaseApiClient.js'; +import { MediaSourceApiFactory } from '@/external/MediaSourceApiFactory.ts'; +import { PlexApiClient } from '@/external/plex/PlexApiClient.js'; +import { Maybe } from '@/types/util.js'; +import { asyncPool } from '@/util/asyncPool.js'; +import { LoggerFactory } from '@/util/logging/LoggerFactory.js'; import { PlexTerminalMedia } from '@tunarr/types/plex'; import dayjs from 'dayjs'; import { @@ -12,18 +25,6 @@ import { trimEnd, } from 'lodash-es'; import { v4 } from 'uuid'; -import { ProgramExternalIdType } from '../../dao/custom_types/ProgramExternalIdType.ts'; -import { ProgramSourceType } from '../../dao/custom_types/ProgramSourceType.js'; -import { directDbAccess } from '../../dao/direct/directDbAccess.ts'; -import { withProgramExternalIds } from '../../dao/direct/programQueryHelpers.ts'; -import { Program } from '../../dao/direct/schema/Program.ts'; -import { NewProgramExternalId } from '../../dao/direct/schema/ProgramExternalId.ts'; -import { upsertRawProgramExternalIds } from '../../dao/programExternalIdHelpers.ts'; -import { isQueryError } from '../../external/BaseApiClient.js'; -import { MediaSourceApiFactory } from '../../external/MediaSourceApiFactory.ts'; -import { PlexApiClient } from '../../external/plex/PlexApiClient.js'; -import { Maybe } from '../../types/util.js'; -import { asyncPool } from '../../util/asyncPool.js'; import { attempt, attemptSync, @@ -31,7 +32,6 @@ import { isNonEmptyString, wait, } from '../../util/index.js'; -import { LoggerFactory } from '../../util/logging/LoggerFactory.js'; import Fixer from './fixer.ts'; export class BackfillProgramExternalIds extends Fixer { @@ -44,7 +44,7 @@ export class BackfillProgramExternalIds extends Fixer { async runInternal(): Promise { const getNextPage = (offset?: string) => { - return directDbAccess() + return getDatabase() .selectFrom('program') .selectAll() .select(withProgramExternalIds) @@ -85,7 +85,7 @@ export class BackfillProgramExternalIds extends Fixer { keys(plexConnections), ); - const serverSettings = await directDbAccess() + const serverSettings = await getDatabase() .selectFrom('mediaSource') .selectAll() .where('name', 'in', missingServers) @@ -133,7 +133,7 @@ export class BackfillProgramExternalIds extends Fixer { } } - private async handleProgram(program: Program, plex: Maybe) { + private async handleProgram(program: ProgramDao, plex: Maybe) { if (isUndefined(plex)) { throw new Error( 'No Plex server connection found for server ' + diff --git a/server/src/tasks/fixers/addPlexServerIds.ts b/server/src/tasks/fixers/addPlexServerIds.ts index bd92e319..5f0bdfbf 100644 --- a/server/src/tasks/fixers/addPlexServerIds.ts +++ b/server/src/tasks/fixers/addPlexServerIds.ts @@ -1,12 +1,12 @@ +import { getDatabase } from '@/db/DBAccess.ts'; +import { MediaSourceType } from '@/db/schema/MediaSource.ts'; +import { PlexApiClient } from '@/external/plex/PlexApiClient.js'; import { find, isNil } from 'lodash-es'; -import { directDbAccess } from '../../dao/direct/directDbAccess.js'; -import { MediaSourceType } from '../../dao/direct/schema/MediaSource.ts'; -import { PlexApiClient } from '../../external/plex/PlexApiClient.js'; import Fixer from './fixer.js'; export class AddPlexServerIdsFixer extends Fixer { async runInternal(): Promise { - const plexServers = await directDbAccess() + const plexServers = await getDatabase() .selectFrom('mediaSource') .selectAll() .where('clientIdentifier', 'is', null) @@ -21,7 +21,7 @@ export class AddPlexServerIdsFixer extends Fixer { (d) => d.provides.includes('server') && d.name === server.name, ); if (matchingServer) { - await directDbAccess() + await getDatabase() .updateTable('mediaSource') .set({ clientIdentifier: matchingServer.clientIdentifier, diff --git a/server/src/tasks/fixers/backfillProgramGroupings.ts b/server/src/tasks/fixers/backfillProgramGroupings.ts index 0fc59f2b..4cbe85b1 100644 --- a/server/src/tasks/fixers/backfillProgramGroupings.ts +++ b/server/src/tasks/fixers/backfillProgramGroupings.ts @@ -1,7 +1,7 @@ -import { directDbAccess } from '../../dao/direct/directDbAccess.js'; -import { ProgramType } from '../../dao/direct/schema/Program.ts'; -import { ProgramGroupingType } from '../../dao/direct/schema/ProgramGrouping.ts'; -import { LoggerFactory } from '../../util/logging/LoggerFactory.ts'; +import { getDatabase } from '@/db/DBAccess.ts'; +import { ProgramType } from '@/db/schema/Program.ts'; +import { ProgramGroupingType } from '@/db/schema/ProgramGrouping.ts'; +import { LoggerFactory } from '@/util/logging/LoggerFactory.ts'; import Fixer from './fixer.ts'; // TODO: Handle Jellyfin items @@ -16,7 +16,7 @@ export class BackfillProgramGroupings extends Fixer { // This clears out mismatches that might have happened on bugged earlier versions // There was a bug where we were setting the season ID to the show ID. // This should only affect seasons since the music album stuff had the fix - const clearedSeasons = await directDbAccess() + const clearedSeasons = await getDatabase() .transaction() .execute((tx) => tx @@ -44,7 +44,7 @@ export class BackfillProgramGroupings extends Fixer { ); // Update program -> show mappings with existing information - const updatedShows = await directDbAccess() + const updatedShows = await getDatabase() .transaction() .execute((tx) => tx @@ -91,7 +91,7 @@ export class BackfillProgramGroupings extends Fixer { ); // Update track -> artist mappings with existing information - const updatedTrackArtists = await directDbAccess() + const updatedTrackArtists = await getDatabase() .transaction() .execute((tx) => tx @@ -138,7 +138,7 @@ export class BackfillProgramGroupings extends Fixer { ); // Update show -> season mappings with existing information - await directDbAccess() + await getDatabase() .transaction() .execute(async (tx) => { const updatedSeasons = await tx @@ -227,7 +227,7 @@ export class BackfillProgramGroupings extends Fixer { }); // Update track -> album mappings with existing information - await directDbAccess() + await getDatabase() .transaction() .execute(async (tx) => { const updatedTracks = await tx @@ -314,7 +314,7 @@ export class BackfillProgramGroupings extends Fixer { ); }); - const stillMissing = await directDbAccess() + const stillMissing = await getDatabase() .selectFrom('program') .select(({ fn }) => fn.count('program.uuid').as('count')) .where((eb) => diff --git a/server/src/tasks/fixers/fixer.ts b/server/src/tasks/fixers/fixer.ts index 5eb93967..03eb7725 100644 --- a/server/src/tasks/fixers/fixer.ts +++ b/server/src/tasks/fixers/fixer.ts @@ -1,4 +1,4 @@ -import { RootLogger } from '../../util/logging/LoggerFactory.js'; +import { RootLogger } from '@/util/logging/LoggerFactory.js'; export default abstract class Fixer { // False if the fixed data isn't required for proper server functioning diff --git a/server/src/tasks/fixers/index.ts b/server/src/tasks/fixers/index.ts index f4939cb8..171fb4c0 100644 --- a/server/src/tasks/fixers/index.ts +++ b/server/src/tasks/fixers/index.ts @@ -1,6 +1,6 @@ +import { groupByUniq } from '@/util/index.js'; +import { LoggerFactory } from '@/util/logging/LoggerFactory.js'; import { round } from 'lodash-es'; -import { groupByUniq } from '../../util/index.js'; -import { LoggerFactory } from '../../util/logging/LoggerFactory.js'; import { BackfillProgramExternalIds } from './BackfillProgramExternalIds.js'; import { AddPlexServerIdsFixer } from './addPlexServerIds.js'; import { BackfillProgramGroupings } from './backfillProgramGroupings.js'; diff --git a/server/src/tasks/fixers/missingSeasonNumbersFixer.ts b/server/src/tasks/fixers/missingSeasonNumbersFixer.ts index ac7e2513..2b97528b 100644 --- a/server/src/tasks/fixers/missingSeasonNumbersFixer.ts +++ b/server/src/tasks/fixers/missingSeasonNumbersFixer.ts @@ -1,3 +1,14 @@ +import { getDatabase } from '@/db/DBAccess.ts'; +import { ProgramExternalIdType } from '@/db/custom_types/ProgramExternalIdType.ts'; +import { withProgramGroupingExternalIds } from '@/db/programQueryHelpers.ts'; +import { MediaSourceType } from '@/db/schema/MediaSource.ts'; +import { ProgramGroupingType } from '@/db/schema/ProgramGrouping.ts'; +import { DB } from '@/db/schema/db.ts'; +import { MediaSourceApiFactory } from '@/external/MediaSourceApiFactory.js'; +import { PlexApiClient } from '@/external/plex/PlexApiClient.js'; +import { Maybe } from '@/types/util.js'; +import { groupByUniqPropAndMap, wait } from '@/util/index.js'; +import { LoggerFactory } from '@/util/logging/LoggerFactory.js'; import { PlexEpisodeView, PlexSeasonView } from '@tunarr/types/plex'; import { CaseWhenBuilder } from 'kysely'; import { @@ -16,21 +27,10 @@ import { pickBy, reduce, } from 'lodash-es'; -import { ProgramExternalIdType } from '../../dao/custom_types/ProgramExternalIdType.js'; -import { directDbAccess } from '../../dao/direct/directDbAccess.js'; -import { withProgramGroupingExternalIds } from '../../dao/direct/programQueryHelpers.js'; -import { MediaSourceType } from '../../dao/direct/schema/MediaSource.ts'; import { ProgramType, - Program as RawProgram, -} from '../../dao/direct/schema/Program.js'; -import { ProgramGroupingType } from '../../dao/direct/schema/ProgramGrouping.ts'; -import { DB } from '../../dao/direct/schema/db.js'; -import { MediaSourceApiFactory } from '../../external/MediaSourceApiFactory.js'; -import { PlexApiClient } from '../../external/plex/PlexApiClient.js'; -import { Maybe } from '../../types/util.js'; -import { groupByUniqPropAndMap, wait } from '../../util/index.js'; -import { LoggerFactory } from '../../util/logging/LoggerFactory.js'; + ProgramDao as RawProgram, +} from '../../db/schema/Program.ts'; import Fixer from './fixer.js'; export class MissingSeasonNumbersFixer extends Fixer { @@ -42,7 +42,7 @@ export class MissingSeasonNumbersFixer extends Fixer { canRunInBackground: boolean = true; async runInternal(): Promise { - const allPlexServers = await directDbAccess() + const allPlexServers = await getDatabase() .selectFrom('mediaSource') .where('mediaSource.type', '=', MediaSourceType.Plex) .selectAll() @@ -61,7 +61,7 @@ export class MissingSeasonNumbersFixer extends Fixer { const updatedPrograms: RawProgram[] = []; let lastId: Maybe = undefined; do { - const items: RawProgram[] = await directDbAccess() + const items: RawProgram[] = await getDatabase() .selectFrom('program') .selectAll() .$if(!isNull(lastId), (eb) => eb.where('uuid', '>', lastId!)) @@ -161,7 +161,7 @@ export class MissingSeasonNumbersFixer extends Fixer { groupByUniqPropAndMap(updateChunk, 'uuid', (p) => p.seasonNumber), isNull, ); - await directDbAccess() + await getDatabase() .updateTable('program') .set((eb) => ({ seasonNumber: reduce( @@ -183,7 +183,7 @@ export class MissingSeasonNumbersFixer extends Fixer { .executeTakeFirst(); } - const seasonsMissingIndexes = await directDbAccess() + const seasonsMissingIndexes = await getDatabase() .selectFrom('programGrouping') .select('programGrouping.uuid') .where('programGrouping.type', '=', ProgramGroupingType.Show) @@ -227,7 +227,7 @@ export class MissingSeasonNumbersFixer extends Fixer { } const plexSeason = first(plexResult.Metadata)!; - await directDbAccess() + await getDatabase() .updateTable('programGrouping') .set({ index: plexSeason.index }) .where('uuid', '=', season.uuid) diff --git a/server/src/tasks/jellyfin/SaveJellyfinProgramExternalIdsTask.ts b/server/src/tasks/jellyfin/SaveJellyfinProgramExternalIdsTask.ts index e8ca9d72..2a6ae4fb 100644 --- a/server/src/tasks/jellyfin/SaveJellyfinProgramExternalIdsTask.ts +++ b/server/src/tasks/jellyfin/SaveJellyfinProgramExternalIdsTask.ts @@ -1,22 +1,22 @@ +import { ProgramDB } from '@/db/ProgramDB.ts'; +import { upsertRawProgramExternalIds } from '@/db/programExternalIdHelpers.ts'; +import { isQueryError } from '@/external/BaseApiClient.js'; +import { MediaSourceApiFactory } from '@/external/MediaSourceApiFactory.js'; +import { JellyfinApiClient } from '@/external/jellyfin/JellyfinApiClient.js'; +import { Task } from '@/tasks/Task.js'; +import { Maybe } from '@/types/util.js'; +import { isDefined, isNonEmptyString } from '@/util/index.js'; import dayjs from 'dayjs'; import { compact, isEmpty, isUndefined, map } from 'lodash-es'; import { v4 } from 'uuid'; import { ProgramExternalIdType, programExternalIdTypeFromJellyfinProvider, -} from '../../dao/custom_types/ProgramExternalIdType.js'; +} from '../../db/custom_types/ProgramExternalIdType.ts'; import { NewProgramExternalId, ProgramExternalId, -} from '../../dao/direct/schema/ProgramExternalId.js'; -import { ProgramDB } from '../../dao/programDB.js'; -import { upsertRawProgramExternalIds } from '../../dao/programExternalIdHelpers.js'; -import { isQueryError } from '../../external/BaseApiClient.js'; -import { MediaSourceApiFactory } from '../../external/MediaSourceApiFactory.js'; -import { JellyfinApiClient } from '../../external/jellyfin/JellyfinApiClient.js'; -import { Maybe } from '../../types/util.js'; -import { isDefined, isNonEmptyString } from '../../util/index.js'; -import { Task } from '../Task.js'; +} from '../../db/schema/ProgramExternalId.ts'; export class SaveJellyfinProgramExternalIdsTask extends Task { ID = SaveJellyfinProgramExternalIdsTask.name; diff --git a/server/src/tasks/jellyfin/UpdateJellyfinPlayStatusTask.ts b/server/src/tasks/jellyfin/UpdateJellyfinPlayStatusTask.ts index 5fadf88f..09a4982f 100644 --- a/server/src/tasks/jellyfin/UpdateJellyfinPlayStatusTask.ts +++ b/server/src/tasks/jellyfin/UpdateJellyfinPlayStatusTask.ts @@ -1,12 +1,12 @@ +import { MediaSource } from '@/db/schema/MediaSource.ts'; +import { MediaSourceApiFactory } from '@/external/MediaSourceApiFactory.ts'; +import { GlobalScheduler } from '@/services/Scheduler.ts'; +import { ScheduledTask } from '@/tasks/ScheduledTask.ts'; +import { Task } from '@/tasks/Task.ts'; +import { run } from '@/util/index.ts'; import dayjs from 'dayjs'; import { RecurrenceRule } from 'node-schedule'; import { v4 } from 'uuid'; -import { MediaSource } from '../../dao/direct/schema/MediaSource.ts'; -import { MediaSourceApiFactory } from '../../external/MediaSourceApiFactory.ts'; -import { GlobalScheduler } from '../../services/scheduler.ts'; -import { run } from '../../util/index.ts'; -import { ScheduledTask } from '../ScheduledTask.ts'; -import { Task } from '../Task.ts'; type UpdateJellyfinPlayStatusScheduleRequest = { first: boolean; diff --git a/server/src/tasks/plex/SavePlexProgramExternalIdsTask.ts b/server/src/tasks/plex/SavePlexProgramExternalIdsTask.ts index 46fac7e3..1c3c6f29 100644 --- a/server/src/tasks/plex/SavePlexProgramExternalIdsTask.ts +++ b/server/src/tasks/plex/SavePlexProgramExternalIdsTask.ts @@ -1,16 +1,16 @@ +import { ProgramDB } from '@/db/ProgramDB.ts'; +import { ProgramExternalIdType } from '@/db/custom_types/ProgramExternalIdType.ts'; +import { upsertRawProgramExternalIds } from '@/db/programExternalIdHelpers.ts'; +import { ProgramExternalId } from '@/db/schema/ProgramExternalId.ts'; +import { isQueryError } from '@/external/BaseApiClient.js'; +import { MediaSourceApiFactory } from '@/external/MediaSourceApiFactory.js'; +import { PlexApiClient } from '@/external/plex/PlexApiClient.js'; +import { Task } from '@/tasks/Task.ts'; +import { Maybe } from '@/types/util.js'; +import { mintExternalIdForPlexGuid } from '@/util/externalIds.js'; +import { isDefined, isNonEmptyString } from '@/util/index.js'; import { PlexTerminalMedia } from '@tunarr/types/plex'; import { compact, isEmpty, isNil, isUndefined, map } from 'lodash-es'; -import { ProgramExternalIdType } from '../../dao/custom_types/ProgramExternalIdType.js'; -import { ProgramExternalId } from '../../dao/direct/schema/ProgramExternalId.js'; -import { ProgramDB } from '../../dao/programDB.js'; -import { upsertRawProgramExternalIds } from '../../dao/programExternalIdHelpers.js'; -import { isQueryError } from '../../external/BaseApiClient.js'; -import { MediaSourceApiFactory } from '../../external/MediaSourceApiFactory.js'; -import { PlexApiClient } from '../../external/plex/PlexApiClient.js'; -import { Maybe } from '../../types/util.js'; -import { mintExternalIdForPlexGuid } from '../../util/externalIds.js'; -import { isDefined, isNonEmptyString } from '../../util/index.js'; -import { Task } from '../Task.js'; export class SavePlexProgramExternalIdsTask extends Task { ID = SavePlexProgramExternalIdsTask.name; diff --git a/server/src/tasks/plex/UpdatePlexPlayStatusTask.ts b/server/src/tasks/plex/UpdatePlexPlayStatusTask.ts index 1777268e..cb2b6b3f 100644 --- a/server/src/tasks/plex/UpdatePlexPlayStatusTask.ts +++ b/server/src/tasks/plex/UpdatePlexPlayStatusTask.ts @@ -1,12 +1,12 @@ +import type { MediaSource } from '@/db/schema/MediaSource.ts'; +import { MediaSourceApiFactory } from '@/external/MediaSourceApiFactory.ts'; +import { GlobalScheduler } from '@/services/Scheduler.ts'; +import { ScheduledTask } from '@/tasks/ScheduledTask.ts'; +import { Task } from '@/tasks/Task.ts'; +import { run } from '@/util/index.ts'; import dayjs from 'dayjs'; import { RecurrenceRule } from 'node-schedule'; import { v4 } from 'uuid'; -import type { MediaSource } from '../../dao/direct/schema/MediaSource.d.ts'; -import { MediaSourceApiFactory } from '../../external/MediaSourceApiFactory.ts'; -import { GlobalScheduler } from '../../services/scheduler.ts'; -import { run } from '../../util/index.ts'; -import { ScheduledTask } from '../ScheduledTask.ts'; -import { Task } from '../Task.ts'; type UpdatePlexPlayStatusScheduleRequest = { ratingKey: string; diff --git a/server/src/testing/getFakeSettingsDb.ts b/server/src/testing/getFakeSettingsDb.ts index 881c6a52..8d4e0a22 100644 --- a/server/src/testing/getFakeSettingsDb.ts +++ b/server/src/testing/getFakeSettingsDb.ts @@ -1,7 +1,7 @@ +import { SettingsFile, getSettings } from '@/db/SettingsDB.ts'; +import { GlobalOptions, globalOptions, setGlobalOptions } from '@/globals.js'; import tmp from 'tmp'; import { DeepPartial } from 'ts-essentials'; -import { SettingsFile, getSettings } from '../dao/settings.js'; -import { GlobalOptions, globalOptions, setGlobalOptions } from '../globals.js'; function createTmpDir(tmpOpts?: tmp.DirOptions) { return new Promise((resolve, reject) => { diff --git a/server/src/types/fastify.d.ts b/server/src/types/fastify.d.ts index 1ca549bf..c71493fe 100644 --- a/server/src/types/fastify.d.ts +++ b/server/src/types/fastify.d.ts @@ -1,6 +1,6 @@ +import { ServerContext } from '@/serverContext.ts'; +import { ExtraLogLevels, LogLevels } from '@/util/logging/LoggerFactory.js'; import { LevelWithSilent } from 'pino'; -import { ServerContext } from '../serverContext.ts'; -import { ExtraLogLevels, LogLevels } from '../util/logging/LoggerFactory.js'; declare module 'fastify' { interface FastifyRequest { diff --git a/server/src/types/internal.ts b/server/src/types/internal.ts index ac7aa03c..f5791d17 100644 --- a/server/src/types/internal.ts +++ b/server/src/types/internal.ts @@ -1,5 +1,5 @@ -import { Lineup } from '../dao/derived_types/Lineup.js'; -import { ChannelWithRelations } from '../dao/direct/derivedTypes.js'; +import { Lineup } from '@/db/derived_types/Lineup.ts'; +import { ChannelWithRelations } from '@/db/schema/derivedTypes.js'; export type ChannelAndLineup = { channel: ChannelWithRelations; diff --git a/server/src/dao/databaseDirectoryUtil.ts b/server/src/util/databaseDirectoryUtil.ts similarity index 75% rename from server/src/dao/databaseDirectoryUtil.ts rename to server/src/util/databaseDirectoryUtil.ts index 496eb730..bdc46ff9 100644 --- a/server/src/dao/databaseDirectoryUtil.ts +++ b/server/src/util/databaseDirectoryUtil.ts @@ -1,5 +1,5 @@ +import { globalOptions } from '@/globals.ts'; import path from 'node:path'; -import { globalOptions } from '../globals.ts'; export function getDatabasePath(dbPath: string) { return path.join(globalOptions().databaseDirectory, dbPath); diff --git a/server/src/util/defaults.ts b/server/src/util/defaults.ts index 8a23d92d..b0552820 100644 --- a/server/src/util/defaults.ts +++ b/server/src/util/defaults.ts @@ -1,7 +1,7 @@ +import { Nullable } from '@/types/util.js'; import constants from '@tunarr/shared/constants'; import { isNull, isUndefined } from 'lodash-es'; import path from 'node:path'; -import { Nullable } from '../types/util.js'; import { DATABASE_LOCATION_ENV_VAR, SERVER_PORT_ENV_VAR } from './constants.js'; import { isNonEmptyString, isProduction } from './index.js'; import { isDocker } from './isDocker.js'; diff --git a/server/src/util/externalIds.ts b/server/src/util/externalIds.ts index 99697f80..b7ae5d94 100644 --- a/server/src/util/externalIds.ts +++ b/server/src/util/externalIds.ts @@ -1,11 +1,11 @@ +import { programExternalIdTypeFromExternalIdType } from '@/db/custom_types/ProgramExternalIdType.ts'; +import { NewProgramExternalId } from '@/db/schema/ProgramExternalId.ts'; +import { Nullable } from '@/types/util.js'; import { MultiExternalId } from '@tunarr/types'; import { isValidSingleExternalIdType } from '@tunarr/types/schemas'; import dayjs from 'dayjs'; import { isError, trimEnd, trimStart } from 'lodash-es'; import { v4 } from 'uuid'; -import { programExternalIdTypeFromExternalIdType } from '../dao/custom_types/ProgramExternalIdType.js'; -import { NewProgramExternalId } from '../dao/direct/schema/ProgramExternalId.js'; -import { Nullable } from '../types/util.js'; import { attemptSync } from './index.js'; import { LoggerFactory } from './logging/LoggerFactory.ts'; diff --git a/server/src/util/index.ts b/server/src/util/index.ts index 96682f98..0e6157c4 100644 --- a/server/src/util/index.ts +++ b/server/src/util/index.ts @@ -1,3 +1,5 @@ +import { Func } from '@/types/func.ts'; +import { Try } from '@/types/util.ts'; import dayjs from 'dayjs'; import duration, { Duration } from 'dayjs/plugin/duration.js'; import { @@ -28,8 +30,6 @@ import fs from 'node:fs/promises'; import { fileURLToPath } from 'node:url'; import { format } from 'node:util'; import { isPromise } from 'node:util/types'; -import { Func } from '../types/func.ts'; -import { Try } from '../types/util.ts'; dayjs.extend(duration); diff --git a/server/src/util/logging/LoggerFactory.ts b/server/src/util/logging/LoggerFactory.ts index 24dedf9d..1d370d9f 100644 --- a/server/src/util/logging/LoggerFactory.ts +++ b/server/src/util/logging/LoggerFactory.ts @@ -1,3 +1,7 @@ +import { SettingsDB, getSettings } from '@/db/SettingsDB.ts'; +import { Maybe, TupleToUnion } from '@/types/util.ts'; +import { getDefaultLogLevel } from '@/util/defaults.ts'; +import { isNonEmptyString, isProduction } from '@/util/index.ts'; import { forEach, isEmpty, @@ -20,10 +24,6 @@ import { } from 'pino'; import pretty, { PrettyOptions } from 'pino-pretty'; import type ThreadStream from 'thread-stream'; -import { SettingsDB, getSettings } from '../../dao/settings.ts'; -import { Maybe, TupleToUnion } from '../../types/util.ts'; -import { getDefaultLogLevel } from '../defaults.ts'; -import { isNonEmptyString, isProduction } from '../index.ts'; export const LogConfigEnvVars = { level: 'LOG_LEVEL', diff --git a/server/src/util/schedulingUtil.ts b/server/src/util/schedulingUtil.ts index acb67675..ad9ca5e9 100644 --- a/server/src/util/schedulingUtil.ts +++ b/server/src/util/schedulingUtil.ts @@ -1,3 +1,4 @@ +import { TupleToUnion } from '@/types/util.ts'; import { EverySchedule } from '@tunarr/types/schemas'; import parser, { CronFields, @@ -9,7 +10,6 @@ import CronExpression from 'cron-parser/lib/expression'; import dayjs from 'dayjs'; import duration from 'dayjs/plugin/duration.js'; import { range, reduce } from 'lodash-es'; -import { TupleToUnion } from '../types/util.ts'; import { run } from './index.ts'; dayjs.extend(duration); diff --git a/server/src/util/serverUtil.ts b/server/src/util/serverUtil.ts index a1b93dd7..c11ca89d 100644 --- a/server/src/util/serverUtil.ts +++ b/server/src/util/serverUtil.ts @@ -1,7 +1,7 @@ +import { FfmpegPlaylistQuery } from '@/api/videoApi.js'; +import { serverOptions } from '@/globals.js'; import { isEmpty, isNil, omitBy } from 'lodash-es'; import querystring, { ParsedUrlQueryInput } from 'node:querystring'; -import { FfmpegPlaylistQuery } from '../api/videoApi.js'; -import { serverOptions } from '../globals.js'; export function makeLocalUrl( path: string, diff --git a/server/src/dao/sqliteUtil.ts b/server/src/util/sqliteUtil.ts similarity index 100% rename from server/src/dao/sqliteUtil.ts rename to server/src/util/sqliteUtil.ts diff --git a/server/src/services/throttle.ts b/server/src/util/throttle.ts similarity index 100% rename from server/src/services/throttle.ts rename to server/src/util/throttle.ts diff --git a/server/tests/vitest.d.ts b/server/tests/vitest.d.ts index dfb05278..4cf6822c 100644 --- a/server/tests/vitest.d.ts +++ b/server/tests/vitest.d.ts @@ -1,4 +1,4 @@ -import { Channel } from '../src/dao/entities/Channel.js'; +import { Channel } from '../src/db/entities/Channel.ts'; interface CustomMatchers { toMatchChannel: (channel: Channel) => R; diff --git a/server/tsconfig.json b/server/tsconfig.json index 00dce18b..7732a19b 100644 --- a/server/tsconfig.json +++ b/server/tsconfig.json @@ -33,7 +33,12 @@ "noEmit": true, "emitDecoratorMetadata": true, "esModuleInterop": true, - "noErrorTruncation": true + "noErrorTruncation": true, + "paths": { + "@/*": [ + "./src/*" + ] + } }, "include": [ "./src/**/*.ts",