diff --git a/client/src/javascript/actions/FloodActions.ts b/client/src/javascript/actions/FloodActions.ts index 00fa1c99..91d66ef6 100644 --- a/client/src/javascript/actions/FloodActions.ts +++ b/client/src/javascript/actions/FloodActions.ts @@ -3,7 +3,6 @@ import axios from 'axios'; import type {HistorySnapshot} from '@shared/constants/historySnapshotTypes'; import type {NotificationFetchOptions} from '@shared/types/Notification'; import type {ServerEvents} from '@shared/types/ServerEvents'; -import type {TorrentProperties} from '@shared/types/Torrent'; import AppDispatcher from '../dispatcher/AppDispatcher'; import ConfigStore from '../stores/ConfigStore'; @@ -145,24 +144,6 @@ const FloodActions = { }; }), - fetchMediainfo: (options: {hash: TorrentProperties['hash']}) => - axios - .get(`${baseURI}api/mediainfo`, { - params: { - hash: options.hash, - }, - }) - .then((json) => json.data) - .then((response) => { - AppDispatcher.dispatchServerAction({ - type: 'FLOOD_FETCH_MEDIAINFO_SUCCESS', - data: { - ...response, - ...options, - }, - }); - }), - fetchNotifications: (options: NotificationFetchOptions) => axios .get(`${baseURI}api/notifications`, { diff --git a/client/src/javascript/actions/TorrentActions.ts b/client/src/javascript/actions/TorrentActions.ts index b241724b..81f14836 100644 --- a/client/src/javascript/actions/TorrentActions.ts +++ b/client/src/javascript/actions/TorrentActions.ts @@ -118,6 +118,20 @@ const TorrentActions = { }, ), + fetchMediainfo: (hash: TorrentProperties['hash']) => + axios + .get(`${baseURI}api/torrents/${hash}/mediainfo`) + .then((json) => json.data) + .then((response) => { + AppDispatcher.dispatchServerAction({ + type: 'CLIENT_FETCH_TORRENT_MEDIAINFO_SUCCESS', + data: { + ...response, + hash, + }, + }); + }), + fetchTorrentDetails: (hash: TorrentProperties['hash']) => axios .get(`${baseURI}api/torrents/${hash}/details`) diff --git a/client/src/javascript/components/modals/torrent-details-modal/TorrentMediainfo.js b/client/src/javascript/components/modals/torrent-details-modal/TorrentMediainfo.js index d23ee43e..fe1b5ba3 100644 --- a/client/src/javascript/components/modals/torrent-details-modal/TorrentMediainfo.js +++ b/client/src/javascript/components/modals/torrent-details-modal/TorrentMediainfo.js @@ -6,8 +6,8 @@ import {Button} from '../../../ui'; import ClipboardIcon from '../../icons/ClipboardIcon'; import connectStores from '../../../util/connectStores'; import EventTypes from '../../../constants/EventTypes'; -import FloodActions from '../../../actions/FloodActions'; import Tooltip from '../../general/Tooltip'; +import TorrentActions from '../../../actions/TorrentActions'; import TorrentStore from '../../../stores/TorrentStore'; const MESSAGES = defineMessages({ @@ -43,7 +43,7 @@ class TorrentMediainfo extends React.Component { } componentDidMount() { - FloodActions.fetchMediainfo({hash: this.props.hash}).then( + TorrentActions.fetchMediainfo(this.props.hash).then( () => { this.setState({ isFetchingMediainfo: false, @@ -148,7 +148,7 @@ const ConnectedTorrentMediainfo = connectStores(injectIntl(TorrentMediainfo), () return [ { store: TorrentStore, - event: EventTypes.FLOOD_FETCH_MEDIAINFO_SUCCESS, + event: EventTypes.CLIENT_FETCH_TORRENT_MEDIAINFO_SUCCESS, getValue: ({store, props}) => { return { mediainfo: store.getMediainfo(props.hash), diff --git a/client/src/javascript/constants/EventTypes.ts b/client/src/javascript/constants/EventTypes.ts index 45eb3245..97e358b6 100644 --- a/client/src/javascript/constants/EventTypes.ts +++ b/client/src/javascript/constants/EventTypes.ts @@ -15,6 +15,7 @@ const eventTypes = [ 'CLIENT_CONNECTION_STATUS_CHANGE', 'CLIENT_ADD_TORRENT_ERROR', 'CLIENT_ADD_TORRENT_SUCCESS', + 'CLIENT_FETCH_TORRENT_MEDIAINFO_SUCCESS', 'CLIENT_FETCH_TORRENT_TAXONOMY_SUCCESS', 'CLIENT_SET_FILE_PRIORITY_ERROR', 'CLIENT_SET_FILE_PRIORITY_SUCCESS', @@ -41,7 +42,6 @@ const eventTypes = [ 'CLIENT_TRANSFER_HISTORY_REQUEST_ERROR', 'CLIENT_TRANSFER_SUMMARY_CHANGE', 'DISK_USAGE_CHANGE', - 'FLOOD_FETCH_MEDIAINFO_SUCCESS', 'NOTIFICATIONS_FETCH_ERROR', 'NOTIFICATIONS_FETCH_SUCCESS', 'NOTIFICATIONS_COUNT_CHANGE', diff --git a/client/src/javascript/constants/ServerActions.ts b/client/src/javascript/constants/ServerActions.ts index b1f867ec..dcfce99d 100644 --- a/client/src/javascript/constants/ServerActions.ts +++ b/client/src/javascript/constants/ServerActions.ts @@ -116,6 +116,11 @@ interface ClientCheckHashErrorAction { }; } +interface ClientFetchTorrentMediainfoSuccessAction { + type: 'CLIENT_FETCH_TORRENT_MEDIAINFO_SUCCESS'; + data: {hash: string; output: string}; +} + interface ClientSettingsFetchRequestSuccessAction { type: 'CLIENT_SETTINGS_FETCH_REQUEST_SUCCESS'; data: ClientSettings; @@ -128,6 +133,7 @@ export interface ClientSettingsSaveSuccessAction { type ClientAction = | ClientCheckHashErrorAction + | ClientFetchTorrentMediainfoSuccessAction | ClientSettingsFetchRequestSuccessAction | ClientSettingsSaveSuccessAction; @@ -137,11 +143,6 @@ type ServerEventAction = { data: ServerEvents[T]; }; -interface FloodFetchMediainfoSuccessAction { - type: 'FLOOD_FETCH_MEDIAINFO_SUCCESS'; - data: {hash: string; output: string}; -} - interface FloodClearNotificationsSuccessAction { type: 'FLOOD_CLEAR_NOTIFICATIONS_SUCCESS'; data: NotificationFetchOptions; @@ -163,7 +164,6 @@ type FloodAction = | ServerEventAction<'TRANSFER_HISTORY_FULL_UPDATE'> | ServerEventAction<'TRANSFER_SUMMARY_FULL_UPDATE'> | ServerEventAction<'TRANSFER_SUMMARY_DIFF_CHANGE'> - | FloodFetchMediainfoSuccessAction | FloodClearNotificationsSuccessAction | FloodFetchNotificationsSuccessAction; diff --git a/client/src/javascript/stores/TorrentStore.ts b/client/src/javascript/stores/TorrentStore.ts index 09258f31..45534026 100644 --- a/client/src/javascript/stores/TorrentStore.ts +++ b/client/src/javascript/stores/TorrentStore.ts @@ -121,7 +121,7 @@ class TorrentStoreClass extends BaseStore { handleFetchMediainfoSuccess(response: {hash: string; output: string}) { this.mediainfo[response.hash] = response.output; - this.emit('FLOOD_FETCH_MEDIAINFO_SUCCESS'); + this.emit('CLIENT_FETCH_TORRENT_MEDIAINFO_SUCCESS'); } handleFetchSettingsRequest() { @@ -314,6 +314,9 @@ TorrentStore.dispatcherID = AppDispatcher.register((payload) => { case 'TORRENT_LIST_FULL_UPDATE': TorrentStore.handleTorrentListFullUpdate(action.data); break; + case 'CLIENT_FETCH_TORRENT_MEDIAINFO_SUCCESS': + TorrentStore.handleFetchMediainfoSuccess(action.data); + break; case 'CLIENT_MOVE_TORRENTS_SUCCESS': TorrentStore.handleMoveTorrentsSuccess(action.data); break; @@ -335,9 +338,6 @@ TorrentStore.dispatcherID = AppDispatcher.register((payload) => { case 'CLIENT_SET_TRACKER_ERROR': // TODO: popup set tracker failed message here break; - case 'FLOOD_FETCH_MEDIAINFO_SUCCESS': - TorrentStore.handleFetchMediainfoSuccess(action.data); - break; case 'UI_CLICK_TORRENT': TorrentStore.setSelectedTorrents(action.data); break; diff --git a/server/routes/api/index.ts b/server/routes/api/index.ts index b186d784..21110775 100644 --- a/server/routes/api/index.ts +++ b/server/routes/api/index.ts @@ -14,7 +14,6 @@ import clientActivityStream from '../../middleware/clientActivityStream'; import eventStream from '../../middleware/eventStream'; import feedMonitorRoutes from './feed-monitor'; import Filesystem from '../../models/Filesystem'; -import mediainfo from '../../util/mediainfo'; import settings from '../../models/settings'; import torrentsRoutes from './torrents'; @@ -42,10 +41,6 @@ router.get('/history', (req: Request { - mediainfo.getMediainfo(req.user, req.query, ajaxUtil.getResponseFn(res)); -}); - router.get('/notifications', (req: Request, res) => { req.services?.notificationService.getNotifications(req.query, ajaxUtil.getResponseFn(res)); }); diff --git a/server/routes/api/torrents.ts b/server/routes/api/torrents.ts index 22be9de0..e6e9e40d 100644 --- a/server/routes/api/torrents.ts +++ b/server/routes/api/torrents.ts @@ -12,6 +12,7 @@ import type { import ajaxUtil from '../../util/ajaxUtil'; import client from '../../models/client'; +import mediainfo from '../../util/mediainfo'; const router = express.Router(); @@ -193,7 +194,7 @@ router.patch('/tracker', (req, res) => { */ /** - * GET /api/{hash}/details + * GET /api/torrents/{hash}/details * @summary Gets details of a torrent. * @security AuthenticatedUser */ @@ -202,7 +203,16 @@ router.get('/:hash/details', (req, res) => { }); /** - * PATCH /api/{hash}/priority + * GET /api/torrents/{hash}/mediainfo + * @summary Gets mediainfo output of a torrent. + * @security AuthenticatedUser + */ +router.get('/:hash/mediainfo', (req, res) => { + mediainfo.getMediainfo(req.services, req.params.hash, ajaxUtil.getResponseFn(res)); +}); + +/** + * PATCH /api/torrents/{hash}/priority * @summary Sets priority of a torrent. * @security AuthenticatedUser */ @@ -211,7 +221,7 @@ router.patch('/:hash/priority', (req, res) => { }); /** - * PATCH /api/{hash}/file-priority + * PATCH /api/torrents/{hash}/file-priority * @summary Sets priority of files of a torrent. * @security AuthenticatedUser */ diff --git a/server/util/mediainfo.js b/server/util/mediainfo.js deleted file mode 100644 index fc99ffb6..00000000 --- a/server/util/mediainfo.js +++ /dev/null @@ -1,38 +0,0 @@ -import childProcess from 'child_process'; - -import services from '../services'; - -export default { - getMediainfo(user, options, callback) { - const torrentService = services.getTorrentService(user); - const {hash} = options; - - if (hash == null) { - callback(null, {error: 'Hash must be defined'}); - return; - } - const selectedTorrent = torrentService.getTorrent(hash); - try { - childProcess.execFile( - 'mediainfo', - [selectedTorrent.basePath], - {maxBuffer: 1024 * 2000}, - (error, stdout, stderr) => { - if (error) { - callback(null, {error}); - return; - } - - if (stderr) { - callback(null, {error: stderr}); - return; - } - - callback({output: stdout}); - }, - ); - } catch (childProcessError) { - callback(null, {error: childProcessError}); - } - }, -}; diff --git a/server/util/mediainfo.ts b/server/util/mediainfo.ts new file mode 100644 index 00000000..3ecef77b --- /dev/null +++ b/server/util/mediainfo.ts @@ -0,0 +1,48 @@ +import {TorrentProperties} from '@shared/types/Torrent'; +import childProcess from 'child_process'; + +import type {Request} from 'express'; + +export default { + getMediainfo( + services: Request['services'], + hash: TorrentProperties['hash'], + callback: (data: {output: string} | null, error?: Error) => void, + ) { + const torrentService = services?.torrentService; + + if (torrentService == null) { + callback(null, Error('Torrent service is not initialized')); + return; + } + + if (hash == null) { + callback(null, Error('Hash must be defined')); + return; + } + + const selectedTorrent = torrentService.getTorrent(hash); + try { + childProcess.execFile( + 'mediainfo', + [selectedTorrent.basePath], + {maxBuffer: 1024 * 2000}, + (error, stdout, stderr) => { + if (error) { + callback(null, error); + return; + } + + if (stderr) { + callback(null, Error(stderr)); + return; + } + + callback({output: stdout}); + }, + ); + } catch (childProcessError) { + callback(null, Error(childProcessError)); + } + }, +};