mirror of
https://github.com/zoriya/flood.git
synced 2025-12-06 07:16:18 +00:00
Introduce uiSettings DB
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,5 +1,6 @@
|
||||
.DS_Store
|
||||
node_modules
|
||||
npm-debug.log
|
||||
server/db/uiSettings.db
|
||||
server/db/users.js
|
||||
server/db/history
|
||||
|
||||
@@ -5,6 +5,12 @@ import ActionTypes from '../constants/ActionTypes';
|
||||
|
||||
const TorrentActions = {
|
||||
addTorrents: function(urls, destination) {
|
||||
axios.post('/ui/torrent-location', {
|
||||
destination
|
||||
})
|
||||
.catch(function (error) {
|
||||
console.log(error);
|
||||
});
|
||||
return axios.post('/client/add', {
|
||||
urls,
|
||||
destination
|
||||
@@ -30,6 +36,25 @@ const TorrentActions = {
|
||||
});
|
||||
},
|
||||
|
||||
fetchLatestTorrentLocation: function () {
|
||||
return axios.get('/ui/torrent-location')
|
||||
.then((json = {}) => {
|
||||
return json.data;
|
||||
})
|
||||
.then((data) => {
|
||||
AppDispatcher.dispatchServerAction({
|
||||
type: ActionTypes.UI_LATEST_TORRENT_LOCATION_REQUEST_SUCCESS,
|
||||
data
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
AppDispatcher.dispatchServerAction({
|
||||
type: ActionTypes.UI_LATEST_TORRENT_LOCATION_REQUEST_ERROR,
|
||||
error
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
fetchTorrents: function () {
|
||||
return axios.get('/client/list')
|
||||
.then((json = {}) => {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import axios from 'axios';
|
||||
|
||||
import AppDispatcher from '../dispatcher/AppDispatcher';
|
||||
import ActionTypes from '../constants/ActionTypes';
|
||||
|
||||
@@ -16,6 +18,25 @@ const UIActions = {
|
||||
});
|
||||
},
|
||||
|
||||
fetchSortProps: function() {
|
||||
return axios.get('/ui/sort-props')
|
||||
.then((json = {}) => {
|
||||
return json.data;
|
||||
})
|
||||
.then((data) => {
|
||||
AppDispatcher.dispatchServerAction({
|
||||
type: ActionTypes.UI_SORT_PROPS_REQUEST_SUCCESS,
|
||||
data
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
AppDispatcher.dispatchServerAction({
|
||||
type: ActionTypes.UI_SORT_PROPS_REQUEST_ERROR,
|
||||
error
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
handleDetailsClick: function(data) {
|
||||
AppDispatcher.dispatchUIAction({
|
||||
type: ActionTypes.UI_CLICK_TORRENT_DETAILS,
|
||||
@@ -45,6 +66,12 @@ const UIActions = {
|
||||
},
|
||||
|
||||
setTorrentsSort: function(data) {
|
||||
axios
|
||||
.post('/ui/sort-props', data)
|
||||
.catch(function (error) {
|
||||
console.log(error);
|
||||
});
|
||||
|
||||
AppDispatcher.dispatchUIAction({
|
||||
type: ActionTypes.UI_SET_TORRENT_SORT,
|
||||
data
|
||||
|
||||
@@ -7,8 +7,13 @@ import Modals from './components/modals/Modals';
|
||||
import Sidebar from './components/panels/Sidebar';
|
||||
import TorrentListView from './components/panels/TorrentListView';
|
||||
import TorrentDetailsView from './components/panels/TorrentDetailsView';
|
||||
import TorrentActions from './actions/TorrentActions';
|
||||
|
||||
class FloodApp extends React.Component {
|
||||
componentDidMount() {
|
||||
TorrentActions.fetchLatestTorrentLocation();
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Application>
|
||||
|
||||
@@ -2,8 +2,10 @@ import _ from 'lodash';
|
||||
import classnames from 'classnames';
|
||||
import React from 'react';
|
||||
|
||||
import EventTypes from '../../constants/EventTypes';
|
||||
import TextboxRepeater from '../forms/TextboxRepeater';
|
||||
import TorrentActions from '../../actions/TorrentActions';
|
||||
import UIStore from '../../stores/UIStore';
|
||||
|
||||
const METHODS_TO_BIND = [
|
||||
'getContent',
|
||||
@@ -11,7 +13,8 @@ const METHODS_TO_BIND = [
|
||||
'handleUrlAdd',
|
||||
'handleUrlChange',
|
||||
'handleUrlRemove',
|
||||
'handleAddTorrents'
|
||||
'handleAddTorrents',
|
||||
'onLatestTorrentLocationChange'
|
||||
];
|
||||
|
||||
export default class AddTorrents extends React.Component {
|
||||
@@ -29,6 +32,23 @@ export default class AddTorrents extends React.Component {
|
||||
});
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
this.setState({destination: UIStore.getLatestTorrentLocation()});
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
UIStore.listen(EventTypes.UI_LATEST_TORRENT_LOCATION_CHANGE, this.onLatestTorrentLocationChange);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
UIStore.unlisten(EventTypes.UI_LATEST_TORRENT_LOCATION_CHANGE, this.onLatestTorrentLocationChange);
|
||||
UIStore.fetchLatestTorrentLocation();
|
||||
}
|
||||
|
||||
onLatestTorrentLocationChange() {
|
||||
this.setState({destination: UIStore.getLatestTorrentLocation()});
|
||||
}
|
||||
|
||||
getContent() {
|
||||
return (
|
||||
<div className="modal__content" onClick={this.handleMenuWrapperClick}>
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import React from 'react';
|
||||
|
||||
import ClientActions from '../../actions/ClientActions';
|
||||
import ClientDataStore from '../../stores/ClientDataStore';
|
||||
import Dropdown from '../forms/Dropdown';
|
||||
import EventTypes from '../../constants/EventTypes';
|
||||
import format from '../../util/formatData';
|
||||
import Limits from '../icons/Limits';
|
||||
import SidebarItem from '../sidebar/SidebarItem';
|
||||
import TransferDataStore from '../../stores/TransferDataStore';
|
||||
|
||||
const METHODS_TO_BIND = ['onTransferDataRequestSuccess'];
|
||||
const SPEEDS = [1024, 10240, 102400, 512000, 1048576, 2097152, 5242880, 10485760, 0];
|
||||
@@ -25,15 +25,15 @@ class Sidebar extends React.Component {
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
ClientDataStore.listen(
|
||||
TransferDataStore.listen(
|
||||
EventTypes.CLIENT_TRANSFER_DATA_REQUEST_SUCCESS,
|
||||
this.onTransferDataRequestSuccess
|
||||
);
|
||||
ClientDataStore.fetchTransferData();
|
||||
TransferDataStore.fetchTransferData();
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
ClientDataStore.unlisten(
|
||||
TransferDataStore.unlisten(
|
||||
EventTypes.CLIENT_TRANSFER_DATA_REQUEST_SUCCESS,
|
||||
this.onTransferDataRequestSuccess
|
||||
);
|
||||
@@ -41,7 +41,7 @@ class Sidebar extends React.Component {
|
||||
|
||||
onTransferDataRequestSuccess() {
|
||||
this.setState({
|
||||
throttle: ClientDataStore.getThrottles({latest: true})
|
||||
throttle: TransferDataStore.getThrottles({latest: true})
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
|
||||
import ClientDataStore from '../../stores/ClientDataStore';
|
||||
import Download from '../icons/Download';
|
||||
import EventTypes from '../../constants/EventTypes';
|
||||
import format from '../../util/formatData';
|
||||
import LineChart from '../ui/LineChart';
|
||||
import LoadingIndicator from '../ui/LoadingIndicator';
|
||||
import TransferDataStore from '../../stores/TransferDataStore';
|
||||
import Upload from '../icons/Upload';
|
||||
|
||||
const METHODS_TO_BIND = [
|
||||
'onTransferDataRequestError',
|
||||
'onTransferDataRequestSuccess'
|
||||
'onTransferDataRequestSuccess',
|
||||
'onTransferHistoryRequestSuccess'
|
||||
];
|
||||
|
||||
class ClientStats extends React.Component {
|
||||
@@ -19,6 +21,7 @@ class ClientStats extends React.Component {
|
||||
|
||||
this.state = {
|
||||
sidebarWidth: 0,
|
||||
transferHistoryRequestSuccess: false,
|
||||
transferDataRequestError: false,
|
||||
transferDataRequestSuccess: false
|
||||
};
|
||||
@@ -32,20 +35,25 @@ class ClientStats extends React.Component {
|
||||
this.setState({
|
||||
sidebarWidth: ReactDOM.findDOMNode(this).offsetWidth
|
||||
});
|
||||
ClientDataStore.listen(
|
||||
EventTypes.CLIENT_TRANSFER_DATA_REQUEST_SUCCESS,
|
||||
this.onTransferDataRequestSuccess
|
||||
);
|
||||
ClientDataStore.fetchTransferData();
|
||||
TransferDataStore.listen(EventTypes.CLIENT_TRANSFER_DATA_REQUEST_SUCCESS,
|
||||
this.onTransferDataRequestSuccess);
|
||||
TransferDataStore.listen(EventTypes.CLIENT_TRANSFER_HISTORY_REQUEST_SUCCESS,
|
||||
this.onTransferHistoryRequestSuccess);
|
||||
TransferDataStore.fetchTransferData();
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
ClientDataStore.unlisten(
|
||||
TransferDataStore.unlisten(
|
||||
EventTypes.CLIENT_TRANSFER_DATA_REQUEST_SUCCESS,
|
||||
this.onTransferDataRequestSuccess
|
||||
);
|
||||
}
|
||||
|
||||
isLoading() {
|
||||
return !this.state.transferHistoryRequestSuccess ||
|
||||
!this.state.transferDataRequestSuccess;
|
||||
}
|
||||
|
||||
onTransferDataRequestError() {
|
||||
this.setState({
|
||||
transferDataRequestError: true,
|
||||
@@ -60,17 +68,25 @@ class ClientStats extends React.Component {
|
||||
});
|
||||
}
|
||||
|
||||
onTransferHistoryRequestSuccess() {
|
||||
if (!this.state.transferHistoryRequestSuccess) {
|
||||
this.setState({
|
||||
transferHistoryRequestSuccess: true
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.state.transferDataRequestError) {
|
||||
return <div>Error</div>;
|
||||
} else if (!this.state.transferDataRequestSuccess) {
|
||||
return <div>Loading</div>;
|
||||
} else if (this.isLoading()) {
|
||||
return <LoadingIndicator />;
|
||||
}
|
||||
|
||||
let throttles = ClientDataStore.getThrottles();
|
||||
let transferRate = ClientDataStore.getTransferRate();
|
||||
let transferRates = ClientDataStore.getTransferRates();
|
||||
let transferTotals = ClientDataStore.getTransferTotals();
|
||||
let throttles = TransferDataStore.getThrottles();
|
||||
let transferRate = TransferDataStore.getTransferRate();
|
||||
let transferRates = TransferDataStore.getTransferRates();
|
||||
let transferTotals = TransferDataStore.getTransferTotals();
|
||||
|
||||
let downloadRate = format.data(transferRate.download, '/s');
|
||||
let downloadTotal = format.data(transferTotals.download);
|
||||
|
||||
@@ -34,6 +34,7 @@ export default class ActionBar extends React.Component {
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
TorrentFilterStore.fetchSortProps();
|
||||
TorrentFilterStore.listen(EventTypes.UI_TORRENTS_SORT_CHANGE, this.onSortChange);
|
||||
}
|
||||
|
||||
|
||||
@@ -41,16 +41,18 @@ export default class LineChart extends React.Component {
|
||||
})
|
||||
]);
|
||||
|
||||
let lineFunc = d3
|
||||
.svg
|
||||
.line()
|
||||
.x(function(dataPoint, index) {
|
||||
return xRange(index);
|
||||
})
|
||||
.y(function(dataPoint) {
|
||||
return yRange(dataPoint);
|
||||
})
|
||||
.interpolate('basis');
|
||||
let lineFunc = function (interpolation) {
|
||||
return d3
|
||||
.svg
|
||||
.line()
|
||||
.x(function(dataPoint, index) {
|
||||
return xRange(index);
|
||||
})
|
||||
.y(function(dataPoint) {
|
||||
return yRange(dataPoint);
|
||||
})
|
||||
.interpolate(interpolation);
|
||||
}
|
||||
|
||||
let areaFunc = d3
|
||||
.svg
|
||||
@@ -64,8 +66,8 @@ export default class LineChart extends React.Component {
|
||||
})
|
||||
.interpolate('basis');
|
||||
|
||||
let transferDataLinePoints = lineFunc(transferData);
|
||||
let transferLimitLinePoints = lineFunc(transferLimit);
|
||||
let transferDataLinePoints = lineFunc('basis')(transferData);
|
||||
let transferLimitLinePoints = lineFunc('step-after')(transferLimit);
|
||||
let transferDataAreaPoints = areaFunc(transferData);
|
||||
|
||||
graph
|
||||
|
||||
@@ -18,9 +18,13 @@ const ActionTypes = {
|
||||
UI_CLICK_TORRENT: 'UI_CLICK_TORRENT',
|
||||
UI_CLICK_TORRENT_DETAILS: 'UI_CLICK_TORRENT_DETAILS',
|
||||
UI_DISPLAY_MODAL: 'UI_DISPLAY_MODAL',
|
||||
UI_LATEST_TORRENT_LOCATION_REQUEST_ERROR: 'UI_LATEST_TORRENT_LOCATION_REQUEST_ERROR',
|
||||
UI_LATEST_TORRENT_LOCATION_REQUEST_SUCCESS: 'UI_LATEST_TORRENT_LOCATION_REQUEST_SUCCESS',
|
||||
UI_SET_TORRENT_SEARCH_FILTER: 'UI_SET_TORRENT_SEARCH_FILTER',
|
||||
UI_SET_TORRENT_SORT: 'UI_SET_TORRENT_SORT',
|
||||
UI_SET_TORRENT_STATUS_FILTER: 'UI_SET_TORRENT_STATUS_FILTER'
|
||||
UI_SET_TORRENT_STATUS_FILTER: 'UI_SET_TORRENT_STATUS_FILTER',
|
||||
UI_SORT_PROPS_REQUEST_SUCCESS: 'UI_SORT_PROPS_REQUEST_SUCCESS',
|
||||
UI_SORT_PROPS_REQUEST_ERROR: 'UI_SORT_PROPS_REQUEST_ERROR'
|
||||
};
|
||||
|
||||
export default ActionTypes;
|
||||
|
||||
@@ -8,6 +8,7 @@ const EventTypes = {
|
||||
CLIENT_TRANSFER_DATA_REQUEST_ERROR: 'CLIENT_TRANSFER_DATA_REQUEST_ERROR',
|
||||
CLIENT_TRANSFER_HISTORY_REQUEST_SUCCESS: 'CLIENT_TRANSFER_HISTORY_REQUEST_SUCCESS',
|
||||
UI_MODAL_CHANGE: 'UI_MODAL_CHANGE',
|
||||
UI_LATEST_TORRENT_LOCATION_CHANGE: 'UI_LATEST_TORRENT_LOCATION_CHANGE',
|
||||
UI_TORRENT_DETAILS_HASH_CHANGE: 'UI_TORRENT_DETAILS_HASH_CHANGE',
|
||||
UI_TORRENT_DETAILS_OPEN_CHANGE: 'UI_TORRENT_DETAILS_OPEN_CHANGE',
|
||||
UI_TORRENT_SELECTION_CHANGE: 'UI_TORRENT_SELECTION_CHANGE',
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import ActionTypes from '../constants/ActionTypes';
|
||||
import AppDispatcher from '../dispatcher/AppDispatcher';
|
||||
import BaseStore from './BaseStore';
|
||||
import TorrentActions from '../actions/TorrentActions';
|
||||
import EventTypes from '../constants/EventTypes';
|
||||
import TorrentActions from '../actions/TorrentActions';
|
||||
import UIActions from '../actions/UIActions';
|
||||
|
||||
class TorrentFilterStoreClass extends BaseStore {
|
||||
constructor() {
|
||||
@@ -18,26 +19,34 @@ class TorrentFilterStoreClass extends BaseStore {
|
||||
};
|
||||
}
|
||||
|
||||
getStatusFilter() {
|
||||
return this.statusFilter;
|
||||
}
|
||||
|
||||
setStatusFilter(filter) {
|
||||
this.statusFilter = filter;
|
||||
this.emit(EventTypes.UI_TORRENTS_FILTER_STATUS_CHANGE);
|
||||
fetchSortProps() {
|
||||
UIActions.fetchSortProps();
|
||||
}
|
||||
|
||||
getSearchFilter() {
|
||||
return this.searchFilter;
|
||||
}
|
||||
|
||||
getStatusFilter() {
|
||||
return this.statusFilter;
|
||||
}
|
||||
|
||||
getTorrentsSort() {
|
||||
return this.sortTorrentsBy;
|
||||
}
|
||||
|
||||
handleSortPropsRequestSuccess(sortBy) {
|
||||
this.setTorrentsSort(sortBy);
|
||||
}
|
||||
|
||||
setSearchFilter(filter) {
|
||||
this.searchFilter = filter;
|
||||
this.emit(EventTypes.UI_TORRENTS_FILTER_SEARCH_CHANGE);
|
||||
}
|
||||
|
||||
getTorrentsSort() {
|
||||
return this.sortTorrentsBy;
|
||||
setStatusFilter(filter) {
|
||||
this.statusFilter = filter;
|
||||
this.emit(EventTypes.UI_TORRENTS_FILTER_STATUS_CHANGE);
|
||||
}
|
||||
|
||||
setTorrentsSort(sortBy) {
|
||||
@@ -61,6 +70,9 @@ AppDispatcher.register((payload) => {
|
||||
case ActionTypes.UI_SET_TORRENT_SORT:
|
||||
TorrentFilterStore.setTorrentsSort(action.data);
|
||||
break;
|
||||
case ActionTypes.UI_SORT_PROPS_REQUEST_SUCCESS:
|
||||
TorrentFilterStore.handleSortPropsRequestSuccess(action.data);
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import ClientActions from '../actions/ClientActions';
|
||||
import config from '../../../../config';
|
||||
import EventTypes from '../constants/EventTypes';
|
||||
|
||||
class ClientDataStoreClass extends BaseStore {
|
||||
class TransferDataStoreClass extends BaseStore {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
@@ -126,43 +126,33 @@ class ClientDataStoreClass extends BaseStore {
|
||||
config.pollInterval
|
||||
);
|
||||
}
|
||||
|
||||
startPollingTorrents() {
|
||||
clearInterval(this.pollTransferDataID);
|
||||
this.pollTransferDataID = null;
|
||||
}
|
||||
|
||||
stopPollingTorrentDetails() {
|
||||
clearInterval(this.pollTorrentDetailsIntervalID);
|
||||
this.isPollingTorrents = false;
|
||||
}
|
||||
}
|
||||
|
||||
const ClientDataStore = new ClientDataStoreClass();
|
||||
const TransferDataStore = new TransferDataStoreClass();
|
||||
|
||||
AppDispatcher.register((payload) => {
|
||||
const {action, source} = payload;
|
||||
|
||||
switch (action.type) {
|
||||
case ActionTypes.CLIENT_FETCH_TRANSFER_DATA_SUCCESS:
|
||||
ClientDataStore.handleTransferDataSuccess(action.data.transferData);
|
||||
TransferDataStore.handleTransferDataSuccess(action.data.transferData);
|
||||
break;
|
||||
case ActionTypes.CLIENT_FETCH_TRANSFER_DATA_ERROR:
|
||||
ClientDataStore.handleTransferDataError(action.data.error);
|
||||
TransferDataStore.handleTransferDataError(action.data.error);
|
||||
break;
|
||||
case ActionTypes.CLIENT_SET_THROTTLE_SUCCESS:
|
||||
ClientDataStore.handleSetThrottleSuccess(action.data.transferData);
|
||||
TransferDataStore.handleSetThrottleSuccess(action.data.transferData);
|
||||
break;
|
||||
case ActionTypes.CLIENT_SET_THROTTLE_ERROR:
|
||||
ClientDataStore.handleSetThrottleError(action.data.error);
|
||||
TransferDataStore.handleSetThrottleError(action.data.error);
|
||||
break;
|
||||
case ActionTypes.CLIENT_FETCH_TRANSFER_HISTORY_ERROR:
|
||||
ClientDataStore.handleTransferHistoryError(action.error);
|
||||
TransferDataStore.handleTransferHistoryError(action.error);
|
||||
break;
|
||||
case ActionTypes.CLIENT_FETCH_TRANSFER_HISTORY_SUCCESS:
|
||||
ClientDataStore.handleTransferHistorySuccess(action.data);
|
||||
TransferDataStore.handleTransferHistorySuccess(action.data);
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
export default ClientDataStore;
|
||||
export default TransferDataStore;
|
||||
@@ -10,6 +10,7 @@ class UIStoreClass extends BaseStore {
|
||||
super();
|
||||
|
||||
this.activeModal = null;
|
||||
this.latestTorrentLocation = null;
|
||||
this.torrentDetailsHash = null;
|
||||
this.torrentDetailsOpen = false;
|
||||
}
|
||||
@@ -21,19 +22,31 @@ class UIStoreClass extends BaseStore {
|
||||
}
|
||||
}
|
||||
|
||||
fetchLatestTorrentLocation() {
|
||||
TorrentActions.fetchLatestTorrentLocation();
|
||||
}
|
||||
|
||||
getActiveModal() {
|
||||
return this.activeModal;
|
||||
}
|
||||
|
||||
setActiveModal(modal) {
|
||||
this.activeModal = modal;
|
||||
this.emit(EventTypes.UI_MODAL_CHANGE);
|
||||
getLatestTorrentLocation() {
|
||||
return this.latestTorrentLocation;
|
||||
}
|
||||
|
||||
getTorrentDetailsHash() {
|
||||
return this.torrentDetailsHash;
|
||||
}
|
||||
|
||||
handleLatestTorrentLocationRequestSuccess(location) {
|
||||
this.latestTorrentLocation = location;
|
||||
this.emit(EventTypes.UI_LATEST_TORRENT_LOCATION_CHANGE);
|
||||
}
|
||||
|
||||
handleLatestTorrentLocationRequestError(error) {
|
||||
console.log(error);
|
||||
}
|
||||
|
||||
handleTorrentClick(hash) {
|
||||
this.torrentDetailsHash = hash;
|
||||
this.emit(EventTypes.UI_TORRENT_DETAILS_HASH_CHANGE);
|
||||
@@ -47,6 +60,11 @@ class UIStoreClass extends BaseStore {
|
||||
isTorrentDetailsOpen() {
|
||||
return this.torrentDetailsOpen;
|
||||
}
|
||||
|
||||
setActiveModal(modal) {
|
||||
this.activeModal = modal;
|
||||
this.emit(EventTypes.UI_MODAL_CHANGE);
|
||||
}
|
||||
}
|
||||
|
||||
const UIStore = new UIStoreClass();
|
||||
@@ -64,6 +82,12 @@ AppDispatcher.register((payload) => {
|
||||
case ActionTypes.UI_DISPLAY_MODAL:
|
||||
UIStore.setActiveModal(action.data);
|
||||
break;
|
||||
case ActionTypes.UI_LATEST_TORRENT_LOCATION_REQUEST_SUCCESS:
|
||||
UIStore.handleLatestTorrentLocationRequestSuccess(action.data.path);
|
||||
break;
|
||||
case ActionTypes.UI_LATEST_TORRENT_LOCATION_REQUEST_ERROR:
|
||||
UIStore.handleLatestTorrentLocationRequestError(action.error);
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
const config = {
|
||||
databasePath: './server/db/',
|
||||
maxHistoryStates: 30,
|
||||
pollInterval: 5000
|
||||
pollInterval: 5000,
|
||||
uiDatabaseCleanInterval: 1000 * 60 * 60 // 1 hour
|
||||
};
|
||||
|
||||
module.exports = config;
|
||||
|
||||
@@ -5,7 +5,8 @@ var favicon = require('serve-favicon');
|
||||
var logger = require('morgan');
|
||||
var path = require('path');
|
||||
|
||||
var client = require('./routes/client');
|
||||
var clientRoutes = require('./routes/client');
|
||||
var uiRoutes = require('./routes/ui');
|
||||
var routes = require('./routes/index');
|
||||
|
||||
var app = express();
|
||||
@@ -33,7 +34,8 @@ app.use(function(req, res, next) {
|
||||
});
|
||||
|
||||
app.use('/', routes);
|
||||
app.use('/client', client);
|
||||
app.use('/client', clientRoutes);
|
||||
app.use('/ui', uiRoutes);
|
||||
|
||||
// catch 404 and forward to error handler
|
||||
app.use(function(req, res, next) {
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -2,9 +2,9 @@
|
||||
|
||||
let Datastore = require('nedb');
|
||||
|
||||
let config = require('../../config');
|
||||
let stringUtil = require('./util/stringUtil');
|
||||
|
||||
const FILE_PATH = './server/db/history/';
|
||||
const MAX_CLEANUP_INTERVAL = 1000 * 60 * 60; // 1 hour
|
||||
const MAX_NEXT_ERA_UPDATE_INTERVAL = 1000 * 60 * 60 * 12; // 12 hours
|
||||
const CUMULATIVE_DATA_BUFFER = 1000 * 2;
|
||||
@@ -92,7 +92,8 @@ class HistoryEra {
|
||||
getData(opts, callback) {
|
||||
let minTimestamp = Date.now() - this.opts.maxTime;
|
||||
|
||||
this.db.find({ts: {$gte: minTimestamp}}).sort({ts: 1})
|
||||
this.db.find({ts: {$gte: minTimestamp}})
|
||||
.sort({ts: 1})
|
||||
.exec(function (err, docs) {
|
||||
callback(err, docs);
|
||||
}
|
||||
@@ -104,7 +105,7 @@ class HistoryEra {
|
||||
|
||||
REQUIRED_FIELDS.forEach(function (field) {
|
||||
if (opts[field] == null) {
|
||||
console.warn(`historyEra requires ${field}`);
|
||||
console.warn(`HistoryEra requires ${field}`);
|
||||
requirementsMet = false;
|
||||
}
|
||||
});
|
||||
@@ -115,7 +116,7 @@ class HistoryEra {
|
||||
loadDatabase(dbName) {
|
||||
let db = new Datastore({
|
||||
autoload: true,
|
||||
filename: `${FILE_PATH}${dbName}.db`
|
||||
filename: `${config.databasePath}history/${dbName}.db`
|
||||
});
|
||||
|
||||
this.ready = true;
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
'use strict';
|
||||
var Datastore = require('nedb');
|
||||
|
||||
var client = require('./client');
|
||||
var config = require('../../config');
|
||||
|
||||
@@ -4,11 +4,9 @@ var Deserializer = require('./util/deserializer');
|
||||
var Serializer = require('./util/serializer');
|
||||
|
||||
var rtorrent = {
|
||||
|
||||
initialized: false,
|
||||
|
||||
get: function(api, array) {
|
||||
|
||||
var stream = net.connect({
|
||||
port: 5000,
|
||||
host: 'localhost'
|
||||
@@ -62,7 +60,6 @@ var rtorrent = {
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = rtorrent;
|
||||
|
||||
70
server/models/uiSettings.js
Normal file
70
server/models/uiSettings.js
Normal file
@@ -0,0 +1,70 @@
|
||||
'use strict';
|
||||
|
||||
let Datastore = require('nedb');
|
||||
|
||||
let config = require('../../config');
|
||||
|
||||
let uiDB = new Datastore({
|
||||
autoload: true,
|
||||
filename: `${config.databasePath}uiSettings.db`
|
||||
});
|
||||
|
||||
uiDB.persistence.setAutocompactionInterval(config.uiDatabaseCleanInterval);
|
||||
|
||||
let uiSettings = {
|
||||
getLatestTorrentLocation: function(callback) {
|
||||
uiDB.find({type: 'location'}, function(error, docs) {
|
||||
if (error) {
|
||||
callback(error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (docs.length) {
|
||||
callback(error, docs[0]);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
getSortProps: function(callback) {
|
||||
uiDB.find({type: 'sort'}, function(error, docs) {
|
||||
if (error) {
|
||||
callback(error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (docs.length) {
|
||||
callback(error, docs[0]);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
setLatestTorrentLocation: function(data, callback) {
|
||||
let newLocationData = Object.assign({}, {type: 'location'}, {path: data.destination});
|
||||
uiDB.update({type: 'location'}, newLocationData, {upsert: true}, function (error, docs) {
|
||||
if (error) {
|
||||
callback(error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (docs.length) {
|
||||
callback(error, docs);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
setSortProps: function(sortProps, callback) {
|
||||
let newSortPropData = Object.assign({}, {type: 'sort'}, sortProps);
|
||||
uiDB.update({type: 'sort'}, newSortPropData, {upsert: true}, function (error, docs) {
|
||||
if (error) {
|
||||
callback(error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (docs.length) {
|
||||
callback(error, docs);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = uiSettings;
|
||||
@@ -1,52 +1,46 @@
|
||||
var express = require('express');
|
||||
var router = express.Router();
|
||||
var xmlrpc = require('xmlrpc');
|
||||
'use strict';
|
||||
|
||||
var client = require('../models/client');
|
||||
var history = require('../models/history');
|
||||
let express = require('express');
|
||||
let router = express.Router();
|
||||
let xmlrpc = require('xmlrpc');
|
||||
|
||||
var handleClientResponse = function (res) {
|
||||
return function (error, response) {
|
||||
if (error) {
|
||||
console.log(error);
|
||||
}
|
||||
res.json(response);
|
||||
}
|
||||
}
|
||||
let ajaxUtil = require('../util/ajaxUtil');
|
||||
let client = require('../models/client');
|
||||
let history = require('../models/history');
|
||||
|
||||
router.post('/add', function(req, res, next) {
|
||||
client.add(req.body, handleClientResponse(res));
|
||||
client.add(req.body, ajaxUtil.getResponseFn(res));
|
||||
});
|
||||
|
||||
router.get('/history', function(req, res, next) {
|
||||
history.get(req.query, handleClientResponse(res));
|
||||
history.get(req.query, ajaxUtil.getResponseFn(res));
|
||||
});
|
||||
|
||||
router.get('/list', function(req, res, next) {
|
||||
client.getTorrentList(handleClientResponse(res));
|
||||
client.getTorrentList(ajaxUtil.getResponseFn(res));
|
||||
});
|
||||
|
||||
router.put('/settings/speed-limits', function(req, res, next) {
|
||||
client.setSpeedLimits(req.body, handleClientResponse(res));
|
||||
client.setSpeedLimits(req.body, ajaxUtil.getResponseFn(res));
|
||||
});
|
||||
|
||||
router.post('/start', function(req, res, next) {
|
||||
var hashes = req.body.hashes;
|
||||
client.startTorrent(hashes, handleClientResponse(res));
|
||||
client.startTorrent(hashes, ajaxUtil.getResponseFn(res));
|
||||
});
|
||||
|
||||
router.get('/stats', function(req, res, next) {
|
||||
client.getTransferStats(handleClientResponse(res));
|
||||
client.getTransferStats(ajaxUtil.getResponseFn(res));
|
||||
});
|
||||
|
||||
router.post('/stop', function(req, res, next) {
|
||||
var hashes = req.body.hashes;
|
||||
client.stopTorrent(hashes, handleClientResponse(res));
|
||||
client.stopTorrent(hashes, ajaxUtil.getResponseFn(res));
|
||||
});
|
||||
|
||||
router.post('/torrent-details', function(req, res, next) {
|
||||
var hash = req.body.hash;
|
||||
client.getTorrentDetails(hash, handleClientResponse(res));
|
||||
client.getTorrentDetails(hash, ajaxUtil.getResponseFn(res));
|
||||
});
|
||||
|
||||
router.get('/methods.json', function(req, res, next) {
|
||||
@@ -60,7 +54,7 @@ router.get('/methods.json', function(req, res, next) {
|
||||
method = 'system.methodSignature';
|
||||
}
|
||||
|
||||
client.listMethods(method, args, handleClientResponse(res));
|
||||
client.listMethods(method, args, ajaxUtil.getResponseFn(res));
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
|
||||
28
server/routes/ui.js
Normal file
28
server/routes/ui.js
Normal file
@@ -0,0 +1,28 @@
|
||||
'use strict';
|
||||
|
||||
let express = require('express');
|
||||
let router = express.Router();
|
||||
let xmlrpc = require('xmlrpc');
|
||||
|
||||
let ajaxUtil = require('../util/ajaxUtil');
|
||||
let client = require('../models/client');
|
||||
let history = require('../models/history');
|
||||
let uiSettings = require('../models/uiSettings');
|
||||
|
||||
router.post('/sort-props', function(req, res, next) {
|
||||
uiSettings.setSortProps(req.body, ajaxUtil.getResponseFn(res));
|
||||
});
|
||||
|
||||
router.get('/sort-props', function(req, res, next) {
|
||||
uiSettings.getSortProps(ajaxUtil.getResponseFn(res));
|
||||
});
|
||||
|
||||
router.get('/torrent-location', function(req, res, next) {
|
||||
uiSettings.getLatestTorrentLocation(ajaxUtil.getResponseFn(res));
|
||||
});
|
||||
|
||||
router.post('/torrent-location', function(req, res, next) {
|
||||
uiSettings.setLatestTorrentLocation(req.body, ajaxUtil.getResponseFn(res));
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
14
server/util/ajaxUtil.js
Normal file
14
server/util/ajaxUtil.js
Normal file
@@ -0,0 +1,14 @@
|
||||
'use strict';
|
||||
|
||||
let ajaxUtil = {
|
||||
getResponseFn: function (res) {
|
||||
return function (error, response) {
|
||||
if (error) {
|
||||
console.log('error in getResponseFn', error);
|
||||
}
|
||||
res.json(response);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = ajaxUtil;
|
||||
Reference in New Issue
Block a user