mirror of
https://github.com/kikootwo/ReadMeABook.git
synced 2026-06-02 20:30:10 +00:00
bulljobs don't respect common headers
added the common truth (user-agent.ts) to all bulljob services
This commit is contained in:
@@ -1,7 +0,0 @@
|
|||||||
export async function register() {
|
|
||||||
if (process.env.NEXT_RUNTIME === 'nodejs') {
|
|
||||||
const axios = (await import('axios')).default;
|
|
||||||
const { RMAB_USER_AGENT } = await import('@/lib/utils/user-agent');
|
|
||||||
axios.defaults.headers.common['User-Agent'] = RMAB_USER_AGENT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -4,6 +4,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import axios, { AxiosInstance } from 'axios';
|
import axios, { AxiosInstance } from 'axios';
|
||||||
|
import { RMAB_USER_AGENT } from '../utils/user-agent';
|
||||||
import * as cheerio from 'cheerio';
|
import * as cheerio from 'cheerio';
|
||||||
import { RMABLogger } from '../utils/logger';
|
import { RMABLogger } from '../utils/logger';
|
||||||
import { getConfigService } from '../services/config.service';
|
import { getConfigService } from '../services/config.service';
|
||||||
@@ -273,7 +274,7 @@ export class AudibleService {
|
|||||||
timeout: 10000,
|
timeout: 10000,
|
||||||
headers: {
|
headers: {
|
||||||
Accept: 'application/json',
|
Accept: 'application/json',
|
||||||
'User-Agent': 'ReadMeABook/1.0',
|
'User-Agent': RMAB_USER_AGENT,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -305,7 +306,7 @@ export class AudibleService {
|
|||||||
timeout: 10000,
|
timeout: 10000,
|
||||||
headers: {
|
headers: {
|
||||||
Accept: 'application/json',
|
Accept: 'application/json',
|
||||||
'User-Agent': 'ReadMeABook/1.0',
|
'User-Agent': RMAB_USER_AGENT,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -7,13 +7,14 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
|
import { RMAB_USER_AGENT } from '@/lib/utils/user-agent';
|
||||||
import { RMABLogger } from '@/lib/utils/logger';
|
import { RMABLogger } from '@/lib/utils/logger';
|
||||||
|
|
||||||
const logger = RMABLogger.create('Audnexus.Authors');
|
const logger = RMABLogger.create('Audnexus.Authors');
|
||||||
|
|
||||||
const AUDNEXUS_BASE = 'https://api.audnex.us';
|
const AUDNEXUS_BASE = 'https://api.audnex.us';
|
||||||
const AUDNEXUS_TIMEOUT = 10000;
|
const AUDNEXUS_TIMEOUT = 10000;
|
||||||
const AUDNEXUS_HEADERS = { 'User-Agent': 'ReadMeABook/1.0' };
|
const AUDNEXUS_HEADERS = { 'User-Agent': RMAB_USER_AGENT };
|
||||||
|
|
||||||
export interface AudnexusAuthorSearch {
|
export interface AudnexusAuthorSearch {
|
||||||
asin: string;
|
asin: string;
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import axios, { AxiosInstance } from 'axios';
|
import axios, { AxiosInstance } from 'axios';
|
||||||
|
import { RMAB_USER_AGENT } from '../utils/user-agent';
|
||||||
import https from 'https';
|
import https from 'https';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import { DOWNLOAD_CLIENT_TIMEOUT } from '../constants/download-timeouts';
|
import { DOWNLOAD_CLIENT_TIMEOUT } from '../constants/download-timeouts';
|
||||||
@@ -50,7 +51,7 @@ export class DelugeService implements IDownloadClient {
|
|||||||
? new https.Agent({ rejectUnauthorized: false }) : undefined;
|
? new https.Agent({ rejectUnauthorized: false }) : undefined;
|
||||||
if (httpsAgent) logger.info('[Deluge] SSL certificate verification disabled');
|
if (httpsAgent) logger.info('[Deluge] SSL certificate verification disabled');
|
||||||
|
|
||||||
this.client = axios.create({ baseURL: this.baseUrl, timeout: DOWNLOAD_CLIENT_TIMEOUT, httpsAgent });
|
this.client = axios.create({ baseURL: this.baseUrl, timeout: DOWNLOAD_CLIENT_TIMEOUT, httpsAgent, headers: { 'User-Agent': RMAB_USER_AGENT } });
|
||||||
}
|
}
|
||||||
|
|
||||||
/** JSON-RPC call with automatic re-authentication on auth failure */
|
/** JSON-RPC call with automatic re-authentication on auth failure */
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import axios, { AxiosInstance } from 'axios';
|
import axios, { AxiosInstance } from 'axios';
|
||||||
|
import { RMAB_USER_AGENT } from '@/lib/utils/user-agent';
|
||||||
import https from 'https';
|
import https from 'https';
|
||||||
import zlib from 'zlib';
|
import zlib from 'zlib';
|
||||||
import { RMABLogger } from '@/lib/utils/logger';
|
import { RMABLogger } from '@/lib/utils/logger';
|
||||||
@@ -140,6 +141,7 @@ export class NZBGetService implements IDownloadClient {
|
|||||||
baseURL: this.baseUrl,
|
baseURL: this.baseUrl,
|
||||||
timeout: 30000,
|
timeout: 30000,
|
||||||
httpsAgent: this.httpsAgent,
|
httpsAgent: this.httpsAgent,
|
||||||
|
headers: { 'User-Agent': RMAB_USER_AGENT },
|
||||||
auth: {
|
auth: {
|
||||||
username: this.username,
|
username: this.username,
|
||||||
password: this.password,
|
password: this.password,
|
||||||
@@ -226,7 +228,10 @@ export class NZBGetService implements IDownloadClient {
|
|||||||
responseType: 'arraybuffer',
|
responseType: 'arraybuffer',
|
||||||
timeout: 30000,
|
timeout: 30000,
|
||||||
maxRedirects: 5,
|
maxRedirects: 5,
|
||||||
headers: options?.sourceHeaders,
|
headers: {
|
||||||
|
'User-Agent': RMAB_USER_AGENT,
|
||||||
|
...options?.sourceHeaders,
|
||||||
|
},
|
||||||
httpsAgent: url.startsWith('https') ? this.httpsAgent : undefined,
|
httpsAgent: url.startsWith('https') ? this.httpsAgent : undefined,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import axios, { AxiosInstance } from 'axios';
|
import axios, { AxiosInstance } from 'axios';
|
||||||
|
import { RMAB_USER_AGENT } from '../utils/user-agent';
|
||||||
import { parseStringPromise } from 'xml2js';
|
import { parseStringPromise } from 'xml2js';
|
||||||
import { RMABLogger } from '../utils/logger';
|
import { RMABLogger } from '../utils/logger';
|
||||||
|
|
||||||
@@ -83,6 +84,7 @@ export class PlexService {
|
|||||||
constructor() {
|
constructor() {
|
||||||
this.client = axios.create({
|
this.client = axios.create({
|
||||||
timeout: 10000,
|
timeout: 10000,
|
||||||
|
headers: { 'User-Agent': RMAB_USER_AGENT },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import axios, { AxiosInstance } from 'axios';
|
import axios, { AxiosInstance } from 'axios';
|
||||||
|
import { RMAB_USER_AGENT } from '../utils/user-agent';
|
||||||
import { XMLParser } from 'fast-xml-parser';
|
import { XMLParser } from 'fast-xml-parser';
|
||||||
import { DOWNLOAD_CLIENT_TIMEOUT } from '../constants/download-timeouts';
|
import { DOWNLOAD_CLIENT_TIMEOUT } from '../constants/download-timeouts';
|
||||||
import { TorrentResult } from '../utils/ranking-algorithm';
|
import { TorrentResult } from '../utils/ranking-algorithm';
|
||||||
@@ -86,6 +87,7 @@ export class ProwlarrService {
|
|||||||
this.client = axios.create({
|
this.client = axios.create({
|
||||||
baseURL: `${this.baseUrl}/api/v1`,
|
baseURL: `${this.baseUrl}/api/v1`,
|
||||||
headers: {
|
headers: {
|
||||||
|
'User-Agent': RMAB_USER_AGENT,
|
||||||
'X-Api-Key': this.apiKey,
|
'X-Api-Key': this.apiKey,
|
||||||
},
|
},
|
||||||
timeout: DOWNLOAD_CLIENT_TIMEOUT,
|
timeout: DOWNLOAD_CLIENT_TIMEOUT,
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import axios, { AxiosInstance } from 'axios';
|
import axios, { AxiosInstance } from 'axios';
|
||||||
|
import { RMAB_USER_AGENT } from '../utils/user-agent';
|
||||||
import https from 'https';
|
import https from 'https';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import { DOWNLOAD_CLIENT_TIMEOUT } from '../constants/download-timeouts';
|
import { DOWNLOAD_CLIENT_TIMEOUT } from '../constants/download-timeouts';
|
||||||
@@ -149,6 +150,7 @@ export class QBittorrentService implements IDownloadClient {
|
|||||||
baseURL: `${this.baseUrl}/api/v2`,
|
baseURL: `${this.baseUrl}/api/v2`,
|
||||||
timeout: DOWNLOAD_CLIENT_TIMEOUT,
|
timeout: DOWNLOAD_CLIENT_TIMEOUT,
|
||||||
httpsAgent: this.httpsAgent,
|
httpsAgent: this.httpsAgent,
|
||||||
|
headers: { 'User-Agent': RMAB_USER_AGENT },
|
||||||
// Support nginx/Apache reverse proxy with HTTP Basic Auth
|
// Support nginx/Apache reverse proxy with HTTP Basic Auth
|
||||||
auth: {
|
auth: {
|
||||||
username: this.username,
|
username: this.username,
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import axios, { AxiosInstance } from 'axios';
|
import axios, { AxiosInstance } from 'axios';
|
||||||
|
import { RMAB_USER_AGENT } from '@/lib/utils/user-agent';
|
||||||
import https from 'https';
|
import https from 'https';
|
||||||
import FormData from 'form-data';
|
import FormData from 'form-data';
|
||||||
import { RMABLogger } from '@/lib/utils/logger';
|
import { RMABLogger } from '@/lib/utils/logger';
|
||||||
@@ -132,6 +133,7 @@ export class SABnzbdService implements IDownloadClient {
|
|||||||
baseURL: this.baseUrl,
|
baseURL: this.baseUrl,
|
||||||
timeout: 30000,
|
timeout: 30000,
|
||||||
httpsAgent: this.httpsAgent,
|
httpsAgent: this.httpsAgent,
|
||||||
|
headers: { 'User-Agent': RMAB_USER_AGENT },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -494,7 +496,10 @@ export class SABnzbdService implements IDownloadClient {
|
|||||||
responseType: 'arraybuffer',
|
responseType: 'arraybuffer',
|
||||||
timeout: 30000,
|
timeout: 30000,
|
||||||
maxRedirects: 5,
|
maxRedirects: 5,
|
||||||
headers: options?.sourceHeaders,
|
headers: {
|
||||||
|
'User-Agent': RMAB_USER_AGENT,
|
||||||
|
...options?.sourceHeaders,
|
||||||
|
},
|
||||||
// Use the same SSL settings as the SABnzbd client if the NZB URL
|
// Use the same SSL settings as the SABnzbd client if the NZB URL
|
||||||
// happens to be served over HTTPS with a self-signed cert
|
// happens to be served over HTTPS with a self-signed cert
|
||||||
httpsAgent: url.startsWith('https') ? this.httpsAgent : undefined,
|
httpsAgent: url.startsWith('https') ? this.httpsAgent : undefined,
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import axios, { AxiosInstance } from 'axios';
|
import axios, { AxiosInstance } from 'axios';
|
||||||
|
import { RMAB_USER_AGENT } from '../utils/user-agent';
|
||||||
import https from 'https';
|
import https from 'https';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import { DOWNLOAD_CLIENT_TIMEOUT } from '../constants/download-timeouts';
|
import { DOWNLOAD_CLIENT_TIMEOUT } from '../constants/download-timeouts';
|
||||||
@@ -109,6 +110,7 @@ export class TransmissionService implements IDownloadClient {
|
|||||||
baseURL: this.baseUrl,
|
baseURL: this.baseUrl,
|
||||||
timeout: DOWNLOAD_CLIENT_TIMEOUT,
|
timeout: DOWNLOAD_CLIENT_TIMEOUT,
|
||||||
httpsAgent: this.httpsAgent,
|
httpsAgent: this.httpsAgent,
|
||||||
|
headers: { 'User-Agent': RMAB_USER_AGENT },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import { getConfigService } from '../services/config.service';
|
|||||||
import { RMABLogger } from '../utils/logger';
|
import { RMABLogger } from '../utils/logger';
|
||||||
import { extractDownloadUrl, ExtractedDownload } from '../services/ebook-scraper';
|
import { extractDownloadUrl, ExtractedDownload } from '../services/ebook-scraper';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
|
import { RMAB_USER_AGENT } from '../utils/user-agent';
|
||||||
import fs from 'fs/promises';
|
import fs from 'fs/promises';
|
||||||
import { createWriteStream } from 'fs';
|
import { createWriteStream } from 'fs';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
@@ -302,7 +303,7 @@ async function downloadFileWithProgress(
|
|||||||
responseType: 'stream',
|
responseType: 'stream',
|
||||||
timeout: DOWNLOAD_TIMEOUT_MS,
|
timeout: DOWNLOAD_TIMEOUT_MS,
|
||||||
headers: {
|
headers: {
|
||||||
'User-Agent': 'ReadMeABook/1.0 (Audiobook Automation)',
|
'User-Agent': RMAB_USER_AGENT,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import axios, { AxiosError } from 'axios';
|
import axios, { AxiosError } from 'axios';
|
||||||
|
import { RMAB_USER_AGENT } from '../utils/user-agent';
|
||||||
import * as cheerio from 'cheerio';
|
import * as cheerio from 'cheerio';
|
||||||
import fs from 'fs/promises';
|
import fs from 'fs/promises';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
@@ -19,7 +20,7 @@ export interface EbookDownloadResult {
|
|||||||
error?: string;
|
error?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const USER_AGENT = 'ReadMeABook/1.0 (Audiobook Automation)';
|
const USER_AGENT = RMAB_USER_AGENT;
|
||||||
const REQUEST_DELAY_MS = 1500; // 1.5 second delay between requests
|
const REQUEST_DELAY_MS = 1500; // 1.5 second delay between requests
|
||||||
const DOWNLOAD_TIMEOUT_MS = 60000; // 60 seconds per download attempt
|
const DOWNLOAD_TIMEOUT_MS = 60000; // 60 seconds per download attempt
|
||||||
const MAX_SLOW_LINK_ATTEMPTS = 5;
|
const MAX_SLOW_LINK_ATTEMPTS = 5;
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
|
import { RMAB_USER_AGENT } from '@/lib/utils/user-agent';
|
||||||
import { XMLParser } from 'fast-xml-parser';
|
import { XMLParser } from 'fast-xml-parser';
|
||||||
import { prisma } from '@/lib/db';
|
import { prisma } from '@/lib/db';
|
||||||
import { Prisma } from '@/generated/prisma/client';
|
import { Prisma } from '@/generated/prisma/client';
|
||||||
@@ -83,7 +84,7 @@ export async function fetchAndValidateRss(rssUrl: string): Promise<{ shelfName:
|
|||||||
for (let page = 1; page <= MAX_PAGES; page++) {
|
for (let page = 1; page <= MAX_PAGES; page++) {
|
||||||
url.searchParams.set('page', page.toString());
|
url.searchParams.set('page', page.toString());
|
||||||
|
|
||||||
const response = await axios.get(url.toString(), { timeout: 15000 });
|
const response = await axios.get(url.toString(), { timeout: 15000, headers: { 'User-Agent': RMAB_USER_AGENT } });
|
||||||
const parsed = parseGoodreadsRss(response.data);
|
const parsed = parseGoodreadsRss(response.data);
|
||||||
|
|
||||||
if (page === 1) {
|
if (page === 1) {
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
|
import { RMAB_USER_AGENT } from '@/lib/utils/user-agent';
|
||||||
import { RMABLogger } from '@/lib/utils/logger';
|
import { RMABLogger } from '@/lib/utils/logger';
|
||||||
|
|
||||||
const logger = RMABLogger.create('HardcoverAPI');
|
const logger = RMABLogger.create('HardcoverAPI');
|
||||||
@@ -120,6 +121,7 @@ export async function fetchHardcoverList(
|
|||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${apiToken}`,
|
Authorization: `Bearer ${apiToken}`,
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
|
'User-Agent': RMAB_USER_AGENT,
|
||||||
},
|
},
|
||||||
timeout: 30000,
|
timeout: 30000,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import fs from 'fs/promises';
|
|||||||
import path from 'path';
|
import path from 'path';
|
||||||
import crypto from 'crypto';
|
import crypto from 'crypto';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
|
import { RMAB_USER_AGENT } from '../utils/user-agent';
|
||||||
import { RMABLogger } from '../utils/logger';
|
import { RMABLogger } from '../utils/logger';
|
||||||
|
|
||||||
const logger = RMABLogger.create('ThumbnailCache');
|
const logger = RMABLogger.create('ThumbnailCache');
|
||||||
@@ -110,7 +111,7 @@ export class ThumbnailCacheService {
|
|||||||
timeout: TIMEOUT_MS,
|
timeout: TIMEOUT_MS,
|
||||||
maxContentLength: MAX_FILE_SIZE,
|
maxContentLength: MAX_FILE_SIZE,
|
||||||
headers: {
|
headers: {
|
||||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
|
'User-Agent': RMAB_USER_AGENT,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -185,7 +186,7 @@ export class ThumbnailCacheService {
|
|||||||
timeout: TIMEOUT_MS,
|
timeout: TIMEOUT_MS,
|
||||||
maxContentLength: MAX_FILE_SIZE,
|
maxContentLength: MAX_FILE_SIZE,
|
||||||
headers: {
|
headers: {
|
||||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
|
'User-Agent': RMAB_USER_AGENT,
|
||||||
...(backendMode === 'audiobookshelf' && { Authorization: `Bearer ${authToken}` }),
|
...(backendMode === 'audiobookshelf' && { Authorization: `Bearer ${authToken}` }),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
import fs from 'fs/promises';
|
import fs from 'fs/promises';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
|
import { RMAB_USER_AGENT } from './user-agent';
|
||||||
import { tagMultipleFiles, checkFfmpegAvailable } from './metadata-tagger';
|
import { tagMultipleFiles, checkFfmpegAvailable } from './metadata-tagger';
|
||||||
import { RMABLogger } from './logger';
|
import { RMABLogger } from './logger';
|
||||||
import { copyFile } from './copy-file';
|
import { copyFile } from './copy-file';
|
||||||
@@ -740,6 +741,7 @@ export class FileOrganizer {
|
|||||||
const response = await axios.get(url, {
|
const response = await axios.get(url, {
|
||||||
responseType: 'arraybuffer',
|
responseType: 'arraybuffer',
|
||||||
timeout: 30000,
|
timeout: 30000,
|
||||||
|
headers: { 'User-Agent': RMAB_USER_AGENT },
|
||||||
});
|
});
|
||||||
|
|
||||||
await fs.writeFile(targetPath, response.data);
|
await fs.writeFile(targetPath, response.data);
|
||||||
|
|||||||
Reference in New Issue
Block a user