distribustream 0.4.0 → 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +13 -0
- data/README +1 -1
- data/bin/dsclient +12 -3
- data/bin/dstream +18 -2
- data/distribustream.gemspec +2 -2
- data/lib/pdtp/common.rb +1 -1
- data/lib/pdtp/common/length_prefix_protocol.rb +27 -28
- data/lib/pdtp/server.rb +18 -2
- data/lib/pdtp/server/status_handler.rb +20 -61
- data/lib/pdtp/server/status_helper.rb +155 -0
- data/status/images/logo.png +0 -0
- data/status/index.erb +44 -0
- data/status/stylesheets/style.css +42 -0
- metadata +28 -22
data/CHANGES
CHANGED
@@ -1,3 +1,16 @@
|
|
1
|
+
Version 0.4.1
|
2
|
+
* Add -v / --version flags to dsclient and dstream
|
3
|
+
|
4
|
+
* Add additional flags to dstream for specifying listen addr / port
|
5
|
+
|
6
|
+
* Status page now factored into its own ERb template in status/
|
7
|
+
|
8
|
+
* Added Mongrel handlers to serve images/stylesheets for status page
|
9
|
+
|
10
|
+
* Added StatusHelper module to provide helpers for status page
|
11
|
+
|
12
|
+
* New status page
|
13
|
+
|
1
14
|
Version 0.4.0
|
2
15
|
* Change PDTP::Client#run to take an instance of PDTP::Client::Callbacks rather
|
3
16
|
than the name of the class to instantiate
|
data/README
CHANGED
@@ -34,7 +34,7 @@ You can see what's going on through the web interface, which runs one port
|
|
34
34
|
above the port you configured the server to listen on. If the server is
|
35
35
|
listening on the default port of 6086, you can reach the web interface at:
|
36
36
|
|
37
|
-
http://myserver.url:6087/
|
37
|
+
http://myserver.url:6087/status/
|
38
38
|
|
39
39
|
To test your server, use the DistribuStream client:
|
40
40
|
|
data/bin/dsclient
CHANGED
@@ -51,6 +51,7 @@ require File.dirname(__FILE__) + '/../lib/pdtp/client'
|
|
51
51
|
|
52
52
|
opts = GetoptLong.new(
|
53
53
|
[ '--help', '-h', GetoptLong::NO_ARGUMENT ],
|
54
|
+
[ '--version', '-v', GetoptLong::NO_ARGUMENT],
|
54
55
|
[ '--output', '-o', GetoptLong::REQUIRED_ARGUMENT ],
|
55
56
|
[ '--listen', '-l', GetoptLong::OPTIONAL_ARGUMENT ]
|
56
57
|
)
|
@@ -64,11 +65,19 @@ def display_usage
|
|
64
65
|
exit
|
65
66
|
end
|
66
67
|
|
68
|
+
# Display version information
|
69
|
+
def display_version
|
70
|
+
STDERR.write "#{File.basename $0} #{PDTP::VERSION} - DistribuStream client application\n"
|
71
|
+
STDERR.write "Copyright (C) 2006-07 ClickCaster, Inc. (info@clickcaster.com)\n"
|
72
|
+
exit
|
73
|
+
end
|
74
|
+
|
67
75
|
opts.each do |opt, arg|
|
68
76
|
case opt
|
69
|
-
when '--help'
|
70
|
-
when '--
|
71
|
-
when '--
|
77
|
+
when '--help' then display_usage
|
78
|
+
when '--version' then display_version
|
79
|
+
when '--output' then filename = arg
|
80
|
+
when '--listen' then listen_port = arg.to_i
|
72
81
|
end
|
73
82
|
end
|
74
83
|
|
data/bin/dstream
CHANGED
@@ -26,20 +26,33 @@ require File.dirname(__FILE__) + '/../lib/pdtp/server'
|
|
26
26
|
|
27
27
|
program_name = File.basename($0)
|
28
28
|
config_filename = nil
|
29
|
+
listen_addr = nil
|
30
|
+
listen_port = nil
|
29
31
|
|
30
32
|
OptionParser.new do |opts|
|
31
33
|
opts.banner = "Usage: #{program_name} [options]"
|
32
34
|
opts.on("--config CONFIGFILE", "Load specified config file.") do |c|
|
33
35
|
config_filename = c
|
34
36
|
end
|
37
|
+
opts.on("--listen ADDR", "Listen at the specified host address.") do |h|
|
38
|
+
listen_addr = h
|
39
|
+
end
|
40
|
+
opts.on("--port PORT", "Listen on the specified port number.") do |p|
|
41
|
+
listen_port = p
|
42
|
+
end
|
35
43
|
opts.on("--help", "Prints this usage info.") do
|
36
44
|
puts opts
|
37
45
|
exit
|
38
46
|
end
|
47
|
+
opts.on("--version", "Print version information.") do
|
48
|
+
puts "#{program_name} #{PDTP::VERSION} - DistribuStream server application"
|
49
|
+
puts "Copyright (C) 2006-07 ClickCaster, Inc. (info@clickcaster.com)"
|
50
|
+
exit
|
51
|
+
end
|
39
52
|
end.parse!
|
40
53
|
|
41
54
|
config = {
|
42
|
-
:host => '
|
55
|
+
:host => '127.0.0.1',
|
43
56
|
:port => 6086, #server port
|
44
57
|
:listen_port => 8000, #client listen port
|
45
58
|
:file_root => '.',
|
@@ -68,7 +81,10 @@ else
|
|
68
81
|
end
|
69
82
|
end
|
70
83
|
|
71
|
-
|
84
|
+
config[:host] = listen_addr unless listen_addr.nil?
|
85
|
+
config[:port] = listen_port unless listen_port.nil?
|
86
|
+
|
87
|
+
puts "#{program_name} #{PDTP::VERSION} starting. Run '#{program_name} --help' for more info."
|
72
88
|
|
73
89
|
server = PDTP::Server.new config[:host], config[:port]
|
74
90
|
|
data/distribustream.gemspec
CHANGED
@@ -2,7 +2,7 @@ require 'rubygems'
|
|
2
2
|
|
3
3
|
GEMSPEC = Gem::Specification.new do |s|
|
4
4
|
s.name = "distribustream"
|
5
|
-
s.version = "0.4.
|
5
|
+
s.version = "0.4.1"
|
6
6
|
s.date = "2008-11-15"
|
7
7
|
s.summary = "DistribuStream is a fully open peercasting system allowing on-demand or live streaming media to be delivered at a fraction of the normal cost"
|
8
8
|
s.email = "tony@clickcaster.com"
|
@@ -12,7 +12,7 @@ GEMSPEC = Gem::Specification.new do |s|
|
|
12
12
|
s.rdoc_options = ["--exclude", "definitions", "--exclude", "indexes"]
|
13
13
|
s.extra_rdoc_files = ["COPYING", "README", "CHANGES", "pdtp-specification.xml"]
|
14
14
|
s.authors = ["Tony Arcieri", "Ashvin Mysore", "Galen Pahlke", "James Sanders", "Tom Stapleton"]
|
15
|
-
s.files = Dir.glob("{bin,lib,conf}/**/*") + ['Rakefile', 'distribustream.gemspec']
|
15
|
+
s.files = Dir.glob("{bin,lib,conf,status}/**/*") + ['Rakefile', 'distribustream.gemspec']
|
16
16
|
s.executables = %w{dstream dsclient}
|
17
17
|
s.add_dependency("eventmachine", ">= 0.9.0")
|
18
18
|
s.add_dependency("mongrel", ">= 1.0.2")
|
data/lib/pdtp/common.rb
CHANGED
@@ -22,7 +22,7 @@
|
|
22
22
|
|
23
23
|
# Namespace for all PDTP components
|
24
24
|
module PDTP
|
25
|
-
PDTP::VERSION = '0.4.
|
25
|
+
PDTP::VERSION = '0.4.1' unless defined? PDTP::VERSION
|
26
26
|
def self.version() VERSION end
|
27
27
|
|
28
28
|
PDTP::DEFAULT_PORT = 6086 unless defined? PDTP::DEFAULT_PORT
|
@@ -88,34 +88,33 @@ module PDTP
|
|
88
88
|
|
89
89
|
# Callback for processing incoming frames
|
90
90
|
def receive_data(data)
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
receive_data remainder
|
91
|
+
begin
|
92
|
+
# Read data and append it to the size prefix unless it's already been read
|
93
|
+
data = @prefix.append(data) unless @prefix.read?
|
94
|
+
return if data.nil?
|
95
|
+
|
96
|
+
# If we've read the prefix, append the data
|
97
|
+
@buffer << data
|
98
|
+
|
99
|
+
# Don't do anything until we receive the specified amount of data
|
100
|
+
return unless @buffer.length >= @prefix.length
|
101
|
+
|
102
|
+
# Extract the specified amount of data and process it
|
103
|
+
data = @buffer[0..(@prefix.length - 1)]
|
104
|
+
|
105
|
+
# Store any remaining data
|
106
|
+
remainder = @buffer[@prefix.length..@buffer.length]
|
107
|
+
|
108
|
+
# Invoke receive_packet and allow the user to process the data
|
109
|
+
receive_packet data
|
110
|
+
|
111
|
+
# Reset the prefix and buffer since we've received a whole frame
|
112
|
+
@prefix.reset!
|
113
|
+
@buffer = ''
|
114
|
+
|
115
|
+
# Store data for next iteration of the loop
|
116
|
+
data = remainder
|
117
|
+
end until data.nil? or data.empty?
|
119
118
|
end
|
120
119
|
|
121
120
|
# Stub for receiving a frame
|
data/lib/pdtp/server.rb
CHANGED
@@ -50,8 +50,24 @@ module PDTP
|
|
50
50
|
|
51
51
|
# Run a web server to display statistics on the given address and port
|
52
52
|
def enable_status_page(path = '/status')
|
53
|
-
|
54
|
-
|
53
|
+
# Strip trailing slash (if present)
|
54
|
+
path.sub!(/\/$/, '')
|
55
|
+
|
56
|
+
log "status at http://#{@addr}:#{@http_port}#{path}/"
|
57
|
+
|
58
|
+
# Redirect requests without a trailing slash
|
59
|
+
http_server.register path, Mongrel::RedirectHandler.new(path + '/')
|
60
|
+
|
61
|
+
# Register the status handler
|
62
|
+
http_server.register path + '/', StatusHandler.new(@orig_addr, @dispatcher), true
|
63
|
+
|
64
|
+
# Serve status images
|
65
|
+
images = Mongrel::DirHandler.new(File.dirname(__FILE__) + '/../../status/images', false)
|
66
|
+
http_server.register path + '/images', images
|
67
|
+
|
68
|
+
# Serve status stylesheets
|
69
|
+
styles = Mongrel::DirHandler.new(File.dirname(__FILE__) + '/../../status/stylesheets', false)
|
70
|
+
http_server.register path + '/stylesheets', styles
|
55
71
|
end
|
56
72
|
|
57
73
|
# Serve files from the given directory
|
@@ -25,79 +25,38 @@ require 'mongrel'
|
|
25
25
|
require 'erb'
|
26
26
|
|
27
27
|
require File.dirname(__FILE__) + '/../common/http_server'
|
28
|
+
require File.dirname(__FILE__) + '/status_helper'
|
28
29
|
|
29
30
|
module PDTP
|
30
31
|
class Server
|
31
|
-
#
|
32
|
+
# A Mongrel::HttpHandler for generating the status page
|
32
33
|
class StatusHandler < Mongrel::HttpHandler
|
33
|
-
|
34
|
-
|
34
|
+
include StatusHelper
|
35
|
+
|
36
|
+
def initialize(vhost, dispatcher)
|
37
|
+
@vhost, @dispatcher = vhost, dispatcher
|
35
38
|
end
|
36
39
|
|
37
|
-
#
|
40
|
+
# Process an incoming request to generate the status page
|
38
41
|
def process(request, response)
|
39
42
|
response.start(200) do |head, out|
|
40
43
|
out.write begin
|
41
|
-
|
44
|
+
# Read the status page ERb template
|
45
|
+
erb_data = File.read(File.dirname(__FILE__) + '/../../../status/index.erb')
|
46
|
+
|
47
|
+
# Render the status ERb template
|
48
|
+
html = ERB.new(erb_data).result(binding)
|
49
|
+
|
50
|
+
# Call reset_cycle from the StatusHelper to reset cycle() calls
|
51
|
+
reset_cycle
|
52
|
+
|
53
|
+
# Return output html
|
54
|
+
html
|
42
55
|
rescue Exception => e
|
43
56
|
"Exception: #{e}\n#{e.backtrace.join("\n")}"
|
44
57
|
end
|
45
58
|
end
|
46
|
-
end
|
47
|
-
|
48
|
-
#builds an html page with information about the server's internal workings
|
49
|
-
def generate_html_stats
|
50
|
-
s = ERB.new <<EOF
|
51
|
-
<html><head><title>DistribuStream Status</title></head>
|
52
|
-
<body>
|
53
|
-
<h1>DistribuStream Status</h1>
|
54
|
-
Time=<%= Time.now %><br> Connected Clients=<%= @dispatcher.connections.size %>
|
55
|
-
<center><table border="1">
|
56
|
-
<tr><th>Client</th><th>Transfers</th><th>Files</th></tr>
|
57
|
-
<% @dispatcher.connections.each do |c| %>
|
58
|
-
<tr><td>
|
59
|
-
<% if c.file_service? %>
|
60
|
-
<b>File Service</b>
|
61
|
-
<% else %>
|
62
|
-
<%= @dispatcher.connection_name(c) %>
|
63
|
-
<% end %>
|
64
|
-
<% host, port = c.get_peer_info %>
|
65
|
-
<br><%= host %>:<%= port %>
|
66
|
-
</td>
|
67
|
-
<td>
|
68
|
-
<%
|
69
|
-
@dispatcher.client_info(c).transfers.each do |key,t|
|
70
|
-
if c==t.giver
|
71
|
-
type="UP: "
|
72
|
-
peer=t.taker
|
73
|
-
else
|
74
|
-
type="DOWN: "
|
75
|
-
peer=t.giver
|
76
|
-
end
|
77
|
-
%>
|
78
|
-
<%= type %> id=<%= t.transfer_id %><br>
|
79
|
-
<%
|
80
|
-
end
|
81
|
-
%>
|
82
|
-
</td>
|
83
|
-
<td>
|
84
|
-
<%
|
85
|
-
@dispatcher.client_info(c).chunk_info.get_file_stats.each do |fs|
|
86
|
-
%>
|
87
|
-
<%= fs.url %> size=<%= fs.file_chunks %> req=<%= fs.chunks_requested %>
|
88
|
-
prov=<%= fs.chunks_provided %> transf=<%= fs.chunks_transferring %><br>
|
89
|
-
<%
|
90
|
-
end
|
91
|
-
%>
|
92
|
-
</td></tr>
|
93
|
-
<%
|
94
|
-
end
|
95
|
-
%>
|
96
|
-
</table>
|
97
|
-
</body></html>
|
98
|
-
EOF
|
99
|
-
s.result binding
|
100
|
-
end
|
59
|
+
end
|
101
60
|
end
|
102
61
|
end
|
103
|
-
end
|
62
|
+
end
|
@@ -0,0 +1,155 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (C) 2006-07 ClickCaster, Inc. (info@clickcaster.com)
|
3
|
+
#
|
4
|
+
# This program is free software: you can redistribute it and/or modify
|
5
|
+
# it under the terms of the GNU General Public License as published by
|
6
|
+
# the Free Software Foundation, either version 3 of the License, or
|
7
|
+
# (at your option) any later version.
|
8
|
+
#
|
9
|
+
# This program is distributed in the hope that it will be useful,
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
# GNU General Public License for more details.
|
13
|
+
#
|
14
|
+
# You should have received a copy of the GNU General Public License
|
15
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
16
|
+
#
|
17
|
+
# This source file is distributed as part of the
|
18
|
+
# DistribuStream file transfer system.
|
19
|
+
#
|
20
|
+
# See http://distribustream.org/
|
21
|
+
#++
|
22
|
+
|
23
|
+
module PDTP
|
24
|
+
class Server
|
25
|
+
# Helpers to be called from the DistribuStream status page ERb
|
26
|
+
module StatusHelper
|
27
|
+
# Number of clients presently connected
|
28
|
+
def client_count
|
29
|
+
clients = @dispatcher.connections.size - 1
|
30
|
+
clients == 1 ? "1 client" : "#{clients} clients"
|
31
|
+
end
|
32
|
+
|
33
|
+
# Server's virtual host name
|
34
|
+
def vhost
|
35
|
+
@vhost
|
36
|
+
end
|
37
|
+
|
38
|
+
# Iterate over all connected peers
|
39
|
+
def each_peer(&block)
|
40
|
+
@dispatcher.connections.each(&block)
|
41
|
+
end
|
42
|
+
|
43
|
+
# Iterate over all of a peer's active transfers
|
44
|
+
def each_transfer(peer)
|
45
|
+
raise ArgumentError, "no block given" unless block_given?
|
46
|
+
@dispatcher.client_info(peer).transfers.each { |_, transfer| yield transfer }
|
47
|
+
end
|
48
|
+
|
49
|
+
# Iterate over all of a peer's active files
|
50
|
+
def each_file(peer, &block)
|
51
|
+
@dispatcher.client_info(peer).chunk_info.get_file_stats.each(&block)
|
52
|
+
end
|
53
|
+
|
54
|
+
# Name of a peer (client ID or file service)
|
55
|
+
def peer_name(peer)
|
56
|
+
if peer.file_service?
|
57
|
+
"<b>File Service</b>"
|
58
|
+
else
|
59
|
+
@dispatcher.connection_name(peer)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# IP address and port of a peer
|
64
|
+
def peer_address(peer)
|
65
|
+
host, port = peer.get_peer_info
|
66
|
+
"#{host}:#{port}"
|
67
|
+
end
|
68
|
+
|
69
|
+
# Information about an active transfer
|
70
|
+
def transfer_info(peer, transfer)
|
71
|
+
"#{peer == transfer.giver ? 'UP' : 'DOWN'}: id=#{transfer.transfer_id.split('$')[2..3].join(':')}"
|
72
|
+
end
|
73
|
+
|
74
|
+
# Path to a file
|
75
|
+
def file_path(file)
|
76
|
+
file.url.sub(/.+?:\/\/.+?\//, '/')
|
77
|
+
end
|
78
|
+
|
79
|
+
# Number of requested chunks that have been completed
|
80
|
+
def chunks_completed(file)
|
81
|
+
file.chunks_provided
|
82
|
+
end
|
83
|
+
|
84
|
+
# Number of requested or completed chunks
|
85
|
+
def chunks_active(file)
|
86
|
+
file.file_chunks
|
87
|
+
end
|
88
|
+
|
89
|
+
# Percent of a file that has been transferred
|
90
|
+
def percent_complete(file)
|
91
|
+
(chunks_completed(file).to_f / chunks_active(file) * 100).to_i
|
92
|
+
end
|
93
|
+
|
94
|
+
#
|
95
|
+
# Cycle code excerpted from ActionPack and released under the MIT license
|
96
|
+
# Copyright (c) 2004-2006 David Heinemeier Hansson
|
97
|
+
#
|
98
|
+
|
99
|
+
def cycle(first_value, *values)
|
100
|
+
if (values.last.instance_of? Hash)
|
101
|
+
params = values.pop
|
102
|
+
name = params[:name]
|
103
|
+
else
|
104
|
+
name = "default"
|
105
|
+
end
|
106
|
+
values.unshift(first_value)
|
107
|
+
|
108
|
+
cycle = get_cycle(name)
|
109
|
+
if (cycle.nil? || cycle.values != values)
|
110
|
+
cycle = set_cycle(name, Cycle.new(*values))
|
111
|
+
end
|
112
|
+
return cycle.to_s
|
113
|
+
end
|
114
|
+
|
115
|
+
def reset_cycle(name = "default")
|
116
|
+
cycle = get_cycle(name)
|
117
|
+
cycle.reset unless cycle.nil?
|
118
|
+
end
|
119
|
+
|
120
|
+
#######
|
121
|
+
private
|
122
|
+
#######
|
123
|
+
|
124
|
+
class Cycle #:nodoc:
|
125
|
+
attr_reader :values
|
126
|
+
|
127
|
+
def initialize(first_value, *values)
|
128
|
+
@values = values.unshift(first_value)
|
129
|
+
reset
|
130
|
+
end
|
131
|
+
|
132
|
+
def reset
|
133
|
+
@index = 0
|
134
|
+
end
|
135
|
+
|
136
|
+
def to_s
|
137
|
+
value = @values[@index].to_s
|
138
|
+
@index = (@index + 1) % @values.size
|
139
|
+
return value
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
|
144
|
+
def get_cycle(name)
|
145
|
+
@_cycles = Hash.new unless defined?(@_cycles)
|
146
|
+
return @_cycles[name]
|
147
|
+
end
|
148
|
+
|
149
|
+
def set_cycle(name, cycle_object)
|
150
|
+
@_cycles = Hash.new unless defined?(@_cycles)
|
151
|
+
@_cycles[name] = cycle_object
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
Binary file
|
data/status/index.erb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
2
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
3
|
+
<head>
|
4
|
+
<title>DistribuStream Status</title>
|
5
|
+
<link href="stylesheets/style.css" rel="stylesheet" type="text/css" />
|
6
|
+
</head>
|
7
|
+
<body>
|
8
|
+
<h1><img src="images/logo.png" alt="DistribuStream Status" /></h1>
|
9
|
+
<div id="server_info">
|
10
|
+
Host: <%= vhost %><br />
|
11
|
+
<%= client_count %>
|
12
|
+
</div>
|
13
|
+
<center>
|
14
|
+
<table border="0" cellpadding="0" cellspacing="0">
|
15
|
+
<tr><th>Client</th><th>Transfers</th><th>Files</th></tr>
|
16
|
+
<% each_peer do |peer| %>
|
17
|
+
<tr class="row<%= cycle(' row_alternate', '') %>"><td>
|
18
|
+
<%= peer_name(peer) %><br />
|
19
|
+
<%= peer_address(peer) %>
|
20
|
+
</td>
|
21
|
+
<td>
|
22
|
+
<% each_transfer(peer) do |transfer| %>
|
23
|
+
<%= transfer_info(peer, transfer) %><br />
|
24
|
+
<% end %>
|
25
|
+
</td>
|
26
|
+
<td>
|
27
|
+
<% each_file(peer) do |file| %>
|
28
|
+
<%= file_path(file) %>
|
29
|
+
(<%= chunks_completed(file) %>/<%= chunks_active(file) %>,
|
30
|
+
<%= percent_complete(file) %>%)<br />
|
31
|
+
<% end %>
|
32
|
+
</td></tr>
|
33
|
+
<% end %>
|
34
|
+
</table>
|
35
|
+
</center>
|
36
|
+
<hr />
|
37
|
+
<div id="footer">
|
38
|
+
<%= vhost %> -
|
39
|
+
<a href="http://distribustream.org/">DistribuStream</a> <%= PDTP::VERSION %>
|
40
|
+
©2006-07 <a href="http://www.clickcaster.com/">ClickCaster, Inc.</a><br />
|
41
|
+
<%= Time.now %>
|
42
|
+
</div>
|
43
|
+
</body>
|
44
|
+
</html>
|
@@ -0,0 +1,42 @@
|
|
1
|
+
* {
|
2
|
+
margin: 0;
|
3
|
+
padding: 0;
|
4
|
+
}
|
5
|
+
|
6
|
+
html, body {
|
7
|
+
font-family: Verdana, Helvetica, Arial, sans-serif;
|
8
|
+
font-size: 12px;
|
9
|
+
color: black;
|
10
|
+
background: white;
|
11
|
+
padding: 0.5em;
|
12
|
+
}
|
13
|
+
|
14
|
+
hr {
|
15
|
+
margin: 0.5em;
|
16
|
+
}
|
17
|
+
|
18
|
+
th {
|
19
|
+
text-align: left;
|
20
|
+
font-size: 1.2em;
|
21
|
+
padding: 0.2em 1em;
|
22
|
+
}
|
23
|
+
|
24
|
+
td {
|
25
|
+
text-align: left;
|
26
|
+
padding: 0.5em;
|
27
|
+
}
|
28
|
+
|
29
|
+
#server_info {
|
30
|
+
position: absolute;
|
31
|
+
top: 1em;
|
32
|
+
right: 1em;
|
33
|
+
font-size: 1.2em;
|
34
|
+
}
|
35
|
+
|
36
|
+
#footer {
|
37
|
+
font-style: italic;
|
38
|
+
}
|
39
|
+
|
40
|
+
.row_alternate {
|
41
|
+
background: #EEEEEE;
|
42
|
+
}
|
metadata
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
|
-
rubygems_version: 0.9.
|
2
|
+
rubygems_version: 0.9.0
|
3
3
|
specification_version: 1
|
4
4
|
name: distribustream
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.4.
|
6
|
+
version: 0.4.1
|
7
7
|
date: 2008-11-15 00:00:00 -07:00
|
8
8
|
summary: DistribuStream is a fully open peercasting system allowing on-demand or live streaming media to be delivered at a fraction of the normal cost
|
9
9
|
require_paths:
|
@@ -33,37 +33,43 @@ authors:
|
|
33
33
|
- James Sanders
|
34
34
|
- Tom Stapleton
|
35
35
|
files:
|
36
|
-
- bin/dsclient
|
37
36
|
- bin/dstream
|
37
|
+
- bin/dsclient
|
38
38
|
- lib/pdtp
|
39
|
+
- lib/pdtp/server
|
40
|
+
- lib/pdtp/common.rb
|
39
41
|
- lib/pdtp/client
|
40
|
-
- lib/pdtp/
|
41
|
-
- lib/pdtp/client
|
42
|
+
- lib/pdtp/common
|
43
|
+
- lib/pdtp/client.rb
|
44
|
+
- lib/pdtp/server.rb
|
45
|
+
- lib/pdtp/server/file_service_protocol.rb
|
46
|
+
- lib/pdtp/server/status_handler.rb
|
47
|
+
- lib/pdtp/server/trust.rb
|
48
|
+
- lib/pdtp/server/status_helper.rb
|
49
|
+
- lib/pdtp/server/transfer.rb
|
50
|
+
- lib/pdtp/server/client_info.rb
|
51
|
+
- lib/pdtp/server/connection.rb
|
52
|
+
- lib/pdtp/server/file_service.rb
|
53
|
+
- lib/pdtp/server/dispatcher.rb
|
42
54
|
- lib/pdtp/client/file_buffer.rb
|
43
|
-
- lib/pdtp/client/file_service.rb
|
44
55
|
- lib/pdtp/client/http_client.rb
|
45
56
|
- lib/pdtp/client/http_handler.rb
|
57
|
+
- lib/pdtp/client/callbacks.rb
|
46
58
|
- lib/pdtp/client/transfer.rb
|
47
|
-
- lib/pdtp/client.rb
|
48
|
-
- lib/pdtp/
|
49
|
-
- lib/pdtp/common/file_service.rb
|
50
|
-
- lib/pdtp/common/http_server.rb
|
59
|
+
- lib/pdtp/client/connection.rb
|
60
|
+
- lib/pdtp/client/file_service.rb
|
51
61
|
- lib/pdtp/common/length_prefix_protocol.rb
|
62
|
+
- lib/pdtp/common/http_server.rb
|
52
63
|
- lib/pdtp/common/protocol.rb
|
53
|
-
- lib/pdtp/common.rb
|
54
|
-
-
|
55
|
-
- lib/pdtp/server/client_info.rb
|
56
|
-
- lib/pdtp/server/connection.rb
|
57
|
-
- lib/pdtp/server/dispatcher.rb
|
58
|
-
- lib/pdtp/server/file_service.rb
|
59
|
-
- lib/pdtp/server/file_service_protocol.rb
|
60
|
-
- lib/pdtp/server/status_handler.rb
|
61
|
-
- lib/pdtp/server/transfer.rb
|
62
|
-
- lib/pdtp/server/trust.rb
|
63
|
-
- lib/pdtp/server.rb
|
64
|
+
- lib/pdtp/common/file_service.rb
|
65
|
+
- conf/example.yml
|
64
66
|
- conf/bigchunk.yml
|
65
67
|
- conf/debug.yml
|
66
|
-
-
|
68
|
+
- status/stylesheets
|
69
|
+
- status/images
|
70
|
+
- status/index.erb
|
71
|
+
- status/stylesheets/style.css
|
72
|
+
- status/images/logo.png
|
67
73
|
- Rakefile
|
68
74
|
- distribustream.gemspec
|
69
75
|
- COPYING
|