UNPKG

n8n-nodes-kodi

Version:

A powerful n8n community node for controlling Kodi media center through JSON-RPC API with intelligent method discovery and comprehensive media management capabilities

295 lines 12.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Kodi = void 0; const n8n_workflow_1 = require("n8n-workflow"); const KodiService_1 = require("./KodiService"); class Kodi { constructor() { this.description = { displayName: 'Kodi', name: 'kodi', group: ['transform'], version: 3, subtitle: '={{$parameter["operation"]}}', description: 'Control Kodi with dynamic method discovery', icon: 'file:Kodi.svg', inputs: ["main"], outputs: ["main"], defaults: { name: 'Kodi', }, credentials: [ { name: 'kodiApi', required: true, }, ], properties: [ { displayName: 'Operation', name: 'operation', type: 'options', options: [ { name: 'Execute Method', value: 'execute', description: 'Execute a Kodi JSON-RPC method', action: 'Execute a kodi method', }, { name: 'Raw JSON-RPC', value: 'raw', description: 'Execute raw JSON-RPC command', action: 'Execute raw JSON-RPC', }, { name: 'Discover Methods', value: 'discover', description: 'Discover available methods from Kodi', action: 'Discover available methods', }, ], default: 'execute', noDataExpression: true, }, { displayName: 'Method Category Name or ID', name: 'methodCategory', type: 'options', displayOptions: { show: { operation: ['execute'], }, }, typeOptions: { loadOptionsMethod: 'getMethodCategories', }, default: '', description: 'Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>', noDataExpression: true, }, { displayName: 'Method Name or ID', name: 'method', type: 'options', displayOptions: { show: { operation: ['execute'], }, }, typeOptions: { loadOptionsMethod: 'getMethods', loadOptionsDependsOn: ['methodCategory'], }, default: '', description: 'Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>', noDataExpression: true, }, { displayName: 'Raw JSON-RPC', name: 'rawPayload', type: 'string', displayOptions: { show: { operation: ['raw'], }, }, default: '{ "jsonrpc": "2.0", "method": "VideoLibrary.Scan", "id": "n8n" }', description: 'Raw JSON-RPC payload to send to Kodi', noDataExpression: false, }, { displayName: 'Options', name: 'options', type: 'collection', placeholder: 'Add Option', default: {}, options: [ { displayName: 'Force Method Discovery', name: 'forceDiscovery', type: 'boolean', default: false, description: 'Whether to force rediscovery of available methods', }, { displayName: 'Include Method Info', name: 'includeMethodInfo', type: 'boolean', default: false, description: 'Whether to include method information in the output', }, ], }, ], }; this.methods = { loadOptions: { async getMethodCategories() { const credentials = await this.getCredentials('kodiApi'); if (!credentials) { return []; } try { const kodiService = new KodiService_1.KodiService(credentials); await kodiService.discoverMethods(); const categories = kodiService.getMethodsByCategory(); const options = [ { name: 'All', value: 'All', description: 'Show all available methods', }, ...Object.keys(categories).map(category => ({ name: category, value: category, description: `${categories[category].length} methods available`, })) ]; return options; } catch (error) { return [ { name: 'All', value: 'All', description: 'Show all available methods', } ]; } }, async getMethods() { const credentials = await this.getCredentials('kodiApi'); const methodCategory = this.getCurrentNodeParameter('methodCategory'); if (!credentials) { return []; } try { const kodiService = new KodiService_1.KodiService(credentials); await kodiService.discoverMethods(); const categories = kodiService.getMethodsByCategory(); let methods = []; if (methodCategory === 'All') { methods = Object.values(categories).flat(); } else if (methodCategory && categories[methodCategory]) { methods = categories[methodCategory]; } return methods.map(method => ({ name: method.name, value: method.name, description: method.description || '', })); } catch (error) { return []; } }, }, }; } async execute() { const operation = this.getNodeParameter('operation', 0); const returnData = []; try { const credentials = await this.getCredentials('kodiApi'); const kodiService = new KodiService_1.KodiService(credentials); const options = this.getNodeParameter('options', 0, {}); if (options.forceDiscovery) { await kodiService.discoverMethods(); } let result; if (operation === 'execute') { const method = this.getNodeParameter('method', 0); result = await kodiService.executeMethod(method); if (options.includeMethodInfo) { const methods = await kodiService.discoverMethods(); const methodInfo = methods.find(m => m.name === method); if (methodInfo) { result = { method: methodInfo, result: result, }; } } } else if (operation === 'raw') { const rawPayload = this.getNodeParameter('rawPayload', 0); let payload; try { payload = JSON.parse(rawPayload); } catch (error) { throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Invalid JSON in raw payload'); } if (!payload.jsonrpc || !payload.method || !payload.id) { throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Invalid JSON-RPC format. Must include jsonrpc, method, and id fields.'); } result = await kodiService.makeRequest(payload); if (result.error) { throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Kodi error: ${result.error.message} (code: ${result.error.code})`); } result = result.result; } else if (operation === 'discover') { const methods = await kodiService.discoverMethods(); const categories = kodiService.getMethodsByCategory(); result = { totalMethods: methods.length, categories: Object.keys(categories).map(category => ({ name: category, methodCount: categories[category].length, methods: categories[category], })), allMethods: methods, }; } if (result && typeof result === 'object') { if (Array.isArray(result)) { for (const item of result) { returnData.push({ json: item }); } } else { if (result.movies) { for (const movie of result.movies) { returnData.push({ json: movie }); } } else if (result.tvshows) { for (const show of result.tvshows) { returnData.push({ json: show }); } } else if (result.albums) { for (const album of result.albums) { returnData.push({ json: album }); } } else if (result.artists) { for (const artist of result.artists) { returnData.push({ json: artist }); } } else if (result.songs) { for (const song of result.songs) { returnData.push({ json: song }); } } else { returnData.push({ json: result }); } } } else { returnData.push({ json: { result } }); } return [returnData]; } catch (error) { throw new n8n_workflow_1.NodeOperationError(this.getNode(), error.message); } } } exports.Kodi = Kodi; //# sourceMappingURL=Kodi.node.js.map