mirror of
https://github.com/ajnart/homarr.git
synced 2025-11-10 23:45:48 +01:00
@@ -15,6 +15,7 @@ import { useEffect, useState } from 'react';
|
|||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { NormalizedTorrent } from '@ctrl/shared-torrent';
|
import { NormalizedTorrent } from '@ctrl/shared-torrent';
|
||||||
import { useViewportSize } from '@mantine/hooks';
|
import { useViewportSize } from '@mantine/hooks';
|
||||||
|
import { showNotification } from '@mantine/notifications';
|
||||||
import { IModule } from '../modules';
|
import { IModule } from '../modules';
|
||||||
import { useConfig } from '../../../tools/state';
|
import { useConfig } from '../../../tools/state';
|
||||||
import { AddItemShelfButton } from '../../AppShelf/AddAppShelfItem';
|
import { AddItemShelfButton } from '../../AppShelf/AddAppShelfItem';
|
||||||
@@ -52,12 +53,28 @@ export default function DownloadComponent() {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
if (downloadServices.length === 0) return;
|
if (downloadServices.length === 0) return;
|
||||||
setSafeInterval(() => {
|
const interval = setSafeInterval(() => {
|
||||||
// Send one request with each download service inside
|
// Send one request with each download service inside
|
||||||
axios.post('/api/modules/downloads', { config }).then((response) => {
|
axios
|
||||||
setTorrents(response.data);
|
.post('/api/modules/downloads')
|
||||||
setIsLoading(false);
|
.then((response) => {
|
||||||
});
|
setTorrents(response.data);
|
||||||
|
setIsLoading(false);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
setTorrents([]);
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.error('Error while fetching torrents', error.response.data);
|
||||||
|
setIsLoading(false);
|
||||||
|
clearInterval(interval);
|
||||||
|
showNotification({
|
||||||
|
title: 'Error fetching torrents',
|
||||||
|
autoClose: false,
|
||||||
|
color: 'red',
|
||||||
|
message:
|
||||||
|
'Please check your config for any potential errors, check the console for more info',
|
||||||
|
});
|
||||||
|
});
|
||||||
}, 5000);
|
}, 5000);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { NormalizedTorrent } from '@ctrl/shared-torrent';
|
|||||||
import { linearGradientDef } from '@nivo/core';
|
import { linearGradientDef } from '@nivo/core';
|
||||||
import { Datum, ResponsiveLine } from '@nivo/line';
|
import { Datum, ResponsiveLine } from '@nivo/line';
|
||||||
import { useListState } from '@mantine/hooks';
|
import { useListState } from '@mantine/hooks';
|
||||||
|
import { showNotification } from '@mantine/notifications';
|
||||||
import { AddItemShelfButton } from '../../AppShelf/AddAppShelfItem';
|
import { AddItemShelfButton } from '../../AppShelf/AddAppShelfItem';
|
||||||
import { useConfig } from '../../../tools/state';
|
import { useConfig } from '../../../tools/state';
|
||||||
import { humanFileSize } from '../../../tools/humanFileSize';
|
import { humanFileSize } from '../../../tools/humanFileSize';
|
||||||
@@ -43,10 +44,25 @@ export default function TotalDownloadsComponent() {
|
|||||||
const totalUploadSpeed = torrents.reduce((acc, torrent) => acc + torrent.uploadSpeed, 0);
|
const totalUploadSpeed = torrents.reduce((acc, torrent) => acc + torrent.uploadSpeed, 0);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (downloadServices.length === 0) return;
|
if (downloadServices.length === 0) return;
|
||||||
setSafeInterval(() => {
|
const interval = setSafeInterval(() => {
|
||||||
axios.post('/api/modules/downloads', { config }).then((response) => {
|
axios
|
||||||
setTorrents(response.data);
|
.post('/api/modules/downloads')
|
||||||
});
|
.then((response) => {
|
||||||
|
setTorrents(response.data);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
setTorrents([]);
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.error('Error while fetching torrents', error.response.data);
|
||||||
|
clearInterval(interval);
|
||||||
|
showNotification({
|
||||||
|
title: 'Error fetching torrents',
|
||||||
|
autoClose: false,
|
||||||
|
color: 'red',
|
||||||
|
message:
|
||||||
|
'Please check your config for any potential errors, check the console for more info',
|
||||||
|
});
|
||||||
|
});
|
||||||
}, 1000);
|
}, 1000);
|
||||||
}, [config.services]);
|
}, [config.services]);
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
// This interface is to be used in all the modules of the project
|
// This interface is to be used in all the modules of the project
|
||||||
// Each module should have its own interface and call the following function:
|
// Each module should have its own interface and call the following function:
|
||||||
// TODO: Add a function to register a module
|
// TODO: Add a function to register a module
|
||||||
|
|
||||||
|
import { TablerIcon } from '@tabler/icons';
|
||||||
|
|
||||||
// Note: Maybe use context to keep track of the modules
|
// Note: Maybe use context to keep track of the modules
|
||||||
export interface IModule {
|
export interface IModule {
|
||||||
title: string;
|
title: string;
|
||||||
description: string;
|
description: string;
|
||||||
icon: React.ReactNode;
|
icon: TablerIcon;
|
||||||
component: React.ComponentType;
|
component: React.ComponentType;
|
||||||
options?: Option;
|
options?: Option;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,12 +2,15 @@ import { Deluge } from '@ctrl/deluge';
|
|||||||
import { QBittorrent } from '@ctrl/qbittorrent';
|
import { QBittorrent } from '@ctrl/qbittorrent';
|
||||||
import { NormalizedTorrent } from '@ctrl/shared-torrent';
|
import { NormalizedTorrent } from '@ctrl/shared-torrent';
|
||||||
import { Transmission } from '@ctrl/transmission';
|
import { Transmission } from '@ctrl/transmission';
|
||||||
|
import { getCookie } from 'cookies-next';
|
||||||
import { NextApiRequest, NextApiResponse } from 'next';
|
import { NextApiRequest, NextApiResponse } from 'next';
|
||||||
|
import { getConfig } from '../../../tools/getConfig';
|
||||||
import { Config } from '../../../tools/types';
|
import { Config } from '../../../tools/types';
|
||||||
|
|
||||||
async function Post(req: NextApiRequest, res: NextApiResponse) {
|
async function Post(req: NextApiRequest, res: NextApiResponse) {
|
||||||
// Get the type of service from the request url
|
// Get the type of service from the request url
|
||||||
const { config }: { config: Config } = req.body;
|
const configName = getCookie('config-name', { req });
|
||||||
|
const { config }: { config: Config } = getConfig(configName?.toString() ?? 'default').props;
|
||||||
const qBittorrentServices = config.services.filter((service) => service.type === 'qBittorrent');
|
const qBittorrentServices = config.services.filter((service) => service.type === 'qBittorrent');
|
||||||
const delugeServices = config.services.filter((service) => service.type === 'Deluge');
|
const delugeServices = config.services.filter((service) => service.type === 'Deluge');
|
||||||
const transmissionServices = config.services.filter((service) => service.type === 'Transmission');
|
const transmissionServices = config.services.filter((service) => service.type === 'Transmission');
|
||||||
@@ -20,40 +23,44 @@ async function Post(req: NextApiRequest, res: NextApiResponse) {
|
|||||||
message: 'Missing services',
|
message: 'Missing services',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
await Promise.all(
|
try {
|
||||||
qBittorrentServices.map((service) =>
|
await Promise.all(
|
||||||
new QBittorrent({
|
qBittorrentServices.map((service) =>
|
||||||
baseUrl: service.url,
|
new QBittorrent({
|
||||||
username: service.username,
|
baseUrl: service.url,
|
||||||
password: service.password,
|
username: service.username,
|
||||||
})
|
password: service.password,
|
||||||
.getAllData()
|
})
|
||||||
.then((e) => torrents.push(...e.torrents))
|
.getAllData()
|
||||||
)
|
.then((e) => torrents.push(...e.torrents))
|
||||||
);
|
)
|
||||||
await Promise.all(
|
);
|
||||||
delugeServices.map((service) =>
|
await Promise.all(
|
||||||
new Deluge({
|
delugeServices.map((service) =>
|
||||||
baseUrl: service.url,
|
new Deluge({
|
||||||
password: 'password' in service ? service.password : '',
|
baseUrl: service.url,
|
||||||
})
|
password: 'password' in service ? service.password : '',
|
||||||
.getAllData()
|
})
|
||||||
.then((e) => torrents.push(...e.torrents))
|
.getAllData()
|
||||||
)
|
.then((e) => torrents.push(...e.torrents))
|
||||||
);
|
)
|
||||||
// Map transmissionServices
|
);
|
||||||
await Promise.all(
|
// Map transmissionServices
|
||||||
transmissionServices.map((service) =>
|
await Promise.all(
|
||||||
new Transmission({
|
transmissionServices.map((service) =>
|
||||||
baseUrl: service.url,
|
new Transmission({
|
||||||
username: 'username' in service ? service.username : '',
|
baseUrl: service.url,
|
||||||
password: 'password' in service ? service.password : '',
|
username: 'username' in service ? service.username : '',
|
||||||
})
|
password: 'password' in service ? service.password : '',
|
||||||
.getAllData()
|
})
|
||||||
.then((e) => torrents.push(...e.torrents))
|
.getAllData()
|
||||||
)
|
.then((e) => torrents.push(...e.torrents))
|
||||||
);
|
)
|
||||||
res.status(200).json(torrents);
|
);
|
||||||
|
} catch (e: any) {
|
||||||
|
return res.status(401).json(e);
|
||||||
|
}
|
||||||
|
return res.status(200).json(torrents);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default async (req: NextApiRequest, res: NextApiResponse) => {
|
export default async (req: NextApiRequest, res: NextApiResponse) => {
|
||||||
|
|||||||
@@ -14,7 +14,11 @@ export function getConfig(name: string) {
|
|||||||
settings: {
|
settings: {
|
||||||
searchUrl: 'https://www.google.com/search?q=',
|
searchUrl: 'https://www.google.com/search?q=',
|
||||||
},
|
},
|
||||||
modules: {},
|
modules: {
|
||||||
|
'Search Bar': {
|
||||||
|
enabled: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user