mirror of
https://github.com/Ernous/TorrServerJellyfin.git
synced 2025-12-19 21:46:11 +05:00
initial
This commit is contained in:
119
src/server/web/templates/AboutPage.go
Normal file
119
src/server/web/templates/AboutPage.go
Normal file
@@ -0,0 +1,119 @@
|
||||
package templates
|
||||
|
||||
import "server/version"
|
||||
|
||||
var aboutPage = `
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link href="` + faviconB64 + `" rel="icon" type="image/x-icon">
|
||||
<script src="/js/api.js"></script>
|
||||
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.1.0/css/all.css" integrity="sha384-lKuwvrZot6UHsBSfcMvOkWwlCMgc0TaWr+30HWe3a4ltaBwTZhyTEggF5tJv8tbt" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" integrity="sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB" crossorigin="anonymous">
|
||||
<script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
|
||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js" integrity="sha384-smHYKdLADwkXOn1EmN1qk/HfnUcbVRZyYmZ4qpPea6sjB/pTJ0euyQp0Mk8ck+5T" crossorigin="anonymous"></script>
|
||||
<title>About</title>
|
||||
</head>
|
||||
<body>
|
||||
<style type="text/css">
|
||||
.inline{
|
||||
display:inline;
|
||||
padding-left: 2%;
|
||||
}
|
||||
.center {
|
||||
display: block;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
.content {
|
||||
padding: 20px;
|
||||
}
|
||||
</style>
|
||||
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
|
||||
<a class="btn navbar-btn pull-left" href="/"><i class="fas fa-arrow-left"></i></a>
|
||||
<span class="navbar-brand mx-auto">
|
||||
О программе
|
||||
</span>
|
||||
</nav>
|
||||
<div class="content">
|
||||
<img class="center" src='` + faviconB64 + `'/>
|
||||
<h3 align="middle">TorrServer</h3>
|
||||
<h4 align="middle">` + version.Version + `</h4>
|
||||
|
||||
<h4>Поддержка проекта:</h4>
|
||||
<a class="inline" target="_blank" href="https://www.paypal.me/yourok">PayPal</a>
|
||||
<br>
|
||||
<a class="inline" target="_blank" href="https://money.yandex.ru/to/410013733697114/100">Yandex.Деньги</a>
|
||||
<br>
|
||||
<hr align="left" width="25%">
|
||||
<br>
|
||||
|
||||
<h4>Инструкция по использованию:</h4>
|
||||
<a class="inline" target="_blank" href="https://4pda.ru/forum/index.php?showtopic=896840&st=0#entry72570782">4pda.ru</a>
|
||||
<p class="inline">Спасибо <b>MadAndron</b></p>
|
||||
<br>
|
||||
<hr align="left" width="25%">
|
||||
<br>
|
||||
|
||||
<h4>Автор:</h4>
|
||||
<b class="inline">YouROK</b>
|
||||
<br>
|
||||
<i class="inline">Email:</i>
|
||||
<a target="_blank" class="inline" href="mailto:8yourok8@gmail.com">8YouROK8@gmail.com</a>
|
||||
<br>
|
||||
<i class="inline">Site: </i>
|
||||
<a target="_blank" class="inline" href="https://github.com/YouROK">GitHub.com/YouROK</a>
|
||||
<br>
|
||||
<hr align="left" width="25%">
|
||||
<br>
|
||||
|
||||
<h4>Спасибо всем, кто тестировал и помогал:</h4>
|
||||
<b class="inline">kuzzman</b>
|
||||
<br>
|
||||
<i class="inline">Site: </i>
|
||||
<a target="_blank" class="inline" href="https://4pda.ru/forum/index.php?showuser=1259550">4pda.ru</a>
|
||||
<a target="_blank" class="inline" href="http://tv-box.pp.ua">tv-box.pp.ua</a>
|
||||
<br>
|
||||
<br>
|
||||
<b class="inline">MadAndron</b>
|
||||
<br>
|
||||
<i class="inline">Site:</i>
|
||||
<a target="_blank" class="inline" href="https://4pda.ru/forum/index.php?showuser=1543999">4pda.ru</a>
|
||||
<br>
|
||||
<br>
|
||||
<b class="inline">SpAwN_LMG</b>
|
||||
<br>
|
||||
<i class="inline">Site:</i>
|
||||
<a target="_blank" class="inline" href="https://4pda.ru/forum/index.php?showuser=700929">4pda.ru</a>
|
||||
<br>
|
||||
<br>
|
||||
<b class="inline">Zivio</b>
|
||||
<br>
|
||||
<i class="inline">Site:</i>
|
||||
<a target="_blank" class="inline" href="https://4pda.ru/forum/index.php?showuser=1195633">4pda.ru</a>
|
||||
<a target="_blank" class="inline" href="http://forum.hdtv.ru/index.php?showtopic=19020">forum.hdtv.ru</a>
|
||||
<br>
|
||||
<br>
|
||||
<b class="inline">Tw1cker Руслан Пахнев</b>
|
||||
<br>
|
||||
<i class="inline">Site:</i>
|
||||
<a target="_blank" class="inline" href="https://4pda.ru/forum/index.php?showuser=2002724">4pda.ru</a>
|
||||
<a target="_blank" class="inline" href="https://github.com/Nemiroff">GitHub.com/Nemiroff</a>
|
||||
<br>
|
||||
<br>
|
||||
</div>
|
||||
<footer class="page-footer navbar-dark bg-dark">
|
||||
<span class="navbar-brand d-flex justify-content-center">
|
||||
<center><h4>TorrServer ` + version.Version + `</h4></center>
|
||||
</span>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
`
|
||||
|
||||
func (t *Template) parseAboutPage() {
|
||||
parsePage(t, "aboutPage", aboutPage)
|
||||
}
|
||||
167
src/server/web/templates/CachePage.go
Normal file
167
src/server/web/templates/CachePage.go
Normal file
@@ -0,0 +1,167 @@
|
||||
package templates
|
||||
|
||||
import (
|
||||
"server/version"
|
||||
)
|
||||
|
||||
var cachePage = `
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link href="` + faviconB64 + `" rel="icon" type="image/x-icon">
|
||||
<script src="/js/api.js"></script>
|
||||
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.1.0/css/all.css" integrity="sha384-lKuwvrZot6UHsBSfcMvOkWwlCMgc0TaWr+30HWe3a4ltaBwTZhyTEggF5tJv8tbt" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" integrity="sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB" crossorigin="anonymous">
|
||||
<script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
|
||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js" integrity="sha384-smHYKdLADwkXOn1EmN1qk/HfnUcbVRZyYmZ4qpPea6sjB/pTJ0euyQp0Mk8ck+5T" crossorigin="anonymous"></script>
|
||||
<title>TorrServer ` + version.Version + `</title>
|
||||
</head>
|
||||
<body>
|
||||
<style>
|
||||
.wrap {
|
||||
white-space: normal;
|
||||
word-wrap: break-word;
|
||||
word-break: break-all;
|
||||
}
|
||||
.content {
|
||||
margin: 1%;
|
||||
}
|
||||
.cache {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
|
||||
}
|
||||
.piece {
|
||||
border: 1px dashed white;
|
||||
font-size: 16px;
|
||||
padding: 2px;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
|
||||
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
|
||||
<a class="btn navbar-btn pull-left" href="/"><i class="fas fa-arrow-left"></i></a>
|
||||
<span class="navbar-brand mx-auto">
|
||||
TorrServer ` + version.Version + `
|
||||
</span>
|
||||
</nav>
|
||||
<div class="content">
|
||||
<div id="torrents"></div>
|
||||
<div id="cacheInfo"></div>
|
||||
<div class="cache" id="cache"></div>
|
||||
</div>
|
||||
<footer class="page-footer navbar-dark bg-dark">
|
||||
<span class="navbar-brand d-flex justify-content-center">
|
||||
<a rel="external" style="text-decoration: none;" href="/about">Описание</a>
|
||||
</span>
|
||||
</footer>
|
||||
</body>
|
||||
<script>
|
||||
$( document ).ready(function() {
|
||||
setInterval(updateState, 1000);
|
||||
});
|
||||
|
||||
var cacheHash = "";
|
||||
var hashTorrents = "";
|
||||
|
||||
function updateTorrents(){
|
||||
listTorrent(function(data){
|
||||
var currHashTorrs = "";
|
||||
for(var key in data) {
|
||||
var tor = data[key];
|
||||
currHashTorrs += tor.Hash;
|
||||
}
|
||||
if (currHashTorrs != hashTorrents){
|
||||
hashTorrents = currHashTorrs;
|
||||
var html = "";
|
||||
html += '<div class="btn-group-vertical d-flex" role="group">';
|
||||
for(var key in data) {
|
||||
var tor = data[key];
|
||||
html += '<button type="button" class="btn btn-secondary wrap w-100" onclick="setCache(\''+tor.Hash+'\')">'+tor.Name+'</button>';
|
||||
}
|
||||
html += '</div>'
|
||||
$("#torrents").empty();
|
||||
$(html).appendTo($("#torrents"));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function updateCache(){
|
||||
var cache = $("#cache");
|
||||
if (cacheHash!=""){
|
||||
cacheTorrent(cacheHash, function(data){
|
||||
var html = "";
|
||||
var st = data;
|
||||
html += '<span>Hash: '+st.Hash+'</span><br>';
|
||||
html += '<span>Capacity: '+humanizeSize(st.Capacity)+'</span><br>';
|
||||
html += '<span>Filled: '+humanizeSize(st.Filled)+'</span><br>';
|
||||
html += '<span>Pieces length: '+humanizeSize(st.PiecesLength)+'</span><br>';
|
||||
html += '<span>Pieces count: '+st.PiecesCount+'</span><br>';
|
||||
$("#cacheInfo").html(html);
|
||||
makePieces(st.PiecesCount);
|
||||
for(var i = 0; i < st.PiecesCount; i++) {
|
||||
var color = "silver";
|
||||
var size = "";
|
||||
var piece = st.Pieces[i];
|
||||
if (piece){
|
||||
if (piece.Completed && piece.BufferSize >= st.PiecesLength)
|
||||
color = "green";
|
||||
else if (piece.Completed && piece.BufferSize == 0)
|
||||
color = "silver";
|
||||
else if (!piece.Completed && piece.BufferSize > 0)
|
||||
color = "red";
|
||||
size = ' ' + humanizeSize(piece.BufferSize);
|
||||
}
|
||||
setPiece(i,color,size);
|
||||
}
|
||||
},function(){
|
||||
$("#cacheInfo").empty();
|
||||
cache.empty();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function makePieces(len){
|
||||
var cache = $("#cache");
|
||||
if (cache.children().length==len)
|
||||
return;
|
||||
var html = "";
|
||||
for(var i = 0; i < len; i++) {
|
||||
html += '<span class="piece" id="p'+i+'" style="background-color: silver;">'+i+'</span>';
|
||||
}
|
||||
cache.html(html);
|
||||
}
|
||||
|
||||
function setPiece(i, color, size){
|
||||
var piece = $("#p"+i);
|
||||
piece.delay(100).css("background-color",color);
|
||||
piece.text(i+''+size);
|
||||
}
|
||||
|
||||
function contains(arr, elem) {
|
||||
for (var i = 0; i < arr.length; i++) {
|
||||
if (arr[i].Id === elem) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function updateState(){
|
||||
updateTorrents();
|
||||
updateCache();
|
||||
}
|
||||
|
||||
function setCache(hash){
|
||||
cacheHash = hash;
|
||||
updateCache();
|
||||
}
|
||||
</script>
|
||||
</html>
|
||||
`
|
||||
|
||||
func (t *Template) parseCachePage() {
|
||||
parsePage(t, "cachePage", cachePage)
|
||||
}
|
||||
3
src/server/web/templates/FavIcon.go
Normal file
3
src/server/web/templates/FavIcon.go
Normal file
File diff suppressed because one or more lines are too long
300
src/server/web/templates/MainPage.go
Normal file
300
src/server/web/templates/MainPage.go
Normal file
@@ -0,0 +1,300 @@
|
||||
package templates
|
||||
|
||||
import (
|
||||
"server/version"
|
||||
)
|
||||
|
||||
var mainPage = `
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link href="` + faviconB64 + `" rel="icon" type="image/x-icon">
|
||||
<script src="/js/api.js"></script>
|
||||
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.1.0/css/all.css" integrity="sha384-lKuwvrZot6UHsBSfcMvOkWwlCMgc0TaWr+30HWe3a4ltaBwTZhyTEggF5tJv8tbt" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" integrity="sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB" crossorigin="anonymous">
|
||||
<script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
|
||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js" integrity="sha384-smHYKdLADwkXOn1EmN1qk/HfnUcbVRZyYmZ4qpPea6sjB/pTJ0euyQp0Mk8ck+5T" crossorigin="anonymous"></script>
|
||||
<title>TorrServer ` + version.Version + `</title>
|
||||
</head>
|
||||
<body>
|
||||
<style>
|
||||
.wrap {
|
||||
white-space: normal;
|
||||
word-wrap: break-word;
|
||||
word-break: break-all;
|
||||
}
|
||||
.content {
|
||||
margin: 1%;
|
||||
}
|
||||
</style>
|
||||
|
||||
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
|
||||
<span class="navbar-brand mx-auto">
|
||||
TorrServer ` + version.Version + `
|
||||
</span>
|
||||
</nav>
|
||||
<div class="content">
|
||||
<div>
|
||||
<label for="magnet">Добавить торрент: </label>
|
||||
<input id="magnet" class="w-100" autocomplete="off">
|
||||
</div>
|
||||
<div class="btn-group d-flex" role="group">
|
||||
<button id="buttonAdd" class="btn w-100" onclick="addTorr()"><i class="fas fa-plus"></i> Добавить</button>
|
||||
<button id="buttonUpload" class="btn w-100"><i class="fas fa-file-upload"></i> Загрузить файл</button>
|
||||
</div>
|
||||
<br>
|
||||
<div>
|
||||
<a href="/torrent/playlist.m3u" rel="external" class="btn btn-primary w-100" role="button" ><i class="fas fa-th-list"></i> Плейлист всех торрентов</a>
|
||||
</div>
|
||||
<br>
|
||||
<h3>Торренты: </h3>
|
||||
<div id="torrents"></div>
|
||||
<br>
|
||||
<div class="btn-group-vertical d-flex" role="group">
|
||||
<a href="/settings" rel="external" class="btn btn-primary w-100" role="button"><i class="fas fa-cog"></i> Настройки</a>
|
||||
<a href="/cache" rel="external" class="btn btn-primary w-100" role="button"><i class="fas fa-info"></i> Кэш</a>
|
||||
<button id="buttonShutdown" class="btn btn-primary w-100" onclick="shutdown()"><i class="fas fa-power-off"></i> Закрыть сервер</button>
|
||||
</div>
|
||||
<form id="uploadForm" style="display:none" action="/torrent/upload" method="post">
|
||||
<input type="file" id="filesUpload" style="display:none" multiple onchange="uploadTorrent()" name="files"/>
|
||||
</form>
|
||||
</div>
|
||||
<footer class="page-footer navbar-dark bg-dark">
|
||||
<span class="navbar-brand d-flex justify-content-center">
|
||||
<a rel="external" style="text-decoration: none;" href="/about">Описание</a>
|
||||
</span>
|
||||
</footer>
|
||||
|
||||
<div class="modal fade" id="preloadModal" role="dialog">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h4 class="modal-title wrap" id="preloadName"></h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p id="preloadStatus"></p>
|
||||
<p id="preloadBuffer"></p>
|
||||
<p id="preloadPeers"></p>
|
||||
<p id="preloadSpeed"></p>
|
||||
<div class="progress">
|
||||
<div id="preloadProgress" class="progress-bar progress-bar-striped progress-bar-animated" role="progressbar" aria-valuenow="100" aria-valuemin="0" aria-valuemax="100" style="width: 100%"></div>
|
||||
</div>
|
||||
<br>
|
||||
<a id="preloadFileLink" role="button" href="" class="btn btn-secondary wrap w-100"></a>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-danger" data-dismiss="modal">Закрыть</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
function addTorr(){
|
||||
var magnet = $("#magnet").val();
|
||||
$("#magnet").val("");
|
||||
if(magnet!=""){
|
||||
addTorrent(magnet,true,
|
||||
function( data ) {
|
||||
loadTorrents();
|
||||
},
|
||||
function( data ) {
|
||||
alert(data.responseJSON.message);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function removeTorr(hash){
|
||||
if(hash!=""){
|
||||
removeTorrent(hash,
|
||||
function( data ) {
|
||||
loadTorrents();
|
||||
},
|
||||
function( data ) {
|
||||
alert(data.responseJSON.message);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
function shutdown(){
|
||||
shutdownServer(function( data ) {
|
||||
alert(data.responseJSON.message);
|
||||
});
|
||||
}
|
||||
|
||||
$( document ).ready(function() {
|
||||
watchInfo();
|
||||
});
|
||||
|
||||
$('#buttonUpload').click(function() {
|
||||
$('#filesUpload').click();
|
||||
});
|
||||
|
||||
function uploadTorrent() {
|
||||
var form = $("#uploadForm");
|
||||
var formData = new FormData(document.getElementById("uploadForm"));
|
||||
var data = new FormData();
|
||||
$.each($('#filesUpload')[0].files, function(i, file) {
|
||||
data.append('file-'+i, file);
|
||||
});
|
||||
$.ajax({
|
||||
cache: false,
|
||||
processData: false,
|
||||
contentType: false,
|
||||
type: form.attr('method'),
|
||||
url: form.attr('action'),
|
||||
data: data
|
||||
}).done(function(data) {
|
||||
loadTorrents();
|
||||
}).fail(function(data) {
|
||||
alert(data.responseJSON.message);
|
||||
});
|
||||
}
|
||||
|
||||
$('#uploadForm').submit(function(event) {
|
||||
event.preventDefault();
|
||||
var form = $(this);
|
||||
$.ajax({
|
||||
type: form.attr('method'),
|
||||
url: form.attr('action'),
|
||||
data: form.serialize()
|
||||
}).done(function(data) {
|
||||
loadTorrents();
|
||||
});
|
||||
});
|
||||
|
||||
function loadTorrents() {
|
||||
listTorrent(
|
||||
function( data ) {
|
||||
var torrents = $("#torrents");
|
||||
torrents.empty();
|
||||
var html = "";
|
||||
var queueInfo = [];
|
||||
for(var key in data) {
|
||||
var tor = data[key];
|
||||
if (tor.Status==1){
|
||||
queueInfo.push(tor);
|
||||
continue;
|
||||
}
|
||||
html += tor2Html(tor);
|
||||
}
|
||||
if (queueInfo.length>0){
|
||||
html += "<br><hr><h3>Got info: </h3>";
|
||||
for(var key in queueInfo) {
|
||||
var tor = queueInfo[key];
|
||||
html += tor2Html(tor);
|
||||
}
|
||||
}
|
||||
$(html).appendTo(torrents);
|
||||
},
|
||||
function( data ) {
|
||||
alert(data.responseJSON.message);
|
||||
});
|
||||
}
|
||||
|
||||
function tor2Html(tor){
|
||||
var html = '';
|
||||
var name = "";
|
||||
if (tor.Status==1)
|
||||
name = tor.Name+' '+humanizeSize(tor.Length)+' '+tor.Hash;
|
||||
else
|
||||
name = tor.Name+' '+humanizeSize(tor.Length);
|
||||
|
||||
html += '<div class="btn-group d-flex" role="group">';
|
||||
html += ' <button type="button" class="btn btn-secondary wrap w-100" data-toggle="collapse" data-target="#info_'+tor.Hash+'">'+name+'</button>';
|
||||
if (tor.Status!=1)
|
||||
html += ' <a role="button" class="btn btn-secondary" href="'+tor.Playlist+'"><i class="fas fa-th-list"></i> Плейлист</a>';
|
||||
else
|
||||
html += ' <button type="button" class="btn btn-secondary" onclick="showPreload(\'\', \''+ tor.Hash +'\');"><i class="fas fa-info"></i></a>';
|
||||
html += ' <button type="button" class="btn btn-secondary" onclick="removeTorrent(\''+tor.Hash+'\');"><i class="fas fa-trash-alt"></i> Удалить</button>';
|
||||
html += '</div>';
|
||||
html += '<div class="collapse" id="info_'+tor.Hash+'">';
|
||||
for(var i in tor.Files){
|
||||
var file = tor.Files[i];
|
||||
var ico = "";
|
||||
if (file.Viewed)
|
||||
ico = '<i class="far fa-eye"></i> ';
|
||||
html += ' <div class="btn-group d-flex" role="group">';
|
||||
html += ' <a role="button" href="'+file.Link+'" class="btn btn-secondary wrap w-100">'+ico+file.Name+" "+humanizeSize(file.Size)+'</a>';
|
||||
html += ' <button type="button" class="btn btn-secondary" onclick="showPreload(\''+ file.Preload +'\', \''+ file.Link +'\', \''+ tor.Hash +'\');"><i class="fas fa-info"></i></button>';
|
||||
html += ' </div>';
|
||||
}
|
||||
html += '<hr></div>';
|
||||
return html;
|
||||
}
|
||||
|
||||
function watchInfo(){
|
||||
var lastTorrentCount = 0;
|
||||
var lastGettingInfo = 0;
|
||||
setInterval(function() {
|
||||
listTorrent(
|
||||
function( data ) {
|
||||
var gettingInfo = 0;
|
||||
for(var key in data) {
|
||||
var tor = data[key];
|
||||
if (tor.Status==1)
|
||||
gettingInfo++;
|
||||
}
|
||||
|
||||
if (lastTorrentCount!=data.length || gettingInfo!=lastGettingInfo){
|
||||
loadTorrents();
|
||||
lastTorrentCount = data.length;
|
||||
lastGettingInfo = gettingInfo;
|
||||
}
|
||||
});
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
function showPreload(preloadlink, fileLink, hash){
|
||||
$('#preloadFileLink').hide(0);
|
||||
$('#preloadFileLink').attr("href","");
|
||||
$('#preloadProgress').width('100%');
|
||||
if (preloadlink!='')
|
||||
preloadTorrent(preloadlink);
|
||||
var ptimer = setInterval(function() {
|
||||
statTorrent(hash,function(data){
|
||||
if (data!=null){
|
||||
$('#preloadStatus').text("Status: " + data.TorrentStatusString);
|
||||
$('#preloadName').text(data.Name);
|
||||
$('#preloadPeers').text("Peers: [" + data.ConnectedSeeders + "] " + data.ActivePeers + " / " + data.TotalPeers);
|
||||
if (data.DownloadSpeed>0)
|
||||
$('#preloadSpeed').text("Speed: "+ humanizeSize(data.DownloadSpeed) + "/Sec");
|
||||
else
|
||||
$('#preloadSpeed').text("Speed:");
|
||||
|
||||
if (data.PreloadSize>0 && data.PreloadedBytes<data.PreloadSize){
|
||||
var prc = data.PreloadedBytes * 100 / data.PreloadSize;
|
||||
if (prc>100) prc = 100;
|
||||
$('#preloadProgress').width(prc+'%');
|
||||
$('#preloadBuffer').text("Loaded: " + humanizeSize(data.PreloadedBytes) + " / " + humanizeSize(data.PreloadSize)+" "+prc+"%");
|
||||
}else{
|
||||
$('#preloadProgress').width('100%');
|
||||
$('#preloadBuffer').text("Loaded: " + humanizeSize(data.BytesReadUsefulData));
|
||||
$('#preloadProgress').width('100%');
|
||||
if (data.BytesReadUsefulData>0 && fileLink && !$('#preloadFileLink').attr("href")){
|
||||
$('#preloadFileLink').text(data.Name);
|
||||
$('#preloadFileLink').attr("href", fileLink);
|
||||
$('#preloadFileLink').show();
|
||||
}
|
||||
}
|
||||
}
|
||||
},function(){
|
||||
$('#preloadModal').modal('hide');
|
||||
})
|
||||
}, 500);
|
||||
$('#preloadModal').modal('show');
|
||||
$("#preloadModal").on('hidden.bs.modal', function () {
|
||||
clearInterval(ptimer);
|
||||
});
|
||||
}
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
`
|
||||
|
||||
func (t *Template) parseMainPage() {
|
||||
parsePage(t, "mainPage", mainPage)
|
||||
}
|
||||
200
src/server/web/templates/SettingsPage.go
Normal file
200
src/server/web/templates/SettingsPage.go
Normal file
@@ -0,0 +1,200 @@
|
||||
package templates
|
||||
|
||||
import "server/version"
|
||||
|
||||
var settingsPage = `
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link href="` + faviconB64 + `" rel="icon" type="image/x-icon">
|
||||
<script src="/js/api.js"></script>
|
||||
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.1.0/css/all.css" integrity="sha384-lKuwvrZot6UHsBSfcMvOkWwlCMgc0TaWr+30HWe3a4ltaBwTZhyTEggF5tJv8tbt" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" integrity="sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB" crossorigin="anonymous">
|
||||
<script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
|
||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js" integrity="sha384-smHYKdLADwkXOn1EmN1qk/HfnUcbVRZyYmZ4qpPea6sjB/pTJ0euyQp0Mk8ck+5T" crossorigin="anonymous"></script>
|
||||
<title>TorrServer ` + version.Version + ` Settings</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<style>
|
||||
.wrap {
|
||||
white-space: normal;
|
||||
word-wrap: break-word;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.content {
|
||||
margin: 1%;
|
||||
}
|
||||
</style>
|
||||
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
|
||||
<a class="btn navbar-btn pull-left" href="/"><i class="fas fa-arrow-left"></i></a>
|
||||
<span class="navbar-brand mx-auto">
|
||||
TorrServer ` + version.Version + `
|
||||
</span>
|
||||
</nav>
|
||||
<div class="content">
|
||||
<form id="settings">
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<div class="input-group-text">Размер кэша</div>
|
||||
</div>
|
||||
<input id="CacheSize" class="form-control" type="number" autocomplete="off">
|
||||
</div>
|
||||
<br>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<div class="input-group-text">Размер буфера предзагрузки</div>
|
||||
</div>
|
||||
<input id="PreloadBufferSize" class="form-control" type="number" autocomplete="off">
|
||||
</div>
|
||||
<small class="form-text text-muted">Размеры кэша и буфера указываются в мегабайтах</small>
|
||||
<br>
|
||||
<div class="form-check">
|
||||
<input id="DisableTCP" class="form-check-input" type="checkbox" autocomplete="off">
|
||||
<label for="DisableTCP">Отключить TCP</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input id="DisableUTP" class="form-check-input" type="checkbox" autocomplete="off">
|
||||
<label for="DisableUTP">Отключить UTP</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input id="DisableUPNP" class="form-check-input" type="checkbox" autocomplete="off">
|
||||
<label for="DisableUPNP">Отключить UPNP</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input id="DisableDHT" class="form-check-input" type="checkbox" autocomplete="off">
|
||||
<label for="DisableDHT">Отключить DHT</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input id="DisableUpload" class="form-check-input" type="checkbox" autocomplete="off">
|
||||
<label for="DisableUpload">Отключить Отдачу</label>
|
||||
</div>
|
||||
<br>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<div class="input-group-text">Шифрование</div>
|
||||
</div>
|
||||
<select id="Encryption" class="form-control">
|
||||
<option value="0">По умолчанию</option>
|
||||
<option value="1">Отключить</option>
|
||||
<option value="2">Принудительно</option>
|
||||
</select>
|
||||
</div>
|
||||
<br>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<div class="input-group-text">Количество соединений</div>
|
||||
</div>
|
||||
<input id="ConnectionsLimit" class="form-control" type="number" autocomplete="off">
|
||||
</div>
|
||||
<br>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<div class="input-group-text">Ограничение загрузки</div>
|
||||
</div>
|
||||
<input id="DownloadRateLimit" class="form-control" type="number" autocomplete="off">
|
||||
</div>
|
||||
<br>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<div class="input-group-text">Ограничение отдачи</div>
|
||||
</div>
|
||||
<input id="UploadRateLimit" class="form-control" type="number" autocomplete="off">
|
||||
</div>
|
||||
<small class="form-text text-muted">Ограничение устанавливается в Килобайтах, 0 - не ограничивать</small>
|
||||
<br>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<div class="input-group-text">Ретрекеры</div>
|
||||
</div>
|
||||
<select id="RetrackersMode" class="form-control">
|
||||
<option value="0">Оставить как есть</option>
|
||||
<option value="1">Добавить</option>
|
||||
<option value="2">Удалить</option>
|
||||
</select>
|
||||
</div>
|
||||
</form>
|
||||
<br>
|
||||
<div class="btn-group d-flex" role="group">
|
||||
<button id="buttonSave" class="btn btn-primary w-100" data-icon="check" onclick="saveSettings()"><i class="far fa-save"></i> Сохранить</button>
|
||||
<button id="buttonRefresh" class="btn btn-primary w-100" data-icon="refresh" onclick="refreshSettings()"><i class="fas fa-sync-alt"></i> Получить с сервера</button>
|
||||
</div>
|
||||
</div>
|
||||
<footer class="page-footer navbar-dark bg-dark">
|
||||
<span class="navbar-brand d-flex justify-content-center">
|
||||
<a rel="external" style="text-decoration: none;" href="/about">Описание</a>
|
||||
</span>
|
||||
</footer>
|
||||
<script>
|
||||
function saveSettings() {
|
||||
var data = {};
|
||||
data.CacheSize = Number($('#CacheSize').val())*(1024*1024);
|
||||
data.PreloadBufferSize = Number($('#PreloadBufferSize').val())*(1024*1024);
|
||||
|
||||
data.DisableTCP = $('#DisableTCP').prop('checked');
|
||||
data.DisableUTP = $('#DisableUTP').prop('checked');
|
||||
data.DisableUPNP = $('#DisableUPNP').prop('checked');
|
||||
data.DisableDHT = $('#DisableDHT').prop('checked');
|
||||
data.DisableUpload = $('#DisableUpload').prop('checked');
|
||||
data.Encryption = Number($('#Encryption').val());
|
||||
|
||||
data.ConnectionsLimit = Number($('#ConnectionsLimit').val());
|
||||
|
||||
data.DownloadRateLimit = Number($('#DownloadRateLimit').val());
|
||||
data.UploadRateLimit = Number($('#UploadRateLimit').val());
|
||||
|
||||
data.RetrackersMode = Number($('#RetrackersMode').val());
|
||||
|
||||
$.post("/settings/write", JSON.stringify(data))
|
||||
.done(function(data) {
|
||||
restartService();
|
||||
alert(data);
|
||||
})
|
||||
.fail(function(data) {
|
||||
alert(data.responseJSON.message);
|
||||
});
|
||||
}
|
||||
|
||||
function refreshSettings() {
|
||||
$.post("/settings/read")
|
||||
.done(function(data) {
|
||||
$('#CacheSize').val(data.CacheSize/(1024*1024));
|
||||
$('#PreloadBufferSize').val(data.PreloadBufferSize/(1024*1024));
|
||||
|
||||
$('#DisableTCP').prop('checked', data.DisableTCP);
|
||||
$('#DisableUTP').prop('checked', data.DisableUTP);
|
||||
$('#DisableUPNP').prop('checked', data.DisableUPNP);
|
||||
$('#DisableDHT').prop('checked', data.DisableDHT);
|
||||
$('#DisableUpload').prop('checked', data.DisableUpload);
|
||||
$('#Encryption').val(data.Encryption);
|
||||
|
||||
$('#ConnectionsLimit').val(data.ConnectionsLimit);
|
||||
|
||||
$('#DownloadRateLimit').val(data.DownloadRateLimit);
|
||||
$('#UploadRateLimit').val(data.UploadRateLimit);
|
||||
|
||||
$('#RetrackersMode').val(data.RetrackersMode);
|
||||
});
|
||||
};
|
||||
|
||||
$(document).ready(function() {
|
||||
refreshSettings();
|
||||
});
|
||||
|
||||
$(document).on("wheel", "input[type=number]", function (e) {
|
||||
$(this).blur();
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
`
|
||||
|
||||
func (t *Template) parseSettingsPage() {
|
||||
parsePage(t, "settingsPage", settingsPage)
|
||||
}
|
||||
45
src/server/web/templates/Template.go
Normal file
45
src/server/web/templates/Template.go
Normal file
@@ -0,0 +1,45 @@
|
||||
package templates
|
||||
|
||||
import (
|
||||
"html/template"
|
||||
"io"
|
||||
|
||||
"github.com/labstack/echo"
|
||||
)
|
||||
|
||||
type Template struct {
|
||||
templates *template.Template
|
||||
}
|
||||
|
||||
func InitTemplate(e *echo.Echo) {
|
||||
temp := new(Template)
|
||||
|
||||
temp.parseMainPage()
|
||||
temp.parseSettingsPage()
|
||||
temp.parseAboutPage()
|
||||
temp.parseCachePage()
|
||||
|
||||
e.Renderer = temp
|
||||
}
|
||||
|
||||
func (t *Template) Render(w io.Writer, name string, data interface{}, c echo.Context) error {
|
||||
return t.templates.ExecuteTemplate(w, name, data)
|
||||
}
|
||||
|
||||
func parsePage(temp *Template, name, page string) error {
|
||||
s := page
|
||||
var tmpl *template.Template
|
||||
if temp.templates == nil {
|
||||
temp.templates = template.New(name)
|
||||
}
|
||||
if name == temp.templates.Name() {
|
||||
tmpl = temp.templates
|
||||
} else {
|
||||
tmpl = temp.templates.New(name)
|
||||
}
|
||||
_, err := tmpl.Parse(s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
133
src/server/web/templates/api_js.go
Normal file
133
src/server/web/templates/api_js.go
Normal file
@@ -0,0 +1,133 @@
|
||||
package templates
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"server/settings"
|
||||
"server/web/helpers"
|
||||
|
||||
"github.com/labstack/echo"
|
||||
)
|
||||
|
||||
var apijs = `
|
||||
function addTorrent(link, save, info, done, fail){
|
||||
var reqJson = JSON.stringify({ Link: link, Info: info, DontSave: !save});
|
||||
$.post('/torrent/add',reqJson)
|
||||
.done(function( data ) {
|
||||
if (done)
|
||||
done(data);
|
||||
})
|
||||
.fail(function( data ) {
|
||||
if (fail)
|
||||
fail(data);
|
||||
});
|
||||
}
|
||||
|
||||
function getTorrent(hash, done, fail){
|
||||
var reqJson = JSON.stringify({ Hash: hash});
|
||||
$.post('/torrent/get',reqJson)
|
||||
.done(function( data ) {
|
||||
if (done)
|
||||
done(data);
|
||||
})
|
||||
.fail(function( data ) {
|
||||
if (fail)
|
||||
fail(data);
|
||||
});
|
||||
}
|
||||
|
||||
function removeTorrent(hash, done, fail){
|
||||
var reqJson = JSON.stringify({ Hash: hash});
|
||||
$.post('/torrent/rem',reqJson)
|
||||
.done(function( data ) {
|
||||
if (done)
|
||||
done(data);
|
||||
})
|
||||
.fail(function( data ) {
|
||||
if (fail)
|
||||
fail(data);
|
||||
});
|
||||
}
|
||||
|
||||
function statTorrent(hash, done, fail){
|
||||
var reqJson = JSON.stringify({ Hash: hash});
|
||||
$.post('/torrent/stat',reqJson)
|
||||
.done(function( data ) {
|
||||
if (done)
|
||||
done(data);
|
||||
})
|
||||
.fail(function( data ) {
|
||||
if (fail)
|
||||
fail(data);
|
||||
});
|
||||
}
|
||||
|
||||
function cacheTorrent(hash, done, fail){
|
||||
var reqJson = JSON.stringify({ Hash: hash});
|
||||
$.post('/torrent/cache',reqJson)
|
||||
.done(function( data ) {
|
||||
if (done)
|
||||
done(data);
|
||||
})
|
||||
.fail(function( data ) {
|
||||
if (fail)
|
||||
fail(data);
|
||||
});
|
||||
}
|
||||
|
||||
function listTorrent(done, fail){
|
||||
$.post('/torrent/list')
|
||||
.done(function( data ) {
|
||||
if (done)
|
||||
done(data);
|
||||
})
|
||||
.fail(function( data ) {
|
||||
if (fail)
|
||||
fail(data);
|
||||
});
|
||||
}
|
||||
|
||||
function restartService(done, fail){
|
||||
$.get('/torrent/restart')
|
||||
.done(function( data ) {
|
||||
if (done)
|
||||
done();
|
||||
})
|
||||
.fail(function( data ) {
|
||||
if (fail)
|
||||
fail(data);
|
||||
});
|
||||
}
|
||||
|
||||
function preloadTorrent(preloadLink, done, fail){
|
||||
$.get(preloadLink)
|
||||
.done(function( data ) {
|
||||
if (done)
|
||||
done();
|
||||
})
|
||||
.fail(function( data ) {
|
||||
if (fail)
|
||||
fail(data);
|
||||
});
|
||||
}
|
||||
|
||||
function shutdownServer(fail){
|
||||
$.post('/shutdown')
|
||||
.fail(function( data ) {
|
||||
if (fail)
|
||||
fail(data);
|
||||
});
|
||||
}
|
||||
|
||||
function humanizeSize(size) {
|
||||
if (typeof size == 'undefined' || size == 0)
|
||||
return "";
|
||||
var i = Math.floor( Math.log(size) / Math.log(1024) );
|
||||
return ( size / Math.pow(1024, i) ).toFixed(2) * 1 + ' ' + ['B', 'kB', 'MB', 'GB', 'TB'][i];
|
||||
}
|
||||
`
|
||||
|
||||
func Api_JS(c echo.Context) error {
|
||||
http.ServeContent(c.Response(), c.Request(), "api.js", settings.StartTime, helpers.NewSeekingBuffer(apijs))
|
||||
return c.NoContent(http.StatusOK)
|
||||
}
|
||||
Reference in New Issue
Block a user