torrent piece plugin - micah
This commit is contained in:
parent
d1342efc67
commit
b6ee1d0e37
|
@ -183,6 +183,63 @@ namespace libtorrent
|
|||
{ return std::auto_ptr<alert>(new torrent_finished_alert(*this)); }
|
||||
};
|
||||
|
||||
struct TORRENT_EXPORT piece_finished_alert: torrent_alert
|
||||
{
|
||||
piece_finished_alert(
|
||||
const torrent_handle& h
|
||||
, int piece_num
|
||||
, const std::string& msg)
|
||||
: torrent_alert(h, alert::warning, msg)
|
||||
, piece_index(piece_num)
|
||||
{ assert(piece_index >= 0);}
|
||||
|
||||
int piece_index;
|
||||
|
||||
virtual std::auto_ptr<alert> clone() const
|
||||
{ return std::auto_ptr<alert>(new piece_finished_alert(*this)); }
|
||||
};
|
||||
|
||||
struct TORRENT_EXPORT block_finished_alert: torrent_alert
|
||||
{
|
||||
block_finished_alert(
|
||||
const torrent_handle& h
|
||||
, int block_num
|
||||
, int piece_num
|
||||
, const std::string& msg)
|
||||
: torrent_alert(h, alert::warning, msg)
|
||||
, block_index(block_num)
|
||||
, piece_index(piece_num)
|
||||
{ assert(block_index >= 0 && piece_index >= 0);}
|
||||
|
||||
int block_index;
|
||||
int piece_index;
|
||||
|
||||
virtual std::auto_ptr<alert> clone() const
|
||||
{ return std::auto_ptr<alert>(new block_finished_alert(*this)); }
|
||||
};
|
||||
|
||||
struct TORRENT_EXPORT block_downloading_alert: torrent_alert
|
||||
{
|
||||
block_downloading_alert(
|
||||
const torrent_handle& h
|
||||
, std::string& speedmsg
|
||||
, int block_num
|
||||
, int piece_num
|
||||
, const std::string& msg)
|
||||
: torrent_alert(h, alert::warning, msg)
|
||||
, peer_speedmsg(speedmsg)
|
||||
, block_index(block_num)
|
||||
, piece_index(piece_num)
|
||||
{ assert(block_index >= 0 && piece_index >= 0);}
|
||||
|
||||
std::string peer_speedmsg;
|
||||
int block_index;
|
||||
int piece_index;
|
||||
|
||||
virtual std::auto_ptr<alert> clone() const
|
||||
{ return std::auto_ptr<alert>(new block_downloading_alert(*this)); }
|
||||
};
|
||||
|
||||
struct TORRENT_EXPORT storage_moved_alert: torrent_alert
|
||||
{
|
||||
storage_moved_alert(torrent_handle const& h, std::string const& path)
|
||||
|
|
|
@ -241,6 +241,12 @@ namespace libtorrent
|
|||
enum { max_blocks_per_piece = 256 };
|
||||
int piece_index;
|
||||
int blocks_in_piece;
|
||||
// the number of blocks in the finished state
|
||||
int finished;
|
||||
// the number of blocks in the writing state
|
||||
int writing;
|
||||
// the number of blocks in the requested state
|
||||
int requested;
|
||||
block_info blocks[max_blocks_per_piece];
|
||||
enum state_t { none, slow, medium, fast };
|
||||
state_t piece_state;
|
||||
|
|
|
@ -1183,6 +1183,11 @@ namespace libtorrent
|
|||
assert(p.start == j.offset);
|
||||
piece_block block_finished(p.piece, p.start / t->block_size());
|
||||
picker.mark_as_finished(block_finished, peer_info_struct());
|
||||
if (t->alerts().should_post(alert::info))
|
||||
{
|
||||
t->alerts().post_alert(block_finished_alert(t->get_handle(),
|
||||
block_finished.block_index, block_finished.piece_index, "block finished"));
|
||||
}
|
||||
|
||||
if (!has_peer_choked() && !t->is_seed() && !m_torrent.expired())
|
||||
{
|
||||
|
@ -1290,11 +1295,29 @@ namespace libtorrent
|
|||
|
||||
piece_picker::piece_state_t state;
|
||||
peer_speed_t speed = peer_speed();
|
||||
if (speed == fast) state = piece_picker::fast;
|
||||
else if (speed == medium) state = piece_picker::medium;
|
||||
else state = piece_picker::slow;
|
||||
std::string speedmsg;
|
||||
if (speed == fast)
|
||||
{
|
||||
speedmsg = "fast";
|
||||
state = piece_picker::fast;
|
||||
}
|
||||
else if (speed == medium)
|
||||
{
|
||||
speedmsg = "medium";
|
||||
state = piece_picker::medium;
|
||||
}
|
||||
else
|
||||
{
|
||||
speedmsg = "slow";
|
||||
state = piece_picker::slow;
|
||||
}
|
||||
|
||||
t->picker().mark_as_downloading(block, peer_info_struct(), state);
|
||||
if (t->alerts().should_post(alert::info))
|
||||
{
|
||||
t->alerts().post_alert(block_downloading_alert(t->get_handle(),
|
||||
speedmsg, block.block_index, block.piece_index, "block downloading"));
|
||||
}
|
||||
|
||||
m_request_queue.push_back(block);
|
||||
}
|
||||
|
|
|
@ -831,6 +831,11 @@ namespace libtorrent
|
|||
|
||||
if (passed_hash_check)
|
||||
{
|
||||
if (m_ses.m_alerts.should_post(alert::info))
|
||||
{
|
||||
m_ses.m_alerts.post_alert(piece_finished_alert(get_handle()
|
||||
, index, "piece finished"));
|
||||
}
|
||||
// the following call may cause picker to become invalid
|
||||
// in case we just became a seed
|
||||
announce_piece(index);
|
||||
|
|
|
@ -773,6 +773,9 @@ namespace libtorrent
|
|||
partial_piece_info pi;
|
||||
pi.piece_state = (partial_piece_info::state_t)i->state;
|
||||
pi.blocks_in_piece = p.blocks_in_piece(i->index);
|
||||
pi.finished = (int)i->finished;
|
||||
pi.writing = (int)i->writing;
|
||||
pi.requested = (int)i->requested;
|
||||
int piece_size = t->torrent_file().piece_size(i->index);
|
||||
for (int j = 0; j < pi.blocks_in_piece; ++j)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,98 @@
|
|||
# Copyright (C) 2007 - Micah Bucy <eternalsword@gmail.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
### Initialization ###
|
||||
|
||||
plugin_name = _("Torrent Pieces")
|
||||
plugin_author = "Micah Bucy"
|
||||
plugin_version = "0.1"
|
||||
plugin_description = _("""
|
||||
Adds a pieces tab which gives piece by piece progress for a torrent.
|
||||
Each piece is represented by a small progress bar.
|
||||
|
||||
Pieces currently downloading show up as partially filled progress bars,
|
||||
but this does not represent percentage done.
|
||||
|
||||
More information is provided as a tooltip for each piece.
|
||||
For currently downloading pieces, the tooltip contains the number
|
||||
of blocks finished as well as the peer speed for that piece.
|
||||
|
||||
When the plugin initializes, such as when enabling the plugin or
|
||||
when a different torrent is selected, the cpu will spike. This is normal,
|
||||
as initialization must get information on every piece from libtorrent,
|
||||
and the cpu will normalize once all of the information is retrieved.""")
|
||||
|
||||
def deluge_init(deluge_path):
|
||||
global path
|
||||
path = deluge_path
|
||||
|
||||
def enable(core, interface):
|
||||
global path
|
||||
return TorrentPieces(path, core, interface)
|
||||
|
||||
### The Plugin ###
|
||||
import deluge
|
||||
import gtk
|
||||
from TorrentPieces.tab_pieces import PiecesManager
|
||||
|
||||
class TorrentPieces:
|
||||
|
||||
def __init__(self, path, core, interface):
|
||||
print "Loading TorrentPieces plugin..."
|
||||
self.manager = core
|
||||
self.parent = interface
|
||||
self.table = gtk.Table()
|
||||
self.viewport = gtk.Viewport()
|
||||
self.viewport.add(self.table)
|
||||
self.scrolledWindow = gtk.ScrolledWindow()
|
||||
self.scrolledWindow.add(self.viewport)
|
||||
self.scrolledWindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
|
||||
|
||||
self.topWidget = self.scrolledWindow
|
||||
|
||||
self.parentNotebook = self.parent.notebook
|
||||
|
||||
self.parentNotebook.append_page(self.topWidget, gtk.Label(_("Pieces")))
|
||||
self.viewport.show()
|
||||
self.scrolledWindow.show()
|
||||
self.table.show()
|
||||
self.tab_pieces = PiecesManager(self.table, self.manager)
|
||||
|
||||
def unload(self):
|
||||
self.manager.disconnect_event(self.manager.constants['EVENT_PIECE_FINISHED'], self.tab_pieces.handle_event)
|
||||
self.manager.disconnect_event(self.manager.constants['EVENT_BLOCK_FINISHED'], self.tab_pieces.handle_event)
|
||||
self.manager.disconnect_event(self.manager.constants['EVENT_BLOCK_DOWNLOADING'], self.tab_pieces.handle_event)
|
||||
numPages = self.parentNotebook.get_n_pages()
|
||||
for page in xrange(numPages):
|
||||
if self.parentNotebook.get_nth_page(page) == self.topWidget:
|
||||
self.parentNotebook.remove_page(page)
|
||||
break
|
||||
|
||||
def update(self):
|
||||
unique_id = self.parent.get_selected_torrent()
|
||||
# If no torrents added or more than one torrent selected
|
||||
if unique_id is None:
|
||||
return
|
||||
if unique_id != self.tab_pieces.unique_id:
|
||||
self.manager.disconnect_event(self.manager.constants['EVENT_PIECE_FINISHED'], self.tab_pieces.handle_event)
|
||||
self.manager.disconnect_event(self.manager.constants['EVENT_BLOCK_FINISHED'], self.tab_pieces.handle_event)
|
||||
self.manager.disconnect_event(self.manager.constants['EVENT_BLOCK_DOWNLOADING'], self.tab_pieces.handle_event)
|
||||
self.tab_pieces.clear_pieces_store()
|
||||
self.tab_pieces.set_unique_id(unique_id)
|
||||
self.tab_pieces.prepare_pieces_store()
|
||||
self.manager.connect_event(self.manager.constants['EVENT_PIECE_FINISHED'], self.tab_pieces.handle_event)
|
||||
self.manager.connect_event(self.manager.constants['EVENT_BLOCK_FINISHED'], self.tab_pieces.handle_event)
|
||||
self.manager.connect_event(self.manager.constants['EVENT_BLOCK_DOWNLOADING'], self.tab_pieces.handle_event)
|
|
@ -0,0 +1,115 @@
|
|||
import gtk
|
||||
|
||||
import math
|
||||
|
||||
class PiecesManager(object):
|
||||
def __init__(self, table, manager):
|
||||
self.table = table
|
||||
self.manager = manager
|
||||
self.progress = []
|
||||
self.tooltips = []
|
||||
self.eventboxes = []
|
||||
self.rows = 0
|
||||
self.columns = 33
|
||||
self.piece_width = 30
|
||||
self.piece_height = 20
|
||||
self.unique_id = -1
|
||||
self.peer_speed = []
|
||||
self.piece_info = []
|
||||
|
||||
def set_unique_id(self, unique_id):
|
||||
self.unique_id = unique_id
|
||||
|
||||
def clear_pieces_store(self):
|
||||
self.unique_id = -1
|
||||
self.rows = 0
|
||||
for widget in self.eventboxes:
|
||||
widget.destroy()
|
||||
for widget in self.progress:
|
||||
widget.hide()
|
||||
widget.destroy()
|
||||
self.peer_speed = []
|
||||
self.eventboxes = []
|
||||
self.progress = []
|
||||
self.piece_info = []
|
||||
self.tooltips = []
|
||||
|
||||
def prepare_pieces_store(self):
|
||||
state = self.manager.get_torrent_state(self.unique_id)
|
||||
num_pieces = state["num_pieces"]
|
||||
self.rows = int(math.ceil(num_pieces/self.columns))
|
||||
self.table.resize(self.rows, self.columns)
|
||||
self.table.set_size_request((self.columns+1)*self.piece_width, (self.rows+1)*self.piece_height)
|
||||
for index in xrange(num_pieces):
|
||||
self.piece_info.append({'blocks_total':0, 'blocks_finished':0, 'blocks_requested':0})
|
||||
self.progress.append(gtk.ProgressBar())
|
||||
self.tooltips.append(gtk.Tooltips())
|
||||
self.eventboxes.append(gtk.EventBox())
|
||||
self.peer_speed.append("unknown")
|
||||
self.progress[index].set_size_request(self.piece_width, self.piece_height)
|
||||
row = index/self.columns
|
||||
column = index%self.columns
|
||||
self.table.attach(self.eventboxes[index], column, column+1, row, row+1,
|
||||
xoptions=0, yoptions=0, xpadding=0, ypadding=0)
|
||||
self.eventboxes[index].add(self.progress[index])
|
||||
if self.manager.has_piece(self.unique_id, index):
|
||||
self.progress[index].set_fraction(1)
|
||||
self.tooltips[index].set_tip(self.eventboxes[index], _("Piece finished"))
|
||||
else:
|
||||
self.tooltips[index].set_tip(self.eventboxes[index], _("Piece not started"))
|
||||
self.eventboxes[index].show_all()
|
||||
all_piece_info = self.manager.get_all_piece_info(self.unique_id)
|
||||
for piece_index in all_piece_info:
|
||||
temp_piece_info = {'blocks_total':piece_index['blocks_total'], \
|
||||
'blocks_finished':piece_index['blocks_finished']}
|
||||
self.piece_info[piece_index['piece_index']] = temp_piece_info
|
||||
blocks_total = str(temp_piece_info['blocks_total'])
|
||||
info_string = str(temp_piece_info['blocks_finished']) + "/" + blocks_total + " " + _("blocks finished") + "\n" \
|
||||
+ _("peer speed: unknown")
|
||||
if self.progress[index].get_fraction() == 0:
|
||||
self.progress[index].set_fraction(0.5)
|
||||
self.tooltips[index].set_tip(self.eventboxes[index], info_string)
|
||||
|
||||
def handle_event(self, event):
|
||||
if event['event_type'] is self.manager.constants['EVENT_PIECE_FINISHED']:
|
||||
if event['unique_ID'] == self.unique_id:
|
||||
self.update_pieces_store(event['piece_index'], piece_finished=True)
|
||||
elif event['event_type'] is self.manager.constants['EVENT_BLOCK_DOWNLOADING']:
|
||||
if event['unique_ID'] == self.unique_id:
|
||||
index = event['piece_index']
|
||||
if self.piece_info[index]['blocks_total'] == 0:
|
||||
self.piece_info[index] = self.manager.get_piece_info(self.unique_id, index)
|
||||
temp_peer_speed = event['peer_speed']
|
||||
if temp_peer_speed == "fast":
|
||||
peer_speed_msg = _("fast")
|
||||
elif temp_peer_speed == "slow":
|
||||
peer_speed_msg = _("slow")
|
||||
elif temp_peer_speed == "medium":
|
||||
peer_speed_msg = _("medium")
|
||||
else:
|
||||
peer_speed_msg = _("unknown")
|
||||
self.peer_speed[index] = peer_speed_msg
|
||||
self.update_pieces_store(index)
|
||||
else:
|
||||
if event['unique_ID'] == self.unique_id:
|
||||
index = event['piece_index']
|
||||
if self.piece_info[index]['blocks_total'] == 0:
|
||||
self.piece_info[index] = self.manager.get_piece_info(self.unique_id, index)
|
||||
else:
|
||||
self.piece_info[index]['blocks_finished'] += 1
|
||||
self.update_pieces_store(event['piece_index'])
|
||||
|
||||
def update_pieces_store(self, index, piece_finished=False):
|
||||
if piece_finished:
|
||||
self.progress[index].set_fraction(1)
|
||||
self.tooltips[index].set_tip(self.eventboxes[index], _("Piece finished"))
|
||||
else:
|
||||
temp_fraction = self.progress[index].get_fraction()
|
||||
if temp_fraction == 0:
|
||||
self.progress[index].set_fraction(0.5)
|
||||
if temp_fraction != 1:
|
||||
temp_piece_info = self.piece_info[index]
|
||||
blocks_total = str(temp_piece_info['blocks_total'])
|
||||
info_string = str(temp_piece_info['blocks_finished']) + "/" + blocks_total + " " + _("blocks finished") + "\n" \
|
||||
+ _("peer speed: ") + self.peer_speed[index]
|
||||
self.tooltips[index].set_tip(self.eventboxes[index], info_string)
|
|
@ -30,3 +30,5 @@ plugins/BlocklistImport/ui.py
|
|||
plugins/BlocklistImport/text.py
|
||||
plugins/BlocklistImport/test.py
|
||||
plugins/BlocklistImport/peerguardian.py
|
||||
plugins/TorrentPieces/__init__.py
|
||||
plugins/TorrentPieces/tab_pieces.py
|
||||
|
|
|
@ -1377,3 +1377,68 @@ msgstr ""
|
|||
#: plugins/BlocklistImport/peerguardian.py:37
|
||||
msgid "Invalid version"
|
||||
msgstr ""
|
||||
|
||||
#: plugins/TorrentPieces/__init__.py:22
|
||||
msgid "Torrent Pieces"
|
||||
msgstr ""
|
||||
|
||||
#: plugins/TorrentPieces/__init__.py:22
|
||||
msgid ""
|
||||
"\n"
|
||||
"Adds a pieces tab which gives piece by piece progress for a torrent.\n"
|
||||
"Each piece is represented by a small progress bar.\n"
|
||||
"\n"
|
||||
"Pieces currently downloading show up as partially filled progress bars,\n"
|
||||
"but this does not represent percentage done.\n"
|
||||
"\n"
|
||||
"More information is provided as a tooltip for each piece.\n"
|
||||
"For currently downloading pieces, the tooltip contains the number\n"
|
||||
"of blocks finished as well as the peer speed for that piece.\n"
|
||||
"\n"
|
||||
"When the plugin initializes, such as when enabling the plugin or\n"
|
||||
"when a different torrent is selected, the cpu will spike. This is normal,\n"
|
||||
"as initialization must get information on every piece from libtorrent,\n"
|
||||
"and the cpu will normalize once all of the information is retrieved.\n"
|
||||
msgstr ""
|
||||
|
||||
#: plugins/TorrentPieces/__init__.py:68
|
||||
msgid "Pieces"
|
||||
msgstr ""
|
||||
|
||||
#: plugins/TorrentPieces/tab_pieces.py:57
|
||||
#: plugins/TorrentPieces/tab_pieces.py:105
|
||||
msgid "Piece finished"
|
||||
msgstr ""
|
||||
|
||||
#: plugins/TorrentPieces/tab_pieces.py:59
|
||||
msgid "Piece not started"
|
||||
msgstr ""
|
||||
|
||||
#: plugins/TorrentPieces/tab_pieces.py:67
|
||||
#: plugins/TorrentPieces/tab_pieces.py:113
|
||||
msgid "blocks finished"
|
||||
msgstr ""
|
||||
|
||||
#: plugins/TorrentPieces/tab_pieces.py:68
|
||||
msgid "peer speed: unknown"
|
||||
msgstr ""
|
||||
|
||||
#: plugins/TorrentPieces/tab_pieces.py:84
|
||||
msgid "fast"
|
||||
msgstr ""
|
||||
|
||||
#: plugins/TorrentPieces/tab_pieces.py:86
|
||||
msgid "slow"
|
||||
msgstr ""
|
||||
|
||||
#: plugins/TorrentPieces/tab_pieces.py:88
|
||||
msgid "medium"
|
||||
msgstr ""
|
||||
|
||||
#: plugins/TorrentPieces/tab_pieces.py:90
|
||||
msgid "unknown"
|
||||
msgstr ""
|
||||
|
||||
#: plugins/TorrentPieces/tab_pieces.py:114
|
||||
msgid "peer speed: "
|
||||
msgstr ""
|
||||
|
|
15
src/core.py
15
src/core.py
|
@ -317,7 +317,11 @@ class Manager:
|
|||
def get_pref(self, key):
|
||||
# Get the value from the preferences object
|
||||
return self.config.get(key)
|
||||
|
||||
|
||||
# Check if piece is finished
|
||||
def has_piece(self, unique_id, piece_index):
|
||||
return deluge_core.has_piece(unique_id, piece_index)
|
||||
|
||||
# Dump torrent info without adding
|
||||
def dump_torrent_file_info(self, torrent):
|
||||
return deluge_core.dump_file_info(torrent)
|
||||
|
@ -437,6 +441,12 @@ class Manager:
|
|||
def get_torrent_file_info(self, unique_ID):
|
||||
return self.get_core_torrent_file_info(unique_ID)
|
||||
|
||||
def get_piece_info(self, unique_ID, piece_index):
|
||||
return deluge_core.get_piece_info(unique_ID, piece_index)
|
||||
|
||||
def get_all_piece_info(self, unique_ID):
|
||||
return deluge_core.get_all_piece_info(unique_ID)
|
||||
|
||||
# Queueing functions
|
||||
|
||||
def queue_top(self, unique_ID, enforce_queue=True):
|
||||
|
@ -571,8 +581,7 @@ class Manager:
|
|||
if 'unique_ID' in event and \
|
||||
event['unique_ID'] not in self.unique_IDs:
|
||||
continue
|
||||
|
||||
# Call plugins events callbacks
|
||||
|
||||
if event['event_type'] in self.event_callbacks:
|
||||
for callback in self.event_callbacks[event['event_type']]:
|
||||
callback(event)
|
||||
|
|
|
@ -83,7 +83,9 @@ using namespace libtorrent;
|
|||
#define EVENT_TRACKER_WARNING 12
|
||||
#define EVENT_OTHER 13
|
||||
#define EVENT_STORAGE_MOVED 14
|
||||
|
||||
#define EVENT_PIECE_FINISHED 15
|
||||
#define EVENT_BLOCK_DOWNLOADING 16
|
||||
#define EVENT_BLOCK_FINISHED 17
|
||||
|
||||
#define STATE_QUEUED 0
|
||||
#define STATE_CHECKING 1
|
||||
|
@ -181,6 +183,17 @@ long get_index_from_unique_ID(long unique_ID)
|
|||
RAISE_INT(DelugeError, "No such unique_ID.");
|
||||
}
|
||||
|
||||
partial_piece_info internal_get_piece_info(torrent_handle h, long piece_index)
|
||||
{
|
||||
std::vector<partial_piece_info> queue;
|
||||
std::vector<partial_piece_info>& q = queue;
|
||||
h.get_download_queue(q);
|
||||
for (unsigned long i = 0; i < q.size(); i++)
|
||||
{
|
||||
if ((long)q[i].piece_index == piece_index) return queue[i];
|
||||
}
|
||||
}
|
||||
|
||||
torrent_info internal_get_torrent_info(std::string const& torrent_name)
|
||||
{
|
||||
std::ifstream in(torrent_name.c_str(), std::ios_base::binary);
|
||||
|
@ -264,6 +277,10 @@ long get_peer_index(tcp::endpoint addr, std::vector<peer_info> const& peers)
|
|||
return index;
|
||||
}
|
||||
|
||||
bool internal_has_piece(std::vector<bool> const& pieces, long index)
|
||||
{
|
||||
return pieces[index];
|
||||
}
|
||||
|
||||
// The following function contains code by Christophe Dumez and Arvid Norberg
|
||||
void internal_add_files(torrent_info& t,
|
||||
|
@ -359,29 +376,32 @@ static PyObject *torrent_init(PyObject *self, PyObject *args)
|
|||
|
||||
M_ses->add_extension(&libtorrent::create_metadata_plugin);
|
||||
|
||||
M_constants = Py_BuildValue("{s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i}",
|
||||
"EVENT_NULL", EVENT_NULL,
|
||||
"EVENT_FINISHED", EVENT_FINISHED,
|
||||
"EVENT_PEER_ERROR", EVENT_PEER_ERROR,
|
||||
"EVENT_INVALID_REQUEST", EVENT_INVALID_REQUEST,
|
||||
"EVENT_FILE_ERROR", EVENT_FILE_ERROR,
|
||||
"EVENT_HASH_FAILED_ERROR", EVENT_HASH_FAILED_ERROR,
|
||||
"EVENT_PEER_BAN_ERROR", EVENT_PEER_BAN_ERROR,
|
||||
"EVENT_FASTRESUME_REJECTED_ERROR", EVENT_FASTRESUME_REJECTED_ERROR,
|
||||
"EVENT_TRACKER_ANNOUNCE", EVENT_TRACKER_ANNOUNCE,
|
||||
"EVENT_TRACKER_REPLY", EVENT_TRACKER_REPLY,
|
||||
"EVENT_TRACKER_ALERT", EVENT_TRACKER_ALERT,
|
||||
"EVENT_TRACKER_WARNING", EVENT_TRACKER_WARNING,
|
||||
"EVENT_OTHER", EVENT_OTHER,
|
||||
"EVENT_STORAGE_MOVED", EVENT_STORAGE_MOVED,
|
||||
"STATE_QUEUED", STATE_QUEUED,
|
||||
"STATE_CHECKING", STATE_CHECKING,
|
||||
"STATE_CONNECTING", STATE_CONNECTING,
|
||||
"STATE_DOWNLOADING_META", STATE_DOWNLOADING_META,
|
||||
"STATE_DOWNLOADING", STATE_DOWNLOADING,
|
||||
"STATE_FINISHED", STATE_FINISHED,
|
||||
"STATE_SEEDING", STATE_SEEDING,
|
||||
"STATE_ALLOCATING", STATE_ALLOCATING);
|
||||
M_constants = Py_BuildValue("{s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i}",
|
||||
"EVENT_NULL", EVENT_NULL,
|
||||
"EVENT_FINISHED", EVENT_FINISHED,
|
||||
"EVENT_PEER_ERROR", EVENT_PEER_ERROR,
|
||||
"EVENT_INVALID_REQUEST", EVENT_INVALID_REQUEST,
|
||||
"EVENT_FILE_ERROR", EVENT_FILE_ERROR,
|
||||
"EVENT_HASH_FAILED_ERROR", EVENT_HASH_FAILED_ERROR,
|
||||
"EVENT_PEER_BAN_ERROR", EVENT_PEER_BAN_ERROR,
|
||||
"EVENT_FASTRESUME_REJECTED_ERROR", EVENT_FASTRESUME_REJECTED_ERROR,
|
||||
"EVENT_TRACKER_ANNOUNCE", EVENT_TRACKER_ANNOUNCE,
|
||||
"EVENT_TRACKER_REPLY", EVENT_TRACKER_REPLY,
|
||||
"EVENT_TRACKER_ALERT", EVENT_TRACKER_ALERT,
|
||||
"EVENT_TRACKER_WARNING", EVENT_TRACKER_WARNING,
|
||||
"EVENT_OTHER", EVENT_OTHER,
|
||||
"EVENT_STORAGE_MOVED", EVENT_STORAGE_MOVED,
|
||||
"EVENT_PIECE_FINISHED", EVENT_PIECE_FINISHED,
|
||||
"EVENT_BLOCK_DOWNLOADING", EVENT_BLOCK_DOWNLOADING,
|
||||
"EVENT_BLOCK_FINISHED", EVENT_BLOCK_FINISHED,
|
||||
"STATE_QUEUED", STATE_QUEUED,
|
||||
"STATE_CHECKING", STATE_CHECKING,
|
||||
"STATE_CONNECTING", STATE_CONNECTING,
|
||||
"STATE_DOWNLOADING_META", STATE_DOWNLOADING_META,
|
||||
"STATE_DOWNLOADING", STATE_DOWNLOADING,
|
||||
"STATE_FINISHED", STATE_FINISHED,
|
||||
"STATE_SEEDING", STATE_SEEDING,
|
||||
"STATE_ALLOCATING", STATE_ALLOCATING);
|
||||
|
||||
Py_INCREF(Py_None); return Py_None;
|
||||
};
|
||||
|
@ -733,6 +753,77 @@ static PyObject *torrent_resume(PyObject *self, PyObject *args)
|
|||
Py_INCREF(Py_None); return Py_None;
|
||||
}
|
||||
|
||||
static PyObject *torrent_has_piece(PyObject *self, PyObject *args)
|
||||
{
|
||||
python_long unique_ID;
|
||||
long piece_index;
|
||||
bool has_piece;
|
||||
if (!PyArg_ParseTuple(args, "ii", &unique_ID, &piece_index))
|
||||
return NULL;
|
||||
|
||||
long index = get_index_from_unique_ID(unique_ID);
|
||||
if (PyErr_Occurred())
|
||||
return NULL;
|
||||
|
||||
torrent_status s = M_torrents->at(index).handle.status();
|
||||
has_piece = internal_has_piece(*s.pieces, piece_index);
|
||||
return Py_BuildValue("b", has_piece);
|
||||
}
|
||||
|
||||
static PyObject *torrent_get_all_piece_info(PyObject *self, PyObject *args)
|
||||
{
|
||||
python_long unique_ID;
|
||||
if (!PyArg_ParseTuple(args, "i", &unique_ID))
|
||||
return NULL;
|
||||
|
||||
long index = get_index_from_unique_ID(unique_ID);
|
||||
if (PyErr_Occurred())
|
||||
return NULL;
|
||||
|
||||
torrent_handle h = M_torrents->at(index).handle;
|
||||
std::vector<partial_piece_info> queue;
|
||||
std::vector<partial_piece_info>& q = queue;
|
||||
h.get_download_queue(q);
|
||||
PyObject *piece_info;
|
||||
long piece_index = 0;
|
||||
PyObject *ret = PyTuple_New(q.size());
|
||||
|
||||
for(unsigned long i=0; i<q.size(); i++)
|
||||
{
|
||||
piece_info = Py_BuildValue("{s:i,s:i,s:i}",
|
||||
"piece_index", q[i].piece_index,
|
||||
"blocks_total", q[i].blocks_in_piece,
|
||||
"blocks_finished", q[i].finished);
|
||||
|
||||
PyTuple_SetItem(ret, piece_index, piece_info);
|
||||
piece_index++;
|
||||
};
|
||||
return ret;
|
||||
}
|
||||
|
||||
static PyObject *torrent_get_piece_info(PyObject *self, PyObject *args)
|
||||
{
|
||||
python_long unique_ID;
|
||||
long piece_index;
|
||||
if (!PyArg_ParseTuple(args, "ii", &unique_ID, &piece_index))
|
||||
return NULL;
|
||||
|
||||
long index = get_index_from_unique_ID(unique_ID);
|
||||
if (PyErr_Occurred())
|
||||
return NULL;
|
||||
|
||||
torrent_handle h = M_torrents->at(index).handle;
|
||||
partial_piece_info piece_info = internal_get_piece_info(h, piece_index);
|
||||
int blocks_total=0, blocks_finished=0;
|
||||
if(piece_info.piece_index == piece_index)
|
||||
{
|
||||
blocks_total = piece_info.blocks_in_piece;
|
||||
blocks_finished = piece_info.finished;
|
||||
}
|
||||
return Py_BuildValue("{s:i,s:i}",
|
||||
"blocks_total", blocks_total,
|
||||
"blocks_finished", blocks_finished);
|
||||
}
|
||||
|
||||
static PyObject *torrent_get_torrent_state(PyObject *self, PyObject *args)
|
||||
{
|
||||
|
@ -810,6 +901,60 @@ static PyObject *torrent_pop_event(PyObject *self, PyObject *args)
|
|||
if (!popped_alert)
|
||||
{
|
||||
Py_INCREF(Py_None); return Py_None;
|
||||
} else if (dynamic_cast<block_downloading_alert*>(popped_alert))
|
||||
{
|
||||
torrent_handle handle = (dynamic_cast<block_downloading_alert*>(popped_alert))->handle;
|
||||
int piece_index = (dynamic_cast<block_downloading_alert*>(popped_alert))->piece_index;
|
||||
int block_index = (dynamic_cast<block_downloading_alert*>(popped_alert))->block_index;
|
||||
std::string speedmsg = (dynamic_cast<block_downloading_alert*>(popped_alert))->peer_speedmsg;
|
||||
long index = get_torrent_index(handle);
|
||||
if (PyErr_Occurred())
|
||||
return NULL;
|
||||
|
||||
if (handle_exists(handle))
|
||||
return Py_BuildValue("{s:i,s:i,s:i,s:i,s:s,s:s}",
|
||||
"event_type", EVENT_BLOCK_DOWNLOADING,
|
||||
"unique_ID", M_torrents->at(index).unique_ID,
|
||||
"block_index", block_index,
|
||||
"piece_index", piece_index,
|
||||
"peer_speed", speedmsg.c_str(),
|
||||
"message", a->msg().c_str());
|
||||
else
|
||||
{ Py_INCREF(Py_None); return Py_None; }
|
||||
} else if (dynamic_cast<block_finished_alert*>(popped_alert))
|
||||
{
|
||||
torrent_handle handle = (dynamic_cast<block_finished_alert*>(popped_alert))->handle;
|
||||
int piece_index = (dynamic_cast<block_finished_alert*>(popped_alert))->piece_index;
|
||||
int block_index = (dynamic_cast<block_finished_alert*>(popped_alert))->block_index;
|
||||
long index = get_torrent_index(handle);
|
||||
if (PyErr_Occurred())
|
||||
return NULL;
|
||||
|
||||
if (handle_exists(handle))
|
||||
return Py_BuildValue("{s:i,s:i,s:i,s:i,s:s}",
|
||||
"event_type", EVENT_BLOCK_FINISHED,
|
||||
"unique_ID", M_torrents->at(index).unique_ID,
|
||||
"block_index", block_index,
|
||||
"piece_index", piece_index,
|
||||
"message", a->msg().c_str());
|
||||
else
|
||||
{ Py_INCREF(Py_None); return Py_None; }
|
||||
} else if (dynamic_cast<piece_finished_alert*>(popped_alert))
|
||||
{
|
||||
torrent_handle handle = (dynamic_cast<piece_finished_alert*>(popped_alert))->handle;
|
||||
int piece_index = (dynamic_cast<piece_finished_alert*>(popped_alert))->piece_index;
|
||||
long index = get_torrent_index(handle);
|
||||
if (PyErr_Occurred())
|
||||
return NULL;
|
||||
|
||||
if (handle_exists(handle))
|
||||
return Py_BuildValue("{s:i,s:i,s:i,s:s}",
|
||||
"event_type", EVENT_PIECE_FINISHED,
|
||||
"unique_ID", M_torrents->at(index).unique_ID,
|
||||
"piece_index", piece_index,
|
||||
"message", a->msg().c_str());
|
||||
else
|
||||
{ Py_INCREF(Py_None); return Py_None; }
|
||||
} else if (dynamic_cast<torrent_finished_alert*>(popped_alert))
|
||||
{
|
||||
torrent_handle handle = (dynamic_cast<torrent_finished_alert*>(popped_alert))->handle;
|
||||
|
@ -1719,6 +1864,9 @@ static PyMethodDef deluge_core_methods[] =
|
|||
{"prioritize_first_last_pieces", torrent_prioritize_first_last_pieces, METH_VARARGS, "."},
|
||||
{"set_priv", torrent_set_priv, METH_VARARGS, "."},
|
||||
{"test_duplicate", torrent_test_duplicate, METH_VARARGS, "."},
|
||||
{"has_piece", torrent_has_piece, METH_VARARGS, "."},
|
||||
{"get_piece_info", torrent_get_piece_info, METH_VARARGS, "."},
|
||||
{"get_all_piece_info", torrent_get_all_piece_info, METH_VARARGS, "."},
|
||||
{NULL}
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue