mirror of
https://github.com/Viren070/AIOStreams.git
synced 2025-12-01 23:14:04 +01:00
refactor: simplify MediaFusion stream retrieval using encoded_user_data, avoiding the need for encrypting configurations
This commit is contained in:
@@ -1,13 +1,7 @@
|
||||
import { AddonDetail, ParseResult, StreamRequest } from '@aiostreams/types';
|
||||
import { ParsedStream, Stream, Config } from '@aiostreams/types';
|
||||
import { BaseWrapper } from './base';
|
||||
import {
|
||||
addonDetails,
|
||||
getTextHash,
|
||||
getTimeTakenSincePoint,
|
||||
Settings,
|
||||
createLogger,
|
||||
} from '@aiostreams/utils';
|
||||
import { addonDetails, Settings, createLogger } from '@aiostreams/utils';
|
||||
|
||||
const logger = createLogger('wrappers');
|
||||
|
||||
@@ -20,16 +14,19 @@ export class MediaFusion extends BaseWrapper {
|
||||
userConfig: Config,
|
||||
indexerTimeout?: number
|
||||
) {
|
||||
let url = overrideUrl
|
||||
? overrideUrl
|
||||
: Settings.MEDIAFUSION_URL + (configString ? configString + '/' : '');
|
||||
let url = overrideUrl ? overrideUrl : Settings.MEDIAFUSION_URL;
|
||||
|
||||
const headers =
|
||||
configString && !overrideUrl
|
||||
? { encoded_user_data: configString }
|
||||
: undefined;
|
||||
super(
|
||||
addonName,
|
||||
url,
|
||||
addonId,
|
||||
userConfig,
|
||||
indexerTimeout || Settings.DEFAULT_MEDIAFUSION_TIMEOUT
|
||||
indexerTimeout || Settings.DEFAULT_MEDIAFUSION_TIMEOUT,
|
||||
headers
|
||||
);
|
||||
}
|
||||
|
||||
@@ -70,40 +67,6 @@ export async function getMediafusionStreams(
|
||||
: undefined;
|
||||
const liveSearchStreams =
|
||||
mediafusionOptions.liveSearchStreams === 'true' ? true : false;
|
||||
const cache = config.instanceCache;
|
||||
|
||||
const getConfigString = async (data: any): Promise<string> => {
|
||||
const startTime = Date.now();
|
||||
const cacheKey = getTextHash(`mediafusionConfig:${JSON.stringify(data)}`);
|
||||
const cachedConfig = cache ? cache.get(cacheKey) : null;
|
||||
if (cachedConfig) {
|
||||
logger.info(`Returning cached config string`, {
|
||||
func: 'mediafusion.getConfigString',
|
||||
});
|
||||
return cachedConfig;
|
||||
}
|
||||
try {
|
||||
const encryptedStr = await _getConfigString(data);
|
||||
|
||||
logger.info(
|
||||
`Config encryption took ${getTimeTakenSincePoint(startTime)}`,
|
||||
{
|
||||
func: 'mediafusion.getConfigString',
|
||||
}
|
||||
);
|
||||
cache?.set(cacheKey, encryptedStr, Settings.CACHE_MEDIAFUSION_CONFIG_TTL);
|
||||
return encryptedStr;
|
||||
} catch (error: any) {
|
||||
if (error.name === 'TimeoutError') {
|
||||
throw new Error(
|
||||
`Config encryption timed out after ${getTimeTakenSincePoint(
|
||||
startTime
|
||||
)}`
|
||||
);
|
||||
}
|
||||
throw new Error(`Failed to get config string: ${error.message}`);
|
||||
}
|
||||
};
|
||||
|
||||
// If overrideUrl is provided, use it to get streams and skip all other steps
|
||||
if (mediafusionOptions.overrideUrl) {
|
||||
@@ -125,13 +88,12 @@ export async function getMediafusionStreams(
|
||||
|
||||
// if no usable services found, use mediafusion without debrid
|
||||
if (usableServices.length < 1) {
|
||||
const configString = await getConfigString(
|
||||
getMediaFusionConfig(
|
||||
mediafusionOptions.filterCertificationLevels,
|
||||
mediafusionOptions.filterNudity,
|
||||
liveSearchStreams
|
||||
)
|
||||
const configString = getConfigString(
|
||||
mediafusionOptions.filterCertificationLevels,
|
||||
mediafusionOptions.filterNudity,
|
||||
liveSearchStreams
|
||||
);
|
||||
|
||||
const mediafusion = new MediaFusion(
|
||||
configString,
|
||||
null,
|
||||
@@ -170,16 +132,15 @@ export async function getMediafusionStreams(
|
||||
}
|
||||
|
||||
// get the encrypted mediafusion string
|
||||
const mediafusionConfig = getMediaFusionConfig(
|
||||
const mediafusionConfig = getConfigString(
|
||||
mediafusionOptions.filterCertificationLevels,
|
||||
mediafusionOptions.filterNudity,
|
||||
liveSearchStreams,
|
||||
debridService.id,
|
||||
debridService.credentials
|
||||
);
|
||||
const encryptedStr = await getConfigString(mediafusionConfig);
|
||||
const mediafusion = new MediaFusion(
|
||||
encryptedStr,
|
||||
mediafusionConfig,
|
||||
null,
|
||||
mediafusionOptions.overrideName,
|
||||
addonId,
|
||||
@@ -197,30 +158,18 @@ export async function getMediafusionStreams(
|
||||
throw new Error(`No enabled services found for MediaFusion`);
|
||||
}
|
||||
const promises = servicesToUse.map(async (service) => {
|
||||
const mediafusionConfig = getMediaFusionConfig(
|
||||
logger.info(`Getting MediaFusion streams for ${service.id}`, {
|
||||
func: 'mediafusion',
|
||||
});
|
||||
const encodedConfigString = getConfigString(
|
||||
mediafusionOptions.filterCertificationLevels,
|
||||
mediafusionOptions.filterNudity,
|
||||
liveSearchStreams,
|
||||
service.id,
|
||||
service.credentials
|
||||
);
|
||||
logger.info(`Getting MediaFusion streams for ${service.id}`, {
|
||||
func: 'mediafusion',
|
||||
});
|
||||
let encryptedStr: string = '';
|
||||
try {
|
||||
encryptedStr = await getConfigString(mediafusionConfig);
|
||||
if (!encryptedStr) {
|
||||
throw new Error(
|
||||
'An unknown error occurred while getting config string'
|
||||
);
|
||||
}
|
||||
} catch (error: any) {
|
||||
logger.error(`${error.message}`, { func: 'mediafusion' });
|
||||
throw new Error(error.message);
|
||||
}
|
||||
const mediafusion = new MediaFusion(
|
||||
encryptedStr,
|
||||
encodedConfigString,
|
||||
null,
|
||||
mediafusionOptions.overrideName,
|
||||
addonId,
|
||||
@@ -246,7 +195,7 @@ export async function getMediafusionStreams(
|
||||
};
|
||||
}
|
||||
|
||||
const getMediaFusionConfig = (
|
||||
const getConfigString = (
|
||||
filterCertificationLevels?: string,
|
||||
filterNudity?: string,
|
||||
liveSearchStreams: boolean = false,
|
||||
@@ -263,116 +212,98 @@ const getMediaFusionConfig = (
|
||||
const levels = filterNudity.split(',');
|
||||
nudityFilter = levels.map((level) => level.trim());
|
||||
}
|
||||
return {
|
||||
streaming_provider: service
|
||||
? {
|
||||
token: !['pikpak'].includes(service) ? credentials.apiKey : undefined,
|
||||
email: credentials.email,
|
||||
password: credentials.password,
|
||||
service: service,
|
||||
enable_watchlists_catalogs: false,
|
||||
download_via_browser: false,
|
||||
only_show_cached_streams: false,
|
||||
}
|
||||
: null,
|
||||
selected_catalogs: [],
|
||||
selected_resolutions: [
|
||||
'4k',
|
||||
'2160p',
|
||||
'1440p',
|
||||
'1080p',
|
||||
'720p',
|
||||
'576p',
|
||||
'480p',
|
||||
'360p',
|
||||
'240p',
|
||||
null,
|
||||
],
|
||||
enable_catalogs: true,
|
||||
enable_imdb_metadata: false,
|
||||
max_size: 'inf',
|
||||
max_streams_per_resolution: '500',
|
||||
torrent_sorting_priority: [
|
||||
{ key: 'language', direction: 'desc' },
|
||||
{ key: 'cached', direction: 'desc' },
|
||||
{ key: 'resolution', direction: 'desc' },
|
||||
{ key: 'quality', direction: 'desc' },
|
||||
{ key: 'size', direction: 'desc' },
|
||||
{ key: 'seeders', direction: 'desc' },
|
||||
{ key: 'created_at', direction: 'desc' },
|
||||
],
|
||||
show_full_torrent_name: true,
|
||||
show_language_country_flag: true,
|
||||
nudity_filter: nudityFilter,
|
||||
certification_filter: certificationFilter,
|
||||
language_sorting: [
|
||||
'English',
|
||||
'Tamil',
|
||||
'Hindi',
|
||||
'Malayalam',
|
||||
'Kannada',
|
||||
'Telugu',
|
||||
'Chinese',
|
||||
'Russian',
|
||||
'Arabic',
|
||||
'Japanese',
|
||||
'Korean',
|
||||
'Taiwanese',
|
||||
'Latino',
|
||||
'French',
|
||||
'Spanish',
|
||||
'Portuguese',
|
||||
'Italian',
|
||||
'German',
|
||||
'Ukrainian',
|
||||
'Polish',
|
||||
'Czech',
|
||||
'Thai',
|
||||
'Indonesian',
|
||||
'Vietnamese',
|
||||
'Dutch',
|
||||
'Bengali',
|
||||
'Turkish',
|
||||
'Greek',
|
||||
'Swedish',
|
||||
null,
|
||||
],
|
||||
quality_filter: [
|
||||
'BluRay/UHD',
|
||||
'WEB/HD',
|
||||
'DVD/TV/SAT',
|
||||
'CAM/Screener',
|
||||
'Unknown',
|
||||
],
|
||||
api_password: Settings.MEDIAFUSION_API_PASSWORD || null,
|
||||
mediaflow_config: null,
|
||||
rpdb_config: null,
|
||||
live_search_streams: liveSearchStreams,
|
||||
contribution_streams: false,
|
||||
mdblist_config: null,
|
||||
};
|
||||
return encodeURIComponent(
|
||||
Buffer.from(
|
||||
JSON.stringify({
|
||||
streaming_provider: service
|
||||
? {
|
||||
token: !['pikpak'].includes(service)
|
||||
? credentials.apiKey
|
||||
: undefined,
|
||||
email: credentials.email,
|
||||
password: credentials.password,
|
||||
service: service,
|
||||
enable_watchlists_catalogs: false,
|
||||
download_via_browser: false,
|
||||
only_show_cached_streams: false,
|
||||
}
|
||||
: null,
|
||||
selected_catalogs: [],
|
||||
selected_resolutions: [
|
||||
'4k',
|
||||
'2160p',
|
||||
'1440p',
|
||||
'1080p',
|
||||
'720p',
|
||||
'576p',
|
||||
'480p',
|
||||
'360p',
|
||||
'240p',
|
||||
null,
|
||||
],
|
||||
enable_catalogs: true,
|
||||
enable_imdb_metadata: false,
|
||||
max_size: 'inf',
|
||||
max_streams_per_resolution: '500',
|
||||
torrent_sorting_priority: [
|
||||
{ key: 'language', direction: 'desc' },
|
||||
{ key: 'cached', direction: 'desc' },
|
||||
{ key: 'resolution', direction: 'desc' },
|
||||
{ key: 'quality', direction: 'desc' },
|
||||
{ key: 'size', direction: 'desc' },
|
||||
{ key: 'seeders', direction: 'desc' },
|
||||
{ key: 'created_at', direction: 'desc' },
|
||||
],
|
||||
show_full_torrent_name: true,
|
||||
show_language_country_flag: true,
|
||||
nudity_filter: nudityFilter,
|
||||
certification_filter: certificationFilter,
|
||||
language_sorting: [
|
||||
'English',
|
||||
'Tamil',
|
||||
'Hindi',
|
||||
'Malayalam',
|
||||
'Kannada',
|
||||
'Telugu',
|
||||
'Chinese',
|
||||
'Russian',
|
||||
'Arabic',
|
||||
'Japanese',
|
||||
'Korean',
|
||||
'Taiwanese',
|
||||
'Latino',
|
||||
'French',
|
||||
'Spanish',
|
||||
'Portuguese',
|
||||
'Italian',
|
||||
'German',
|
||||
'Ukrainian',
|
||||
'Polish',
|
||||
'Czech',
|
||||
'Thai',
|
||||
'Indonesian',
|
||||
'Vietnamese',
|
||||
'Dutch',
|
||||
'Bengali',
|
||||
'Turkish',
|
||||
'Greek',
|
||||
'Swedish',
|
||||
null,
|
||||
],
|
||||
quality_filter: [
|
||||
'BluRay/UHD',
|
||||
'WEB/HD',
|
||||
'DVD/TV/SAT',
|
||||
'CAM/Screener',
|
||||
'Unknown',
|
||||
],
|
||||
api_password: Settings.MEDIAFUSION_API_PASSWORD || null,
|
||||
mediaflow_config: null,
|
||||
rpdb_config: null,
|
||||
live_search_streams: liveSearchStreams,
|
||||
contribution_streams: false,
|
||||
mdblist_config: null,
|
||||
})
|
||||
).toString('base64')
|
||||
);
|
||||
};
|
||||
|
||||
async function _getConfigString(data: any): Promise<string> {
|
||||
const encryptUrl = `${Settings.MEDIAFUSION_URL}encrypt-user-data`;
|
||||
const response = await fetch(encryptUrl, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(data),
|
||||
signal: AbortSignal.timeout(
|
||||
Settings.MEDIAFUSION_CONFIG_TIMEOUT ||
|
||||
Settings.DEFAULT_MEDIAFUSION_TIMEOUT ||
|
||||
Settings.DEFAULT_TIMEOUT
|
||||
),
|
||||
});
|
||||
|
||||
const encryptedData = await response.json();
|
||||
if (encryptedData.status !== 'success') {
|
||||
throw new Error(
|
||||
`Config encryption failed: ${encryptedData.message || 'Unknown error'}`
|
||||
);
|
||||
}
|
||||
return encryptedData.encrypted_str;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user