From 4a049d324188db5a54fd95876ed47dbfb263901f Mon Sep 17 00:00:00 2001 From: Andrea Cotza Date: Mon, 10 Aug 2015 22:57:41 +0200 Subject: [PATCH] Release --- README.md | 18 + manifest.json | 46 + scripts/install | 134 +++ scripts/remove | 26 + scripts/upgrade | 0 sources/init/rtorrent | 36 + sources/nginx/rutorrent.conf | 27 + sources/plugins/create/conf.php | 13 + sources/plugins/filemanager/conf.php | 29 + sources/plugins/mobile/init.js | 1402 ++++++++++++++++++++++++++ sources/rtorrent/rtorrent.rc | 20 + sources/rutorrent/config.php | 64 ++ 12 files changed, 1815 insertions(+) create mode 100755 README.md create mode 100755 manifest.json create mode 100755 scripts/install create mode 100755 scripts/remove create mode 100644 scripts/upgrade create mode 100644 sources/init/rtorrent create mode 100644 sources/nginx/rutorrent.conf create mode 100755 sources/plugins/create/conf.php create mode 100644 sources/plugins/filemanager/conf.php create mode 100644 sources/plugins/mobile/init.js create mode 100644 sources/rtorrent/rtorrent.rc create mode 100755 sources/rutorrent/config.php diff --git a/README.md b/README.md new file mode 100755 index 0000000..b092bfc --- /dev/null +++ b/README.md @@ -0,0 +1,18 @@ +RuTorrent for Yunohost +============ + +Install ruTorrent + rtorrent + +Official website: + +Info +---- + +This package install only a shared instance of rutorrent/rtorrent. + +Every user who has access to rutorrent sees all the torrents + +Versions +-------- + +rtorrent v0.9.4 and libtorrent 0.13.4 diff --git a/manifest.json b/manifest.json new file mode 100755 index 0000000..05aa39c --- /dev/null +++ b/manifest.json @@ -0,0 +1,46 @@ +{ + "name": "ruTorrent", + "id": "rutorrent", + "description": { + "en": "Torrent client", + "fr": "Client torrent" + }, + "developer": { + "name": "Andrea Cotza", + "email": "andrea@cotza.me" + }, + "multi_instance": "false", + "arguments": { + "install": [ + { + "name": "domain", + "type": "domain", + "ask": { + "en": "Choose a domain for ruTorrent", + "fr": "Choisissez un domaine pour ruTorrent" + }, + "example": "domain.org" + }, + { + "name": "path", + "type": "path", + "ask": { + "en": "Choose a path for ruTorrent", + "fr": "Choisissez un chemin pour ruTorrent" + }, + "example": "/rutorrent", + "default": "/rutorrent" + }, + { + "name": "data_dir", + "type": "path", + "ask": { + "en": "Choose a folder to store the downloads", + "fr": "Choisissez un dossier pour sauver les telechargements" + }, + "example": "/mnt/disk1/torrents", + "default": "/home/rtorrent" + } + ] + } +} diff --git a/scripts/install b/scripts/install new file mode 100755 index 0000000..778fe29 --- /dev/null +++ b/scripts/install @@ -0,0 +1,134 @@ +#!/bin/bash + +# Retrieve arguments +domain=$1 +path=$2 +data_dir=$3 +current_dir=${PWD} +debian_version=$(lsb_release -c -s) + +# Check domain/path availability +sudo yunohost app checkurl $domain$path -a rutorrent +if [[ ! $? -eq 0 ]]; then + echo "Error: domain/path not available" + exit 1 +fi + +# Install sources +if [ "$debian_version" = "jessie" ]; then + sudo apt-get install -y deb-multimedia-keyring + echo 'deb http://ftp2.fr.debian.org/debian/ jessie main non-free' | sudo tee -a /etc/apt/sources.list.d/rutorrent.list + echo 'deb-src http://ftp2.fr.debian.org/debian/ jessie main non-free' | sudo tee -a /etc/apt/sources.list.d/rutorrent.list + echo 'deb ftp://ftp.deb-multimedia.org jessie main non-free' | sudo tee -a /etc/apt/sources.list.d/rutorrent.list +else + echo 'deb http://ftp2.fr.debian.org/debian/ wheezy main non-free' | sudo tee -a /etc/apt/sources.list.d/rutorrent.list + echo 'deb-src http://ftp2.fr.debian.org/debian/ wheezy main non-free' | sudo tee -a /etc/apt/sources.list.d/rutorrent.list +fi + +# Install de dependencies +sudo apt-get update +sudo apt-get install -y htop automake libcppunit-dev libtool build-essential pkg-config libssl-dev libcurl4-openssl-dev libsigc++-2.0-dev libncurses5-dev screen subversion apache2-utils php5-cli php5-geoip unzip unrar rar zip ffmpeg buildtorrent mediainfo + +# Build xmlrpc +cd /tmp +sudo svn checkout http://svn.code.sf.net/p/xmlrpc-c/code/stable xmlrpc-c +cd xmlrpc-c/ +sudo ./configure +sudo make +sudo make install + +# Build libtorrent +cd /tmp +sudo git clone https://github.com/rakshasa/libtorrent.git +cd libtorrent +sudo git checkout 0.13.4 +sudo ./autogen.sh +sudo ./configure +sudo make +sudo make install + +# Build rtorrent +cd /tmp +sudo git clone https://github.com/rakshasa/rtorrent.git +cd rtorrent +sudo git checkout 0.9.4 +sudo ./autogen.sh +sudo ./configure --with-xmlrpc-c +sudo make +sudo make install + +sudo ldconfig + +# Install rutorrent +sudo git clone https://github.com/Novik/ruTorrent.git /var/www/rutorrent + +# Install rutorrent plugins +cd /var/www/rutorrent/plugins/ + +sudo git clone https://github.com/xombiemp/rutorrentMobile.git mobile + +sudo svn checkout http://svn.rutorrent.org/svn/filemanager/trunk/filemanager + +# Configure plugins +cd $current_dir + +sudo rm /var/www/rutorrent/plugins/create/conf.php +sudo cp ../sources/plugins/create/conf.php /var/www/rutorrent/plugins/create/conf.php + +sudo rm /var/www/rutorrent/plugins/filemanager/conf.php +sudo cp ../sources/plugins/filemanager/conf.php /var/www/rutorrent/plugins/filemanager/conf.php + +sudo rm /var/www/rutorrent/plugins/mobile/init.js +sudo cp ../sources/plugins/mobile/init.js /var/www/rutorrent/plugins/mobile/init.js + +# Configure nginx +sudo sed -i "s@PATHTOCHANGE@$path@g" ../sources/nginx/rutorrent.conf +sudo cp ../sources/nginx/rutorrent.conf /etc/nginx/conf.d/$domain.d/rutorrent.conf + +# Create data dir +sudo mkdir $data_dir +sudo mkdir $data_dir/watch +sudo mkdir $data_dir/downloads +sudo mkdir $data_dir/.session + +# Create rtorrent user +sudo useradd -p $(openssl passwd -1 rtorrent) -m rtorrent + +# Add rtorrent config +sudo sed -i "s@DATA_DIR@$data_dir@g" ../sources/rtorrent/rtorrent.rc +sudo cp ../sources/rtorrent/rtorrent.rc /home/rtorrent/.rtorrent.rc +sudo chown -R rtorrent:www-data /home/rtorrent/.rtorrent.rc + +sudo chown -R rtorrent:www-data $data_dir +sudo chmod 755 $data_dir + +# Configure rutorrent +sudo sed -i "s@DATA_DIR@$data_dir@g" ../sources/rutorrent/config.php +sudo cp ../sources/rutorrent/config.php /var/www/rutorrent/conf/config.php +sudo chown -R www-data:www-data /var/www/rutorrent + +# Check port availability +sudo yunohost app checkport 45069 +if [[ ! $? -eq 0 ]]; then + exit 1 +fi + +# Open port in firewall +sudo yunohost firewall allow TCP 45069 > /dev/null 2>&1 + +# Launch rtorrent on boot +sudo cp ../sources/init/rtorrent /etc/init.d/rtorrent +sudo chmod +x /etc/init.d/rtorrent +sudo update-rc.d rtorrent defaults + +# Start rtorrent +sudo service rtorrent start +sudo yunohost app ssowatconf +sudo service nginx reload + +# Save config +sudo yunohost app setting rutorrent data_dir -v $data_dir +sudo yunohost app setting rutorrent path -v $path + +# Register the service on yunohost +sudo yunohost service add rtorrent diff --git a/scripts/remove b/scripts/remove new file mode 100755 index 0000000..deb50ea --- /dev/null +++ b/scripts/remove @@ -0,0 +1,26 @@ +#!/bin/bash +domain=$(sudo yunohost app setting rutorrent domain) +data_dir=$(sudo yunohost app setting rutorrent data_dir) + +sudo service rtorrent stop + +sudo rm -rf /var/www/rutorrent +sudo rm -rf $data_dir +sudo rm -f /etc/nginx/conf.d/$domain.d/rutorrent.conf +sudo rm -f /etc/init.d/rtorrent + +# Remove the user +sudo userdel -f rtorrent +sudo rm -rf /home/rtorrent + +# Remove the service +sudo yunohost service remove rtorrent + +# Remove the sources +sudo rm -f /etc/apt/sources.list.d/rutorrent.list + +# Remove rtorrent +sudo rm -f /usr/local/bin/rtorrent + +sudo yunohost app ssowatconf +sudo service nginx reload diff --git a/scripts/upgrade b/scripts/upgrade new file mode 100644 index 0000000..e69de29 diff --git a/sources/init/rtorrent b/sources/init/rtorrent new file mode 100644 index 0000000..e386c10 --- /dev/null +++ b/sources/init/rtorrent @@ -0,0 +1,36 @@ +#!/usr/bin/env bash + +# Dépendance : screen, killall et rtorrent +### BEGIN INIT INFO +# Provides: -rtorrent +# Required-Start: $syslog $network +# Required-Stop: $syslog $network +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Start daemon at boot time +# Description: Start-Stop rtorrent user session +### END INIT INFO + +## Début configuration ## +user="rtorrent" +## Fin configuration ## + +rt_start() { + su --command="screen -dmS rtorrent rtorrent" "${user}" +} + +rt_stop() { + killall --user "${user}" screen +} + +case "$1" in +start) echo "Starting rtorrent..."; rt_start + ;; +stop) echo "Stopping rtorrent..."; rt_stop + ;; +restart) echo "Restart rtorrent..."; rt_stop; sleep 1; rt_start + ;; +*) echo "Usage: $0 {start|stop|restart}"; exit 1 + ;; +esac +exit 0 diff --git a/sources/nginx/rutorrent.conf b/sources/nginx/rutorrent.conf new file mode 100644 index 0000000..f970e1f --- /dev/null +++ b/sources/nginx/rutorrent.conf @@ -0,0 +1,27 @@ +location PATHTOCHANGE { + alias /var/www/rutorrent; + + if ($scheme = http) { + rewrite ^ https://$server_name$request_uri? permanent; + } + + client_max_body_size 10G; + index index.html; + try_files $uri $uri/ index.html; + location ~ [^/]\.php(/|$) { + fastcgi_split_path_info ^(.+?\.php)(/.*)$; + fastcgi_pass unix:/var/run/php5-fpm.sock; + fastcgi_index index.html; + fastcgi_param SCRIPT_FILENAME $request_filename; + include fastcgi_params; + } + + include conf.d/yunohost_panel.conf.inc; + +} + +location PATHTOCHANGE/RPC2 { + scgi_pass 127.0.0.1:5000; + include scgi_params; + scgi_param SCRIPT_NAME /RPC2; +} diff --git a/sources/plugins/create/conf.php b/sources/plugins/create/conf.php new file mode 100755 index 0000000..1cf6366 --- /dev/null +++ b/sources/plugins/create/conf.php @@ -0,0 +1,13 @@ + diff --git a/sources/plugins/mobile/init.js b/sources/plugins/mobile/init.js new file mode 100644 index 0000000..c30374c --- /dev/null +++ b/sources/plugins/mobile/init.js @@ -0,0 +1,1402 @@ +/*** Configurable Options ***/ +plugin.enableAutodetect = true; +plugin.tabletsDetect = true; +plugin.eraseWithDataDefault = false; +plugin.sort = '-addtime'; /* 'name', 'size', 'uploaded', 'downloaded', 'done', 'eta', 'ul', 'dl', 'ratio', 'addtime', 'seedingtime'. Add preceding negative for descending sort. */ +/*** End Configurable Options ***/ + +plugin.statusFilter = {downloading: 1, completed: 2, label: 4, all: 3, tracker: 5, active: 6, inactive: 7, error: 8}; +plugin.navFilter = undefined; +plugin.torrents = null; +plugin.labels = null; +plugin.torrent = undefined; +plugin.lastHref = ""; +plugin.currFilter = plugin.statusFilter.all; +plugin.labelInEdit = false; +plugin.eraseWithDataLoaded = false; +plugin.ratioGroupsLoaded = false; +plugin.throttleLoaded = false; +plugin.seedingtimeLoaded = false; +plugin.getDirLoaded = false; +plugin.bootstrapJS = false; + +var pageToHash = { + 'torrentsList': '', + 'torrentDetails': 'details', + 'globalSettings': 'settings', + 'torrentSort': 'sort', + 'addTorrent': 'add', + 'confimTorrentDelete': 'delete', + 'getDirList': 'filesystem' +}; + +var detailsIdToLangId = { + 'status' : 'Status', + 'done' : 'Done', + 'downloaded' : 'Downloaded', + 'size' : 'Size', + 'timeElapsed' : 'Time_el', + 'remaining' : 'Remaining', + 'eta' : 'ETA', + 'ratio' : 'Ratio', + 'downloadSpeed' : 'Down_speed', + 'wasted' : 'Wasted', + 'uploaded' : 'Uploaded', + 'uploadSpeed' : 'Ul_speed', + 'seeds' : 'Seeds', + 'peers' : 'Peers', + 'label' : 'Label', + 'priority' : 'Priority', + 'trackerStatus' : 'Track_status' +}; + +if(!$type(theWebUI.getTrackerName)) +{ + theWebUI.getTrackerName = function(announce) + { + var domain = ''; + if(announce) + { + var parts = announce.match(/^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/); + if(parts && (parts.length>6)) + { + domain = parts[6]; + if(!domain.match(/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/)) + { + parts = domain.split("."); + if(parts.length>2) + { + if($.inArray(parts[parts.length-2]+"", ["co", "com", "net", "org"])>=0 || + $.inArray(parts[parts.length-1]+"", ["uk"])>=0) + parts = parts.slice(parts.length-3); + else + parts = parts.slice(parts.length-2); + domain = parts.join("."); + } + } + } + } + return(domain); + } +} + +$(document).on('blur', 'input, select, textarea', function() { + setTimeout(function() { + $(window).scrollTop($(window).scrollTop()+1); + }, 0); +}); + +plugin.getRatioData = function(id) +{ + var curNo = -1; + var s = this.torrents[id].ratiogroup; + var arr = s.match(/rat_(\d{1,2})/); + if(arr && (arr.length>1)) { + curNo = arr[1]; + } + return(curNo); +}; + +plugin.toogleDisplay = function(s) { + if (s.css('display') == 'none') { + s.css('display', '') + } else{ + s.css('display', 'none'); + } +}; + +plugin.backListener = function() { + if (this.lastHref != window.location.href) { + if (window.location.hash == '#details') { + if (this.torrent != undefined) { + this.showDetails(this.torrent.hash); + } + } else if (window.location.hash == '#settings') { + this.showSettings(); + } else if (window.location.hash == '#add') { + this.addTorrent(); + } else if (window.location.hash == '#sort') { + this.showSort(); + } else if (window.location.hash == '#delete') { + if (this.torrent != undefined) { + this.delete(); + } + } else { + this.showList(); + } + } +}; + +plugin.request = function(url, func) { + theWebUI.requestWithTimeout(url, function(d){if (func != undefined) func(d);}, function(){}, function(){}); +}; + +plugin.setHash = function(page) { + window.location.hash = pageToHash[page]; + this.lastHref = window.location.href; + window.scrollTo(0,0); +}; + +plugin.showAlert = function(message,alerttype) { + $('#alert_placeholder').append(''); + setTimeout(function() { + $('#alertdiv').removeClass('in'); + setTimeout(function() { + $("#alertdiv").remove(); + }, 1500); + }, 5000); +}; + +plugin.createiFrame = function() { + $('#addTorrent').prepend('') + $('#uploadFrame').load(function() { + var d = (this.contentDocument || this.contentWindow.document); + + if(d && (d.location.href != "about:blank")) { + var matchedRegex = d.body.innerHTML.match(/noty\(".*"\+(.*),"(.*)"/); + if (matchedRegex != null) { + var message = ''; + try {message = eval(matchedRegex[1]);} catch(e) { } + if (message != '') { + if(matchedRegex[2] == "success") { + plugin.showAlert(message,"alert-success"); + } else if (matchedRegex[2] == "error") { + plugin.showAlert(message,"alert-danger"); + } + } + } + } + $('#uploadFrame').remove(); + }); +}; + +plugin.showPage = function(page) { + $('.mainContainer').css('display', 'none'); + $('.torrentControl').css('display', 'none'); + $('#' + page).css('display', ''); + this.setHash(page); +}; + +plugin.showList = function() { + this.showPage('torrentsList'); +}; + +plugin.filter = function(f, self, l) { + if ($('#torrentsList').is(':visible')) { + $('#torrentsLabels').css('width', ''); + $('#torrentsTrackers').css('width', ''); + $('#torrentsLabels > a > span').css('width', ''); + $('#torrentsTrackers > a > span').css('width', ''); + } + if (f == this.statusFilter.label) { + $('.torrentBlock').css('display', 'none'); + $('.label' + this.labelIds[l]).css('display', ''); + this.navFilter = l; + if (l == '') + l = theUILang.No_label; + $('#torrentsStatus > a > span').html(theUILang.Status); + $('#torrentsTrackers > a > span').html(theUILang.Trackers); + $('#torrentsLabels > a > span').html(l); + $('#torrentsList ul li').removeClass('active'); + $('#torrentsLabels').addClass('active'); + var totalWidth = $('#torrentsList .nav').width(); + var combinedWidth = $('#torrentsStatus').outerWidth(true) + $('#torrentsTrackers').outerWidth(true) + $('#sort').outerWidth(true); + var selfWidth = $('#torrentsLabels').width(); + var selfExcess = $('#torrentsLabels').outerWidth(true) - selfWidth; + var diffWidth = totalWidth - combinedWidth - selfExcess; + if (diffWidth < selfWidth && selfWidth > 0 && diffWidth > 0) { + $('#torrentsLabels').width(diffWidth); + var spanWidth = $('#torrentsLabels > a').width() - $('#torrentsLabels > a > b').outerWidth(true); + $('#torrentsLabels > a > span').width(spanWidth); + } + } else if (f == this.statusFilter.tracker) { + $('.torrentBlock').css('display', 'none'); + $('.tracker' + this.trackerIds[l]).css('display', ''); + this.navFilter = l; + $('#torrentsStatus > a > span').html(theUILang.Status); + $('#torrentsLabels > a > span').html(theUILang.Labels); + $('#torrentsTrackers > a > span').html(l); + $('#torrentsList ul li').removeClass('active'); + $('#torrentsTrackers').addClass('active'); + var totalWidth = $('#torrentsList .nav').width(); + var combinedWidth = $('#torrentsStatus').outerWidth(true) + $('#torrentsLabels').outerWidth(true) + $('#sort').outerWidth(true); + var selfWidth = $('#torrentsTrackers').width(); + var selfExcess = $('#torrentsTrackers').outerWidth(true) - selfWidth; + var diffWidth = totalWidth - combinedWidth - selfExcess; + if (diffWidth < selfWidth && selfWidth > 0 && diffWidth > 0) { + $('#torrentsTrackers').width(diffWidth); + var spanWidth = $('#torrentsTrackers > a').width() - $('#torrentsTrackers > a > b').outerWidth(true); + $('#torrentsTrackers > a > span').width(spanWidth); + } + } else { + if (f == this.statusFilter.all) { + $('.statusDownloading').css({display: ''}); + $('.statusCompleted').css({display: ''}); + $('#torrentsStatus > a > span').html(theUILang.All); + } + if (f == this.statusFilter.downloading) { + $('.statusDownloading').css({display: ''}); + $('.statusCompleted').css({display: 'none'}); + $('#torrentsStatus > a > span').html(theUILang.Downloading); + } + if (f == this.statusFilter.completed) { + $('.statusDownloading').css({display: 'none'}); + $('.statusCompleted').css({display: ''}); + $('#torrentsStatus > a > span').html(theUILang.Finished); + } + if (f == this.statusFilter.active) { + $('.stateActive').css({display: ''}); + $('.stateInactive').css({display: 'none'}); + $('#torrentsStatus > a > span').html(theUILang.Active); + } + if (f == this.statusFilter.inactive) { + $('.stateActive').css({display: 'none'}); + $('.stateInactive').css({display: ''}); + $('#torrentsStatus > a > span').html(theUILang.Inactive); + } + if (f == this.statusFilter.error) { + $('.errorNo').css({display: 'none'}); + $('.errorYes').css({display: ''}); + $('#torrentsStatus > a > span').html(theUILang.Error); + } + + $('#torrentsLabels > a > span').html(theUILang.Labels); + $('#torrentsTrackers > a > span').html(theUILang.Trackers); + $('#torrentsList ul li').removeClass('active'); + $('#torrentsStatus').addClass('active'); + } + this.currFilter = f; +}; + +plugin.showSettings = function() { + this.request("?action=gettotal", function(total) { + $('#dlLimit').html(''); + $('#ulLimit').html(''); + + var speeds = theWebUI.settings["webui.speedlistdl"].split(","); + + for (var i = 0; i < speeds.length; i++) { + var spd = speeds[i] * 1024; + $('#dlLimit').append('' + theConverter.speed(spd) + ''); + }; + $('#dlLimit').append('= 100*1024*1024) ? ' selected' : '') + ' value="' + 100 * 1024 * 1024 + '">' + theUILang.unlimited + ''); + + speeds=theWebUI.settings["webui.speedlistul"].split(","); + + for (var i = 0; i < speeds.length; i++) { + var spd = speeds[i] * 1024; + $('#ulLimit').append('' + theConverter.speed(spd) + ''); + }; + $('#ulLimit').append('= 100*1024*1024) ? ' selected' : '') + ' value="' + 100 * 1024 * 1024 + '">' + theUILang.unlimited + ''); + + plugin.showPage('globalSettings'); + }); +}; + +plugin.showSort = function() { + $('#sortOption option').prop('selected', false); + $('#sort_asc').prop('checked', false); + $('#sort_desc').prop('checked', false); + + var sort = ''; + if(plugin.sort[0] === "-") { + sort = plugin.sort.substr(1); + $('#sort_desc').prop('checked', true); + } else { + sort = plugin.sort; + $('#sort_asc').prop('checked', true); + } + + sortHtml = '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + ''; + + if (this.seedingtimeLoaded) { + sortHtml += '' + + '' + } + $('#sortOption').html(sortHtml); + $('#sortOption option[value=' + sort + ']').prop('selected', true); + + plugin.showPage('torrentSort'); +}; + +plugin.setDLLimit = function() { + theWebUI.setDLRate($('#dlLimit').val()); +}; + +plugin.setULLimit = function() { + theWebUI.setULRate($('#ulLimit').val()); +}; + +plugin.setSort = function() { + var sort = $('#sortOption').val(); + if($('#sort_desc').prop('checked')) { + sort = '-' + sort + } + plugin.sort = sort; + plugin.update(true); + history.go(-1); +}; + +plugin.addTorrent = function() { + this.showPage('addTorrent'); + var used = ($('#dir_edit').outerWidth(true) - $('#dir_edit').width()) + $('#showGetDir').outerWidth(true) + 1; + $('#dir_edit').width($('#addTorrentFile').outerWidth(true) - used); +}; + +plugin.fillLabel = function(label) { + if (this.labelInEdit) { + return; + } + + $('#torrentDetails #label td:last').text(label + ' ').append(''); +}; + +plugin.fillDetails = function(d) { + $('#torrentName').text(d.name); + + var percent = d.done / 10.0; + $('#torrentProgress').removeClass('active'); + if (d.done != 1000) { + $('#torrentProgress').addClass('active'); + } + $('#torrentProgress .progress-bar').css('width', percent + '%'); + $('#torrentProgress .progress-bar').text(percent + '% of ' + theConverter.bytes(d.size,2)); + + $('#torrentDetails #status td:last').text(theWebUI.getStatusIcon(d)[1] + ' ').append(''); + $('#torrentPriority option').prop('selected', false); + $('#torrentPriority option[value=' + d.priority + ']').prop('selected', true); + if (this.ratioGroupsLoaded) { + $('#torrentRatioGrp option').prop('selected', false); + if (d.ratiogroup) { + $('#torrentRatioGrp option[value=' + d.ratiogroup.replace('rat_','') + ']').prop('selected', true); + } else { + $('#torrentRatioGrp option[value=-1]').prop('selected', true); + } + } + if (this.throttleLoaded) { + $('#torrentChannel option').prop('selected', false); + if (d.throttle) { + $('#torrentChannel option[value=' + d.throttle.replace('thr_','') + ']').prop('selected', true); + } else { + $('#torrentChannel option[value=-1]').prop('selected', true); + } + } + this.fillLabel(d.label); + $('#torrentDetails #done td:last').text(percent + '%'); + $('#torrentDetails #downloaded td:last').text(theConverter.bytes(d.downloaded,2)); + $('#torrentDetails #size td:last').text(theConverter.bytes(d.size,2)); + $('#torrentDetails #remaining td:last').text(theConverter.bytes(d.remaining,2)); + $('#torrentDetails #timeElapsed td:last').text(theConverter.time(Math.floor((new Date().getTime()-theWebUI.deltaTime)/1000-iv(d.state_changed)),true)); + if (this.seedingtimeLoaded) { + $('#torrentDetails #seedtime td:last').text((d.seedingtime>3600*24*365) ? theConverter.time(new Date().getTime()/1000-(iv(d.seedingtime)+theWebUI.deltaTime/1000),true) : ""); + $('#torrentDetails #dateAdded td:last').text((d.addtime>3600*24*365) ? theConverter.date(iv(d.addtime)+theWebUI.deltaTime/1000) : ""); + } + $('#torrentDetails #eta td:last').html((d.eta ==- 1) ? "∞" : theConverter.time(d.eta)); + $('#torrentDetails #ratio td:last').html((d.ratio ==- 1) ? "∞" : theConverter.round(d.ratio/1000,3)); + $('#torrentDetails #downloadSpeed td:last').text(theConverter.speed(d.dl)); + $('#torrentDetails #wasted td:last').text(theConverter.bytes(d.skip_total,2)); + $('#torrentDetails #uploaded td:last').text(theConverter.bytes(d.uploaded,2)); + $('#torrentDetails #uploadSpeed td:last').text(theConverter.speed(d.ul)); + $('#torrentDetails #seeds td:last').text(d.seeds_actual + " " + theUILang.of + " " + d.seeds_all + " " + theUILang.connected); + $('#torrentDetails #peers td:last').text(d.peers_actual + " " + theUILang.of + " " + d.peers_all + " " + theUILang.connected); + $('#torrentDetails #trackerStatus td:last').text(d.msg); +}; + +plugin.changePriority = function() { + this.request('?action=dsetprio&v=' + $('#torrentPriority').val() + '&hash=' + this.torrent.hash); +}; + +plugin.changeRatioGrp = function() { + this.request('?action=setratio&v=' + $('#torrentRatioGrp').val() + '&hash=' + this.torrent.hash); +}; + +plugin.changeChannel = function() { + this.request('?action=setthrottle&v=' + $('#torrentChannel').val() + '&hash=' + this.torrent.hash); +}; + +plugin.editLabel = function() { + plugin.labelInEdit = true; + $('#torrentDetails #label td:last') + .html('
' + + '' + + '
'); + $('#labelEdit').focus(); + $('#labelEdit').blur(function() { + var newLabel = $('#labelEdit').val(); + plugin.labelInEdit = false; + plugin.fillLabel(newLabel); + + if (plugin.torrent.label != newLabel) { + plugin.torrent.label = newLabel; + plugin.torrents[plugin.torrent.hash].label = newLabel; + + plugin.request('?action=setlabel&hash=' + plugin.torrent.hash + '&s=label&v=' + encodeURIComponent(newLabel)); + }; + }); +}; + +plugin.showDetails = function(e) { + this.torrent = this.torrents[e]; + if (this.torrent == undefined) + return; + + this.torrent.hash = e; + var d = this.torrent; + + this.fillDetails(d); + + this.showPage('torrentDetails'); + setTimeout(function() { + var totalWidth = $('#torrentDetails').width(); + var combinedWidth = $('#detailsDetailsPage #priority td:nth-child(1)').outerWidth(true); + var tdExcess = $('#detailsDetailsPage #priority td:nth-child(2)').outerWidth(true) - $('#detailsDetailsPage #priority td:nth-child(2)').width(); + var diffWidth = totalWidth - combinedWidth - tdExcess; + $('#torrentDetails select').css('max-width',diffWidth); + }, 0); + $('.torrentControl').css('display', ''); + this.showDetailsInDetails(); +}; + +plugin.showDetailsInDetails = function() { + $('.detailsPage').css('display', 'none'); + $('#detailsDetailsPage').css('display', ''); + $('#detailsNav li').removeClass('active'); + $('#detailsDetailsTab').addClass('active'); +}; + +plugin.showTrackersInDetails = function() { + $('.detailsPage').css('display', 'none'); + $('#detailsTrackersPage').css('display', ''); + $('#detailsNav li').removeClass('active'); + $('#detailsTrackers').addClass('active'); + this.loadTrackers(); +} + +plugin.showFilesInDetails = function() { + $('.detailsPage').css('display', 'none'); + $('#detailsFilesPage').css('display', ''); + $('#detailsNav li').removeClass('active'); + $('#detailsFiles').addClass('active'); + this.loadFiles(); +} + +plugin.toogleTrackerInfo = function(s) { + this.toogleDisplay($(s).parent().find('div')); +} + +plugin.loadTrackers = function() { + if (this.torrent != undefined) { + var hash = this.torrent.hash; + this.request('?action=gettrackers&hash=' + hash, function(data) { + var trackers = data[hash]; + if (hash == mobile.torrent.hash) { + var trackersHtml = '
'; + + for (var i = 0; i < trackers.length; i++) { + trackersHtml += + '
' + + '
' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '
' + theUILang.Type + '' + theFormatter.trackerType(trackers[i].type) + '
' + theUILang.Enabled + '' + theFormatter.yesNo(trackers[i].enabled) + '
' + theUILang.Group + '' + trackers[i].group + '
' + theUILang.Seeds + '' + trackers[i].seeds + '
' + theUILang.Peers + '' + trackers[i].peers + '
' + theUILang.scrapeDownloaded + '' + trackers[i].downloaded + '
' + theUILang.scrapeUpdate + '' + + (trackers[i].last ? theConverter.time($.now() / 1000 - trackers[i].last - theWebUI.deltaTime / 1000, true) : '') + + '
' + theUILang.trkInterval + '' + theConverter.time(trackers[i].interval) + '
' + theUILang.trkPrivate + '' + theFormatter.yesNo(theWebUI.trkIsPrivate(trackers[i].name)) + '
'; + } + + trackersHtml += '
'; + $('#detailsTrackersPage').html(trackersHtml); + + if (!plugin.bootstrapJS) { + $('#trackersAccordion a').click(function() { + $('#trackersAccordion .in').removeClass('in'); + $(this).parent().parent().find('.panel-body').addClass('in'); + return false; + }); + } + } + }); + } +}; + +plugin.files = undefined; + +plugin.getDir = function(p) { + var path = p.split('/'); + if ((path[0] == '') && (path.length == 1)) { + path = []; + } + + var dir = plugin.files; + var realPath = ''; + for (var i = 0; i < path.length; i++) { + if (path[i] == '') { + continue; + } + + if (dir.container[path[i]] != undefined) { + dir = dir.container[path[i]]; + realPath += '/' + path[i]; + if (!dir.directory) { + break; + } + } else { + break; + } + } + + realPath = realPath.substr(1); + return [realPath, dir]; +} + +plugin.getFilesList = function(s) { + var ret = ''; + + for (var name in s) { + if (s[name].directory) { + ret += this.getFilesList(s[name].container); + } else { + ret += '&v=' + s[name].id; + } + } + + return ret; +} + +plugin.drawFiles = function(p) { + var vars = this.getDir(p); + var realPath = vars[0]; + var dir = vars[1]; + + var filesHtml = ''; + + if (!dir.root) { + var i = realPath.lastIndexOf('/'); + if (i < 0) { + i = 0; + } + var upperDir = realPath.substr(0, i); + filesHtml += '' + + ' ..
'; + } + + for (var name in dir.container) { + filesHtml += '
' + + '
' + realPath + '/' + name + '
' + + '' + if (dir.container[name].directory) { + filesHtml += '' + + ' ' + name + ''; + } else { + var idName = 'file' + dir.container[name].id; + filesHtml += '' + + ' ' + name + ''; + } + filesHtml += '

'; + + } + + $('#detailsFilesPage').html(filesHtml); + $('#detailsFilesPage select').change(function() { + var newValue = $(this).val(); + if (newValue < 0) { + return; + } + + var vars = plugin.getDir($(this).parent().find('.hiddenPath').text()); + + var filesList = ''; + if (!vars[1].directory) { + filesList = vars[1].id; + } else { + filesList = plugin.getFilesList(vars[1].container); + } + + plugin.request('?action=setprio&hash=' + plugin.torrent.hash + '&v=' +filesList + '&s=' + newValue); + }); +} + +plugin.fillDirectoriesPriority = function(p) { + var priority = -2; + for (var name in p.container) { + if (p.container[name].directory) { + this.fillDirectoriesPriority(p.container[name]); + } + if (priority == -2) { + priority = p.container[name].priority; + } else if (priority != p.container[name].priority) { + priority = -1; + } + } + p.priority = priority; +} + +plugin.loadFiles = function() { + if (this.torrent != undefined) { + var hash = this.torrent.hash; + $('#detailsFilesPage').html(''); + this.request('?action=getfiles&hash=' + hash, function(data) { + var rawFiles = data[hash]; + var files = {root: true, directory: true, priority: -1, container: {}}; + + for (var i = 0; i < rawFiles.length; i++) { + var path = rawFiles[i].name.replace(/^\/|\/$/g, '').split('/'); + var currDir = files; + for (var j = 0; j < path.length -1; j++) { + if (currDir.container[path[j]] == undefined) { + currDir.container[path[j]] = {directory: true, root: false, container: {}, priority: -2}; + } + currDir = currDir.container[path[j]]; + } + currDir.container[path[path.length - 1]] = {root: false, + directory: false, + size: rawFiles[i].size, + done: rawFiles[i].done, + priority: rawFiles[i].priority, + id: i + }; + } + + plugin.fillDirectoriesPriority(files); + mobile.files = files; + mobile.drawFiles(''); + }); + } +} + +plugin.start = function() { + if (this.torrent != undefined) { + var status = this.torrent.state; + + if ((!(status & dStatus.started) || (status & dStatus.paused) && !(status & dStatus.checking) && !(status & dStatus.hashing))) { + this.request('?action=start&hash=' + this.torrent.hash); + } + } +}; + +plugin.stop = function() { + if (this.torrent != undefined) { + var status = this.torrent.state; + + if ((status & dStatus.started) || (status & dStatus.hashing) || (status & dStatus.checking)) { + this.request('?action=stop&hash=' + this.torrent.hash); + } + } +}; + +plugin.pause = function() { + if (this.torrent != undefined) { + var status = this.torrent.state; + + if (((status & dStatus.started) && !(status & dStatus.paused) && !(status & dStatus.checking) && !(status & dStatus.hashing))) { + this.request('?action=pause&hash=' + this.torrent.hash); + } else if (((status & dStatus.paused) && !(status & dStatus.checking) && !(status & dStatus.hashing))) { + this.request('?action=unpause&hash=' + this.torrent.hash); + } + } +}; + +plugin.recheck = function() { + if (this.torrent != undefined) { + var status = this.torrent.state; + + if (!(status & dStatus.checking) && !(status & dStatus.hashing)) { + this.request('?action=recheck&hash=' + this.torrent.hash); + } + } +}; + +plugin.delete = function() { + if (this.torrent == undefined) { + this.showList(); + } else { + + if ((this.eraseWithDataLoaded) && (this.eraseWithDataDefault != undefined)) { + $('#deleteWithData input').prop('checked', this.eraseWithDataDefault); + } + if (theWebUI.settings["webui.confirm_when_deleting"]) { + $('#confimTorrentDelete h5').html('' + theUILang.Rem_torrents_prompt + '
' + this.torrent.name); + this.showPage('confimTorrentDelete'); + } else { + this.deleteConfimed(); + } + } +}; + +plugin.deleteConfimed = function() { + if ((this.eraseWithDataLoaded) && ($('#deleteWithData input').prop('checked'))) { + this.request('?action=removewithdata&hash=' + this.torrent.hash); + } else { + this.request('?action=remove&hash=' + this.torrent.hash); + } + this.torrent = undefined; + this.showList(); +}; + +plugin.chooseGetDir = function(path) { + $('#dir_edit').val(path); + history.go(-1); +} + +plugin.drawGetDir = function(path, first) { + $.ajax({ + url: 'plugins/_getdir/getdirs.php', + data: { + 'btn': '', + 'edit': '', + 'frame_id': '', + 'dir': path, + 'time': ((new Date()).getTime()) + }, + + success: function(data) { + var re = /  ([\s\S]+?)<\/td>/g; + var match = null; + + var html = '' + + while ((match = re.exec(data)) != null) { + if (match[2] == '.') { + html = '
' + decodeURIComponent(match[1]) + '
' + + '' + + '' + + html; + } else { + html += '' + + ''; + } + } + + html += '
' + match[2] + '
'; + $('#getDirList').html(html); + + if (first === true) { + mobile.showPage('getDirList'); + } + } + }); +}; + +plugin.showGetDir = function() { + this.drawGetDir('', true); +}; + +plugin.updateLabelDropdown = function () { + $('#torrentsLabels ul').css('width', ''); + $('#torrentsList .nav > li > ul a').css('white-space',''); + var totalWidth = $('#torrentsList .nav').width(); + var combinedWidth = $('#torrentsStatus').outerWidth(true); + var selfWidth = $('#torrentsLabels ul').width(); + var selfExcess = $('#torrentsLabels ul').outerWidth(true) - selfWidth; + var diffWidth = totalWidth - combinedWidth - selfExcess; + if (diffWidth < selfWidth && selfWidth > 0 && diffWidth > 0) { + $('#torrentsLabels ul').width(diffWidth); + $('#torrentsList .nav > li > ul a').css('white-space','normal'); + } +}; + +plugin.updateTrackerDropdown = function () { + $('#torrentsTrackers ul').css('width', ''); + $('#torrentsList .nav > li > ul a').css('white-space',''); + var combinedWidth = $('#torrentsStatus').outerWidth(true) + $('#torrentsLabels').outerWidth(true) + $('#torrentsTrackers').outerWidth(true); + var selfWidth = $('#torrentsTrackers ul').width(); + var selfExcess = $('#torrentsTrackers ul').outerWidth(true) - selfWidth; + var diffWidth = combinedWidth - selfExcess; + if (diffWidth < selfWidth && selfWidth > 0 && diffWidth > 0) { + $('#torrentsTrackers ul').width(diffWidth); + $('#torrentsList .nav > li > ul a').css('white-space','normal'); + } +}; + +plugin.loadRatio = function () { + var ratio = thePlugins.get("ratio"); + if (ratio.allStuffLoaded) { + $('#priority').after(''); + $('#torrentRatioGrp').change(function(){mobile.changeRatioGrp()}); + var ratioHTML = '' + $.each(theWebUI.ratios, function(i, v) { + ratioHTML += ''; + }); + $('#torrentRatioGrp').html(ratioHTML); + $('#ratiogrp').children('td:first').text(theUILang.ratio); + + rTorrentStub.prototype.setratio = function() + { + for(var i=0; i=0) + { + cmd = new rXMLRPCCommand('view.set_not_visible'); + cmd.addParameter("string",this.hashes[i]); + cmd.addParameter("string","rat_"+wasNo); + this.commands.push( cmd ); + cmd = new rXMLRPCCommand('d.views.remove'); + cmd.addParameter("string",this.hashes[i]); + cmd.addParameter("string","rat_"+wasNo); + this.commands.push( cmd ); + } + if(this.vs[i]>=0) + { + cmd = new rXMLRPCCommand('d.views.push_back_unique'); + cmd.addParameter("string",this.hashes[i]); + cmd.addParameter("string","rat_"+this.vs[i]); + this.commands.push( cmd ); + cmd = new rXMLRPCCommand('view.set_visible'); + cmd.addParameter("string",this.hashes[i]); + cmd.addParameter("string","rat_"+this.vs[i]); + this.commands.push( cmd ); + } + } + } + } + } else { + setTimeout(function(){plugin.loadRatio()}, 1000); + } +}; + +plugin.loadThrottle = function () { + var throttle = thePlugins.get("throttle"); + if (throttle.allStuffLoaded) { + $('#priority').after(''); + $('#torrentChannel').change(function(){mobile.changeChannel()}); + var throttleHTML = ''; + $.each(theWebUI.throttles, function(i, v) { + throttleHTML += ''; + }); + $('#torrentChannel').html(throttleHTML); + $('#throttle').children('td:first').text(theUILang.throttle); + + rTorrentStub.prototype.setthrottle = function() + { + for(var i=0; i=0) ? "thr_"+this.vs[i] : ""; + if(needRestart) + { + cmd = new rXMLRPCCommand('d.stop'); + cmd.addParameter("string",this.hashes[i]); + this.commands.push( cmd ); + } + cmd = new rXMLRPCCommand('d.set_throttle_name'); + cmd.addParameter("string",this.hashes[i]); + cmd.addParameter("string",name); + this.commands.push( cmd ); + if(needRestart) + { + cmd = new rXMLRPCCommand('d.start'); + cmd.addParameter("string",this.hashes[i]); + this.commands.push( cmd ); + } + } + } + } else { + setTimeout(function(){plugin.loadThrottle()}, 1000); + } +}; + +plugin.loadSeedingTime = function () { + var seedingtime = thePlugins.get("seedingtime"); + if (seedingtime.allStuffLoaded) { + $('#timeElapsed').after(''); + $('#timeElapsed').after(''); + $('#dateAdded').children('td:first').text(theUILang.Added); + $('#seedtime').children('td:first').text(theUILang.seedingTime); + } else { + setTimeout(function(){plugin.loadSeedingTime()}, 1000); + } +}; + +plugin.dynamicSort = function (property) { + var sortOrder = 1; + if(property[0] === "-") { + sortOrder = -1; + property = property.substr(1); + } + return function (a,b) { + if (typeof a[property] == 'string' || a[property] instanceof String) { + if (parseInt(a[property])) { + if (parseInt(b[property])) { + var result = (parseInt(a[property]) < parseInt(b[property])) ? -1 : (parseInt(a[property]) > parseInt(b[property])) ? 1 : 0; + } else { + var result = -1; + } + } else if (parseInt(b[property])) { + var result = 1; + } else { + var result = (a[property].toLowerCase() < b[property].toLowerCase()) ? -1 : (a[property].toLowerCase() > b[property].toLowerCase()) ? 1 : 0; + } + } else { + var result = (a[property] < b[property]) ? -1 : (a[property] > b[property]) ? 1 : 0; + } + return result * sortOrder; + } +} + +plugin.update = function(singleUpdate) { + theWebUI.requestWithTimeout("?list=1&getmsg=1", + function(data) { + plugin.torrents = data.torrents; + plugin.labels = data.labels; + plugin.labelIds = {}; + plugin.trackerIds = {}; + plugin.labelIds[''] = 0; + var torrentArray = []; + var trackersCount = {}; + var trackersMap = {}; + var count = Object.keys(plugin.torrents).length; + var tul = 0; + var tdl = 0; + var nextLabelId = 1; + var nextTrackerId = 1; + var labelsHtml = '
  • ' + theUILang.No_label + '
  • '; + var trackersHtml = ''; + + Object.keys(plugin.labels).sort().forEach(function(l) { + if (plugin.labelIds[l] == undefined) { + plugin.labelIds[l] = nextLabelId++; + } + + labelsHtml += '
  • ' + l + ' (' + plugin.labels[l] + ')
  • '; + }); + $('#torrentsLabels ul').html(labelsHtml); + if ($('#torrentsLabels ul').is(':visible')) { + plugin.updateLabelDropdown(); + } + + var listHtml = ''; + + $.each(plugin.torrents, function(n, v){ + v.hash = n; + torrentArray.push(v); + }); + torrentArray.sort(plugin.dynamicSort(plugin.sort)); + + $.each(torrentArray, function(n, v){ + var status = theWebUI.getStatusIcon(v); + var statusClass = (v.done == 1000) ? 'Completed' : 'Downloading'; + var stateClass = (v.ul || v.dl) ? 'Active' : 'Inactive'; + var errorClass = (v.state & dStatus.error) ? 'Yes' : 'No'; + var percent = v.done / 10; + + tul += iv(v.ul); + tdl += iv(v.dl); + + listHtml += + ''; + + mobile.request('?action=gettrackers&hash=' + v.hash, function(data) { + var trackers = data[v.hash]; + var uniqueTrackers = []; + for (var i = 0; i < trackers.length; i++) { + var trackerName = theWebUI.getTrackerName(trackers[i].name); + if (trackerName) { + if (trackerName in trackersCount) { + if ($.inArray(trackerName, uniqueTrackers) == -1) { + trackersCount[trackerName]++; + } + } else { + trackersCount[trackerName] = 1; + } + if (plugin.trackerIds[trackerName] == undefined) { + plugin.trackerIds[trackerName] = nextTrackerId++; + } + if ($.inArray(trackerName, uniqueTrackers) == -1) { + uniqueTrackers.push(trackerName); + } + } + } + trackersMap[v.hash] = uniqueTrackers; + count--; + if(count == 0) { + Object.keys(trackersCount).sort().forEach(function(t) { + trackersHtml += '
  • ' + t + ' (' + trackersCount[t] + ')
  • '; + }); + $('#torrentsTrackers ul').html(trackersHtml); + if ($('#torrentsTrackers ul').is(':visible')) { + plugin.updateTrackerDropdown(); + } + + listHtml += '
    ' + + '
    ' + v.name + '
    ' + status[1] + ((v.ul) ? ' ↑' + theConverter.speed(v.ul) : '') + ((v.dl) ? ' ↓' + theConverter.speed(v.dl) : '') + + '
    ' + + '
    ' + percent + '% of ' + theConverter.bytes(v.size,2) + '
    ' + + '
    ' + + '
    '; + $('#torrentsList #list').html(listHtml); + + $.each(trackersMap, function(id, ns) { + $.each(ns, function(i, n) { + $('#'+id).addClass("tracker"+plugin.trackerIds[n]); + }); + }); + $('#torrentsAll > a').text(theUILang.All + ' (' + $('.torrentBlock').length + ')'); + $('#torrentsDownloading > a').text(theUILang.Downloading + ' (' + $('.statusDownloading').length + ')'); + $('#torrentsCompleted > a').text(theUILang.Finished + ' (' + $('.statusCompleted').length + ')'); + $('#torrentsActive > a').text(theUILang.Active + ' (' + $('.stateActive').length + ')'); + $('#torrentsInactive > a').text(theUILang.Inactive + ' (' + $('.stateInactive').length + ')'); + $('#torrentsError > a').text(theUILang.Error + ' (' + $('.errorYes').length + ')'); + + plugin.filter(plugin.currFilter, undefined, plugin.navFilter); + + if (plugin.torrent != undefined) { + if (plugin.torrents[plugin.torrent.hash] != undefined) { + plugin.torrent = plugin.torrents[plugin.torrent.hash]; + plugin.fillDetails(plugin.torrent); + } else { + plugin.showList(); + } + } + + $('#upspeed').text(theConverter.speed(tul)); + $('#downspeed').text(theConverter.speed(tdl)); + + if (!singleUpdate) { + setTimeout(function() {mobile.update();}, theWebUI.settings['webui.update_interval']); + } + } + }); + }); + }, + + function() + { + //TODO: Timeout + }, + + function(status,text) + { + //TODO: Error + } +); +}; + +plugin.init = function() { +var start = (window.location.href.indexOf('mobile=1') > 0); + +if ((!start) && this.enableAutodetect) { + start = jQuery.browser.mobile; +} + +if (start) { +dxSTable.prototype.renameColumn = function(no,name) {} + +dxSTable.prototype.Sort = function(e) {} + +dxSTable.prototype.createRow = function(cols, sId, icon, attr) +{ + if(!$type(attr)) + attr = []; + var tr = $("").attr( { index: this.rows, title: cols[0] }); + if(sId != null) + tr.attr("id",sId); + var self = this; + if(this.colorEvenRows) + tr.addClass( (this.rows & 1) ? "odd" : "even" ); + + tr.mouseclick( function(e) { return(self.selectRow(e, this)); }); + + if($type(this.ondblclick) == "function") + tr.dblclick( function(e) { return(self.ondblclick(this)); }); + + for(var k in attr) + tr.attr(k, attr[k]); + var data = this.rowdata[sId].fmtdata; + var s = ""; + var div; + var ret; + for(var i = 0; i < this.cols; i++) + { + var ind = this.colOrder[i]; + s+=""; + div = "
     
    "; + } + else + div = "
    "+((String(data[ind]) == "") ? " " : escapeHTML(data[ind]))+"
    "; + if((ind == 0) && (icon != null)) + span2 = ""; + if(!this.colsdata[i].enabled && !browser.isIE7x) + s+=" style='display: none'"; + s+=">"; + s+=span1; + s+=span2; + s+=div; + s+=""; + } + ret = tr.append(s).get(0); + //if(!browser.isIE7x) + //{ + // var _e = this.tBody.getElementsByTagName("colgroup")[0].getElementsByTagName("col"); + // for(var i = 0, l = _e.length; i < l; i++) + // ret.cells[i].style.textAlign = this.tHeadCols[i].style.textAlign; + //} + return(ret); +} + + $.each(thePlugins.list, function(i, v) { + if (v.name != 'rpc' && v.name != 'httprpc' && v.name != '_getdir' && v.name != 'throttle' && v.name != 'ratio' && v.name != 'erasedata' && v.name != 'seedingtime' && v.name != 'mobile') { + v.disable(); + } + }); + + this.lastHref = window.location.href; + + setInterval(function() {plugin.backListener();}, 500); + + var jQueryVer = jQuery.fn.jquery.split('.'); + if ((jQueryVer[0] == 1) && (jQueryVer[1] >= 7)) { + this.bootstrapJS = true; + } else if (jQueryVer[0] > 1) { + this.bootstrapJS = true; //For future =) + } + + $.ajax({ + type: 'GET', + url: this.path + 'mobile.html', + processData: false, + + error: function(XMLHttpRequest, textStatus, errorThrown) { + //TODO: Error + }, + + success: function(data, textStatus) { + $('body').html(data); + + $('link[rel=stylesheet]').remove(); + plugin.loadLang(); + plugin.loadCSS('css/bootstrap.min'); + plugin.loadMainCSS(); + $('head').append(''); + if (plugin.bootstrapJS) + injectScript(plugin.path+'js/bootstrap.min.js'); + + if (!plugin.bootstrapJS) { + $('#torrentsStatus > a').click(function(){ + var menu = $('#torrentsStatus'); + + if (menu.hasClass('open')) { + menu.removeClass('open'); + } else { + menu.addClass('open'); + } + }); + $('#torrentsStatus > ul').click(function() { + $('#torrentsStatus').removeClass('open'); + }); + + $('#torrentsLabels > a').click(function(){ + var menu = $('#torrentsLabels'); + + if (menu.hasClass('open')) { + menu.removeClass('open'); + } else { + menu.addClass('open'); + } + }); + $('#torrentsLabels > ul').click(function() { + $('#torrentsLabels').removeClass('open'); + }); + + $('#torrentsTrackers > a').click(function(){ + var menu = $('#torrentsTrackers'); + + if (menu.hasClass('open')) { + menu.removeClass('open'); + } else { + menu.addClass('open'); + } + }); + $('#torrentsTrackers > ul').click(function() { + $('#torrentsTrackers').removeClass('open'); + }); + } + + $('#torrentsLabels > a').click(function(){ + plugin.updateLabelDropdown(); + }); + + $('#torrentsTrackers > a').click(function(){ + plugin.updateTrackerDropdown(); + }); + + $('#mainNavbar').addClass('navbar-fixed-bottom'); + $('.nav-tabs').addClass('navbar-fixed-top'); + + $('.torrentControl').css('display', 'none'); + + $('#dlLimit').change(function(){plugin.setDLLimit();}); + $('#ulLimit').change(function(){plugin.setULLimit();}); + + $('input[id=torrent_file]').change(function() { + $('#torrentFileName').val($(this).val()); + }); + + $('#notAddPath').append(' ' + theUILang.Dont_add_tname); + $('#startStopped').append(' ' + theUILang.Dnt_start_down_auto); + $('#fastResume').append(' ' + theUILang.doFastResume); + $('#torrentFileSend').text(theUILang.add_button); + + $('#torrentPriority').html( + '' + + '' + + '' + + '' + ); + $('#torrentPriority').change(function(){mobile.changePriority()}); + + var makeAddRequest = function(frm) + { + var s = theURLs.AddTorrentURL+"?"; + if($("#torrents_start_stopped").prop("checked")) { + s += 'torrents_start_stopped=1&'; + } + if($("#fast_resume").prop("checked")) { + s += 'fast_resume=1&'; + } + if($("#not_add_path").prop("checked")) { + s += 'not_add_path=1&'; + } + var dir = $.trim($("#dir_edit").val()); + if(dir.length) { + s += ('dir_edit='+encodeURIComponent(dir)+'&'); + } + var lbl = $.trim($("#tadd_label").val()); + if(lbl.length) { + s += ('label='+encodeURIComponent(lbl)); + } + frm.action = s; + return(true); + } + $("#addTorrentFile").submit(function() + { + if(!$("#torrent_file").val().match(".torrent")) { + plugin.showAlert(theUILang.Not_torrent_file,"alert-danger"); + return(false); + } + plugin.createiFrame(); + return(makeAddRequest(this)); + }); + $("#addTorrentUrl").submit(function() { + plugin.createiFrame(); + return(makeAddRequest(this)); + }); + + if (thePlugins.isInstalled('erasedata')) { + $('#confimTorrentDelete h5').after( + '
    ' + + ' ' + theUILang.Delete_data + '
    '); + + plugin.eraseWithDataLoaded = true; + } + + if (thePlugins.isInstalled('throttle')) { + plugin.throttleLoaded = true; + plugin.loadThrottle(); + } + + if (thePlugins.isInstalled('ratio')) { + plugin.ratioGroupsLoaded = true; + plugin.loadRatio(); + } + + if (thePlugins.isInstalled('_getdir')) { + plugin.getDirLoaded = true; + $('#dirEditBlock').append(''); + } + + if (thePlugins.isInstalled('seedingtime')) { + plugin.seedingtimeLoaded = true; + plugin.loadSeedingTime(); + } + plugin.update(); + } + }); + } else { + this.disable(); + } +}; + +plugin.onLangLoaded = function() { + $('#torrentsStatus > a > span').html(theUILang.All); + $('#torrentsLabels > a > span').html(theUILang.Labels); + $('#torrentsTrackers > a > span').html(theUILang.Trackers); + + $('#detailsDetailsTab a').text(theUILang.General); + $('#detailsTrackers a').text(theUILang.Trackers); + $('#detailsFiles a').text(theUILang.Files); + + $('#torrentDetails table tr').each(function(n, v) { + $(v).children('td:first').text(theUILang[detailsIdToLangId[v.id]]); + }); + + $('#dlLimit').parent().children('label').children('h5').text(theUILang.Glob_max_downl); + $('#ulLimit').parent().children('label').children('h5').text(theUILang.Global_max_upl); + $('#speedLimitsOk').text(theUILang.ok); + $('#speedLimitsCancel').text(theUILang.Cancel); + + $('#torrentFile').text(theUILang.Torrent_file+':'); + $('#addUrl').text(theUILang.add_url); + + $('#deleteOk').text(theUILang.ok); + $('#deleteCancel').text(theUILang.Cancel); + + $('#sortAsc').append(' ' + theUILang.acs); + $('#sortDesc').append(' ' + theUILang.decs); + $('#sortOption').parent().children('label').children('h5').text(theUILang.SortTorrents); + $('#sortOk').text(theUILang.ok); + $('#sortCancel').text(theUILang.Cancel); +}; + +/** +* jQuery.browser.mobile (http://detectmobilebrowser.com/) +* +* jQuery.browser.mobile will be true if the browser is a mobile device +* +**/ +(function(a){(jQuery.browser=jQuery.browser||{}).mobile=/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4))})(navigator.userAgent||navigator.vendor||window.opera); +if ((plugin.tabletsDetect) && (!jQuery.browser.mobile)) { + (function(a){(jQuery.browser=jQuery.browser||{}).mobile=/android|ipad|playbook|silk/i.test(a)})(navigator.userAgent||navigator.vendor||window.opera); +} + +mobile = plugin; +plugin.init(); diff --git a/sources/rtorrent/rtorrent.rc b/sources/rtorrent/rtorrent.rc new file mode 100644 index 0000000..b97ab6b --- /dev/null +++ b/sources/rtorrent/rtorrent.rc @@ -0,0 +1,20 @@ +scgi_port = 127.0.0.1:5000 +encoding_list = UTF-8 +port_range = 45069-45069 +port_random = no +check_hash = no +directory = DATA_DIR/downloads +session = DATA_DIR/.session +encryption = allow_incoming, try_outgoing, enable_retry +schedule = watch_directory,1,1,"load_start=DATA_DIR/watch/*.torrent" +schedule = untied_directory,5,5,"stop_untied=DATA_DIR/watch/*.torrent" +use_udp_trackers = yes +dht = off +peer_exchange = no +min_peers = 40 +max_peers = 100 +min_peers_seed = 10 +max_peers_seed = 50 +max_uploads = 15 +execute = {sh,-c,/usr/bin/php /var/www/rutorrent/php/initplugins.php &} +schedule = espace_disque_insuffisant,1,30,close_low_diskspace=500M diff --git a/sources/rutorrent/config.php b/sources/rutorrent/config.php new file mode 100755 index 0000000..8829f14 --- /dev/null +++ b/sources/rutorrent/config.php @@ -0,0 +1,64 @@ +rtorrent link through unix domain socket + // (scgi_local in rtorrent conf file), change variables + // above to something like this: + // + // $scgi_port = 0; + // $scgi_host = "unix:///tmp/rpc.socket"; + + $XMLRPCMountPoint = "/RPC2"; // DO NOT DELETE THIS LINE!!! DO NOT COMMENT THIS LINE!!! + + $pathToExternals = array( + "php" => '', // Something like /usr/bin/php. If empty, will be found in PATH. + "curl" => '/usr/bin/curl', // Something like /usr/bin/curl. If empty, will be found in PATH. + "gzip" => '', // Something like /usr/bin/gzip. If empty, will be found in PATH. + "id" => '', // Something like /usr/bin/id. If empty, will be found in PATH. + "stat" => '', // Something like /usr/bin/stat. If empty, will be found in PATH. + ); + + $localhosts = array( // list of local interfaces + "127.0.0.1", + "localhost", + ); + + $profilePath = '../share'; // Path to user profiles + $profileMask = 0777; // Mask for files and directory creation in user profiles. + // Both Webserver and rtorrent users must have read-write access to it. + // For example, if Webserver and rtorrent users are in the same group then the value may be 0770. + + $tempDirectory = null; // Temp directory. Absolute path with trail slash. If null, then autodetect will be used. + + $canUseXSendFile = true; // Use X-Sendfile feature if it exist + + $locale = "UTF8";