first
This commit is contained in:
parent
7fad640cca
commit
77519e6d52
2
app.js
2
app.js
@ -39,7 +39,7 @@ app.onListen.push(function(){
|
|||||||
|
|
||||||
app.contollers.pubsub.subscribe(/./g, function(data, topic){
|
app.contollers.pubsub.subscribe(/./g, function(data, topic){
|
||||||
app.io.emit('P2PSub', { topic, data });
|
app.io.emit('P2PSub', { topic, data });
|
||||||
});
|
});
|
||||||
|
|
||||||
app.io.on('connection', (socket) => {
|
app.io.on('connection', (socket) => {
|
||||||
// console.log('socket', socket)
|
// console.log('socket', socket)
|
||||||
|
443
public/js/app.js
443
public/js/app.js
@ -1,419 +1,56 @@
|
|||||||
var app = {};
|
// socket
|
||||||
|
|
||||||
app.pubsub = (function(){
|
// api
|
||||||
app.topics = {};
|
|
||||||
|
|
||||||
app.subscribe = function(topic, listener) {
|
// auth
|
||||||
if(topic instanceof RegExp){
|
|
||||||
listener.match = topic;
|
|
||||||
topic = "__REGEX__";
|
|
||||||
}
|
|
||||||
|
|
||||||
// create the topic if not yet created
|
// user
|
||||||
if(!app.topics[topic]) app.topics[topic] = [];
|
|
||||||
|
|
||||||
// add the listener
|
// group
|
||||||
app.topics[topic].push(listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
app.matchTopics = function(topic){
|
"use strict";
|
||||||
topic = topic || '';
|
/* globals jQuery, Mustache, XRegExp, $, app */
|
||||||
var matches = [... app.topics[topic] ? app.topics[topic] : []];
|
var app = app || {};
|
||||||
|
|
||||||
if(!app.topics['__REGEX__']) return matches;
|
( function($){
|
||||||
|
|
||||||
for(var listener of app.topics['__REGEX__']){
|
/*
|
||||||
if(topic.match(listener.match)) matches.push(listener);
|
delay calling document.ready until app is loaded.
|
||||||
}
|
*/
|
||||||
|
jQuery.holdReady(true);
|
||||||
|
|
||||||
return matches;
|
app.includeScrip = function(path, base){
|
||||||
}
|
path = (base || JQapp_BASE_PATH || '') + path;
|
||||||
|
|
||||||
app.publish = function(topic, data) {
|
jQuery.ajax({
|
||||||
|
url: path,
|
||||||
// send the event to all listeners
|
dataType: 'script',
|
||||||
app.matchTopics(topic).forEach(function(listener) {
|
async: false
|
||||||
setTimeout(function(data, topic){
|
|
||||||
listener(data || {}, topic);
|
|
||||||
}, 0, data, topic);
|
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
return this;
|
|
||||||
})(app);
|
|
||||||
|
|
||||||
app.socket = (function(app){
|
|
||||||
// $.getScript('/socket.io/socket.io.js')
|
|
||||||
// <script type="text/javascript" src="/socket.io/socket.io.js"></script>
|
|
||||||
|
|
||||||
var socket;
|
|
||||||
$(document).ready(function(){
|
|
||||||
socket = io({
|
|
||||||
auth: {
|
|
||||||
token: app.auth.getToken()
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// socket.emit('chat message', $('#m').val());
|
|
||||||
socket.on('P2PSub', function(msg){
|
|
||||||
msg.data.__noSocket = true;
|
|
||||||
app.publish(msg.topic, msg.data);
|
|
||||||
});
|
|
||||||
|
|
||||||
app.subscribe(/./g, function(data, topic){
|
|
||||||
// console.log('local_pubs', data, topic)
|
|
||||||
if(data.__noSocket) return;
|
|
||||||
// console.log('local_pubs 2', data, topic)
|
|
||||||
|
|
||||||
socket.emit('P2PSub', { topic, data });
|
|
||||||
});
|
|
||||||
})
|
|
||||||
|
|
||||||
return socket;
|
|
||||||
|
|
||||||
})(app);
|
|
||||||
|
|
||||||
app.api = (function(app){
|
|
||||||
var baseURL = '/__api/'
|
|
||||||
|
|
||||||
|
|
||||||
$( document ).on( "ajaxError", function(event, res, req) {
|
|
||||||
console.log('bad!', `app:api:error:`, res.status);
|
|
||||||
app.publish(`app:api:error:${res.status}`, {res, res});
|
|
||||||
} );
|
|
||||||
|
|
||||||
function post(url, data, callback){
|
|
||||||
callback = callback || app.util.emptyFuction;
|
|
||||||
$.ajax({
|
|
||||||
type: 'POST',
|
|
||||||
url: baseURL+url,
|
|
||||||
headers:{
|
|
||||||
'auth-token': app.auth.getToken()
|
|
||||||
},
|
|
||||||
data: JSON.stringify(data),
|
|
||||||
contentType: "application/json; charset=utf-8",
|
|
||||||
dataType: "json",
|
|
||||||
complete: function(res, text){
|
|
||||||
callback(
|
|
||||||
text !== 'success' ? res.statusText : null,
|
|
||||||
JSON.parse(res.responseText),
|
|
||||||
res.status
|
|
||||||
)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function put(url, data, callback){
|
|
||||||
$.ajax({
|
|
||||||
type: 'PUT',
|
|
||||||
url: baseURL+url,
|
|
||||||
headers:{
|
|
||||||
'auth-token': app.auth.getToken()
|
|
||||||
},
|
|
||||||
data: JSON.stringify(data),
|
|
||||||
contentType: "application/json; charset=utf-8",
|
|
||||||
dataType: "json",
|
|
||||||
complete: function(res, text){
|
|
||||||
callback(
|
|
||||||
text !== 'success' ? res.statusText : null,
|
|
||||||
JSON.parse(res.responseText),
|
|
||||||
res.status
|
|
||||||
)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function remove(url, callback, callback2){
|
|
||||||
if(!$.isFunction(callback)) callback = callback2;
|
|
||||||
$.ajax({
|
|
||||||
type: 'delete',
|
|
||||||
url: baseURL+url,
|
|
||||||
headers:{
|
|
||||||
'auth-token': app.auth.getToken()
|
|
||||||
},
|
|
||||||
contentType: "application/json; charset=utf-8",
|
|
||||||
dataType: "json",
|
|
||||||
complete: function(res, text){
|
|
||||||
callback(
|
|
||||||
text !== 'success' ? res.statusText : null,
|
|
||||||
JSON.parse(res.responseText),
|
|
||||||
res.status
|
|
||||||
)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function get(url, callback){
|
|
||||||
$.ajax({
|
|
||||||
type: 'GET',
|
|
||||||
url: baseURL+url,
|
|
||||||
headers:{
|
|
||||||
'auth-token': app.auth.getToken()
|
|
||||||
},
|
|
||||||
contentType: "application/json; charset=utf-8",
|
|
||||||
dataType: "json",
|
|
||||||
complete: function(res, text){
|
|
||||||
callback(
|
|
||||||
text !== 'success' ? res.statusText : null,
|
|
||||||
JSON.parse(res.responseText),
|
|
||||||
res.status
|
|
||||||
)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return {post: post, get: get, put: put, delete: remove}
|
|
||||||
})(app)
|
|
||||||
|
|
||||||
app.auth = (function(app) {
|
|
||||||
var user = {}
|
|
||||||
function setToken(token){
|
|
||||||
localStorage.setItem('APIToken', token);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getToken(){
|
|
||||||
return localStorage.getItem('APIToken');
|
|
||||||
}
|
|
||||||
|
|
||||||
function isLoggedIn(callback){
|
|
||||||
if(getToken()){
|
|
||||||
return app.api.get('user/me', function(error, data){
|
|
||||||
if(error === 'Unauthorized') logOut();
|
|
||||||
if(!error) app.auth.user = data;
|
|
||||||
return callback(error, data);
|
|
||||||
});
|
|
||||||
}else{
|
|
||||||
callback(null, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function logIn(args, callback){
|
|
||||||
app.api.post('auth/login', args, function(error, data){
|
|
||||||
if(data.login){
|
|
||||||
setToken(data.token);
|
|
||||||
}
|
|
||||||
callback(error, !!data.token);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function logOut(callback){
|
|
||||||
callback = callback || app.util.emptyFuction;
|
|
||||||
localStorage.removeItem('APIToken');
|
|
||||||
callback();
|
|
||||||
}
|
|
||||||
|
|
||||||
function makeUserFromInvite(args, callback){
|
|
||||||
app.api.post('auth/invite/'+ args.token, args, function(error, data){
|
|
||||||
if(data.login){
|
|
||||||
callback(null, data);
|
|
||||||
setToken(data.token);
|
|
||||||
}
|
|
||||||
callback(error, !!data.token);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function forceLogin(){
|
|
||||||
$.holdReady( true );
|
|
||||||
app.auth.isLoggedIn(function(error, isLoggedIn){
|
|
||||||
if(error || !isLoggedIn){
|
|
||||||
app.auth.logOut(function(){})
|
|
||||||
location.replace(`/login${location.href.replace(location.origin, '')}`);
|
|
||||||
}else{
|
|
||||||
$.holdReady( false );
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function logInRedirect(){
|
|
||||||
window.location.href = location.href.replace(location.origin+'/login', '') || '/'
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
$( document ).ready( function(){
|
|
||||||
isLoggedIn(function(error, isLoggedIn){
|
|
||||||
if(!error && isLoggedIn){
|
|
||||||
$('.tbp_proxy_is_authed').show();
|
|
||||||
$('.tbp_proxy_not_authed').hide();
|
|
||||||
}else{
|
|
||||||
$('.tbp_proxy_is_authed').hide();
|
|
||||||
$('.tbp_proxy_not_authed').show();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
|
||||||
getToken: getToken,
|
|
||||||
setToken: setToken,
|
|
||||||
isLoggedIn: isLoggedIn,
|
|
||||||
logIn: logIn,
|
|
||||||
logOut: logOut,
|
|
||||||
makeUserFromInvite: makeUserFromInvite,
|
|
||||||
forceLogin,
|
|
||||||
logInRedirect,
|
|
||||||
}
|
|
||||||
|
|
||||||
})(app);
|
|
||||||
|
|
||||||
app.util = (function(app){
|
|
||||||
|
|
||||||
function getUrlParameter(name) {
|
|
||||||
name = name.replace(/[\[]/, '\\[').replace(/[\]]/, '\\]');
|
|
||||||
var regex = new RegExp('[\\?&]' + name + '=([^&#]*)');
|
|
||||||
var results = regex.exec(location.search);
|
|
||||||
return results === null ? '' : decodeURIComponent(results[1].replace(/\+/g, ' '));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
function actionMessage(message, $target, type, callback){
|
app.include = function(scripts, base){
|
||||||
message = message || '';
|
scripts = $.isArray(scripts) ? scripts : [scripts];
|
||||||
$target = $target.closest('div.card').find('.actionMessage');
|
for(let script of scripts){
|
||||||
type = type || 'info';
|
app.includeScrip(script, base)
|
||||||
callback = callback || function(){};
|
|
||||||
|
|
||||||
if($target.html() === message) return;
|
|
||||||
|
|
||||||
if($target.html()){
|
|
||||||
$target.slideUp('fast', function(){
|
|
||||||
$target.html('')
|
|
||||||
$target.removeClass (function (index, className) {
|
|
||||||
return (className.match (/(^|\s)ui-\S+/g) || []).join(' ');
|
|
||||||
});
|
|
||||||
if(message) return actionMessage(message, $target, type, callback);
|
|
||||||
$target.hide()
|
|
||||||
})
|
|
||||||
}else{
|
|
||||||
if(type) $target.addClass('ui-' + type);
|
|
||||||
$target.html(message).slideDown('fast');
|
|
||||||
}
|
}
|
||||||
setTimeout(callback,10)
|
|
||||||
}
|
}
|
||||||
|
})(jQuery);
|
||||||
|
|
||||||
$.fn.serializeObject = function() {
|
app.include([
|
||||||
var
|
'/utils.js',
|
||||||
arr = $(this).serializeArray(),
|
'/pubsub.js',
|
||||||
obj = {};
|
'/api.js',
|
||||||
|
'/socket.js',
|
||||||
for(var i = 0; i < arr.length; i++) {
|
'/user.js',
|
||||||
if(obj[arr[i].name] === undefined) {
|
'/group.js',
|
||||||
obj[arr[i].name] = arr[i].value;
|
'/auth.js',
|
||||||
} else {
|
], JQapp_BASE_PATH)
|
||||||
if(!(obj[arr[i].name] instanceof Array)) {
|
|
||||||
obj[arr[i].name] = [obj[arr[i].name]];
|
|
||||||
}
|
|
||||||
obj[arr[i].name].push(arr[i].value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return obj;
|
|
||||||
};
|
|
||||||
|
|
||||||
return {
|
/*
|
||||||
getUrlParameter: getUrlParameter,
|
when the DOM is finished, start the app
|
||||||
actionMessage: actionMessage,
|
*/
|
||||||
emptyFuction: function(){},
|
jQuery(document).on("DOMContentLoaded", function(event) {
|
||||||
|
app.publish("__dom-content-loaded-start");
|
||||||
}
|
app.publish("__dom-content-loaded-end");
|
||||||
})(app);
|
});
|
||||||
|
|
||||||
|
|
||||||
app.user = (function(app){
|
|
||||||
function list(callback){
|
|
||||||
app.api.get('user/?detail=true', function(error, data){
|
|
||||||
callback(error, data);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function add(args, callback){
|
|
||||||
app.api.post('user/', args, function(error, data){
|
|
||||||
callback(error, data);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function remove(args, callback){
|
|
||||||
if(!confirm('Delete '+ args.uid+ 'user?')) return false;
|
|
||||||
app.api.delete('user/'+ args.uid, function(error, data){
|
|
||||||
callback(error, data);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function changePassword(args, callback){
|
|
||||||
app.api.put('users/'+ arg.uid || '', args, function(error, data){
|
|
||||||
callback(error, data);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function createInvite(callback){
|
|
||||||
app.api.post('user/invite', {}, function(error, data, status){
|
|
||||||
callback(error, data);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function consumeInvite(args){
|
|
||||||
app.api.post('/auth/invite/'+args.token, args, function(error, data){
|
|
||||||
if(data.token){
|
|
||||||
app.auth.setToken(data.token)
|
|
||||||
return callback(null, true)
|
|
||||||
}
|
|
||||||
callback(error)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return {list, remove, createInvite};
|
|
||||||
|
|
||||||
})(app);
|
|
||||||
|
|
||||||
app.group = (function(app){
|
|
||||||
function list(callback){
|
|
||||||
app.api.get('group?detail=true', function(error, data){
|
|
||||||
callback(error, data);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function remove(args, callback){
|
|
||||||
app.api.delete('group/'+args.cn, function(error, data){
|
|
||||||
callback(error, data);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return {list, remove}
|
|
||||||
})(app);
|
|
||||||
|
|
||||||
$( document ).ready( function () {
|
|
||||||
|
|
||||||
$( 'div.row' ).fadeIn( 'slow' ); //show the page
|
|
||||||
|
|
||||||
//panel button's
|
|
||||||
$( '.fa-arrows-v' ).click( function () {
|
|
||||||
$( this ).closest( '.card' ).find( '.card-body' ).slideToggle( 'fast' );
|
|
||||||
});
|
|
||||||
|
|
||||||
$('.actionMessage').on('click', 'button.action-close', function(event){
|
|
||||||
app.util.actionMessage(null, $(this));
|
|
||||||
})
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
//ajax form submit
|
|
||||||
function formAJAX( btn, del ) {
|
|
||||||
event.preventDefault(); // avoid to execute the actual submit of the form.
|
|
||||||
var $form = $(btn).closest( '[action]' ); // gets the 'form' parent
|
|
||||||
var formData = $form.find( '[name]' ).serializeObject(); // builds query formDataing
|
|
||||||
var method = $form.attr('method') || 'post';
|
|
||||||
|
|
||||||
// if( !$form.validate()) {
|
|
||||||
// app.util.actionMessage('Please fix the form errors.', $form, 'danger')
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
|
|
||||||
app.util.actionMessage(
|
|
||||||
'<div class="spinner-border" role="status"><span class="sr-only">Loading...</span></div>',
|
|
||||||
$form,
|
|
||||||
'state-highlight'
|
|
||||||
);
|
|
||||||
|
|
||||||
app.api[method]($form.attr('action'), formData, function(error, data){
|
|
||||||
app.util.actionMessage(data.message, $form, error ? 'state-error' : 'priority-primary'); //re-populate table
|
|
||||||
if(!error){
|
|
||||||
$form.trigger("reset");
|
|
||||||
eval($form.attr('evalAJAX')); //gets JS to run after completion
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
91
public/js/app/api.js
Normal file
91
public/js/app/api.js
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
app.api = (function(app){
|
||||||
|
var baseURL = '/__api/'
|
||||||
|
|
||||||
|
|
||||||
|
$( document ).on( "ajaxError", function(event, res, req) {
|
||||||
|
console.log('bad!', `app:api:error:`, res.status);
|
||||||
|
app.publish(`app:api:error:${res.status}`, {res, res});
|
||||||
|
} );
|
||||||
|
|
||||||
|
function post(url, data, callback){
|
||||||
|
callback = callback || app.util.emptyFuction;
|
||||||
|
$.ajax({
|
||||||
|
type: 'POST',
|
||||||
|
url: baseURL+url,
|
||||||
|
headers:{
|
||||||
|
'auth-token': app.auth.getToken()
|
||||||
|
},
|
||||||
|
data: JSON.stringify(data),
|
||||||
|
contentType: "application/json; charset=utf-8",
|
||||||
|
dataType: "json",
|
||||||
|
complete: function(res, text){
|
||||||
|
callback(
|
||||||
|
text !== 'success' ? res.statusText : null,
|
||||||
|
JSON.parse(res.responseText),
|
||||||
|
res.status
|
||||||
|
)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function put(url, data, callback){
|
||||||
|
$.ajax({
|
||||||
|
type: 'PUT',
|
||||||
|
url: baseURL+url,
|
||||||
|
headers:{
|
||||||
|
'auth-token': app.auth.getToken()
|
||||||
|
},
|
||||||
|
data: JSON.stringify(data),
|
||||||
|
contentType: "application/json; charset=utf-8",
|
||||||
|
dataType: "json",
|
||||||
|
complete: function(res, text){
|
||||||
|
callback(
|
||||||
|
text !== 'success' ? res.statusText : null,
|
||||||
|
JSON.parse(res.responseText),
|
||||||
|
res.status
|
||||||
|
)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function remove(url, callback, callback2){
|
||||||
|
if(!$.isFunction(callback)) callback = callback2;
|
||||||
|
$.ajax({
|
||||||
|
type: 'delete',
|
||||||
|
url: baseURL+url,
|
||||||
|
headers:{
|
||||||
|
'auth-token': app.auth.getToken()
|
||||||
|
},
|
||||||
|
contentType: "application/json; charset=utf-8",
|
||||||
|
dataType: "json",
|
||||||
|
complete: function(res, text){
|
||||||
|
callback(
|
||||||
|
text !== 'success' ? res.statusText : null,
|
||||||
|
JSON.parse(res.responseText),
|
||||||
|
res.status
|
||||||
|
)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function get(url, callback){
|
||||||
|
$.ajax({
|
||||||
|
type: 'GET',
|
||||||
|
url: baseURL+url,
|
||||||
|
headers:{
|
||||||
|
'auth-token': app.auth.getToken()
|
||||||
|
},
|
||||||
|
contentType: "application/json; charset=utf-8",
|
||||||
|
dataType: "json",
|
||||||
|
complete: function(res, text){
|
||||||
|
callback(
|
||||||
|
text !== 'success' ? res.statusText : null,
|
||||||
|
JSON.parse(res.responseText),
|
||||||
|
res.status
|
||||||
|
)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return {post: post, get: get, put: put, delete: remove}
|
||||||
|
})(app);
|
87
public/js/app/auth.js
Normal file
87
public/js/app/auth.js
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
app.auth = (function(app) {
|
||||||
|
var user = {}
|
||||||
|
function setToken(token){
|
||||||
|
localStorage.setItem('APIToken', token);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getToken(){
|
||||||
|
return localStorage.getItem('APIToken');
|
||||||
|
}
|
||||||
|
|
||||||
|
function isLoggedIn(callback){
|
||||||
|
if(getToken()){
|
||||||
|
return app.api.get('user/me', function(error, data){
|
||||||
|
if(error === 'Unauthorized') logOut();
|
||||||
|
if(!error) app.auth.user = data;
|
||||||
|
return callback(error, data);
|
||||||
|
});
|
||||||
|
}else{
|
||||||
|
callback(null, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function logIn(args, callback){
|
||||||
|
app.api.post('auth/login', args, function(error, data){
|
||||||
|
if(data.login){
|
||||||
|
setToken(data.token);
|
||||||
|
}
|
||||||
|
callback(error, !!data.token);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function logOut(callback){
|
||||||
|
callback = callback || app.util.emptyFuction;
|
||||||
|
localStorage.removeItem('APIToken');
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
|
||||||
|
function makeUserFromInvite(args, callback){
|
||||||
|
app.api.post('auth/invite/'+ args.token, args, function(error, data){
|
||||||
|
if(data.login){
|
||||||
|
callback(null, data);
|
||||||
|
setToken(data.token);
|
||||||
|
}
|
||||||
|
callback(error, !!data.token);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function forceLogin(){
|
||||||
|
$.holdReady( true );
|
||||||
|
app.auth.isLoggedIn(function(error, isLoggedIn){
|
||||||
|
if(error || !isLoggedIn){
|
||||||
|
app.auth.logOut(function(){})
|
||||||
|
location.replace(`/login${location.href.replace(location.origin, '')}`);
|
||||||
|
}else{
|
||||||
|
$.holdReady( false );
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function logInRedirect(){
|
||||||
|
window.location.href = location.href.replace(location.origin+'/login', '') || '/'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$( document ).ready( function(){
|
||||||
|
isLoggedIn(function(error, isLoggedIn){
|
||||||
|
if(!error && isLoggedIn){
|
||||||
|
$('.tbp_proxy_is_authed').show();
|
||||||
|
$('.tbp_proxy_not_authed').hide();
|
||||||
|
}else{
|
||||||
|
$('.tbp_proxy_is_authed').hide();
|
||||||
|
$('.tbp_proxy_not_authed').show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
getToken: getToken,
|
||||||
|
setToken: setToken,
|
||||||
|
isLoggedIn: isLoggedIn,
|
||||||
|
logIn: logIn,
|
||||||
|
logOut: logOut,
|
||||||
|
makeUserFromInvite: makeUserFromInvite,
|
||||||
|
forceLogin,
|
||||||
|
logInRedirect,
|
||||||
|
}
|
||||||
|
})(app);
|
15
public/js/app/group.js
Normal file
15
public/js/app/group.js
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
app.group = (function(app){
|
||||||
|
function list(callback){
|
||||||
|
app.api.get('group?detail=true', function(error, data){
|
||||||
|
callback(error, data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function remove(args, callback){
|
||||||
|
app.api.delete('group/'+args.cn, function(error, data){
|
||||||
|
callback(error, data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return {list, remove}
|
||||||
|
})(app);
|
41
public/js/app/pubsub.js
Normal file
41
public/js/app/pubsub.js
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
app.pubsub = (function(){
|
||||||
|
app.topics = {};
|
||||||
|
|
||||||
|
app.subscribe = function(topic, listener) {
|
||||||
|
if(topic instanceof RegExp){
|
||||||
|
listener.match = topic;
|
||||||
|
topic = "__REGEX__";
|
||||||
|
}
|
||||||
|
|
||||||
|
// create the topic if not yet created
|
||||||
|
if(!app.topics[topic]) app.topics[topic] = [];
|
||||||
|
|
||||||
|
// add the listener
|
||||||
|
app.topics[topic].push(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
app.matchTopics = function(topic){
|
||||||
|
topic = topic || '';
|
||||||
|
var matches = [... app.topics[topic] ? app.topics[topic] : []];
|
||||||
|
|
||||||
|
if(!app.topics['__REGEX__']) return matches;
|
||||||
|
|
||||||
|
for(var listener of app.topics['__REGEX__']){
|
||||||
|
if(topic.match(listener.match)) matches.push(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
return matches;
|
||||||
|
}
|
||||||
|
|
||||||
|
app.publish = function(topic, data) {
|
||||||
|
|
||||||
|
// send the event to all listeners
|
||||||
|
app.matchTopics(topic).forEach(function(listener) {
|
||||||
|
setTimeout(function(data, topic){
|
||||||
|
listener(data || {}, topic);
|
||||||
|
}, 0, data, topic);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
})(app);
|
28
public/js/app/socket.js
Normal file
28
public/js/app/socket.js
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
app.socket = (function(app){
|
||||||
|
// $.getScript('/socket.io/socket.io.js')
|
||||||
|
// <script type="text/javascript" src="/socket.io/socket.io.js"></script>
|
||||||
|
|
||||||
|
var socket;
|
||||||
|
$(document).ready(function(){
|
||||||
|
socket = io({
|
||||||
|
auth: {
|
||||||
|
token: app.auth.getToken()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// socket.emit('chat message', $('#m').val());
|
||||||
|
socket.on('P2PSub', function(msg){
|
||||||
|
msg.data.__noSocket = true;
|
||||||
|
app.publish(msg.topic, msg.data);
|
||||||
|
});
|
||||||
|
|
||||||
|
app.subscribe(/./g, function(data, topic){
|
||||||
|
// console.log('local_pubs', data, topic)
|
||||||
|
if(data.__noSocket) return;
|
||||||
|
// console.log('local_pubs 2', data, topic)
|
||||||
|
|
||||||
|
socket.emit('P2PSub', { topic, data });
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
|
return socket;
|
||||||
|
})(app);
|
122
public/js/app/torrent.js
Normal file
122
public/js/app/torrent.js
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
app.torrent = (function(app){
|
||||||
|
let isDown = false;
|
||||||
|
|
||||||
|
$( document ).on( "ajaxSend", function(event, ajax, res, ...args) {
|
||||||
|
console.log('right?', res.url, res.url.startsWith('/__api/torrent'), app.torrent.isDown)
|
||||||
|
if(res.url.startsWith('/__api/torrent') && isDown){
|
||||||
|
ajax.abort()
|
||||||
|
}
|
||||||
|
// $( ".log" ).text( "Triggered ajaxStart handler." );
|
||||||
|
// throw new Error('go')
|
||||||
|
} );
|
||||||
|
|
||||||
|
statusMap = [
|
||||||
|
'Inactive', // 0
|
||||||
|
'CHECK_WAIT', // 1
|
||||||
|
'Verifying', // 2
|
||||||
|
'DOWNLOAD_WAIT', // 3
|
||||||
|
'Downloading', // 4
|
||||||
|
'SEED_WAIT', // 5
|
||||||
|
'Seeding', // 6
|
||||||
|
'ISOLATED', // 7
|
||||||
|
'Unknown', // 8
|
||||||
|
];
|
||||||
|
|
||||||
|
function list(callback, username) {
|
||||||
|
app.api.get('torrent', function(error, data){
|
||||||
|
if(error) return;
|
||||||
|
callback(null, data)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function get(callback, id, forceUpdate){
|
||||||
|
app.api.get(`torrent/${id}?${forceUpdate ? 'latest': '' }`, function(error, data){
|
||||||
|
if(error) return;
|
||||||
|
callback(null, data)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function start(id, callback){
|
||||||
|
app.api.post(`torrent/${id}/start`, function(error, data){
|
||||||
|
if(error) return;
|
||||||
|
callback(null, data)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function stop(id, callback){
|
||||||
|
app.api.post(`torrent/${id}/stop`, function(error, data){
|
||||||
|
if(error) return;
|
||||||
|
callback(null, data)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function destroy(id, callback){
|
||||||
|
app.api.delete(`torrent/${id}`, function(error, data){
|
||||||
|
if(error) return;
|
||||||
|
callback(null, data)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseServerStatus(data){
|
||||||
|
return {
|
||||||
|
...data,
|
||||||
|
"downloadSpeed": humanFileSize(data.downloadSpeed)+'/s',
|
||||||
|
"uploadSpeed": humanFileSize(data.uploadSpeed)+'/s',
|
||||||
|
/* "activeTorrentCount": 11,
|
||||||
|
"cumulative-stats": {
|
||||||
|
"downloadedBytes": 2925927098021,
|
||||||
|
"filesAdded": 80609,
|
||||||
|
"secondsActive": 12136579,
|
||||||
|
"sessionCount": 21,
|
||||||
|
"uploadedBytes": 107123787853
|
||||||
|
},
|
||||||
|
"current-stats": {
|
||||||
|
"downloadedBytes": 48440590262,
|
||||||
|
"filesAdded": 544,
|
||||||
|
"secondsActive": 111907,
|
||||||
|
"sessionCount": 1,
|
||||||
|
"uploadedBytes": 461874022
|
||||||
|
},
|
||||||
|
"pausedTorrentCount": 462,
|
||||||
|
"torrentCount": 473,
|
||||||
|
"__noSocket": true*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseTorrnetItem(torrent){
|
||||||
|
let percentDone = (torrent.percentDone || 0)*100;
|
||||||
|
return {
|
||||||
|
...torrent,
|
||||||
|
"eta": torrent.eta > 0 ? moment().seconds(torrent.eta).fromNow() : 'Unknown',
|
||||||
|
"rateDownload": `${humanFileSize(torrent.rateDownload)}/s`,
|
||||||
|
"sizeWhenDone": humanFileSize(torrent.sizeWhenDone),
|
||||||
|
"percentDone": percentDone,
|
||||||
|
"statusText": statusMap[torrent.status],
|
||||||
|
"isActive": [3, 4, 5, 6].includes(torrent.status), // DOWNLOAD_WAIT ,DOWNLOAD, SEED_WAIT, SEED
|
||||||
|
"isFinished": torrent.isFinished || percentDone === 100,
|
||||||
|
"createdAtString": moment(torrent.createdAt).fromNow(),
|
||||||
|
|
||||||
|
// "isFinished": false,
|
||||||
|
// "isStalled": false,
|
||||||
|
// "name": "reacher.s02e06.1080p.web.h264-successfulcrab[EZTVx.to].mkv",
|
||||||
|
// "hashString": "4794a0915cada6c491eb5c910e1f4a0da727cac8",
|
||||||
|
// "status": 4,
|
||||||
|
// "id": 1,
|
||||||
|
|
||||||
|
// "peersConnected": 50,
|
||||||
|
// "added_by": "wmantly",
|
||||||
|
// "errorString": "",
|
||||||
|
|
||||||
|
// "downloadDir": "/media/torrents",
|
||||||
|
// "files": [],
|
||||||
|
// "peers": [],
|
||||||
|
// "magnetLink": "magnet:?xt=urn:btih:4794A0915CADA6C491EB5C910E1F4A0DA727CAC8&dn=Reacher+S02E06+1080p+WEB+H264-SuccessfulCrab&tr=http%3A%2F%2Fp4p.arenabg.com%3A1337%2Fannounce&tr=udp%3A%2F%2F47.ip-51-68-199.eu%3A6969%2Fannounce&tr=udp%3A%2F%2F9.rarbg.me%3A2780%2Fannounce&tr=udp%3A%2F%2F9.rarbg.to%3A2710%2Fannounce&tr=udp%3A%2F%2F9.rarbg.to%3A2730%2Fannounce&tr=udp%3A%2F%2F9.rarbg.to%3A2920%2Fannounce&tr=udp%3A%2F%2Fopen.stealth.si%3A80%2Fannounce&tr=udp%3A%2F%2Fopentracker.i2p.rocks%3A6969%2Fannounce&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969%2Fannounce&tr=udp%3A%2F%2Ftracker.cyberia.is%3A6969%2Fannounce&tr=udp%3A%2F%2Ftracker.dler.org%3A6969%2Fannounce&tr=udp%3A%2F%2Ftracker.internetwarriors.net%3A1337%2Fannounce&tr=udp%3A%2F%2Ftracker.leechers-paradise.org%3A6969%2Fannounce&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A6969%2Fannounce&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337&tr=udp%3A%2F%2Ftracker.pirateparty.gr%3A6969%2Fannounce&tr=udp%3A%2F%2Ftracker.tiny-vps.com%3A6969%2Fannounce&tr=udp%3A%2F%2Ftracker.torrent.eu.org%3A451%2Fannounce",
|
||||||
|
// "isPrivate": false,
|
||||||
|
// "createdAt": "2024-01-05T21:18:30.607Z",
|
||||||
|
// "updatedAt": "2024-01-05T21:32:54.493Z"
|
||||||
|
// "torrent_id": "454",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {list, get, start, stop, destroy, parseTorrnetItem, parseServerStatus, isDown};
|
||||||
|
})(app);
|
44
public/js/app/user.js
Normal file
44
public/js/app/user.js
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
app.user = (function(app){
|
||||||
|
function list(callback){
|
||||||
|
app.api.get('user/?detail=true', function(error, data){
|
||||||
|
callback(error, data);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function add(args, callback){
|
||||||
|
app.api.post('user/', args, function(error, data){
|
||||||
|
callback(error, data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function remove(args, callback){
|
||||||
|
if(!confirm('Delete '+ args.uid+ 'user?')) return false;
|
||||||
|
app.api.delete('user/'+ args.uid, function(error, data){
|
||||||
|
callback(error, data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function changePassword(args, callback){
|
||||||
|
app.api.put('users/'+ arg.uid || '', args, function(error, data){
|
||||||
|
callback(error, data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function createInvite(callback){
|
||||||
|
app.api.post('user/invite', {}, function(error, data, status){
|
||||||
|
callback(error, data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function consumeInvite(args){
|
||||||
|
app.api.post('/auth/invite/'+args.token, args, function(error, data){
|
||||||
|
if(data.token){
|
||||||
|
app.auth.setToken(data.token)
|
||||||
|
return callback(null, true)
|
||||||
|
}
|
||||||
|
callback(error)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return {list, remove, createInvite};
|
||||||
|
})(app);
|
96
public/js/app/utils.js
Normal file
96
public/js/app/utils.js
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
app.util = (function(app){
|
||||||
|
|
||||||
|
function getUrlParameter(name) {
|
||||||
|
name = name.replace(/[\[]/, '\\[').replace(/[\]]/, '\\]');
|
||||||
|
var regex = new RegExp('[\\?&]' + name + '=([^&#]*)');
|
||||||
|
var results = regex.exec(location.search);
|
||||||
|
return results === null ? '' : decodeURIComponent(results[1].replace(/\+/g, ' '));
|
||||||
|
};
|
||||||
|
|
||||||
|
function actionMessage(message, $target, type, callback){
|
||||||
|
message = message || '';
|
||||||
|
$target = $target.closest('div.card').find('.actionMessage');
|
||||||
|
type = type || 'info';
|
||||||
|
callback = callback || function(){};
|
||||||
|
|
||||||
|
if($target.html() === message) return;
|
||||||
|
|
||||||
|
if($target.html()){
|
||||||
|
$target.slideUp('fast', function(){
|
||||||
|
$target.html('')
|
||||||
|
$target.removeClass (function (index, className) {
|
||||||
|
return (className.match (/(^|\s)ui-\S+/g) || []).join(' ');
|
||||||
|
});
|
||||||
|
if(message) return actionMessage(message, $target, type, callback);
|
||||||
|
$target.hide()
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
if(type) $target.addClass('ui-' + type);
|
||||||
|
$target.html(message).slideDown('fast');
|
||||||
|
}
|
||||||
|
setTimeout(callback,10)
|
||||||
|
}
|
||||||
|
|
||||||
|
$( document ).ready( function () {
|
||||||
|
$('.actionMessage').on('click', 'button.action-close', function(event){
|
||||||
|
app.util.actionMessage(null, $(this));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$.fn.serializeObject = function() {
|
||||||
|
var
|
||||||
|
arr = $(this).serializeArray(),
|
||||||
|
obj = {};
|
||||||
|
|
||||||
|
for(var i = 0; i < arr.length; i++) {
|
||||||
|
if(obj[arr[i].name] === undefined) {
|
||||||
|
obj[arr[i].name] = arr[i].value;
|
||||||
|
} else {
|
||||||
|
if(!(obj[arr[i].name] instanceof Array)) {
|
||||||
|
obj[arr[i].name] = [obj[arr[i].name]];
|
||||||
|
}
|
||||||
|
obj[arr[i].name].push(arr[i].value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
};
|
||||||
|
|
||||||
|
function formAJAX( btn, del ) {
|
||||||
|
event.preventDefault(); // avoid to execute the actual submit of the form.
|
||||||
|
var $form = $(btn).closest( '[action]' ); // gets the 'form' parent
|
||||||
|
var formData = $form.find( '[name]' ).serializeObject(); // builds query formDataing
|
||||||
|
var method = $form.attr('method') || 'post';
|
||||||
|
|
||||||
|
// if( !$form.validate()) {
|
||||||
|
// app.util.actionMessage('Please fix the form errors.', $form, 'danger')
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
|
||||||
|
app.util.actionMessage(
|
||||||
|
'<div class="spinner-border" role="status"><span class="sr-only">Loading...</span></div>',
|
||||||
|
$form,
|
||||||
|
'state-highlight'
|
||||||
|
);
|
||||||
|
|
||||||
|
app.api[method]($form.attr('action'), formData, function(error, data){
|
||||||
|
app.util.actionMessage(data.message, $form, error ? 'state-error' : 'priority-primary'); //re-populate table
|
||||||
|
if(!error){
|
||||||
|
$form.trigger("reset");
|
||||||
|
eval($form.attr('evalAJAX')); //gets JS to run after completion
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function humanFileSize(size) {
|
||||||
|
var i = size == 0 ? 0 : Math.floor(Math.log(size) / Math.log(1024));
|
||||||
|
return (size / Math.pow(1024, i)).toFixed(2) * 1 + ' ' + ['B', 'kB', 'MB', 'GB', 'TB'][i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
emptyFuction: function(){},
|
||||||
|
getUrlParameter,
|
||||||
|
actionMessage,
|
||||||
|
humanFileSize,
|
||||||
|
formAJAX,
|
||||||
|
}
|
||||||
|
})(app);
|
@ -1,3 +1,6 @@
|
|||||||
|
<script type="text/javascript">
|
||||||
|
var JQapp_BASE_PATH = '/__static/js/app';
|
||||||
|
</script>
|
||||||
<link rel="stylesheet" href="/__static-modules/jquery-ui/dist/themes/smoothness/jquery-ui.css">
|
<link rel="stylesheet" href="/__static-modules/jquery-ui/dist/themes/smoothness/jquery-ui.css">
|
||||||
|
|
||||||
<script type="text/javascript" src="/socket.io/socket.io.js"></script>
|
<script type="text/javascript" src="/socket.io/socket.io.js"></script>
|
||||||
@ -6,6 +9,10 @@
|
|||||||
<script src="/__static-modules/moment/min/moment-with-locales.min.js"></script>
|
<script src="/__static-modules/moment/min/moment-with-locales.min.js"></script>
|
||||||
<script src="/__static-modules/jquery-ui/dist/jquery-ui.min.js"></script>
|
<script src="/__static-modules/jquery-ui/dist/jquery-ui.min.js"></script>
|
||||||
<script src="/__static/js/app.js"></script>
|
<script src="/__static/js/app.js"></script>
|
||||||
|
<script>
|
||||||
|
console.log("here", app)
|
||||||
|
app.include('/torrent.js');
|
||||||
|
</script>
|
||||||
|
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
.ui-dialog .ui-dialog-title{
|
.ui-dialog .ui-dialog-title{
|
||||||
@ -353,128 +360,4 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
app.torrent = (function(app){
|
|
||||||
let isDown = false;
|
|
||||||
|
|
||||||
$( document ).on( "ajaxSend", function(event, ajax, res, ...args) {
|
|
||||||
console.log('right?', res.url, res.url.startsWith('/__api/torrent'), app.torrent.isDown)
|
|
||||||
if(res.url.startsWith('/__api/torrent') && isDown){
|
|
||||||
ajax.abort()
|
|
||||||
}
|
|
||||||
// $( ".log" ).text( "Triggered ajaxStart handler." );
|
|
||||||
// throw new Error('go')
|
|
||||||
} );
|
|
||||||
|
|
||||||
statusMap = [
|
|
||||||
'Inactive', // 0
|
|
||||||
'CHECK_WAIT', // 1
|
|
||||||
'Verifying', // 2
|
|
||||||
'DOWNLOAD_WAIT', // 3
|
|
||||||
'Downloading', // 4
|
|
||||||
'SEED_WAIT', // 5
|
|
||||||
'Seeding', // 6
|
|
||||||
'ISOLATED', // 7
|
|
||||||
'Unknown', // 8
|
|
||||||
];
|
|
||||||
|
|
||||||
|
|
||||||
function list(callback, username) {
|
|
||||||
app.api.get('torrent', function(error, data){
|
|
||||||
if(error) return;
|
|
||||||
callback(null, data)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function get(callback, id, forceUpdate){
|
|
||||||
app.api.get(`torrent/${id}?${forceUpdate ? 'latest': '' }`, function(error, data){
|
|
||||||
if(error) return;
|
|
||||||
callback(null, data)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function start(id, callback){
|
|
||||||
app.api.post(`torrent/${id}/start`, function(error, data){
|
|
||||||
if(error) return;
|
|
||||||
callback(null, data)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function stop(id, callback){
|
|
||||||
app.api.post(`torrent/${id}/stop`, function(error, data){
|
|
||||||
if(error) return;
|
|
||||||
callback(null, data)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function destroy(id, callback){
|
|
||||||
app.api.delete(`torrent/${id}`, function(error, data){
|
|
||||||
if(error) return;
|
|
||||||
callback(null, data)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function parseServerStatus(data){
|
|
||||||
return {
|
|
||||||
...data,
|
|
||||||
"downloadSpeed": humanFileSize(data.downloadSpeed)+'/s',
|
|
||||||
"uploadSpeed": humanFileSize(data.uploadSpeed)+'/s',
|
|
||||||
/* "activeTorrentCount": 11,
|
|
||||||
"cumulative-stats": {
|
|
||||||
"downloadedBytes": 2925927098021,
|
|
||||||
"filesAdded": 80609,
|
|
||||||
"secondsActive": 12136579,
|
|
||||||
"sessionCount": 21,
|
|
||||||
"uploadedBytes": 107123787853
|
|
||||||
},
|
|
||||||
"current-stats": {
|
|
||||||
"downloadedBytes": 48440590262,
|
|
||||||
"filesAdded": 544,
|
|
||||||
"secondsActive": 111907,
|
|
||||||
"sessionCount": 1,
|
|
||||||
"uploadedBytes": 461874022
|
|
||||||
},
|
|
||||||
"pausedTorrentCount": 462,
|
|
||||||
"torrentCount": 473,
|
|
||||||
"__noSocket": true*/
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function parseTorrnetItem(torrent){
|
|
||||||
let percentDone = (torrent.percentDone || 0)*100;
|
|
||||||
return {
|
|
||||||
...torrent,
|
|
||||||
"eta": torrent.eta > 0 ? moment().seconds(torrent.eta).fromNow() : 'Unknown',
|
|
||||||
"rateDownload": `${humanFileSize(torrent.rateDownload)}/s`,
|
|
||||||
"sizeWhenDone": humanFileSize(torrent.sizeWhenDone),
|
|
||||||
"percentDone": percentDone,
|
|
||||||
"statusText": statusMap[torrent.status],
|
|
||||||
"isActive": [3, 4, 5, 6].includes(torrent.status), // DOWNLOAD_WAIT ,DOWNLOAD, SEED_WAIT, SEED
|
|
||||||
"isFinished": torrent.isFinished || percentDone === 100,
|
|
||||||
"createdAtString": moment(torrent.createdAt).fromNow(),
|
|
||||||
|
|
||||||
// "isFinished": false,
|
|
||||||
// "isStalled": false,
|
|
||||||
// "name": "reacher.s02e06.1080p.web.h264-successfulcrab[EZTVx.to].mkv",
|
|
||||||
// "hashString": "4794a0915cada6c491eb5c910e1f4a0da727cac8",
|
|
||||||
// "status": 4,
|
|
||||||
// "id": 1,
|
|
||||||
|
|
||||||
// "peersConnected": 50,
|
|
||||||
// "added_by": "wmantly",
|
|
||||||
// "errorString": "",
|
|
||||||
|
|
||||||
// "downloadDir": "/media/torrents",
|
|
||||||
// "files": [],
|
|
||||||
// "peers": [],
|
|
||||||
// "magnetLink": "magnet:?xt=urn:btih:4794A0915CADA6C491EB5C910E1F4A0DA727CAC8&dn=Reacher+S02E06+1080p+WEB+H264-SuccessfulCrab&tr=http%3A%2F%2Fp4p.arenabg.com%3A1337%2Fannounce&tr=udp%3A%2F%2F47.ip-51-68-199.eu%3A6969%2Fannounce&tr=udp%3A%2F%2F9.rarbg.me%3A2780%2Fannounce&tr=udp%3A%2F%2F9.rarbg.to%3A2710%2Fannounce&tr=udp%3A%2F%2F9.rarbg.to%3A2730%2Fannounce&tr=udp%3A%2F%2F9.rarbg.to%3A2920%2Fannounce&tr=udp%3A%2F%2Fopen.stealth.si%3A80%2Fannounce&tr=udp%3A%2F%2Fopentracker.i2p.rocks%3A6969%2Fannounce&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969%2Fannounce&tr=udp%3A%2F%2Ftracker.cyberia.is%3A6969%2Fannounce&tr=udp%3A%2F%2Ftracker.dler.org%3A6969%2Fannounce&tr=udp%3A%2F%2Ftracker.internetwarriors.net%3A1337%2Fannounce&tr=udp%3A%2F%2Ftracker.leechers-paradise.org%3A6969%2Fannounce&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A6969%2Fannounce&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337&tr=udp%3A%2F%2Ftracker.pirateparty.gr%3A6969%2Fannounce&tr=udp%3A%2F%2Ftracker.tiny-vps.com%3A6969%2Fannounce&tr=udp%3A%2F%2Ftracker.torrent.eu.org%3A451%2Fannounce",
|
|
||||||
// "isPrivate": false,
|
|
||||||
// "createdAt": "2024-01-05T21:18:30.607Z",
|
|
||||||
// "updatedAt": "2024-01-05T21:32:54.493Z"
|
|
||||||
// "torrent_id": "454",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {list, get, start, stop, destroy, parseTorrnetItem, parseServerStatus, isDown};
|
|
||||||
})(app);
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
@ -7,8 +7,10 @@ router.get('/', async function(req, res, next){
|
|||||||
try{
|
try{
|
||||||
res.json({results: await Torrent.findAll({
|
res.json({results: await Torrent.findAll({
|
||||||
where:{added_by: req.query.username || req.user.username},
|
where:{added_by: req.query.username || req.user.username},
|
||||||
limit: req.query.limit,
|
// limit: req.query.limit,
|
||||||
offset: req.query.offset
|
// offset: req.query.offset,
|
||||||
|
// order: [[req.query.orderKey || "created_at", (req.query.asc && "ASC")]],
|
||||||
|
// from: {$between: [startDate, endDate]}
|
||||||
})});
|
})});
|
||||||
}catch(error){
|
}catch(error){
|
||||||
next(error);
|
next(error);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user