Compare commits
20 Commits
master
...
deluge-0.5
Author | SHA1 | Date | |
---|---|---|---|
da0dd8a4a9 | |||
d182928f8c | |||
0f680b43e3 | |||
7bb59d19d8 | |||
eba7d24550 | |||
59116daf71 | |||
2b1a4a8a8e | |||
fd2a3a5607 | |||
1e541a5b43 | |||
7e74457fac | |||
4c2388499b | |||
804b534009 | |||
d8681a0593 | |||
edb20e0c05 | |||
3fb3bd9233 | |||
8dfb4b73eb | |||
3ea3b6b5b0 | |||
733ce63553 | |||
715e3ce463 | |||
8730830470 |
@ -1,10 +1,14 @@
|
||||
Deluge 0.5.7 (xx November 2007)
|
||||
Deluge 0.5.7 (27 November 2007)
|
||||
* Scrape support
|
||||
* Manual force-recheck
|
||||
* Add local peer discovery (aka local service discovery)
|
||||
* Blocklist plugin will now display errors, instead of just crashing on a bad
|
||||
list or wrong type
|
||||
* Add torrent in paused state option
|
||||
* Add advanced progress bar
|
||||
* Fix bug in merging trackers
|
||||
* Various updates to WebUI, including https support and advanced template by vonck7
|
||||
* Add maximum connection attempts per second preference
|
||||
* Fix bug where loaded plugins were forgotten if Deluge crashed
|
||||
* Fix ratio bugs (hopefully for the last time)
|
||||
* Add preference to only show file selection popup if torrent has multiple files
|
||||
@ -18,6 +22,9 @@ Deluge 0.5.7 (xx November 2007)
|
||||
* Add preference for the location of torrent files
|
||||
* Add autoload folder
|
||||
* Copy translator credits from Launchpad to our about->credits
|
||||
* Differentiate between queued and paused torrents. Able to pause queued
|
||||
torrents - patch by yobbobandana
|
||||
* Show error when writing/permission problems occur
|
||||
|
||||
Deluge 0.5.6.2 (31 October 2007)
|
||||
* Set default piece size to 256-KiB in TorrentCreator plugin and add 2048KiB
|
||||
|
1
README
1
README
@ -35,6 +35,7 @@ python-all version >= 2.4
|
||||
python-dbus
|
||||
python-gtk2 version >= 2.9
|
||||
python-notify
|
||||
python-pyopenssl
|
||||
librsvg2-common
|
||||
python-xdg
|
||||
python-support
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -122,7 +122,7 @@
|
||||
<child>
|
||||
<widget class="GtkButton" id="button2">
|
||||
<property name="visible">True</property>
|
||||
<property name="label">gtk-no</property>
|
||||
<property name="label" translatable="no">gtk-no</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="response_id">0</property>
|
||||
</widget>
|
||||
@ -130,7 +130,7 @@
|
||||
<child>
|
||||
<widget class="GtkButton" id="button1">
|
||||
<property name="visible">True</property>
|
||||
<property name="label">gtk-yes</property>
|
||||
<property name="label" translatable="no">gtk-yes</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="response_id">1</property>
|
||||
</widget>
|
||||
@ -197,7 +197,7 @@
|
||||
<child>
|
||||
<widget class="GtkImageMenuItem" id="menuitem12">
|
||||
<property name="visible">True</property>
|
||||
<property name="label">gtk-preferences</property>
|
||||
<property name="label" translatable="no">gtk-preferences</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal name="activate" handler="preferences"/>
|
||||
@ -227,7 +227,7 @@
|
||||
<child>
|
||||
<widget class="GtkImageMenuItem" id="menuitem14">
|
||||
<property name="visible">True</property>
|
||||
<property name="label">gtk-quit</property>
|
||||
<property name="label" translatable="no">gtk-quit</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal name="activate" handler="quit"/>
|
||||
@ -299,7 +299,7 @@
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label">gtk-cancel</property>
|
||||
<property name="label" translatable="no">gtk-cancel</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="response_id">0</property>
|
||||
</widget>
|
||||
@ -310,7 +310,7 @@
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label">gtk-ok</property>
|
||||
<property name="label" translatable="no">gtk-ok</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="response_id">1</property>
|
||||
</widget>
|
||||
|
@ -64,7 +64,7 @@
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label">gtk-cancel</property>
|
||||
<property name="label" translatable="no">gtk-cancel</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="response_id">0</property>
|
||||
<signal name="clicked" handler="cancel_button_clicked"/>
|
||||
@ -81,7 +81,7 @@
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label">gtk-ok</property>
|
||||
<property name="label" translatable="no">gtk-ok</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="response_id">0</property>
|
||||
<signal name="clicked" handler="ok_button_clicked"/>
|
||||
|
@ -57,7 +57,7 @@
|
||||
<child>
|
||||
<widget class="GtkButton" id="button2">
|
||||
<property name="visible">True</property>
|
||||
<property name="label">gtk-cancel</property>
|
||||
<property name="label" translatable="no">gtk-cancel</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="response_id">0</property>
|
||||
</widget>
|
||||
@ -65,7 +65,7 @@
|
||||
<child>
|
||||
<widget class="GtkButton" id="button1">
|
||||
<property name="visible">True</property>
|
||||
<property name="label">gtk-ok</property>
|
||||
<property name="label" translatable="no">gtk-ok</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="response_id">1</property>
|
||||
</widget>
|
||||
|
@ -31,7 +31,7 @@
|
||||
<child>
|
||||
<widget class="GtkButton" id="button_cancel">
|
||||
<property name="visible">True</property>
|
||||
<property name="label">gtk-cancel</property>
|
||||
<property name="label" translatable="no">gtk-cancel</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="response_id">0</property>
|
||||
</widget>
|
||||
@ -39,7 +39,7 @@
|
||||
<child>
|
||||
<widget class="GtkButton" id="button_ok">
|
||||
<property name="visible">True</property>
|
||||
<property name="label">gtk-ok</property>
|
||||
<property name="label" translatable="no">gtk-ok</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="response_id">1</property>
|
||||
</widget>
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -41,10 +41,10 @@ namespace error
|
||||
system_category = ASIO_WIN_OR_POSIX(0, 0),
|
||||
|
||||
/// Error codes from NetDB functions.
|
||||
netdb_category = ASIO_WIN_OR_POSIX(_system_category, 1),
|
||||
netdb_category = ASIO_WIN_OR_POSIX(system_category, 1),
|
||||
|
||||
/// Error codes from getaddrinfo.
|
||||
addrinfo_category = ASIO_WIN_OR_POSIX(_system_category, 2),
|
||||
addrinfo_category = ASIO_WIN_OR_POSIX(system_category, 2),
|
||||
|
||||
/// Miscellaneous error codes.
|
||||
misc_category = ASIO_WIN_OR_POSIX(3, 3),
|
||||
|
@ -473,7 +473,7 @@ namespace libtorrent
|
||||
// we might need more than one listen socket
|
||||
std::list<listen_socket_t> m_listen_sockets;
|
||||
|
||||
listen_socket_t setup_listener(tcp::endpoint ep, int retries);
|
||||
listen_socket_t setup_listener(tcp::endpoint ep, int retries, bool v6_only = false);
|
||||
|
||||
// the settings for the client
|
||||
session_settings m_settings;
|
||||
|
@ -171,6 +171,21 @@ namespace libtorrent
|
||||
return Endpoint(addr, port);
|
||||
}
|
||||
}
|
||||
|
||||
struct v6only
|
||||
{
|
||||
v6only(bool enable): m_value(enable) {}
|
||||
template<class Protocol>
|
||||
int level(Protocol const&) const { return IPPROTO_IPV6; }
|
||||
template<class Protocol>
|
||||
int name(Protocol const&) const { return IPV6_V6ONLY; }
|
||||
template<class Protocol>
|
||||
int const* data(Protocol const&) const { return &m_value; }
|
||||
template<class Protocol>
|
||||
size_t size(Protocol const&) const { return sizeof(m_value); }
|
||||
int m_value;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // TORRENT_SOCKET_HPP_INCLUDED
|
||||
|
@ -273,6 +273,9 @@ namespace libtorrent { namespace dht
|
||||
udp::endpoint ep(listen_interface, listen_port);
|
||||
m_socket.open(ep.protocol());
|
||||
m_socket.bind(ep);
|
||||
m_socket.async_receive_from(asio::buffer(&m_in_buf[m_buffer][0]
|
||||
, m_in_buf[m_buffer].size()), m_remote_endpoint[m_buffer]
|
||||
, m_strand.wrap(bind(&dht_tracker::on_receive, self(), _1, _2)));
|
||||
}
|
||||
|
||||
void dht_tracker::tick(asio::error_code const& e)
|
||||
|
@ -814,13 +814,15 @@ namespace detail
|
||||
return m_ipv6_interface;
|
||||
}
|
||||
|
||||
session_impl::listen_socket_t session_impl::setup_listener(tcp::endpoint ep, int retries)
|
||||
session_impl::listen_socket_t session_impl::setup_listener(tcp::endpoint ep
|
||||
, int retries, bool v6_only)
|
||||
{
|
||||
asio::error_code ec;
|
||||
listen_socket_t s;
|
||||
s.sock.reset(new socket_acceptor(m_io_service));
|
||||
s.sock->open(ep.protocol(), ec);
|
||||
s.sock->set_option(socket_acceptor::reuse_address(true), ec);
|
||||
if (ep.protocol() == tcp::v6()) s.sock->set_option(v6only(v6_only), ec);
|
||||
s.sock->bind(ep, ec);
|
||||
while (ec && retries > 0)
|
||||
{
|
||||
@ -913,7 +915,7 @@ namespace detail
|
||||
|
||||
s = setup_listener(
|
||||
tcp::endpoint(address_v6::any(), m_listen_interface.port())
|
||||
, m_listen_port_retries);
|
||||
, m_listen_port_retries, true);
|
||||
|
||||
if (s.sock)
|
||||
{
|
||||
@ -2279,6 +2281,8 @@ namespace detail
|
||||
|
||||
INVARIANT_CHECK;
|
||||
|
||||
if (m_lsd) return;
|
||||
|
||||
m_lsd = new lsd(m_io_service
|
||||
, m_listen_interface.address()
|
||||
, bind(&session_impl::on_lsd_peer, this, _1, _2));
|
||||
@ -2290,6 +2294,8 @@ namespace detail
|
||||
|
||||
INVARIANT_CHECK;
|
||||
|
||||
if (m_natpmp) return;
|
||||
|
||||
m_natpmp = new natpmp(m_io_service
|
||||
, m_listen_interface.address()
|
||||
, bind(&session_impl::on_port_mapping
|
||||
@ -2308,6 +2314,8 @@ namespace detail
|
||||
|
||||
INVARIANT_CHECK;
|
||||
|
||||
if (m_upnp) return;
|
||||
|
||||
m_upnp = new upnp(m_io_service, m_half_open
|
||||
, m_listen_interface.address()
|
||||
, m_settings.user_agent
|
||||
|
@ -43,7 +43,8 @@ namespace libtorrent
|
||||
if (e)
|
||||
{
|
||||
(*h)(e);
|
||||
close();
|
||||
asio::error_code ec;
|
||||
close(ec);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -54,8 +55,8 @@ namespace libtorrent
|
||||
if (i == tcp::resolver::iterator())
|
||||
{
|
||||
asio::error_code ec = asio::error::operation_not_supported;
|
||||
(*h)(e);
|
||||
close();
|
||||
(*h)(ec);
|
||||
close(ec);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -68,7 +69,8 @@ namespace libtorrent
|
||||
if (e)
|
||||
{
|
||||
(*h)(e);
|
||||
close();
|
||||
asio::error_code ec;
|
||||
close(ec);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -93,7 +95,8 @@ namespace libtorrent
|
||||
if (e)
|
||||
{
|
||||
(*h)(e);
|
||||
close();
|
||||
asio::error_code ec;
|
||||
close(ec);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -107,7 +110,8 @@ namespace libtorrent
|
||||
if (e)
|
||||
{
|
||||
(*h)(e);
|
||||
close();
|
||||
asio::error_code ec;
|
||||
close(ec);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -119,8 +123,9 @@ namespace libtorrent
|
||||
|
||||
if (reply_version != 0)
|
||||
{
|
||||
(*h)(asio::error::operation_not_supported);
|
||||
close();
|
||||
asio::error_code ec = asio::error::operation_not_supported;
|
||||
(*h)(ec);
|
||||
close(ec);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -140,7 +145,7 @@ namespace libtorrent
|
||||
case 93: ec = asio::error::no_permission; break;
|
||||
}
|
||||
(*h)(ec);
|
||||
close();
|
||||
close(ec);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -44,7 +44,8 @@ namespace libtorrent
|
||||
if (e || i == tcp::resolver::iterator())
|
||||
{
|
||||
(*h)(e);
|
||||
close();
|
||||
asio::error_code ec;
|
||||
close(ec);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -57,7 +58,8 @@ namespace libtorrent
|
||||
if (e)
|
||||
{
|
||||
(*h)(e);
|
||||
close();
|
||||
asio::error_code ec;
|
||||
close(ec);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -86,7 +88,8 @@ namespace libtorrent
|
||||
if (e)
|
||||
{
|
||||
(*h)(e);
|
||||
close();
|
||||
asio::error_code ec;
|
||||
close(ec);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -100,7 +103,8 @@ namespace libtorrent
|
||||
if (e)
|
||||
{
|
||||
(*h)(e);
|
||||
close();
|
||||
asio::error_code ec;
|
||||
close(ec);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -113,7 +117,8 @@ namespace libtorrent
|
||||
if (version < 5)
|
||||
{
|
||||
(*h)(asio::error::operation_not_supported);
|
||||
close();
|
||||
asio::error_code ec;
|
||||
close(ec);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -126,7 +131,8 @@ namespace libtorrent
|
||||
if (m_user.empty())
|
||||
{
|
||||
(*h)(asio::error::operation_not_supported);
|
||||
close();
|
||||
asio::error_code ec;
|
||||
close(ec);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -144,7 +150,8 @@ namespace libtorrent
|
||||
else
|
||||
{
|
||||
(*h)(asio::error::operation_not_supported);
|
||||
close();
|
||||
asio::error_code ec;
|
||||
close(ec);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -155,7 +162,8 @@ namespace libtorrent
|
||||
if (e)
|
||||
{
|
||||
(*h)(e);
|
||||
close();
|
||||
asio::error_code ec;
|
||||
close(ec);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -170,7 +178,8 @@ namespace libtorrent
|
||||
if (e)
|
||||
{
|
||||
(*h)(e);
|
||||
close();
|
||||
asio::error_code ec;
|
||||
close(ec);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -183,14 +192,16 @@ namespace libtorrent
|
||||
if (version != 1)
|
||||
{
|
||||
(*h)(asio::error::operation_not_supported);
|
||||
close();
|
||||
asio::error_code ec;
|
||||
close(ec);
|
||||
return;
|
||||
}
|
||||
|
||||
if (status != 0)
|
||||
{
|
||||
(*h)(asio::error::operation_not_supported);
|
||||
close();
|
||||
asio::error_code ec;
|
||||
close(ec);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -222,7 +233,8 @@ namespace libtorrent
|
||||
if (e)
|
||||
{
|
||||
(*h)(e);
|
||||
close();
|
||||
asio::error_code ec;
|
||||
close(ec);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -236,7 +248,8 @@ namespace libtorrent
|
||||
if (e)
|
||||
{
|
||||
(*h)(e);
|
||||
close();
|
||||
asio::error_code ec;
|
||||
close(ec);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -248,7 +261,8 @@ namespace libtorrent
|
||||
if (version < 5)
|
||||
{
|
||||
(*h)(asio::error::operation_not_supported);
|
||||
close();
|
||||
asio::error_code ec;
|
||||
close(ec);
|
||||
return;
|
||||
}
|
||||
int response = read_uint8(p);
|
||||
@ -267,7 +281,8 @@ namespace libtorrent
|
||||
case 8: e = asio::error::address_family_not_supported; break;
|
||||
}
|
||||
(*h)(e);
|
||||
close();
|
||||
asio::error_code ec;
|
||||
close(ec);
|
||||
return;
|
||||
}
|
||||
p += 1; // reserved
|
||||
@ -291,7 +306,8 @@ namespace libtorrent
|
||||
else
|
||||
{
|
||||
(*h)(asio::error::operation_not_supported);
|
||||
close();
|
||||
asio::error_code ec;
|
||||
close(ec);
|
||||
return;
|
||||
}
|
||||
m_buffer.resize(skip_bytes);
|
||||
@ -305,7 +321,8 @@ namespace libtorrent
|
||||
if (e)
|
||||
{
|
||||
(*h)(e);
|
||||
close();
|
||||
asio::error_code ec;
|
||||
close(ec);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -287,6 +287,9 @@ namespace libtorrent
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
bool torrent::should_announce_dht() const
|
||||
{
|
||||
if (m_ses.m_listen_sockets.empty()) return false;
|
||||
|
||||
if (!m_ses.m_dht) return false;
|
||||
// don't announce private torrents
|
||||
if (m_torrent_file->is_valid() && m_torrent_file->priv()) return false;
|
||||
|
||||
@ -434,7 +437,8 @@ namespace libtorrent
|
||||
bind(&torrent::on_announce_disp, self, _1)));
|
||||
|
||||
// announce with the local discovery service
|
||||
m_ses.announce_lsd(m_torrent_file->info_hash());
|
||||
if (!m_paused)
|
||||
m_ses.announce_lsd(m_torrent_file->info_hash());
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -444,13 +448,12 @@ namespace libtorrent
|
||||
}
|
||||
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
if (m_paused) return;
|
||||
if (!m_ses.m_dht) return;
|
||||
ptime now = time_now();
|
||||
if (should_announce_dht() && now - m_last_dht_announce > minutes(14))
|
||||
{
|
||||
m_last_dht_announce = now;
|
||||
// TODO: There should be a way to abort an announce operation on the dht.
|
||||
// when the torrent is destructed
|
||||
if (m_ses.m_listen_sockets.empty()) return;
|
||||
m_ses.m_dht->announce(m_torrent_file->info_hash()
|
||||
, m_ses.m_listen_sockets.front().external_port
|
||||
@ -2250,15 +2253,15 @@ namespace libtorrent
|
||||
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
// only start the announce if we want to announce with the dht
|
||||
if (should_announce_dht())
|
||||
ptime now = time_now();
|
||||
if (should_announce_dht() && now - m_last_dht_announce > minutes(14))
|
||||
{
|
||||
if (m_abort) return;
|
||||
// force the DHT to reannounce
|
||||
m_last_dht_announce = time_now() - minutes(15);
|
||||
m_last_dht_announce = now;
|
||||
boost::weak_ptr<torrent> self(shared_from_this());
|
||||
m_announce_timer.expires_from_now(seconds(1));
|
||||
m_announce_timer.async_wait(m_ses.m_strand.wrap(
|
||||
bind(&torrent::on_announce_disp, self, _1)));
|
||||
m_ses.m_dht->announce(m_torrent_file->info_hash()
|
||||
, m_ses.m_listen_sockets.front().external_port
|
||||
, m_ses.m_strand.wrap(bind(&torrent::on_dht_announce_response_disp, self, _1)));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -306,10 +306,12 @@ namespace libtorrent
|
||||
|
||||
namespace
|
||||
{
|
||||
bool range_contains(peer_request const& range, peer_request const& req)
|
||||
bool range_contains(peer_request const& range, peer_request const& req, int piece_size)
|
||||
{
|
||||
return range.start <= req.start
|
||||
&& range.start + range.length >= req.start + req.length;
|
||||
size_type range_start = size_type(range.piece) * piece_size + range.start;
|
||||
size_type req_start = size_type(req.piece) * piece_size + req.start;
|
||||
return range_start <= req_start
|
||||
&& range_start + range.length >= req_start + req.length;
|
||||
}
|
||||
}
|
||||
|
||||
@ -470,6 +472,9 @@ namespace libtorrent
|
||||
}
|
||||
}
|
||||
|
||||
// std::cerr << "REQUESTS: m_requests: " << m_requests.size()
|
||||
// << " file_requests: " << m_file_requests.size() << std::endl;
|
||||
|
||||
torrent_info const& info = t->torrent_file();
|
||||
|
||||
if (m_requests.empty() || m_file_requests.empty())
|
||||
@ -480,16 +485,16 @@ namespace libtorrent
|
||||
, range_end - range_start);
|
||||
|
||||
peer_request front_request = m_requests.front();
|
||||
|
||||
/*
|
||||
size_type rs = size_type(in_range.piece) * info.piece_length() + in_range.start;
|
||||
size_type re = rs + in_range.length;
|
||||
size_type fs = size_type(front_request.piece) * info.piece_length() + front_request.start;
|
||||
size_type fe = fs + front_request.length;
|
||||
if (fs < rs || fe > re)
|
||||
{
|
||||
throw std::runtime_error("invalid range in HTTP response");
|
||||
}
|
||||
|
||||
std::cerr << "RANGE: r = (" << rs << ", " << re << " ) "
|
||||
"f = (" << fs << ", " << fe << ") "
|
||||
"file_index = " << file_index << " received_body = " << m_received_body << std::endl;
|
||||
*/
|
||||
// skip the http header and the blocks we've already read. The
|
||||
// http_body.begin is now in sync with the request at the front
|
||||
// of the request queue
|
||||
@ -504,11 +509,16 @@ namespace libtorrent
|
||||
bool range_overlaps_request = in_range.start + in_range.length
|
||||
> front_request.start + int(m_piece.size());
|
||||
|
||||
if (!range_overlaps_request)
|
||||
{
|
||||
throw std::runtime_error("invalid range in HTTP response");
|
||||
}
|
||||
|
||||
// if the request is contained in the range (i.e. the entire request
|
||||
// fits in the range) we should not start a partial piece, since we soon
|
||||
// will receive enough to call incoming_piece() and pass the read buffer
|
||||
// directly (in the next loop below).
|
||||
if (range_overlaps_request && !range_contains(in_range, front_request))
|
||||
if (range_overlaps_request && !range_contains(in_range, front_request, info.piece_length()))
|
||||
{
|
||||
// the start of the next block to receive is stored
|
||||
// in m_piece. We need to append the rest of that
|
||||
@ -549,7 +559,7 @@ namespace libtorrent
|
||||
|
||||
// report all received blocks to the bittorrent engine
|
||||
while (!m_requests.empty()
|
||||
&& range_contains(in_range, m_requests.front())
|
||||
&& range_contains(in_range, m_requests.front(), info.piece_length())
|
||||
&& recv_buffer.left() >= m_requests.front().length)
|
||||
{
|
||||
peer_request r = m_requests.front();
|
||||
|
@ -96,12 +96,7 @@ class movetorrentMenu:
|
||||
if path:
|
||||
self.paused_or_not = {}
|
||||
for unique_id in unique_ids:
|
||||
self.paused_or_not[unique_id] = self.core.is_user_paused(unique_id)
|
||||
if not self.paused_or_not[unique_id]:
|
||||
self.core.set_user_pause(unique_id, True, enforce_queue=False)
|
||||
self.core.move_storage(unique_id, path)
|
||||
if not self.paused_or_not[unique_id]:
|
||||
self.core.set_user_pause(unique_id, False, enforce_queue=False)
|
||||
|
||||
def configure(self, window):
|
||||
import os.path
|
||||
|
@ -63,7 +63,7 @@ class plugin_Search:
|
||||
### Note: All other plugins should use self.interface.toolbar
|
||||
### when adding items to the toolbar
|
||||
self.se = ''
|
||||
self.toolbar = self.interface.wtree.get_widget("tb_right")
|
||||
self.toolbar = self.interface.wtree.get_widget("tb_left")
|
||||
self.engines = deluge.pref.Preferences(self.conf_file, False)
|
||||
self.search_entry = gtk.Entry()
|
||||
self.search_entry.connect("activate", self.torrent_search)
|
||||
|
@ -75,6 +75,5 @@ class webseedMenu:
|
||||
self.dialog.hide()
|
||||
if response:
|
||||
text = self.glade.get_widget("txt_url").get_text().strip()
|
||||
if common.is_url(text):
|
||||
if deluge.common.is_url(text):
|
||||
self.core.add_url_seed(self.unique_ID, text)
|
||||
|
||||
|
@ -37,7 +37,9 @@ Firefox greasemonkey script: http://userscripts.org/scripts/show/12639
|
||||
|
||||
Remotely add a file: "curl -F torrent=@./test1.torrent -F pwd=deluge http://localhost:8112/remote/torrent/add"
|
||||
|
||||
There is support for multiple templates, but just one is included.
|
||||
Advanced template is only tested on firefox and garanteed not to work in IE6
|
||||
|
||||
ssl keys are located in WebUi/ssl/
|
||||
|
||||
Other contributors:
|
||||
*somedude : template enhancements.
|
||||
@ -203,11 +205,8 @@ class ConfigDialog(gtk.Dialog):
|
||||
gtk.combo_box_new_text())
|
||||
self.cache_templates = self.add_widget(_('Cache Templates'),
|
||||
gtk.CheckButton())
|
||||
"""
|
||||
temporary disable for 0.5.7
|
||||
self.use_https = self.add_widget(_('Use https://'),
|
||||
self.use_https = self.add_widget(_('https://'),
|
||||
gtk.CheckButton())
|
||||
"""
|
||||
|
||||
#self.share_downloads = self.add_widget(_('Share Download Directory'),
|
||||
# gtk.CheckButton())
|
||||
@ -236,7 +235,7 @@ class ConfigDialog(gtk.Dialog):
|
||||
# bool(self.config.get("share_downloads")))
|
||||
|
||||
self.cache_templates.set_active(self.config.get("cache_templates"))
|
||||
"""0.5.7.. self.use_https.set_active(self.config.get("use_https"))"""
|
||||
self.use_https.set_active(self.config.get("use_https"))
|
||||
|
||||
self.vbox.pack_start(self.vb, True, True, 0)
|
||||
self.vb.show_all()
|
||||
@ -272,7 +271,7 @@ class ConfigDialog(gtk.Dialog):
|
||||
self.config.set("template", self.template.get_active_text())
|
||||
self.config.set("button_style", self.button_style.get_active())
|
||||
self.config.set("cache_templates", self.cache_templates.get_active())
|
||||
#0.5.7.. self.config.set("use_https", self.use_https.get_active())
|
||||
self.config.set("use_https", self.use_https.get_active())
|
||||
#self.config.set("share_downloads", self.share_downloads.get_active())
|
||||
self.config.save(self.plugin.config_file)
|
||||
self.plugin.start_server() #restarts server
|
||||
|
@ -50,7 +50,7 @@ urls = (
|
||||
"/torrent/stop/(.*)", "torrent_stop",
|
||||
"/torrent/start/(.*)", "torrent_start",
|
||||
"/torrent/reannounce/(.*)", "torrent_reannounce",
|
||||
"/torrent/add", "torrent_add",
|
||||
"/torrent/add(.*)", "torrent_add",
|
||||
"/torrent/delete/(.*)", "torrent_delete",
|
||||
"/torrent/queue/up/(.*)", "torrent_queue_up",
|
||||
"/torrent/queue/down/(.*)", "torrent_queue_down",
|
||||
@ -98,21 +98,36 @@ class index:
|
||||
@deluge_page
|
||||
@auto_refreshed
|
||||
def GET(self, name):
|
||||
vars = web.input(sort=None, order=None)
|
||||
vars = web.input(sort=None, order=None ,filter=None , category=None)
|
||||
|
||||
status_rows = [get_torrent_status(torrent_id)
|
||||
torrent_list = [get_torrent_status(torrent_id)
|
||||
for torrent_id in ws.proxy.get_session_state()]
|
||||
all_torrents = torrent_list[:]
|
||||
|
||||
#filter-state
|
||||
if vars.filter:
|
||||
torrent_list = filter_torrent_state(torrent_list, vars.filter)
|
||||
setcookie("filter", vars.filter)
|
||||
else:
|
||||
setcookie("filter", "")
|
||||
|
||||
#filter-cat
|
||||
if vars.category:
|
||||
torrent_list = [t for t in torrent_list if t.category == vars.category]
|
||||
setcookie("category", vars.category)
|
||||
else:
|
||||
setcookie("category", "")
|
||||
|
||||
#sorting:
|
||||
if vars.sort:
|
||||
status_rows.sort(key=attrgetter(vars.sort))
|
||||
torrent_list.sort(key=attrgetter(vars.sort))
|
||||
if vars.order == 'up':
|
||||
status_rows = reversed(status_rows)
|
||||
torrent_list = reversed(torrent_list)
|
||||
|
||||
setcookie("order", vars.order)
|
||||
setcookie("sort", vars.sort)
|
||||
|
||||
return ws.render.index(status_rows)
|
||||
return ws.render.index(torrent_list, all_torrents)
|
||||
|
||||
class torrent_info:
|
||||
@deluge_page
|
||||
@ -162,16 +177,29 @@ class torrent_add:
|
||||
|
||||
@check_session
|
||||
def POST(self, name):
|
||||
vars = web.input(url = None, torrent = {})
|
||||
"""
|
||||
allows:
|
||||
*posting of url
|
||||
*posting file-upload
|
||||
*posting of data as string(for greasemonkey-private)
|
||||
"""
|
||||
|
||||
if vars.url and vars.torrent.filename:
|
||||
vars = web.input(url = None, torrent = {},
|
||||
torrent_name=None, torrent_data = None)
|
||||
|
||||
torrent_name = vars.torrent_name
|
||||
torrent_data = vars.torrent_data
|
||||
if vars.torrent.filename:
|
||||
torrent_name = vars.torrent.filename
|
||||
torrent_data = vars.torrent.file.read()
|
||||
|
||||
if vars.url and torrent_name:
|
||||
error_page(_("Choose an url or a torrent, not both."))
|
||||
if vars.url:
|
||||
ws.proxy.add_torrent_url(vars.url)
|
||||
do_redirect()
|
||||
elif vars.torrent.filename:
|
||||
data = vars.torrent.file.read()
|
||||
data_b64 = base64.b64encode(data)
|
||||
elif torrent_name:
|
||||
data_b64 = base64.b64encode(torrent_data)
|
||||
#b64 because of strange bug-reports related to binary data
|
||||
ws.proxy.add_torrent_filecontent(vars.torrent.filename, data_b64)
|
||||
do_redirect()
|
||||
@ -213,14 +241,24 @@ class torrent_delete:
|
||||
class torrent_queue_up:
|
||||
@check_session
|
||||
def POST(self, name):
|
||||
for torrent_id in sorted(name.split(',')):
|
||||
#a bit too verbose..
|
||||
torrent_ids = name.split(',')
|
||||
torrents = [get_torrent_status(id) for id in torrent_ids]
|
||||
torrents.sort(lambda x, y : x.queue_pos - y.queue_pos)
|
||||
torrent_ids = [t.id for t in torrents]
|
||||
for torrent_id in torrent_ids:
|
||||
ws.proxy.queue_up(torrent_id)
|
||||
do_redirect()
|
||||
|
||||
class torrent_queue_down:
|
||||
@check_session
|
||||
def POST(self, name):
|
||||
for torrent_id in reversed(sorted(name.split(','))):
|
||||
#a bit too verbose..
|
||||
torrent_ids = name.split(',')
|
||||
torrents = [get_torrent_status(id) for id in torrent_ids]
|
||||
torrents.sort(lambda x, y : x.queue_pos - y.queue_pos)
|
||||
torrent_ids = [t.id for t in torrents]
|
||||
for torrent_id in reversed(torrent_ids):
|
||||
ws.proxy.queue_down(torrent_id)
|
||||
do_redirect()
|
||||
|
||||
|
@ -1 +1 @@
|
||||
143
|
||||
160
|
||||
|
@ -1,13 +1,18 @@
|
||||
from __future__ import with_statement
|
||||
import os
|
||||
import re
|
||||
template_dir = '~/prj/WebUi/templates/deluge'
|
||||
template_dir = os.path.expanduser(template_dir )
|
||||
template_dirs = ['~/prj/WebUi/templates/deluge',
|
||||
'~/prj/WebUi/templates/advanced']
|
||||
|
||||
template_dirs = [os.path.expanduser(template_dir ) for template_dir in template_dirs]
|
||||
|
||||
|
||||
files = [os.path.join(template_dir,fname)
|
||||
for fname in os.listdir(template_dir)
|
||||
if fname.endswith('.html')]
|
||||
files = []
|
||||
for template_dir in template_dirs:
|
||||
files += [os.path.join(template_dir,fname)
|
||||
for fname in os.listdir(template_dir)
|
||||
if fname.endswith('.html')]
|
||||
|
||||
|
||||
all_strings = []
|
||||
for filename in files:
|
||||
|
@ -1,5 +1,6 @@
|
||||
_('# Of Files')
|
||||
_('About')
|
||||
_('Add')
|
||||
_('Add Torrent')
|
||||
_('Add torrent')
|
||||
_('Apply')
|
||||
@ -13,6 +14,7 @@ _('Delete .torrent file')
|
||||
_('Delete downloaded files.')
|
||||
_('Details')
|
||||
_('Disable')
|
||||
_('Down')
|
||||
_('Down Speed')
|
||||
_('Download')
|
||||
_('Downloaded')
|
||||
@ -27,19 +29,20 @@ _('Next Announce')
|
||||
_('Off')
|
||||
_('Password')
|
||||
_('Password is invalid,try again')
|
||||
_('Pause')
|
||||
_('Pause all')
|
||||
_('Peers')
|
||||
_('Pieces')
|
||||
_('Progress')
|
||||
_('Queue Down')
|
||||
_('Queue Position')
|
||||
_('Queue Up')
|
||||
_('Queue pos:')
|
||||
_('Ratio')
|
||||
_('Reannounce')
|
||||
_('Refresh page every:')
|
||||
_('Remove')
|
||||
_('Remove %s ')
|
||||
_('Remove %s?')
|
||||
_('Remove torrent')
|
||||
_('Resume')
|
||||
_('Resume all')
|
||||
_('Seeders')
|
||||
_('Set')
|
||||
@ -47,11 +50,13 @@ _('Set Timeout')
|
||||
_('Share Ratio')
|
||||
_('Size')
|
||||
_('Speed')
|
||||
_('Start')
|
||||
_('Submit')
|
||||
_('Torrent list')
|
||||
_('Total Size')
|
||||
_('Tracker')
|
||||
_('Tracker Status')
|
||||
_('Up')
|
||||
_('Up Speed')
|
||||
_('Upload')
|
||||
_('Upload torrent')
|
||||
|
27
plugins/WebUi/ssl/deluge.key
Normal file
27
plugins/WebUi/ssl/deluge.key
Normal file
@ -0,0 +1,27 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEogIBAAKCAQEA1sPXr1O6l2J9NAEvEYQ/JFDSVcJHh9YxP7kPdjsu7k9Ih845
|
||||
BHMX52A3Ypbe5MHe2bCj/8dRYCixRdF1KUTAKXdzc7mw9prgf3sS3RvmfcRsln6u
|
||||
x7XRg7YprZJ46hFmcHiUPRgtTFLuFO2YWBnqxu/caTtAxx3PdoK6LDVnuVjHYofC
|
||||
8uD4A9k6yL/jj3Yrkf8WYQqJ6pJcMAz/2c8ZXlBuiUCb9j5xKTzYoJaiUkKN2YrA
|
||||
hoxRxfI7Zc7MH2yWw8/fTZJbGXo8nrfek7coSE7yQS1M6ciwkYk5VO2mBVJBJgAT
|
||||
QUR/jGfLzEqNKXghQ564v9wmuFmUMd99a0tkVwIDAQABAoIBACID6sluLYOEqefu
|
||||
uBHCLG4IDwheOQ4esrYxDW3gedJs5EP+ObGmuQaAisUmuC7rNeysuYzteMoOJ+Wz
|
||||
AyeCKB1pOfP+WTT12tDWIWq73InW7ov3jJ89AO4nj/pZ1KTeFKeDsZbrmWEZUXQn
|
||||
HZX2pOTVYMeaBuyCoDVZBzuxSbhlON4wS6ClMhem+eBOxg351CDTZa2cbq7Ffcos
|
||||
VP7LY2ORQYNDTQSLguV/dJrFSotB8Eoz2xIpg5XR7msp6lzPzyAd+Aoz/T1lYxCY
|
||||
IFZCJYKnIpgoYQvmtUlhQrdD8P0J4Kth7I8NgkWvXCKazQjhpUm+wojLKD0G7Kcz
|
||||
9znIV+ECgYEA+qfp1C8jWbaAn1yAeORUA9aB6aGIURfOpZjnCvtMWM0Nu0nAJYDv
|
||||
X7L5GRa1ulfKhfUG1Jv/ynMKXYuBUDhyccYLpP7BHpd29Arr7YAgb52KaD1PoKNa
|
||||
Z45c61dj4sFoCmJEbDoL21UGb0LX3mc4XzPzwWs8AKfLW4aZh1NwCisCgYEA21gJ
|
||||
Hy3egBgMT9+nVjqsgtIXgJOnzQRhvRwT7IFf392ZyFi8iM+pDUsx1yj0zSG4XNPw
|
||||
NY8VtZuTBUlG73RKcrrz31jhCMfLCnoRkQeweZv0QWzbLU3V8DleUYdjFc/t0me5
|
||||
4NBR9lBlwYHgyU3GQ814vum+m0IAH0Ng1UxAVIUCgYAFOHwZTEYLN07kgtO2MOND
|
||||
FTOtfwzMy5clQdMGGofTjanMjdOvtEjIEH05tYxhbjSsp5bV1M32FIFRw3cVCafw
|
||||
kLRrYlb5YSQ8HwIc9z81s+1PEH/ZE63tXDy5Nh/BeE/Hb5aHPopCrjmtFZJTcojt
|
||||
CrL4A1jDlrsYk+wcsnMx8wKBgEhJJQhvd2pDgps4G8+hGoUqc7Bd+OjpzsQh4rcI
|
||||
k+4U+7847zkvJolJBK3hw3tu53FAL2OXOhJVqQgO9B+p9XcGAaTTh6X7IgDb5bok
|
||||
DJanPMHq+/hcNGssnNbFhXQEyF2U7X8XaEuCh2ZURR5SUUq7BlX0dmp4P84NyHXC
|
||||
4Vh5AoGAZYWkXxQUGzVm+H3fPpmETWGRNFDTimzi+6N+/uHkqkiDa3LGSnabmKh+
|
||||
voKm//DUjEVGlAZ3CGOjO/5SlZc/zjkgh1vg7KOU4x7DqVOuZjom5Tx3ZI4xVVVt
|
||||
tVtvK0qjzUTVcwAQALN/PNak+gs9534e954rmA9kmc3xBe4ho9M=
|
||||
-----END RSA PRIVATE KEY-----
|
22
plugins/WebUi/ssl/deluge.pem
Normal file
22
plugins/WebUi/ssl/deluge.pem
Normal file
@ -0,0 +1,22 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDlzCCAn+gAwIBAgIJAPnW/GEzRy8xMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNV
|
||||
BAYTAkFVMRUwEwYDVQQIEwxUaGUgSW50ZXJuZXQxFTATBgNVBAoTDERlbHVnZSBX
|
||||
ZWJ1aTAeFw0wNzExMjQxMDAzNDRaFw0wODExMjMxMDAzNDRaMDsxCzAJBgNVBAYT
|
||||
AkFVMRUwEwYDVQQIEwxUaGUgSW50ZXJuZXQxFTATBgNVBAoTDERlbHVnZSBXZWJ1
|
||||
aTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANbD169TupdifTQBLxGE
|
||||
PyRQ0lXCR4fWMT+5D3Y7Lu5PSIfOOQRzF+dgN2KW3uTB3tmwo//HUWAosUXRdSlE
|
||||
wCl3c3O5sPaa4H97Et0b5n3EbJZ+rse10YO2Ka2SeOoRZnB4lD0YLUxS7hTtmFgZ
|
||||
6sbv3Gk7QMcdz3aCuiw1Z7lYx2KHwvLg+APZOsi/4492K5H/FmEKieqSXDAM/9nP
|
||||
GV5QbolAm/Y+cSk82KCWolJCjdmKwIaMUcXyO2XOzB9slsPP302SWxl6PJ633pO3
|
||||
KEhO8kEtTOnIsJGJOVTtpgVSQSYAE0FEf4xny8xKjSl4IUOeuL/cJrhZlDHffWtL
|
||||
ZFcCAwEAAaOBnTCBmjAdBgNVHQ4EFgQU1BbX1/4WtAKRKmWI1gqryIoj7BQwawYD
|
||||
VR0jBGQwYoAU1BbX1/4WtAKRKmWI1gqryIoj7BShP6Q9MDsxCzAJBgNVBAYTAkFV
|
||||
MRUwEwYDVQQIEwxUaGUgSW50ZXJuZXQxFTATBgNVBAoTDERlbHVnZSBXZWJ1aYIJ
|
||||
APnW/GEzRy8xMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAEoiSz5x
|
||||
hRCplxUG34g3F5yJe0QboqzJ/XmECfO80a980C/WVeivM2Kb1uafsKNp+WK7wD8g
|
||||
mei+todYXG+fD8WmG41LG87Xi2Xe4SlAcemEpGcC5F1bpCdvqnVAWFnqoF88FOHx
|
||||
NDlrq5H5lhMH9wVrX9qJvxL+StaDJ0sFk4kMGWEN+bdSYfFdBQzF903nPtm+PlvO
|
||||
1Uo6gCuRTMYM5J1DC/GpNpo/Fzrkgm8mMf1MYy3rljiNgMt2rnxhtwi6jugwyMui
|
||||
id6Of6gYAtvhi7kmaUpdI5PHO35dqRK7pHXH+YXaulosCPw/+bSRptFTykeEMrBj
|
||||
CzotqJ+74MwXZyM=
|
||||
-----END CERTIFICATE-----
|
BIN
plugins/WebUi/static/images/tango/details.png
Normal file
BIN
plugins/WebUi/static/images/tango/details.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 498 B |
@ -4,7 +4,10 @@
|
||||
|
||||
Theme Name: Simple
|
||||
Theme URI: http://deluge-torrent.org
|
||||
Description: Deluge Theme
|
||||
Description: Deluge Theme
|
||||
Version: 1.0
|
||||
-----------------------------------------------------------
|
||||
|
||||
*/
|
||||
|
||||
|
||||
@ -55,9 +58,6 @@ tr.torrent_table_selected {
|
||||
#main form table tr th {
|
||||
background: #1f3044;
|
||||
font-size: 16px;
|
||||
#main form table tr th {
|
||||
background: #1f3044;
|
||||
font-size: 16px;
|
||||
border: 0px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
@ -71,4 +71,21 @@ body.inner {
|
||||
|
||||
#main form table tr th a {
|
||||
color: #8fa6c3;
|
||||
font-size: 16px;
|
||||
font-size: 16px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
#main form table tr th a, a:active, a:visited { color: #8fa6c3; text-decoration: none; }
|
||||
#main form table tr th a:hover {color: #fff; text-decoration: underline;}
|
||||
|
||||
#main form table tr td a {
|
||||
color: #fff;
|
||||
font-size: 12px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
#main form table tr td a, a:active, a:visited { color: #fff; text-decoration: none;}
|
||||
#main form table tr td a:hover {color: #fff; text-decoration: underline;}
|
||||
|
||||
#main a {
|
||||
color: #fff;
|
||||
font-size: 12px;
|
||||
|
@ -1,14 +1,49 @@
|
||||
$def with (torrent_list)
|
||||
$def with (torrent_list, all_torrents)
|
||||
$:render.header(_('Torrent list'))
|
||||
|
||||
<div class="panel" id="toolbar">
|
||||
|
||||
<a href='/torrent/add' >[Add]</a>
|
||||
<a href='#' onclick=' toolbar_post("/torrent/queue/up/")'>[Up]</a>
|
||||
<a href='#' onclick=' toolbar_post("/torrent/queue/down/")'>[Down]</a>
|
||||
<a href='#' onclick=' toolbar_get("/torrent/delete/")'>[Delete]</a>
|
||||
<a href='#' onclick=' toolbar_get("/torrent/info/")'>[Info]</a>
|
||||
<a href='#' onclick=' toolbar_post("/torrent/stop/")'>[Pause]</a>
|
||||
<a href='#' onclick=' toolbar_post("/torrent/start/")'>[Start]</a>
|
||||
<a class='toolbar_btn' href="#"
|
||||
onclick='toolbar_get("/torrent/add/",0)'
|
||||
title='$_("Add")'><img class='toolbar_btn'
|
||||
src='/static/images/tango/list-add.png'></a>
|
||||
|
||||
<a class='toolbar_btn' href="#"
|
||||
onclick='toolbar_get("/torrent/delete/",2)'><img class='toolbar_btn'
|
||||
src='/static/images/tango/list-remove.png'
|
||||
title='$_("Remove")'></a>
|
||||
|
||||
<a class='toolbar_btn' href="#"
|
||||
onclick='toolbar_post("/torrent/stop/",2)'
|
||||
title='$_("Pause")'><img class='toolbar_btn'
|
||||
src='/static/images/tango/pause.png'
|
||||
></a>
|
||||
|
||||
<a class='toolbar_btn' href="#"
|
||||
onclick='toolbar_post("/torrent/start/",2)'
|
||||
title='$_("Start")'><img class='toolbar_btn'
|
||||
src='/static/images/tango/start.png'></a>
|
||||
|
||||
<a class='toolbar_btn' href="#"
|
||||
onclick='toolbar_post("/torrent/queue/up/",2)'
|
||||
title='$_("Up")'><img class='toolbar_btn'
|
||||
src='/static/images/tango/queue-up.png'></a>
|
||||
|
||||
|
||||
<a class='toolbar_btn' href="#"
|
||||
onclick='toolbar_post("/torrent/queue/down/",2)'
|
||||
title='$_("Down")'><img class='toolbar_btn'
|
||||
src='/static/images/tango/queue-down.png'></a>
|
||||
|
||||
|
||||
<a class='toolbar_btn' href="#"
|
||||
onclick='toolbar_get("/torrent/info/",1)'
|
||||
title='$_("Details")'><img class='toolbar_btn'
|
||||
src='/static/images/tango/details.png'></a>
|
||||
|
||||
$:category_tabs(all_torrents)
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!--
|
||||
@ -21,10 +56,10 @@ $#end
|
||||
-->
|
||||
|
||||
|
||||
<form action="/torrent/pause" method="POST">
|
||||
|
||||
|
||||
<div id="tableContainer" class="tableContainer">
|
||||
<table class="torrent_list" border=1>
|
||||
<table class="torrent_list" border=1 id="torrent_list">
|
||||
<thead class="fixedHeader">
|
||||
<tr>
|
||||
$:(sort_head('calc_state_str', 'S'))
|
||||
@ -32,6 +67,7 @@ $#end
|
||||
$:(sort_head('name', _('Name')))
|
||||
$:(sort_head('total_size', _('Size')))
|
||||
$:(sort_head('progress', _('Progress')))
|
||||
$:(sort_head('category', _('Tracker')))
|
||||
$:(sort_head('num_seeds', _('Seeders')))
|
||||
$:(sort_head('num_peers', _('Peers')))
|
||||
$:(sort_head('download_rate', _('Download')))
|
||||
@ -45,11 +81,14 @@ $#end
|
||||
$#4-space indentation is mandatory for for-loops in templetor!
|
||||
$for torrent in torrent_list:
|
||||
<tr class="torrent_table" onclick="on_click_row(event, '$torrent.id')" id="torrent_$torrent.id">
|
||||
<td><input type="image"
|
||||
src="/static/images/$(torrent.calc_state_str)16.png"
|
||||
name="$torrent.action" value="$torrent.id"
|
||||
onclick="state.row_js_continue = false;">
|
||||
</td>
|
||||
<td>
|
||||
<form action="/torrent/$torrent.action/$torrent.id" method="POST"
|
||||
class="pause_resume">
|
||||
<input type="image"
|
||||
src="/static/images/$(torrent.calc_state_str)16.png"
|
||||
name="pauseresume" value="submit" />
|
||||
</form>
|
||||
</td>
|
||||
<td>$torrent.queue_pos</td>
|
||||
<td style="width:100px; overflow:hidden;white-space: nowrap">
|
||||
$(crop(torrent.name, 40))</td>
|
||||
@ -61,10 +100,21 @@ $for torrent in torrent_list:
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>$torrent.category</td>
|
||||
<td>$torrent.num_seeds ($torrent.total_seeds)</td>
|
||||
<td>$torrent.num_peers ($torrent.total_peers)</td>
|
||||
<td>$fspeed(torrent.download_rate)</td>
|
||||
<td>$fspeed(torrent.upload_rate)</td>
|
||||
<td>
|
||||
$if (torrent.download_rate):
|
||||
$fspeed(torrent.download_rate)
|
||||
$else:
|
||||
|
||||
</td>
|
||||
<td>
|
||||
$if (torrent.upload_rate):
|
||||
$fspeed(torrent.upload_rate)
|
||||
$else:
|
||||
|
||||
</td>
|
||||
<td>$torrent.eta</td>
|
||||
<td>$("%.3f" % torrent.distributed_copies)</td>
|
||||
<td>$("%.3f" % torrent.ratio)</td\>
|
||||
@ -73,7 +123,6 @@ $for torrent in torrent_list:
|
||||
</table>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
$:part_stats()
|
||||
|
||||
@ -84,6 +133,8 @@ $:part_stats()
|
||||
</iframe>
|
||||
</div>
|
||||
|
||||
<br />
|
||||
|
||||
|
||||
|
||||
<script language='javascript'>
|
||||
|
37
plugins/WebUi/templates/advanced/part_categories.html
Normal file
37
plugins/WebUi/templates/advanced/part_categories.html
Normal file
@ -0,0 +1,37 @@
|
||||
$def with (filter_tabs, category_tabs)
|
||||
<form method="GET" id="category_form">
|
||||
<input type="hidden" name="sort" value="$get('sort')">
|
||||
<input type="hidden" name="order" value="$get('order')">
|
||||
<select name='filter' id='filter'
|
||||
onchange="document.getElementById('category_form').submit()"
|
||||
title="$_('Filter on state')">
|
||||
$for tab in filter_tabs:
|
||||
<option value="$tab.filter"
|
||||
$if tab.filter == get('filter'):
|
||||
selected
|
||||
>
|
||||
$tab.title
|
||||
</option>
|
||||
</select>
|
||||
<select name='category' id='category'
|
||||
onchange="document.getElementById('category_form').submit()"
|
||||
title="$_('Filter on Tracker')">
|
||||
$for tab in category_tabs:
|
||||
<option value="$tab.category"
|
||||
$if tab.category == get('category'):
|
||||
selected
|
||||
>
|
||||
$tab.title
|
||||
</option>
|
||||
</select>
|
||||
|
||||
<input type="image" id='toolbar_refresh'
|
||||
src='/static/images/tango/view-refresh.png'
|
||||
title='$_('Refresh')'
|
||||
>
|
||||
|
||||
</form>
|
||||
|
||||
|
||||
|
||||
|
@ -1,16 +1,32 @@
|
||||
/*
|
||||
/*
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
|
||||
Theme Name: Simple
|
||||
Theme URI: http://deluge-torrent.org
|
||||
Description: Deluge Theme
|
||||
Version: 1.0
|
||||
Description: Deluge Theme
|
||||
-----------------------------------------------------------
|
||||
|
||||
*/
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
BODY {
|
||||
background: #304663 url(../../static/images/simple_bg.jpg) repeat-x;
|
||||
font-family: Bitstream Vera,Verdana;
|
||||
font-size: 10pt;
|
||||
margin: 0;
|
||||
padding:0;
|
||||
border:0;
|
||||
}
|
||||
|
||||
/* GENERIC STYLES */
|
||||
|
||||
a img {border: 0px}
|
||||
hr {color: #627082; margin: 15px 0 15px 0;}
|
||||
td {font-family: Bitstream Vera,Verdana;}
|
||||
tr {font-family: Bitstream Vera,Verdana;}
|
||||
table {font-family: Bitstream Vera,Verdana;}
|
||||
div {font-family: Bitstream Vera,Verdana;}
|
||||
/* STRUCTURE */
|
||||
@ -92,6 +108,12 @@ body.inner {
|
||||
.info {
|
||||
text-align: right;
|
||||
padding: 0 50px 0 0;
|
||||
color: #8fa6c3;
|
||||
font-size: 16px;
|
||||
letter-spacing: 4px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.title {
|
||||
color: #dce4ee;
|
||||
font-size: 32px;
|
||||
@ -110,15 +132,18 @@ body.inner {
|
||||
border:1px solid #68a;
|
||||
|
||||
background: #99acc3;
|
||||
.title {
|
||||
color: #000;
|
||||
/*vertical-align:middle;*/
|
||||
font-size: 32px;
|
||||
padding: 10px 50px 0 0;
|
||||
-moz-border-radius:5px;
|
||||
/*margin-top:5px;*/
|
||||
|
||||
}
|
||||
|
||||
input:hover {
|
||||
background-color:#68a;
|
||||
}
|
||||
|
||||
|
||||
|
||||
TEXTAREA{
|
||||
border:1px solid #23344b;
|
||||
@ -128,9 +153,95 @@ body.inner {
|
||||
|
||||
|
||||
.footertext a { color: #c0c0c0; text-decoration:none;}
|
||||
.footertext a:visited { color: #c0c0c0; text-decoration:none;}
|
||||
.footertext a:active { color: #c0c0c0; text-decoration:none;}
|
||||
.footertext a:hover {color: #fff; text-decoration: underline;}
|
||||
|
||||
|
||||
.footertext {
|
||||
text-align: center;
|
||||
|
||||
padding: 60px 0 0 0;
|
||||
font-size: 8pt;
|
||||
left: -100px;
|
||||
font-family: Bitstream Vera,Verdana;
|
||||
color: #fff;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.clearfix:after {
|
||||
content: ".";
|
||||
display: block;
|
||||
height: 0;
|
||||
clear: both;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
div.progress_bar{
|
||||
background-color:#4573a5;
|
||||
/*color:blue;*/
|
||||
-moz-border-radius:5px; /*ff only setting*/
|
||||
}
|
||||
|
||||
div.progress_bar_outer { /*used in table-view*/
|
||||
width:150px;
|
||||
}
|
||||
|
||||
td.progress_bar {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
td.info_label {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
td {
|
||||
font-size: 10pt;
|
||||
color: #d1dae5;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
tr {
|
||||
font-size: 10pt;
|
||||
color: #d1dae5;
|
||||
}
|
||||
|
||||
div.panel {
|
||||
padding:10px;
|
||||
width:750px;
|
||||
background-color: #37506f;
|
||||
-moz-border-radius:10px; /*ff-only!*/
|
||||
margin-top:10px;
|
||||
margin-bottom:10px;
|
||||
}
|
||||
|
||||
|
||||
/*New styles:*/
|
||||
|
||||
div.deluge_button {
|
||||
display:inline;
|
||||
}
|
||||
form.deluge_button {
|
||||
display:inline;
|
||||
}
|
||||
button.deluge_button {
|
||||
background-color: #37506f;
|
||||
border:1px solid #68a;
|
||||
|
||||
background: #99acc3;
|
||||
color: #000;
|
||||
vertical-align:middle;
|
||||
-moz-border-radius:7px;
|
||||
}
|
||||
button.deluge_button:hover {
|
||||
background-color:#68a;
|
||||
}
|
||||
div.error {
|
||||
background-color:#FFFFFF;
|
||||
color:#AA0000;
|
||||
font-weight:bold;
|
||||
-moz-border-radius:10px;
|
||||
width:200px;
|
||||
margin-bottom:20px;
|
||||
padding:10px;
|
||||
|
@ -29,10 +29,17 @@ function on_click_row(e,id) {
|
||||
function on_click_row_js(e, id) {
|
||||
/*real onClick event*/
|
||||
if (!e.ctrlKey) {
|
||||
deselect_rows();
|
||||
deselect_all_rows();
|
||||
select_row(id);
|
||||
open_inner_details(id);
|
||||
}
|
||||
else if (state.selected_rows.indexOf(id) != -1) {
|
||||
deselect_row(id);
|
||||
}
|
||||
else{
|
||||
select_row(id);
|
||||
open_inner_details(id);
|
||||
}
|
||||
select_row(id);
|
||||
open_inner_details(id);
|
||||
}
|
||||
|
||||
function select_row(id){
|
||||
@ -43,19 +50,30 @@ function select_row(id){
|
||||
setCookie('selected_rows',state.selected_rows);
|
||||
}
|
||||
}
|
||||
function deselect_rows(){
|
||||
for (i in state.selected_rows) {
|
||||
deselect_row(state.selected_rows[i]);
|
||||
}
|
||||
state.selected_rows = new Array();
|
||||
}
|
||||
|
||||
function deselect_row(id){
|
||||
var row = get_row(id);
|
||||
if (row) {
|
||||
row.className = 'torrent_table'
|
||||
/*TODO : remove from state.selected_rows*/
|
||||
/*remove from state.selected_rows*/
|
||||
var idx = state.selected_rows.indexOf(id);
|
||||
state.selected_rows.splice(idx,1);
|
||||
setCookie('selected_rows',state.selected_rows);
|
||||
}
|
||||
}
|
||||
|
||||
function deselect_all_rows(){
|
||||
/*unbind state.selected_rows from for..in:
|
||||
there must be a better way to do this*/
|
||||
var a = new Array()
|
||||
for (i in state.selected_rows) {
|
||||
a[a.length] = state.selected_rows[i];
|
||||
}
|
||||
for (i in a){
|
||||
deselect_row(a[i]);
|
||||
}
|
||||
}
|
||||
|
||||
function reselect_rows(){
|
||||
var selected_rows = getCookie('selected_rows').split(',');
|
||||
for (i in getCookie('selected_rows')) {
|
||||
@ -79,19 +97,24 @@ function on_click_do_nothing(e, id){
|
||||
on_click_action = on_click_do_nothing;
|
||||
|
||||
/*toobar buttons, */
|
||||
function toolbar_post(url) {
|
||||
/*this feels hacky, but it's the only way i know of*/
|
||||
var ids = state.selected_rows.join(',');
|
||||
var form = $('toolbar_form');
|
||||
form.action = url +ids;
|
||||
form.submit();
|
||||
function toolbar_post(url, selected) {
|
||||
if ((!selected) || (state.selected_rows.length > 0)) {
|
||||
var ids = state.selected_rows.join(',');
|
||||
var form = $('toolbar_form');
|
||||
form.action = url +ids;
|
||||
form.submit();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function toolbar_get(url) {
|
||||
/*this feels hacky, but it's the only way i know of*/
|
||||
var ids = state.selected_rows.join(',');
|
||||
window.location.href = url +ids;
|
||||
function toolbar_get(url , selected) {
|
||||
if (!selected) {
|
||||
window.location.href = url
|
||||
}
|
||||
else if (state.selected_rows.length > 0) {
|
||||
var ids = state.selected_rows.join(',');
|
||||
window.location.href = url +ids;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
$def with (torrent_list)
|
||||
$def with (torrent_list, all_torrents)
|
||||
$:render.header(_('Torrent list'))
|
||||
|
||||
<table class="torrent_list" border=1>
|
||||
<table class="torrent_list" border=0 id='torrent_table'>
|
||||
<tr>
|
||||
$:(sort_head('calc_state_str', 'S'))
|
||||
$:(sort_head('queue_pos', '#'))
|
||||
@ -20,13 +20,10 @@ $#4-space indentation is mandatory for for-loops in templetor!
|
||||
$for torrent in torrent_list:
|
||||
<tr class="torrent_table" id="torrent_$torrent.id">
|
||||
<td>
|
||||
<form action="/torrent/$torrent.action/$torrent.id" method="POST">
|
||||
<form action="/torrent/$torrent.action/$torrent.id" method="POST" class="pause_resume">
|
||||
<input type="image"
|
||||
src="/static/images/$(torrent.calc_state_str)16.png"
|
||||
name="pauseresume" value="submit" />
|
||||
</form>
|
||||
</td>
|
||||
|
||||
name="pauseresume" value="submit" /></form></td>
|
||||
<td>$torrent.queue_pos</td>
|
||||
<td style="width:100px; overflow:hidden;white-space: nowrap">
|
||||
<a href="/torrent/info/$torrent.id" >
|
||||
@ -53,8 +50,8 @@ $for torrent in torrent_list:
|
||||
|
||||
<div class="panel">
|
||||
$:render.part_button('GET', '/torrent/add', _('Add torrent'), 'tango/list-add.png')
|
||||
$:render.part_button('POST', '/pause_all', _('Pause all'), 'tango/media-playback-pause.png')
|
||||
$:render.part_button('POST', '/resume_all', _('Resume all'), 'tango/media-playback-start.png')
|
||||
$:render.part_button('POST', '/pause_all', _('Pause all'), 'tango/pause.png')
|
||||
$:render.part_button('POST', '/resume_all', _('Resume all'), 'tango/start.png')
|
||||
<!--$:render.part_button('POST', '/logout', _('Logout'), 'tango/system-log-out.png')-->
|
||||
</div>
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
$def with (column_id, column_name, order, active_up, active_down)
|
||||
<th class="torrent_table">
|
||||
<a href="/index?sort=$column_id&order=$order">
|
||||
<a href="/index?sort=$column_id&order=$order&filter=$get('filter')&category=$get('category')">
|
||||
$column_name\
|
||||
$if active_up:
|
||||
<img src="/static/images/tango/up.png" />
|
||||
|
@ -68,10 +68,10 @@ $fspeed(torrent.download_rate)</td></td></tr>
|
||||
<td class="info_value">$torrent.num_files</td></tr>
|
||||
|
||||
<tr><td class="info_label">$_('Tracker'):</td>
|
||||
<td class="info_value">$(crop(torrent.tracker, 30))</td></tr>
|
||||
<td class="info_value" title="$torrent.tracker">$(crop(torrent.tracker, 30))</td></tr>
|
||||
|
||||
<tr><td class="info_label">$_('Tracker Status'):</td>
|
||||
<td class="info_value">$torrent.tracker_status </td></tr>
|
||||
<td class="info_value" title="$torrent.tracker_status">$(crop(torrent.tracker_status, 30)) </td></tr>
|
||||
|
||||
<tr><td class="info_label">$_('Next Announce'):</td>
|
||||
<td class="info_value">$torrent.next_announce </td></tr>
|
||||
|
@ -12,7 +12,7 @@ $else:
|
||||
$:render.part_button('POST', '/torrent/stop/' + str(torrent.id), _('Pause'), 'tango/pause.png')
|
||||
|
||||
|
||||
$:render.part_button('GET', '/torrent/delete/' + str(torrent.id), _('Remove'), 'tango/user-trash.png')
|
||||
$:render.part_button('GET', '/torrent/delete/' + str(torrent.id), _('Remove'), 'tango/list-remove.png')
|
||||
$:render.part_button('POST', '/torrent/reannounce/' + str(torrent.id), _('Reannounce'), 'tango/view-refresh.png')
|
||||
|
||||
$:render.part_button('POST', '/torrent/queue/up/' + str(torrent.id), _('Queue Up'), 'tango/queue-up.png')
|
||||
|
@ -1,3 +0,0 @@
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1,12 +0,0 @@
|
||||
$def with (title)
|
||||
<html>
|
||||
<head>
|
||||
<title>Deluge(example) : $title</title>
|
||||
<link rel="icon" href="/static/images/deluge_icon.gif" type="image/gif" />
|
||||
<link rel="shortcut icon" href="/static/images/deluge_icon.gif" type="image/gif" />
|
||||
</head>
|
||||
<body>
|
||||
<img src="/template/static/example.png">
|
||||
<a href=/home>[HOME]</a>
|
||||
|
||||
<h1>$title</h1>
|
@ -1,42 +0,0 @@
|
||||
$def with (torrent_list)
|
||||
$:render.header(_('Torrent list'))
|
||||
|
||||
<form action="/torrent/pause" method="POST">
|
||||
<table class="torrent_list" border=1>
|
||||
<tr>
|
||||
$:(sort_head('calc_state_str', 'S'))
|
||||
$:(sort_head('queue_pos', '#'))
|
||||
$:(sort_head('name', _('Name')))
|
||||
$:(sort_head('progress', _('Progress')))
|
||||
</tr>
|
||||
$#4-space indentation is mandatory for for-loops in templetor!
|
||||
$for torrent in torrent_list:
|
||||
<tr>
|
||||
<td><input type="image"
|
||||
src="/static/images/$(torrent.calc_state_str)16.png"
|
||||
name="$torrent.action" value="$torrent.id">
|
||||
</td>
|
||||
<td>$torrent.queue_pos</td>
|
||||
<td style="width:100px; overflow:hidden;white-space: nowrap">
|
||||
<a href="/torrent/info/$torrent.id">$(crop(torrent.name, 40))</a></td>
|
||||
<td class="progress_bar">
|
||||
<div class="progress_bar_outer">
|
||||
<div class="progress_bar" style="width:$(torrent.progress)%">
|
||||
$torrent.message
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</form>
|
||||
|
||||
<div class="panel" bgcolor="5555AA">
|
||||
$:render.part_button('GET', '/torrent/add', _('Add torrent'), 'tango/list-add.png')
|
||||
$:render.part_button('POST', '/pause_all', _('Pause all'), 'tango/media-playback-pause.png')
|
||||
$:render.part_button('POST', '/resume_all', _('Resume all'), 'tango/media-playback-start.png')
|
||||
$:render.part_button('POST', '/logout', _('Logout'), 'tango/system-log-out.png')
|
||||
</div>
|
||||
|
||||
$:render.footer()
|
||||
|
@ -211,7 +211,7 @@ class TestIntegration(TestWebUiBase):
|
||||
#delete all, nice use case for refactoring delete..
|
||||
torrent_ids = ws.proxy.get_session_state()
|
||||
for torrent in torrent_ids:
|
||||
ws.proxy.remove_torrent(torrent, False, False)
|
||||
ws.proxy.remove_torrent([torrent], False, False)
|
||||
|
||||
torrent_ids = ws.proxy.get_session_state()
|
||||
self.assertEqual(torrent_ids, [])
|
||||
@ -237,14 +237,14 @@ class TestIntegration(TestWebUiBase):
|
||||
#pause all
|
||||
self.assert_303('/pause_all','/index', post=1)
|
||||
#pause worked?
|
||||
pause_status = [get_status(id)["paused"] for id in ws.proxy.get_session_state()]
|
||||
pause_status = [get_status(id)["user_paused"] for id in ws.proxy.get_session_state()]
|
||||
for paused in pause_status:
|
||||
self.assertEqual(paused, True)
|
||||
|
||||
#resume all
|
||||
self.assert_303('/resume_all','/index', post=1)
|
||||
#resume worked?
|
||||
pause_status = [get_status(id)["paused"] for id in ws.proxy.get_session_state()]
|
||||
pause_status = [get_status(id)["user_paused"] for id in ws.proxy.get_session_state()]
|
||||
for paused in pause_status:
|
||||
self.assertEqual(paused,False)
|
||||
#pause again.
|
||||
@ -253,10 +253,10 @@ class TestIntegration(TestWebUiBase):
|
||||
torrent_id = self.first_torrent_id
|
||||
#single resume.
|
||||
self.assert_303('/torrent/start/%s' % torrent_id ,'/index', post=1)
|
||||
self.assertEqual(get_status(torrent_id)["paused"] ,False)
|
||||
self.assertEqual(get_status(torrent_id)["user_paused"] ,False)
|
||||
#single pause
|
||||
self.assert_303('/torrent/stop/%s' % torrent_id,'/index', post=1)
|
||||
self.assertEqual(get_status(torrent_id)["paused"] , True)
|
||||
self.assertEqual(get_status(torrent_id)["user_paused"] , True)
|
||||
|
||||
def testQueue(self):
|
||||
#find last:
|
||||
|
@ -1,5 +1,5 @@
|
||||
revision-id: mvoncken@gmail.com-20070930083408-sv8mo0mi1rbjnfvk
|
||||
date: 2007-11-21 15:10:08 +0200
|
||||
build-date: 2007-11-21 15:34:50 +0200
|
||||
revno: 143
|
||||
date: 2007-11-26 15:10:08 +0200
|
||||
build-date: 2007-11-26 15:34:50 +0200
|
||||
revno: 160
|
||||
branch-nick: WebUi
|
||||
|
@ -42,7 +42,7 @@ import pickle
|
||||
import sys
|
||||
from webpy022 import template
|
||||
random.seed()
|
||||
path = os.path.dirname(__file__)
|
||||
webui_path = os.path.dirname(__file__)
|
||||
|
||||
ENV = 'UNKNOWN'
|
||||
|
||||
@ -68,11 +68,11 @@ class subclassed_render(object):
|
||||
"""
|
||||
def __init__(self, template_dirname, cache=False):
|
||||
self.base_template = template.render(
|
||||
os.path.join(path, 'templates/deluge/'),
|
||||
os.path.join(webui_path, 'templates/deluge/'),
|
||||
cache=cache)
|
||||
|
||||
self.sub_template = template.render(
|
||||
os.path.join(path, 'templates/%s/' % template_dirname),
|
||||
os.path.join(webui_path, 'templates/%s/' % template_dirname),
|
||||
cache=cache)
|
||||
|
||||
def __getattr__(self, attr):
|
||||
|
@ -56,6 +56,7 @@ from operator import attrgetter
|
||||
import datetime
|
||||
import pickle
|
||||
from md5 import md5
|
||||
from urlparse import urlparse
|
||||
|
||||
from deluge import common
|
||||
from webserver_common import REVNO, VERSION
|
||||
@ -97,13 +98,20 @@ def do_redirect():
|
||||
"""for redirects after a POST"""
|
||||
vars = web.input(redir = None)
|
||||
ck = cookies()
|
||||
url_vars = {}
|
||||
|
||||
if vars.redir:
|
||||
seeother(vars.redir)
|
||||
elif ("order" in ck and "sort" in ck):
|
||||
seeother(url("/index", sort=ck['sort'], order=ck['order']))
|
||||
else:
|
||||
seeother(url("/index"))
|
||||
return
|
||||
#todo:cleanup
|
||||
if ("order" in ck and "sort" in ck):
|
||||
url_vars.update({'sort':ck['sort'] ,'order':ck['order'] })
|
||||
if ("filter" in ck) and ck['filter']:
|
||||
url_vars['filter'] = ck['filter']
|
||||
if ("category" in ck) and ck['category']:
|
||||
url_vars['category'] = ck['category']
|
||||
|
||||
seeother(url("/index", **url_vars))
|
||||
|
||||
def error_page(error):
|
||||
web.header("Content-Type", "text/html; charset=utf-8")
|
||||
@ -211,6 +219,12 @@ def get_torrent_status(torrent_id):
|
||||
|
||||
status["id"] = torrent_id
|
||||
|
||||
url = urlparse(status.tracker)
|
||||
if hasattr(url,'hostname'):
|
||||
status.category = url.hostname or 'unknown'
|
||||
else:
|
||||
status.category = 'No-tracker'
|
||||
|
||||
#for naming the status-images
|
||||
status.calc_state_str = "downloading"
|
||||
if status.paused:
|
||||
@ -219,7 +233,7 @@ def get_torrent_status(torrent_id):
|
||||
status.calc_state_str = "seeding"
|
||||
|
||||
#action for torrent_pause
|
||||
if status.calc_state_str == "inactive":
|
||||
if status.user_paused:
|
||||
status.action = "start"
|
||||
else:
|
||||
status.action = "stop"
|
||||
@ -250,9 +264,59 @@ def get_torrent_status(torrent_id):
|
||||
raise Exception('Non Unicode for key:%s' % (k, ))
|
||||
return status
|
||||
|
||||
def get_categories(torrent_list):
|
||||
trackers = [(torrent['category'] or 'unknown') for torrent in torrent_list]
|
||||
categories = {}
|
||||
for tracker in trackers:
|
||||
categories[tracker] = categories.get(tracker,0) + 1
|
||||
return categories
|
||||
|
||||
def filter_torrent_state(torrent_list,filter_name):
|
||||
filters = {
|
||||
'downloading': lambda t: (not t.paused and not t.is_seed)
|
||||
,'queued':lambda t: (t.paused and not t.user_paused)
|
||||
,'paused':lambda t: (t.user_paused)
|
||||
,'seeding':lambda t:(t.is_seed and not t.paused )
|
||||
}
|
||||
filter_func = filters[filter_name]
|
||||
return [t for t in torrent_list if filter_func(t)]
|
||||
|
||||
#/utils
|
||||
|
||||
#template-defs:
|
||||
def category_tabs(torrent_list):
|
||||
categories = get_categories(torrent_list)
|
||||
|
||||
filter_tabs = [Storage(title='All (%s)' % len(torrent_list),
|
||||
filter=None, category=None)]
|
||||
|
||||
#static filters
|
||||
for title, filter_name in [
|
||||
(_('Downloading'),'downloading') ,
|
||||
(_('Queued'),'queued') ,
|
||||
(_('Paused'),'paused') ,
|
||||
(_('Seeding'),'seeding')
|
||||
]:
|
||||
title += ' (%s)' % (
|
||||
len(filter_torrent_state(torrent_list, filter_name)), )
|
||||
filter_tabs.append(Storage(title=title, filter=filter_name))
|
||||
|
||||
categories = [x for x in get_categories(torrent_list).iteritems()]
|
||||
categories.sort()
|
||||
|
||||
#trackers:
|
||||
category_tabs = []
|
||||
category_tabs.append(
|
||||
Storage(title=_('Trackers'),category=None))
|
||||
for title,count in categories:
|
||||
category = title
|
||||
title += ' (%s)' % (count, )
|
||||
category_tabs.append(Storage(title=title, category=category))
|
||||
|
||||
|
||||
return ws.render.part_categories(filter_tabs, category_tabs)
|
||||
|
||||
|
||||
def template_crop(text, end):
|
||||
if len(text) > end:
|
||||
return text[0:end - 3] + '...'
|
||||
@ -283,6 +347,7 @@ def get_config(var):
|
||||
template.Template.globals.update({
|
||||
'sort_head': template_sort_head,
|
||||
'part_stats':template_part_stats,
|
||||
'category_tabs':category_tabs,
|
||||
'crop': template_crop,
|
||||
'_': _ , #gettext/translations
|
||||
'str': str, #because % in templetor is broken.
|
||||
@ -295,7 +360,6 @@ template.Template.globals.update({
|
||||
'rev': 'rev.%s' % (REVNO, ),
|
||||
'version': VERSION,
|
||||
'getcookie':getcookie,
|
||||
'js_enabled': lambda : ws.config.get('use_javascript'),
|
||||
'get': lambda (var): getattr(web.input(**{var:None}), var) # unreadable :-(
|
||||
})
|
||||
#/template-defs
|
||||
@ -304,14 +368,15 @@ def create_webserver(urls, methods):
|
||||
from webpy022.request import webpyfunc
|
||||
from webpy022 import webapi
|
||||
from gtk_cherrypy_wsgiserver import CherryPyWSGIServer
|
||||
import os
|
||||
|
||||
func = webapi.wsgifunc(webpyfunc(urls, methods, False))
|
||||
server_address=("0.0.0.0", int(ws.config.get('port')))
|
||||
|
||||
server = CherryPyWSGIServer(server_address, func, server_name="localhost")
|
||||
if ws.config.get('use_https'):
|
||||
server.ssl_certificate = ws.config.get('ssl_certificate')
|
||||
server.ssl_private_key = ws.config.get('ssl_private_key')
|
||||
server.ssl_certificate = os.path.join(ws.webui_path,'ssl/deluge.pem')
|
||||
server.ssl_private_key = os.path.join(ws.webui_path,'ssl/deluge.key')
|
||||
|
||||
print "http://%s:%d/" % server_address
|
||||
return server
|
||||
@ -321,4 +386,5 @@ __all__ = ['deluge_page_noauth', 'deluge_page', 'remote',
|
||||
'auto_refreshed', 'check_session',
|
||||
'do_redirect', 'error_page','start_session','getcookie'
|
||||
,'setcookie','create_webserver','end_session',
|
||||
'get_torrent_status', 'check_pwd','static_handler']
|
||||
'get_torrent_status', 'check_pwd','static_handler','get_categories'
|
||||
,'template','filter_torrent_state']
|
||||
|
601
po/deluge.pot
601
po/deluge.pot
File diff suppressed because it is too large
Load Diff
1921
po/en_AU.po
1921
po/en_AU.po
File diff suppressed because it is too large
Load Diff
1954
po/en_CA.po
1954
po/en_CA.po
File diff suppressed because it is too large
Load Diff
1793
po/en_GB.po
1793
po/en_GB.po
File diff suppressed because it is too large
Load Diff
1893
po/pt_BR.po
1893
po/pt_BR.po
File diff suppressed because it is too large
Load Diff
2438
po/zh_CN.po
2438
po/zh_CN.po
File diff suppressed because it is too large
Load Diff
2243
po/zh_TW.po
2243
po/zh_TW.po
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user