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
|
* Scrape support
|
||||||
* Manual force-recheck
|
* Manual force-recheck
|
||||||
* Add local peer discovery (aka local service discovery)
|
* Add local peer discovery (aka local service discovery)
|
||||||
* Blocklist plugin will now display errors, instead of just crashing on a bad
|
* Blocklist plugin will now display errors, instead of just crashing on a bad
|
||||||
list or wrong type
|
list or wrong type
|
||||||
* Add torrent in paused state option
|
* 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 bug where loaded plugins were forgotten if Deluge crashed
|
||||||
* Fix ratio bugs (hopefully for the last time)
|
* Fix ratio bugs (hopefully for the last time)
|
||||||
* Add preference to only show file selection popup if torrent has multiple files
|
* 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 preference for the location of torrent files
|
||||||
* Add autoload folder
|
* Add autoload folder
|
||||||
* Copy translator credits from Launchpad to our about->credits
|
* 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)
|
Deluge 0.5.6.2 (31 October 2007)
|
||||||
* Set default piece size to 256-KiB in TorrentCreator plugin and add 2048KiB
|
* 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-dbus
|
||||||
python-gtk2 version >= 2.9
|
python-gtk2 version >= 2.9
|
||||||
python-notify
|
python-notify
|
||||||
|
python-pyopenssl
|
||||||
librsvg2-common
|
librsvg2-common
|
||||||
python-xdg
|
python-xdg
|
||||||
python-support
|
python-support
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -122,7 +122,7 @@
|
|||||||
<child>
|
<child>
|
||||||
<widget class="GtkButton" id="button2">
|
<widget class="GtkButton" id="button2">
|
||||||
<property name="visible">True</property>
|
<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="use_stock">True</property>
|
||||||
<property name="response_id">0</property>
|
<property name="response_id">0</property>
|
||||||
</widget>
|
</widget>
|
||||||
@ -130,7 +130,7 @@
|
|||||||
<child>
|
<child>
|
||||||
<widget class="GtkButton" id="button1">
|
<widget class="GtkButton" id="button1">
|
||||||
<property name="visible">True</property>
|
<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="use_stock">True</property>
|
||||||
<property name="response_id">1</property>
|
<property name="response_id">1</property>
|
||||||
</widget>
|
</widget>
|
||||||
@ -197,7 +197,7 @@
|
|||||||
<child>
|
<child>
|
||||||
<widget class="GtkImageMenuItem" id="menuitem12">
|
<widget class="GtkImageMenuItem" id="menuitem12">
|
||||||
<property name="visible">True</property>
|
<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_underline">True</property>
|
||||||
<property name="use_stock">True</property>
|
<property name="use_stock">True</property>
|
||||||
<signal name="activate" handler="preferences"/>
|
<signal name="activate" handler="preferences"/>
|
||||||
@ -227,7 +227,7 @@
|
|||||||
<child>
|
<child>
|
||||||
<widget class="GtkImageMenuItem" id="menuitem14">
|
<widget class="GtkImageMenuItem" id="menuitem14">
|
||||||
<property name="visible">True</property>
|
<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_underline">True</property>
|
||||||
<property name="use_stock">True</property>
|
<property name="use_stock">True</property>
|
||||||
<signal name="activate" handler="quit"/>
|
<signal name="activate" handler="quit"/>
|
||||||
@ -299,7 +299,7 @@
|
|||||||
<property name="can_focus">True</property>
|
<property name="can_focus">True</property>
|
||||||
<property name="receives_default">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="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="use_stock">True</property>
|
||||||
<property name="response_id">0</property>
|
<property name="response_id">0</property>
|
||||||
</widget>
|
</widget>
|
||||||
@ -310,7 +310,7 @@
|
|||||||
<property name="can_focus">True</property>
|
<property name="can_focus">True</property>
|
||||||
<property name="receives_default">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="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="use_stock">True</property>
|
||||||
<property name="response_id">1</property>
|
<property name="response_id">1</property>
|
||||||
</widget>
|
</widget>
|
||||||
|
|||||||
@ -64,7 +64,7 @@
|
|||||||
<property name="can_focus">True</property>
|
<property name="can_focus">True</property>
|
||||||
<property name="receives_default">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="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="use_stock">True</property>
|
||||||
<property name="response_id">0</property>
|
<property name="response_id">0</property>
|
||||||
<signal name="clicked" handler="cancel_button_clicked"/>
|
<signal name="clicked" handler="cancel_button_clicked"/>
|
||||||
@ -81,7 +81,7 @@
|
|||||||
<property name="can_focus">True</property>
|
<property name="can_focus">True</property>
|
||||||
<property name="receives_default">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="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="use_stock">True</property>
|
||||||
<property name="response_id">0</property>
|
<property name="response_id">0</property>
|
||||||
<signal name="clicked" handler="ok_button_clicked"/>
|
<signal name="clicked" handler="ok_button_clicked"/>
|
||||||
|
|||||||
@ -57,7 +57,7 @@
|
|||||||
<child>
|
<child>
|
||||||
<widget class="GtkButton" id="button2">
|
<widget class="GtkButton" id="button2">
|
||||||
<property name="visible">True</property>
|
<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="use_stock">True</property>
|
||||||
<property name="response_id">0</property>
|
<property name="response_id">0</property>
|
||||||
</widget>
|
</widget>
|
||||||
@ -65,7 +65,7 @@
|
|||||||
<child>
|
<child>
|
||||||
<widget class="GtkButton" id="button1">
|
<widget class="GtkButton" id="button1">
|
||||||
<property name="visible">True</property>
|
<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="use_stock">True</property>
|
||||||
<property name="response_id">1</property>
|
<property name="response_id">1</property>
|
||||||
</widget>
|
</widget>
|
||||||
|
|||||||
@ -31,7 +31,7 @@
|
|||||||
<child>
|
<child>
|
||||||
<widget class="GtkButton" id="button_cancel">
|
<widget class="GtkButton" id="button_cancel">
|
||||||
<property name="visible">True</property>
|
<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="use_stock">True</property>
|
||||||
<property name="response_id">0</property>
|
<property name="response_id">0</property>
|
||||||
</widget>
|
</widget>
|
||||||
@ -39,7 +39,7 @@
|
|||||||
<child>
|
<child>
|
||||||
<widget class="GtkButton" id="button_ok">
|
<widget class="GtkButton" id="button_ok">
|
||||||
<property name="visible">True</property>
|
<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="use_stock">True</property>
|
||||||
<property name="response_id">1</property>
|
<property name="response_id">1</property>
|
||||||
</widget>
|
</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),
|
system_category = ASIO_WIN_OR_POSIX(0, 0),
|
||||||
|
|
||||||
/// Error codes from NetDB functions.
|
/// 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.
|
/// 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.
|
/// Miscellaneous error codes.
|
||||||
misc_category = ASIO_WIN_OR_POSIX(3, 3),
|
misc_category = ASIO_WIN_OR_POSIX(3, 3),
|
||||||
|
|||||||
@ -473,7 +473,7 @@ namespace libtorrent
|
|||||||
// we might need more than one listen socket
|
// we might need more than one listen socket
|
||||||
std::list<listen_socket_t> m_listen_sockets;
|
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
|
// the settings for the client
|
||||||
session_settings m_settings;
|
session_settings m_settings;
|
||||||
|
|||||||
@ -171,6 +171,21 @@ namespace libtorrent
|
|||||||
return Endpoint(addr, port);
|
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
|
#endif // TORRENT_SOCKET_HPP_INCLUDED
|
||||||
|
|||||||
@ -273,6 +273,9 @@ namespace libtorrent { namespace dht
|
|||||||
udp::endpoint ep(listen_interface, listen_port);
|
udp::endpoint ep(listen_interface, listen_port);
|
||||||
m_socket.open(ep.protocol());
|
m_socket.open(ep.protocol());
|
||||||
m_socket.bind(ep);
|
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)
|
void dht_tracker::tick(asio::error_code const& e)
|
||||||
|
|||||||
@ -814,13 +814,15 @@ namespace detail
|
|||||||
return m_ipv6_interface;
|
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;
|
asio::error_code ec;
|
||||||
listen_socket_t s;
|
listen_socket_t s;
|
||||||
s.sock.reset(new socket_acceptor(m_io_service));
|
s.sock.reset(new socket_acceptor(m_io_service));
|
||||||
s.sock->open(ep.protocol(), ec);
|
s.sock->open(ep.protocol(), ec);
|
||||||
s.sock->set_option(socket_acceptor::reuse_address(true), 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);
|
s.sock->bind(ep, ec);
|
||||||
while (ec && retries > 0)
|
while (ec && retries > 0)
|
||||||
{
|
{
|
||||||
@ -913,7 +915,7 @@ namespace detail
|
|||||||
|
|
||||||
s = setup_listener(
|
s = setup_listener(
|
||||||
tcp::endpoint(address_v6::any(), m_listen_interface.port())
|
tcp::endpoint(address_v6::any(), m_listen_interface.port())
|
||||||
, m_listen_port_retries);
|
, m_listen_port_retries, true);
|
||||||
|
|
||||||
if (s.sock)
|
if (s.sock)
|
||||||
{
|
{
|
||||||
@ -2279,6 +2281,8 @@ namespace detail
|
|||||||
|
|
||||||
INVARIANT_CHECK;
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
|
if (m_lsd) return;
|
||||||
|
|
||||||
m_lsd = new lsd(m_io_service
|
m_lsd = new lsd(m_io_service
|
||||||
, m_listen_interface.address()
|
, m_listen_interface.address()
|
||||||
, bind(&session_impl::on_lsd_peer, this, _1, _2));
|
, bind(&session_impl::on_lsd_peer, this, _1, _2));
|
||||||
@ -2290,6 +2294,8 @@ namespace detail
|
|||||||
|
|
||||||
INVARIANT_CHECK;
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
|
if (m_natpmp) return;
|
||||||
|
|
||||||
m_natpmp = new natpmp(m_io_service
|
m_natpmp = new natpmp(m_io_service
|
||||||
, m_listen_interface.address()
|
, m_listen_interface.address()
|
||||||
, bind(&session_impl::on_port_mapping
|
, bind(&session_impl::on_port_mapping
|
||||||
@ -2308,6 +2314,8 @@ namespace detail
|
|||||||
|
|
||||||
INVARIANT_CHECK;
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
|
if (m_upnp) return;
|
||||||
|
|
||||||
m_upnp = new upnp(m_io_service, m_half_open
|
m_upnp = new upnp(m_io_service, m_half_open
|
||||||
, m_listen_interface.address()
|
, m_listen_interface.address()
|
||||||
, m_settings.user_agent
|
, m_settings.user_agent
|
||||||
|
|||||||
@ -43,7 +43,8 @@ namespace libtorrent
|
|||||||
if (e)
|
if (e)
|
||||||
{
|
{
|
||||||
(*h)(e);
|
(*h)(e);
|
||||||
close();
|
asio::error_code ec;
|
||||||
|
close(ec);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,8 +55,8 @@ namespace libtorrent
|
|||||||
if (i == tcp::resolver::iterator())
|
if (i == tcp::resolver::iterator())
|
||||||
{
|
{
|
||||||
asio::error_code ec = asio::error::operation_not_supported;
|
asio::error_code ec = asio::error::operation_not_supported;
|
||||||
(*h)(e);
|
(*h)(ec);
|
||||||
close();
|
close(ec);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,7 +69,8 @@ namespace libtorrent
|
|||||||
if (e)
|
if (e)
|
||||||
{
|
{
|
||||||
(*h)(e);
|
(*h)(e);
|
||||||
close();
|
asio::error_code ec;
|
||||||
|
close(ec);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,7 +95,8 @@ namespace libtorrent
|
|||||||
if (e)
|
if (e)
|
||||||
{
|
{
|
||||||
(*h)(e);
|
(*h)(e);
|
||||||
close();
|
asio::error_code ec;
|
||||||
|
close(ec);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,7 +110,8 @@ namespace libtorrent
|
|||||||
if (e)
|
if (e)
|
||||||
{
|
{
|
||||||
(*h)(e);
|
(*h)(e);
|
||||||
close();
|
asio::error_code ec;
|
||||||
|
close(ec);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,8 +123,9 @@ namespace libtorrent
|
|||||||
|
|
||||||
if (reply_version != 0)
|
if (reply_version != 0)
|
||||||
{
|
{
|
||||||
(*h)(asio::error::operation_not_supported);
|
asio::error_code ec = asio::error::operation_not_supported;
|
||||||
close();
|
(*h)(ec);
|
||||||
|
close(ec);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -140,7 +145,7 @@ namespace libtorrent
|
|||||||
case 93: ec = asio::error::no_permission; break;
|
case 93: ec = asio::error::no_permission; break;
|
||||||
}
|
}
|
||||||
(*h)(ec);
|
(*h)(ec);
|
||||||
close();
|
close(ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -44,7 +44,8 @@ namespace libtorrent
|
|||||||
if (e || i == tcp::resolver::iterator())
|
if (e || i == tcp::resolver::iterator())
|
||||||
{
|
{
|
||||||
(*h)(e);
|
(*h)(e);
|
||||||
close();
|
asio::error_code ec;
|
||||||
|
close(ec);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,7 +58,8 @@ namespace libtorrent
|
|||||||
if (e)
|
if (e)
|
||||||
{
|
{
|
||||||
(*h)(e);
|
(*h)(e);
|
||||||
close();
|
asio::error_code ec;
|
||||||
|
close(ec);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,7 +88,8 @@ namespace libtorrent
|
|||||||
if (e)
|
if (e)
|
||||||
{
|
{
|
||||||
(*h)(e);
|
(*h)(e);
|
||||||
close();
|
asio::error_code ec;
|
||||||
|
close(ec);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,7 +103,8 @@ namespace libtorrent
|
|||||||
if (e)
|
if (e)
|
||||||
{
|
{
|
||||||
(*h)(e);
|
(*h)(e);
|
||||||
close();
|
asio::error_code ec;
|
||||||
|
close(ec);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,7 +117,8 @@ namespace libtorrent
|
|||||||
if (version < 5)
|
if (version < 5)
|
||||||
{
|
{
|
||||||
(*h)(asio::error::operation_not_supported);
|
(*h)(asio::error::operation_not_supported);
|
||||||
close();
|
asio::error_code ec;
|
||||||
|
close(ec);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,7 +131,8 @@ namespace libtorrent
|
|||||||
if (m_user.empty())
|
if (m_user.empty())
|
||||||
{
|
{
|
||||||
(*h)(asio::error::operation_not_supported);
|
(*h)(asio::error::operation_not_supported);
|
||||||
close();
|
asio::error_code ec;
|
||||||
|
close(ec);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,7 +150,8 @@ namespace libtorrent
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
(*h)(asio::error::operation_not_supported);
|
(*h)(asio::error::operation_not_supported);
|
||||||
close();
|
asio::error_code ec;
|
||||||
|
close(ec);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -155,7 +162,8 @@ namespace libtorrent
|
|||||||
if (e)
|
if (e)
|
||||||
{
|
{
|
||||||
(*h)(e);
|
(*h)(e);
|
||||||
close();
|
asio::error_code ec;
|
||||||
|
close(ec);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,7 +178,8 @@ namespace libtorrent
|
|||||||
if (e)
|
if (e)
|
||||||
{
|
{
|
||||||
(*h)(e);
|
(*h)(e);
|
||||||
close();
|
asio::error_code ec;
|
||||||
|
close(ec);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -183,14 +192,16 @@ namespace libtorrent
|
|||||||
if (version != 1)
|
if (version != 1)
|
||||||
{
|
{
|
||||||
(*h)(asio::error::operation_not_supported);
|
(*h)(asio::error::operation_not_supported);
|
||||||
close();
|
asio::error_code ec;
|
||||||
|
close(ec);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status != 0)
|
if (status != 0)
|
||||||
{
|
{
|
||||||
(*h)(asio::error::operation_not_supported);
|
(*h)(asio::error::operation_not_supported);
|
||||||
close();
|
asio::error_code ec;
|
||||||
|
close(ec);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -222,7 +233,8 @@ namespace libtorrent
|
|||||||
if (e)
|
if (e)
|
||||||
{
|
{
|
||||||
(*h)(e);
|
(*h)(e);
|
||||||
close();
|
asio::error_code ec;
|
||||||
|
close(ec);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -236,7 +248,8 @@ namespace libtorrent
|
|||||||
if (e)
|
if (e)
|
||||||
{
|
{
|
||||||
(*h)(e);
|
(*h)(e);
|
||||||
close();
|
asio::error_code ec;
|
||||||
|
close(ec);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -248,7 +261,8 @@ namespace libtorrent
|
|||||||
if (version < 5)
|
if (version < 5)
|
||||||
{
|
{
|
||||||
(*h)(asio::error::operation_not_supported);
|
(*h)(asio::error::operation_not_supported);
|
||||||
close();
|
asio::error_code ec;
|
||||||
|
close(ec);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int response = read_uint8(p);
|
int response = read_uint8(p);
|
||||||
@ -267,7 +281,8 @@ namespace libtorrent
|
|||||||
case 8: e = asio::error::address_family_not_supported; break;
|
case 8: e = asio::error::address_family_not_supported; break;
|
||||||
}
|
}
|
||||||
(*h)(e);
|
(*h)(e);
|
||||||
close();
|
asio::error_code ec;
|
||||||
|
close(ec);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
p += 1; // reserved
|
p += 1; // reserved
|
||||||
@ -291,7 +306,8 @@ namespace libtorrent
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
(*h)(asio::error::operation_not_supported);
|
(*h)(asio::error::operation_not_supported);
|
||||||
close();
|
asio::error_code ec;
|
||||||
|
close(ec);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_buffer.resize(skip_bytes);
|
m_buffer.resize(skip_bytes);
|
||||||
@ -305,7 +321,8 @@ namespace libtorrent
|
|||||||
if (e)
|
if (e)
|
||||||
{
|
{
|
||||||
(*h)(e);
|
(*h)(e);
|
||||||
close();
|
asio::error_code ec;
|
||||||
|
close(ec);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -287,6 +287,9 @@ namespace libtorrent
|
|||||||
#ifndef TORRENT_DISABLE_DHT
|
#ifndef TORRENT_DISABLE_DHT
|
||||||
bool torrent::should_announce_dht() const
|
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
|
// don't announce private torrents
|
||||||
if (m_torrent_file->is_valid() && m_torrent_file->priv()) return false;
|
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)));
|
bind(&torrent::on_announce_disp, self, _1)));
|
||||||
|
|
||||||
// announce with the local discovery service
|
// 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
|
else
|
||||||
{
|
{
|
||||||
@ -444,13 +448,12 @@ namespace libtorrent
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifndef TORRENT_DISABLE_DHT
|
#ifndef TORRENT_DISABLE_DHT
|
||||||
|
if (m_paused) return;
|
||||||
if (!m_ses.m_dht) return;
|
if (!m_ses.m_dht) return;
|
||||||
ptime now = time_now();
|
ptime now = time_now();
|
||||||
if (should_announce_dht() && now - m_last_dht_announce > minutes(14))
|
if (should_announce_dht() && now - m_last_dht_announce > minutes(14))
|
||||||
{
|
{
|
||||||
m_last_dht_announce = now;
|
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;
|
if (m_ses.m_listen_sockets.empty()) return;
|
||||||
m_ses.m_dht->announce(m_torrent_file->info_hash()
|
m_ses.m_dht->announce(m_torrent_file->info_hash()
|
||||||
, m_ses.m_listen_sockets.front().external_port
|
, m_ses.m_listen_sockets.front().external_port
|
||||||
@ -2250,15 +2253,15 @@ namespace libtorrent
|
|||||||
|
|
||||||
#ifndef TORRENT_DISABLE_DHT
|
#ifndef TORRENT_DISABLE_DHT
|
||||||
// only start the announce if we want to announce with the 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
|
// 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());
|
boost::weak_ptr<torrent> self(shared_from_this());
|
||||||
m_announce_timer.expires_from_now(seconds(1));
|
m_ses.m_dht->announce(m_torrent_file->info_hash()
|
||||||
m_announce_timer.async_wait(m_ses.m_strand.wrap(
|
, m_ses.m_listen_sockets.front().external_port
|
||||||
bind(&torrent::on_announce_disp, self, _1)));
|
, m_ses.m_strand.wrap(bind(&torrent::on_dht_announce_response_disp, self, _1)));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@ -306,10 +306,12 @@ namespace libtorrent
|
|||||||
|
|
||||||
namespace
|
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
|
size_type range_start = size_type(range.piece) * piece_size + range.start;
|
||||||
&& range.start + range.length >= req.start + req.length;
|
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();
|
torrent_info const& info = t->torrent_file();
|
||||||
|
|
||||||
if (m_requests.empty() || m_file_requests.empty())
|
if (m_requests.empty() || m_file_requests.empty())
|
||||||
@ -480,16 +485,16 @@ namespace libtorrent
|
|||||||
, range_end - range_start);
|
, range_end - range_start);
|
||||||
|
|
||||||
peer_request front_request = m_requests.front();
|
peer_request front_request = m_requests.front();
|
||||||
|
/*
|
||||||
size_type rs = size_type(in_range.piece) * info.piece_length() + in_range.start;
|
size_type rs = size_type(in_range.piece) * info.piece_length() + in_range.start;
|
||||||
size_type re = rs + in_range.length;
|
size_type re = rs + in_range.length;
|
||||||
size_type fs = size_type(front_request.piece) * info.piece_length() + front_request.start;
|
size_type fs = size_type(front_request.piece) * info.piece_length() + front_request.start;
|
||||||
size_type fe = fs + front_request.length;
|
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
|
// 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
|
// http_body.begin is now in sync with the request at the front
|
||||||
// of the request queue
|
// of the request queue
|
||||||
@ -504,11 +509,16 @@ namespace libtorrent
|
|||||||
bool range_overlaps_request = in_range.start + in_range.length
|
bool range_overlaps_request = in_range.start + in_range.length
|
||||||
> front_request.start + int(m_piece.size());
|
> 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
|
// 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
|
// 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
|
// will receive enough to call incoming_piece() and pass the read buffer
|
||||||
// directly (in the next loop below).
|
// 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
|
// the start of the next block to receive is stored
|
||||||
// in m_piece. We need to append the rest of that
|
// 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
|
// report all received blocks to the bittorrent engine
|
||||||
while (!m_requests.empty()
|
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)
|
&& recv_buffer.left() >= m_requests.front().length)
|
||||||
{
|
{
|
||||||
peer_request r = m_requests.front();
|
peer_request r = m_requests.front();
|
||||||
|
|||||||
@ -96,12 +96,7 @@ class movetorrentMenu:
|
|||||||
if path:
|
if path:
|
||||||
self.paused_or_not = {}
|
self.paused_or_not = {}
|
||||||
for unique_id in unique_ids:
|
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)
|
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):
|
def configure(self, window):
|
||||||
import os.path
|
import os.path
|
||||||
|
|||||||
@ -63,7 +63,7 @@ class plugin_Search:
|
|||||||
### Note: All other plugins should use self.interface.toolbar
|
### Note: All other plugins should use self.interface.toolbar
|
||||||
### when adding items to the toolbar
|
### when adding items to the toolbar
|
||||||
self.se = ''
|
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.engines = deluge.pref.Preferences(self.conf_file, False)
|
||||||
self.search_entry = gtk.Entry()
|
self.search_entry = gtk.Entry()
|
||||||
self.search_entry.connect("activate", self.torrent_search)
|
self.search_entry.connect("activate", self.torrent_search)
|
||||||
|
|||||||
@ -75,6 +75,5 @@ class webseedMenu:
|
|||||||
self.dialog.hide()
|
self.dialog.hide()
|
||||||
if response:
|
if response:
|
||||||
text = self.glade.get_widget("txt_url").get_text().strip()
|
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)
|
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"
|
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:
|
Other contributors:
|
||||||
*somedude : template enhancements.
|
*somedude : template enhancements.
|
||||||
@ -203,11 +205,8 @@ class ConfigDialog(gtk.Dialog):
|
|||||||
gtk.combo_box_new_text())
|
gtk.combo_box_new_text())
|
||||||
self.cache_templates = self.add_widget(_('Cache Templates'),
|
self.cache_templates = self.add_widget(_('Cache Templates'),
|
||||||
gtk.CheckButton())
|
gtk.CheckButton())
|
||||||
"""
|
self.use_https = self.add_widget(_('https://'),
|
||||||
temporary disable for 0.5.7
|
|
||||||
self.use_https = self.add_widget(_('Use https://'),
|
|
||||||
gtk.CheckButton())
|
gtk.CheckButton())
|
||||||
"""
|
|
||||||
|
|
||||||
#self.share_downloads = self.add_widget(_('Share Download Directory'),
|
#self.share_downloads = self.add_widget(_('Share Download Directory'),
|
||||||
# gtk.CheckButton())
|
# gtk.CheckButton())
|
||||||
@ -236,7 +235,7 @@ class ConfigDialog(gtk.Dialog):
|
|||||||
# bool(self.config.get("share_downloads")))
|
# bool(self.config.get("share_downloads")))
|
||||||
|
|
||||||
self.cache_templates.set_active(self.config.get("cache_templates"))
|
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.vbox.pack_start(self.vb, True, True, 0)
|
||||||
self.vb.show_all()
|
self.vb.show_all()
|
||||||
@ -272,7 +271,7 @@ class ConfigDialog(gtk.Dialog):
|
|||||||
self.config.set("template", self.template.get_active_text())
|
self.config.set("template", self.template.get_active_text())
|
||||||
self.config.set("button_style", self.button_style.get_active())
|
self.config.set("button_style", self.button_style.get_active())
|
||||||
self.config.set("cache_templates", self.cache_templates.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.set("share_downloads", self.share_downloads.get_active())
|
||||||
self.config.save(self.plugin.config_file)
|
self.config.save(self.plugin.config_file)
|
||||||
self.plugin.start_server() #restarts server
|
self.plugin.start_server() #restarts server
|
||||||
|
|||||||
@ -50,7 +50,7 @@ urls = (
|
|||||||
"/torrent/stop/(.*)", "torrent_stop",
|
"/torrent/stop/(.*)", "torrent_stop",
|
||||||
"/torrent/start/(.*)", "torrent_start",
|
"/torrent/start/(.*)", "torrent_start",
|
||||||
"/torrent/reannounce/(.*)", "torrent_reannounce",
|
"/torrent/reannounce/(.*)", "torrent_reannounce",
|
||||||
"/torrent/add", "torrent_add",
|
"/torrent/add(.*)", "torrent_add",
|
||||||
"/torrent/delete/(.*)", "torrent_delete",
|
"/torrent/delete/(.*)", "torrent_delete",
|
||||||
"/torrent/queue/up/(.*)", "torrent_queue_up",
|
"/torrent/queue/up/(.*)", "torrent_queue_up",
|
||||||
"/torrent/queue/down/(.*)", "torrent_queue_down",
|
"/torrent/queue/down/(.*)", "torrent_queue_down",
|
||||||
@ -98,21 +98,36 @@ class index:
|
|||||||
@deluge_page
|
@deluge_page
|
||||||
@auto_refreshed
|
@auto_refreshed
|
||||||
def GET(self, name):
|
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()]
|
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:
|
#sorting:
|
||||||
if vars.sort:
|
if vars.sort:
|
||||||
status_rows.sort(key=attrgetter(vars.sort))
|
torrent_list.sort(key=attrgetter(vars.sort))
|
||||||
if vars.order == 'up':
|
if vars.order == 'up':
|
||||||
status_rows = reversed(status_rows)
|
torrent_list = reversed(torrent_list)
|
||||||
|
|
||||||
setcookie("order", vars.order)
|
setcookie("order", vars.order)
|
||||||
setcookie("sort", vars.sort)
|
setcookie("sort", vars.sort)
|
||||||
|
|
||||||
return ws.render.index(status_rows)
|
return ws.render.index(torrent_list, all_torrents)
|
||||||
|
|
||||||
class torrent_info:
|
class torrent_info:
|
||||||
@deluge_page
|
@deluge_page
|
||||||
@ -162,16 +177,29 @@ class torrent_add:
|
|||||||
|
|
||||||
@check_session
|
@check_session
|
||||||
def POST(self, name):
|
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."))
|
error_page(_("Choose an url or a torrent, not both."))
|
||||||
if vars.url:
|
if vars.url:
|
||||||
ws.proxy.add_torrent_url(vars.url)
|
ws.proxy.add_torrent_url(vars.url)
|
||||||
do_redirect()
|
do_redirect()
|
||||||
elif vars.torrent.filename:
|
elif torrent_name:
|
||||||
data = vars.torrent.file.read()
|
data_b64 = base64.b64encode(torrent_data)
|
||||||
data_b64 = base64.b64encode(data)
|
|
||||||
#b64 because of strange bug-reports related to binary data
|
#b64 because of strange bug-reports related to binary data
|
||||||
ws.proxy.add_torrent_filecontent(vars.torrent.filename, data_b64)
|
ws.proxy.add_torrent_filecontent(vars.torrent.filename, data_b64)
|
||||||
do_redirect()
|
do_redirect()
|
||||||
@ -213,14 +241,24 @@ class torrent_delete:
|
|||||||
class torrent_queue_up:
|
class torrent_queue_up:
|
||||||
@check_session
|
@check_session
|
||||||
def POST(self, name):
|
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)
|
ws.proxy.queue_up(torrent_id)
|
||||||
do_redirect()
|
do_redirect()
|
||||||
|
|
||||||
class torrent_queue_down:
|
class torrent_queue_down:
|
||||||
@check_session
|
@check_session
|
||||||
def POST(self, name):
|
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)
|
ws.proxy.queue_down(torrent_id)
|
||||||
do_redirect()
|
do_redirect()
|
||||||
|
|
||||||
|
|||||||
@ -1 +1 @@
|
|||||||
143
|
160
|
||||||
|
|||||||
@ -1,13 +1,18 @@
|
|||||||
from __future__ import with_statement
|
from __future__ import with_statement
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
template_dir = '~/prj/WebUi/templates/deluge'
|
template_dirs = ['~/prj/WebUi/templates/deluge',
|
||||||
template_dir = os.path.expanduser(template_dir )
|
'~/prj/WebUi/templates/advanced']
|
||||||
|
|
||||||
|
template_dirs = [os.path.expanduser(template_dir ) for template_dir in template_dirs]
|
||||||
|
|
||||||
|
|
||||||
files = [os.path.join(template_dir,fname)
|
files = []
|
||||||
for fname in os.listdir(template_dir)
|
for template_dir in template_dirs:
|
||||||
if fname.endswith('.html')]
|
files += [os.path.join(template_dir,fname)
|
||||||
|
for fname in os.listdir(template_dir)
|
||||||
|
if fname.endswith('.html')]
|
||||||
|
|
||||||
|
|
||||||
all_strings = []
|
all_strings = []
|
||||||
for filename in files:
|
for filename in files:
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
_('# Of Files')
|
_('# Of Files')
|
||||||
_('About')
|
_('About')
|
||||||
|
_('Add')
|
||||||
_('Add Torrent')
|
_('Add Torrent')
|
||||||
_('Add torrent')
|
_('Add torrent')
|
||||||
_('Apply')
|
_('Apply')
|
||||||
@ -13,6 +14,7 @@ _('Delete .torrent file')
|
|||||||
_('Delete downloaded files.')
|
_('Delete downloaded files.')
|
||||||
_('Details')
|
_('Details')
|
||||||
_('Disable')
|
_('Disable')
|
||||||
|
_('Down')
|
||||||
_('Down Speed')
|
_('Down Speed')
|
||||||
_('Download')
|
_('Download')
|
||||||
_('Downloaded')
|
_('Downloaded')
|
||||||
@ -27,19 +29,20 @@ _('Next Announce')
|
|||||||
_('Off')
|
_('Off')
|
||||||
_('Password')
|
_('Password')
|
||||||
_('Password is invalid,try again')
|
_('Password is invalid,try again')
|
||||||
|
_('Pause')
|
||||||
_('Pause all')
|
_('Pause all')
|
||||||
_('Peers')
|
_('Peers')
|
||||||
_('Pieces')
|
_('Pieces')
|
||||||
_('Progress')
|
_('Progress')
|
||||||
_('Queue Down')
|
_('Queue Down')
|
||||||
|
_('Queue Position')
|
||||||
_('Queue Up')
|
_('Queue Up')
|
||||||
_('Queue pos:')
|
|
||||||
_('Ratio')
|
_('Ratio')
|
||||||
_('Reannounce')
|
_('Reannounce')
|
||||||
_('Refresh page every:')
|
_('Refresh page every:')
|
||||||
_('Remove')
|
_('Remove')
|
||||||
_('Remove %s ')
|
_('Remove torrent')
|
||||||
_('Remove %s?')
|
_('Resume')
|
||||||
_('Resume all')
|
_('Resume all')
|
||||||
_('Seeders')
|
_('Seeders')
|
||||||
_('Set')
|
_('Set')
|
||||||
@ -47,11 +50,13 @@ _('Set Timeout')
|
|||||||
_('Share Ratio')
|
_('Share Ratio')
|
||||||
_('Size')
|
_('Size')
|
||||||
_('Speed')
|
_('Speed')
|
||||||
|
_('Start')
|
||||||
_('Submit')
|
_('Submit')
|
||||||
_('Torrent list')
|
_('Torrent list')
|
||||||
_('Total Size')
|
_('Total Size')
|
||||||
_('Tracker')
|
_('Tracker')
|
||||||
_('Tracker Status')
|
_('Tracker Status')
|
||||||
|
_('Up')
|
||||||
_('Up Speed')
|
_('Up Speed')
|
||||||
_('Upload')
|
_('Upload')
|
||||||
_('Upload torrent')
|
_('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 @@
|
|||||||
div.progress_bar_outer { /*used in table-view*/
|
div.progress_bar_outer { /*used in table-view*/
|
||||||
width:150px;
|
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;
}
|
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 {
|
div.panel {
|
||||||
padding:10px;
|
padding:10px;
|
||||||
@ -55,9 +58,6 @@ tr.torrent_table_selected {
|
|||||||
background-color:#900;
|
background-color:#900;
|
||||||
}
|
}
|
||||||
|
|
||||||
th.torrent_table:hover {
|
|
||||||
background-color:#68a;
|
|
||||||
}
|
|
||||||
|
|
||||||
img.button {
|
img.button {
|
||||||
margin-bottom:0px;
|
margin-bottom:0px;
|
||||||
@ -71,4 +71,21 @@ body.inner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
form.pause_resume {
|
||||||
|
margin:0;
|
||||||
|
padding:0;
|
||||||
|
border:0;
|
||||||
|
}
|
||||||
|
|
||||||
|
th {
|
||||||
|
background: #1f3044;
|
||||||
|
font-size: 14px;
|
||||||
|
border: 0px;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
#torrent_table {
|
||||||
|
border: #2a425c 1px solid;
|
||||||
|
}
|
||||||
|
|
||||||
/* Hides from IE-mac \*/
* html .clearfix {height: 1%;}
.clearfix {display: block;}
/* End hide from IE-mac */
|
/* Hides from IE-mac \*/
* html .clearfix {height: 1%;}
.clearfix {display: block;}
/* End hide from IE-mac */
|
||||||
@ -1,14 +1,49 @@
|
|||||||
$def with (torrent_list)
|
$def with (torrent_list, all_torrents)
|
||||||
$:render.header(_('Torrent list'))
|
$:render.header(_('Torrent list'))
|
||||||
|
|
||||||
|
<div class="panel" id="toolbar">
|
||||||
|
|
||||||
<a href='/torrent/add' >[Add]</a>
|
<a class='toolbar_btn' href="#"
|
||||||
<a href='#' onclick=' toolbar_post("/torrent/queue/up/")'>[Up]</a>
|
onclick='toolbar_get("/torrent/add/",0)'
|
||||||
<a href='#' onclick=' toolbar_post("/torrent/queue/down/")'>[Down]</a>
|
title='$_("Add")'><img class='toolbar_btn'
|
||||||
<a href='#' onclick=' toolbar_get("/torrent/delete/")'>[Delete]</a>
|
src='/static/images/tango/list-add.png'></a>
|
||||||
<a href='#' onclick=' toolbar_get("/torrent/info/")'>[Info]</a>
|
|
||||||
<a href='#' onclick=' toolbar_post("/torrent/stop/")'>[Pause]</a>
|
<a class='toolbar_btn' href="#"
|
||||||
<a href='#' onclick=' toolbar_post("/torrent/start/")'>[Start]</a>
|
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">
|
<div id="tableContainer" class="tableContainer">
|
||||||
<table class="torrent_list" border=1>
|
<table class="torrent_list" border=1 id="torrent_list">
|
||||||
<thead class="fixedHeader">
|
<thead class="fixedHeader">
|
||||||
<tr>
|
<tr>
|
||||||
$:(sort_head('calc_state_str', 'S'))
|
$:(sort_head('calc_state_str', 'S'))
|
||||||
@ -32,6 +67,7 @@ $#end
|
|||||||
$:(sort_head('name', _('Name')))
|
$:(sort_head('name', _('Name')))
|
||||||
$:(sort_head('total_size', _('Size')))
|
$:(sort_head('total_size', _('Size')))
|
||||||
$:(sort_head('progress', _('Progress')))
|
$:(sort_head('progress', _('Progress')))
|
||||||
|
$:(sort_head('category', _('Tracker')))
|
||||||
$:(sort_head('num_seeds', _('Seeders')))
|
$:(sort_head('num_seeds', _('Seeders')))
|
||||||
$:(sort_head('num_peers', _('Peers')))
|
$:(sort_head('num_peers', _('Peers')))
|
||||||
$:(sort_head('download_rate', _('Download')))
|
$:(sort_head('download_rate', _('Download')))
|
||||||
@ -45,11 +81,14 @@ $#end
|
|||||||
$#4-space indentation is mandatory for for-loops in templetor!
|
$#4-space indentation is mandatory for for-loops in templetor!
|
||||||
$for torrent in torrent_list:
|
$for torrent in torrent_list:
|
||||||
<tr class="torrent_table" onclick="on_click_row(event, '$torrent.id')" id="torrent_$torrent.id">
|
<tr class="torrent_table" onclick="on_click_row(event, '$torrent.id')" id="torrent_$torrent.id">
|
||||||
<td><input type="image"
|
<td>
|
||||||
src="/static/images/$(torrent.calc_state_str)16.png"
|
<form action="/torrent/$torrent.action/$torrent.id" method="POST"
|
||||||
name="$torrent.action" value="$torrent.id"
|
class="pause_resume">
|
||||||
onclick="state.row_js_continue = false;">
|
<input type="image"
|
||||||
</td>
|
src="/static/images/$(torrent.calc_state_str)16.png"
|
||||||
|
name="pauseresume" value="submit" />
|
||||||
|
</form>
|
||||||
|
</td>
|
||||||
<td>$torrent.queue_pos</td>
|
<td>$torrent.queue_pos</td>
|
||||||
<td style="width:100px; overflow:hidden;white-space: nowrap">
|
<td style="width:100px; overflow:hidden;white-space: nowrap">
|
||||||
$(crop(torrent.name, 40))</td>
|
$(crop(torrent.name, 40))</td>
|
||||||
@ -61,10 +100,21 @@ $for torrent in torrent_list:
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
|
<td>$torrent.category</td>
|
||||||
<td>$torrent.num_seeds ($torrent.total_seeds)</td>
|
<td>$torrent.num_seeds ($torrent.total_seeds)</td>
|
||||||
<td>$torrent.num_peers ($torrent.total_peers)</td>
|
<td>$torrent.num_peers ($torrent.total_peers)</td>
|
||||||
<td>$fspeed(torrent.download_rate)</td>
|
<td>
|
||||||
<td>$fspeed(torrent.upload_rate)</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>$torrent.eta</td>
|
||||||
<td>$("%.3f" % torrent.distributed_copies)</td>
|
<td>$("%.3f" % torrent.distributed_copies)</td>
|
||||||
<td>$("%.3f" % torrent.ratio)</td\>
|
<td>$("%.3f" % torrent.ratio)</td\>
|
||||||
@ -73,7 +123,6 @@ $for torrent in torrent_list:
|
|||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</form>
|
|
||||||
|
|
||||||
$:part_stats()
|
$:part_stats()
|
||||||
|
|
||||||
@ -84,6 +133,8 @@ $:part_stats()
|
|||||||
</iframe>
|
</iframe>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<script language='javascript'>
|
<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
-----------------------------------------------------------
*/
BODY {
background: #304663 url(../../static/images/simple_bg.jpg) repeat-x;
font-family: Bitstream Vera;
font-size: 10pt;
margin: 0;
|
/*
-----------------------------------------------------------
Theme Name: Simple
Theme URI: http://deluge-torrent.org
Description: Deluge Theme
Version: 1.0
-----------------------------------------------------------
*/
BODY {
background: #304663 url(../../static/images/simple_bg.jpg) repeat-x;
font-family: Bitstream Vera,Verdana;
font-size: 10pt;
margin: 0;
|
||||||
padding:0;
|
padding:0;
|
||||||
border:0;
}
/* GENERIC STYLES */
a img {border: 0px}
hr {color: #627082; margin: 15px 0 15px 0;}
|
border:0;
}
/* GENERIC STYLES */
a img {border: 0px}
hr {color: #627082; margin: 15px 0 15px 0;}
|
||||||
td {font-family: Bitstream Vera;}
/* STRUCTURE */
#page {
min-width: 800px;
margin-left: auto;
margin-right: auto;
|
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 */
#page {
min-width: 800px;
margin-left: auto;
margin-right: auto;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding:0;
|
padding:0;
|
||||||
font-family: Bitstream Vera;
}
#main_content {
background:url(../../static/images/simple_line.jpg) repeat-x;
|
font-family: Bitstream Vera,Verdana;
}
#main_content {
background:url(../../static/images/simple_line.jpg) repeat-x;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding:0;
}
#simple_logo {
background:url(../../static/images/simple_logo.jpg) no-repeat;
}
#main {
|
padding:0;
}
#simple_logo {
background:url(../../static/images/simple_logo.jpg) no-repeat;
}
#main {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding:0;
padding-top: 20px;
color: #fff;
}
#main form table {
border: #2a425c 1px solid;
}
#main form table tr {
border: 0px;
}
#main form table tr th {
background: #1f3044;
font-size: 16px;
border: 0px;
|
padding:0;
padding-top: 6px;
color: #fff;
}
#main form table {
border: #2a425c 1px solid;
}
#main form table tr {
border: 0px;
}
#main form table tr th {
background: #1f3044;
font-size: 16px;
border: 0px;
|
||||||
white-space: nowrap;
}
#main form table tr td{
border: 0px;
color: #fff;
font-size: 12px;
white-space: nowrap;
}
#main form table tr th a {
color: #8fa6c3;
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;
}
#main a, a:active, a:visited { color: #fff; text-decoration: none;}
#main a:hover {color: #fff; text-decoration: underline;}
.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;
padding: 10px 50px 0 0;
text-align: right;
}
.title a, a:active, a:visited { color: #dce4ee; text-decoration: none;}
.title a:hover {color: #fff; text-decoration: underline;}
#button {
border:1px solid #23344b;
background: #99acc3;
color: #000;
|
white-space: nowrap;
}
#main form table tr td{
border: 0px;
color: #fff;
font-size: 12px;
white-space: nowrap;
|
||||||
font-family: Bitstream Vera;
font-size:10px;
margin-top:5px;
}
INPUT{
border:1px solid #23344b;
background: #99acc3;
color: #000;
}
TEXTAREA{
border:1px solid #23344b;
background: #99acc3;
width:480px;
}
.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;
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*/
}
|
font-family: Bitstream Vera,Verdana;
}
#main form table tr th a {
color: #8fa6c3;
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;
|
||||||
|
font-family: Bitstream Vera,Verdana;
}
#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;
}
#main a, a:active, a:visited { color: #fff; text-decoration: none;}
#main a:hover {color: #fff; text-decoration: underline;}
.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;
padding: 10px 50px 0 0;
text-align: right;
}
.title a, a:active, a:visited { color: #dce4ee; text-decoration: none;}
.title a:hover {color: #fff; text-decoration: underline;}
input{
|
||||||
|
background-color: #37506f;
|
||||||
|
border:1px solid #68a;
|
||||||
|
|
||||||
|
background: #99acc3;
|
||||||
|
color: #000;
|
||||||
|
/*vertical-align:middle;*/
|
||||||
|
-moz-border-radius:5px;
|
||||||
|
/*margin-top:5px;*/
|
||||||
|
}
|
||||||
|
|
||||||
|
input:hover {
|
||||||
|
background-color:#68a;
|
||||||
|
}
TEXTAREA{
border:1px solid #23344b;
background: #99acc3;
width:480px;
}
.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*/
|
div.progress_bar_outer { /*used in table-view*/
|
||||||
width:150px;
|
width:150px;
|
||||||
@ -92,6 +108,12 @@ body.inner {
|
|||||||
padding:0;
|
padding:0;
|
||||||
text-align:left;
|
text-align:left;
|
||||||
height:20px;
|
height:20px;
|
||||||
|
background-color:#ddd;
|
||||||
|
color:#000;
|
||||||
|
border-style:solid;
|
||||||
|
border:0;
|
||||||
|
border-top:1px;
|
||||||
|
border-color:#000;
|
||||||
}
|
}
|
||||||
|
|
||||||
#about {
|
#about {
|
||||||
@ -110,15 +132,18 @@ body.inner {
|
|||||||
|
|
||||||
#refresh_panel {
|
#refresh_panel {
|
||||||
-moz-border-radius:0px;
|
-moz-border-radius:0px;
|
||||||
width:100%;
|
width:350px;
|
||||||
position:fixed;
|
position:fixed;
|
||||||
bottom:20px;
|
bottom:0px;
|
||||||
left:0px;
|
right:0px;
|
||||||
background-color:#304663;
|
background-color:#304663;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding:0;
|
padding:0;
|
||||||
text-align:right;
|
text-align:right;
|
||||||
height:20px;
|
height:20px;
|
||||||
|
background-color:#ddd;
|
||||||
|
color:#000;
|
||||||
|
z-index:999;
|
||||||
}
|
}
|
||||||
|
|
||||||
#refresh_panel button {
|
#refresh_panel button {
|
||||||
@ -128,9 +153,95 @@ body.inner {
|
|||||||
position:relative;
|
position:relative;
|
||||||
top:0px;
|
top:0px;
|
||||||
height:20px;
|
height:20px;
|
||||||
|
background-color:#ddd;
|
||||||
|
color:#000;
|
||||||
}
|
}
|
||||||
#refresh_panel button:hover {
|
#refresh_panel button:hover {
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#category_panel {
|
||||||
|
margin-bottom:0;
|
||||||
|
padding-bottom:0;
|
||||||
|
-moz-border-radius-bottomleft:0px;
|
||||||
|
-moz-border-radius-bottomright:0px;
|
||||||
|
padding-right:32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#toolbar {
|
||||||
|
text-align:left;
|
||||||
|
margin-top:0;
|
||||||
|
padding-top:0;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
-moz-border-radius-topleft:0px;
|
||||||
|
-moz-border-radius-topright:0px;
|
||||||
|
padding-top:5px;
|
||||||
|
padding-bottom:5px;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
padding-left:32px;
|
||||||
|
height:20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#toolbar select{
|
||||||
|
/*border:1px solid #68a;*/
|
||||||
|
border:0;
|
||||||
|
background-color: #37506f;
|
||||||
|
color: #FFF;
|
||||||
|
}
|
||||||
|
#toolbar select:hover{
|
||||||
|
background-color:#68a;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.toolbar_btn {
|
||||||
|
width:20px;
|
||||||
|
height:20px;
|
||||||
|
padding-left:3px;
|
||||||
|
padding-top:7px;
|
||||||
|
padding-right:3px;
|
||||||
|
text-decoration: none;
|
||||||
|
margin-bottom:3px;
|
||||||
|
}
|
||||||
|
a.toolbar_btn:hover {
|
||||||
|
background-color:#68a;
|
||||||
|
-moz-border-radius:5px;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#toolbar_refresh {
|
||||||
|
margin:0;
|
||||||
|
border:0;
|
||||||
|
background-color:none;
|
||||||
|
padding-left:2px;
|
||||||
|
padding-top:2px;
|
||||||
|
padding-right:2px;
|
||||||
|
text-decoration: none;
|
||||||
|
background-color: #37506f;
|
||||||
|
position:relative;
|
||||||
|
top:5px;
|
||||||
|
}
|
||||||
|
#toolbar_refresh:hover {
|
||||||
|
background-color:#68a;
|
||||||
|
-moz-border-radius:5px;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
#category_form{
|
||||||
|
display:inline;
|
||||||
|
position:relative;
|
||||||
|
top:-3px;
|
||||||
|
padding-left:20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
form { /*all forms!*/
|
||||||
|
margin:0;
|
||||||
|
padding:0;
|
||||||
|
border:0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#torrent_list {
|
||||||
|
-moz-border-radius:7px;
|
||||||
|
}
|
||||||
/* Hides from IE-mac \*/
* html .clearfix {height: 1%;}
.clearfix {display: block;}
/* End hide from IE-mac */
|
/* Hides from IE-mac \*/
* html .clearfix {height: 1%;}
.clearfix {display: block;}
/* End hide from IE-mac */
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -29,10 +29,17 @@ function on_click_row(e,id) {
|
|||||||
function on_click_row_js(e, id) {
|
function on_click_row_js(e, id) {
|
||||||
/*real onClick event*/
|
/*real onClick event*/
|
||||||
if (!e.ctrlKey) {
|
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){
|
function select_row(id){
|
||||||
@ -43,19 +50,30 @@ function select_row(id){
|
|||||||
setCookie('selected_rows',state.selected_rows);
|
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){
|
function deselect_row(id){
|
||||||
var row = get_row(id);
|
var row = get_row(id);
|
||||||
if (row) {
|
if (row) {
|
||||||
row.className = 'torrent_table'
|
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(){
|
function reselect_rows(){
|
||||||
var selected_rows = getCookie('selected_rows').split(',');
|
var selected_rows = getCookie('selected_rows').split(',');
|
||||||
for (i in getCookie('selected_rows')) {
|
for (i in getCookie('selected_rows')) {
|
||||||
@ -79,19 +97,24 @@ function on_click_do_nothing(e, id){
|
|||||||
on_click_action = on_click_do_nothing;
|
on_click_action = on_click_do_nothing;
|
||||||
|
|
||||||
/*toobar buttons, */
|
/*toobar buttons, */
|
||||||
function toolbar_post(url) {
|
function toolbar_post(url, selected) {
|
||||||
/*this feels hacky, but it's the only way i know of*/
|
if ((!selected) || (state.selected_rows.length > 0)) {
|
||||||
var ids = state.selected_rows.join(',');
|
var ids = state.selected_rows.join(',');
|
||||||
var form = $('toolbar_form');
|
var form = $('toolbar_form');
|
||||||
form.action = url +ids;
|
form.action = url +ids;
|
||||||
form.submit();
|
form.submit();
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function toolbar_get(url) {
|
function toolbar_get(url , selected) {
|
||||||
/*this feels hacky, but it's the only way i know of*/
|
if (!selected) {
|
||||||
var ids = state.selected_rows.join(',');
|
window.location.href = url
|
||||||
window.location.href = url +ids;
|
}
|
||||||
|
else if (state.selected_rows.length > 0) {
|
||||||
|
var ids = state.selected_rows.join(',');
|
||||||
|
window.location.href = url +ids;
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
$def with (torrent_list)
|
$def with (torrent_list, all_torrents)
|
||||||
$:render.header(_('Torrent list'))
|
$:render.header(_('Torrent list'))
|
||||||
|
|
||||||
<table class="torrent_list" border=1>
|
<table class="torrent_list" border=0 id='torrent_table'>
|
||||||
<tr>
|
<tr>
|
||||||
$:(sort_head('calc_state_str', 'S'))
|
$:(sort_head('calc_state_str', 'S'))
|
||||||
$:(sort_head('queue_pos', '#'))
|
$:(sort_head('queue_pos', '#'))
|
||||||
@ -20,13 +20,10 @@ $#4-space indentation is mandatory for for-loops in templetor!
|
|||||||
$for torrent in torrent_list:
|
$for torrent in torrent_list:
|
||||||
<tr class="torrent_table" id="torrent_$torrent.id">
|
<tr class="torrent_table" id="torrent_$torrent.id">
|
||||||
<td>
|
<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"
|
<input type="image"
|
||||||
src="/static/images/$(torrent.calc_state_str)16.png"
|
src="/static/images/$(torrent.calc_state_str)16.png"
|
||||||
name="pauseresume" value="submit" />
|
name="pauseresume" value="submit" /></form></td>
|
||||||
</form>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td>$torrent.queue_pos</td>
|
<td>$torrent.queue_pos</td>
|
||||||
<td style="width:100px; overflow:hidden;white-space: nowrap">
|
<td style="width:100px; overflow:hidden;white-space: nowrap">
|
||||||
<a href="/torrent/info/$torrent.id" >
|
<a href="/torrent/info/$torrent.id" >
|
||||||
@ -53,8 +50,8 @@ $for torrent in torrent_list:
|
|||||||
|
|
||||||
<div class="panel">
|
<div class="panel">
|
||||||
$:render.part_button('GET', '/torrent/add', _('Add torrent'), 'tango/list-add.png')
|
$: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', '/pause_all', _('Pause all'), 'tango/pause.png')
|
||||||
$:render.part_button('POST', '/resume_all', _('Resume all'), 'tango/media-playback-start.png')
|
$:render.part_button('POST', '/resume_all', _('Resume all'), 'tango/start.png')
|
||||||
<!--$:render.part_button('POST', '/logout', _('Logout'), 'tango/system-log-out.png')-->
|
<!--$:render.part_button('POST', '/logout', _('Logout'), 'tango/system-log-out.png')-->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
$def with (column_id, column_name, order, active_up, active_down)
|
$def with (column_id, column_name, order, active_up, active_down)
|
||||||
<th class="torrent_table">
|
<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\
|
$column_name\
|
||||||
$if active_up:
|
$if active_up:
|
||||||
<img src="/static/images/tango/up.png" />
|
<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>
|
<td class="info_value">$torrent.num_files</td></tr>
|
||||||
|
|
||||||
<tr><td class="info_label">$_('Tracker'):</td>
|
<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>
|
<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>
|
<tr><td class="info_label">$_('Next Announce'):</td>
|
||||||
<td class="info_value">$torrent.next_announce </td></tr>
|
<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('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/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')
|
$: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..
|
#delete all, nice use case for refactoring delete..
|
||||||
torrent_ids = ws.proxy.get_session_state()
|
torrent_ids = ws.proxy.get_session_state()
|
||||||
for torrent in torrent_ids:
|
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()
|
torrent_ids = ws.proxy.get_session_state()
|
||||||
self.assertEqual(torrent_ids, [])
|
self.assertEqual(torrent_ids, [])
|
||||||
@ -237,14 +237,14 @@ class TestIntegration(TestWebUiBase):
|
|||||||
#pause all
|
#pause all
|
||||||
self.assert_303('/pause_all','/index', post=1)
|
self.assert_303('/pause_all','/index', post=1)
|
||||||
#pause worked?
|
#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:
|
for paused in pause_status:
|
||||||
self.assertEqual(paused, True)
|
self.assertEqual(paused, True)
|
||||||
|
|
||||||
#resume all
|
#resume all
|
||||||
self.assert_303('/resume_all','/index', post=1)
|
self.assert_303('/resume_all','/index', post=1)
|
||||||
#resume worked?
|
#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:
|
for paused in pause_status:
|
||||||
self.assertEqual(paused,False)
|
self.assertEqual(paused,False)
|
||||||
#pause again.
|
#pause again.
|
||||||
@ -253,10 +253,10 @@ class TestIntegration(TestWebUiBase):
|
|||||||
torrent_id = self.first_torrent_id
|
torrent_id = self.first_torrent_id
|
||||||
#single resume.
|
#single resume.
|
||||||
self.assert_303('/torrent/start/%s' % torrent_id ,'/index', post=1)
|
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
|
#single pause
|
||||||
self.assert_303('/torrent/stop/%s' % torrent_id,'/index', post=1)
|
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):
|
def testQueue(self):
|
||||||
#find last:
|
#find last:
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
revision-id: mvoncken@gmail.com-20070930083408-sv8mo0mi1rbjnfvk
|
revision-id: mvoncken@gmail.com-20070930083408-sv8mo0mi1rbjnfvk
|
||||||
date: 2007-11-21 15:10:08 +0200
|
date: 2007-11-26 15:10:08 +0200
|
||||||
build-date: 2007-11-21 15:34:50 +0200
|
build-date: 2007-11-26 15:34:50 +0200
|
||||||
revno: 143
|
revno: 160
|
||||||
branch-nick: WebUi
|
branch-nick: WebUi
|
||||||
|
|||||||
@ -42,7 +42,7 @@ import pickle
|
|||||||
import sys
|
import sys
|
||||||
from webpy022 import template
|
from webpy022 import template
|
||||||
random.seed()
|
random.seed()
|
||||||
path = os.path.dirname(__file__)
|
webui_path = os.path.dirname(__file__)
|
||||||
|
|
||||||
ENV = 'UNKNOWN'
|
ENV = 'UNKNOWN'
|
||||||
|
|
||||||
@ -68,11 +68,11 @@ class subclassed_render(object):
|
|||||||
"""
|
"""
|
||||||
def __init__(self, template_dirname, cache=False):
|
def __init__(self, template_dirname, cache=False):
|
||||||
self.base_template = template.render(
|
self.base_template = template.render(
|
||||||
os.path.join(path, 'templates/deluge/'),
|
os.path.join(webui_path, 'templates/deluge/'),
|
||||||
cache=cache)
|
cache=cache)
|
||||||
|
|
||||||
self.sub_template = template.render(
|
self.sub_template = template.render(
|
||||||
os.path.join(path, 'templates/%s/' % template_dirname),
|
os.path.join(webui_path, 'templates/%s/' % template_dirname),
|
||||||
cache=cache)
|
cache=cache)
|
||||||
|
|
||||||
def __getattr__(self, attr):
|
def __getattr__(self, attr):
|
||||||
|
|||||||
@ -56,6 +56,7 @@ from operator import attrgetter
|
|||||||
import datetime
|
import datetime
|
||||||
import pickle
|
import pickle
|
||||||
from md5 import md5
|
from md5 import md5
|
||||||
|
from urlparse import urlparse
|
||||||
|
|
||||||
from deluge import common
|
from deluge import common
|
||||||
from webserver_common import REVNO, VERSION
|
from webserver_common import REVNO, VERSION
|
||||||
@ -97,13 +98,20 @@ def do_redirect():
|
|||||||
"""for redirects after a POST"""
|
"""for redirects after a POST"""
|
||||||
vars = web.input(redir = None)
|
vars = web.input(redir = None)
|
||||||
ck = cookies()
|
ck = cookies()
|
||||||
|
url_vars = {}
|
||||||
|
|
||||||
if vars.redir:
|
if vars.redir:
|
||||||
seeother(vars.redir)
|
seeother(vars.redir)
|
||||||
elif ("order" in ck and "sort" in ck):
|
return
|
||||||
seeother(url("/index", sort=ck['sort'], order=ck['order']))
|
#todo:cleanup
|
||||||
else:
|
if ("order" in ck and "sort" in ck):
|
||||||
seeother(url("/index"))
|
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):
|
def error_page(error):
|
||||||
web.header("Content-Type", "text/html; charset=utf-8")
|
web.header("Content-Type", "text/html; charset=utf-8")
|
||||||
@ -211,6 +219,12 @@ def get_torrent_status(torrent_id):
|
|||||||
|
|
||||||
status["id"] = 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
|
#for naming the status-images
|
||||||
status.calc_state_str = "downloading"
|
status.calc_state_str = "downloading"
|
||||||
if status.paused:
|
if status.paused:
|
||||||
@ -219,7 +233,7 @@ def get_torrent_status(torrent_id):
|
|||||||
status.calc_state_str = "seeding"
|
status.calc_state_str = "seeding"
|
||||||
|
|
||||||
#action for torrent_pause
|
#action for torrent_pause
|
||||||
if status.calc_state_str == "inactive":
|
if status.user_paused:
|
||||||
status.action = "start"
|
status.action = "start"
|
||||||
else:
|
else:
|
||||||
status.action = "stop"
|
status.action = "stop"
|
||||||
@ -250,9 +264,59 @@ def get_torrent_status(torrent_id):
|
|||||||
raise Exception('Non Unicode for key:%s' % (k, ))
|
raise Exception('Non Unicode for key:%s' % (k, ))
|
||||||
return status
|
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
|
#/utils
|
||||||
|
|
||||||
#template-defs:
|
#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):
|
def template_crop(text, end):
|
||||||
if len(text) > end:
|
if len(text) > end:
|
||||||
return text[0:end - 3] + '...'
|
return text[0:end - 3] + '...'
|
||||||
@ -283,6 +347,7 @@ def get_config(var):
|
|||||||
template.Template.globals.update({
|
template.Template.globals.update({
|
||||||
'sort_head': template_sort_head,
|
'sort_head': template_sort_head,
|
||||||
'part_stats':template_part_stats,
|
'part_stats':template_part_stats,
|
||||||
|
'category_tabs':category_tabs,
|
||||||
'crop': template_crop,
|
'crop': template_crop,
|
||||||
'_': _ , #gettext/translations
|
'_': _ , #gettext/translations
|
||||||
'str': str, #because % in templetor is broken.
|
'str': str, #because % in templetor is broken.
|
||||||
@ -295,7 +360,6 @@ template.Template.globals.update({
|
|||||||
'rev': 'rev.%s' % (REVNO, ),
|
'rev': 'rev.%s' % (REVNO, ),
|
||||||
'version': VERSION,
|
'version': VERSION,
|
||||||
'getcookie':getcookie,
|
'getcookie':getcookie,
|
||||||
'js_enabled': lambda : ws.config.get('use_javascript'),
|
|
||||||
'get': lambda (var): getattr(web.input(**{var:None}), var) # unreadable :-(
|
'get': lambda (var): getattr(web.input(**{var:None}), var) # unreadable :-(
|
||||||
})
|
})
|
||||||
#/template-defs
|
#/template-defs
|
||||||
@ -304,14 +368,15 @@ def create_webserver(urls, methods):
|
|||||||
from webpy022.request import webpyfunc
|
from webpy022.request import webpyfunc
|
||||||
from webpy022 import webapi
|
from webpy022 import webapi
|
||||||
from gtk_cherrypy_wsgiserver import CherryPyWSGIServer
|
from gtk_cherrypy_wsgiserver import CherryPyWSGIServer
|
||||||
|
import os
|
||||||
|
|
||||||
func = webapi.wsgifunc(webpyfunc(urls, methods, False))
|
func = webapi.wsgifunc(webpyfunc(urls, methods, False))
|
||||||
server_address=("0.0.0.0", int(ws.config.get('port')))
|
server_address=("0.0.0.0", int(ws.config.get('port')))
|
||||||
|
|
||||||
server = CherryPyWSGIServer(server_address, func, server_name="localhost")
|
server = CherryPyWSGIServer(server_address, func, server_name="localhost")
|
||||||
if ws.config.get('use_https'):
|
if ws.config.get('use_https'):
|
||||||
server.ssl_certificate = ws.config.get('ssl_certificate')
|
server.ssl_certificate = os.path.join(ws.webui_path,'ssl/deluge.pem')
|
||||||
server.ssl_private_key = ws.config.get('ssl_private_key')
|
server.ssl_private_key = os.path.join(ws.webui_path,'ssl/deluge.key')
|
||||||
|
|
||||||
print "http://%s:%d/" % server_address
|
print "http://%s:%d/" % server_address
|
||||||
return server
|
return server
|
||||||
@ -321,4 +386,5 @@ __all__ = ['deluge_page_noauth', 'deluge_page', 'remote',
|
|||||||
'auto_refreshed', 'check_session',
|
'auto_refreshed', 'check_session',
|
||||||
'do_redirect', 'error_page','start_session','getcookie'
|
'do_redirect', 'error_page','start_session','getcookie'
|
||||||
,'setcookie','create_webserver','end_session',
|
,'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
Loading…
x
Reference in New Issue
Block a user