distribustream 0.4.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|