Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion anify-backend/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,6 @@ PROXY_CRON_ENABLED=false

# NovelUpdates login credentials
# Optional
NOVELUPDATES_LOGIN=
NOVELUPDATES_LOGIN=

PROXIES_API_KEY=
3 changes: 2 additions & 1 deletion anify-backend/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,5 @@ METAProxies.json
proxy-config.json
configs
.wrangler
test.ts
test.ts
proxies.json
3 changes: 2 additions & 1 deletion anify-backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
"prettier": "bunx prettier --write .",
"lint": "bun run prettier && bunx tsc --noEmit && bunx eslint --fix .",
"scripts": "bun src/scripts/index.ts",
"test": "bun src/tests/index.ts"
"test": "bun src/tests/index.ts",
"extract-proxies": "bun run src/proxies/impl/proxies.ts"
},
"dependencies": {
"@extractus/article-extractor": "^8.0.18",
Expand Down
2 changes: 2 additions & 0 deletions anify-backend/src/mappings/impl/base/impl/anilist.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1352,3 +1352,5 @@ interface IMediaEntry {
type: MediaType;
format: MediaFormat;
}

// console.dir(await (new AniListBase).search("Alya sometimes hides her feelings in russian", MediaType.ANIME, [MediaFormat.TV], 1, 20))
90 changes: 0 additions & 90 deletions anify-backend/src/proxies/impl/cloudflare/index.js

This file was deleted.

12 changes: 0 additions & 12 deletions anify-backend/src/proxies/impl/cloudflare/package.json

This file was deleted.

19 changes: 0 additions & 19 deletions anify-backend/src/proxies/impl/cloudflare/wrangler.toml

This file was deleted.

12 changes: 0 additions & 12 deletions anify-backend/src/proxies/impl/helper/loadJSON.ts

This file was deleted.

3 changes: 0 additions & 3 deletions anify-backend/src/proxies/impl/helper/saveJSON.ts

This file was deleted.

64 changes: 64 additions & 0 deletions anify-backend/src/proxies/impl/manager.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// 🌸 proxies/impl/manager.ts

import fs from "fs";
import path from "path";
import { ProviderType } from "../../types";

// 🗂️ Map each ProviderType to its proxy file
const PROXY_FILES: Record<ProviderType, string> = {
[ProviderType.BASE]: "BASEProxies.json",
[ProviderType.INFORMATION]: "INFORMATIONProxies.json",
[ProviderType.MANGA]: "MANGAProxies.json",
[ProviderType.META]: "METAProxies.json",
[ProviderType.ANIME]: "",
};

function loadProxyFile(filename: string): string[] {
if (!filename) return [];
try {
const filepath = path.resolve(process.cwd(), filename);
const raw = fs.readFileSync(filepath, "utf-8");
return JSON.parse(raw) as string[];
} catch {
return [];
}
}

// 🗂️ Lazily loaded proxy pool
const PROXY_POOL: Partial<Record<ProviderType, string[]>> = {};

function getPool(providerType: ProviderType): string[] {
if (!PROXY_POOL[providerType]) {
PROXY_POOL[providerType] = loadProxyFile(PROXY_FILES[providerType]);
}
return PROXY_POOL[providerType]!;
}

// 🔄 Round-robin index per provider instance
const roundRobinIndex: Map<string, number> = new Map();

/**
* 🎯 Selects a proxy from the pool for the given provider type.
* Uses round-robin per providerId to spread load evenly~
*/
export function selectProxy(providerType: ProviderType, providerId: string): string | null {
const pool = getPool(providerType);
if (pool.length === 0) return null;

const key = `${providerType}:${providerId}`;
const current = roundRobinIndex.get(key) ?? 0;
const proxy = pool[current % pool.length];

roundRobinIndex.set(key, current + 1);

return proxy ?? null;
}

/**
* 🔗 Converts a proxy string ("ip:port") to a full CORS Anywhere URL.
* Returns null if no proxy provided~
*/
export function proxyToUrl(proxy: string | null): string | null {
if (!proxy) return null;
return `http://${proxy}`;
}
Loading
Loading