mirror of
https://github.com/Viren070/AIOStreams.git
synced 2025-12-01 23:14:04 +01:00
style: format code
This commit is contained in:
+36
-13
@@ -54,8 +54,12 @@ export class AIOStreams {
|
||||
this.config = config;
|
||||
// Pre-compile regex patterns if they exist
|
||||
if (this.config.regexSortPatterns) {
|
||||
const regexSortPatterns = this.config.regexSortPatterns.split(/\s+/).filter(Boolean);
|
||||
this.preCompiledRegexPatterns = regexSortPatterns.map(pattern => new RegExp(pattern));
|
||||
const regexSortPatterns = this.config.regexSortPatterns
|
||||
.split(/\s+/)
|
||||
.filter(Boolean);
|
||||
this.preCompiledRegexPatterns = regexSortPatterns.map(
|
||||
(pattern) => new RegExp(pattern)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -377,22 +381,35 @@ export class AIOStreams {
|
||||
// apply regex filters if API key is set
|
||||
if (this.config.apiKey && this.config.regexFilters) {
|
||||
const { excludePattern, includePattern } = this.config.regexFilters;
|
||||
|
||||
|
||||
if (excludePattern) {
|
||||
const regexExclude = new RegExp(excludePattern, 'i');
|
||||
if (parsedStream.filename && safeRegexTest(regexExclude, parsedStream.filename)) {
|
||||
if (
|
||||
parsedStream.filename &&
|
||||
safeRegexTest(regexExclude, parsedStream.filename)
|
||||
) {
|
||||
skipReasons.excludeRegex++;
|
||||
return false;
|
||||
}
|
||||
if (parsedStream.indexers && safeRegexTest(regexExclude, parsedStream.indexers)) {
|
||||
if (
|
||||
parsedStream.indexers &&
|
||||
safeRegexTest(regexExclude, parsedStream.indexers)
|
||||
) {
|
||||
skipReasons.excludeRegex++;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (includePattern) {
|
||||
const regexInclude = new RegExp(includePattern, 'i');
|
||||
if (!((parsedStream.filename && safeRegexTest(regexInclude, parsedStream.filename)) || (parsedStream.indexers && safeRegexTest(regexInclude, parsedStream.indexers)))) {
|
||||
if (
|
||||
!(
|
||||
(parsedStream.filename &&
|
||||
safeRegexTest(regexInclude, parsedStream.filename)) ||
|
||||
(parsedStream.indexers &&
|
||||
safeRegexTest(regexInclude, parsedStream.indexers))
|
||||
)
|
||||
) {
|
||||
skipReasons.requiredRegex++;
|
||||
return false;
|
||||
}
|
||||
@@ -677,7 +694,11 @@ export class AIOStreams {
|
||||
// Identify streams that require proxying
|
||||
const streamsToProxy = parsedStreams
|
||||
.map((stream, index) => ({ stream, index }))
|
||||
.filter(({ stream }) => stream.url && this.shouldProxyStream(stream, mediaFlowConfig, stremThruConfig));
|
||||
.filter(
|
||||
({ stream }) =>
|
||||
stream.url &&
|
||||
this.shouldProxyStream(stream, mediaFlowConfig, stremThruConfig)
|
||||
);
|
||||
|
||||
const proxiedUrls = streamsToProxy.length
|
||||
? mediaFlowConfig.mediaFlowEnabled
|
||||
@@ -795,18 +816,20 @@ export class AIOStreams {
|
||||
);
|
||||
} else if (field === 'regexSort') {
|
||||
if (!this.config.regexSortPatterns) return 0;
|
||||
|
||||
|
||||
try {
|
||||
for (let i = 0; i < this.preCompiledRegexPatterns.length; i++) {
|
||||
const regex = this.preCompiledRegexPatterns[i];
|
||||
const aMatch = a.filename ? safeRegexTest(regex, a.filename) : false;
|
||||
const bMatch = b.filename ? safeRegexTest(regex, b.filename) : false;
|
||||
|
||||
|
||||
// If both match or both don't match, continue to next pattern
|
||||
if ((aMatch && bMatch) || (!aMatch && !bMatch)) continue;
|
||||
|
||||
|
||||
// If one matches and the other doesn't, use direction to determine order
|
||||
const direction = this.config.sortBy.find((sort) => Object.keys(sort)[0] === 'regexSort')?.direction;
|
||||
const direction = this.config.sortBy.find(
|
||||
(sort) => Object.keys(sort)[0] === 'regexSort'
|
||||
)?.direction;
|
||||
if (direction === 'asc') {
|
||||
// In ascending order, matching files come last
|
||||
return aMatch ? 1 : -1;
|
||||
@@ -815,7 +838,7 @@ export class AIOStreams {
|
||||
return aMatch ? -1 : 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// If we get here, no patterns matched or all patterns matched the same way
|
||||
return 0;
|
||||
} catch (e) {
|
||||
|
||||
@@ -383,7 +383,10 @@ export function validateConfig(
|
||||
);
|
||||
}
|
||||
|
||||
if (config.mediaFlowConfig?.mediaFlowEnabled && config.stremThruConfig?.stremThruEnabled) {
|
||||
if (
|
||||
config.mediaFlowConfig?.mediaFlowEnabled &&
|
||||
config.stremThruConfig?.stremThruEnabled
|
||||
) {
|
||||
return createResponse(
|
||||
false,
|
||||
'multipleProxyServices',
|
||||
@@ -464,7 +467,7 @@ export function validateConfig(
|
||||
'Regex filtering requires an API key to be set'
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
if (config.regexFilters.excludePattern) {
|
||||
try {
|
||||
new RegExp(config.regexFilters.excludePattern);
|
||||
@@ -476,7 +479,7 @@ export function validateConfig(
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (config.regexFilters.includePattern) {
|
||||
try {
|
||||
new RegExp(config.regexFilters.includePattern);
|
||||
|
||||
@@ -9,7 +9,11 @@ const DEFAULT_TIMEOUT = 1000; // 1 second timeout
|
||||
* @param timeoutMs Optional timeout in milliseconds (default: 1000ms)
|
||||
* @returns boolean indicating if the pattern matches the string
|
||||
*/
|
||||
export function safeRegexTest(pattern: RegExp, str: string, timeoutMs: number = DEFAULT_TIMEOUT): boolean {
|
||||
export function safeRegexTest(
|
||||
pattern: RegExp,
|
||||
str: string,
|
||||
timeoutMs: number = DEFAULT_TIMEOUT
|
||||
): boolean {
|
||||
try {
|
||||
return isMatch(pattern, str, { timeout: timeoutMs });
|
||||
} catch (error) {
|
||||
@@ -25,7 +29,11 @@ export function safeRegexTest(pattern: RegExp, str: string, timeoutMs: number =
|
||||
* @param timeoutMs Optional timeout in milliseconds (default: 1000ms)
|
||||
* @returns The first match or undefined if no match or timeout
|
||||
*/
|
||||
export function safeRegexMatch(pattern: RegExp, str: string, timeoutMs: number = DEFAULT_TIMEOUT): string | undefined {
|
||||
export function safeRegexMatch(
|
||||
pattern: RegExp,
|
||||
str: string,
|
||||
timeoutMs: number = DEFAULT_TIMEOUT
|
||||
): string | undefined {
|
||||
try {
|
||||
const match = firstMatch(pattern, str, { timeout: timeoutMs });
|
||||
return match?.match;
|
||||
@@ -42,12 +50,16 @@ export function safeRegexMatch(pattern: RegExp, str: string, timeoutMs: number =
|
||||
* @param timeoutMs Optional timeout in milliseconds (default: 1000ms)
|
||||
* @returns Array of matches or empty array if no matches or timeout
|
||||
*/
|
||||
export function safeRegexMatches(pattern: RegExp, str: string, timeoutMs: number = DEFAULT_TIMEOUT): string[] {
|
||||
export function safeRegexMatches(
|
||||
pattern: RegExp,
|
||||
str: string,
|
||||
timeoutMs: number = DEFAULT_TIMEOUT
|
||||
): string[] {
|
||||
try {
|
||||
const matches = Array.from(pattern[Symbol.matchAll](str));
|
||||
return matches.map(m => m[0]);
|
||||
return matches.map((m) => m[0]);
|
||||
} catch (error) {
|
||||
console.error(`Regex matches timed out after ${timeoutMs}ms:`, error);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -302,10 +302,13 @@ export default function Configure() {
|
||||
},
|
||||
addons,
|
||||
services,
|
||||
regexFilters: (regexFilters.excludePattern || regexFilters.includePattern) ? {
|
||||
excludePattern: regexFilters.excludePattern || undefined,
|
||||
includePattern: regexFilters.includePattern || undefined
|
||||
} : undefined,
|
||||
regexFilters:
|
||||
regexFilters.excludePattern || regexFilters.includePattern
|
||||
? {
|
||||
excludePattern: regexFilters.excludePattern || undefined,
|
||||
includePattern: regexFilters.includePattern || undefined,
|
||||
}
|
||||
: undefined,
|
||||
regexSortPatterns: regexSortPatterns,
|
||||
};
|
||||
return config;
|
||||
@@ -1034,54 +1037,63 @@ export default function Configure() {
|
||||
{showApiKeyInput && (
|
||||
<div className={styles.section}>
|
||||
<div>
|
||||
<h2 style={{ padding: '5px', margin: '0px ' }}>Regex Filtering</h2>
|
||||
<h2 style={{ padding: '5px', margin: '0px ' }}>
|
||||
Regex Filtering
|
||||
</h2>
|
||||
<p style={{ margin: '5px 0 12px 5px' }}>
|
||||
Configure regex patterns to filter streams. These filters will be applied in addition to keyword filters.
|
||||
Configure regex patterns to filter streams. These filters will
|
||||
be applied in addition to keyword filters.
|
||||
</p>
|
||||
</div>
|
||||
<div style={{ marginBottom: '0px' }}>
|
||||
<div className={styles.section}>
|
||||
<h3 style={{ margin: '2px 0 2px 0' }}>Exclude Pattern</h3>
|
||||
<p style={{ margin: '10px 0 10px 0' }}>
|
||||
Enter a regex pattern to exclude streams. Streams will be excluded if their filename OR indexers match this pattern.
|
||||
Enter a regex pattern to exclude streams. Streams will be
|
||||
excluded if their filename OR indexers match this pattern.
|
||||
</p>
|
||||
<input
|
||||
type="text"
|
||||
value={regexFilters.excludePattern || ''}
|
||||
onChange={(e) => setRegexFilters({
|
||||
...regexFilters,
|
||||
excludePattern: e.target.value
|
||||
})}
|
||||
onChange={(e) =>
|
||||
setRegexFilters({
|
||||
...regexFilters,
|
||||
excludePattern: e.target.value,
|
||||
})
|
||||
}
|
||||
placeholder="Example: \b(0neshot|1XBET)\b"
|
||||
className={styles.input}
|
||||
/>
|
||||
<p className={styles.helpText}>
|
||||
Example patterns:
|
||||
<br />
|
||||
- \b(0neshot|1XBET|24xHD)\b (exclude 0neshot, 1XBET, and 24xHD releases)
|
||||
<br />
|
||||
- ^.*Hi10.*$ (exclude Hi10 profile releases)
|
||||
- \b(0neshot|1XBET|24xHD)\b (exclude 0neshot, 1XBET, and 24xHD
|
||||
releases)
|
||||
<br />- ^.*Hi10.*$ (exclude Hi10 profile releases)
|
||||
</p>
|
||||
</div>
|
||||
<div className={styles.section} style={{ marginBottom: '0px' }}>
|
||||
<h3 style={{ margin: '2px 0 2px 0' }}>Include Pattern</h3>
|
||||
<p style={{ margin: '10px 0 10px 0' }}>
|
||||
Enter a regex pattern to include streams. Only streams whose filename or indexers match this pattern will be included.
|
||||
Enter a regex pattern to include streams. Only streams whose
|
||||
filename or indexers match this pattern will be included.
|
||||
</p>
|
||||
<input
|
||||
type="text"
|
||||
value={regexFilters.includePattern || ''}
|
||||
onChange={(e) => setRegexFilters({
|
||||
...regexFilters,
|
||||
includePattern: e.target.value
|
||||
})}
|
||||
onChange={(e) =>
|
||||
setRegexFilters({
|
||||
...regexFilters,
|
||||
includePattern: e.target.value,
|
||||
})
|
||||
}
|
||||
placeholder="Example: \b(3L|BiZKiT)\b"
|
||||
className={styles.input}
|
||||
/>
|
||||
<p className={styles.helpText}>
|
||||
Example patterns:
|
||||
<br />
|
||||
- \b(3L|BiZKiT|BLURANiUM)\b (only include 3L, BiZKiT, and BLURANiUM releases)
|
||||
<br />- \b(3L|BiZKiT|BLURANiUM)\b (only include 3L, BiZKiT,
|
||||
and BLURANiUM releases)
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1092,8 +1104,10 @@ export default function Configure() {
|
||||
<div className={styles.section}>
|
||||
<h2 style={{ padding: '5px' }}>Regex Sort Patterns</h2>
|
||||
<p style={{ padding: '5px' }}>
|
||||
Enter space-separated regex patterns to sort streams. Streams will be sorted based on the order of matching patterns.
|
||||
Matching files will come first in descending order, and last in ascending order for each pattern.
|
||||
Enter space-separated regex patterns to sort streams. Streams will
|
||||
be sorted based on the order of matching patterns. Matching files
|
||||
will come first in descending order, and last in ascending order
|
||||
for each pattern.
|
||||
</p>
|
||||
<input
|
||||
type="text"
|
||||
@@ -1109,8 +1123,8 @@ export default function Configure() {
|
||||
/>
|
||||
<p className={styles.helpText}>
|
||||
Example patterns:
|
||||
<br />
|
||||
- \b(3L|BiZKiT|BLURANiUM)\b \b(FraMeSToR)\b (sort 3L/BiZKiT/BLURANiUM releases first, then FraMeSToR releases)
|
||||
<br />- \b(3L|BiZKiT|BLURANiUM)\b \b(FraMeSToR)\b (sort
|
||||
3L/BiZKiT/BLURANiUM releases first, then FraMeSToR releases)
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -88,7 +88,8 @@ export class Settings {
|
||||
public static readonly MAX_KEYWORD_FILTERS = process.env.MAX_KEYWORD_FILTERS
|
||||
? parseInt(process.env.MAX_KEYWORD_FILTERS)
|
||||
: 30;
|
||||
public static readonly MAX_REGEX_SORT_PATTERNS = process.env.MAX_REGEX_SORT_PATTERNS
|
||||
public static readonly MAX_REGEX_SORT_PATTERNS = process.env
|
||||
.MAX_REGEX_SORT_PATTERNS
|
||||
? parseInt(process.env.MAX_REGEX_SORT_PATTERNS)
|
||||
: 20;
|
||||
public static readonly MAX_MOVIE_SIZE = process.env.MAX_MOVIE_SIZE
|
||||
|
||||
@@ -47,7 +47,8 @@ export async function generateStremThruStreams(
|
||||
});
|
||||
|
||||
if (Settings.ENCRYPT_STREMTHRU_URLS) {
|
||||
headers['X-StremThru-Authorization'] = `Basic ${stremThruConfig.credential}`;
|
||||
headers['X-StremThru-Authorization'] =
|
||||
`Basic ${stremThruConfig.credential}`;
|
||||
} else {
|
||||
proxyUrl.searchParams.set('token', stremThruConfig.credential);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user