2013-01-29 13:47:40 +01:00
angular
2013-03-02 12:01:07 +01:00
. module ( 'webui.services.rpc' , [
2013-03-11 19:16:48 +01:00
'webui.services.rpc.syscall' , 'webui.services.constants' , 'webui.services.alerts' ,
'webui.services.utils'
2013-03-02 12:01:07 +01:00
] )
2013-03-12 07:51:44 +01:00
. factory ( '$rpc' , [
'$syscall' , '$globalTimeout' , '$alerts' , '$utils' ,
2013-03-20 10:08:50 +01:00
'$rootScope' , '$location' ,
function ( syscall , time , alerts , utils , rootScope , uri ) {
2013-03-02 12:01:07 +01:00
2013-01-17 07:51:03 +01:00
var subscriptions = [ ]
2013-03-09 06:35:53 +01:00
, configurations = [ { host : 'localhost' , port : 6800 , encrypt : false } ]
2013-03-02 12:01:07 +01:00
, currentConf = { }
2013-01-17 07:51:03 +01:00
, timeout = null
, forceNextUpdate = false ;
2013-01-15 09:24:09 +01:00
2013-03-20 10:08:50 +01:00
if ( [ 'http' , 'https' ] . indexOf ( uri . protocol ( ) ) != - 1 ) {
console . log ( uri . host ( ) ) ;
configurations . unshift ( {
host : uri . host ( ) ,
2013-03-19 22:03:34 +01:00
port : 6800 ,
encrypt : false
} ) ;
2013-03-20 10:08:50 +01:00
console . log ( configurations ) ;
}
2013-03-19 22:03:34 +01:00
2013-03-11 19:16:48 +01:00
var cookieConf = utils . getCookie ( 'aria2conf' ) ;
2013-06-22 22:37:14 +02:00
// try at the end, so that it is not overwridden in case it doesnt work
if ( cookieConf ) configurations . push ( cookieConf ) ;
2013-01-15 09:24:09 +01:00
// update is implemented such that
// only one syscall at max is ongoing
// (i.e. serially) so should be private
// to maintain that invariant
var update = function ( ) {
2013-03-02 12:01:07 +01:00
clearTimeout ( timeout ) ;
timeout = null ;
2014-01-09 04:18:44 +01:00
subscriptions = _ . filter ( subscriptions , function ( e ) {
return ! ! e && e . once !== 2 ;
} ) ;
var subs = subscriptions . slice ( ) ;
if ( ! subs . length ) {
2013-03-02 12:01:07 +01:00
timeout = setTimeout ( update , time ) ;
2013-01-17 07:51:03 +01:00
return ;
2013-03-02 12:01:07 +01:00
}
2013-01-17 07:51:03 +01:00
2013-03-02 12:01:07 +01:00
if ( configurations . length ) {
currentConf = configurations . shift ( ) ;
syscall . init ( currentConf ) ;
}
2013-01-15 09:24:09 +01:00
2014-01-09 04:18:44 +01:00
var params = _ . map ( subs , function ( s ) {
2013-01-15 09:24:09 +01:00
return {
methodName : s . name ,
params : s . params && s . params . length ? s . params : undefined
} ;
} ) ;
syscall . invoke ( {
name : 'system.multicall' ,
params : [ params ] ,
success : function ( data ) {
2013-02-22 20:44:10 +01:00
2013-03-02 12:01:07 +01:00
if ( configurations . length ) {
// configuration worked, save it in cookie for next time and
// delete the pipelined configurations!!
2014-02-22 03:39:52 +01:00
alerts . log ( 'Success alas! Saving the current configuration…' ) ;
2013-03-02 12:01:07 +01:00
configurations = [ ] ;
}
2013-03-11 19:16:48 +01:00
utils . setCookie ( 'aria2conf' , currentConf ) ;
2013-03-18 15:59:40 +01:00
var cbs = [ ] ;
2013-01-15 09:24:09 +01:00
_ . each ( data . result , function ( d , i ) {
2014-01-09 04:18:44 +01:00
var handle = subs [ i ] ;
2013-01-15 09:24:09 +01:00
if ( handle ) {
2013-02-22 20:44:10 +01:00
if ( d . code ) {
2014-01-09 04:18:44 +01:00
console . error ( handle , d ) ;
2013-02-22 20:44:10 +01:00
alerts . addAlert ( d . message , 'error' ) ;
}
2013-03-18 15:59:40 +01:00
// run them later as the cb itself can mutate the subscriptions
cbs . push ( { cb : handle . cb , data : d } ) ;
2013-01-15 09:24:09 +01:00
if ( handle . once ) {
2014-01-09 04:18:44 +01:00
handle . once = 2 ;
2013-01-15 09:24:09 +01:00
}
}
} ) ;
2013-03-18 15:59:40 +01:00
_ . each ( cbs , function ( hnd ) {
hnd . cb ( hnd . data ) ;
} ) ;
rootScope . $digest ( ) ;
2013-03-12 07:51:44 +01:00
2013-01-15 09:24:09 +01:00
if ( forceNextUpdate ) {
forceNextUpdate = false ;
2013-03-02 12:01:07 +01:00
timeout = setTimeout ( update , 0 ) ;
}
else {
timeout = setTimeout ( update , time ) ;
2013-01-15 09:24:09 +01:00
}
} ,
error : function ( ) {
2013-01-17 07:51:03 +01:00
// If some proposed configurations are still in the pipeline then retry
2013-02-26 15:02:26 +01:00
if ( configurations . length ) {
2014-02-22 03:39:52 +01:00
alerts . log ( "The last connection attempt was unsuccessful. Trying another configuration" ) ;
2013-03-02 12:01:07 +01:00
timeout = setTimeout ( update , 0 ) ;
2013-02-26 15:02:26 +01:00
}
2013-01-17 07:51:03 +01:00
else {
2014-02-22 03:39:52 +01:00
alerts . addAlert ( '<strong>Oh Snap!</strong> Could not connect to the aria2 RPC server. Will retry in ' + time / 1000 + ' secs. You might want to check the connection settings by going to Settings > Connection Settings' , 'error' ) ;
2013-01-17 07:51:03 +01:00
timeout = setTimeout ( update , time ) ;
}
2013-01-15 09:24:09 +01:00
}
} ) ;
2013-03-02 12:01:07 +01:00
} ;
// initiate the update loop
timeout = setTimeout ( update , time ) ;
2013-01-15 09:24:09 +01:00
return {
2013-01-17 07:51:03 +01:00
// conf can be configuration or array of configurations,
// each one will be tried one after the other till success,
// for all options for one conf read rpc/syscall.js
2013-01-15 09:24:09 +01:00
configure : function ( conf ) {
2013-03-09 06:35:53 +01:00
alerts . addAlert ( 'Successfully changed aria2 connection configuration' , 'success' ) ;
2013-01-17 07:51:03 +01:00
if ( conf instanceof Array )
configurations = conf ;
else
configurations = [ conf ] ;
2013-01-15 09:24:09 +01:00
} ,
2013-03-09 06:35:53 +01:00
// get current configuration being used
getConfiguration : function ( ) { return currentConf } ,
2013-01-28 15:18:21 +01:00
// syscall is done only once, delay is optional
// and pass true to only dispatch it in the global timeout
// which can be used to batch up once calls
once : function ( name , params , cb , delay ) {
2013-01-22 11:12:40 +01:00
cb = cb || angular . noop ;
params = params || [ ] ;
2013-03-18 15:59:40 +01:00
subscriptions . unshift ( {
2013-01-15 09:24:09 +01:00
once : true ,
name : 'aria2.' + name ,
params : params ,
cb : cb
} ) ;
2013-01-28 15:18:21 +01:00
if ( ! delay ) {
this . forceUpdate ( ) ;
}
2013-01-15 09:24:09 +01:00
} ,
// callback is called each time with updated syscall data
2013-01-28 15:18:21 +01:00
// after the global timeout, delay is optional and pass it
// true to dispatch the first syscall also on global timeout
// which can be used to batch the subscribe calls
subscribe : function ( name , params , cb , delay ) {
2013-01-22 11:12:40 +01:00
cb = cb || angular . noop ;
params = params || [ ] ;
2013-01-15 09:24:09 +01:00
var handle = {
once : false ,
name : 'aria2.' + name ,
params : params ,
cb : cb
} ;
subscriptions . push ( handle ) ;
2013-01-28 15:18:21 +01:00
if ( ! delay ) this . forceUpdate ( ) ;
2013-01-15 09:24:09 +01:00
return handle ;
} ,
// remove the subscribed callback by passing
// the returned handle bysubscribe
unsubscribe : function ( handle ) {
var ind = subscriptions . indexOf ( handle ) ;
subscriptions [ ind ] = null ;
} ,
// force the global syscall update
forceUpdate : function ( ) {
if ( timeout ) {
clearTimeout ( timeout ) ;
2013-03-02 12:01:07 +01:00
timeout = setTimeout ( update , 0 ) ;
2013-01-15 09:24:09 +01:00
}
else {
// a batch call is already in progress,
// wait till it returns and force the next one
forceNextUpdate = true ;
}
}
} ;
} ] ) ;