btorrent/app.coffee

242 lines
7.5 KiB
CoffeeScript
Raw Normal View History

2015-12-01 03:01:26 +00:00
trackers = [
2015-12-08 16:29:19 +00:00
[ 'wss://tracker.btorrent.xyz' ],
[ 'wss://tracker.webtorrent.io' ]
2015-12-01 03:01:26 +00:00
]
opts = {
announce: trackers
}
2015-12-01 03:01:26 +00:00
2015-12-08 16:29:19 +00:00
rtcConfig = {
"iceServers":[
{"url":"stun:23.21.150.121","urls":"stun:23.21.150.121"},
{"url":"stun:stun.l.google.com:19302","urls":"stun:stun.l.google.com:19302"},
{"url":"stun:stun1.l.google.com:19302","urls":"stun:stun1.l.google.com:19302"},
{"url":"stun:stun2.l.google.com:19302","urls":"stun:stun2.l.google.com:19302"},
{"url":"stun:stun3.l.google.com:19302","urls":"stun:stun3.l.google.com:19302"},
{"url":"stun:stun4.l.google.com:19302","urls":"stun:stun4.l.google.com:19302"},
{
"url":"turn:global.turn.twilio.com:3478?transport=udp",
"urls":"turn:global.turn.twilio.com:3478?transport=udp",
"username":"857315a4616be37252127d4ff924c3a3536dd3fa729b56206dfa0e6808a80478",
"credential":"EEEr7bxx8umMHC4sOoWDC/4MxU/4JCfL+W7KeSJEsBQ="
},
{
"url": "turn:numb.viagenie.ca",
"urls": "turn:numb.viagenie.ca",
"credential": "webrtcdemo",
"username": "louis%40mozilla.com"
}
]
}
client = new WebTorrent {rtcConfig: rtcConfig}
dbg = (string, item, color) ->
color = if color? then color else '#333333'
2015-12-07 04:53:33 +00:00
if window.localStorage.getItem('debug')?
if item? && item.name
console.debug '%cβTorrent:' + (if item.infoHash? then 'torrent ' else 'torrent ' + item._torrent.name + ':file ') + item.name + (if item.infoHash? then ' (' + item.infoHash + ')' else '') + ' %c' + string, 'color: #33C3F0', 'color: ' + color
2015-12-03 01:05:27 +00:00
return
else
console.debug '%cβTorrent:client %c' + string, 'color: #33C3F0', 'color: ' + color
2015-12-03 01:05:27 +00:00
return
return
er = (err, torrent) ->
dbg err, torrent, '#FF0000'
app = angular.module 'bTorrent', ['ui.grid', 'ui.grid.resizeColumns', 'ui.grid.selection', 'ngFileUpload', 'ngNotify'], ['$compileProvider','$locationProvider', ($compileProvider, $locationProvider) ->
$compileProvider.aHrefSanitizationWhitelist /^\s*(https?|magnet|blob|javascript):/
$locationProvider.html5Mode(
enabled: true
requireBase: false).hashPrefix '#'
]
app.controller 'bTorrentCtrl', ['$scope','$http','$log','$location', 'ngNotify', ($scope, $http, $log, $location, ngNotify) ->
$scope.client = client
$scope.seedIt = true
$scope.client.validTorrents = []
2015-12-03 01:05:27 +00:00
$scope.columns = [
{field: 'name', cellTooltip: true, minWidth: '200'}
{field: 'length', name: 'Size', cellFilter: 'pbytes', width: '80'}
{field: 'received', displayName: 'Downloaded', cellFilter: 'pbytes', width: '135'}
{field: 'downloadSpeed()', displayName: '↓ Speed', cellFilter: 'pbytes:1', width: '100'}
{field: 'progress', displayName: 'Progress', cellFilter: 'progress', width: '100'}
{field: 'timeRemaining', displayName: 'ETA', cellFilter: 'humanTime', width: '150'}
{field: 'uploaded', displayName: 'Uploaded', cellFilter: 'pbytes', width: '125'}
{field: 'uploadSpeed()', displayName: '↑ Speed', cellFilter: 'pbytes:1', width: '100'}
{field: 'numPeers', displayName: 'Peers', width: '80'}
{field: 'ratio', cellFilter: 'number:2', width: '80'}
]
$scope.gridOptions =
columnDefs: $scope.columns
data: $scope.client.torrents
2015-12-03 01:05:27 +00:00
enableColumnResizing: true
enableColumnMenus: false
enableRowSelection: true
enableRowHeaderSelection: false
multiSelect: false
updateAll = ->
2015-12-03 01:05:27 +00:00
if $scope.client.processing
return
$scope.$apply()
return
setInterval updateAll, 500
2015-12-03 01:05:27 +00:00
$scope.gridOptions.onRegisterApi = ( gridApi ) ->
$scope.gridApi = gridApi
gridApi.selection.on.rowSelectionChanged $scope, (row) ->
if !row.isSelected && $scope.selectedTorrent? && $scope.selectedTorrent.infoHash = row.entity.infoHash
$scope.selectedTorrent = null
else
$scope.selectedTorrent = row.entity
$scope.seedFiles = (files) ->
if files?
if files.length == 1
dbg 'Seeding file ' + files[0].name
else
dbg 'Seeding ' + files.length + ' files'
name = prompt('Please name your torrent', 'My Awesome Torrent') || 'My Awesome Torrent'
opts.name = name
$scope.client.processing = true
$scope.client.seed files, opts, $scope.onSeed
delete opts.name
return
$scope.openTorrentFile = (file) ->
if file?
dbg 'Adding torrent file ' + file.name
$scope.client.processing = true
2015-12-07 16:53:57 +00:00
$scope.client.add file, opts, $scope.onTorrent
$scope.client.on('error', (err, torrent) ->
$scope.client.processing = false
ngNotify.set(err, 'error');
er err, torrent
)
$scope.addMagnet = ->
2015-12-01 01:12:35 +00:00
if $scope.torrentInput != ''
dbg 'Adding magnet/hash ' + $scope.torrentInput
2015-12-03 01:05:27 +00:00
$scope.client.processing = true
2015-12-01 06:34:04 +00:00
$scope.client.add $scope.torrentInput, opts, $scope.onTorrent
$scope.torrentInput = ''
2015-12-01 01:12:35 +00:00
return
$scope.destroyedTorrent = (err) ->
if err
throw err
dbg 'Destroyed torrent', $scope.selectedTorrent
$scope.selectedTorrent = null
$scope.client.processing = false
return
$scope.changePriority = (file) ->
if file.priority == '-1'
dbg 'Deselected', file
file.deselect()
else
dbg 'Selected ', file
file.select()
$scope.onTorrent = (torrent, isSeed) ->
2015-12-03 01:05:27 +00:00
torrent.safeTorrentFileURL = torrent.torrentFileURL
torrent.fileName = torrent.name + '.torrent'
2015-12-03 01:05:27 +00:00
if !isSeed
$scope.client.validTorrents.push torrent
if !($scope.selectedTorrent?)
$scope.selectedTorrent = torrent
$scope.client.processing = false
torrent.files.forEach (file) ->
file.getBlobURL (err, url) ->
if err
throw err
2015-12-01 07:52:10 +00:00
if isSeed
dbg 'Started seeding', torrent
if $scope.client.validTorrents.indexOf(torrent) == -1
$scope.client.validTorrents.push torrent
if !($scope.selectedTorrent?)
$scope.selectedTorrent = torrent
2015-12-01 07:52:10 +00:00
$scope.client.processing = false
file.url = url
if !isSeed
dbg 'Finished downloading file ' + file.name, torrent
return
if !isSeed
dbg 'Received file ' + file.name + ' metadata', torrent
2015-12-01 01:12:35 +00:00
return
torrent.on 'download', (chunkSize) ->
if !isSeed
dbg 'Downloaded chunk', torrent
2015-12-01 01:12:35 +00:00
return
torrent.on 'upload', (chunkSize) ->
dbg 'Uploaded chunk', torrent
return
torrent.on 'done', ->
if !isSeed
dbg 'Done', torrent
2015-12-01 01:12:35 +00:00
return
torrent.update()
return
torrent.on 'wire', (wire, addr) ->
dbg 'Wire ' + addr, torrent
return
return
$scope.onSeed = (torrent) ->
$scope.onTorrent torrent, true
return
if $location.hash() != ''
$scope.client.processing = true
2015-12-03 01:05:27 +00:00
setTimeout ->
dbg 'Adding ' + $location.hash()
$scope.client.add $location.hash(), $scope.onTorrent
, 500
2015-12-01 01:12:35 +00:00
return
]
app.filter 'html', ['$sce', ($sce) ->
(input) ->
$sce.trustAsHtml input
2015-12-01 01:12:35 +00:00
return
]
app.filter 'pbytes', ->
2015-12-03 01:05:27 +00:00
(num, speed) ->
2015-12-01 07:52:10 +00:00
if isNaN(num)
return ''
exponent = undefined
unit = undefined
units = [
'B'
'kB'
'MB'
'GB'
'TB'
]
if num < 1
2015-12-03 01:05:27 +00:00
return (if speed then '' else '0 B')
2015-12-01 01:12:35 +00:00
exponent = Math.min(Math.floor(Math.log(num) / Math.log(1000)), 8)
num = (num / 1000 ** exponent).toFixed(1) * 1
unit = units[exponent]
2015-12-03 01:05:27 +00:00
num + ' ' + unit + (if speed then '/s' else '')
app.filter 'humanTime', ->
(millis) ->
if millis < 1000
return ''
remaining = moment.duration(millis / 1000, 'seconds').humanize()
remaining[0].toUpperCase() + remaining.substr(1)
app.filter 'progress', ->
(num) ->
(100 * num).toFixed(1) + '%'