Moved to HarpJS with Jade, Sass and CoffeeScript
This commit is contained in:
parent
b3783752ae
commit
7b8e4c62ea
16 changed files with 617 additions and 346 deletions
179
app.coffee
Normal file
179
app.coffee
Normal file
|
@ -0,0 +1,179 @@
|
||||||
|
client = new WebTorrent
|
||||||
|
debug = true
|
||||||
|
|
||||||
|
|
||||||
|
app = angular.module 'bTorrent', [], ['$compileProvider','$locationProvider', ($compileProvider, $locationProvider) ->
|
||||||
|
$compileProvider.aHrefSanitizationWhitelist /^\s*(https?|magnet|blob|javascript):/
|
||||||
|
$locationProvider.html5Mode(
|
||||||
|
enabled: true
|
||||||
|
requireBase: false).hashPrefix '#'
|
||||||
|
return
|
||||||
|
]
|
||||||
|
|
||||||
|
app.controller 'bTorrentCtrl', ['$scope','$http','$log','$location', ($scope, $http, $log, $location) ->
|
||||||
|
$scope.client = client
|
||||||
|
$scope.seedIt = true
|
||||||
|
|
||||||
|
dbg = (string, torrent) ->
|
||||||
|
if debug
|
||||||
|
if torrent
|
||||||
|
$log.debug '%c' + torrent.name + ' (' + torrent.infoHash + '): %c' + string, 'color: #33C3F0', 'color: #333'
|
||||||
|
else
|
||||||
|
$log.debug '%cClient: %c' + string, 'color: #33C3F0', 'color: #333'
|
||||||
|
return
|
||||||
|
|
||||||
|
updateAll = ->
|
||||||
|
$scope.$apply()
|
||||||
|
return
|
||||||
|
|
||||||
|
setInterval updateAll, 500
|
||||||
|
|
||||||
|
$scope.client.done = ->
|
||||||
|
done = true
|
||||||
|
$scope.client.torrents.forEach (torrent) ->
|
||||||
|
if !torrent.done
|
||||||
|
done = false
|
||||||
|
return
|
||||||
|
done
|
||||||
|
|
||||||
|
$scope.client.downloading = ->
|
||||||
|
downloading = true
|
||||||
|
$scope.client.torrents.forEach (torrent) ->
|
||||||
|
if torrent.done
|
||||||
|
downloading = false
|
||||||
|
return
|
||||||
|
downloading
|
||||||
|
|
||||||
|
$scope.uploadFile = ->
|
||||||
|
document.getElementById('fileUpload').click()
|
||||||
|
return
|
||||||
|
|
||||||
|
$scope.uploadFile2 = (elem) ->
|
||||||
|
$scope.client.processing = true
|
||||||
|
dbg 'Seeding ' + elem.files[0].name
|
||||||
|
$scope.client.seed elem.files, $scope.onSeed
|
||||||
|
return
|
||||||
|
|
||||||
|
$scope.fromInput = ->
|
||||||
|
if !$scope.torrentInput == ''
|
||||||
|
$scope.client.processing = true
|
||||||
|
dbg 'Adding ' + $scope.torrentInput
|
||||||
|
$scope.client.add $scope.torrentInput, $scope.onTorrent
|
||||||
|
$scope.torrentInput = ''
|
||||||
|
return
|
||||||
|
|
||||||
|
$scope.toggleTorrent = (torrent) ->
|
||||||
|
if torrent.showFiles
|
||||||
|
torrent.showFiles = false
|
||||||
|
$scope.sTorrent = null
|
||||||
|
else
|
||||||
|
$scope.client.torrents.forEach (t) ->
|
||||||
|
t.showFiles = false
|
||||||
|
return
|
||||||
|
torrent.showFiles = true
|
||||||
|
$scope.sTorrent = torrent
|
||||||
|
return
|
||||||
|
|
||||||
|
$scope.destroyedTorrent = (err) ->
|
||||||
|
if err
|
||||||
|
throw err
|
||||||
|
dbg 'Destroyed torrent'
|
||||||
|
return
|
||||||
|
|
||||||
|
$scope.onTorrent = (torrent, isSeed) ->
|
||||||
|
$scope.client.processing = false
|
||||||
|
torrent.showFiles = false
|
||||||
|
torrent.fileName = torrent.name + '.torrent'
|
||||||
|
torrent.oTorrentFileURL = torrent.torrentFileURL
|
||||||
|
if angular.isUndefined($scope.sTorrent) or $scope.sTorrent == null
|
||||||
|
$scope.sTorrent = torrent
|
||||||
|
torrent.showFiles = true
|
||||||
|
|
||||||
|
torrent.update = ->
|
||||||
|
torrent.pProgress = (100 * torrent.progress).toFixed(1)
|
||||||
|
torrent.pDownloaded = torrent.downloaded
|
||||||
|
torrent.pUploaded = torrent.uploaded
|
||||||
|
torrent.pUploadSpeed = torrent.uploadSpeed()
|
||||||
|
torrent.pDownloadSpeed = torrent.downloadSpeed()
|
||||||
|
if torrent.done
|
||||||
|
torrent.tRemaining = 'Done'
|
||||||
|
else
|
||||||
|
remaining = moment.duration(torrent.timeRemaining / 1000, 'seconds').humanize()
|
||||||
|
torrent.tRemaining = remaining[0].toUpperCase() + remaining.substr(1)
|
||||||
|
return
|
||||||
|
|
||||||
|
torrent.files.forEach (file) ->
|
||||||
|
file.pSize = file.length
|
||||||
|
file.status = 'Downloading'
|
||||||
|
file.url = 'javascript: return false;'
|
||||||
|
file.getBlobURL (err, url) ->
|
||||||
|
if err
|
||||||
|
throw err
|
||||||
|
file.url = url
|
||||||
|
if !isSeed
|
||||||
|
dbg 'Finished downloading file ' + file.name, torrent
|
||||||
|
file.status = 'Ready'
|
||||||
|
$scope.$apply()
|
||||||
|
return
|
||||||
|
if !isSeed
|
||||||
|
dbg 'Received file ' + file.name + ' metadata', torrent
|
||||||
|
return
|
||||||
|
torrent.on 'download', (chunkSize) ->
|
||||||
|
if !isSeed
|
||||||
|
dbg 'Downloaded chunk', torrent
|
||||||
|
return
|
||||||
|
torrent.on 'upload', (chunkSize) ->
|
||||||
|
dbg 'Uploaded chunk', torrent
|
||||||
|
return
|
||||||
|
torrent.on 'done', ->
|
||||||
|
if !isSeed
|
||||||
|
dbg 'Done', torrent
|
||||||
|
torrent.update()
|
||||||
|
return
|
||||||
|
torrent.on 'wire', (wire, addr) ->
|
||||||
|
dbg 'Wire ' + addr, torrent
|
||||||
|
return
|
||||||
|
setInterval torrent.update, 500
|
||||||
|
torrent.update()
|
||||||
|
return
|
||||||
|
|
||||||
|
$scope.onSeed = (torrent) ->
|
||||||
|
$scope.onTorrent torrent, true
|
||||||
|
return
|
||||||
|
|
||||||
|
if $location.hash() != ''
|
||||||
|
$scope.client.processing = true
|
||||||
|
dbg 'Adding ' + $location.hash()
|
||||||
|
client.add $location.hash(), $scope.onTorrent
|
||||||
|
return
|
||||||
|
]
|
||||||
|
|
||||||
|
app.filter 'html', ['$sce', ($sce) ->
|
||||||
|
(input) ->
|
||||||
|
$sce.trustAsHtml input
|
||||||
|
]
|
||||||
|
|
||||||
|
app.filter 'pbytes', ->
|
||||||
|
(num) ->
|
||||||
|
exponent = undefined
|
||||||
|
unit = undefined
|
||||||
|
neg = num < 0
|
||||||
|
units = [
|
||||||
|
'B'
|
||||||
|
'kB'
|
||||||
|
'MB'
|
||||||
|
'GB'
|
||||||
|
'TB'
|
||||||
|
'PB'
|
||||||
|
'EB'
|
||||||
|
'ZB'
|
||||||
|
'YB'
|
||||||
|
]
|
||||||
|
if neg
|
||||||
|
num = -num
|
||||||
|
if num < 1
|
||||||
|
return (if neg then '-' else '') + num + ' B'
|
||||||
|
exponent = Math.min(Math.floor(Math.log(num) / Math.log(1000)), units.length - 1)
|
||||||
|
num = (num / 1000 ** exponent).toFixed(1) * 1
|
||||||
|
unit = units[exponent]
|
||||||
|
(if neg then '-' else '') + num + ' ' + unit
|
192
app.js
192
app.js
|
@ -1,192 +0,0 @@
|
||||||
var client = new WebTorrent({
|
|
||||||
rtcConfig: {
|
|
||||||
"iceServers": [{
|
|
||||||
"url": "stun:23.21.150.121",
|
|
||||||
"urls": "stun:23.21.150.121"
|
|
||||||
}, {
|
|
||||||
"url": "turn:global.turn.twilio.com:3478?transport=udp",
|
|
||||||
"username": "00bb844e6c2a07d4ed3e22a6edd6da6a715714a7c3eb118dc20246e5e0cc50c1",
|
|
||||||
"credential": "Wv1IxOBVhm4CGqoWYQWQ0X4Ia0Va7p2SOENv/S7M9Vg=",
|
|
||||||
"urls": "turn:global.turn.twilio.com:3478?transport=udp"
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
});
|
|
||||||
var debug = true;
|
|
||||||
|
|
||||||
var prettyBytes = function (num) {
|
|
||||||
var exponent;
|
|
||||||
var unit;
|
|
||||||
var neg = num < 0;
|
|
||||||
var units = ['B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
|
|
||||||
|
|
||||||
if (neg) {
|
|
||||||
num = -num;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (num < 1) {
|
|
||||||
return (neg ? '-' : '') + num + ' B';
|
|
||||||
}
|
|
||||||
|
|
||||||
exponent = Math.min(Math.floor(Math.log(num) / Math.log(1000)), units.length - 1);
|
|
||||||
num = (num / Math.pow(1000, exponent)).toFixed(1) * 1;
|
|
||||||
unit = units[exponent];
|
|
||||||
|
|
||||||
return (neg ? '-' : '') + num + ' ' + unit;
|
|
||||||
};
|
|
||||||
|
|
||||||
angular.module('bTorrent', [], function ($compileProvider, $locationProvider) {
|
|
||||||
$compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|magnet|blob|javascript):/);
|
|
||||||
$locationProvider.html5Mode({
|
|
||||||
enabled: true,
|
|
||||||
requireBase: false
|
|
||||||
}).hashPrefix('#');
|
|
||||||
}).controller('bTorrentCtrl', function ($scope, $http, $log, $location) {
|
|
||||||
$scope.client = client;
|
|
||||||
$scope.seedIt = true;
|
|
||||||
|
|
||||||
var dbg = function (string, torrent) {
|
|
||||||
if (debug) {
|
|
||||||
if (torrent)
|
|
||||||
$log.debug("%c" + torrent.name + " (" + torrent.infoHash + "): %c" + string, 'color: #33C3F0', 'color: #333');
|
|
||||||
else
|
|
||||||
$log.debug("%cClient: %c" + string, 'color: #33C3F0', 'color: #333');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var updateAll = function () {
|
|
||||||
$scope.$apply();
|
|
||||||
};
|
|
||||||
|
|
||||||
setInterval(updateAll, 500);
|
|
||||||
|
|
||||||
$scope.client.done = function () {
|
|
||||||
var done = true;
|
|
||||||
$scope.client.torrents.forEach(function (torrent) {
|
|
||||||
if (!torrent.done) {
|
|
||||||
done = false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return done;
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.client.downloading = function () {
|
|
||||||
var downloading = true;
|
|
||||||
$scope.client.torrents.forEach(function (torrent) {
|
|
||||||
if (torrent.done) {
|
|
||||||
downloading = false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return downloading;
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.uploadFile = function () {
|
|
||||||
document.getElementById("fileUpload").click();
|
|
||||||
};
|
|
||||||
$scope.uploadFile2 = function (elem) {
|
|
||||||
$scope.client.processing = true;
|
|
||||||
dbg("Seeding " + elem.files[0].name);
|
|
||||||
$scope.client.seed(elem.files, $scope.onSeed);
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.fromInput = function () {
|
|
||||||
if (!$scope.torrentInput == "") {
|
|
||||||
$scope.client.processing = true;
|
|
||||||
dbg("Adding " + $scope.torrentInput);
|
|
||||||
$scope.client.add($scope.torrentInput, $scope.onTorrent);
|
|
||||||
$scope.torrentInput = "";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.toggleTorrent = function (torrent) {
|
|
||||||
if (torrent.showFiles) {
|
|
||||||
torrent.showFiles = false;
|
|
||||||
$scope.sTorrent = null;
|
|
||||||
} else {
|
|
||||||
$scope.client.torrents.forEach(function (t) {
|
|
||||||
t.showFiles = false;
|
|
||||||
});
|
|
||||||
torrent.showFiles = true;
|
|
||||||
$scope.sTorrent = torrent;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.destroyedTorrent = function (err) {
|
|
||||||
if (err) throw err;
|
|
||||||
dbg("Destroyed torrent");
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.onTorrent = function (torrent, isSeed) {
|
|
||||||
$scope.client.processing = false;
|
|
||||||
torrent.showFiles = false;
|
|
||||||
torrent.pSize = prettyBytes(torrent.length);
|
|
||||||
torrent.fileName = torrent.name + '.torrent';
|
|
||||||
torrent.oTorrentFileURL = torrent.torrentFileURL;
|
|
||||||
|
|
||||||
if (angular.isUndefined($scope.sTorrent) || $scope.sTorrent === null) {
|
|
||||||
$scope.sTorrent = torrent;
|
|
||||||
torrent.showFiles = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
torrent.update = function () {
|
|
||||||
torrent.pProgress = (100 * torrent.progress).toFixed(1);
|
|
||||||
torrent.pDownloaded = prettyBytes(torrent.downloaded);
|
|
||||||
torrent.pUploaded = prettyBytes(torrent.uploaded);
|
|
||||||
torrent.pUploadSpeed = prettyBytes(torrent.uploadSpeed());
|
|
||||||
torrent.pDownloadSpeed = prettyBytes(torrent.downloadSpeed());
|
|
||||||
if (torrent.done) {
|
|
||||||
torrent.tRemaining = 'Done'
|
|
||||||
} else {
|
|
||||||
var remaining = moment.duration(torrent.timeRemaining / 1000, 'seconds').humanize();
|
|
||||||
torrent.tRemaining = remaining[0].toUpperCase() + remaining.substr(1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
torrent.files.forEach(function (file) {
|
|
||||||
file.pSize = prettyBytes(file.length);
|
|
||||||
file.status = "Downloading";
|
|
||||||
file.url = 'javascript: return false;';
|
|
||||||
file.getBlobURL(function (err, url) {
|
|
||||||
if (err) throw err;
|
|
||||||
file.url = url;
|
|
||||||
if(!isSeed) dbg("Finished downloading file " + file.name, torrent);
|
|
||||||
file.status = "Ready";
|
|
||||||
$scope.$apply();
|
|
||||||
});
|
|
||||||
if(!isSeed) dbg("Received file " + file.name + " metadata", torrent);
|
|
||||||
});
|
|
||||||
|
|
||||||
torrent.on('download', function (chunkSize) {
|
|
||||||
if(!isSeed) dbg("Downloaded chunk", torrent);
|
|
||||||
});
|
|
||||||
|
|
||||||
torrent.on('upload', function (chunkSize) {
|
|
||||||
dbg("Uploaded chunk", torrent);
|
|
||||||
});
|
|
||||||
|
|
||||||
torrent.on('done', function () {
|
|
||||||
if(!isSeed) dbg("Done", torrent);
|
|
||||||
torrent.update();
|
|
||||||
});
|
|
||||||
|
|
||||||
torrent.on('wire', function (wire, addr) {
|
|
||||||
dbg("Wire " + addr, torrent);
|
|
||||||
});
|
|
||||||
|
|
||||||
setInterval(torrent.update, 500);
|
|
||||||
torrent.update();
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.onSeed = function(torrent) {
|
|
||||||
$scope.onTorrent(torrent, true);
|
|
||||||
};
|
|
||||||
|
|
||||||
if ($location.hash() != '') {
|
|
||||||
$scope.client.processing = true;
|
|
||||||
dbg("Adding " + $location.hash());
|
|
||||||
client.add($location.hash(), $scope.onTorrent);
|
|
||||||
}
|
|
||||||
}).filter('html', function ($sce) {
|
|
||||||
return function (input) {
|
|
||||||
return $sce.trustAsHtml(input);
|
|
||||||
}
|
|
||||||
});
|
|
99
index.html
99
index.html
|
@ -1,99 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html ng-app="bTorrent" lang="en">
|
|
||||||
<head>
|
|
||||||
<base href="">
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<title>βTorrent: Browser WebTorrent Client</title>
|
|
||||||
|
|
||||||
<meta name="description" content="βTorrent: Browser WebTorrent Client">
|
|
||||||
<meta name="keywords" content="βTorrent, btorrent, client, webtorrent, browser, torrent">
|
|
||||||
<meta name="author" content="Diego Rodríguez Baquero - DiegoRBaquero">
|
|
||||||
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
||||||
|
|
||||||
<script src="https://cdn.jsdelivr.net/g/webtorrent@0.62,momentjs@2.10,angularjs@1.4"></script>
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/g/normalize@3.0,skeleton@2.0">
|
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/fontawesome/4.5/css/font-awesome.min.css">
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="style.css">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<header>
|
|
||||||
<h1>βTorrent<span class="version"> v0.4.1</span></h1>
|
|
||||||
</header>
|
|
||||||
<div class="container" ng-controller="bTorrentCtrl" ng-cloak>
|
|
||||||
<div class="row">
|
|
||||||
<div class="twelve columns">
|
|
||||||
<div class="row">
|
|
||||||
<div class="five columns"><input type="text" class="u-full-width" placeholder="magnet link or hash" id="torrentInput" ng-model="torrentInput"></div>
|
|
||||||
<div class="two columns"><button class="button-primary" ng-click="fromInput()"><i class="fa fa-download"></i> Download</button></div>
|
|
||||||
<div class="five columns u-pull-right">
|
|
||||||
<input type="file" style="display: none;" id="fileUpload" onchange="angular.element(this).scope().uploadFile2(this)">
|
|
||||||
<label class="u-pull-right">
|
|
||||||
<button class="button-primary" ng-click="uploadFile()" ><i class="fa fa-upload"></i> Seed a file</button>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<table class="u-full-width">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Name</th>
|
|
||||||
<th ng-hide="client.done()">Downloaded</th>
|
|
||||||
<th ng-hide="client.done()">Remaining</th>
|
|
||||||
<th ng-hide="client.downloading()">Uploaded</th>
|
|
||||||
<th>Peers</th>
|
|
||||||
<th>Share</th>
|
|
||||||
<th>Actions</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody ng-hide="client.torrents.length">
|
|
||||||
<tr>
|
|
||||||
<td colspan="100" class="center">Add a torrent o seed a file!</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
<tbody ng-repeat="torrent in client.torrents" ng-if="torrent.name">
|
|
||||||
<tr class="torrentRow" ng-class="{selectedTorrent: torrent.showFiles}">
|
|
||||||
<td><div><i class="fa fa-cloud-download" ng-hide="torrent.done"></i><i class="fa fa-check" ng-show="torrent.done"></i> {{torrent.name}}</div><span class="subInfo">{{torrent.pSize}} in <a href="#" onclick="return false;" ng-click="toggleTorrent(torrent)">{{torrent.files.length}} files</a></span></td>
|
|
||||||
<td ng-hide="client.done()">{{torrent.pDownloaded}} <span class="subInfo">({{torrent.pProgress}}%)</span><br /><span class="subInfo">@ {{torrent.pDownloadSpeed}}/s</span></td>
|
|
||||||
<td ng-hide="client.done()">{{torrent.tRemaining}}</td>
|
|
||||||
<td ng-hide="client.downloading()">{{torrent.pUploaded}}<br /><span class="subInfo">@ {{torrent.pUploadSpeed}}/s</span></td>
|
|
||||||
<td>{{torrent.swarm.wires.length}}</td>
|
|
||||||
<td>
|
|
||||||
<a href="#{{torrent.infoHash}}" target="_blank">βTorrent</a>
|
|
||||||
| <a href="{{torrent.magnetURI}}" target="_blank">Magnet URI</a>
|
|
||||||
| <a href="{{torrent.oTorrentFileURL}}" target="_blank" download="{{torrent.fileName}}">.torrent</a>
|
|
||||||
<br><span class="subInfo"><i class="fa fa-hashtag"></i>{{torrent.infoHash}}</span>
|
|
||||||
</td>
|
|
||||||
<td><i class="fa fa-times" ng-click="client.remove(torrent, destroyedTorrent)"></i></td>
|
|
||||||
</tr>
|
|
||||||
<tr ng-show="torrent.showFiles">
|
|
||||||
<td class="files" colspan="100">
|
|
||||||
<div class="row">
|
|
||||||
<div class="two columns center"><i class="fa fa-file"></i> <strong>Files:</strong></div>
|
|
||||||
<div class="ten columns fix-height">
|
|
||||||
<ul class="no-margin">
|
|
||||||
<li ng-repeat="file in torrent.files">
|
|
||||||
<span ng-hide="file.done">{{file.status}}: {{file.name}}</span><a href="{{file.url}}" download="{{file.name}}" target="_blank" ng-show="file.done">{{file.name}}</a> <span class="subInfo">{{file.pSize}}</span>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
<tbody ng-show="client.processing">
|
|
||||||
<tr>
|
|
||||||
<td colspan="100" class="center">Please wait a few seconds!</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<footer>
|
|
||||||
Made in Bogotá, Colombia by <a href="http://diegorbaquero.com">DiegoRBaquero</a><br><small><a href="https://webtorrent.io">WebTorrent</a> is powered by JavaScript and WebRTC. Works in Chrome, Firefox, and Opera (desktop and Android).</small></p>
|
|
||||||
</footer>
|
|
||||||
<script src="app.js"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
104
index.jade
Normal file
104
index.jade
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
doctype html
|
||||||
|
html(ng-app='bTorrent', lang='en')
|
||||||
|
head
|
||||||
|
base(href='')
|
||||||
|
meta(charset='UTF-8')
|
||||||
|
title βTorrent: Browser WebTorrent Client
|
||||||
|
meta(name='description', content='βTorrent: Browser WebTorrent Client')
|
||||||
|
meta(name='keywords', content='βTorrent, btorrent, client, webtorrent, browser, torrent')
|
||||||
|
meta(name='author', content='Diego Rodríguez Baquero - DiegoRBaquero')
|
||||||
|
meta(name='viewport', content='width=device-width, initial-scale=1')
|
||||||
|
script(src='https://cdn.jsdelivr.net/g/webtorrent@0.62,momentjs@2.10,angularjs@1.4')
|
||||||
|
link(rel='stylesheet', href='https://cdn.jsdelivr.net/g/normalize@3.0,skeleton@2.0')
|
||||||
|
link(rel='stylesheet', href='https://cdn.jsdelivr.net/fontawesome/4.5/css/font-awesome.min.css')
|
||||||
|
link(rel='stylesheet', href='style.css')
|
||||||
|
body
|
||||||
|
header
|
||||||
|
h1
|
||||||
|
| βTorrent
|
||||||
|
span.version v0.4.1
|
||||||
|
.container(ng-controller='bTorrentCtrl', ng-cloak='')
|
||||||
|
.row
|
||||||
|
.twelve.columns
|
||||||
|
.row
|
||||||
|
.five.columns
|
||||||
|
input#torrentInput.u-full-width(type='text', placeholder='magnet link or hash', ng-model='torrentInput')
|
||||||
|
.two.columns
|
||||||
|
button.button-primary(ng-click='fromInput()')
|
||||||
|
i.fa.fa-download
|
||||||
|
| Download
|
||||||
|
.five.columns.u-pull-right
|
||||||
|
input#fileUpload(type='file', style='display: none;', onchange='angular.element(this).scope().uploadFile2(this)')
|
||||||
|
label.u-pull-right
|
||||||
|
button.button-primary(ng-click='uploadFile()')
|
||||||
|
i.fa.fa-upload
|
||||||
|
| Seed a file
|
||||||
|
table.u-full-width
|
||||||
|
thead
|
||||||
|
tr
|
||||||
|
th Name
|
||||||
|
th(ng-hide='client.done()') Downloaded
|
||||||
|
th(ng-hide='client.done()') Remaining
|
||||||
|
th(ng-hide='client.downloading()') Uploaded
|
||||||
|
th Peers
|
||||||
|
th Share
|
||||||
|
th Actions
|
||||||
|
tbody(ng-hide='client.torrents.length')
|
||||||
|
tr
|
||||||
|
td.center(colspan='100') Add a torrent o seed a file!
|
||||||
|
tbody(ng-repeat='torrent in client.torrents', ng-if='torrent.name')
|
||||||
|
tr.torrentRow(ng-class='{selectedTorrent: torrent.showFiles}')
|
||||||
|
td
|
||||||
|
div
|
||||||
|
i.fa.fa-cloud-download(ng-hide='torrent.done')
|
||||||
|
i.fa.fa-check(ng-show='torrent.done')
|
||||||
|
| {{torrent.name}}
|
||||||
|
span.subInfo
|
||||||
|
| {{torrent.length | pbytes}} in
|
||||||
|
a(href='#', onclick='return false;', ng-click='toggleTorrent(torrent)') {{torrent.files.length}} files
|
||||||
|
td(ng-hide='client.done()')
|
||||||
|
| {{torrent.downloaded | pbytes}}
|
||||||
|
span.subInfo ({{torrent.pProgress}}%)
|
||||||
|
br
|
||||||
|
span.subInfo @ {{torrent.downloadSpeed() | pbytes}}/s
|
||||||
|
td(ng-hide='client.done()') {{torrent.tRemaining}}
|
||||||
|
td(ng-hide='client.downloading()') {{torrent.uploaded | pbytes}}
|
||||||
|
br
|
||||||
|
span.subInfo @ {{torrent.uploadSpeed() | pbytes}}/s
|
||||||
|
td {{torrent.swarm.wires.length}}
|
||||||
|
td
|
||||||
|
a(href='#{{torrent.infoHash}}', target='_blank') βTorrent
|
||||||
|
|
|
||||||
|
a(href='{{torrent.magnetURI}}', target='_blank') Magnet URI
|
||||||
|
|
|
||||||
|
a(href='{{torrent.oTorrentFileURL}}', target='_blank', download='{{torrent.fileName}}') .torrent
|
||||||
|
br
|
||||||
|
span.subInfo
|
||||||
|
i.fa.fa-hashtag
|
||||||
|
| {{torrent.infoHash}}
|
||||||
|
td
|
||||||
|
i.fa.fa-times(ng-click='client.remove(torrent, destroyedTorrent)')
|
||||||
|
tr(ng-show='torrent.showFiles')
|
||||||
|
td.files(colspan='100')
|
||||||
|
.row
|
||||||
|
.two.columns.center
|
||||||
|
i.fa.fa-file
|
||||||
|
strong Files:
|
||||||
|
.ten.columns.fix-height
|
||||||
|
ul.no-margin
|
||||||
|
li(ng-repeat='file in torrent.files')
|
||||||
|
span(ng-hide='file.done') {{file.status}}: {{file.name}}
|
||||||
|
a(href='{{file.url}}', download='{{file.name}}', target='_blank', ng-show='file.done') {{file.name}}
|
||||||
|
span.subInfo {{file.length | pbytes}}
|
||||||
|
tbody(ng-show='client.processing')
|
||||||
|
tr
|
||||||
|
td.center(colspan='100') Please wait a few seconds!
|
||||||
|
footer
|
||||||
|
| Made in Bogotá, Colombia by
|
||||||
|
a(href='http://diegorbaquero.com') DiegoRBaquero
|
||||||
|
br
|
||||||
|
small
|
||||||
|
a(href='https://webtorrent.io') WebTorrent
|
||||||
|
| is powered by JavaScript and WebRTC. Works in Chrome, Firefox, and Opera (desktop and Android).
|
||||||
|
p
|
||||||
|
script(src='app.js')
|
55
style.css
55
style.css
|
@ -1,55 +0,0 @@
|
||||||
body {
|
|
||||||
height: 100%;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
header, footer, .center {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
th, td {
|
|
||||||
padding-left: 10px;
|
|
||||||
padding-right: 10px;
|
|
||||||
max-width: 200px;
|
|
||||||
overflow: scroll;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.version {
|
|
||||||
color: #ccc;
|
|
||||||
font-size: 0.3em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.torrentRow {
|
|
||||||
line-height: 1.2;
|
|
||||||
border-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.subInfo {
|
|
||||||
color: #bbbbbb;
|
|
||||||
font-size: 0.7em;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.column, .columns {
|
|
||||||
margin-left: 1%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.files {
|
|
||||||
padding-top: 1px;
|
|
||||||
padding-bottom: 1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.fix-height {
|
|
||||||
max-height: 24px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.no-margin {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.selectedTorrent {
|
|
||||||
background: rgb(100,100,100);
|
|
||||||
background: rgba(100,100,100,.06);
|
|
||||||
}
|
|
42
style.sass
Normal file
42
style.sass
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
body
|
||||||
|
height: 100%
|
||||||
|
width: 100%
|
||||||
|
|
||||||
|
header, footer, .center
|
||||||
|
text-align: center
|
||||||
|
|
||||||
|
th, td
|
||||||
|
padding-left: 10px
|
||||||
|
padding-right: 10px
|
||||||
|
max-width: 200px
|
||||||
|
overflow: scroll
|
||||||
|
white-space: nowrap
|
||||||
|
|
||||||
|
.version
|
||||||
|
color: #ccc
|
||||||
|
font-size: 0.3em
|
||||||
|
|
||||||
|
.torrentRow
|
||||||
|
line-height: 1.2
|
||||||
|
border-bottom: 0
|
||||||
|
|
||||||
|
.subInfo
|
||||||
|
color: #bbbbbb
|
||||||
|
font-size: 0.7em
|
||||||
|
|
||||||
|
.column, .columns
|
||||||
|
margin-left: 1%
|
||||||
|
|
||||||
|
.files
|
||||||
|
padding-top: 1px
|
||||||
|
padding-bottom: 1px
|
||||||
|
|
||||||
|
.fix-height
|
||||||
|
max-height: 24px
|
||||||
|
|
||||||
|
.no-margin
|
||||||
|
margin: 0
|
||||||
|
|
||||||
|
.selectedTorrent
|
||||||
|
background: rgb(100, 100, 100)
|
||||||
|
background: rgba(100, 100, 100, 0.06)
|
1
www/.idea/.name
Normal file
1
www/.idea/.name
Normal file
|
@ -0,0 +1 @@
|
||||||
|
btorrent-web
|
8
www/.idea/btorrent-web.iml
Normal file
8
www/.idea/btorrent-web.iml
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="WEB_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$" />
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
6
www/.idea/encodings.xml
Normal file
6
www/.idea/encodings.xml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="Encoding">
|
||||||
|
<file url="PROJECT" charset="UTF-8" />
|
||||||
|
</component>
|
||||||
|
</project>
|
13
www/.idea/misc.xml
Normal file
13
www/.idea/misc.xml
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectLevelVcsManager" settingsEditedManually="false">
|
||||||
|
<OptionsSetting value="true" id="Add" />
|
||||||
|
<OptionsSetting value="true" id="Remove" />
|
||||||
|
<OptionsSetting value="true" id="Checkout" />
|
||||||
|
<OptionsSetting value="true" id="Update" />
|
||||||
|
<OptionsSetting value="true" id="Status" />
|
||||||
|
<OptionsSetting value="true" id="Edit" />
|
||||||
|
<ConfirmationsSetting value="0" id="Add" />
|
||||||
|
<ConfirmationsSetting value="0" id="Remove" />
|
||||||
|
</component>
|
||||||
|
</project>
|
8
www/.idea/modules.xml
Normal file
8
www/.idea/modules.xml
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/btorrent-web.iml" filepath="$PROJECT_DIR$/.idea/btorrent-web.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
4
www/.idea/watcherTasks.xml
Normal file
4
www/.idea/watcherTasks.xml
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectTasksOptions" suppressed-tasks="Jade;Sass;CoffeeScript" />
|
||||||
|
</project>
|
249
www/.idea/workspace.xml
Normal file
249
www/.idea/workspace.xml
Normal file
|
@ -0,0 +1,249 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ChangeListManager">
|
||||||
|
<list default="true" id="b4fff367-e330-4d8e-a0e3-6d8302538c50" name="Default" comment="" />
|
||||||
|
<ignored path="btorrent-web.iws" />
|
||||||
|
<ignored path=".idea/workspace.xml" />
|
||||||
|
<option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
|
||||||
|
<option name="TRACKING_ENABLED" value="true" />
|
||||||
|
<option name="SHOW_DIALOG" value="false" />
|
||||||
|
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||||
|
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
||||||
|
<option name="LAST_RESOLUTION" value="IGNORE" />
|
||||||
|
</component>
|
||||||
|
<component name="ChangesViewManager" flattened_view="true" show_ignored="false" />
|
||||||
|
<component name="CreatePatchCommitExecutor">
|
||||||
|
<option name="PATCH_PATH" value="" />
|
||||||
|
</component>
|
||||||
|
<component name="ExecutionTargetManager" SELECTED_TARGET="default_target" />
|
||||||
|
<component name="FavoritesManager">
|
||||||
|
<favorites_list name="btorrent-web" />
|
||||||
|
</component>
|
||||||
|
<component name="FileEditorManager">
|
||||||
|
<leaf>
|
||||||
|
<file leaf-file-name="index.jade" pinned="false" current-in-tab="true">
|
||||||
|
<entry file="file://$PROJECT_DIR$/index.jade">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state vertical-scroll-proportion="-0.6435986">
|
||||||
|
<caret line="15" column="14" selection-start-line="15" selection-start-column="14" selection-end-line="15" selection-end-column="14" />
|
||||||
|
<folding />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
</file>
|
||||||
|
<file leaf-file-name="app.coffee" pinned="false" current-in-tab="false">
|
||||||
|
<entry file="file://$PROJECT_DIR$/app.coffee">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state vertical-scroll-proportion="0.0">
|
||||||
|
<caret line="156" column="6" selection-start-line="156" selection-start-column="6" selection-end-line="156" selection-end-column="6" />
|
||||||
|
<folding />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
</file>
|
||||||
|
</leaf>
|
||||||
|
</component>
|
||||||
|
<component name="IdeDocumentHistory">
|
||||||
|
<option name="CHANGED_PATHS">
|
||||||
|
<list>
|
||||||
|
<option value="$PROJECT_DIR$/style.sass" />
|
||||||
|
<option value="$PROJECT_DIR$/app.coffee" />
|
||||||
|
<option value="$PROJECT_DIR$/index.jade" />
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
<component name="JsBuildToolGruntFileManager" detection-done="true" />
|
||||||
|
<component name="JsBuildToolPackageJson" detection-done="true" />
|
||||||
|
<component name="JsGulpfileManager">
|
||||||
|
<detection-done>true</detection-done>
|
||||||
|
</component>
|
||||||
|
<component name="ProjectFrameBounds">
|
||||||
|
<option name="y" value="23" />
|
||||||
|
<option name="width" value="1680" />
|
||||||
|
<option name="height" value="991" />
|
||||||
|
</component>
|
||||||
|
<component name="ProjectLevelVcsManager" settingsEditedManually="false">
|
||||||
|
<OptionsSetting value="true" id="Add" />
|
||||||
|
<OptionsSetting value="true" id="Remove" />
|
||||||
|
<OptionsSetting value="true" id="Checkout" />
|
||||||
|
<OptionsSetting value="true" id="Update" />
|
||||||
|
<OptionsSetting value="true" id="Status" />
|
||||||
|
<OptionsSetting value="true" id="Edit" />
|
||||||
|
<ConfirmationsSetting value="0" id="Add" />
|
||||||
|
<ConfirmationsSetting value="0" id="Remove" />
|
||||||
|
</component>
|
||||||
|
<component name="ProjectView">
|
||||||
|
<navigator currentView="ProjectPane" proportions="" version="1">
|
||||||
|
<flattenPackages />
|
||||||
|
<showMembers />
|
||||||
|
<showModules />
|
||||||
|
<showLibraryContents />
|
||||||
|
<hideEmptyPackages />
|
||||||
|
<abbreviatePackageNames />
|
||||||
|
<autoscrollToSource />
|
||||||
|
<autoscrollFromSource />
|
||||||
|
<sortByType />
|
||||||
|
<manualOrder />
|
||||||
|
<foldersAlwaysOnTop value="true" />
|
||||||
|
</navigator>
|
||||||
|
<panes>
|
||||||
|
<pane id="Scratches" />
|
||||||
|
<pane id="Scope" />
|
||||||
|
<pane id="ProjectPane">
|
||||||
|
<subPane>
|
||||||
|
<PATH>
|
||||||
|
<PATH_ELEMENT>
|
||||||
|
<option name="myItemId" value="btorrent-web" />
|
||||||
|
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
|
||||||
|
</PATH_ELEMENT>
|
||||||
|
</PATH>
|
||||||
|
<PATH>
|
||||||
|
<PATH_ELEMENT>
|
||||||
|
<option name="myItemId" value="btorrent-web" />
|
||||||
|
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
|
||||||
|
</PATH_ELEMENT>
|
||||||
|
<PATH_ELEMENT>
|
||||||
|
<option name="myItemId" value="btorrent-web" />
|
||||||
|
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
|
||||||
|
</PATH_ELEMENT>
|
||||||
|
</PATH>
|
||||||
|
</subPane>
|
||||||
|
</pane>
|
||||||
|
</panes>
|
||||||
|
</component>
|
||||||
|
<component name="PropertiesComponent">
|
||||||
|
<property name="last_opened_file_path" value="$PROJECT_DIR$" />
|
||||||
|
<property name="WebServerToolWindowFactoryState" value="false" />
|
||||||
|
<property name="HbShouldOpenHtmlAsHb" value="" />
|
||||||
|
<property name="js-jscs-nodeInterpreter" value="/usr/local/bin/node" />
|
||||||
|
</component>
|
||||||
|
<component name="RunManager">
|
||||||
|
<configuration default="true" type="DartCommandLineRunConfigurationType" factoryName="Dart Command Line Application">
|
||||||
|
<method />
|
||||||
|
</configuration>
|
||||||
|
<configuration default="true" type="DartUnitRunConfigurationType" factoryName="DartUnit">
|
||||||
|
<method />
|
||||||
|
</configuration>
|
||||||
|
<configuration default="true" type="JavaScriptTestRunnerKarma" factoryName="Karma" config-file="">
|
||||||
|
<envs />
|
||||||
|
<method />
|
||||||
|
</configuration>
|
||||||
|
<configuration default="true" type="JavascriptDebugType" factoryName="JavaScript Debug">
|
||||||
|
<method />
|
||||||
|
</configuration>
|
||||||
|
<configuration default="true" type="NodeJSConfigurationType" factoryName="Node.js" working-dir="">
|
||||||
|
<method />
|
||||||
|
</configuration>
|
||||||
|
<configuration default="true" type="cucumber.js" factoryName="Cucumber.js">
|
||||||
|
<option name="cucumberJsArguments" value="" />
|
||||||
|
<option name="executablePath" />
|
||||||
|
<option name="filePath" />
|
||||||
|
<method />
|
||||||
|
</configuration>
|
||||||
|
<configuration default="true" type="js.build_tools.gulp" factoryName="Gulp.js">
|
||||||
|
<method />
|
||||||
|
</configuration>
|
||||||
|
<configuration default="true" type="js.build_tools.npm" factoryName="npm">
|
||||||
|
<command value="run-script" />
|
||||||
|
<scripts />
|
||||||
|
<envs />
|
||||||
|
<method />
|
||||||
|
</configuration>
|
||||||
|
<configuration default="true" type="mocha-javascript-test-runner" factoryName="Mocha">
|
||||||
|
<node-options />
|
||||||
|
<working-directory>$PROJECT_DIR$</working-directory>
|
||||||
|
<pass-parent-env>true</pass-parent-env>
|
||||||
|
<envs />
|
||||||
|
<ui>bdd</ui>
|
||||||
|
<extra-mocha-options />
|
||||||
|
<test-kind>DIRECTORY</test-kind>
|
||||||
|
<test-directory />
|
||||||
|
<recursive>false</recursive>
|
||||||
|
<method />
|
||||||
|
</configuration>
|
||||||
|
</component>
|
||||||
|
<component name="ShelveChangesManager" show_recycled="false" />
|
||||||
|
<component name="SvnConfiguration">
|
||||||
|
<configuration />
|
||||||
|
</component>
|
||||||
|
<component name="TaskManager">
|
||||||
|
<task active="true" id="Default" summary="Default task">
|
||||||
|
<changelist id="b4fff367-e330-4d8e-a0e3-6d8302538c50" name="Default" comment="" />
|
||||||
|
<created>1448905387131</created>
|
||||||
|
<option name="number" value="Default" />
|
||||||
|
<updated>1448905387131</updated>
|
||||||
|
</task>
|
||||||
|
<servers />
|
||||||
|
</component>
|
||||||
|
<component name="ToolWindowManager">
|
||||||
|
<frame x="0" y="23" width="1680" height="991" extended-state="6" />
|
||||||
|
<editor active="true" />
|
||||||
|
<layout>
|
||||||
|
<window_info id="Project" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
|
||||||
|
<window_info id="TODO" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="6" side_tool="false" content_ui="tabs" />
|
||||||
|
<window_info id="Event Log" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="-1" side_tool="true" content_ui="tabs" />
|
||||||
|
<window_info id="Find" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
|
||||||
|
<window_info id="Version Control" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="-1" side_tool="false" content_ui="tabs" />
|
||||||
|
<window_info id="Run" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" />
|
||||||
|
<window_info id="Structure" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
|
||||||
|
<window_info id="Terminal" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="-1" side_tool="false" content_ui="tabs" />
|
||||||
|
<window_info id="Favorites" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="-1" side_tool="true" content_ui="tabs" />
|
||||||
|
<window_info id="Debug" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
|
||||||
|
<window_info id="Cvs" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="4" side_tool="false" content_ui="tabs" />
|
||||||
|
<window_info id="Hierarchy" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="2" side_tool="false" content_ui="combo" />
|
||||||
|
<window_info id="Message" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
|
||||||
|
<window_info id="Commander" active="false" anchor="right" auto_hide="false" internal_type="SLIDING" type="SLIDING" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
|
||||||
|
<window_info id="Inspection" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="5" side_tool="false" content_ui="tabs" />
|
||||||
|
<window_info id="Ant Build" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
|
||||||
|
</layout>
|
||||||
|
</component>
|
||||||
|
<component name="Vcs.Log.UiProperties">
|
||||||
|
<option name="RECENTLY_FILTERED_USER_GROUPS">
|
||||||
|
<collection />
|
||||||
|
</option>
|
||||||
|
<option name="RECENTLY_FILTERED_BRANCH_GROUPS">
|
||||||
|
<collection />
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
<component name="VcsContentAnnotationSettings">
|
||||||
|
<option name="myLimit" value="2678400000" />
|
||||||
|
</component>
|
||||||
|
<component name="XDebuggerManager">
|
||||||
|
<breakpoint-manager />
|
||||||
|
<watches-manager />
|
||||||
|
</component>
|
||||||
|
<component name="editorHistoryManager">
|
||||||
|
<entry file="file://$PROJECT_DIR$/style.sass">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state vertical-scroll-proportion="0.70689654">
|
||||||
|
<caret line="41" column="39" selection-start-line="41" selection-start-column="39" selection-end-line="41" selection-end-column="39" />
|
||||||
|
<folding />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/404.jade">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state vertical-scroll-proportion="0.0">
|
||||||
|
<caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
|
||||||
|
<folding />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/app.coffee">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state vertical-scroll-proportion="0.0">
|
||||||
|
<caret line="156" column="6" selection-start-line="156" selection-start-column="6" selection-end-line="156" selection-end-column="6" />
|
||||||
|
<folding />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/index.jade">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state vertical-scroll-proportion="-0.6435986">
|
||||||
|
<caret line="15" column="14" selection-start-line="15" selection-start-column="14" selection-end-line="15" selection-end-column="14" />
|
||||||
|
<folding />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
</component>
|
||||||
|
</project>
|
1
www/app.js
Normal file
1
www/app.js
Normal file
|
@ -0,0 +1 @@
|
||||||
|
var app,client,debug;client=new WebTorrent;debug=true;app=angular.module("bTorrent",[],["$compileProvider","$locationProvider",function(e,n){e.aHrefSanitizationWhitelist(/^\s*(https?|magnet|blob|javascript):/);n.html5Mode({enabled:true,requireBase:false}).hashPrefix("#")}]);app.controller("bTorrentCtrl",["$scope","$http","$log","$location",function(e,n,t,o){var r,i;e.client=client;e.seedIt=true;r=function(e,n){if(debug){if(n){t.debug("%c"+n.name+" ("+n.infoHash+"): %c"+e,"color: #33C3F0","color: #333")}else{t.debug("%cClient: %c"+e,"color: #33C3F0","color: #333")}}};i=function(){e.$apply()};setInterval(i,500);e.client.done=function(){var n;n=true;e.client.torrents.forEach(function(e){if(!e.done){n=false}});return n};e.client.downloading=function(){var n;n=true;e.client.torrents.forEach(function(e){if(e.done){n=false}});return n};e.uploadFile=function(){document.getElementById("fileUpload").click()};e.uploadFile2=function(n){e.client.processing=true;r("Seeding "+n.files[0].name);e.client.seed(n.files,e.onSeed)};e.fromInput=function(){if(!e.torrentInput===""){e.client.processing=true;r("Adding "+e.torrentInput);e.client.add(e.torrentInput,e.onTorrent);e.torrentInput=""}};e.toggleTorrent=function(n){if(n.showFiles){n.showFiles=false;e.sTorrent=null}else{e.client.torrents.forEach(function(e){e.showFiles=false});n.showFiles=true;e.sTorrent=n}};e.destroyedTorrent=function(e){if(e){throw e}r("Destroyed torrent")};e.onTorrent=function(n,t){e.client.processing=false;n.showFiles=false;n.fileName=n.name+".torrent";n.oTorrentFileURL=n.torrentFileURL;if(angular.isUndefined(e.sTorrent)||e.sTorrent===null){e.sTorrent=n;n.showFiles=true}n.update=function(){var e;n.pProgress=(100*n.progress).toFixed(1);n.pDownloaded=n.downloaded;n.pUploaded=n.uploaded;n.pUploadSpeed=n.uploadSpeed();n.pDownloadSpeed=n.downloadSpeed();if(n.done){n.tRemaining="Done"}else{e=moment.duration(n.timeRemaining/1e3,"seconds").humanize();n.tRemaining=e[0].toUpperCase()+e.substr(1)}};n.files.forEach(function(o){o.pSize=o.length;o.status="Downloading";o.url="javascript: return false;";o.getBlobURL(function(i,l){if(i){throw i}o.url=l;if(!t){r("Finished downloading file "+o.name,n)}o.status="Ready";e.$apply()});if(!t){r("Received file "+o.name+" metadata",n)}});n.on("download",function(e){if(!t){r("Downloaded chunk",n)}});n.on("upload",function(e){r("Uploaded chunk",n)});n.on("done",function(){if(!t){r("Done",n)}n.update()});n.on("wire",function(e,t){r("Wire "+t,n)});setInterval(n.update,500);n.update()};e.onSeed=function(n){e.onTorrent(n,true)};if(o.hash()!==""){e.client.processing=true;r("Adding "+o.hash());client.add(o.hash(),e.onTorrent)}}]);app.filter("html",["$sce",function(e){return function(n){return e.trustAsHtml(n)}}]);app.filter("pbytes",function(){return function(e){var n,t,o,r;n=void 0;o=void 0;t=e<0;r=["B","kB","MB","GB","TB","PB","EB","ZB","YB"];if(t){e=-e}if(e<1){return(t?"-":"")+e+" B"}n=Math.min(Math.floor(Math.log(e)/Math.log(1e3)),r.length-1);e=(e/Math.pow(1e3,n)).toFixed(1)*1;o=r[n];return(t?"-":"")+e+" "+o}});
|
1
www/index.html
Normal file
1
www/index.html
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<!DOCTYPE html><html ng-app="bTorrent" lang="en"><head><base href=""><meta charset="UTF-8"><title>βTorrent: Browser WebTorrent Client</title><meta name="description" content="βTorrent: Browser WebTorrent Client"><meta name="keywords" content="βTorrent, btorrent, client, webtorrent, browser, torrent"><meta name="author" content="Diego Rodríguez Baquero - DiegoRBaquero"><meta name="viewport" content="width=device-width, initial-scale=1"><script src="https://cdn.jsdelivr.net/g/webtorrent@0.62,momentjs@2.10,angularjs@1.4"></script><link rel="stylesheet" href="https://cdn.jsdelivr.net/g/normalize@3.0,skeleton@2.0"><link rel="stylesheet" href="https://cdn.jsdelivr.net/fontawesome/4.5/css/font-awesome.min.css"><link rel="stylesheet" href="style.css"></head><body><header><h1>βTorrent<span class="version"> v0.4.1</span></h1></header><div ng-controller="bTorrentCtrl" ng-cloak="" class="container"><div class="row"><div class="twelve columns"><div class="row"><div class="five columns"><input id="torrentInput" type="text" placeholder="magnet link or hash" ng-model="torrentInput" class="u-full-width"></div><div class="two columns"><button ng-click="fromInput()" class="button-primary"><i class="fa fa-download"></i> Download</button></div><div class="five columns u-pull-right"><input id="fileUpload" type="file" style="display: none;" onchange="angular.element(this).scope().uploadFile2(this)"><label class="u-pull-right"><button ng-click="uploadFile()" class="button-primary"><i class="fa fa-upload"></i> Seed a file</button></label></div></div><table class="u-full-width"><thead><tr><th>Name</th><th ng-hide="client.done()">Downloaded</th><th ng-hide="client.done()">Remaining</th><th ng-hide="client.downloading()">Uploaded</th><th>Peers</th><th>Share</th><th>Actions</th></tr></thead><tbody ng-hide="client.torrents.length"><tr><td colspan="100" class="center">Add a torrent o seed a file!</td></tr></tbody><tbody ng-repeat="torrent in client.torrents" ng-if="torrent.name"><tr ng-class="{selectedTorrent: torrent.showFiles}" class="torrentRow"><td><div><i ng-hide="torrent.done" class="fa fa-cloud-download"></i><i ng-show="torrent.done" class="fa fa-check"></i> {{torrent.name}}</div><span class="subInfo">{{torrent.length | pbytes}} in <a href="#" onclick="return false;" ng-click="toggleTorrent(torrent)">{{torrent.files.length}} files</a></span></td><td ng-hide="client.done()">{{torrent.downloaded | pbytes}}<span class="subInfo">({{torrent.pProgress}}%)</span><br><span class="subInfo">@ {{torrent.downloadSpeed() | pbytes}}/s</span></td><td ng-hide="client.done()">{{torrent.tRemaining}}</td><td ng-hide="client.downloading()">{{torrent.uploaded | pbytes}}<br><span class="subInfo">@ {{torrent.uploadSpeed() | pbytes}}/s</span></td><td>{{torrent.swarm.wires.length}}</td><td><a href="#{{torrent.infoHash}}" target="_blank">βTorrent</a> <a href="{{torrent.magnetURI}}" target="_blank">Magnet URI</a> <a href="{{torrent.oTorrentFileURL}}" target="_blank" download="{{torrent.fileName}}">.torrent</a><br><span class="subInfo"><i class="fa fa-hashtag"></i>{{torrent.infoHash}}</span></td><td><i ng-click="client.remove(torrent, destroyedTorrent)" class="fa fa-times"></i></td></tr><tr ng-show="torrent.showFiles"><td colspan="100" class="files"><div class="row"><div class="two columns center"><i class="fa fa-file"></i><strong>Files:</strong></div><div class="ten columns fix-height"><ul class="no-margin"><li ng-repeat="file in torrent.files"><span ng-hide="file.done">{{file.status}}: {{file.name}}</span><a href="{{file.url}}" download="{{file.name}}" target="_blank" ng-show="file.done">{{file.name}}</a><span class="subInfo"> {{file.length | pbytes}}</span></li></ul></div></div></td></tr></tbody><tbody ng-show="client.processing"><tr><td colspan="100" class="center">Please wait a few seconds!</td></tr></tbody></table></div></div></div><footer>Made in Bogotá, Colombia by<a href="http://diegorbaquero.com">DiegoRBaquero</a><br><small><a href="https://webtorrent.io">WebTorrent</a> is powered by JavaScript and WebRTC. Works in Chrome, Firefox, and Opera (desktop and Android).</small><p></p></footer><script src="app.js"></script></body></html>
|
1
www/style.css
Normal file
1
www/style.css
Normal file
|
@ -0,0 +1 @@
|
||||||
|
body{height:100%;width:100%}header,footer,.center{text-align:center}th,td{padding-left:10px;padding-right:10px;max-width:200px;overflow:scroll;white-space:nowrap}.version{color:#ccc;font-size:0.3em}.torrentRow{line-height:1.2;border-bottom:0}.subInfo{color:#bbb;font-size:0.7em}.column,.columns{margin-left:1%}.files{padding-top:1px;padding-bottom:1px}.fix-height{max-height:24px}.no-margin{margin:0}.selectedTorrent{background:#646464;background:rgba(100,100,100,0.06)}
|
Loading…
Reference in a new issue