use webdav for files
This commit is contained in:
+17
-2
@@ -17,6 +17,15 @@ import bencode from 'bencode';
|
|||||||
import { FileType, FileNameVideoMetaExtractor, episodePatterns, seasonAndEpisodePatterns, seasonPatterns, extraEpKeyWords, keywordsArray, substringArray, soloEp } from '@metazla/filename-tools';
|
import { FileType, FileNameVideoMetaExtractor, episodePatterns, seasonAndEpisodePatterns, seasonPatterns, extraEpKeyWords, keywordsArray, substringArray, soloEp } from '@metazla/filename-tools';
|
||||||
import type { PluginManifest, ProcessRequest, CallbackPayload } from './types.js';
|
import type { PluginManifest, ProcessRequest, CallbackPayload } from './types.js';
|
||||||
import { MetaCoreClient } from './meta-core-client.js';
|
import { MetaCoreClient } from './meta-core-client.js';
|
||||||
|
import { createWebDAVClient, WebDAVClient } from './webdav-client.js';
|
||||||
|
|
||||||
|
// Initialize WebDAV client if WEBDAV_URL is set
|
||||||
|
const webdavClient = createWebDAVClient();
|
||||||
|
if (webdavClient) {
|
||||||
|
console.log('[torrent] Using WebDAV for file access');
|
||||||
|
} else {
|
||||||
|
console.log('[torrent] Using direct filesystem access');
|
||||||
|
}
|
||||||
|
|
||||||
const fileType = new FileType();
|
const fileType = new FileType();
|
||||||
const fileNameMetaExtractor = new FileNameVideoMetaExtractor(
|
const fileNameMetaExtractor = new FileNameVideoMetaExtractor(
|
||||||
@@ -73,7 +82,12 @@ export async function process(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Read and parse torrent file
|
// Read and parse torrent file
|
||||||
const torrentData = await readFile(filePath);
|
let torrentData: Buffer;
|
||||||
|
if (webdavClient) {
|
||||||
|
torrentData = await webdavClient.readFile(filePath);
|
||||||
|
} else {
|
||||||
|
torrentData = await readFile(filePath);
|
||||||
|
}
|
||||||
const parsed = bencode.decode(torrentData, 'utf8') as Record<string, any>;
|
const parsed = bencode.decode(torrentData, 'utf8') as Record<string, any>;
|
||||||
const metadata: Record<string, string> = {};
|
const metadata: Record<string, string> = {};
|
||||||
|
|
||||||
@@ -157,7 +171,8 @@ export async function process(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`[torrent] Parsed torrent file: ${filePath}`);
|
const mode = webdavClient ? 'WebDAV' : 'filesystem';
|
||||||
|
console.log(`[torrent] Parsed torrent file: ${filePath} (${mode})`);
|
||||||
|
|
||||||
await sendCallback({
|
await sendCallback({
|
||||||
taskId: request.taskId,
|
taskId: request.taskId,
|
||||||
|
|||||||
@@ -0,0 +1,109 @@
|
|||||||
|
/**
|
||||||
|
* WebDAV Client for Plugin File Access
|
||||||
|
*
|
||||||
|
* Provides HTTP-based file access to meta-sort's WebDAV endpoint.
|
||||||
|
* Replaces direct filesystem access for containerized plugins.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export interface FileStats {
|
||||||
|
size: number;
|
||||||
|
mtime?: Date;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class WebDAVClient {
|
||||||
|
private baseUrl: string;
|
||||||
|
|
||||||
|
constructor(baseUrl: string) {
|
||||||
|
// Remove trailing slash if present
|
||||||
|
this.baseUrl = baseUrl.replace(/\/$/, '');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert absolute file path to WebDAV URL
|
||||||
|
* Strips /files prefix and appends to base URL
|
||||||
|
*/
|
||||||
|
toWebDAVUrl(filePath: string): string {
|
||||||
|
// filePath is like "/files/watch/movie.mkv"
|
||||||
|
// We need to convert to "http://meta-sort-dev/webdav/watch/movie.mkv"
|
||||||
|
let relativePath = filePath;
|
||||||
|
|
||||||
|
// Strip /files prefix if present
|
||||||
|
if (relativePath.startsWith('/files/')) {
|
||||||
|
relativePath = relativePath.substring(6); // Remove "/files"
|
||||||
|
} else if (relativePath.startsWith('/files')) {
|
||||||
|
relativePath = relativePath.substring(6);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure path starts with /
|
||||||
|
if (!relativePath.startsWith('/')) {
|
||||||
|
relativePath = '/' + relativePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.baseUrl + relativePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get file stats (size, mtime) via HTTP HEAD request
|
||||||
|
*/
|
||||||
|
async stat(filePath: string): Promise<FileStats> {
|
||||||
|
const url = this.toWebDAVUrl(filePath);
|
||||||
|
|
||||||
|
const response = await fetch(url, { method: 'HEAD' });
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`WebDAV HEAD failed for ${filePath}: ${response.status} ${response.statusText}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const contentLength = response.headers.get('content-length');
|
||||||
|
const lastModified = response.headers.get('last-modified');
|
||||||
|
|
||||||
|
return {
|
||||||
|
size: contentLength ? parseInt(contentLength, 10) : 0,
|
||||||
|
mtime: lastModified ? new Date(lastModified) : undefined,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read entire file as buffer (for small files like .torrent)
|
||||||
|
*/
|
||||||
|
async readFile(filePath: string): Promise<Buffer> {
|
||||||
|
const url = this.toWebDAVUrl(filePath);
|
||||||
|
|
||||||
|
const response = await fetch(url, { method: 'GET' });
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`WebDAV GET failed for ${filePath}: ${response.status} ${response.statusText}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const arrayBuffer = await response.arrayBuffer();
|
||||||
|
return Buffer.from(arrayBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if file exists via HTTP HEAD
|
||||||
|
*/
|
||||||
|
async exists(filePath: string): Promise<boolean> {
|
||||||
|
const url = this.toWebDAVUrl(filePath);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch(url, { method: 'HEAD' });
|
||||||
|
return response.ok;
|
||||||
|
} catch {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a WebDAV client from environment variables
|
||||||
|
*/
|
||||||
|
export function createWebDAVClient(): WebDAVClient | null {
|
||||||
|
const webdavUrl = process.env.WEBDAV_URL;
|
||||||
|
|
||||||
|
if (!webdavUrl) {
|
||||||
|
console.warn('[webdav-client] WEBDAV_URL not set, WebDAV client unavailable');
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new WebDAVClient(webdavUrl);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user