diff --git a/web/.eslintcache b/web/.eslintcache
index c976326..80b1a76 100644
--- a/web/.eslintcache
+++ b/web/.eslintcache
@@ -1 +1 @@
-[{"/home/yourok/MEGAWork/Web/TorrServerWeb/src/index.js":"1","/home/yourok/MEGAWork/Web/TorrServerWeb/src/App.js":"2","/home/yourok/MEGAWork/Web/TorrServerWeb/src/components/Appbar.js":"3","/home/yourok/MEGAWork/Web/TorrServerWeb/src/components/TorrentList.js":"4","/home/yourok/MEGAWork/Web/TorrServerWeb/src/components/RemoveAll.js":"5","/home/yourok/MEGAWork/Web/TorrServerWeb/src/components/Add.js":"6","/home/yourok/MEGAWork/Web/TorrServerWeb/src/components/Upload.js":"7","/home/yourok/MEGAWork/Web/TorrServerWeb/src/utils/Hosts.js":"8","/home/yourok/MEGAWork/Web/TorrServerWeb/src/components/Donate.js":"9","/home/yourok/MEGAWork/Web/TorrServerWeb/src/components/Settings.js":"10","/home/yourok/MEGAWork/Web/TorrServerWeb/src/components/Torrent.js":"11","/home/yourok/MEGAWork/Web/TorrServerWeb/src/components/DialogCacheInfo.js":"12","/home/yourok/MEGAWork/Web/TorrServerWeb/src/utils/Utils.js":"13","/home/yourok/MEGAWork/Web/TorrServerWeb/src/components/DialogTorrentInfo.js":"14","/home/yourok/MEGAWork/go/TorrServer/web/src/index.js":"15","/home/yourok/MEGAWork/go/TorrServer/web/src/App.js":"16","/home/yourok/MEGAWork/go/TorrServer/web/src/components/Appbar.js":"17","/home/yourok/MEGAWork/go/TorrServer/web/src/components/TorrentList.js":"18","/home/yourok/MEGAWork/go/TorrServer/web/src/components/Add.js":"19","/home/yourok/MEGAWork/go/TorrServer/web/src/components/RemoveAll.js":"20","/home/yourok/MEGAWork/go/TorrServer/web/src/components/Donate.js":"21","/home/yourok/MEGAWork/go/TorrServer/web/src/components/Upload.js":"22","/home/yourok/MEGAWork/go/TorrServer/web/src/components/Settings.js":"23","/home/yourok/MEGAWork/go/TorrServer/web/src/utils/Hosts.js":"24","/home/yourok/MEGAWork/go/TorrServer/web/src/components/Torrent.js":"25","/home/yourok/MEGAWork/go/TorrServer/web/src/components/DialogTorrentInfo.js":"26","/home/yourok/MEGAWork/go/TorrServer/web/src/components/DialogCacheInfo.js":"27","/home/yourok/MEGAWork/go/TorrServer/web/src/utils/Utils.js":"28"},{"size":224,"mtime":1607328766846,"results":"29","hashOfConfig":"30"},{"size":840,"mtime":1607329513826,"results":"31","hashOfConfig":"30"},{"size":6484,"mtime":1607340369952,"results":"32","hashOfConfig":"30"},{"size":1568,"mtime":1607340137621,"results":"33","hashOfConfig":"30"},{"size":1416,"mtime":1607335705443,"results":"34","hashOfConfig":"30"},{"size":3345,"mtime":1607335694784,"results":"35","hashOfConfig":"30"},{"size":1348,"mtime":1607335733737,"results":"36","hashOfConfig":"30"},{"size":737,"mtime":1607427032081,"results":"37","hashOfConfig":"30"},{"size":2793,"mtime":1607330316050,"results":"38","hashOfConfig":"30"},{"size":9183,"mtime":1608638362207,"results":"39","hashOfConfig":"30"},{"size":6820,"mtime":1607591408226,"results":"40","hashOfConfig":"30"},{"size":4168,"mtime":1608211292654,"results":"41","hashOfConfig":"30"},{"size":428,"mtime":1607431364533,"results":"42","hashOfConfig":"30"},{"size":4424,"mtime":1608211201124,"results":"43","hashOfConfig":"30"},{"size":224,"mtime":1607328766846,"results":"44","hashOfConfig":"45"},{"size":840,"mtime":1607329513826,"results":"46","hashOfConfig":"45"},{"size":6484,"mtime":1607340369952,"results":"47","hashOfConfig":"45"},{"size":1568,"mtime":1607340137621,"results":"48","hashOfConfig":"45"},{"size":3345,"mtime":1607335694784,"results":"49","hashOfConfig":"45"},{"size":1416,"mtime":1607335705443,"results":"50","hashOfConfig":"45"},{"size":2793,"mtime":1607330316050,"results":"51","hashOfConfig":"45"},{"size":1348,"mtime":1607335733737,"results":"52","hashOfConfig":"45"},{"size":9183,"mtime":1608638362207,"results":"53","hashOfConfig":"45"},{"size":737,"mtime":1607427032081,"results":"54","hashOfConfig":"45"},{"size":6820,"mtime":1607591408226,"results":"55","hashOfConfig":"45"},{"size":4424,"mtime":1608211201124,"results":"56","hashOfConfig":"45"},{"size":4173,"mtime":1608803193680,"results":"57","hashOfConfig":"45"},{"size":428,"mtime":1607431364533,"results":"58","hashOfConfig":"45"},{"filePath":"59","messages":"60","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"61"},"bgudbu",{"filePath":"62","messages":"63","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"61"},{"filePath":"64","messages":"65","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"61"},{"filePath":"66","messages":"67","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"61"},{"filePath":"68","messages":"69","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"61"},{"filePath":"70","messages":"71","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"61"},{"filePath":"72","messages":"73","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"61"},{"filePath":"74","messages":"75","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"61"},{"filePath":"76","messages":"77","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"61"},{"filePath":"78","messages":"79","errorCount":0,"warningCount":2,"fixableErrorCount":0,"fixableWarningCount":0,"source":"80","usedDeprecatedRules":"61"},{"filePath":"81","messages":"82","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"61"},{"filePath":"83","messages":"84","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"61"},{"filePath":"85","messages":"86","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"87"},{"filePath":"88","messages":"89","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"61"},{"filePath":"90","messages":"91","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"92"},"17eruzz",{"filePath":"93","messages":"94","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"92"},{"filePath":"95","messages":"96","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"92"},{"filePath":"97","messages":"98","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"92"},{"filePath":"99","messages":"100","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"92"},{"filePath":"101","messages":"102","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"92"},{"filePath":"103","messages":"104","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"92"},{"filePath":"105","messages":"106","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"92"},{"filePath":"107","messages":"108","errorCount":0,"warningCount":2,"fixableErrorCount":0,"fixableWarningCount":0,"source":"80","usedDeprecatedRules":"92"},{"filePath":"109","messages":"110","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"92"},{"filePath":"111","messages":"112","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"92"},{"filePath":"113","messages":"114","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"92"},{"filePath":"115","messages":"116","errorCount":0,"warningCount":3,"fixableErrorCount":0,"fixableWarningCount":0,"source":"117"},{"filePath":"118","messages":"119","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"92"},"/home/yourok/MEGAWork/Web/TorrServerWeb/src/index.js",[],["120","121"],"/home/yourok/MEGAWork/Web/TorrServerWeb/src/App.js",[],"/home/yourok/MEGAWork/Web/TorrServerWeb/src/components/Appbar.js",[],"/home/yourok/MEGAWork/Web/TorrServerWeb/src/components/TorrentList.js",[],"/home/yourok/MEGAWork/Web/TorrServerWeb/src/components/RemoveAll.js",[],"/home/yourok/MEGAWork/Web/TorrServerWeb/src/components/Add.js",[],"/home/yourok/MEGAWork/Web/TorrServerWeb/src/components/Upload.js",[],"/home/yourok/MEGAWork/Web/TorrServerWeb/src/utils/Hosts.js",[],"/home/yourok/MEGAWork/Web/TorrServerWeb/src/components/Donate.js",[],"/home/yourok/MEGAWork/Web/TorrServerWeb/src/components/Settings.js",["122","123"],"import ListItem from '@material-ui/core/ListItem'\nimport ListItemIcon from '@material-ui/core/ListItemIcon'\nimport ListItemText from '@material-ui/core/ListItemText'\nimport React, { useEffect } from 'react'\nimport SettingsIcon from '@material-ui/icons/Settings'\nimport Dialog from '@material-ui/core/Dialog'\nimport DialogTitle from '@material-ui/core/DialogTitle'\nimport DialogContent from '@material-ui/core/DialogContent'\nimport TextField from '@material-ui/core/TextField'\nimport DialogActions from '@material-ui/core/DialogActions'\nimport Button from '@material-ui/core/Button'\nimport { FormControlLabel, InputLabel, Select, Switch } from '@material-ui/core'\nimport { settingsHost, setTorrServerHost, torrserverHost } from '../utils/Hosts'\n\nexport default function SettingsDialog() {\n const [open, setOpen] = React.useState(false)\n const [settings, setSets] = React.useState({})\n const [show, setShow] = React.useState(false)\n const [tsHost, setTSHost] = React.useState(torrserverHost ? torrserverHost : window.location.protocol + '//' + window.location.hostname + (window.location.port ? ':' + window.location.port : ''))\n\n const handleClickOpen = () => {\n setOpen(true)\n }\n const handleClose = () => {\n setOpen(false)\n }\n const handleCloseSave = () => {\n setOpen(false)\n let sets = JSON.parse(JSON.stringify(settings))\n sets.CacheSize *= 1024 * 1024\n sets.PreloadBufferSize *= 1024 * 1024\n fetch(settingsHost(), {\n method: 'post',\n body: JSON.stringify({ action: 'set', sets: sets }),\n headers: {\n Accept: 'application/json, text/plain, */*',\n 'Content-Type': 'application/json',\n },\n })\n }\n\n useEffect(() => {\n fetch(settingsHost(), {\n method: 'post',\n body: JSON.stringify({ action: 'get' }),\n headers: {\n Accept: 'application/json, text/plain, */*',\n 'Content-Type': 'application/json',\n },\n })\n .then((res) => res.json())\n .then(\n (json) => {\n json.CacheSize /= 1024 * 1024\n json.PreloadBufferSize /= 1024 * 1024\n setSets(json)\n setShow(true)\n },\n (error) => {\n setShow(false)\n console.log(error)\n }\n )\n .catch((e) => {\n setShow(false)\n console.log(e)\n })\n }, [tsHost])\n\n const onInputHost = (event) => {\n let host = event.target.value\n setTorrServerHost(host)\n setTSHost(host)\n }\n\n const inputForm = (event) => {\n let sets = JSON.parse(JSON.stringify(settings))\n if (event.target.type === 'number' || event.target.type === 'select-one') {\n sets[event.target.id] = Number(event.target.value)\n } else if (event.target.type === 'checkbox') {\n sets[event.target.id] = Boolean(event.target.checked)\n }\n setSets(sets)\n }\n\n return (\n
\n \n \n \n \n \n \n \n
\n )\n}\n\n/*\n{\n\t\"CacheSize\": 209715200,\n\t\"PreloadBufferSize\": 20971520,\n\t\"RetrackersMode\": 1,\n\t\"TorrentDisconnectTimeout\": 30,\n\t\"EnableIPv6\": false,\n\t\"DisableTCP\": false,\n\t\"DisableUTP\": true,\n\t\"DisableUPNP\": false,\n\t\"DisableDHT\": false,\n\t\"DisableUpload\": false,\n\t\"DownloadRateLimit\": 0,\n\t\"UploadRateLimit\": 0,\n\t\"ConnectionsLimit\": 20,\n\t\"DhtConnectionLimit\": 500,\n\t\"PeersListenPort\": 0\n}\n */\n","/home/yourok/MEGAWork/Web/TorrServerWeb/src/components/Torrent.js",[],"/home/yourok/MEGAWork/Web/TorrServerWeb/src/components/DialogCacheInfo.js",[],"/home/yourok/MEGAWork/Web/TorrServerWeb/src/utils/Utils.js",[],["124","125"],"/home/yourok/MEGAWork/Web/TorrServerWeb/src/components/DialogTorrentInfo.js",[],"/home/yourok/MEGAWork/go/TorrServer/web/src/index.js",[],["126","127"],"/home/yourok/MEGAWork/go/TorrServer/web/src/App.js",[],"/home/yourok/MEGAWork/go/TorrServer/web/src/components/Appbar.js",[],"/home/yourok/MEGAWork/go/TorrServer/web/src/components/TorrentList.js",[],"/home/yourok/MEGAWork/go/TorrServer/web/src/components/Add.js",[],"/home/yourok/MEGAWork/go/TorrServer/web/src/components/RemoveAll.js",[],"/home/yourok/MEGAWork/go/TorrServer/web/src/components/Donate.js",[],"/home/yourok/MEGAWork/go/TorrServer/web/src/components/Upload.js",[],"/home/yourok/MEGAWork/go/TorrServer/web/src/components/Settings.js",["128","129"],"/home/yourok/MEGAWork/go/TorrServer/web/src/utils/Hosts.js",[],"/home/yourok/MEGAWork/go/TorrServer/web/src/components/Torrent.js",[],"/home/yourok/MEGAWork/go/TorrServer/web/src/components/DialogTorrentInfo.js",[],"/home/yourok/MEGAWork/go/TorrServer/web/src/components/DialogCacheInfo.js",["130","131","132"],"import React, { useEffect, useRef } from 'react'\nimport Typography from '@material-ui/core/Typography'\n\nimport { getPeerString, humanizeSize } from '../utils/Utils'\nimport DialogTitle from '@material-ui/core/DialogTitle'\nimport DialogContent from '@material-ui/core/DialogContent'\nimport { cacheHost } from '../utils/Hosts'\n\nexport default function DialogCacheInfo(props) {\n const [hash] = React.useState(props.hash)\n const [cache, setCache] = React.useState({})\n const timerID = useRef(-1)\n\n useEffect(() => {\n if (hash)\n timerID.current = setInterval(() => {\n getCache(hash, (cache) => {\n setCache(cache)\n })\n }, 1000)\n else clearInterval(timerID.current)\n\n return () => {\n clearInterval(timerID.current)\n }\n }, [hash, props.open])\n\n return (\n \n
\n \n Hash {cache.Hash}\n
\n Capacity {humanizeSize(cache.Capacity)}\n
\n Filled {humanizeSize(cache.Filled)}\n
\n Torrent size {cache.Torrent && cache.Torrent.torrent_size && humanizeSize(cache.Torrent.torrent_size)}\n
\n Pieces length {humanizeSize(cache.PiecesLength)}\n
\n Pieces count {cache.PiecesCount}\n
\n Peers: {getPeerString(cache.Torrent)}\n
\n Download speed {cache.Torrent && cache.Torrent.download_speed ? humanizeSize(cache.Torrent.download_speed) + '/sec' : ''}\n
\n Status {cache.Torrent && cache.Torrent.stat_string && cache.Torrent.stat_string}\n \n \n
\n \n \n
\n )\n}\n\nfunction getCacheMap(cache) {\n if (!cache || !cache.PiecesCount) return ''\n var html = ''\n for (let i = 0; i < cache.PiecesCount; i++) {\n html += \" {\n if (i >= r.Start && i <= r.End && i != r.Reader)\n html += ' reader-range'\n if (i == r.Reader) {\n html += ' piece-reader'\n info += ' reader'\n }\n })\n }\n html += \"' title='\" + info + \"'>\"\n }\n return html\n}\n\nfunction getCache(hash, callback) {\n try {\n fetch(cacheHost(), {\n method: 'post',\n body: JSON.stringify({ action: 'get', hash: hash }),\n headers: {\n Accept: 'application/json, text/plain, */*',\n 'Content-Type': 'application/json',\n },\n })\n .then((res) => res.json())\n .then(\n (json) => {\n callback(json)\n },\n (error) => {\n callback({})\n console.error(error)\n }\n )\n } catch (e) {\n console.error(e)\n callback({})\n }\n}\n/*\n{\n\t\"Hash\": \"41e36c8de915d80db83fc134bee4e7e2d292657e\",\n\t\"Capacity\": 209715200,\n\t\"Filled\": 2914808,\n\t\"PiecesLength\": 4194304,\n\t\"PiecesCount\": 2065,\n\t\"DownloadSpeed\": 32770.860273455524,\n\t\"Pieces\": {\n\t\t\"2064\": {\n\t\t\t\"Id\": 2064,\n\t\t\t\"Length\": 2914808,\n\t\t\t\"Size\": 162296,\n\t\t\t\"Completed\": false\n\t\t}\n\t}\n}\n */\n","/home/yourok/MEGAWork/go/TorrServer/web/src/utils/Utils.js",[],{"ruleId":"133","replacedBy":"134"},{"ruleId":"135","replacedBy":"136"},{"ruleId":"137","severity":1,"message":"138","line":103,"column":29,"nodeType":"139","endLine":103,"endColumn":35},{"ruleId":"137","severity":1,"message":"138","line":139,"column":29,"nodeType":"139","endLine":139,"endColumn":35},{"ruleId":"133","replacedBy":"140"},{"ruleId":"135","replacedBy":"141"},{"ruleId":"133","replacedBy":"142"},{"ruleId":"135","replacedBy":"143"},{"ruleId":"137","severity":1,"message":"138","line":103,"column":29,"nodeType":"139","endLine":103,"endColumn":35},{"ruleId":"137","severity":1,"message":"138","line":139,"column":29,"nodeType":"139","endLine":139,"endColumn":35},{"ruleId":"144","severity":1,"message":"145","line":74,"column":35,"nodeType":"146","messageId":"147","endLine":81,"endColumn":14},{"ruleId":"148","severity":1,"message":"149","line":75,"column":53,"nodeType":"150","messageId":"151","endLine":75,"endColumn":55},{"ruleId":"148","severity":1,"message":"152","line":77,"column":23,"nodeType":"150","messageId":"151","endLine":77,"endColumn":25},"no-native-reassign",["153"],"no-negated-in-lhs",["154"],"jsx-a11y/heading-has-content","Headings must have content and the content must be accessible by a screen reader.","JSXOpeningElement",["153"],["154"],["153"],["154"],"no-loop-func","Function declared in a loop contains unsafe references to variable(s) 'html', 'html'.","ArrowFunctionExpression","unsafeRefs","eqeqeq","Expected '!==' and instead saw '!='.","BinaryExpression","unexpected","Expected '===' and instead saw '=='.","no-global-assign","no-unsafe-negation"]
\ No newline at end of file
+[{"/home/yourok/MEGAWork/Web/TorrServerWeb/src/index.js":"1","/home/yourok/MEGAWork/Web/TorrServerWeb/src/App.js":"2","/home/yourok/MEGAWork/Web/TorrServerWeb/src/components/Appbar.js":"3","/home/yourok/MEGAWork/Web/TorrServerWeb/src/components/TorrentList.js":"4","/home/yourok/MEGAWork/Web/TorrServerWeb/src/components/RemoveAll.js":"5","/home/yourok/MEGAWork/Web/TorrServerWeb/src/components/Add.js":"6","/home/yourok/MEGAWork/Web/TorrServerWeb/src/components/Upload.js":"7","/home/yourok/MEGAWork/Web/TorrServerWeb/src/utils/Hosts.js":"8","/home/yourok/MEGAWork/Web/TorrServerWeb/src/components/Donate.js":"9","/home/yourok/MEGAWork/Web/TorrServerWeb/src/components/Settings.js":"10","/home/yourok/MEGAWork/Web/TorrServerWeb/src/components/Torrent.js":"11","/home/yourok/MEGAWork/Web/TorrServerWeb/src/components/DialogCacheInfo.js":"12","/home/yourok/MEGAWork/Web/TorrServerWeb/src/utils/Utils.js":"13","/home/yourok/MEGAWork/Web/TorrServerWeb/src/components/DialogTorrentInfo.js":"14","/home/yourok/MEGAWork/go/TorrServer/web/src/index.js":"15","/home/yourok/MEGAWork/go/TorrServer/web/src/App.js":"16","/home/yourok/MEGAWork/go/TorrServer/web/src/components/Appbar.js":"17","/home/yourok/MEGAWork/go/TorrServer/web/src/components/TorrentList.js":"18","/home/yourok/MEGAWork/go/TorrServer/web/src/components/Add.js":"19","/home/yourok/MEGAWork/go/TorrServer/web/src/components/RemoveAll.js":"20","/home/yourok/MEGAWork/go/TorrServer/web/src/components/Donate.js":"21","/home/yourok/MEGAWork/go/TorrServer/web/src/components/Upload.js":"22","/home/yourok/MEGAWork/go/TorrServer/web/src/components/Settings.js":"23","/home/yourok/MEGAWork/go/TorrServer/web/src/utils/Hosts.js":"24","/home/yourok/MEGAWork/go/TorrServer/web/src/components/Torrent.js":"25","/home/yourok/MEGAWork/go/TorrServer/web/src/components/DialogTorrentInfo.js":"26","/home/yourok/MEGAWork/go/TorrServer/web/src/components/DialogCacheInfo.js":"27","/home/yourok/MEGAWork/go/TorrServer/web/src/utils/Utils.js":"28","/home/yourok/MEGAWork/go/TorrServer/web/src/components/About.js":"29"},{"size":224,"mtime":1607328766846,"results":"30","hashOfConfig":"31"},{"size":840,"mtime":1607329513826,"results":"32","hashOfConfig":"31"},{"size":6484,"mtime":1607340369952,"results":"33","hashOfConfig":"31"},{"size":1568,"mtime":1607340137621,"results":"34","hashOfConfig":"31"},{"size":1416,"mtime":1607335705443,"results":"35","hashOfConfig":"31"},{"size":3345,"mtime":1607335694784,"results":"36","hashOfConfig":"31"},{"size":1348,"mtime":1607335733737,"results":"37","hashOfConfig":"31"},{"size":737,"mtime":1607427032081,"results":"38","hashOfConfig":"31"},{"size":2793,"mtime":1607330316050,"results":"39","hashOfConfig":"31"},{"size":9183,"mtime":1608638362207,"results":"40","hashOfConfig":"31"},{"size":6820,"mtime":1607591408226,"results":"41","hashOfConfig":"31"},{"size":4168,"mtime":1608211292654,"results":"42","hashOfConfig":"31"},{"size":428,"mtime":1607431364533,"results":"43","hashOfConfig":"31"},{"size":4424,"mtime":1608211201124,"results":"44","hashOfConfig":"31"},{"size":224,"mtime":1607328766846,"results":"45","hashOfConfig":"46"},{"size":840,"mtime":1607329513826,"results":"47","hashOfConfig":"46"},{"size":6554,"mtime":1608804908376,"results":"48","hashOfConfig":"46"},{"size":1568,"mtime":1607340137621,"results":"49","hashOfConfig":"46"},{"size":3345,"mtime":1607335694784,"results":"50","hashOfConfig":"46"},{"size":1416,"mtime":1607335705443,"results":"51","hashOfConfig":"46"},{"size":2793,"mtime":1607330316050,"results":"52","hashOfConfig":"46"},{"size":1348,"mtime":1607335733737,"results":"53","hashOfConfig":"46"},{"size":9183,"mtime":1608638362207,"results":"54","hashOfConfig":"46"},{"size":737,"mtime":1607427032081,"results":"55","hashOfConfig":"46"},{"size":6820,"mtime":1607591408226,"results":"56","hashOfConfig":"46"},{"size":4424,"mtime":1608211201124,"results":"57","hashOfConfig":"46"},{"size":4175,"mtime":1608804244130,"results":"58","hashOfConfig":"46"},{"size":428,"mtime":1607431364533,"results":"59","hashOfConfig":"46"},{"size":2278,"mtime":1608810011199,"results":"60","hashOfConfig":"46"},{"filePath":"61","messages":"62","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"63"},"bgudbu",{"filePath":"64","messages":"65","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"63"},{"filePath":"66","messages":"67","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"63"},{"filePath":"68","messages":"69","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"63"},{"filePath":"70","messages":"71","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"63"},{"filePath":"72","messages":"73","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"63"},{"filePath":"74","messages":"75","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"63"},{"filePath":"76","messages":"77","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"63"},{"filePath":"78","messages":"79","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"63"},{"filePath":"80","messages":"81","errorCount":0,"warningCount":2,"fixableErrorCount":0,"fixableWarningCount":0,"source":"82","usedDeprecatedRules":"63"},{"filePath":"83","messages":"84","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"63"},{"filePath":"85","messages":"86","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"63"},{"filePath":"87","messages":"88","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"89"},{"filePath":"90","messages":"91","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"63"},{"filePath":"92","messages":"93","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"94"},"17eruzz",{"filePath":"95","messages":"96","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"94"},{"filePath":"97","messages":"98","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"94"},{"filePath":"99","messages":"100","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"94"},{"filePath":"101","messages":"102","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"94"},{"filePath":"103","messages":"104","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"94"},{"filePath":"105","messages":"106","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"94"},{"filePath":"107","messages":"108","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"94"},{"filePath":"109","messages":"110","errorCount":0,"warningCount":2,"fixableErrorCount":0,"fixableWarningCount":0,"source":"82","usedDeprecatedRules":"94"},{"filePath":"111","messages":"112","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"94"},{"filePath":"113","messages":"114","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"94"},{"filePath":"115","messages":"116","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"117"},{"filePath":"118","messages":"119","errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"120","usedDeprecatedRules":"94"},{"filePath":"121","messages":"122","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"94"},{"filePath":"123","messages":"124","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"94"},"/home/yourok/MEGAWork/Web/TorrServerWeb/src/index.js",[],["125","126"],"/home/yourok/MEGAWork/Web/TorrServerWeb/src/App.js",[],"/home/yourok/MEGAWork/Web/TorrServerWeb/src/components/Appbar.js",[],"/home/yourok/MEGAWork/Web/TorrServerWeb/src/components/TorrentList.js",[],"/home/yourok/MEGAWork/Web/TorrServerWeb/src/components/RemoveAll.js",[],"/home/yourok/MEGAWork/Web/TorrServerWeb/src/components/Add.js",[],"/home/yourok/MEGAWork/Web/TorrServerWeb/src/components/Upload.js",[],"/home/yourok/MEGAWork/Web/TorrServerWeb/src/utils/Hosts.js",[],"/home/yourok/MEGAWork/Web/TorrServerWeb/src/components/Donate.js",[],"/home/yourok/MEGAWork/Web/TorrServerWeb/src/components/Settings.js",["127","128"],"import ListItem from '@material-ui/core/ListItem'\nimport ListItemIcon from '@material-ui/core/ListItemIcon'\nimport ListItemText from '@material-ui/core/ListItemText'\nimport React, { useEffect } from 'react'\nimport SettingsIcon from '@material-ui/icons/Settings'\nimport Dialog from '@material-ui/core/Dialog'\nimport DialogTitle from '@material-ui/core/DialogTitle'\nimport DialogContent from '@material-ui/core/DialogContent'\nimport TextField from '@material-ui/core/TextField'\nimport DialogActions from '@material-ui/core/DialogActions'\nimport Button from '@material-ui/core/Button'\nimport { FormControlLabel, InputLabel, Select, Switch } from '@material-ui/core'\nimport { settingsHost, setTorrServerHost, torrserverHost } from '../utils/Hosts'\n\nexport default function SettingsDialog() {\n const [open, setOpen] = React.useState(false)\n const [settings, setSets] = React.useState({})\n const [show, setShow] = React.useState(false)\n const [tsHost, setTSHost] = React.useState(torrserverHost ? torrserverHost : window.location.protocol + '//' + window.location.hostname + (window.location.port ? ':' + window.location.port : ''))\n\n const handleClickOpen = () => {\n setOpen(true)\n }\n const handleClose = () => {\n setOpen(false)\n }\n const handleCloseSave = () => {\n setOpen(false)\n let sets = JSON.parse(JSON.stringify(settings))\n sets.CacheSize *= 1024 * 1024\n sets.PreloadBufferSize *= 1024 * 1024\n fetch(settingsHost(), {\n method: 'post',\n body: JSON.stringify({ action: 'set', sets: sets }),\n headers: {\n Accept: 'application/json, text/plain, */*',\n 'Content-Type': 'application/json',\n },\n })\n }\n\n useEffect(() => {\n fetch(settingsHost(), {\n method: 'post',\n body: JSON.stringify({ action: 'get' }),\n headers: {\n Accept: 'application/json, text/plain, */*',\n 'Content-Type': 'application/json',\n },\n })\n .then((res) => res.json())\n .then(\n (json) => {\n json.CacheSize /= 1024 * 1024\n json.PreloadBufferSize /= 1024 * 1024\n setSets(json)\n setShow(true)\n },\n (error) => {\n setShow(false)\n console.log(error)\n }\n )\n .catch((e) => {\n setShow(false)\n console.log(e)\n })\n }, [tsHost])\n\n const onInputHost = (event) => {\n let host = event.target.value\n setTorrServerHost(host)\n setTSHost(host)\n }\n\n const inputForm = (event) => {\n let sets = JSON.parse(JSON.stringify(settings))\n if (event.target.type === 'number' || event.target.type === 'select-one') {\n sets[event.target.id] = Number(event.target.value)\n } else if (event.target.type === 'checkbox') {\n sets[event.target.id] = Boolean(event.target.checked)\n }\n setSets(sets)\n }\n\n return (\n \n \n \n \n \n \n \n \n
\n )\n}\n\n/*\n{\n\t\"CacheSize\": 209715200,\n\t\"PreloadBufferSize\": 20971520,\n\t\"RetrackersMode\": 1,\n\t\"TorrentDisconnectTimeout\": 30,\n\t\"EnableIPv6\": false,\n\t\"DisableTCP\": false,\n\t\"DisableUTP\": true,\n\t\"DisableUPNP\": false,\n\t\"DisableDHT\": false,\n\t\"DisableUpload\": false,\n\t\"DownloadRateLimit\": 0,\n\t\"UploadRateLimit\": 0,\n\t\"ConnectionsLimit\": 20,\n\t\"DhtConnectionLimit\": 500,\n\t\"PeersListenPort\": 0\n}\n */\n","/home/yourok/MEGAWork/Web/TorrServerWeb/src/components/Torrent.js",[],"/home/yourok/MEGAWork/Web/TorrServerWeb/src/components/DialogCacheInfo.js",[],"/home/yourok/MEGAWork/Web/TorrServerWeb/src/utils/Utils.js",[],["129","130"],"/home/yourok/MEGAWork/Web/TorrServerWeb/src/components/DialogTorrentInfo.js",[],"/home/yourok/MEGAWork/go/TorrServer/web/src/index.js",[],["131","132"],"/home/yourok/MEGAWork/go/TorrServer/web/src/App.js",[],"/home/yourok/MEGAWork/go/TorrServer/web/src/components/Appbar.js",[],"/home/yourok/MEGAWork/go/TorrServer/web/src/components/TorrentList.js",[],"/home/yourok/MEGAWork/go/TorrServer/web/src/components/Add.js",[],"/home/yourok/MEGAWork/go/TorrServer/web/src/components/RemoveAll.js",[],"/home/yourok/MEGAWork/go/TorrServer/web/src/components/Donate.js",[],"/home/yourok/MEGAWork/go/TorrServer/web/src/components/Upload.js",[],"/home/yourok/MEGAWork/go/TorrServer/web/src/components/Settings.js",["133","134"],"/home/yourok/MEGAWork/go/TorrServer/web/src/utils/Hosts.js",[],"/home/yourok/MEGAWork/go/TorrServer/web/src/components/Torrent.js",[],"/home/yourok/MEGAWork/go/TorrServer/web/src/components/DialogTorrentInfo.js",[],["135","136"],"/home/yourok/MEGAWork/go/TorrServer/web/src/components/DialogCacheInfo.js",["137"],"import React, { useEffect, useRef } from 'react'\nimport Typography from '@material-ui/core/Typography'\n\nimport { getPeerString, humanizeSize } from '../utils/Utils'\nimport DialogTitle from '@material-ui/core/DialogTitle'\nimport DialogContent from '@material-ui/core/DialogContent'\nimport { cacheHost } from '../utils/Hosts'\n\nexport default function DialogCacheInfo(props) {\n const [hash] = React.useState(props.hash)\n const [cache, setCache] = React.useState({})\n const timerID = useRef(-1)\n\n useEffect(() => {\n if (hash)\n timerID.current = setInterval(() => {\n getCache(hash, (cache) => {\n setCache(cache)\n })\n }, 1000)\n else clearInterval(timerID.current)\n\n return () => {\n clearInterval(timerID.current)\n }\n }, [hash, props.open])\n\n return (\n \n
\n \n Hash {cache.Hash}\n
\n Capacity {humanizeSize(cache.Capacity)}\n
\n Filled {humanizeSize(cache.Filled)}\n
\n Torrent size {cache.Torrent && cache.Torrent.torrent_size && humanizeSize(cache.Torrent.torrent_size)}\n
\n Pieces length {humanizeSize(cache.PiecesLength)}\n
\n Pieces count {cache.PiecesCount}\n
\n Peers: {getPeerString(cache.Torrent)}\n
\n Download speed {cache.Torrent && cache.Torrent.download_speed ? humanizeSize(cache.Torrent.download_speed) + '/sec' : ''}\n
\n Status {cache.Torrent && cache.Torrent.stat_string && cache.Torrent.stat_string}\n \n \n
\n \n \n
\n )\n}\n\nfunction getCacheMap(cache) {\n if (!cache || !cache.PiecesCount) return ''\n var html = ''\n for (let i = 0; i < cache.PiecesCount; i++) {\n html += \" {\n if (i >= r.Start && i <= r.End && i !== r.Reader)\n html += ' reader-range'\n if (i === r.Reader) {\n html += ' piece-reader'\n info += ' reader'\n }\n })\n }\n html += \"' title='\" + info + \"'>\"\n }\n return html\n}\n\nfunction getCache(hash, callback) {\n try {\n fetch(cacheHost(), {\n method: 'post',\n body: JSON.stringify({ action: 'get', hash: hash }),\n headers: {\n Accept: 'application/json, text/plain, */*',\n 'Content-Type': 'application/json',\n },\n })\n .then((res) => res.json())\n .then(\n (json) => {\n callback(json)\n },\n (error) => {\n callback({})\n console.error(error)\n }\n )\n } catch (e) {\n console.error(e)\n callback({})\n }\n}\n/*\n{\n\t\"Hash\": \"41e36c8de915d80db83fc134bee4e7e2d292657e\",\n\t\"Capacity\": 209715200,\n\t\"Filled\": 2914808,\n\t\"PiecesLength\": 4194304,\n\t\"PiecesCount\": 2065,\n\t\"DownloadSpeed\": 32770.860273455524,\n\t\"Pieces\": {\n\t\t\"2064\": {\n\t\t\t\"Id\": 2064,\n\t\t\t\"Length\": 2914808,\n\t\t\t\"Size\": 162296,\n\t\t\t\"Completed\": false\n\t\t}\n\t}\n}\n */\n","/home/yourok/MEGAWork/go/TorrServer/web/src/utils/Utils.js",[],"/home/yourok/MEGAWork/go/TorrServer/web/src/components/About.js",[],{"ruleId":"138","replacedBy":"139"},{"ruleId":"140","replacedBy":"141"},{"ruleId":"142","severity":1,"message":"143","line":103,"column":29,"nodeType":"144","endLine":103,"endColumn":35},{"ruleId":"142","severity":1,"message":"143","line":139,"column":29,"nodeType":"144","endLine":139,"endColumn":35},{"ruleId":"138","replacedBy":"145"},{"ruleId":"140","replacedBy":"146"},{"ruleId":"138","replacedBy":"147"},{"ruleId":"140","replacedBy":"148"},{"ruleId":"142","severity":1,"message":"143","line":103,"column":29,"nodeType":"144","endLine":103,"endColumn":35},{"ruleId":"142","severity":1,"message":"143","line":139,"column":29,"nodeType":"144","endLine":139,"endColumn":35},{"ruleId":"138","replacedBy":"149"},{"ruleId":"140","replacedBy":"150"},{"ruleId":"151","severity":1,"message":"152","line":74,"column":35,"nodeType":"153","messageId":"154","endLine":81,"endColumn":14},"no-native-reassign",["155"],"no-negated-in-lhs",["156"],"jsx-a11y/heading-has-content","Headings must have content and the content must be accessible by a screen reader.","JSXOpeningElement",["155"],["156"],["155"],["156"],["155"],["156"],"no-loop-func","Function declared in a loop contains unsafe references to variable(s) 'html', 'html'.","ArrowFunctionExpression","unsafeRefs","no-global-assign","no-unsafe-negation"]
\ No newline at end of file
diff --git a/web/src/components/About.js b/web/src/components/About.js
new file mode 100644
index 0000000..513b894
--- /dev/null
+++ b/web/src/components/About.js
@@ -0,0 +1,46 @@
+import React from 'react';
+import Button from '@material-ui/core/Button';
+import Dialog from '@material-ui/core/Dialog';
+import DialogActions from '@material-ui/core/DialogActions';
+import DialogContent from '@material-ui/core/DialogContent';
+import DialogContentText from '@material-ui/core/DialogContentText';
+import DialogTitle from '@material-ui/core/DialogTitle';
+import InfoIcon from '@material-ui/icons/Info';
+import ListItem from '@material-ui/core/ListItem'
+import ListItemIcon from '@material-ui/core/ListItemIcon'
+import ListItemText from '@material-ui/core/ListItemText'
+
+export default function AboutDialog() {
+ const [open, setOpen] = React.useState(false)
+
+ return (
+
+
{setOpen(true)}}>
+
+
+
+
+
+
+
+ )
+}
\ No newline at end of file
diff --git a/web/src/components/Appbar.js b/web/src/components/Appbar.js
index 7752ec4..ac38cb5 100644
--- a/web/src/components/Appbar.js
+++ b/web/src/components/Appbar.js
@@ -25,6 +25,7 @@ import { Box } from '@material-ui/core'
import AddDialog from './Add'
import RemoveAll from './RemoveAll'
import SettingsDialog from './Settings'
+import AboutDialog from './About'
import { playlistAllHost, shutdownHost, torrserverHost } from '../utils/Hosts'
import DonateDialog from './Donate'
import UploadDialog from './Upload'
@@ -162,17 +163,18 @@ export default function MiniDrawer() {
-
-
-
-
window.open(playlistAllHost(), '_blank')}>
+
+
+
+
+
fetch(shutdownHost())}>
diff --git a/web/src/components/DialogCacheInfo.js b/web/src/components/DialogCacheInfo.js
index 8af8c34..3448e15 100644
--- a/web/src/components/DialogCacheInfo.js
+++ b/web/src/components/DialogCacheInfo.js
@@ -72,9 +72,9 @@ function getCacheMap(cache) {
}
cache.Readers.forEach((r,k)=> {
- if (i >= r.Start && i <= r.End && i != r.Reader)
+ if (i >= r.Start && i <= r.End && i !== r.Reader)
html += ' reader-range'
- if (i == r.Reader) {
+ if (i === r.Reader) {
html += ' piece-reader'
info += ' reader'
}