brunner56's picture
implement app
0bfe2e3
import {
AddonDetail,
ErrorStream,
ParseResult,
StreamRequest,
} from '@aiostreams/types';
import { ParsedStream, Stream, Config } from '@aiostreams/types';
import { BaseWrapper } from './base';
import { addonDetails, createLogger } from '@aiostreams/utils';
import { Settings } from '@aiostreams/utils';
const logger = createLogger('wrappers');
// name, title, url
export class OrionStremioAddon extends BaseWrapper {
constructor(
configString: string | null,
overrideUrl: string | null,
addonName: string = 'Orion',
addonId: string,
userConfig: Config,
indexerTimeout?: number
) {
let url = overrideUrl
? overrideUrl
: Settings.ORION_STREMIO_ADDON_URL +
(configString ? configString + '/' : '');
super(
addonName,
url,
addonId,
userConfig,
indexerTimeout || Settings.DEFAULT_ORION_TIMEOUT,
Settings.DEFAULT_ORION_USER_AGENT
? { 'User-Agent': Settings.DEFAULT_ORION_USER_AGENT }
: undefined
);
}
protected parseStream(stream: Stream): ParseResult {
if (stream.title?.includes('ERROR')) {
return {
type: 'error',
result: stream.title,
};
}
return super.parseStream(stream);
}
}
function getOrionConfigString(
orionApiKey: string,
linkLimit: string = '10',
showTorrents: string = 'false',
debridServices: string[]
) {
return Buffer.from(
JSON.stringify({
api: orionApiKey,
linkLimit: linkLimit,
sortValue: 'best',
audiochannels: '1,2,6,8',
videoquality:
'hd8k,hd6k,hd4k,hd2k,hd1080,hd720,sd,scr1080,scr720,scr,cam1080,cam720,cam',
listOpt:
debridServices.length > 0
? showTorrents === 'true'
? 'both'
: 'debrid'
: 'torrent',
debridservices: debridServices,
audiolanguages: [],
additionalParameters: '',
})
).toString('base64');
}
export async function getOrionStreams(
config: Config,
orionOptions: {
orionApiKey?: string;
showTorrents?: string;
linkLimit?: string;
overrideUrl?: string;
indexerTimeout?: string;
overrideName?: string;
},
streamRequest: StreamRequest,
addonId: string
): Promise<{ addonStreams: ParsedStream[]; addonErrors: string[] }> {
const orionServiceConfig = config.services.find(
(service) => service.id === 'orion'
);
// orion api key can either be in deprecated orionApiKey or in the new orionServiceConfig
let orionApiKey =
orionOptions.orionApiKey || orionServiceConfig?.credentials.apiKey || '';
if (!orionApiKey && !orionOptions.overrideUrl) {
throw new Error('Missing Orion API key or override URL');
}
const supportedServices: string[] =
addonDetails.find(
(addon: AddonDetail) => addon.id === 'orion-stremio-addon'
)?.supportedServices || [];
const indexerTimeout = orionOptions.indexerTimeout
? parseInt(orionOptions.indexerTimeout)
: undefined;
// If overrideUrl is provided, use it to get streams and skip all other steps
if (orionOptions.overrideUrl) {
const orion = new OrionStremioAddon(
null,
orionOptions.overrideUrl,
orionOptions.overrideName,
addonId,
config,
indexerTimeout
);
return await orion.getParsedStreams(streamRequest);
}
// find all usable services
const usableServices = config.services.filter(
(service) => supportedServices.includes(service.id) && service.enabled
);
// if no usable services found, use orion without any configuration
if (usableServices.length < 1) {
const configString = getOrionConfigString(
orionApiKey,
orionOptions.linkLimit,
'true',
[]
);
const orion = new OrionStremioAddon(
configString,
null,
orionOptions.overrideName,
addonId,
config,
indexerTimeout
);
return orion.getParsedStreams(streamRequest);
}
// otherwise, pass all the services to orion
const debridServices = usableServices.map((service) => service.id);
logger.info(`Using Orion with debrid services: ${debridServices}`);
const configString = getOrionConfigString(
orionApiKey,
orionOptions.linkLimit,
orionOptions.showTorrents,
debridServices
);
const orion = new OrionStremioAddon(
configString,
null,
orionOptions.overrideName,
addonId,
config,
indexerTimeout
);
return orion.getParsedStreams(streamRequest);
}