mirror of
https://github.com/Viren070/AIOStreams.git
synced 2025-12-01 23:14:04 +01:00
uncommit
This commit is contained in:
@@ -359,13 +359,15 @@ export class AIOStreams {
|
||||
const initialStreams = filteredResults;
|
||||
const normaliseFilename = (filename?: string): string | undefined =>
|
||||
filename
|
||||
?.replace(
|
||||
/\.(mkv|mp4|avi|mov|wmv|flv|webm|m4v|mpg|mpeg|3gp|3g2|m2ts|ts|vob|ogv|ogm|divx|xvid|rm|rmvb|asf|mxf|mka|mks|mk3d|webm|f4v|f4p|f4a|f4b)$/i,
|
||||
''
|
||||
)
|
||||
.replace(/[^\p{L}\p{N}+]/gu, '')
|
||||
.replace(/\s+/g, '')
|
||||
.toLowerCase();
|
||||
? filename
|
||||
?.replace(
|
||||
/\.(mkv|mp4|avi|mov|wmv|flv|webm|m4v|mpg|mpeg|3gp|3g2|m2ts|ts|vob|ogv|ogm|divx|xvid|rm|rmvb|asf|mxf|mka|mks|mk3d|webm|f4v|f4p|f4a|f4b)$/i,
|
||||
''
|
||||
)
|
||||
.replace(/[^\p{L}\p{N}+]/gu, '')
|
||||
.replace(/\s+/g, '')
|
||||
.toLowerCase()
|
||||
: undefined;
|
||||
|
||||
const groupStreamsByKey = (
|
||||
streams: ParsedStream[],
|
||||
@@ -398,7 +400,13 @@ export class AIOStreams {
|
||||
);
|
||||
|
||||
logger.info(
|
||||
`Found ${Object.keys(streamsGroupedByFilename).length} unique filenames`
|
||||
`Found ${Object.keys(streamsGroupedByFilename).length} unique filenames with ${
|
||||
initialStreams.length -
|
||||
Object.values(streamsGroupedByFilename).reduce(
|
||||
(sum, group) => sum + group.length,
|
||||
0
|
||||
)
|
||||
} streams not grouped`
|
||||
);
|
||||
|
||||
// Process grouped streams by filename
|
||||
|
||||
@@ -24,7 +24,7 @@ export function torboxFormat(stream: ParsedStream): {
|
||||
|
||||
let description: string = '';
|
||||
|
||||
description += `Quality: ${stream.quality}\nName: ${stream.filename}\nSize: ${formatSize(stream.size || 0)}\nLanguage: ${stream.languages.length > 0 ? stream.languages.join(', ') : 'Unknown'}`;
|
||||
description += `Quality: ${stream.quality}\nName: ${stream.filename}\nSize: ${formatSize(stream.size || 0)}${stream.indexers ? `| Source: ${stream.indexers}` : ''}\nLanguage: ${stream.languages.length > 0 ? stream.languages.join(', ') : 'Unknown'}`;
|
||||
|
||||
let streamType = stream.torrent
|
||||
? 'Torrent'
|
||||
|
||||
@@ -229,12 +229,14 @@ export class BaseWrapper {
|
||||
indexer?: string,
|
||||
duration?: number,
|
||||
personal?: boolean,
|
||||
infoHash?: string
|
||||
infoHash?: string,
|
||||
message?: string
|
||||
): ParseResult {
|
||||
return {
|
||||
type: 'stream',
|
||||
result: {
|
||||
...parsedInfo,
|
||||
message: message,
|
||||
addon: { name: this.addonName, id: this.addonId },
|
||||
filename: filename,
|
||||
size: size,
|
||||
|
||||
@@ -15,10 +15,10 @@ const logger = createLogger('wrappers');
|
||||
interface TorboxStream extends Stream {
|
||||
name: string;
|
||||
url: string;
|
||||
hash: string;
|
||||
is_cached: boolean;
|
||||
size: number;
|
||||
description: string;
|
||||
hash?: string;
|
||||
is_cached?: boolean;
|
||||
size?: number;
|
||||
magnet?: string;
|
||||
nzb?: string;
|
||||
seeders?: number;
|
||||
@@ -28,6 +28,7 @@ interface TorboxStream extends Stream {
|
||||
language?: string;
|
||||
type?: string;
|
||||
adult?: boolean;
|
||||
user_search?: boolean;
|
||||
}
|
||||
|
||||
export class Torbox extends BaseWrapper {
|
||||
@@ -48,104 +49,47 @@ export class Torbox extends BaseWrapper {
|
||||
}
|
||||
|
||||
protected parseStream(stream: TorboxStream): ParseResult {
|
||||
let type = stream.type;
|
||||
let personal = false;
|
||||
if (stream.name.includes('Your Media')) {
|
||||
logger.debug(`${stream.name} was detected as a personal stream.`, {
|
||||
func: 'torbox',
|
||||
});
|
||||
personal = true;
|
||||
const filename =
|
||||
stream.behaviorHints?.filename ||
|
||||
stream.description.match(/Name:\s*([^\n]+)/)?.[1];
|
||||
let message = undefined;
|
||||
if (stream.description.includes('Click play to start streaming')) {
|
||||
message = stream.description;
|
||||
}
|
||||
const [dQuality, dFilename, dSize, dLanguage, dAgeOrSeeders] =
|
||||
stream.description.split('\n').map((field: string) => {
|
||||
if (field.startsWith('Type')) {
|
||||
// the last line can either contain only the type or the type and the seeders/age
|
||||
// we will always return the age or seeders and assign the type to the variable declared outside the map
|
||||
const parts = field.split('|');
|
||||
type = ['torrent', 'usenet', 'web'].includes(type || '')
|
||||
? type
|
||||
: parts[0].split(':')[1].trim().toLowerCase();
|
||||
if (parts.length > 1) {
|
||||
return parts[1].split(':')[1].trim();
|
||||
}
|
||||
// since the last line only contains the type, we will return undefined
|
||||
return undefined;
|
||||
}
|
||||
const [_, value] = field.split(':');
|
||||
return value.trim();
|
||||
});
|
||||
const filename = stream.behaviorHints?.filename || dFilename;
|
||||
const parsedFilename: ParsedNameData = parseFilename(
|
||||
filename || stream.description
|
||||
);
|
||||
|
||||
/* If the quality from Torbox is not one of the qualities in the Config, they get filtered out
|
||||
So, for now, we will not update the quality from Torbox
|
||||
We can revisit this later and match the quality from Torbox to one of the qualities in the Config
|
||||
if (parsedFilename.quality === 'Unknown' && quality !== 'Unknown') {
|
||||
parsedFilename.quality = quality;
|
||||
}
|
||||
*/
|
||||
|
||||
const language = stream.language || dLanguage;
|
||||
const normaliseLanguage = (lang: string) => {
|
||||
if (lang.toLowerCase() === 'multi audio') {
|
||||
return 'Multi';
|
||||
}
|
||||
return lang
|
||||
.split(' ')
|
||||
.map(
|
||||
(word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()
|
||||
)
|
||||
.join(' ');
|
||||
};
|
||||
if (language) {
|
||||
const normalisedLanguage = normaliseLanguage(language);
|
||||
if (
|
||||
normalisedLanguage !== 'Unknown' &&
|
||||
!parsedFilename.languages.includes(normalisedLanguage)
|
||||
) {
|
||||
parsedFilename.languages.push(normalisedLanguage);
|
||||
}
|
||||
}
|
||||
|
||||
// usenet results provide size as a string, we need to convert it to a number
|
||||
const validateBehaviorHintSize = (size: string | number | undefined) =>
|
||||
typeof size === 'string' ? parseInt(size) : size;
|
||||
const sizeInBytes =
|
||||
stream.size ||
|
||||
validateBehaviorHintSize(stream.behaviorHints?.videoSize) ||
|
||||
(dSize ? this.extractSizeInBytes(dSize, 1000) : undefined);
|
||||
|
||||
const size = stream.behaviorHints?.videoSize || stream.size;
|
||||
const seeders =
|
||||
stream.seeders && stream.seeders !== -1 ? stream.seeders : undefined;
|
||||
const age =
|
||||
stream.description.match(/\|\sAge:\s([0-9]+[dmyh])/)?.[1] || undefined;
|
||||
const source =
|
||||
stream.description.match(/Source:\s*([^\n]+)/)?.[1] || undefined;
|
||||
const infoHash =
|
||||
stream.hash ||
|
||||
stream.magnet?.match(/btih:([0-9a-fA-F]{40,})/)?.[1] ||
|
||||
undefined;
|
||||
const personal = stream.name.includes('Your Media');
|
||||
const provider = {
|
||||
id: 'torbox',
|
||||
cached: stream.is_cached,
|
||||
cached: stream.is_cached || true,
|
||||
};
|
||||
|
||||
const seeders =
|
||||
type === 'torrent'
|
||||
? stream.seeders ||
|
||||
(dAgeOrSeeders ? parseInt(dAgeOrSeeders) : undefined)
|
||||
: undefined;
|
||||
const age = type === 'usenet' ? dAgeOrSeeders || undefined : undefined;
|
||||
let infoHash = stream.hash || this.extractInfoHash(stream.url);
|
||||
if (age && infoHash) {
|
||||
// we only need the infoHash for torrents
|
||||
infoHash = undefined;
|
||||
}
|
||||
|
||||
const parsedStream: ParseResult = this.createParsedResult(
|
||||
parsedFilename,
|
||||
stream,
|
||||
filename,
|
||||
sizeInBytes,
|
||||
size,
|
||||
provider,
|
||||
seeders,
|
||||
age,
|
||||
undefined,
|
||||
source,
|
||||
undefined,
|
||||
personal,
|
||||
infoHash
|
||||
infoHash,
|
||||
message
|
||||
);
|
||||
|
||||
return parsedStream;
|
||||
|
||||
Reference in New Issue
Block a user