diff --git a/glade/merge_dialog.glade b/glade/merge_dialog.glade
new file mode 100644
index 000000000..ed2b83270
--- /dev/null
+++ b/glade/merge_dialog.glade
@@ -0,0 +1,56 @@
+
+
+
+
+
+ 5
+ Deluge Merge Tracker Lists
+ GTK_WIN_POS_CENTER_ALWAYS
+ 200
+ 50
+ False
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK
+ 2
+
+
+ True
+ Torrent already detected in Deluge, would you like to merge the tracker lists?
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK
+ GTK_BUTTONBOX_END
+
+
+ True
+ gtk-cancel
+ True
+ 0
+
+
+
+
+ True
+ gtk-ok
+ True
+ 1
+
+
+ 1
+
+
+
+
+ False
+ GTK_PACK_END
+
+
+
+
+
+
diff --git a/src/core.py b/src/core.py
index dab1e0854..16c79ff6e 100644
--- a/src/core.py
+++ b/src/core.py
@@ -309,11 +309,19 @@ class Manager:
def dump_torrent_file_info(self, torrent):
return deluge_core.dump_file_info(torrent)
+ # Dump trackers from torrent file
+ def dump_trackers(self, torrent):
+ return deluge_core.dump_trackers(torrent)
+
# Torrent addition and removal functions
def add_torrent(self, filename, save_dir, compact):
self.add_torrent_ns(filename, save_dir, compact)
return self.sync() # Syncing will create a new torrent in the core, and return it's ID
+
+ # When duplicate torrent error, use to find duplicate when merging tracker lists
+ def test_duplicate(self, torrent, unique_id):
+ return deluge_core.test_duplicate(torrent, unique_id)
def remove_torrent(self, unique_ID, data_also, torrent_also):
temp = self.unique_IDs[unique_ID]
diff --git a/src/deluge_core.cpp b/src/deluge_core.cpp
index 401f2d05f..3d1f9a2c1 100644
--- a/src/deluge_core.cpp
+++ b/src/deluge_core.cpp
@@ -170,7 +170,6 @@ long get_torrent_index(torrent_handle &handle)
RAISE_INT(DelugeError, "Handle not found.");
}
-
long get_index_from_unique_ID(long unique_ID)
{
@@ -181,7 +180,7 @@ long get_index_from_unique_ID(long unique_ID)
RAISE_INT(DelugeError, "No such unique_ID.");
}
-torrent_info internal_dump_file_info(std::string const& torrent_name)
+torrent_info internal_get_torrent_info(std::string const& torrent_name)
{
std::ifstream in(torrent_name.c_str(), std::ios_base::binary);
in.unsetf(std::ios_base::skipws);
@@ -534,7 +533,7 @@ static PyObject *torrent_dump_file_info(PyObject *self, PyObject *args)
if (!PyArg_ParseTuple(args, "s", &name))
return NULL;
- torrent_info t = internal_dump_file_info(name);
+ torrent_info t = internal_get_torrent_info(name);
PyObject *file_info;
long file_index = 0;
@@ -557,6 +556,24 @@ static PyObject *torrent_dump_file_info(PyObject *self, PyObject *args)
return ret;
}
+static PyObject *torrent_dump_trackers(PyObject *self, PyObject *args)
+{
+ const char *name;
+ if (!PyArg_ParseTuple(args, "s", &name))
+ return NULL;
+
+ torrent_info t = internal_get_torrent_info(name);
+ std::string trackerslist;
+ {
+ for (std::vector::const_iterator i = t.trackers().begin();
+ i != t.trackers().end(); ++i)
+ {
+ trackerslist = trackerslist + i->url +"\n";
+ }
+ }
+ return Py_BuildValue("s",trackerslist.c_str());
+}
+
static PyObject *torrent_add_torrent(PyObject *self, PyObject *args)
{
const char *name, *save_dir;
@@ -583,6 +600,22 @@ static PyObject *torrent_add_torrent(PyObject *self, PyObject *args)
{ RAISE_PTR(DuplicateTorrentError, "libtorrent reports this is a duplicate torrent"); }
}
+static PyObject *torrent_test_duplicate(PyObject *self, PyObject *args)
+{
+ const char *name;
+ python_long unique_ID;
+ if (!PyArg_ParseTuple(args, "si", &name, &unique_ID))
+ return NULL;
+
+ long index = get_index_from_unique_ID(unique_ID);
+ if (PyErr_Occurred())
+ return NULL;
+
+ torrent_info t = internal_get_torrent_info(name);
+ return Py_BuildValue("b", t.info_hash() == M_torrents->at(index).handle.info_hash());
+
+}
+
static PyObject *torrent_move_storage(PyObject *self, PyObject *args)
{
const char *move_dir;
@@ -1511,49 +1544,51 @@ static PyObject *torrent_set_priv(PyObject *self, PyObject *args)
static PyMethodDef deluge_core_methods[] =
{
- {"pe_settings", torrent_pe_settings, METH_VARARGS, "."},
- {"pre_init", torrent_pre_init, METH_VARARGS, "."},
- {"init", torrent_init, METH_VARARGS, "."},
- {"quit", torrent_quit, METH_VARARGS, "."},
- {"save_fastresume", torrent_save_fastresume, METH_VARARGS, "."},
- {"set_max_half_open", torrent_set_max_half_open, METH_VARARGS, "."},
- {"set_download_rate_limit", torrent_set_download_rate_limit, METH_VARARGS, "."},
- {"set_upload_rate_limit", torrent_set_upload_rate_limit, METH_VARARGS, "."},
- {"set_listen_on", torrent_set_listen_on, METH_VARARGS, "."},
- {"is_listening", torrent_is_listening, METH_VARARGS, "."},
- {"listening_port", torrent_listening_port, METH_VARARGS, "."},
- {"set_max_uploads", torrent_set_max_uploads, METH_VARARGS, "."},
- {"set_max_connections", torrent_set_max_connections, METH_VARARGS, "."},
- {"add_torrent", torrent_add_torrent, METH_VARARGS, "."},
- {"move_storage", torrent_move_storage, METH_VARARGS, "."},
- {"remove_torrent", torrent_remove_torrent, METH_VARARGS, "."},
- {"get_num_torrents", torrent_get_num_torrents, METH_VARARGS, "."},
- {"reannounce", torrent_reannounce, METH_VARARGS, "."},
- {"pause", torrent_pause, METH_VARARGS, "."},
- {"resume", torrent_resume, METH_VARARGS, "."},
- {"get_torrent_state", torrent_get_torrent_state, METH_VARARGS, "."},
- {"pop_event", torrent_pop_event, METH_VARARGS, "."},
- {"get_session_info", torrent_get_session_info, METH_VARARGS, "."},
- {"get_peer_info", torrent_get_peer_info, METH_VARARGS, "."},
- {"get_file_info", torrent_get_file_info, METH_VARARGS, "."},
- {"dump_file_info", torrent_dump_file_info, METH_VARARGS, "."},
- {"constants", torrent_constants, METH_VARARGS, "."},
- {"start_DHT", torrent_start_DHT, METH_VARARGS, "."},
- {"stop_DHT", torrent_stop_DHT, METH_VARARGS, "."},
- {"get_DHT_info", torrent_get_DHT_info, METH_VARARGS, "."},
- {"create_torrent", torrent_create_torrent, METH_VARARGS, "."},
- {"reset_IP_filter", torrent_reset_IP_filter, METH_VARARGS, "."},
- {"add_range_to_IP_filter", torrent_add_range_to_IP_filter, METH_VARARGS, "."},
- {"use_upnp", torrent_use_upnp, METH_VARARGS, "."},
- {"use_natpmp", torrent_use_natpmp, METH_VARARGS, "."},
- {"use_utpex", torrent_use_utpex, METH_VARARGS, "."},
- {"set_ratio", torrent_set_ratio, METH_VARARGS, "."},
- {"proxy_settings", torrent_proxy_settings, METH_VARARGS, "."},
- {"get_trackers", torrent_get_trackers, METH_VARARGS, "."},
- {"replace_trackers", torrent_replace_trackers, METH_VARARGS, "."},
- {"set_flp", torrent_set_flp, METH_VARARGS, "."},
- {"prioritize_files", torrent_prioritize_files, METH_VARARGS, "."},
- {"set_priv", torrent_set_priv, METH_VARARGS, "."},
+ {"pe_settings", torrent_pe_settings, METH_VARARGS, "."},
+ {"pre_init", torrent_pre_init, METH_VARARGS, "."},
+ {"init", torrent_init, METH_VARARGS, "."},
+ {"quit", torrent_quit, METH_VARARGS, "."},
+ {"save_fastresume", torrent_save_fastresume, METH_VARARGS, "."},
+ {"set_max_half_open", torrent_set_max_half_open, METH_VARARGS, "."},
+ {"set_download_rate_limit", torrent_set_download_rate_limit, METH_VARARGS, "."},
+ {"set_upload_rate_limit", torrent_set_upload_rate_limit, METH_VARARGS, "."},
+ {"set_listen_on", torrent_set_listen_on, METH_VARARGS, "."},
+ {"is_listening", torrent_is_listening, METH_VARARGS, "."},
+ {"listening_port", torrent_listening_port, METH_VARARGS, "."},
+ {"set_max_uploads", torrent_set_max_uploads, METH_VARARGS, "."},
+ {"set_max_connections", torrent_set_max_connections, METH_VARARGS, "."},
+ {"add_torrent", torrent_add_torrent, METH_VARARGS, "."},
+ {"move_storage", torrent_move_storage, METH_VARARGS, "."},
+ {"remove_torrent", torrent_remove_torrent, METH_VARARGS, "."},
+ {"get_num_torrents", torrent_get_num_torrents, METH_VARARGS, "."},
+ {"reannounce", torrent_reannounce, METH_VARARGS, "."},
+ {"pause", torrent_pause, METH_VARARGS, "."},
+ {"resume", torrent_resume, METH_VARARGS, "."},
+ {"get_torrent_state", torrent_get_torrent_state, METH_VARARGS, "."},
+ {"pop_event", torrent_pop_event, METH_VARARGS, "."},
+ {"get_session_info", torrent_get_session_info, METH_VARARGS, "."},
+ {"get_peer_info", torrent_get_peer_info, METH_VARARGS, "."},
+ {"get_file_info", torrent_get_file_info, METH_VARARGS, "."},
+ {"dump_file_info", torrent_dump_file_info, METH_VARARGS, "."},
+ {"constants", torrent_constants, METH_VARARGS, "."},
+ {"start_DHT", torrent_start_DHT, METH_VARARGS, "."},
+ {"stop_DHT", torrent_stop_DHT, METH_VARARGS, "."},
+ {"get_DHT_info", torrent_get_DHT_info, METH_VARARGS, "."},
+ {"create_torrent", torrent_create_torrent, METH_VARARGS, "."},
+ {"reset_IP_filter", torrent_reset_IP_filter, METH_VARARGS, "."},
+ {"add_range_to_IP_filter", torrent_add_range_to_IP_filter, METH_VARARGS, "."},
+ {"use_upnp", torrent_use_upnp, METH_VARARGS, "."},
+ {"use_natpmp", torrent_use_natpmp, METH_VARARGS, "."},
+ {"use_utpex", torrent_use_utpex, METH_VARARGS, "."},
+ {"set_ratio", torrent_set_ratio, METH_VARARGS, "."},
+ {"proxy_settings", torrent_proxy_settings, METH_VARARGS, "."},
+ {"get_trackers", torrent_get_trackers, METH_VARARGS, "."},
+ {"dump_trackers", torrent_dump_trackers, METH_VARARGS, "."},
+ {"replace_trackers", torrent_replace_trackers, METH_VARARGS, "."},
+ {"set_flp", torrent_set_flp, METH_VARARGS, "."},
+ {"prioritize_files", torrent_prioritize_files, METH_VARARGS, "."},
+ {"set_priv", torrent_set_priv, METH_VARARGS, "."},
+ {"test_duplicate", torrent_test_duplicate, METH_VARARGS, "."},
{NULL}
};
diff --git a/src/dialogs.py b/src/dialogs.py
index aeaa71083..cec540b66 100644
--- a/src/dialogs.py
+++ b/src/dialogs.py
@@ -201,6 +201,20 @@ class PreferencesDlg:
elif widget == self.glade.get_widget('chk_lock_tray'):
self.glade.get_widget('txt_tray_passwd').set_sensitive(value)
+class MergeDlg:
+ def __init__(self):
+ self.glade = gtk.glade.XML(common.get_glade_file("merge_dialog.glade"),
+ domain='deluge')
+ self.dialog = self.glade.get_widget("merge_dialog")
+ self.dialog.set_icon_from_file(common.get_pixmap("deluge32.png"))
+
+ def show(self):
+ self.dialog.show()
+ r = self.dialog.run()
+ self.dialog.hide()
+
+ return r
+
class FilesDlg:
def __init__(self, dumped_torrent):
self.glade = gtk.glade.XML(common.get_glade_file("files_dialog.glade"),
diff --git a/src/interface.py b/src/interface.py
index 88187602d..7427c3acd 100644
--- a/src/interface.py
+++ b/src/interface.py
@@ -1108,7 +1108,23 @@ class DelugeGTK:
print "InvalidEncodingError", e
dialogs.show_popup_warning(self.window, _("An error occured while trying to add the torrent. It's possible your .torrent file is corrupted."))
except core.DuplicateTorrentError, e:
- dialogs.show_popup_warning(self.window, _("The torrent you've added seems to already be in Deluge."))
+ for unique_id in self.manager.unique_IDs:
+ is_duplicate = self.manager.test_duplicate(torrent, unique_id)
+ if is_duplicate:
+ break
+ if is_duplicate:
+ merge_dialog = dialogs.MergeDlg()
+ if merge_dialog.show() == 1:
+ new_trackers_as_list = self.manager.dump_trackers(torrent).replace(' ','').splitlines(True)
+ original_trackers_as_list = self.manager.get_trackers(unique_id).replace(' ','').splitlines(True)
+ for index in xrange(len(new_trackers_as_list)):
+ if original_trackers_as_list.count(new_trackers_as_list[index]) == 0:
+ original_trackers_as_list.append(new_trackers_as_list[index])
+ merged_trackers_as_string = ''.join([original_trackers_as_list[index] for \
+ index in xrange(len(original_trackers_as_list))])
+ self.manager.replace_trackers(unique_id, merged_trackers_as_string)
+ else:
+ dialogs.show_popup_warning(self.window, _("Unknown duplicate torrent error."))
except core.InsufficientFreeSpaceError, e:
nice_need = common.fsize(e.needed_space)
nice_free = common.fsize(e.free_space)