first
This commit is contained in:
parent
7fad640cca
commit
77519e6d52
441
public/js/app.js
441
public/js/app.js
@ -1,419 +1,56 @@
|
||||
var app = {};
|
||||
// socket
|
||||
|
||||
app.pubsub = (function(){
|
||||
app.topics = {};
|
||||
// api
|
||||
|
||||
app.subscribe = function(topic, listener) {
|
||||
if(topic instanceof RegExp){
|
||||
listener.match = topic;
|
||||
topic = "__REGEX__";
|
||||
}
|
||||
// auth
|
||||
|
||||
// create the topic if not yet created
|
||||
if(!app.topics[topic]) app.topics[topic] = [];
|
||||
// user
|
||||
|
||||
// add the listener
|
||||
app.topics[topic].push(listener);
|
||||
}
|
||||
// group
|
||||
|
||||
app.matchTopics = function(topic){
|
||||
topic = topic || '';
|
||||
var matches = [... app.topics[topic] ? app.topics[topic] : []];
|
||||
"use strict";
|
||||
/* globals jQuery, Mustache, XRegExp, $, app */
|
||||
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) {
|
||||
|
||||
// send the event to all listeners
|
||||
app.matchTopics(topic).forEach(function(listener) {
|
||||
setTimeout(function(data, topic){
|
||||
listener(data || {}, topic);
|
||||
}, 0, data, topic);
|
||||
jQuery.ajax({
|
||||
url: path,
|
||||
dataType: 'script',
|
||||
async: false
|
||||
});
|
||||
}
|
||||
|
||||
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){
|
||||
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');
|
||||
app.include = function(scripts, base){
|
||||
scripts = $.isArray(scripts) ? scripts : [scripts];
|
||||
for(let script of scripts){
|
||||
app.includeScrip(script, base)
|
||||
}
|
||||
setTimeout(callback,10)
|
||||
}
|
||||
})(jQuery);
|
||||
|
||||
$.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;
|
||||
};
|
||||
|
||||
return {
|
||||
getUrlParameter: getUrlParameter,
|
||||
actionMessage: actionMessage,
|
||||
emptyFuction: function(){},
|
||||
|
||||
}
|
||||
})(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));
|
||||
})
|
||||
app.include([
|
||||
'/utils.js',
|
||||
'/pubsub.js',
|
||||
'/api.js',
|
||||
'/socket.js',
|
||||
'/user.js',
|
||||
'/group.js',
|
||||
'/auth.js',
|
||||
], JQapp_BASE_PATH)
|
||||
|
||||
/*
|
||||
when the DOM is finished, start the app
|
||||
*/
|
||||
jQuery(document).on("DOMContentLoaded", function(event) {
|
||||
app.publish("__dom-content-loaded-start");
|
||||
app.publish("__dom-content-loaded-end");
|
||||
});
|
||||
|
||||
//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">
|
||||
|
||||
<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/jquery-ui/dist/jquery-ui.min.js"></script>
|
||||
<script src="/__static/js/app.js"></script>
|
||||
<script>
|
||||
console.log("here", app)
|
||||
app.include('/torrent.js');
|
||||
</script>
|
||||
|
||||
<style type="text/css">
|
||||
.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>
|
||||
|
@ -7,8 +7,10 @@ router.get('/', async function(req, res, next){
|
||||
try{
|
||||
res.json({results: await Torrent.findAll({
|
||||
where:{added_by: req.query.username || req.user.username},
|
||||
limit: req.query.limit,
|
||||
offset: req.query.offset
|
||||
// limit: req.query.limit,
|
||||
// offset: req.query.offset,
|
||||
// order: [[req.query.orderKey || "created_at", (req.query.asc && "ASC")]],
|
||||
// from: {$between: [startDate, endDate]}
|
||||
})});
|
||||
}catch(error){
|
||||
next(error);
|
||||
|
Loading…
x
Reference in New Issue
Block a user