mirror of
https://git.deluge-torrent.org/deluge
synced 2025-04-24 13:34:50 +00:00
prepping for fix release
This commit is contained in:
parent
dbbace5f23
commit
ba7143acb9
57 changed files with 9535 additions and 450 deletions
|
@ -1,4 +1,8 @@
|
|||
Deluge 0.5.6 (xx October 2007)
|
||||
Deluge 0.5.7 (xx November 2007)
|
||||
* Set default piece size to 256-KiB in TorrentCreator plugin and add 2048KiB
|
||||
as a size option.
|
||||
|
||||
Deluge 0.5.6 (24 October 2007)
|
||||
* Web Interface Plugin
|
||||
* Hopefully fix "losing data" and having to re-download parts (for real this time :p)
|
||||
* Use new full allocation method which does not create files until one of its
|
||||
|
|
7
TODO
7
TODO
|
@ -1,2 +1,5 @@
|
|||
for 0.5.6
|
||||
1. fix ratio saving
|
||||
for 0.5.7
|
||||
1. manual recheck
|
||||
2. preference for .torrent location
|
||||
3. have blocklist detect 7zip files and popup a warning instead of crashing
|
||||
4. add auto-pickup folder
|
||||
|
|
|
@ -375,12 +375,6 @@ namespace libtorrent
|
|||
// buffers from.
|
||||
boost::pool<> m_send_buffers;
|
||||
|
||||
// this is where all active sockets are stored.
|
||||
// the selector can sleep while there's no activity on
|
||||
// them
|
||||
io_service m_io_service;
|
||||
asio::strand m_strand;
|
||||
|
||||
// the file pool that all storages in this session's
|
||||
// torrents uses. It sets a limit on the number of
|
||||
// open files by this session.
|
||||
|
@ -395,6 +389,12 @@ namespace libtorrent
|
|||
// object.
|
||||
disk_io_thread m_disk_thread;
|
||||
|
||||
// this is where all active sockets are stored.
|
||||
// the selector can sleep while there's no activity on
|
||||
// them
|
||||
io_service m_io_service;
|
||||
asio::strand m_strand;
|
||||
|
||||
// this is a list of half-open tcp connections
|
||||
// (only outgoing connections)
|
||||
// this has to be one of the last
|
||||
|
@ -646,7 +646,7 @@ namespace libtorrent
|
|||
|
||||
void debug_log(const std::string& line)
|
||||
{
|
||||
(*m_ses.m_logger) << line << "\n";
|
||||
(*m_ses.m_logger) << time_now_string() << " " << line << "\n";
|
||||
}
|
||||
session_impl& m_ses;
|
||||
};
|
||||
|
|
|
@ -56,6 +56,7 @@ public:
|
|||
void done(int ticket);
|
||||
void limit(int limit);
|
||||
int limit() const;
|
||||
void close();
|
||||
|
||||
#ifndef NDEBUG
|
||||
|
||||
|
|
|
@ -130,6 +130,8 @@ namespace libtorrent
|
|||
, proxy_settings const& ps
|
||||
, std::string const& password = "");
|
||||
|
||||
void close();
|
||||
|
||||
private:
|
||||
|
||||
boost::intrusive_ptr<http_tracker_connection> self()
|
||||
|
|
|
@ -357,6 +357,7 @@ namespace libtorrent
|
|||
// the different priority levels
|
||||
switch (piece_priority)
|
||||
{
|
||||
case 1: return prio;
|
||||
case 2: return prio - 1;
|
||||
case 3: return (std::max)(prio / 2, 1);
|
||||
case 4: return (std::max)(prio / 2 - 1, 1);
|
||||
|
|
|
@ -111,6 +111,7 @@ namespace libtorrent
|
|||
, initial_picker_threshold(4)
|
||||
, allowed_fast_set_size(10)
|
||||
, max_outstanding_disk_bytes_per_connection(64 * 1024)
|
||||
, handshake_timeout(10)
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
, use_dht_as_fallback(true)
|
||||
#endif
|
||||
|
@ -270,6 +271,11 @@ namespace libtorrent
|
|||
// to not completely disrupt normal downloads.
|
||||
int max_outstanding_disk_bytes_per_connection;
|
||||
|
||||
// the number of seconds to wait for a handshake
|
||||
// response from a peer. If no response is received
|
||||
// within this time, the peer is disconnected.
|
||||
int handshake_timeout;
|
||||
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
// while this is true, the dht will note be used unless the
|
||||
// tracker is online
|
||||
|
|
|
@ -240,8 +240,8 @@ namespace libtorrent
|
|||
|
||||
void parse_info_section(entry const& e);
|
||||
|
||||
entry extra(char const* key) const
|
||||
{ return m_extra_info[key]; }
|
||||
entry const* extra(char const* key) const
|
||||
{ return m_extra_info.find_key(key); }
|
||||
|
||||
// frees parts of the metadata that isn't
|
||||
// used by seeds
|
||||
|
|
|
@ -202,7 +202,7 @@ namespace libtorrent
|
|||
|
||||
void fail(int code, char const* msg);
|
||||
void fail_timeout();
|
||||
void close();
|
||||
virtual void close();
|
||||
address const& bind_interface() const { return m_bind_interface; }
|
||||
|
||||
protected:
|
||||
|
|
|
@ -74,6 +74,8 @@ namespace libtorrent
|
|||
, boost::weak_ptr<request_callback> c
|
||||
, session_settings const& stn);
|
||||
|
||||
void close();
|
||||
|
||||
private:
|
||||
|
||||
enum action_t
|
||||
|
|
|
@ -148,7 +148,18 @@ private:
|
|||
{
|
||||
mapping[0].protocol = 0;
|
||||
mapping[1].protocol = 1;
|
||||
#ifndef NDEBUG
|
||||
magic = 1337;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
~rootdevice()
|
||||
{
|
||||
TORRENT_ASSERT(magic == 1337);
|
||||
magic = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
// the interface url, through which the list of
|
||||
// supported interfaces are fetched
|
||||
|
@ -174,8 +185,12 @@ private:
|
|||
|
||||
mutable boost::shared_ptr<http_connection> upnp_connection;
|
||||
|
||||
#ifndef NDEBUG
|
||||
int magic;
|
||||
#endif
|
||||
void close() const
|
||||
{
|
||||
TORRENT_ASSERT(magic == 1337);
|
||||
if (!upnp_connection) return;
|
||||
upnp_connection->close();
|
||||
upnp_connection.reset();
|
||||
|
|
|
@ -48,8 +48,8 @@ namespace aux
|
|||
template<class IO_Control_Command>
|
||||
struct io_control_visitor_ec: boost::static_visitor<>
|
||||
{
|
||||
io_control_visitor_ec(IO_Control_Command& ioc, asio::error_code& ec)
|
||||
: ioc(ioc), ec(ec) {}
|
||||
io_control_visitor_ec(IO_Control_Command& ioc, asio::error_code& ec_)
|
||||
: ioc(ioc), ec(ec_) {}
|
||||
|
||||
template <class T>
|
||||
void operator()(T* p) const
|
||||
|
@ -188,7 +188,7 @@ namespace aux
|
|||
: boost::static_visitor<>
|
||||
{
|
||||
close_visitor_ec(asio::error_code& ec_)
|
||||
: ec(ec)
|
||||
: ec(ec_)
|
||||
{}
|
||||
|
||||
template <class T>
|
||||
|
@ -329,9 +329,9 @@ namespace aux
|
|||
struct read_some_visitor_ec
|
||||
: boost::static_visitor<std::size_t>
|
||||
{
|
||||
read_some_visitor_ec(Mutable_Buffers const& buffers, asio::error_code& ec)
|
||||
read_some_visitor_ec(Mutable_Buffers const& buffers, asio::error_code& ec_)
|
||||
: buffers(buffers)
|
||||
, ec(ec)
|
||||
, ec(ec_)
|
||||
{}
|
||||
|
||||
template <class T>
|
||||
|
|
|
@ -86,6 +86,11 @@ namespace libtorrent
|
|||
try_connect();
|
||||
}
|
||||
|
||||
void connection_queue::close()
|
||||
{
|
||||
m_timer.cancel();
|
||||
}
|
||||
|
||||
void connection_queue::limit(int limit)
|
||||
{ m_half_open_limit = limit; }
|
||||
|
||||
|
|
|
@ -341,6 +341,10 @@ namespace libtorrent
|
|||
// else std::cerr << "DISK THREAD: invoking callback" << std::endl;
|
||||
try { if (handler) handler(ret, j); }
|
||||
catch (std::exception&) {}
|
||||
|
||||
#ifndef NDEBUG
|
||||
m_current.storage = 0;
|
||||
#endif
|
||||
|
||||
if (j.buffer && free_buffer)
|
||||
{
|
||||
|
|
|
@ -489,7 +489,9 @@ namespace libtorrent
|
|||
, boost::lexical_cast<std::string>(m_port));
|
||||
m_name_lookup.async_resolve(q, m_strand.wrap(
|
||||
boost::bind(&http_tracker_connection::name_lookup, self(), _1, _2)));
|
||||
set_timeout(m_settings.tracker_completion_timeout
|
||||
set_timeout(req.event == tracker_request::stopped
|
||||
? m_settings.stop_tracker_timeout
|
||||
: m_settings.tracker_completion_timeout
|
||||
, m_settings.tracker_receive_timeout);
|
||||
}
|
||||
|
||||
|
@ -503,6 +505,17 @@ namespace libtorrent
|
|||
fail_timeout();
|
||||
}
|
||||
|
||||
void http_tracker_connection::close()
|
||||
{
|
||||
asio::error_code ec;
|
||||
m_socket.close(ec);
|
||||
m_name_lookup.cancel();
|
||||
if (m_connection_ticket > -1) m_cc.done(m_connection_ticket);
|
||||
m_connection_ticket = -1;
|
||||
m_timed_out = true;
|
||||
tracker_connection::close();
|
||||
}
|
||||
|
||||
void http_tracker_connection::name_lookup(asio::error_code const& error
|
||||
, tcp::resolver::iterator i) try
|
||||
{
|
||||
|
@ -759,7 +772,6 @@ namespace libtorrent
|
|||
if (m_parser.status_code() != 200)
|
||||
{
|
||||
fail(m_parser.status_code(), m_parser.message().c_str());
|
||||
close();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -821,6 +833,7 @@ namespace libtorrent
|
|||
TORRENT_ASSERT(false);
|
||||
}
|
||||
#endif
|
||||
close();
|
||||
}
|
||||
|
||||
peer_entry http_tracker_connection::extract_peer_info(const entry& info)
|
||||
|
|
|
@ -184,5 +184,6 @@ void lsd::on_announce(udp::endpoint const& from, char* buffer
|
|||
void lsd::close()
|
||||
{
|
||||
m_socket.close();
|
||||
m_broadcast_timer.cancel();
|
||||
}
|
||||
|
||||
|
|
|
@ -382,6 +382,8 @@ void natpmp::try_next_mapping(int i)
|
|||
|
||||
void natpmp::close()
|
||||
{
|
||||
asio::error_code ec;
|
||||
m_socket.close(ec);
|
||||
if (m_disabled) return;
|
||||
for (int i = 0; i < num_mappings; ++i)
|
||||
{
|
||||
|
@ -390,5 +392,7 @@ void natpmp::close()
|
|||
m_mappings[i].external_port = 0;
|
||||
refresh_mapping(i);
|
||||
}
|
||||
m_refresh_timer.cancel();
|
||||
m_send_timer.cancel();
|
||||
}
|
||||
|
||||
|
|
|
@ -3000,13 +3000,12 @@ namespace libtorrent
|
|||
return true;
|
||||
}
|
||||
|
||||
// if it takes more than 5 seconds to receive
|
||||
// handshake, disconnect
|
||||
if (in_handshake() && d > seconds(5))
|
||||
// do not stall waiting for a handshake
|
||||
if (in_handshake() && d > seconds(m_ses.settings().handshake_timeout))
|
||||
{
|
||||
#ifdef TORRENT_VERBOSE_LOGGING
|
||||
(*m_logger) << time_now_string() << " *** NO HANDSHAKE [ "
|
||||
<< total_seconds(d) << " seconds ago ] ***\n";
|
||||
(*m_logger) << time_now_string() << " *** NO HANDSHAKE [ waited "
|
||||
<< total_seconds(d) << " seconds ] ***\n";
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -547,8 +547,8 @@ namespace detail
|
|||
, fingerprint const& cl_fprint
|
||||
, char const* listen_interface)
|
||||
: m_send_buffers(send_buffer_size)
|
||||
, m_strand(m_io_service)
|
||||
, m_files(40)
|
||||
, m_strand(m_io_service)
|
||||
, m_half_open(m_io_service)
|
||||
, m_download_channel(m_io_service, peer_connection::download_channel)
|
||||
, m_upload_channel(m_io_service, peer_connection::upload_channel)
|
||||
|
@ -675,6 +675,14 @@ namespace detail
|
|||
if (m_dht) m_dht->stop();
|
||||
#endif
|
||||
m_timer.cancel();
|
||||
|
||||
// close the listen sockets
|
||||
for (std::list<listen_socket_t>::iterator i = m_listen_sockets.begin()
|
||||
, end(m_listen_sockets.end()); i != end; ++i)
|
||||
{
|
||||
i->sock->close();
|
||||
}
|
||||
|
||||
// abort all torrents
|
||||
for (torrent_map::iterator i = m_torrents.begin()
|
||||
, end(m_torrents.end()); i != end; ++i)
|
||||
|
@ -682,7 +690,15 @@ namespace detail
|
|||
i->second->abort();
|
||||
}
|
||||
|
||||
m_io_service.stop();
|
||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||
(*m_logger) << time_now_string() << " aborting all tracker requests\n";
|
||||
#endif
|
||||
m_tracker_manager.abort_all_requests();
|
||||
|
||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||
(*m_logger) << time_now_string() << " shutting down connection queue\n";
|
||||
#endif
|
||||
m_half_open.close();
|
||||
|
||||
mutex::scoped_lock l2(m_checker_impl.m_mutex);
|
||||
// abort the checker thread
|
||||
|
@ -977,6 +993,17 @@ namespace detail
|
|||
return;
|
||||
}
|
||||
|
||||
// don't allow more connections than the max setting
|
||||
if (m_connections.size() > max_connections())
|
||||
{
|
||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||
(*m_logger) << "number of connections limit exceeded (conns: "
|
||||
<< num_connections() << ", limit: " << max_connections()
|
||||
<< "), connection rejected\n";
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
// check if we have any active torrents
|
||||
// if we don't reject the connection
|
||||
if (m_torrents.empty()) return;
|
||||
|
@ -1474,20 +1501,12 @@ namespace detail
|
|||
while (!m_abort);
|
||||
|
||||
deadline_timer tracker_timer(m_io_service);
|
||||
// this will remove the port mappings
|
||||
if (m_natpmp.get())
|
||||
m_natpmp->close();
|
||||
if (m_upnp.get())
|
||||
m_upnp->close();
|
||||
|
||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||
(*m_logger) << time_now_string() << " locking mutex\n";
|
||||
#endif
|
||||
session_impl::mutex_t::scoped_lock l(m_mutex);
|
||||
|
||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||
(*m_logger) << time_now_string() << " aborting all tracker requests\n";
|
||||
#endif
|
||||
m_tracker_manager.abort_all_requests();
|
||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||
(*m_logger) << time_now_string() << " sending stopped to all torrent's trackers\n";
|
||||
|
@ -2127,16 +2146,10 @@ namespace detail
|
|||
|
||||
session_impl::~session_impl()
|
||||
{
|
||||
abort();
|
||||
|
||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||
(*m_logger) << time_now_string() << "\n\n *** shutting down session *** \n\n";
|
||||
#endif
|
||||
// lock the main thread and abort it
|
||||
mutex_t::scoped_lock l(m_mutex);
|
||||
m_abort = true;
|
||||
m_io_service.stop();
|
||||
l.unlock();
|
||||
abort();
|
||||
|
||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||
(*m_logger) << time_now_string() << " waiting for main thread\n";
|
||||
|
|
|
@ -1526,7 +1526,7 @@ namespace libtorrent
|
|||
INVARIANT_CHECK;
|
||||
|
||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||
(*m_ses.m_logger) << time_now_string() << " resolving: " << url << "\n";
|
||||
(*m_ses.m_logger) << time_now_string() << " resolving web seed: " << url << "\n";
|
||||
#endif
|
||||
|
||||
m_resolving_web_seeds.insert(url);
|
||||
|
@ -3055,7 +3055,7 @@ namespace libtorrent
|
|||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||
void torrent::debug_log(const std::string& line)
|
||||
{
|
||||
(*m_ses.m_logger) << line << "\n";
|
||||
(*m_ses.m_logger) << time_now_string() << " " << line << "\n";
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -302,12 +302,12 @@ namespace libtorrent
|
|||
{
|
||||
m_completion_timeout = completion_timeout;
|
||||
m_read_timeout = read_timeout;
|
||||
m_start_time = time_now();
|
||||
m_read_time = time_now();
|
||||
m_start_time = m_read_time = time_now();
|
||||
|
||||
m_timeout.expires_at((std::min)(
|
||||
m_read_time + seconds(m_read_timeout)
|
||||
, m_start_time + seconds(m_completion_timeout)));
|
||||
, m_start_time + seconds((std::min)(m_completion_timeout
|
||||
, m_read_timeout))));
|
||||
m_timeout.async_wait(m_strand.wrap(bind(
|
||||
&timeout_handler::timeout_callback, self(), _1)));
|
||||
}
|
||||
|
@ -343,7 +343,8 @@ namespace libtorrent
|
|||
|
||||
m_timeout.expires_at((std::min)(
|
||||
m_read_time + seconds(m_read_timeout)
|
||||
, m_start_time + seconds(m_completion_timeout)));
|
||||
, m_start_time + seconds((std::min)(m_completion_timeout
|
||||
, m_read_timeout))));
|
||||
m_timeout.async_wait(m_strand.wrap(
|
||||
bind(&timeout_handler::timeout_callback, self(), _1)));
|
||||
}
|
||||
|
@ -567,12 +568,24 @@ namespace libtorrent
|
|||
m_abort = true;
|
||||
tracker_connections_t keep_connections;
|
||||
|
||||
for (tracker_connections_t::const_iterator i =
|
||||
m_connections.begin(); i != m_connections.end(); ++i)
|
||||
while (!m_connections.empty())
|
||||
{
|
||||
tracker_request const& req = (*i)->tracker_req();
|
||||
boost::intrusive_ptr<tracker_connection>& c = m_connections.back();
|
||||
if (!c)
|
||||
{
|
||||
m_connections.pop_back();
|
||||
continue;
|
||||
}
|
||||
tracker_request const& req = c->tracker_req();
|
||||
if (req.event == tracker_request::stopped)
|
||||
keep_connections.push_back(*i);
|
||||
{
|
||||
keep_connections.push_back(c);
|
||||
m_connections.pop_back();
|
||||
continue;
|
||||
}
|
||||
// close will remove the entry from m_connections
|
||||
// so no need to pop
|
||||
c->close();
|
||||
}
|
||||
|
||||
std::swap(m_connections, keep_connections);
|
||||
|
|
|
@ -96,7 +96,9 @@ namespace libtorrent
|
|||
m_name_lookup.async_resolve(q
|
||||
, m_strand.wrap(boost::bind(
|
||||
&udp_tracker_connection::name_lookup, self(), _1, _2)));
|
||||
set_timeout(m_settings.tracker_completion_timeout
|
||||
set_timeout(req.event == tracker_request::stopped
|
||||
? m_settings.stop_tracker_timeout
|
||||
: m_settings.tracker_completion_timeout
|
||||
, m_settings.tracker_receive_timeout);
|
||||
}
|
||||
|
||||
|
@ -156,11 +158,20 @@ namespace libtorrent
|
|||
|
||||
void udp_tracker_connection::on_timeout()
|
||||
{
|
||||
m_socket.close();
|
||||
asio::error_code ec;
|
||||
m_socket.close(ec);
|
||||
m_name_lookup.cancel();
|
||||
fail_timeout();
|
||||
}
|
||||
|
||||
void udp_tracker_connection::close()
|
||||
{
|
||||
asio::error_code ec;
|
||||
m_socket.close(ec);
|
||||
m_name_lookup.cancel();
|
||||
tracker_connection::close();
|
||||
}
|
||||
|
||||
void udp_tracker_connection::send_udp_connect()
|
||||
{
|
||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||
|
@ -468,6 +479,7 @@ namespace libtorrent
|
|||
, complete, incomplete);
|
||||
|
||||
m_man.remove_request(this);
|
||||
close();
|
||||
return;
|
||||
}
|
||||
catch (std::exception& e)
|
||||
|
@ -543,6 +555,7 @@ namespace libtorrent
|
|||
if (!cb)
|
||||
{
|
||||
m_man.remove_request(this);
|
||||
close();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -551,6 +564,7 @@ namespace libtorrent
|
|||
, complete, incomplete);
|
||||
|
||||
m_man.remove_request(this);
|
||||
close();
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
|
|
|
@ -148,6 +148,7 @@ void upnp::set_mappings(int tcp, int udp)
|
|||
, end(m_devices.end()); i != end; ++i)
|
||||
{
|
||||
rootdevice& d = const_cast<rootdevice&>(*i);
|
||||
TORRENT_ASSERT(d.magic == 1337);
|
||||
if (d.mapping[0].local_port != m_tcp_local_port)
|
||||
{
|
||||
if (d.mapping[0].external_port == 0)
|
||||
|
@ -200,8 +201,13 @@ try
|
|||
// we don't have a WANIP or WANPPP url for this device,
|
||||
// ask for it
|
||||
rootdevice& d = const_cast<rootdevice&>(*i);
|
||||
TORRENT_ASSERT(d.magic == 1337);
|
||||
try
|
||||
{
|
||||
#ifdef TORRENT_UPNP_LOGGING
|
||||
m_log << time_now_string()
|
||||
<< " ==> connecting to " << d.url << std::endl;
|
||||
#endif
|
||||
d.upnp_connection.reset(new http_connection(m_io_service
|
||||
, m_cc, m_strand.wrap(bind(&upnp::on_upnp_xml, self(), _1, _2
|
||||
, boost::ref(d)))));
|
||||
|
@ -270,7 +276,7 @@ try
|
|||
{
|
||||
#ifdef TORRENT_UPNP_LOGGING
|
||||
m_log << time_now_string()
|
||||
<< " <== Rootdevice responded with incorrect HTTP packet. Ignoring device (" << e.what() << ")" << std::endl;
|
||||
<< " <== (" << from << ") Rootdevice responded with incorrect HTTP packet. Ignoring device (" << e.what() << ")" << std::endl;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
@ -280,11 +286,11 @@ try
|
|||
#ifdef TORRENT_UPNP_LOGGING
|
||||
if (p.method().empty())
|
||||
m_log << time_now_string()
|
||||
<< " <== Device responded with HTTP status: " << p.status_code()
|
||||
<< " <== (" << from << ") Device responded with HTTP status: " << p.status_code()
|
||||
<< ". Ignoring device" << std::endl;
|
||||
else
|
||||
m_log << time_now_string()
|
||||
<< " <== Device with HTTP method: " << p.method()
|
||||
<< " <== (" << from << ") Device with HTTP method: " << p.method()
|
||||
<< ". Ignoring device" << std::endl;
|
||||
#endif
|
||||
return;
|
||||
|
@ -294,7 +300,7 @@ try
|
|||
{
|
||||
#ifdef TORRENT_UPNP_LOGGING
|
||||
m_log << time_now_string()
|
||||
<< " <== Rootdevice responded with incomplete HTTP "
|
||||
<< " <== (" << from << ") Rootdevice responded with incomplete HTTP "
|
||||
"packet. Ignoring device" << std::endl;
|
||||
#endif
|
||||
return;
|
||||
|
@ -305,7 +311,7 @@ try
|
|||
{
|
||||
#ifdef TORRENT_UPNP_LOGGING
|
||||
m_log << time_now_string()
|
||||
<< " <== Rootdevice response is missing a location header. "
|
||||
<< " <== (" << from << ") Rootdevice response is missing a location header. "
|
||||
"Ignoring device" << std::endl;
|
||||
#endif
|
||||
return;
|
||||
|
@ -332,7 +338,7 @@ try
|
|||
{
|
||||
#ifdef TORRENT_UPNP_LOGGING
|
||||
m_log << time_now_string()
|
||||
<< " <== Rootdevice uses unsupported protocol: '" << protocol
|
||||
<< " <== (" << from << ") Rootdevice uses unsupported protocol: '" << protocol
|
||||
<< "'. Ignoring device" << std::endl;
|
||||
#endif
|
||||
return;
|
||||
|
@ -342,16 +348,27 @@ try
|
|||
{
|
||||
#ifdef TORRENT_UPNP_LOGGING
|
||||
m_log << time_now_string()
|
||||
<< " <== Rootdevice responded with a url with port 0. "
|
||||
<< " <== (" << from << ") Rootdevice responded with a url with port 0. "
|
||||
"Ignoring device" << std::endl;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
#ifdef TORRENT_UPNP_LOGGING
|
||||
m_log << time_now_string()
|
||||
<< " <== Found rootdevice: " << d.url << std::endl;
|
||||
<< " <== (" << from << ") Found rootdevice: " << d.url
|
||||
<< " total: " << m_devices.size() << std::endl;
|
||||
#endif
|
||||
|
||||
if (m_devices.size() >= 50)
|
||||
{
|
||||
#ifdef TORRENT_UPNP_LOGGING
|
||||
m_log << time_now_string()
|
||||
<< " <== (" << from << ") Too many devices (" << m_devices.size() << "), "
|
||||
"ignoring: " << d.url << std::endl;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_tcp_local_port != 0)
|
||||
{
|
||||
d.mapping[0].need_update = true;
|
||||
|
@ -390,8 +407,13 @@ try
|
|||
// we don't have a WANIP or WANPPP url for this device,
|
||||
// ask for it
|
||||
rootdevice& d = const_cast<rootdevice&>(*i);
|
||||
TORRENT_ASSERT(d.magic == 1337);
|
||||
try
|
||||
{
|
||||
#ifdef TORRENT_UPNP_LOGGING
|
||||
m_log << time_now_string()
|
||||
<< " ==> connecting to " << d.url << std::endl;
|
||||
#endif
|
||||
d.upnp_connection.reset(new http_connection(m_io_service
|
||||
, m_cc, m_strand.wrap(bind(&upnp::on_upnp_xml, self(), _1, _2
|
||||
, boost::ref(d)))));
|
||||
|
@ -420,6 +442,7 @@ catch (std::exception&)
|
|||
void upnp::post(upnp::rootdevice const& d, std::string const& soap
|
||||
, std::string const& soap_action)
|
||||
{
|
||||
TORRENT_ASSERT(d.magic == 1337);
|
||||
std::stringstream header;
|
||||
|
||||
header << "POST " << d.control_url << " HTTP/1.1\r\n"
|
||||
|
@ -439,6 +462,7 @@ void upnp::post(upnp::rootdevice const& d, std::string const& soap
|
|||
|
||||
void upnp::create_port_mapping(http_connection& c, rootdevice& d, int i)
|
||||
{
|
||||
TORRENT_ASSERT(d.magic == 1337);
|
||||
std::string soap_action = "AddPortMapping";
|
||||
|
||||
std::stringstream soap;
|
||||
|
@ -463,6 +487,7 @@ void upnp::create_port_mapping(http_connection& c, rootdevice& d, int i)
|
|||
|
||||
void upnp::map_port(rootdevice& d, int i)
|
||||
{
|
||||
TORRENT_ASSERT(d.magic == 1337);
|
||||
if (d.upnp_connection) return;
|
||||
|
||||
if (!d.mapping[i].need_update)
|
||||
|
@ -479,6 +504,10 @@ void upnp::map_port(rootdevice& d, int i)
|
|||
TORRENT_ASSERT(!d.upnp_connection);
|
||||
TORRENT_ASSERT(d.service_namespace);
|
||||
|
||||
#ifdef TORRENT_UPNP_LOGGING
|
||||
m_log << time_now_string()
|
||||
<< " ==> connecting to " << d.hostname << std::endl;
|
||||
#endif
|
||||
d.upnp_connection.reset(new http_connection(m_io_service
|
||||
, m_cc, m_strand.wrap(bind(&upnp::on_upnp_map_response, self(), _1, _2
|
||||
, boost::ref(d), i)), true
|
||||
|
@ -490,6 +519,7 @@ void upnp::map_port(rootdevice& d, int i)
|
|||
|
||||
void upnp::delete_port_mapping(rootdevice& d, int i)
|
||||
{
|
||||
TORRENT_ASSERT(d.magic == 1337);
|
||||
std::stringstream soap;
|
||||
|
||||
std::string soap_action = "DeletePortMapping";
|
||||
|
@ -510,23 +540,24 @@ void upnp::delete_port_mapping(rootdevice& d, int i)
|
|||
// requires the mutex to be locked
|
||||
void upnp::unmap_port(rootdevice& d, int i)
|
||||
{
|
||||
if (d.mapping[i].external_port == 0)
|
||||
TORRENT_ASSERT(d.magic == 1337);
|
||||
if (d.mapping[i].external_port == 0
|
||||
|| d.disabled)
|
||||
{
|
||||
if (i < num_mappings - 1)
|
||||
{
|
||||
unmap_port(d, i + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_devices.erase(d);
|
||||
}
|
||||
return;
|
||||
}
|
||||
#ifdef TORRENT_UPNP_LOGGING
|
||||
m_log << time_now_string()
|
||||
<< " ==> connecting to " << d.hostname << std::endl;
|
||||
#endif
|
||||
d.upnp_connection.reset(new http_connection(m_io_service
|
||||
, m_cc, m_strand.wrap(bind(&upnp::on_upnp_unmap_response, self(), _1, _2
|
||||
, boost::ref(d), i)), true
|
||||
, bind(&upnp::delete_port_mapping, self(), boost::ref(d), i)));
|
||||
|
||||
d.upnp_connection->start(d.hostname, boost::lexical_cast<std::string>(d.port)
|
||||
, seconds(10));
|
||||
}
|
||||
|
@ -591,6 +622,7 @@ namespace
|
|||
void upnp::on_upnp_xml(asio::error_code const& e
|
||||
, libtorrent::http_parser const& p, rootdevice& d) try
|
||||
{
|
||||
TORRENT_ASSERT(d.magic == 1337);
|
||||
if (d.upnp_connection)
|
||||
{
|
||||
d.upnp_connection->close();
|
||||
|
@ -601,8 +633,10 @@ void upnp::on_upnp_xml(asio::error_code const& e
|
|||
{
|
||||
#ifdef TORRENT_UPNP_LOGGING
|
||||
m_log << time_now_string()
|
||||
<< " <== error while fetching control url: " << e.message() << std::endl;
|
||||
<< " <== (" << d.url << ") error while fetching control url: "
|
||||
<< e.message() << std::endl;
|
||||
#endif
|
||||
d.disabled = true;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -610,8 +644,9 @@ void upnp::on_upnp_xml(asio::error_code const& e
|
|||
{
|
||||
#ifdef TORRENT_UPNP_LOGGING
|
||||
m_log << time_now_string()
|
||||
<< " <== error while fetching control url: incomplete http message" << std::endl;
|
||||
<< " <== (" << d.url << ") error while fetching control url: incomplete http message" << std::endl;
|
||||
#endif
|
||||
d.disabled = true;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -619,8 +654,9 @@ void upnp::on_upnp_xml(asio::error_code const& e
|
|||
{
|
||||
#ifdef TORRENT_UPNP_LOGGING
|
||||
m_log << time_now_string()
|
||||
<< " <== error while fetching control url: " << p.message() << std::endl;
|
||||
<< " <== (" << d.url << ") error while fetching control url: " << p.message() << std::endl;
|
||||
#endif
|
||||
d.disabled = true;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -647,15 +683,17 @@ void upnp::on_upnp_xml(asio::error_code const& e
|
|||
{
|
||||
#ifdef TORRENT_UPNP_LOGGING
|
||||
m_log << time_now_string()
|
||||
<< " <== Rootdevice response, did not find a port mapping interface" << std::endl;
|
||||
<< " <== (" << d.url << ") Rootdevice response, did not find "
|
||||
"a port mapping interface" << std::endl;
|
||||
#endif
|
||||
d.disabled = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef TORRENT_UPNP_LOGGING
|
||||
m_log << time_now_string()
|
||||
<< " <== Rootdevice response, found control URL: " << s.control_url
|
||||
<< " <== (" << d.url << ") Rootdevice response, found control URL: " << s.control_url
|
||||
<< " namespace: " << d.service_namespace << std::endl;
|
||||
#endif
|
||||
|
||||
|
@ -732,6 +770,7 @@ namespace
|
|||
void upnp::on_upnp_map_response(asio::error_code const& e
|
||||
, libtorrent::http_parser const& p, rootdevice& d, int mapping) try
|
||||
{
|
||||
TORRENT_ASSERT(d.magic == 1337);
|
||||
if (d.upnp_connection)
|
||||
{
|
||||
d.upnp_connection->close();
|
||||
|
@ -744,7 +783,7 @@ void upnp::on_upnp_map_response(asio::error_code const& e
|
|||
m_log << time_now_string()
|
||||
<< " <== error while adding portmap: " << e.message() << std::endl;
|
||||
#endif
|
||||
m_devices.erase(d);
|
||||
d.disabled = true;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -773,7 +812,7 @@ void upnp::on_upnp_map_response(asio::error_code const& e
|
|||
m_log << time_now_string()
|
||||
<< " <== error while adding portmap: incomplete http message" << std::endl;
|
||||
#endif
|
||||
m_devices.erase(d);
|
||||
d.disabled = true;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -877,6 +916,7 @@ catch (std::exception&)
|
|||
void upnp::on_upnp_unmap_response(asio::error_code const& e
|
||||
, libtorrent::http_parser const& p, rootdevice& d, int mapping) try
|
||||
{
|
||||
TORRENT_ASSERT(d.magic == 1337);
|
||||
if (d.upnp_connection)
|
||||
{
|
||||
d.upnp_connection->close();
|
||||
|
@ -906,7 +946,7 @@ void upnp::on_upnp_unmap_response(asio::error_code const& e
|
|||
m_log << time_now_string()
|
||||
<< " <== error while deleting portmap: " << p.message() << std::endl;
|
||||
#endif
|
||||
m_devices.erase(d);
|
||||
d.disabled = true;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -922,10 +962,6 @@ void upnp::on_upnp_unmap_response(asio::error_code const& e
|
|||
unmap_port(d, mapping + 1);
|
||||
return;
|
||||
}
|
||||
|
||||
// the main thread is likely to be waiting for
|
||||
// all the unmap operations to complete
|
||||
m_devices.erase(d);
|
||||
}
|
||||
catch (std::exception&)
|
||||
{
|
||||
|
@ -943,6 +979,7 @@ void upnp::on_expire(asio::error_code const& e) try
|
|||
, end(m_devices.end()); i != end; ++i)
|
||||
{
|
||||
rootdevice& d = const_cast<rootdevice&>(*i);
|
||||
TORRENT_ASSERT(d.magic == 1337);
|
||||
for (int m = 0; m < num_mappings; ++m)
|
||||
{
|
||||
if (d.mapping[m].expires != max_time())
|
||||
|
@ -984,15 +1021,11 @@ void upnp::close()
|
|||
}
|
||||
|
||||
for (std::set<rootdevice>::iterator i = m_devices.begin()
|
||||
, end(m_devices.end()); i != end;)
|
||||
, end(m_devices.end()); i != end; ++i)
|
||||
{
|
||||
rootdevice& d = const_cast<rootdevice&>(*i);
|
||||
if (d.control_url.empty())
|
||||
{
|
||||
m_devices.erase(i++);
|
||||
continue;
|
||||
}
|
||||
++i;
|
||||
TORRENT_ASSERT(d.magic == 1337);
|
||||
if (d.control_url.empty()) continue;
|
||||
unmap_port(d, 0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -82,7 +82,7 @@ class TorrentCreator:
|
|||
self.glade = gtk.glade.XML(self.path + "/torrentcreator.glade")
|
||||
|
||||
self.dialog = self.glade.get_widget("torrentcreator")
|
||||
self.glade.get_widget("piece_size_combobox").set_active(0)
|
||||
self.glade.get_widget("piece_size_combobox").set_active(3)
|
||||
self.glade.get_widget("torrent_chooserbutton").connect("clicked", self.torrent_chooserbutton_clicked)
|
||||
self.glade.get_widget("ok_button").connect("clicked", self.create_torrent)
|
||||
self.glade.get_widget("close_button").connect("clicked", self.destroy)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
|
||||
<!--Generated with glade3 3.2.2 on Wed Sep 5 12:27:39 2007 by markybob@peg-->
|
||||
<!--Generated with glade3 3.2.2 on Thu Oct 25 22:18:52 2007 by markybob@peg-->
|
||||
<glade-interface>
|
||||
<widget class="GtkDialog" id="torrentcreator">
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
|
@ -54,7 +54,6 @@
|
|||
<widget class="GtkFrame" id="frame2">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label_xalign">0</property>
|
||||
<property name="shadow_type">GTK_SHADOW_NONE</property>
|
||||
<child>
|
||||
<widget class="GtkAlignment" id="alignment2">
|
||||
|
@ -151,7 +150,6 @@
|
|||
<widget class="GtkFrame" id="frame1">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label_xalign">0</property>
|
||||
<property name="shadow_type">GTK_SHADOW_NONE</property>
|
||||
<child>
|
||||
<widget class="GtkAlignment" id="alignment3">
|
||||
|
@ -271,7 +269,6 @@
|
|||
<widget class="GtkFrame" id="frame3">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label_xalign">0</property>
|
||||
<property name="shadow_type">GTK_SHADOW_NONE</property>
|
||||
<child>
|
||||
<widget class="GtkAlignment" id="alignment4">
|
||||
|
@ -318,7 +315,6 @@
|
|||
<widget class="GtkFrame" id="frame4">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label_xalign">0</property>
|
||||
<property name="shadow_type">GTK_SHADOW_NONE</property>
|
||||
<child>
|
||||
<widget class="GtkAlignment" id="alignment5">
|
||||
|
@ -365,7 +361,6 @@
|
|||
<widget class="GtkFrame" id="frame5">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label_xalign">0</property>
|
||||
<property name="shadow_type">GTK_SHADOW_NONE</property>
|
||||
<child>
|
||||
<widget class="GtkAlignment" id="alignment6">
|
||||
|
@ -417,6 +412,9 @@
|
|||
<property name="n_rows">2</property>
|
||||
<property name="n_columns">2</property>
|
||||
<property name="column_spacing">10</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkCheckButton" id="chk_set_priv">
|
||||
<property name="visible">True</property>
|
||||
|
@ -431,9 +429,6 @@
|
|||
<property name="bottom_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkComboBox" id="piece_size_combobox">
|
||||
<property name="visible">True</property>
|
||||
|
@ -445,6 +440,7 @@
|
|||
256 KiB
|
||||
512 KiB
|
||||
1024 KiB
|
||||
2048 KiB
|
||||
</property>
|
||||
</widget>
|
||||
<packing>
|
||||
|
|
|
@ -28,10 +28,10 @@
|
|||
# but you are not obligated to do so. If you do not wish to do so, delete
|
||||
# this exception statement from your version. If you delete this exception
|
||||
|
||||
plugin_name = "Web User Interface"
|
||||
plugin_name = _("Web User Interface")
|
||||
plugin_author = "Martijn Voncken"
|
||||
plugin_version = "rev."
|
||||
plugin_description = """A Web based User Interface
|
||||
plugin_description = _("""A Web based User Interface
|
||||
|
||||
Firefox greasemonkey script: http://userscripts.org/scripts/show/12639
|
||||
|
||||
|
@ -41,8 +41,8 @@ There is support for multiple templates, but just one is included.
|
|||
|
||||
Other contributors:
|
||||
*somedude : template enhancements.
|
||||
|
||||
"""
|
||||
*markybob : stability : synced with his changes in deluge-svn.
|
||||
""")
|
||||
|
||||
import deluge.common
|
||||
import deluge.pref
|
||||
|
@ -80,9 +80,10 @@ class plugin_WebUi(object):
|
|||
self.web_server = None
|
||||
if not deluge.common.windows_check():
|
||||
import commands
|
||||
status = commands.getstatusoutput('ps x |grep -v grep |grep run_webserver')
|
||||
status = commands.getstatusoutput(
|
||||
'ps x |grep -v grep |grep run_webserver')
|
||||
if status[0] == 0:
|
||||
os.kill(status[1].split()[0], 9)
|
||||
os.kill(int(status[1].split()[0]), 9)
|
||||
time.sleep(1) #safe time to wait for kill to finish.
|
||||
self.config_file = deluge.common.CONFIG_DIR + "/webui.conf"
|
||||
self.config = deluge.pref.Preferences(self.config_file, False)
|
||||
|
@ -95,9 +96,6 @@ class plugin_WebUi(object):
|
|||
if not self.config.get('port'): #ugly way to detect new config file.
|
||||
#set default values:
|
||||
self.config.set("port", 8112)
|
||||
#future->use deluge-core setting for download_dir (if it is set)
|
||||
self.config.set("download_dir", os.path.expanduser("~"))
|
||||
self.config.set("torrent_dir", os.path.expanduser("~"))
|
||||
self.config.set("button_style", 2)
|
||||
self.config.set("auto_refresh", False)
|
||||
self.config.set("auto_refresh_secs", 4)
|
||||
|
@ -112,11 +110,9 @@ class plugin_WebUi(object):
|
|||
self.config.set("cache_templates", True)
|
||||
|
||||
if deluge.common.windows_check():
|
||||
if self.config.get("run_in_thread") == None:
|
||||
self.config.set("run_in_thread", True)
|
||||
self.config.set("run_in_thread", True)
|
||||
else:
|
||||
if self.config.get("run_in_thread") == None:
|
||||
self.config.set("run_in_thread", False)
|
||||
self.config.set("run_in_thread", False)
|
||||
|
||||
self.dbus_manager = get_dbus_manager(deluge_core, deluge_interface,
|
||||
self.config, self.config_file)
|
||||
|
@ -141,8 +137,8 @@ class plugin_WebUi(object):
|
|||
self.kill_server()
|
||||
|
||||
if self.config.get("run_in_thread"):
|
||||
print 'start Webui(inside gtk)..'
|
||||
webserver_common.init() #reload changed config.
|
||||
print 'Start Webui(inside gtk)..'
|
||||
webserver_common.init_gtk_05() #reload changed config.
|
||||
from deluge_webserver import WebServer #only import in threaded mode
|
||||
|
||||
|
||||
|
@ -150,11 +146,9 @@ class plugin_WebUi(object):
|
|||
self.web_server.start_gtk()
|
||||
|
||||
else:
|
||||
print 'start Webui(in process)..'
|
||||
path = os.path.dirname(__file__)
|
||||
server_bin = path + '/run_webserver'
|
||||
port = str(self.config.get('port'))
|
||||
self.proc = Popen((server_bin, port),cwd=path)
|
||||
print 'Start Webui(in process)..'
|
||||
server_bin = os.path.dirname(__file__) + '/run_webserver'
|
||||
self.proc = Popen((server_bin,'env=0.5'))
|
||||
|
||||
def kill_server(self):
|
||||
if self.web_server:
|
||||
|
@ -187,7 +181,8 @@ class ConfigDialog(gtk.Dialog):
|
|||
template_path = os.path.join(os.path.dirname(__file__), 'templates')
|
||||
self.templates = [dirname for dirname
|
||||
in os.listdir(template_path)
|
||||
if os.path.isdir(os.path.join(template_path, dirname))]
|
||||
if os.path.isdir(os.path.join(template_path, dirname))
|
||||
and not dirname.startswith('.')]
|
||||
|
||||
self.port = self.add_widget(_('Port Number'), gtk.SpinButton())
|
||||
self.pwd1 = self.add_widget(_('New Password'), gtk.Entry())
|
||||
|
@ -195,16 +190,11 @@ class ConfigDialog(gtk.Dialog):
|
|||
self.template = self.add_widget(_('Template'), gtk.combo_box_new_text())
|
||||
self.button_style = self.add_widget(_('Button Style'),
|
||||
gtk.combo_box_new_text())
|
||||
self.download_dir = self.add_widget(_('Download Directory'),
|
||||
gtk.FileChooserButton(_('Download Directory')))
|
||||
self.torrent_dir = self.add_widget(_('Torrent Directory'),
|
||||
gtk.FileChooserButton(_('Torrent Directory')))
|
||||
self.cache_templates = self.add_widget(_('Cache Templates'),
|
||||
gtk.CheckButton())
|
||||
self.run_in_thread = self.add_widget(_('Run inside GTK'), gtk.CheckButton())
|
||||
#self.share_downloads = self.add_widget(_('Share Download Directory'),
|
||||
# gtk.CheckButton())
|
||||
|
||||
self.download_dir.set_action(gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER)
|
||||
self.torrent_dir.set_action(gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER)
|
||||
self.port.set_range(80, 65536)
|
||||
self.port.set_increments(1, 10)
|
||||
self.pwd1.set_visibility(False)
|
||||
|
@ -218,23 +208,16 @@ class ConfigDialog(gtk.Dialog):
|
|||
|
||||
for item in [_('Text and image'), _('Image Only'), _('Text Only')]:
|
||||
self.button_style.append_text(item)
|
||||
if not self.config.get("button_style"):
|
||||
if self.config.get("button_style") == None:
|
||||
self.config.set("button_style", 2)
|
||||
|
||||
self.port.set_value(int(self.config.get("port")))
|
||||
self.template.set_active(
|
||||
self.templates.index(self.config.get("template")))
|
||||
self.button_style.set_active(self.config.get("button_style"))
|
||||
#self.share_downloads.set_active(
|
||||
# bool(self.config.get("share_downloads")))
|
||||
|
||||
self.torrent_dir.set_filename(self.config.get("torrent_dir"))
|
||||
self.download_dir.set_filename(self.config.get("download_dir"))
|
||||
|
||||
if deluge.common.windows_check():
|
||||
self.run_in_thread.set_active(True)
|
||||
self.run_in_thread.set_sensitive(False)
|
||||
else:
|
||||
self.run_in_thread.set_active(False)
|
||||
self.run_in_thread.set_sensitive(False)
|
||||
self.cache_templates.set_active(self.config.get("cache_templates"))
|
||||
|
||||
self.vbox.pack_start(self.vb, True, True, 0)
|
||||
|
@ -270,9 +253,7 @@ class ConfigDialog(gtk.Dialog):
|
|||
self.config.set("port", int(self.port.get_value()))
|
||||
self.config.set("template", self.template.get_active_text())
|
||||
self.config.set("button_style", self.button_style.get_active())
|
||||
self.config.set("torrent_dir", self.torrent_dir.get_filename())
|
||||
self.config.set("download_dir",self.download_dir.get_filename())
|
||||
self.config.set("cache_templates", self.cache_templates.get_active())
|
||||
self.config.set("run_in_thread", self.run_in_thread.get_active())
|
||||
#self.config.set("share_downloads", self.share_downloads.get_active())
|
||||
self.config.save(self.plugin.config_file)
|
||||
self.plugin.start_server() #restarts server
|
||||
|
|
|
@ -68,7 +68,7 @@ class DbusManager(dbus.service.Object):
|
|||
|
||||
@dbus.service.method(dbus_interface=dbus_interface,
|
||||
in_signature="",out_signature="as")
|
||||
def get_torrent_state(self):
|
||||
def get_session_state(self):
|
||||
"""Returns a list of torrent_ids in the session.
|
||||
same as 0.6, but returns type "as" instead of a pickle
|
||||
"""
|
||||
|
@ -129,18 +129,20 @@ class DbusManager(dbus.service.Object):
|
|||
return status_subset
|
||||
|
||||
@dbus.service.method(dbus_interface=dbus_interface,
|
||||
in_signature="s",out_signature="")
|
||||
def pause_torrent(self, torrent_id):
|
||||
in_signature="as",out_signature="")
|
||||
def pause_torrent(self, torrents):
|
||||
"""same as 0.6 interface"""
|
||||
torrent_id = int(torrent_id)
|
||||
self.core.set_user_pause(torrent_id,True)
|
||||
for torrent_id in torrents:
|
||||
torrent_id = int(torrent_id)
|
||||
self.core.set_user_pause(torrent_id,True)
|
||||
|
||||
@dbus.service.method(dbus_interface=dbus_interface,
|
||||
in_signature="s", out_signature="")
|
||||
def resume_torrent(self, torrent_id):
|
||||
in_signature="as", out_signature="")
|
||||
def resume_torrent(self, torrents):
|
||||
"""same as 0.6 interface"""
|
||||
torrent_id = int(torrent_id)
|
||||
self.core.set_user_pause(torrent_id,False)
|
||||
for torrent_id in torrents:
|
||||
torrent_id = int(torrent_id)
|
||||
self.core.set_user_pause(torrent_id,False)
|
||||
|
||||
@dbus.service.method(dbus_interface=dbus_interface,
|
||||
in_signature="sbb", out_signature="")
|
||||
|
@ -157,7 +159,6 @@ class DbusManager(dbus.service.Object):
|
|||
@dbus.service.method(dbus_interface=dbus_interface,
|
||||
in_signature="s", out_signature="b")
|
||||
def add_torrent_url(self, url):
|
||||
"""not available in deluge 0.6 interface"""
|
||||
filename = fetch_url(url)
|
||||
self._add_torrent(filename)
|
||||
return True
|
||||
|
@ -182,8 +183,8 @@ class DbusManager(dbus.service.Object):
|
|||
#name = fillename without directory
|
||||
name = name.replace('\\','/')
|
||||
name = 'deluge_' + str(random.random()) + '_' + name.split('/')[-1]
|
||||
filename = os.path.join(self.core.config.get("default_download_path"), name)
|
||||
|
||||
filename = os.path.join(self.config.get("torrent_dir"),name)
|
||||
filecontent = base64.b64decode(filecontent_b64)
|
||||
f = open(filename,"wb") #no with statement, that's py 2.5+
|
||||
f.write(filecontent)
|
||||
|
@ -192,11 +193,42 @@ class DbusManager(dbus.service.Object):
|
|||
self._add_torrent(filename)
|
||||
return True
|
||||
|
||||
|
||||
@dbus.service.method(dbus_interface=dbus_interface,
|
||||
in_signature="", out_signature="a{sv}")
|
||||
def get_config(self):
|
||||
return self.core.config.mapping
|
||||
|
||||
@dbus.service.method(dbus_interface=dbus_interface,
|
||||
in_signature="s", out_signature="v")
|
||||
def get_config_value(self,key):
|
||||
return self.core.config.mapping[pythonize(key)] #ugly!
|
||||
|
||||
@dbus.service.method(dbus_interface=dbus_interface,
|
||||
in_signature="a{sv}", out_signature="")
|
||||
def set_config(self, config):
|
||||
"""Set the config with values from dictionary"""
|
||||
config = deluge.common.pythonize(config)
|
||||
# Load all the values into the configuration
|
||||
for key in self.core.config.keys():
|
||||
self.core.config[key] = config[key]
|
||||
self.core.apply_prefs()
|
||||
|
||||
@dbus.service.method(dbus_interface=dbus_interface,
|
||||
in_signature="", out_signature="v")
|
||||
def get_download_rate(self):
|
||||
return self.core.get_state()['download_rate']
|
||||
|
||||
@dbus.service.method(dbus_interface=dbus_interface,
|
||||
in_signature="", out_signature="v")
|
||||
def get_upload_rate(self):
|
||||
return self.core.get_state()['upload_rate']
|
||||
|
||||
|
||||
#internal
|
||||
def _add_torrent(self, filename):
|
||||
#dbus types break pickle, again.....
|
||||
filename = unicode(filename)
|
||||
target = self.config.get("download_dir")
|
||||
target = self.core.config.get("default_download_path")
|
||||
|
||||
torrent_id = self.core.add_torrent(filename, target,
|
||||
self.interface.config.get("use_compact_storage"))
|
||||
|
|
|
@ -31,67 +31,15 @@
|
|||
# this exception statement from your version. If you delete this exception
|
||||
# statement from all source files in the program, then also delete it here.
|
||||
|
||||
|
||||
from webserver_common import TORRENT_KEYS, STATE_MESSAGES
|
||||
import webserver_common as ws
|
||||
from webserver_framework import *
|
||||
|
||||
|
||||
import webpy022 as web
|
||||
from webpy022.http import seeother, url
|
||||
from webpy022.utils import Storage
|
||||
|
||||
from md5 import md5
|
||||
import base64
|
||||
from deluge.common import fsize
|
||||
from operator import attrgetter
|
||||
|
||||
#utils:
|
||||
def check_pwd(pwd):
|
||||
m = md5()
|
||||
m.update(ws.config.get('pwd_salt'))
|
||||
m.update(pwd)
|
||||
return (m.digest() == ws.config.get('pwd_md5'))
|
||||
|
||||
def get_torrent_status(torrent_id):
|
||||
"""
|
||||
helper method.
|
||||
enhance ws.proxy.get_torrent_status with some extra data
|
||||
"""
|
||||
status = ws.proxy.get_torrent_status(torrent_id,TORRENT_KEYS)
|
||||
status["id"] = torrent_id
|
||||
|
||||
#for naming the status-images
|
||||
status["calc_state_str"] = "downloading"
|
||||
if status["paused"]:
|
||||
status["calc_state_str"] = "inactive"
|
||||
elif status["is_seed"]:
|
||||
status["calc_state_str"] = "seeding"
|
||||
|
||||
#action for torrent_pause
|
||||
if status["calc_state_str"] == "inactive":
|
||||
status["action"] = "start"
|
||||
else:
|
||||
status["action"] = "stop"
|
||||
|
||||
if status["paused"]:
|
||||
status["message"] = _("Paused %s%%") % status['progress']
|
||||
else:
|
||||
status["message"] = "%s %i%%" % (STATE_MESSAGES[status["state"]]
|
||||
, status['progress'])
|
||||
|
||||
#add some pre-calculated values
|
||||
status.update({
|
||||
"calc_total_downloaded" : (fsize(status["total_done"])
|
||||
+ " (" + fsize(status["total_download"]) + ")"),
|
||||
"calc_total_uploaded": (fsize(status['uploaded_memory']
|
||||
+ status["total_payload_upload"]) + " ("
|
||||
+ fsize(status["total_upload"]) + ")"),
|
||||
})
|
||||
|
||||
return Storage(status) #Storage for easy templating.
|
||||
|
||||
#/utils
|
||||
import os
|
||||
|
||||
#routing:
|
||||
urls = (
|
||||
|
@ -107,15 +55,21 @@ urls = (
|
|||
"/resume_all(.*)", "resume_all",
|
||||
"/refresh/set(.*)", "refresh_set",
|
||||
"/refresh/(.*)", "refresh",
|
||||
"/config(.*)","config",
|
||||
"/home(.*)", "home",
|
||||
"/about(.*)", "about",
|
||||
"/logout(.*)", "logout",
|
||||
#default-pages
|
||||
"/", "login",
|
||||
"", "login",
|
||||
"/", "home",
|
||||
"", "home",
|
||||
#remote-api:
|
||||
"/remote/torrent/add(.*)", "remote_torrent_add"
|
||||
)
|
||||
"/remote/torrent/add(.*)", "remote_torrent_add",
|
||||
#static:
|
||||
"/static/(.*)","static",
|
||||
"/template/static/(.*)","template_static",
|
||||
#"/downloads/(.*)","downloads" disabled until it can handle large downloads.
|
||||
|
||||
)
|
||||
#/routing
|
||||
|
||||
#pages:
|
||||
|
@ -133,15 +87,10 @@ class login:
|
|||
start_session()
|
||||
do_redirect()
|
||||
elif vars.redir:
|
||||
seeother(url('/login',error=1,redir=vars.redir))
|
||||
seeother(url('/login',error=1, redir=vars.redir))
|
||||
else:
|
||||
seeother('/login?error=1')
|
||||
|
||||
class home:
|
||||
@check_session
|
||||
def GET(self, name):
|
||||
do_redirect()
|
||||
|
||||
class index:
|
||||
"page containing the torrent list."
|
||||
@auto_refreshed
|
||||
|
@ -150,7 +99,7 @@ class index:
|
|||
vars = web.input(sort=None, order=None)
|
||||
|
||||
status_rows = [get_torrent_status(torrent_id)
|
||||
for torrent_id in ws.proxy.get_torrent_state()]
|
||||
for torrent_id in ws.proxy.get_session_state()]
|
||||
|
||||
#sorting:
|
||||
if vars.sort:
|
||||
|
@ -164,21 +113,19 @@ class index:
|
|||
return ws.render.index(status_rows)
|
||||
|
||||
class torrent_info:
|
||||
"torrent details"
|
||||
@auto_refreshed
|
||||
@deluge_page
|
||||
def GET(self, torrent_id):
|
||||
return ws.render.torrent_info(get_torrent_status(torrent_id))
|
||||
|
||||
class torrent_pause:
|
||||
"start/stop a torrent"
|
||||
@check_session
|
||||
def POST(self, name):
|
||||
vars = web.input(stop = None, start = None, redir = None)
|
||||
if vars.stop:
|
||||
ws.proxy.pause_torrent(vars.stop)
|
||||
ws.proxy.pause_torrent([vars.stop])
|
||||
elif vars.start:
|
||||
ws.proxy.resume_torrent(vars.start)
|
||||
ws.proxy.resume_torrent([vars.start])
|
||||
|
||||
do_redirect()
|
||||
|
||||
|
@ -194,7 +141,7 @@ class torrent_add:
|
|||
if vars.url and vars.torrent.filename:
|
||||
error_page(_("Choose an url or a torrent, not both."))
|
||||
if vars.url:
|
||||
ws.proxy.add_torrent_url(vars.url)
|
||||
ws.proxy.add_torrent_url(vars.url )
|
||||
do_redirect()
|
||||
elif vars.torrent.filename:
|
||||
data = vars.torrent.file.read()
|
||||
|
@ -227,8 +174,7 @@ class torrent_delete:
|
|||
return ws.render.torrent_delete(get_torrent_status(torrent_id))
|
||||
|
||||
@check_session
|
||||
def POST(self, name):
|
||||
torrent_id = name
|
||||
def POST(self, torrent_id):
|
||||
vars = web.input(data_also = None, torrent_also = None)
|
||||
data_also = bool(vars.data_also)
|
||||
torrent_also = bool(vars.torrent_also)
|
||||
|
@ -238,30 +184,26 @@ class torrent_delete:
|
|||
|
||||
class torrent_queue_up:
|
||||
@check_session
|
||||
def POST(self, name):
|
||||
torrent_id = name
|
||||
def POST(self, torrent_id):
|
||||
ws.proxy.queue_up(torrent_id)
|
||||
do_redirect()
|
||||
|
||||
class torrent_queue_down:
|
||||
@check_session
|
||||
def POST(self, name):
|
||||
torrent_id = name
|
||||
def POST(self, torrent_id):
|
||||
ws.proxy.queue_down(torrent_id)
|
||||
do_redirect()
|
||||
|
||||
class pause_all:
|
||||
@check_session
|
||||
def POST(self, name):
|
||||
for torrent_id in ws.proxy.get_torrent_state():
|
||||
ws.proxy.pause_torrent(torrent_id)
|
||||
ws.proxy.pause_torrent(ws.proxy.get_session_state())
|
||||
do_redirect()
|
||||
|
||||
class resume_all:
|
||||
@check_session
|
||||
def POST(self, name):
|
||||
for torrent_id in ws.proxy.get_torrent_state():
|
||||
ws.proxy.resume_torrent(torrent_id)
|
||||
ws.proxy.resume_torrent(ws.proxy.get_session_state())
|
||||
do_redirect()
|
||||
|
||||
class refresh:
|
||||
|
@ -287,13 +229,61 @@ class refresh_set:
|
|||
else:
|
||||
error_page(_('refresh must be > 0'))
|
||||
|
||||
class config:
|
||||
"""core config
|
||||
TODO:good validation.
|
||||
"""
|
||||
cfg_form = web.form.Form(
|
||||
web.form.Dropdown('max_download', ws.SPEED_VALUES,
|
||||
description=_('Download Speed Limit'),
|
||||
post='%s Kib/sec' % ws.proxy.get_config_value('max_download_speed')
|
||||
)
|
||||
,web.form.Dropdown('max_upload', ws.SPEED_VALUES,
|
||||
description=_('Upload Speed Limit'),
|
||||
post='%s Kib/sec' % ws.proxy.get_config_value('max_upload_speed')
|
||||
)
|
||||
)
|
||||
|
||||
@deluge_page
|
||||
def GET(self, name):
|
||||
return ws.render.config(self.cfg_form())
|
||||
|
||||
def POST(self, name):
|
||||
vars = web.input(max_download=None, max_upload=None)
|
||||
|
||||
#self.config.set("max_download_speed", float(str_bwdown))
|
||||
raise NotImplementedError('todo')
|
||||
|
||||
class home:
|
||||
@check_session
|
||||
def GET(self, name):
|
||||
do_redirect()
|
||||
|
||||
class about:
|
||||
@deluge_page_noauth
|
||||
def GET(self, name):
|
||||
return ws.render.about()
|
||||
|
||||
#/pages
|
||||
class logout:
|
||||
def POST(self, name):
|
||||
end_session()
|
||||
seeother('/login')
|
||||
|
||||
class static(static_handler):
|
||||
base_dir = os.path.join(os.path.dirname(__file__),'static')
|
||||
|
||||
class template_static(static_handler):
|
||||
def get_base_dir(self):
|
||||
return os.path.join(os.path.dirname(__file__),
|
||||
'templates/%s/static' % ws.config.get('template'))
|
||||
|
||||
class downloads(static_handler):
|
||||
def GET(self, name):
|
||||
self.base_dir = ws.proxy.get_config_value('default_download_path')
|
||||
if not ws.config.get('share_downloads'):
|
||||
raise Exception('Access to downloads is forbidden.')
|
||||
return static_handler.GET(self, name)
|
||||
#/pages
|
||||
|
||||
def WebServer():
|
||||
return create_webserver(urls, globals())
|
||||
|
@ -307,4 +297,3 @@ def run():
|
|||
|
||||
if __name__ == "__main__":
|
||||
run()
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
87
|
||||
112
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
#!/usr/bin/env python
|
||||
from deluge_webserver import *
|
||||
web.run(urls, globals())
|
||||
import deluge_webserver
|
||||
deluge_webserver.run()
|
||||
|
|
10
plugins/WebUi/scripts/add_torrent_to_deluge_webui
Executable file
10
plugins/WebUi/scripts/add_torrent_to_deluge_webui
Executable file
|
@ -0,0 +1,10 @@
|
|||
#!/bin/bash
|
||||
|
||||
pwd=deluge
|
||||
url=http://localhost:8112
|
||||
|
||||
for arg in "$@"
|
||||
do
|
||||
curl -F torrent=@"$arg" -F pwd=$pwd $url/remote/torrent/add
|
||||
done
|
||||
|
BIN
plugins/WebUi/static/images/tango/system-log-out.png
Normal file
BIN
plugins/WebUi/static/images/tango/system-log-out.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 799 B |
136
plugins/WebUi/static_handler.py
Normal file
136
plugins/WebUi/static_handler.py
Normal file
|
@ -0,0 +1,136 @@
|
|||
#!/usr/bin/env python
|
||||
#(c) Martijn Voncken, mvoncken@gmail.com
|
||||
#Same Licence as web.py 0.22 ->Public Domain
|
||||
#
|
||||
"""
|
||||
static fileserving for web.py
|
||||
without the need for wsgi wrapper magic.
|
||||
"""
|
||||
import webpy022 as web
|
||||
from webpy022.http import seeother, url
|
||||
|
||||
import posixpath
|
||||
import urlparse
|
||||
import urllib
|
||||
import mimetypes
|
||||
import os
|
||||
import datetime
|
||||
import cgi
|
||||
from StringIO import StringIO
|
||||
mimetypes.init() # try to read system mime.types
|
||||
|
||||
class static_handler:
|
||||
"""
|
||||
mostly c&p from SimpleHttpServer
|
||||
serves relative from start location
|
||||
"""
|
||||
base_dir = './'
|
||||
extensions_map = mimetypes.types_map
|
||||
|
||||
def get_base_dir(self):
|
||||
#override this if you have a config that changes the base dir at runtime
|
||||
#deluge on windows :(
|
||||
return self.base_dir
|
||||
|
||||
def GET(self, path):
|
||||
path = self.translate_path(path)
|
||||
if os.path.isdir(path):
|
||||
if not path.endswith('/'):
|
||||
path += "/"
|
||||
return self.list_directory(path)
|
||||
|
||||
ctype = self.guess_type(path)
|
||||
|
||||
try:
|
||||
f = open(path, 'rb')
|
||||
except IOError:
|
||||
raise Exception('file not found:%s' % path)
|
||||
#web.header("404", "File not found")
|
||||
#return
|
||||
web.header("Content-type", ctype)
|
||||
fs = os.fstat(f.fileno())
|
||||
web.header("Content-Length", str(fs[6]))
|
||||
web.lastmodified(datetime.datetime.fromtimestamp(fs.st_mtime))
|
||||
print f.read()
|
||||
|
||||
def translate_path(self, path):
|
||||
"""Translate a /-separated PATH to the local filename syntax.
|
||||
|
||||
Components that mean special things to the local file system
|
||||
(e.g. drive or directory names) are ignored. (XXX They should
|
||||
probably be diagnosed.)
|
||||
|
||||
"""
|
||||
# abandon query parameters
|
||||
path = urlparse.urlparse(path)[2]
|
||||
path = posixpath.normpath(urllib.unquote(path))
|
||||
words = path.split('/')
|
||||
words = filter(None, words)
|
||||
path = self.get_base_dir()
|
||||
for word in words:
|
||||
drive, word = os.path.splitdrive(word)
|
||||
head, word = os.path.split(word)
|
||||
if word in (os.curdir, os.pardir): continue
|
||||
path = os.path.join(path, word)
|
||||
return path
|
||||
|
||||
def guess_type(self, path):
|
||||
base, ext = posixpath.splitext(path)
|
||||
if ext in self.extensions_map:
|
||||
return self.extensions_map[ext]
|
||||
ext = ext.lower()
|
||||
if ext in self.extensions_map:
|
||||
return self.extensions_map[ext]
|
||||
else:
|
||||
return 'application/octet-stream'
|
||||
|
||||
|
||||
def list_directory(self, path):
|
||||
"""Helper to produce a directory listing (absent index.html).
|
||||
|
||||
Return value is either a file object, or None (indicating an
|
||||
error). In either case, the headers are sent, making the
|
||||
interface the same as for send_head().
|
||||
#TODO ->use web.py +template!
|
||||
"""
|
||||
try:
|
||||
list = os.listdir(path)
|
||||
except os.error:
|
||||
web.header('404', "No permission to list directory")
|
||||
return None
|
||||
list.sort(key=lambda a: a.lower())
|
||||
f = StringIO()
|
||||
displaypath = cgi.escape(urllib.unquote(path))
|
||||
f.write("<title>Directory listing for %s</title>\n" % displaypath)
|
||||
f.write("<h2>Directory listing for %s</h2>\n" % displaypath)
|
||||
f.write("<hr>\n<ul>\n")
|
||||
for name in list:
|
||||
fullname = os.path.join(path, name)
|
||||
displayname = linkname = name
|
||||
# Append / for directories or @ for symbolic links
|
||||
if os.path.isdir(fullname):
|
||||
displayname = name + "/"
|
||||
linkname = name + "/"
|
||||
if os.path.islink(fullname):
|
||||
displayname = name + "@"
|
||||
# Note: a link to a directory displays with @ and links with /
|
||||
f.write('<li><a href="%s">%s</a>\n'
|
||||
% (urllib.quote(linkname), cgi.escape(displayname)))
|
||||
f.write("</ul>\n<hr>\n")
|
||||
length = f.tell()
|
||||
f.seek(0)
|
||||
|
||||
web.header("Content-type", "text/html")
|
||||
web.header("Content-Length", str(length))
|
||||
print f.read()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
#example:
|
||||
class usr_static(static_handler):
|
||||
base_dir = os.path.expanduser('~')
|
||||
|
||||
urls = ('/relative/(.*)','static_handler',
|
||||
'/(.*)','usr_static')
|
||||
|
||||
web.run(urls,globals())
|
|
@ -7,6 +7,7 @@ $:render.header(_('About'))
|
|||
<li><a href="http://deluge-torrent.org">Deluge</a></li>
|
||||
<li><a href="http://forum.deluge-torrent.org/viewtopic.php?f=9&t=425">
|
||||
WebUi forum Thread</a>
|
||||
|
||||
</li>
|
||||
<li><a href="http://www.gnu.org/licenses/old-licenses/gpl-2.0.html">GPL v2
|
||||
</a></li>
|
||||
|
@ -18,6 +19,7 @@ $:render.header(_('About'))
|
|||
<ul>
|
||||
<li>Martijn Voncken</li>
|
||||
</ul>
|
||||
|
||||
<h3>Template</h3>
|
||||
<ul>
|
||||
<li>Martijn Voncken</li>
|
||||
|
@ -27,6 +29,7 @@ $:render.header(_('About'))
|
|||
<ul>
|
||||
<li>Zach Tibbitts</li>
|
||||
<li>Alon Zakai</li>
|
||||
|
||||
<li>Alon Zakai</li>
|
||||
<li>Marcos Pinto</li>
|
||||
<li>Andrew Resch</li>
|
||||
|
@ -36,4 +39,4 @@ $:render.header(_('About'))
|
|||
*and all other authors/helpers/contributors I forgot to mention.
|
||||
</div>
|
||||
|
||||
$:render.footer()
|
||||
$:render.footer()
|
||||
|
|
10
plugins/WebUi/templates/deluge/config.html
Normal file
10
plugins/WebUi/templates/deluge/config.html
Normal file
|
@ -0,0 +1,10 @@
|
|||
$def with (form)
|
||||
$:render.header(_('Config'))
|
||||
|
||||
<div class="error">Not Implemented!</div>
|
||||
<form method="POST">
|
||||
$:form.render()
|
||||
<input type="submit" value="$_('Apply')"/>
|
||||
</form>
|
||||
|
||||
$:render.footer()
|
|
@ -51,8 +51,10 @@ $for torrent in torrent_list:
|
|||
$: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.part_refresh()
|
||||
$:part_stats()
|
||||
|
||||
$:render.footer()
|
||||
|
||||
|
|
|
@ -2,21 +2,25 @@ $def with (method, url, title, image='')
|
|||
<div class="deluge_button">
|
||||
<form method="$method" action="$url" class="deluge_button">
|
||||
<input type="hidden" name="redir" value="$self_url()">
|
||||
<button type="submit" class="deluge_button">
|
||||
$if (get_config('button_style') == 0):
|
||||
<button type="submit" class="deluge_button" alt="$title">
|
||||
$title
|
||||
$if image:
|
||||
<image src="/static/images/$image" class="button" alt="$title"/>
|
||||
</button>
|
||||
|
||||
$if (get_config('button_style') == 1):
|
||||
$if image:
|
||||
<image src="/static/images/$image" class="button" alt="$title"/>
|
||||
<input type="image" image src="/static/images/$image" class="img_button" alt="$title"/>
|
||||
$else:
|
||||
<button type="submit" class="deluge_button" alt="$title">
|
||||
$title
|
||||
</button>
|
||||
|
||||
$if (get_config('button_style') == 2):
|
||||
<button type="submit" class="deluge_button" alt="$title">
|
||||
$title
|
||||
</button>
|
||||
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
|
|
30
plugins/WebUi/templates/deluge/part_stats.html
Normal file
30
plugins/WebUi/templates/deluge/part_stats.html
Normal file
|
@ -0,0 +1,30 @@
|
|||
$def with (stats)
|
||||
|
||||
|
||||
<div class="panel" id='refresh_panel'>
|
||||
|
||||
$_('Auto refresh:')
|
||||
$if getcookie('auto_refresh') == '1':
|
||||
($getcookie('auto_refresh_secs')) $_('seconds')
|
||||
$:render.part_button('GET', '/refresh/set', _('Set'), 'tango/preferences-system.png')
|
||||
$:render.part_button('POST', '/refresh/off', _('Disable'), 'tango/process-stop.png')
|
||||
$else:
|
||||
$_('Off')
|
||||
$:render.part_button('POST', '/refresh/on', _('Enable'), 'tango/view-refresh.png')
|
||||
$#end
|
||||
</div>
|
||||
|
||||
<div class="panel" id='refresh_panel'>
|
||||
<a href='/config'>
|
||||
$_('Down Speed') : $stats.download_rate ($stats.max_download)
|
||||
|
||||
$_('Up Speed') : $stats.upload_rate ($stats.max_upload)
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
(<a href='/about'>$_('About')</a>)
|
||||
|
||||
</div>
|
||||
|
||||
|
|
@ -84,6 +84,7 @@ $:render.part_button('GET', '/torrent/delete/' + str(torrent.id), _('Remove'), '
|
|||
|
||||
|
||||
<br>
|
||||
<!--
|
||||
[<a onclick="javascript:toggle_dump()">$_('Debug:Data Dump')</a>]
|
||||
|
||||
<pre style="background-color:white;color:black;display:none" id="data_dump">
|
||||
|
@ -102,6 +103,8 @@ function toggle_dump(){
|
|||
}
|
||||
}
|
||||
</script>
|
||||
-->
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
@ -114,6 +117,6 @@ $:render.part_button('POST', '/torrent/queue/up/' + str(torrent.id), _('Queue Up
|
|||
$:render.part_button('POST', '/torrent/queue/down/' + str(torrent.id), _('Queue Down'), 'tango/down.png')
|
||||
</div>
|
||||
|
||||
$:render.part_refresh()
|
||||
$:part_stats()
|
||||
|
||||
$:render.footer()
|
||||
|
|
3
plugins/WebUi/templates/example/footer.html
Normal file
3
plugins/WebUi/templates/example/footer.html
Normal file
|
@ -0,0 +1,3 @@
|
|||
|
||||
</body>
|
||||
</html>
|
12
plugins/WebUi/templates/example/header.html
Normal file
12
plugins/WebUi/templates/example/header.html
Normal file
|
@ -0,0 +1,12 @@
|
|||
$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>
|
42
plugins/WebUi/templates/example/index.html
Normal file
42
plugins/WebUi/templates/example/index.html
Normal file
|
@ -0,0 +1,42 @@
|
|||
$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()
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
revision-id: mvoncken@gmail.com-20070930083408-sv8mo0mi1rbjnfvk
|
||||
date: 2007-10-23 15:10:08 +0200
|
||||
build-date: 2007-10-23 15:34:50 +0200
|
||||
revno: 87
|
||||
revno: 112
|
||||
branch-nick: WebUi
|
||||
|
|
|
@ -29,40 +29,96 @@
|
|||
# this exception statement from your version. If you delete this exception
|
||||
# statement from all source files in the program, then also delete it here.
|
||||
|
||||
"""
|
||||
initializes config,render and proxy.
|
||||
contains all hacks to support running in process0.5 ,run inside-gtk0.5 and
|
||||
run in process0.6
|
||||
"""
|
||||
|
||||
import os
|
||||
import deluge
|
||||
from deluge.common import INSTALL_PREFIX
|
||||
import random
|
||||
import pickle
|
||||
import sys
|
||||
from webpy022 import template
|
||||
|
||||
random.seed()
|
||||
path = os.path.dirname(__file__)
|
||||
|
||||
config_file = deluge.common.CONFIG_DIR + "/webui.conf"
|
||||
try:
|
||||
_('translate something')
|
||||
except:
|
||||
import gettext
|
||||
gettext.install('~/') #no translations :(
|
||||
|
||||
#a bit hacky way of detecting i'm in the deluge gui or in a process :(
|
||||
if not hasattr(deluge,'pref'):
|
||||
try:
|
||||
config_dir = deluge.common.CONFIG_DIR
|
||||
except:
|
||||
config_dir = os.path.expanduser("~/.config/deluge")
|
||||
|
||||
config_file = os.path.join(config_dir,'webui.conf')
|
||||
session_file = os.path.join(config_dir,'webui.sessions')
|
||||
|
||||
|
||||
class subclassed_render(object):
|
||||
"""
|
||||
try to use the html template in configured dir.
|
||||
not available : use template in /deluge/
|
||||
"""
|
||||
def __init__(self, template_dirname, cache=False):
|
||||
self.base_template = template.render(
|
||||
os.path.join(path, 'templates/deluge/'),
|
||||
cache=cache)
|
||||
|
||||
self.sub_template = template.render(
|
||||
os.path.join(path, 'templates/%s/' % template_dirname),
|
||||
cache=cache)
|
||||
|
||||
def __getattr__(self, attr):
|
||||
if hasattr(self.sub_template, attr):
|
||||
return getattr(self.sub_template, attr)
|
||||
else:
|
||||
return getattr(self.base_template, attr)
|
||||
|
||||
def init_process():
|
||||
globals()['config'] = pickle.load(open(config_file))
|
||||
globals()['render'] = subclassed_render(config.get('template'),
|
||||
config.get('cache_templates'))
|
||||
|
||||
def init_06():
|
||||
import deluge.ui.client as proxy
|
||||
proxy.set_core_uri('http://localhost:58846') #How to configure this?
|
||||
|
||||
init_process()
|
||||
globals()['proxy'] = proxy
|
||||
|
||||
def init_05():
|
||||
import dbus
|
||||
init_process()
|
||||
bus = dbus.SessionBus()
|
||||
proxy = bus.get_object("org.deluge_torrent.dbusplugin"
|
||||
, "/org/deluge_torrent/DelugeDbusPlugin")
|
||||
config = pickle.load(open(config_file))
|
||||
render = template.render('templates/%s/' % config.get('template'),
|
||||
cache=config.get('cache_templates'))
|
||||
globals()['proxy'] = proxy
|
||||
|
||||
def init():
|
||||
def init_gtk_05():
|
||||
#appy possibly changed config-vars, only called in when runing inside gtk.
|
||||
path = os.path.dirname(__file__)
|
||||
from dbus_interface import get_dbus_manager
|
||||
globals()['proxy'] = get_dbus_manager()
|
||||
globals()['config'] = deluge.pref.Preferences(config_file, False)
|
||||
globals()['render'] = template.render(os.path.join(path, 'templates/%s/' %
|
||||
config.get('template')), cache=config.get('cache_templates'))
|
||||
globals()['render'] = subclassed_render(config.get('template'),
|
||||
config.get('cache_templates'))
|
||||
|
||||
|
||||
#hacks to determine environment, TODO: clean up.
|
||||
if 'env=0.5' in sys.argv:
|
||||
init_05()
|
||||
elif not hasattr(deluge, 'common'):
|
||||
init_06()
|
||||
elif not hasattr(deluge,'pref'):
|
||||
init_05()
|
||||
|
||||
|
||||
REVNO = '0.56.stable.' + open(os.path.join(os.path.dirname(__file__),'revno')).read()
|
||||
#constants
|
||||
REVNO = open(os.path.join(os.path.dirname(__file__),'revno')).read()
|
||||
VERSION = open(os.path.join(os.path.dirname(__file__),'version')).read()
|
||||
|
||||
TORRENT_KEYS = ['distributed_copies', 'download_payload_rate',
|
||||
|
@ -82,3 +138,30 @@ STATE_MESSAGES = (_("Queued"),
|
|||
_("Finished"),
|
||||
_("Seeding"),
|
||||
_("Allocating"))
|
||||
|
||||
SPEED_VALUES = [
|
||||
(-1, 'Unlimited'),
|
||||
(5, '5.0 Kib/sec'),
|
||||
(10, '10.0 Kib/sec'),
|
||||
(15, '15.0 Kib/sec'),
|
||||
(25, '25.0 Kib/sec'),
|
||||
(30, '30.0 Kib/sec'),
|
||||
(50, '50.0 Kib/sec'),
|
||||
(80, '80.0 Kib/sec'),
|
||||
(300, '300.0 Kib/sec'),
|
||||
(500, '500.0 Kib/sec')
|
||||
]
|
||||
|
||||
COOKIE_DEFAULTS = {
|
||||
'auto_refresh_secs':'10'
|
||||
}
|
||||
|
||||
try:
|
||||
SESSIONS = pickle.load(open(session_file))
|
||||
except:
|
||||
SESSIONS = []
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -45,15 +45,21 @@ import webpy022 as web
|
|||
from webpy022.webapi import cookies, setcookie as w_setcookie
|
||||
from webpy022.http import seeother, url
|
||||
from webpy022 import template,changequery as self_url
|
||||
from webpy022.utils import Storage
|
||||
from static_handler import static_handler
|
||||
|
||||
from deluge.common import fsize,fspeed
|
||||
|
||||
import traceback
|
||||
import random
|
||||
from operator import attrgetter
|
||||
import datetime
|
||||
import pickle
|
||||
from md5 import md5
|
||||
|
||||
from deluge import common
|
||||
from webserver_common import REVNO, VERSION
|
||||
from webserver_common import REVNO, VERSION, COOKIE_DEFAULTS
|
||||
import webserver_common as ws
|
||||
|
||||
from debugerror import deluge_debugerror
|
||||
|
||||
#init:
|
||||
|
@ -65,14 +71,22 @@ def setcookie(key, val):
|
|||
"""add 30 days expires header for persistent cookies"""
|
||||
return w_setcookie(key, val , expires=2592000)
|
||||
|
||||
SESSIONS = [] #dumb sessions.
|
||||
#really simple sessions, to bad i had to implement them myself.
|
||||
def start_session():
|
||||
session_id = str(random.random())
|
||||
SESSIONS.append(session_id)
|
||||
ws.SESSIONS.append(session_id)
|
||||
if len(ws.SESSIONS) > 20: #save max 20 sessions?
|
||||
ws.SESSIONS = ws.SESSIONS[-20:]
|
||||
#not thread safe! , but a verry rare bug.
|
||||
pickle.dump(ws.SESSIONS, open(ws.session_file,'wb'))
|
||||
setcookie("session_id", session_id)
|
||||
|
||||
if getcookie('auto_refresh_secs') == None:
|
||||
setcookie('auto_refresh_secs','10')
|
||||
def end_session():
|
||||
session_id = getcookie("session_id")
|
||||
if session_id in ws.SESSIONS:
|
||||
ws.SESSIONS.remove(session_id)
|
||||
#not thread safe! , but a verry rare bug.
|
||||
pickle.dump(ws.SESSIONS, open(ws.session_file,'wb'))
|
||||
|
||||
def do_redirect():
|
||||
"""for redirects after a POST"""
|
||||
|
@ -92,7 +106,6 @@ def error_page(error):
|
|||
print ws.render.error(error)
|
||||
|
||||
def getcookie(key, default=None):
|
||||
COOKIE_DEFAULTS = {'auto_refresh_secs':'10'}
|
||||
key = str(key).strip()
|
||||
ck = cookies()
|
||||
val = ck.get(key, default)
|
||||
|
@ -120,9 +133,8 @@ def check_session(func):
|
|||
"""
|
||||
def deco(self, name):
|
||||
vars = web.input(redir_after_login=None)
|
||||
|
||||
ck = cookies()
|
||||
if ck.has_key("session_id") and ck["session_id"] in SESSIONS:
|
||||
if ck.has_key("session_id") and ck["session_id"] in ws.SESSIONS:
|
||||
return func(self, name) #ok, continue..
|
||||
elif vars.redir_after_login:
|
||||
seeother(url("/login",redir=self_url()))
|
||||
|
@ -154,6 +166,77 @@ def remote(func):
|
|||
print traceback.format_exc()
|
||||
return deco
|
||||
|
||||
#utils:
|
||||
def check_pwd(pwd):
|
||||
m = md5()
|
||||
m.update(ws.config.get('pwd_salt'))
|
||||
m.update(pwd)
|
||||
return (m.digest() == ws.config.get('pwd_md5'))
|
||||
|
||||
def get_stats():
|
||||
stats = Storage({
|
||||
'download_rate':fspeed(ws.proxy.get_download_rate()),
|
||||
'upload_rate':fspeed(ws.proxy.get_upload_rate()),
|
||||
'max_download':ws.proxy.get_config_value('max_download_speed_bps'),
|
||||
'max_upload':ws.proxy.get_config_value('max_upload_speed_bps'),
|
||||
})
|
||||
if stats.max_upload < 0:
|
||||
stats.max_upload = _("Unlimited")
|
||||
else:
|
||||
stats.max_upload = fspeed(stats.max_upload)
|
||||
|
||||
if stats.max_download < 0:
|
||||
stats.max_download = _("Unlimited")
|
||||
else:
|
||||
stats.max_download = fspeed(stats.max_download)
|
||||
|
||||
return stats
|
||||
|
||||
|
||||
def get_torrent_status(torrent_id):
|
||||
"""
|
||||
helper method.
|
||||
enhance ws.proxy.get_torrent_status with some extra data
|
||||
"""
|
||||
status = Storage(ws.proxy.get_torrent_status(torrent_id,ws.TORRENT_KEYS))
|
||||
|
||||
#add missing values for deluge 0.6:
|
||||
for key in ws.TORRENT_KEYS:
|
||||
if not key in status:
|
||||
status[key] = 0
|
||||
|
||||
status["id"] = torrent_id
|
||||
|
||||
#for naming the status-images
|
||||
status["calc_state_str"] = "downloading"
|
||||
if status["paused"]:
|
||||
status["calc_state_str"] = "inactive"
|
||||
elif status["is_seed"]:
|
||||
status["calc_state_str"] = "seeding"
|
||||
|
||||
#action for torrent_pause
|
||||
if status["calc_state_str"] == "inactive":
|
||||
status["action"] = "start"
|
||||
else:
|
||||
status["action"] = "stop"
|
||||
|
||||
if status["paused"]:
|
||||
status["message"] = _("Paused %s%%") % status['progress']
|
||||
else:
|
||||
status["message"] = "%s %i%%" % (ws.STATE_MESSAGES[status["state"]]
|
||||
, status['progress'])
|
||||
|
||||
#add some pre-calculated values
|
||||
status.update({
|
||||
"calc_total_downloaded" : (fsize(status["total_done"])
|
||||
+ " (" + fsize(status["total_download"]) + ")"),
|
||||
"calc_total_uploaded": (fsize(status['uploaded_memory']
|
||||
+ status["total_payload_upload"]) + " ("
|
||||
+ fsize(status["total_upload"]) + ")"),
|
||||
})
|
||||
return status
|
||||
#/utils
|
||||
|
||||
#template-defs:
|
||||
def template_crop(text, end):
|
||||
if len(text) > end:
|
||||
|
@ -176,12 +259,15 @@ def template_sort_head(id,name):
|
|||
|
||||
return ws.render.sort_column_head(id, name, order, active_up, active_down)
|
||||
|
||||
def template_part_stats():
|
||||
return ws.render.part_stats(get_stats())
|
||||
|
||||
def get_config(var):
|
||||
return ws.config.get(var)
|
||||
|
||||
template.Template.globals.update({
|
||||
'sort_head': template_sort_head,
|
||||
'part_stats':template_part_stats,
|
||||
'crop': template_crop,
|
||||
'_': _ , #gettext/translations
|
||||
'str': str, #because % in templetor is broken.
|
||||
|
@ -198,145 +284,20 @@ template.Template.globals.update({
|
|||
})
|
||||
#/template-defs
|
||||
|
||||
def create_webserver(urls, methods):
|
||||
from webpy022.request import webpyfunc
|
||||
from webpy022 import webapi
|
||||
from gtk_cherrypy_wsgiserver import CherryPyWSGIServer
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
#Some copy and paste from web.py
|
||||
#mostly caused by /static
|
||||
#TODO : FIX THIS.
|
||||
#static-files serving should be moved to the normal webserver!
|
||||
from SimpleHTTPServer import SimpleHTTPRequestHandler
|
||||
from BaseHTTPServer import BaseHTTPRequestHandler
|
||||
from gtk_cherrypy_wsgiserver import CherryPyWSGIServer
|
||||
from BaseHTTPServer import BaseHTTPRequestHandler
|
||||
|
||||
from webpy022.request import webpyfunc
|
||||
from webpy022 import webapi
|
||||
import os
|
||||
|
||||
import posixpath
|
||||
import urllib
|
||||
import urlparse
|
||||
|
||||
class RelativeHandler(SimpleHTTPRequestHandler):
|
||||
def translate_path(self, path):
|
||||
"""Translate a /-separated PATH to the local filename syntax.
|
||||
|
||||
Components that mean special things to the local file system
|
||||
(e.g. drive or directory names) are ignored. (XXX They should
|
||||
probably be diagnosed.)
|
||||
|
||||
"""
|
||||
# abandon query parameters
|
||||
path = urlparse.urlparse(path)[2]
|
||||
path = posixpath.normpath(urllib.unquote(path))
|
||||
words = path.split('/')
|
||||
words = filter(None, words)
|
||||
path = os.path.dirname(__file__)
|
||||
for word in words:
|
||||
drive, word = os.path.splitdrive(word)
|
||||
head, word = os.path.split(word)
|
||||
if word in (os.curdir, os.pardir): continue
|
||||
path = os.path.join(path, word)
|
||||
return path
|
||||
|
||||
class StaticApp(RelativeHandler):
|
||||
"""WSGI application for serving static files."""
|
||||
def __init__(self, environ, start_response):
|
||||
self.headers = []
|
||||
self.environ = environ
|
||||
self.start_response = start_response
|
||||
|
||||
def send_response(self, status, msg=""):
|
||||
self.status = str(status) + " " + msg
|
||||
|
||||
def send_header(self, name, value):
|
||||
self.headers.append((name, value))
|
||||
|
||||
def end_headers(self):
|
||||
pass
|
||||
|
||||
def log_message(*a): pass
|
||||
|
||||
def __iter__(self):
|
||||
environ = self.environ
|
||||
|
||||
self.path = environ.get('PATH_INFO', '')
|
||||
self.client_address = environ.get('REMOTE_ADDR','-'), \
|
||||
environ.get('REMOTE_PORT','-')
|
||||
self.command = environ.get('REQUEST_METHOD', '-')
|
||||
|
||||
from cStringIO import StringIO
|
||||
self.wfile = StringIO() # for capturing error
|
||||
|
||||
f = self.send_head()
|
||||
self.start_response(self.status, self.headers)
|
||||
|
||||
if f:
|
||||
block_size = 16 * 1024
|
||||
while True:
|
||||
buf = f.read(block_size)
|
||||
if not buf:
|
||||
break
|
||||
yield buf
|
||||
f.close()
|
||||
else:
|
||||
value = self.wfile.getvalue()
|
||||
yield value
|
||||
|
||||
class WSGIWrapper(BaseHTTPRequestHandler):
|
||||
"""WSGI wrapper for logging the status and serving static files."""
|
||||
def __init__(self, app):
|
||||
self.app = app
|
||||
self.format = '%s - - [%s] "%s %s %s" - %s'
|
||||
|
||||
def __call__(self, environ, start_response):
|
||||
def xstart_response(status, response_headers, *args):
|
||||
write = start_response(status, response_headers, *args)
|
||||
self.log(status, environ)
|
||||
return write
|
||||
|
||||
path = environ.get('PATH_INFO', '')
|
||||
if path.startswith('/static/'):
|
||||
return StaticApp(environ, xstart_response)
|
||||
else:
|
||||
return self.app(environ, xstart_response)
|
||||
|
||||
def log(self, status, environ):
|
||||
#mvoncken,no logging..
|
||||
return
|
||||
|
||||
outfile = environ.get('wsgi.errors', web.debug)
|
||||
req = environ.get('PATH_INFO', '_')
|
||||
protocol = environ.get('ACTUAL_SERVER_PROTOCOL', '-')
|
||||
method = environ.get('REQUEST_METHOD', '-')
|
||||
host = "%s:%s" % (environ.get('REMOTE_ADDR','-'),
|
||||
environ.get('REMOTE_PORT','-'))
|
||||
|
||||
#@@ It is really bad to extend from
|
||||
#@@ BaseHTTPRequestHandler just for this method
|
||||
time = self.log_date_time_string()
|
||||
|
||||
print >> outfile, self.format % (host, time, protocol,
|
||||
method, req, status)
|
||||
|
||||
def create_webserver(urls,methods):
|
||||
func = webapi.wsgifunc(webpyfunc(urls,methods, False))
|
||||
server_address=("0.0.0.0",ws.config.get('port'))
|
||||
|
||||
func = WSGIWrapper(func)
|
||||
func = webapi.wsgifunc(webpyfunc(urls, methods, False))
|
||||
server_address=("0.0.0.0", int(ws.config.get('port')))
|
||||
server = CherryPyWSGIServer(server_address, func, server_name="localhost")
|
||||
|
||||
|
||||
print "(created) http://%s:%d/" % server_address
|
||||
|
||||
print "http://%s:%d/" % server_address
|
||||
return server
|
||||
|
||||
#------
|
||||
__all__ = ['deluge_page_noauth', 'deluge_page', 'remote',
|
||||
'auto_refreshed', 'check_session',
|
||||
'do_redirect', 'error_page','start_session','getcookie'
|
||||
,'create_webserver','setcookie']
|
||||
|
||||
|
||||
|
||||
,'setcookie','create_webserver','end_session',
|
||||
'get_torrent_status', 'check_pwd','static_handler']
|
||||
|
|
|
@ -54,3 +54,7 @@ plugins/WebSeed/__init__.py
|
|||
plugins/WebSeed/webseed.glade
|
||||
plugins/Scheduler/__init__.py
|
||||
plugins/Scheduler/plugin.py
|
||||
plugins/WebUi/__init__.py
|
||||
plugins/WebUi/webserver_common.py
|
||||
plugins/WebUi/deluge_webserver.py
|
||||
plugins/WebUi/scripts/template_strings.py
|
||||
|
|
254
po/deluge.pot
254
po/deluge.pot
|
@ -8,7 +8,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2007-10-22 22:35-0500\n"
|
||||
"POT-Creation-Date: 2007-10-27 20:34-0500\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
|
@ -88,7 +88,7 @@ msgstr ""
|
|||
msgid "<b>Torrent Info</b>"
|
||||
msgstr ""
|
||||
|
||||
#: glade/delugegtk.glade:750
|
||||
#: glade/delugegtk.glade:750 plugins/WebUi/scripts/template_strings.py:8
|
||||
msgid "Details"
|
||||
msgstr ""
|
||||
|
||||
|
@ -140,7 +140,7 @@ msgstr ""
|
|||
msgid "_Columns"
|
||||
msgstr ""
|
||||
|
||||
#: glade/delugegtk.glade:947 src/interface.py:596 src/files.py:79
|
||||
#: glade/delugegtk.glade:947 src/interface.py:596 src/files.py:80
|
||||
msgid "Size"
|
||||
msgstr ""
|
||||
|
||||
|
@ -149,11 +149,13 @@ msgid "Status"
|
|||
msgstr ""
|
||||
|
||||
#: glade/delugegtk.glade:965 src/interface.py:602
|
||||
#: plugins/WebUi/scripts/template_strings.py:19
|
||||
msgid "Seeders"
|
||||
msgstr ""
|
||||
|
||||
#: glade/delugegtk.glade:974 src/interface.py:605
|
||||
#: plugins/TorrentPeers/__init__.py:72
|
||||
#: plugins/WebUi/scripts/template_strings.py:15
|
||||
msgid "Peers"
|
||||
msgstr ""
|
||||
|
||||
|
@ -171,11 +173,11 @@ msgstr ""
|
|||
msgid "Time Remaining"
|
||||
msgstr ""
|
||||
|
||||
#: glade/delugegtk.glade:1010
|
||||
#: glade/delugegtk.glade:1010 plugins/WebUi/scripts/template_strings.py:4
|
||||
msgid "Availability"
|
||||
msgstr ""
|
||||
|
||||
#: glade/delugegtk.glade:1019
|
||||
#: glade/delugegtk.glade:1019 plugins/WebUi/scripts/template_strings.py:21
|
||||
msgid "Share Ratio"
|
||||
msgstr ""
|
||||
|
||||
|
@ -211,7 +213,7 @@ msgstr ""
|
|||
msgid "Remove Torrent"
|
||||
msgstr ""
|
||||
|
||||
#: glade/delugegtk.glade:1157
|
||||
#: glade/delugegtk.glade:1157 plugins/WebUi/scripts/template_strings.py:18
|
||||
msgid "Remove"
|
||||
msgstr ""
|
||||
|
||||
|
@ -278,7 +280,7 @@ msgstr ""
|
|||
msgid "Delete downloaded files"
|
||||
msgstr ""
|
||||
|
||||
#: glade/dgtkpopups.glade:88
|
||||
#: glade/dgtkpopups.glade:88 plugins/WebUi/scripts/template_strings.py:6
|
||||
msgid "Delete .torrent file"
|
||||
msgstr ""
|
||||
|
||||
|
@ -294,7 +296,7 @@ msgstr ""
|
|||
msgid "Clear Finished"
|
||||
msgstr ""
|
||||
|
||||
#: glade/dgtkpopups.glade:241
|
||||
#: glade/dgtkpopups.glade:241 plugins/WebUi/scripts/template_strings.py:22
|
||||
msgid "Speed"
|
||||
msgstr ""
|
||||
|
||||
|
@ -542,6 +544,7 @@ msgid "<b>Seeding</b>"
|
|||
msgstr ""
|
||||
|
||||
#: glade/preferences_dialog.glade:964 src/core.py:91
|
||||
#: plugins/WebUi/webserver_common.py:139
|
||||
msgid "Seeding"
|
||||
msgstr ""
|
||||
|
||||
|
@ -646,6 +649,7 @@ msgstr ""
|
|||
|
||||
#: glade/preferences_dialog.glade:1478 glade/preferences_dialog.glade:1672
|
||||
#: glade/preferences_dialog.glade:1866 glade/preferences_dialog.glade:2060
|
||||
#: plugins/WebUi/scripts/template_strings.py:13
|
||||
msgid "Password"
|
||||
msgstr ""
|
||||
|
||||
|
@ -1004,7 +1008,7 @@ msgstr ""
|
|||
msgid "Name"
|
||||
msgstr ""
|
||||
|
||||
#: src/interface.py:614
|
||||
#: src/interface.py:614 plugins/WebUi/scripts/template_strings.py:10
|
||||
msgid "ETA"
|
||||
msgstr ""
|
||||
|
||||
|
@ -1088,31 +1092,32 @@ msgstr ""
|
|||
msgid "Are you sure that you want to remove all seeding torrents?"
|
||||
msgstr ""
|
||||
|
||||
#: src/core.py:85
|
||||
#: src/core.py:85 plugins/WebUi/webserver_common.py:133
|
||||
msgid "Queued"
|
||||
msgstr ""
|
||||
|
||||
#: src/core.py:86
|
||||
#: src/core.py:86 plugins/WebUi/webserver_common.py:134
|
||||
msgid "Checking"
|
||||
msgstr ""
|
||||
|
||||
#: src/core.py:87
|
||||
#: src/core.py:87 plugins/WebUi/webserver_common.py:135
|
||||
msgid "Connecting"
|
||||
msgstr ""
|
||||
|
||||
#: src/core.py:88
|
||||
#: src/core.py:88 plugins/WebUi/webserver_common.py:136
|
||||
msgid "Downloading Metadata"
|
||||
msgstr ""
|
||||
|
||||
#: src/core.py:89 plugins/BlocklistImport/ui.py:117
|
||||
#: plugins/WebUi/webserver_common.py:137
|
||||
msgid "Downloading"
|
||||
msgstr ""
|
||||
|
||||
#: src/core.py:90
|
||||
#: src/core.py:90 plugins/WebUi/webserver_common.py:138
|
||||
msgid "Finished"
|
||||
msgstr ""
|
||||
|
||||
#: src/core.py:92
|
||||
#: src/core.py:92 plugins/WebUi/webserver_common.py:140
|
||||
msgid "Allocating"
|
||||
msgstr ""
|
||||
|
||||
|
@ -1156,11 +1161,11 @@ msgstr ""
|
|||
msgid "Filename"
|
||||
msgstr ""
|
||||
|
||||
#: src/files.py:81
|
||||
#: src/files.py:82
|
||||
msgid "Priority"
|
||||
msgstr ""
|
||||
|
||||
#: src/files.py:103
|
||||
#: src/files.py:104
|
||||
msgid ""
|
||||
"File priority can only be set when using full allocation.\n"
|
||||
"Please change your preference to disable compact allocation, then remove and "
|
||||
|
@ -1175,11 +1180,11 @@ msgstr ""
|
|||
msgid "Enabled"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.py:433
|
||||
#: src/dialogs.py:435
|
||||
msgid "translator-credits"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.py:434
|
||||
#: src/dialogs.py:436
|
||||
msgid ""
|
||||
"Deluge is free software, you can redistribute it and/or\n"
|
||||
"modify it under the terms of the GNU General Public\n"
|
||||
|
@ -1196,15 +1201,15 @@ msgid ""
|
|||
"1301 USA"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.py:474
|
||||
#: src/dialogs.py:476
|
||||
msgid "Choose a .torrent file"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.py:479
|
||||
#: src/dialogs.py:481
|
||||
msgid "Torrent files"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.py:483
|
||||
#: src/dialogs.py:485
|
||||
msgid "All files"
|
||||
msgstr ""
|
||||
|
||||
|
@ -1390,66 +1395,66 @@ msgstr ""
|
|||
msgid "Torrent Creator"
|
||||
msgstr ""
|
||||
|
||||
#: plugins/TorrentCreator/torrentcreator.glade:103
|
||||
#: plugins/TorrentCreator/torrentcreator.glade:102
|
||||
msgid "This torrent will be made from a single file"
|
||||
msgstr ""
|
||||
|
||||
#: plugins/TorrentCreator/torrentcreator.glade:104
|
||||
#: plugins/TorrentCreator/torrentcreator.glade:103
|
||||
msgid "File:"
|
||||
msgstr ""
|
||||
|
||||
#: plugins/TorrentCreator/torrentcreator.glade:120
|
||||
#: plugins/TorrentCreator/torrentcreator.glade:119
|
||||
msgid "This torrent will be made from a directory"
|
||||
msgstr ""
|
||||
|
||||
#: plugins/TorrentCreator/torrentcreator.glade:121
|
||||
#: plugins/TorrentCreator/torrentcreator.glade:120
|
||||
msgid "Folder:"
|
||||
msgstr ""
|
||||
|
||||
#: plugins/TorrentCreator/torrentcreator.glade:138
|
||||
#: plugins/TorrentCreator/torrentcreator.glade:137
|
||||
msgid "<b>Source</b>"
|
||||
msgstr ""
|
||||
|
||||
#: plugins/TorrentCreator/torrentcreator.glade:184
|
||||
#: plugins/TorrentCreator/torrentcreator.glade:182
|
||||
msgid "Save Torrent File As:"
|
||||
msgstr ""
|
||||
|
||||
#: plugins/TorrentCreator/torrentcreator.glade:237
|
||||
#: plugins/TorrentCreator/torrentcreator.glade:235
|
||||
msgid "Load this torrent into Deluge for seeding"
|
||||
msgstr ""
|
||||
|
||||
#: plugins/TorrentCreator/torrentcreator.glade:238
|
||||
#: plugins/TorrentCreator/torrentcreator.glade:236
|
||||
msgid "Add new torrent to queue"
|
||||
msgstr ""
|
||||
|
||||
#: plugins/TorrentCreator/torrentcreator.glade:257
|
||||
#: plugins/TorrentCreator/torrentcreator.glade:255
|
||||
msgid "<b>Torrent File</b>"
|
||||
msgstr ""
|
||||
|
||||
#: plugins/TorrentCreator/torrentcreator.glade:305
|
||||
#: plugins/TorrentCreator/torrentcreator.glade:302
|
||||
msgid "<b>Trackers</b>"
|
||||
msgstr ""
|
||||
|
||||
#: plugins/TorrentCreator/torrentcreator.glade:352
|
||||
#: plugins/TorrentCreator/torrentcreator.glade:348
|
||||
msgid "<b>Comments</b>"
|
||||
msgstr ""
|
||||
|
||||
#: plugins/TorrentCreator/torrentcreator.glade:389
|
||||
#: plugins/TorrentCreator/torrentcreator.glade:384
|
||||
msgid "<b>Author</b>"
|
||||
msgstr ""
|
||||
|
||||
#: plugins/TorrentCreator/torrentcreator.glade:425
|
||||
#: plugins/TorrentCreator/torrentcreator.glade:423
|
||||
msgid "Set Private Flag"
|
||||
msgstr ""
|
||||
|
||||
#: plugins/TorrentCreator/torrentcreator.glade:441
|
||||
#: plugins/TorrentCreator/torrentcreator.glade:461
|
||||
#: plugins/TorrentCreator/torrentcreator.glade:436
|
||||
#: plugins/TorrentCreator/torrentcreator.glade:457
|
||||
msgid ""
|
||||
"The smaller the piece sizes, the more efficient the transfers will be, but "
|
||||
"the actual \".torrent\" file will be larger"
|
||||
msgstr ""
|
||||
|
||||
#: plugins/TorrentCreator/torrentcreator.glade:442
|
||||
#: plugins/TorrentCreator/torrentcreator.glade:437
|
||||
msgid ""
|
||||
"32 KiB\n"
|
||||
"64 KiB\n"
|
||||
|
@ -1457,13 +1462,14 @@ msgid ""
|
|||
"256 KiB\n"
|
||||
"512 KiB\n"
|
||||
"1024 KiB\n"
|
||||
"2048 KiB\n"
|
||||
msgstr ""
|
||||
|
||||
#: plugins/TorrentCreator/torrentcreator.glade:463
|
||||
#: plugins/TorrentCreator/torrentcreator.glade:459
|
||||
msgid "Piece Size:"
|
||||
msgstr ""
|
||||
|
||||
#: plugins/TorrentCreator/torrentcreator.glade:477
|
||||
#: plugins/TorrentCreator/torrentcreator.glade:473
|
||||
msgid "<b>Advanced</b>"
|
||||
msgstr ""
|
||||
|
||||
|
@ -2102,3 +2108,171 @@ msgid ""
|
|||
"When set to -1 (unlimited), the global limits in Deluge's preferences will "
|
||||
"be obeyed."
|
||||
msgstr ""
|
||||
|
||||
#: plugins/WebUi/__init__.py:31
|
||||
msgid "Web User Interface"
|
||||
msgstr ""
|
||||
|
||||
#: plugins/WebUi/__init__.py:34
|
||||
msgid ""
|
||||
"A Web based User Interface\n"
|
||||
"\n"
|
||||
"Firefox greasemonkey script: http://userscripts.org/scripts/show/12639\n"
|
||||
"\n"
|
||||
"Remotely add a file: \"curl -F torrent=@./test1.torrent -F pwd=deluge http://"
|
||||
"localhost:8112/remote/torrent/add\"\n"
|
||||
"\n"
|
||||
"There is support for multiple templates, but just one is included.\n"
|
||||
"\n"
|
||||
"Other contributors:\n"
|
||||
"*somedude : template enhancements.\n"
|
||||
"*markybob : stability : synced with his changes in deluge-svn.\n"
|
||||
msgstr ""
|
||||
|
||||
#: plugins/WebUi/__init__.py:179
|
||||
msgid "WebUi Config"
|
||||
msgstr ""
|
||||
|
||||
#: plugins/WebUi/__init__.py:187
|
||||
msgid "Port Number"
|
||||
msgstr ""
|
||||
|
||||
#: plugins/WebUi/__init__.py:188
|
||||
msgid "New Password"
|
||||
msgstr ""
|
||||
|
||||
#: plugins/WebUi/__init__.py:189
|
||||
msgid "New Password(confirm)"
|
||||
msgstr ""
|
||||
|
||||
#: plugins/WebUi/__init__.py:190
|
||||
msgid "Template"
|
||||
msgstr ""
|
||||
|
||||
#: plugins/WebUi/__init__.py:191
|
||||
msgid "Button Style"
|
||||
msgstr ""
|
||||
|
||||
#: plugins/WebUi/__init__.py:193
|
||||
msgid "Cache Templates"
|
||||
msgstr ""
|
||||
|
||||
#: plugins/WebUi/__init__.py:209
|
||||
msgid "Text and image"
|
||||
msgstr ""
|
||||
|
||||
#: plugins/WebUi/__init__.py:209
|
||||
msgid "Image Only"
|
||||
msgstr ""
|
||||
|
||||
#: plugins/WebUi/__init__.py:209
|
||||
msgid "Text Only"
|
||||
msgstr ""
|
||||
|
||||
#: plugins/WebUi/__init__.py:243
|
||||
msgid "Confirmed Password <> New Password\n"
|
||||
msgstr ""
|
||||
|
||||
#: plugins/WebUi/webserver_common.py:48
|
||||
msgid "translate something"
|
||||
msgstr ""
|
||||
|
||||
#: plugins/WebUi/deluge_webserver.py:142
|
||||
msgid "Choose an url or a torrent, not both."
|
||||
msgstr ""
|
||||
|
||||
#: plugins/WebUi/deluge_webserver.py:153
|
||||
msgid "no data."
|
||||
msgstr ""
|
||||
|
||||
#: plugins/WebUi/deluge_webserver.py:230
|
||||
msgid "refresh must be > 0"
|
||||
msgstr ""
|
||||
|
||||
#: plugins/WebUi/deluge_webserver.py:238
|
||||
msgid "Download Speed Limit"
|
||||
msgstr ""
|
||||
|
||||
#: plugins/WebUi/deluge_webserver.py:242
|
||||
msgid "Upload Speed Limit"
|
||||
msgstr ""
|
||||
|
||||
#: plugins/WebUi/scripts/template_strings.py:1
|
||||
msgid "# Of Files"
|
||||
msgstr ""
|
||||
|
||||
#: plugins/WebUi/scripts/template_strings.py:2
|
||||
msgid "About"
|
||||
msgstr ""
|
||||
|
||||
#: plugins/WebUi/scripts/template_strings.py:3
|
||||
msgid "Auto refresh:"
|
||||
msgstr ""
|
||||
|
||||
#: plugins/WebUi/scripts/template_strings.py:5
|
||||
msgid "Debug:Data Dump"
|
||||
msgstr ""
|
||||
|
||||
#: plugins/WebUi/scripts/template_strings.py:7
|
||||
msgid "Delete downloaded files."
|
||||
msgstr ""
|
||||
|
||||
#: plugins/WebUi/scripts/template_strings.py:9
|
||||
msgid "Downloaded"
|
||||
msgstr ""
|
||||
|
||||
#: plugins/WebUi/scripts/template_strings.py:11
|
||||
msgid "Next Announce"
|
||||
msgstr ""
|
||||
|
||||
#: plugins/WebUi/scripts/template_strings.py:12
|
||||
msgid "Off"
|
||||
msgstr ""
|
||||
|
||||
#: plugins/WebUi/scripts/template_strings.py:14
|
||||
msgid "Password is invalid,try again"
|
||||
msgstr ""
|
||||
|
||||
#: plugins/WebUi/scripts/template_strings.py:16
|
||||
msgid "Pieces"
|
||||
msgstr ""
|
||||
|
||||
#: plugins/WebUi/scripts/template_strings.py:17
|
||||
msgid "Refresh page every:"
|
||||
msgstr ""
|
||||
|
||||
#: plugins/WebUi/scripts/template_strings.py:20
|
||||
msgid "Set"
|
||||
msgstr ""
|
||||
|
||||
#: plugins/WebUi/scripts/template_strings.py:23
|
||||
msgid "Submit"
|
||||
msgstr ""
|
||||
|
||||
#: plugins/WebUi/scripts/template_strings.py:24
|
||||
msgid "Total Size"
|
||||
msgstr ""
|
||||
|
||||
#: plugins/WebUi/scripts/template_strings.py:25
|
||||
msgid "Tracker"
|
||||
msgstr ""
|
||||
|
||||
#: plugins/WebUi/scripts/template_strings.py:26
|
||||
msgid "Tracker Status"
|
||||
msgstr ""
|
||||
|
||||
#: plugins/WebUi/scripts/template_strings.py:27
|
||||
msgid "Upload torrent"
|
||||
msgstr ""
|
||||
|
||||
#: plugins/WebUi/scripts/template_strings.py:28
|
||||
msgid "Uploaded"
|
||||
msgstr ""
|
||||
|
||||
#: plugins/WebUi/scripts/template_strings.py:29
|
||||
msgid "Url"
|
||||
msgstr ""
|
||||
|
||||
#: plugins/WebUi/scripts/template_strings.py:30
|
||||
msgid "seconds"
|
||||
msgstr ""
|
||||
|
|
2
setup.py
2
setup.py
|
@ -28,7 +28,7 @@
|
|||
|
||||
NAME = "deluge"
|
||||
FULLNAME = "Deluge BitTorrent Client"
|
||||
VERSION = "0.5.5.95"
|
||||
VERSION = "0.5.6.1"
|
||||
AUTHOR = "Zach Tibbitts, Alon Zakai, Marcos Pinto, Andrew Resch, Alex Dedul"
|
||||
EMAIL = "zach@collegegeek.org, kripkensteiner@gmail.com, marcospinto@dipconsultants.com, alonzakai@gmail.com, rotmer@gmail.com"
|
||||
DESCRIPTION = "A bittorrent client written in PyGTK"
|
||||
|
|
|
@ -32,7 +32,7 @@ import os
|
|||
import xdg.BaseDirectory
|
||||
|
||||
PROGRAM_NAME = "Deluge"
|
||||
PROGRAM_VERSION = "0.5.5.95"
|
||||
PROGRAM_VERSION = "0.5.6.1"
|
||||
|
||||
CLIENT_CODE = "DE"
|
||||
CLIENT_VERSION = "".join(PROGRAM_VERSION.split('.'))+"0"*(4 - len(PROGRAM_VERSION.split('.')))
|
||||
|
|
|
@ -646,7 +646,6 @@ static PyObject *torrent_set_max_connections_global(PyObject *self, PyObject *ar
|
|||
|
||||
// printf("Setting max connections: %d\r\n", max_conn);
|
||||
M_ses->set_max_connections(max_conn);
|
||||
|
||||
Py_INCREF(Py_None); return Py_None;
|
||||
}
|
||||
|
||||
|
@ -1217,11 +1216,12 @@ static PyObject *torrent_get_session_info(PyObject *self, PyObject *args)
|
|||
{
|
||||
session_status s = M_ses->status();
|
||||
|
||||
return Py_BuildValue("{s:l,s:f,s:f,s:l,s:f,s:f}",
|
||||
return Py_BuildValue("{s:l,s:f,s:f,s:ls:l,s:f,s:f}",
|
||||
"has_incoming_connections", long(s.has_incoming_connections),
|
||||
"upload_rate", float(s.payload_upload_rate),
|
||||
"download_rate", float(s.payload_download_rate),
|
||||
"num_peers", long(s.num_peers),
|
||||
"num_connections", long(M_ses->num_connections()),
|
||||
"total_downloaded", float(s.total_payload_download),
|
||||
"total_uploaded", float(s.total_payload_upload));
|
||||
}
|
||||
|
@ -1778,8 +1778,7 @@ static PyObject *torrent_replace_trackers(PyObject *self, PyObject *args)
|
|||
if (PyErr_Occurred())
|
||||
return NULL;
|
||||
|
||||
torrent_handle& h = M_torrents->at(index).handle;
|
||||
if (h.is_valid()){
|
||||
if (M_torrents->at(index).handle.is_valid()){
|
||||
std::vector<libtorrent::announce_entry> trackerlist;
|
||||
std::istringstream trackers(tracker);
|
||||
std::string line;
|
||||
|
@ -1787,8 +1786,8 @@ static PyObject *torrent_replace_trackers(PyObject *self, PyObject *args)
|
|||
libtorrent::announce_entry a_entry(line);
|
||||
trackerlist.push_back(a_entry);
|
||||
}
|
||||
h.replace_trackers(trackerlist);
|
||||
h.force_reannounce();
|
||||
M_torrents->at(index).handle.replace_trackers(trackerlist);
|
||||
M_torrents->at(index).handle.force_reannounce();
|
||||
}
|
||||
Py_INCREF(Py_None); return Py_None;
|
||||
}
|
||||
|
|
|
@ -43,7 +43,8 @@ import gtk
|
|||
|
||||
def cell_data_speed(column, cell, model, iter, data):
|
||||
speed = int(model.get_value(iter, data))
|
||||
speed_str = common.fspeed(speed)
|
||||
if speed<100: speed_str = ""
|
||||
else: speed_str = common.fspeed(speed)
|
||||
cell.set_property('text', speed_str)
|
||||
|
||||
def cell_data_size(column, cell, model, iter, data):
|
||||
|
|
|
@ -428,6 +428,8 @@ def show_about_dialog(window):
|
|||
abt.set_transient_for(window)
|
||||
abt.set_name(common.PROGRAM_NAME)
|
||||
abt.set_version(common.PROGRAM_VERSION)
|
||||
abt.set_comments("Deluge is a full-featured BitTorrent\nclient for Linux, Mac OS X and Windows")
|
||||
abt.set_documenters(["Marcos Pinto"])
|
||||
abt.set_authors(["Zach Tibbitts", "Alon Zakai", "Marcos Pinto", "Andrew Resch", "Alex Dedul"])
|
||||
abt.set_artists(["Andrew Wedderburn"])
|
||||
abt.set_translator_credits(_("translator-credits"))
|
||||
|
|
|
@ -947,11 +947,17 @@ window, please enter your password"))
|
|||
unique_id = self.manager.get_torrent_unique_id(torrent)
|
||||
try:
|
||||
if self.manager.unique_IDs[unique_id].trackers:
|
||||
self.manager.replace_trackers(unique_id, \
|
||||
try:
|
||||
self.manager.replace_trackers(unique_id, \
|
||||
self.manager.unique_IDs[unique_id].trackers)
|
||||
except:
|
||||
pass
|
||||
if self.manager.unique_IDs[unique_id].uploaded_memory:
|
||||
self.manager.unique_IDs[unique_id].initial_uploaded_memory \
|
||||
try:
|
||||
self.manager.unique_IDs[unique_id].initial_uploaded_memory \
|
||||
= self.manager.unique_IDs[unique_id].uploaded_memory
|
||||
except:
|
||||
pass
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
|
@ -1091,7 +1097,7 @@ window, please enter your password"))
|
|||
def update_statusbar_and_tray(self):
|
||||
plugin_messages = self.plugins.get_plugin_tray_messages()
|
||||
core_state = self.manager.get_state()
|
||||
connections = core_state['num_peers']
|
||||
connections = core_state['num_connections']
|
||||
if self.config.get("max_connections_global") < 0 :
|
||||
max_connections = _("Unlimited")
|
||||
else:
|
||||
|
|
Loading…
Add table
Reference in a new issue