feat(filter): torrents filters (basic maxFiles filter)

This commit is contained in:
Alexey Kasyanchuk 2018-04-01 22:36:30 +03:00
parent 534999d1cb
commit 5348d1f88f
7 changed files with 264 additions and 2 deletions

128
src/app/filters-page.js Normal file
View File

@ -0,0 +1,128 @@
import React from 'react';
import Page from './page';
import Toggle from 'material-ui/Toggle';
import RaisedButton from 'material-ui/RaisedButton';
import TextField from 'material-ui/TextField'
import Slider from 'material-ui/Slider'
import fs from 'fs'
const {dialog} = require('electron').remote
export default class ConfigPage extends Page {
constructor(props) {
super(props)
this.setTitle('Rats filters');
this.options = {}
}
componentDidMount() {
this.loadSettings()
}
loadSettings() {
window.torrentSocket.emit('config', window.customLoader((options) => {
this.options = options;
console.log(this.options)
this.forceUpdate();
}));
}
saveSettings() {
window.torrentSocket.emit('setConfig', this.options)
this.settingsSavedMessage = true
this.forceUpdate()
setTimeout(() => {
this.settingsSavedMessage = false
this.forceUpdate()
}, 1000)
}
render() {
return (
<div>
<div className='row center pad0-75'>
<RaisedButton label="Back to main page" primary={true} onClick={() => {
window.router('/')
}} />
</div>
<div className='column center w100p pad0-75'>
<div className='column w100p'>
<div className='row inline w100p'>
<div style={{flex: 1}}>Max files per torrent (current: {this.options.filters && this.options.filters.maxFiles})</div>
<Slider
min={0}
max={50000}
step={1}
style={{width: 300}}
value={this.options.spider && this.options.filters.maxFiles}
onChange={(event, value) => {
this.options.filters.maxFiles = value
this.forceUpdate()
}}
/>
<TextField
hintText="Max files"
className='pad0-75'
style={{width: 200}}
value={this.options.filters && this.options.filters.maxFiles}
onChange={(e, value) => {
if(!this.options.filters)
return
this.options.filters.maxFiles = parseInt(value)
this.forceUpdate()
}}
/>
</div>
<div className='fs0-75' style={{color: 'grey'}}>* 0 - Disabled.
</div>
</div>
<div className='row center pad0-75'>
<RaisedButton label="Check torrents" primary={true} onClick={() => {
window.torrentSocket.emit('removeTorrents', true, window.customLoader((toRemove) => {
this.toRemoveProbably = toRemove
this.forceUpdate()
}));
}} />
<RaisedButton label="Clean torrents" secondary={true} onClick={() => {
window.torrentSocket.emit('removeTorrents', false, window.customLoader((toRemove) => {
this.toRemove = toRemove
this.forceUpdate()
}));
}} />
</div>
{
this.toRemoveProbably && this.toRemoveProbably > 0
?
<div style={{color: 'orange'}}>Torrents to clean: {this.toRemoveProbably}</div>
:
null
}
{
this.toRemove && this.toRemove > 0
?
<div style={{color: 'red'}}>Torrents cleaned: {this.toRemove}</div>
:
null
}
{
this.settingsSavedMessage
&&
<div style={{color: 'green'}}>Settings saved</div>
}
<div className='row center pad0-75'>
<RaisedButton label="Save Settings" primary={true} onClick={() => {
this.saveSettings()
}} />
</div>
</div>
</div>
);
}
}

View File

@ -49,6 +49,60 @@ const Header = (props) => {
C302.1,704.538,332,675.438,368.3,675.837z"/> C302.1,704.538,332,675.438,368.3,675.837z"/>
</g> </g>
</svg> </svg>
<svg className='clickable'
onClick={() => {
window.router('/filters')
}}
fill='white' style={{height: 45, margin: 4}} viewBox="0 0 512 512">
<g>
<g>
<path d="M256,103.536c-58.559,0-106.2,47.641-106.2,106.2c0,4.512,3.657,8.169,8.169,8.169s8.169-3.658,8.169-8.169
c0-49.55,40.313-89.862,89.862-89.862c49.549,0,89.862,40.311,89.862,89.862c0,4.512,3.658,8.169,8.169,8.169
c4.513,0,8.169-3.658,8.169-8.169C362.2,151.177,314.559,103.536,256,103.536z"/>
</g>
</g>
<g>
<g>
<path d="M256,136.213c-40.541,0-73.523,32.982-73.523,73.523c0,4.512,3.657,8.169,8.169,8.169s8.169-3.658,8.169-8.169
c0-31.532,25.654-57.185,57.185-57.185s57.185,25.653,57.185,57.185c0,4.512,3.657,8.169,8.169,8.169
c4.513,0,8.169-3.658,8.169-8.169C329.523,169.195,296.541,136.213,256,136.213z"/>
</g>
</g>
<g>
<g>
<path d="M503.801,234.245H8.199c-4.513,0-8.169,3.658-8.169,8.169v43.569c0,2.721,1.354,5.263,3.612,6.781L167.331,402.76
c5.092,3.857,9.699,13.038,9.699,19.379v81.693c0,4.512,3.656,8.169,8.169,8.169h141.6c4.513,0,8.169-3.658,8.169-8.169v-81.693
c0-6.34,4.606-15.522,9.699-19.379l163.691-109.995c2.258-1.517,3.612-4.06,3.612-6.781v-43.569
C511.97,237.903,508.313,234.245,503.801,234.245z M495.632,277.815H157.969c-4.513,0-8.169,3.658-8.169,8.169
s3.657,8.169,8.169,8.169h319.028l-141.61,95.159c-0.1,0.068-0.199,0.137-0.296,0.209c-9.383,6.93-16.458,20.951-16.458,32.616
v73.523H193.37v-73.523c0-11.665-7.076-25.686-16.458-32.616c-0.098-0.072-0.197-0.142-0.296-0.209L35.003,294.153h90.289
c4.513,0,8.169-3.658,8.169-8.169s-3.657-8.169-8.169-8.169H16.368v-27.231h479.263V277.815z"/>
</g>
</g>
<g>
<g>
<path d="M296.504,397.63h-81.006c-4.513,0-8.169,3.658-8.169,8.169c0,4.512,3.657,8.169,8.169,8.169h81.006
c4.513,0,8.169-3.658,8.169-8.169C304.674,401.288,301.016,397.63,296.504,397.63z"/>
</g>
</g>
<g>
<g>
<path d="M458.171,168.573l-36.481-3.382c-3.895-14.477-9.68-28.351-17.251-41.376l23.416-28.2
c2.696-3.246,2.475-8.011-0.509-10.995l-46.545-46.545c-2.983-2.983-7.749-3.206-10.996-0.509L341.51,61.063
c-13.017-7.52-26.88-13.258-41.343-17.113l-3.386-36.534C296.391,3.213,292.866,0,288.647,0h-65.826
c-4.22,0-7.745,3.213-8.134,7.416l-3.401,36.68c-14.413,3.894-28.222,9.657-41.187,17.193L141.73,37.731
c-3.247-2.697-8.011-2.475-10.996,0.509L84.189,84.785c-2.983,2.983-3.203,7.749-0.509,10.995l23.634,28.465
c-7.486,12.964-13.206,26.763-17.059,41.156l-36.728,3.404c-4.201,0.389-7.416,3.915-7.416,8.134v32.798
c0.001,4.513,3.658,8.17,8.17,8.17s8.169-3.658,8.169-8.169v-25.352l35.083-3.251c3.51-0.325,6.415-2.864,7.206-6.298
c3.835-16.632,10.393-32.454,19.49-47.028c1.865-2.988,1.606-6.835-0.645-9.544l-22.579-27.193l36.013-36.013l27.111,22.511
c2.717,2.256,6.576,2.511,9.563,0.633c14.566-9.15,30.394-15.758,47.046-19.64c3.426-0.798,5.955-3.7,6.279-7.202l3.247-35.022
h50.931l3.235,34.896c0.326,3.513,2.869,6.419,6.307,7.209c16.7,3.833,32.582,10.405,47.205,19.535
c2.986,1.866,6.834,1.607,9.545-0.645l27.023-22.438l36.013,36.013l-22.371,26.941c-2.255,2.717-2.511,6.575-0.632,9.565
c9.189,14.625,15.814,30.514,19.69,47.225c0.795,3.429,3.699,5.964,7.203,6.287l34.829,3.229v25.582
c0,4.512,3.657,8.169,8.169,8.169s8.169-3.658,8.169-8.169v-33.029C465.586,172.488,462.373,168.963,458.171,168.573z"/>
</g>
</g>
</svg>
</div> </div>
Welcome to ROTB! This is file search engine based on the torrents from the internet. Welcome to ROTB! This is file search engine based on the torrents from the internet.

View File

@ -8,6 +8,7 @@ import ConfigPage from './config-page.js'
import TopPage from './top-page.js' import TopPage from './top-page.js'
import DownloadPage from './download-page.js' import DownloadPage from './download-page.js'
import ChangelogPage from './changelog-page.js' import ChangelogPage from './changelog-page.js'
import FiltersPage from './filters-page.js'
let routers = {} let routers = {}
const router = (page, callback) => { const router = (page, callback) => {
@ -75,6 +76,11 @@ router('/config', () => {
PagesPie.instance().open(ConfigPage, {replace: 'all'}); PagesPie.instance().open(ConfigPage, {replace: 'all'});
}); });
router('/filters', () => {
//singleton
PagesPie.instance().open(FiltersPage, {replace: 'all'});
});
router('/top', () => { router('/top', () => {
//singleton //singleton
PagesPie.instance().open(TopPage, {replace: 'all'}); PagesPie.instance().open(TopPage, {replace: 'all'});

View File

@ -11,7 +11,9 @@ module.exports = ({
spider, spider,
upnp, upnp,
crypto, crypto,
insertTorrentToDB insertTorrentToDB,
removeTorrentFromDB,
checkTorrent
}) => { }) => {
let torrentClientHashMap = {} let torrentClientHashMap = {}
@ -601,6 +603,44 @@ module.exports = ({
}))) })))
}) })
recive('removeTorrents', (checkOnly = true, callback) =>
{
console.log('checktorrents call')
const toRemove = []
const done = () => {
console.log('torrents to remove founded', toRemove.length)
if(checkOnly)
{
callback(toRemove.length)
return
}
toRemove.forEach(torrent => removeTorrentFromDB(torrent))
callback(toRemove.length)
console.log('removed torrents by filter:', toRemove.length)
}
const checker = (index = 0) => {
sphinx.query(`SELECT * FROM torrents LIMIT ${index},50000`, (err, torrents) => {
if(err || torrents.length == 0)
{
done()
return
}
torrents.forEach((torrent) => {
if(!checkTorrent(torrent))
toRemove.push(torrent)
})
checker(index + torrents.length)
});
}
checker()
})
let socketIPV4 = () => { let socketIPV4 = () => {
let ip = socket.request.connection.remoteAddress; let ip = socket.request.connection.remoteAddress;
if (ipaddr.IPv4.isValid(ip)) { if (ipaddr.IPv4.isValid(ip)) {

View File

@ -36,6 +36,10 @@ let config = {
timeout: 5000 timeout: 5000
}, },
filters: {
maxFiles: 0,
},
cleanup: true, cleanup: true,
cleanupDiscLimit: 7 * 1024 * 1024 * 1024, cleanupDiscLimit: 7 * 1024 * 1024 * 1024,
spaceQuota: false, spaceQuota: false,

View File

@ -9,6 +9,13 @@ export const settingsMenuTemplate = {
click: () => { click: () => {
BrowserWindow.getFocusedWindow().webContents.send('url', '/config') BrowserWindow.getFocusedWindow().webContents.send('url', '/config')
} }
},
{
label: "Torrents filters",
accelerator: "CmdOrCtrl+\\",
click: () => {
BrowserWindow.getFocusedWindow().webContents.send('url', '/filters')
}
} }
] ]
}; };

View File

@ -447,6 +447,16 @@ const cleanupTorrents = (cleanTorrents = 1) => {
*/ */
} }
const checkTorrent = (torrent) => {
if(config.filters.maxFiles > 0 && torrent.files > config.filters.maxFiles)
{
console.log('ignore', torrent.name, 'because files', torrent.files, '>', config.filters.maxFiles)
return false
}
return true
}
const insertTorrentToDB = (torrent) => { const insertTorrentToDB = (torrent) => {
if(!torrent) if(!torrent)
return return
@ -463,6 +473,11 @@ const insertTorrentToDB = (torrent) => {
delete torrent.contenttype; delete torrent.contenttype;
} }
if(!checkTorrent(torrent))
{
return
}
const { filesList } = torrent const { filesList } = torrent
delete torrent.filesList; delete torrent.filesList;
@ -533,6 +548,12 @@ const insertTorrentToDB = (torrent) => {
}) })
} }
const removeTorrentFromDB = (torrent) => {
const {hash} = torrent
mysqlSingle.query('DELETE FROM torrents WHERE hash = ?', hash)
mysqlSingle.query('DELETE FROM files WHERE hash = ?', hash)
}
const updateTorrent = (metadata, infohash, rinfo) => { const updateTorrent = (metadata, infohash, rinfo) => {
console.log('finded torrent', metadata.info.name, ' and add to database'); console.log('finded torrent', metadata.info.name, ' and add to database');
@ -713,7 +734,9 @@ API({
spider, spider,
upnp, upnp,
crypto, crypto,
insertTorrentToDB insertTorrentToDB,
removeTorrentFromDB,
checkTorrent
}) })
if(config.indexer) { if(config.indexer) {