From 442cac8aef4adba474d4a9581360cef565c70bae Mon Sep 17 00:00:00 2001 From: Alex Dedul Date: Mon, 23 Jul 2007 23:29:37 +0000 Subject: [PATCH] Fixed #368 - Added ability to prioritize first and last pieces of files in torrent. --- glade/preferences_dialog.glade | 393 ++++++++++++++++++--------------- plugins/FirstLast/__init__.py | 120 ---------- src/common.py | 2 +- src/core.py | 34 +-- src/deluge_core.cpp | 186 ++++++++++++---- src/dialogs.py | 2 + src/files.py | 1 - src/pref.py | 1 + 8 files changed, 379 insertions(+), 360 deletions(-) delete mode 100644 plugins/FirstLast/__init__.py diff --git a/glade/preferences_dialog.glade b/glade/preferences_dialog.glade index 07a4ce847..fb6d3962b 100644 --- a/glade/preferences_dialog.glade +++ b/glade/preferences_dialog.glade @@ -55,6 +55,7 @@ True Ask where to save each download True + 0 True @@ -65,30 +66,16 @@ 2 2 - - True - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Store all downloads in: - Store all downloads in: - True - True - radio_ask_save - - - - - + True False - True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Move completed downloads to (*same partition only*): - Move completed downloads to: - True - + GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER + Select A Folder + 1 + 2 1 2 @@ -107,20 +94,36 @@ - + True False + True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER - Select A Folder + Move completed downloads to (*same partition only*): + Move completed downloads to: + 0 + True + - 1 - 2 1 2 + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Store all downloads in: + Store all downloads in: + 0 + True + True + radio_ask_save + + + 1 @@ -203,6 +206,7 @@ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK Enable selecting files for torrents before loading Enable selecting files for torrents before loading + 0 True @@ -210,6 +214,21 @@ 1 + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Prioritize first and last pieces of files in torrent + Prioritize first and last pieces of files in torrent + 0 + True + + + False + 2 + + @@ -249,6 +268,7 @@ Compact allocation will only allocate as much storage as it needs to keep the pieces downloaded so far. Use compact storage allocation True + 0 True @@ -292,6 +312,7 @@ True Queue torrents to bottom when they begin seeding True + 0 True @@ -303,6 +324,7 @@ True Queue new torrents above completed ones True + 0 True @@ -318,6 +340,7 @@ True Stop seeding torrents when their share ratio reaches: True + 0 True @@ -353,6 +376,7 @@ True Automatically clear torrents that reach the max share ratio True + 0 True @@ -399,42 +423,87 @@ 4 2 - + True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 10 - - - True - The maximum upload speed for all torrents. Set -1 for unlimited. - 0 - Maximum Upload Speed (KiB/s): - - + True + The maximum upload speed for all torrents. Set -1 for unlimited. + 1 + -1 -1 9000 1 10 10 + 1 + 1 + 2 3 4 GTK_FILL - + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + The maximum download speed for all torrents. Set -1 for unlimited. + 1 + -1 -1 9000 1 10 10 + 1 + + + 1 + 2 + 2 + 3 + GTK_FILL + + + + + True + True + The maximum number of upload slots. Set -1 for unlimited. + 1 + -1 -1 1000 1 10 10 + 1 + + + 1 + 2 + 1 + 2 + GTK_FILL + + + + + True + True + The maximum number of connections allowed. Set -1 for unlimited. + 1 + -1 -1 1000 1 10 10 + 1 + + + 1 + 2 + GTK_FILL + + + + True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 10 - + True - The maximum download speed for all torrents. Set -1 for unlimited. + The maximum number of connections allowed. Set -1 for unlimited. 0 - Maximum Download Speed (KiB/s): + Maximum Connections: - 2 - 3 GTK_FILL @@ -459,85 +528,40 @@ - + True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 10 - + True - The maximum number of connections allowed. Set -1 for unlimited. + The maximum download speed for all torrents. Set -1 for unlimited. 0 - Maximum Connections: + Maximum Download Speed (KiB/s): - GTK_FILL - - - - - True - True - The maximum number of connections allowed. Set -1 for unlimited. - 1 - -1 -1 1000 1 10 10 - 1 - - - 1 - 2 - GTK_FILL - - - - - True - True - The maximum number of upload slots. Set -1 for unlimited. - 1 - -1 -1 1000 1 10 10 - 1 - - - 1 - 2 - 1 - 2 - GTK_FILL - - - - - True - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - The maximum download speed for all torrents. Set -1 for unlimited. - 1 - -1 -1 9000 1 10 10 - 1 - - - 1 - 2 2 3 GTK_FILL - + True - True - The maximum upload speed for all torrents. Set -1 for unlimited. - 1 - -1 -1 9000 1 10 10 - 1 + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 10 + + + True + The maximum upload speed for all torrents. Set -1 for unlimited. + 0 + Maximum Upload Speed (KiB/s): + + - 1 - 2 3 4 GTK_FILL @@ -742,6 +766,7 @@ True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK Test Active Port + 0 @@ -797,6 +822,7 @@ Distributed hash table may improve the amount of active connections. Enable Mainline DHT True + 0 True @@ -848,6 +874,7 @@ Universal Plug and Play UPnP True + 0 True True @@ -862,6 +889,7 @@ NAT Port Mapping Protocol NAT-PMP True + 0 True True @@ -877,6 +905,7 @@ µTorrent Peer-Exchange µTorrent-PeX True + 0 True True @@ -984,6 +1013,7 @@ Forced True Prefer to encrypt the entire stream True + 0 True @@ -1059,6 +1089,7 @@ Full Stream GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK Affects regular bittorrent peers Peer Proxy + 0 True @@ -1070,6 +1101,7 @@ Full Stream GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK Only affects HTTP tracker connections (UDP tracker connections are affected if the given proxy supports UDP, e.g. SOCKS5). Tracker Proxy + 0 True @@ -1084,6 +1116,7 @@ Full Stream GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK Affects the DHT messages. Since they are sent over UDP, it only has any effect if the proxy supports UDP. DHT Proxy + 0 True @@ -1106,85 +1139,34 @@ Full Stream - + True - False - True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 8080 0 10000 1 10 10 + Proxy type + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Username - 3 - 4 1 2 - - True - False - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - - - 3 - 4 - - - - + True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Port + Password - 2 - 3 - 1 - 2 - - - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Server - - - 2 - 3 - - - - - True - False - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - False - - - 1 - 2 2 3 - - - True - False - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - - - 1 - 2 - 1 - 2 - - True @@ -1203,33 +1185,84 @@ HTTP W/ Auth - + True + False + True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Password - - - 2 - 3 - - - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Username + 1 + 2 1 2 - + + True + False + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + False + + + 1 + 2 + 2 + 3 + + + + True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Proxy type + Server + + 2 + 3 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Port + + + 2 + 3 + 1 + 2 + + + + + True + False + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + 3 + 4 + + + + + True + False + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 8080 0 10000 1 10 10 + + + 3 + 4 + 1 + 2 + @@ -1311,6 +1344,7 @@ HTTP W/ Auth True Enable system tray icon True + 0 True True @@ -1326,6 +1360,7 @@ HTTP W/ Auth False Minimize to tray on close True + 0 True @@ -1349,6 +1384,7 @@ HTTP W/ Auth True Password protect system tray True + 0 True @@ -1517,6 +1553,7 @@ HTTP W/ Auth True gtk-cancel True + 0 diff --git a/plugins/FirstLast/__init__.py b/plugins/FirstLast/__init__.py deleted file mode 100644 index ccdd9603d..000000000 --- a/plugins/FirstLast/__init__.py +++ /dev/null @@ -1,120 +0,0 @@ -# Copyright (C) 2007 - Marcos Pinto -# -# 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 = _("First/Last Priority") -plugin_author = "Marcos Pinto" -plugin_version = "0.1" -plugin_description = _("Set the highest priority to the first and last pieces.") - -def deluge_init(deluge_path): - global path - path = deluge_path - -def enable(core, interface): - global path - return FirstLast(path, core, interface) - -### The Plugin ### - -DEFAULT_PREFS = { - "flpriorities": [7] -} - -import deluge -import gtk, gtk.glade - -class FirstLast: - - def __init__(self, path, core, interface): - self.path = path - self.core = core - self.interface = interface - self.set_flpriorities = {} - self.callback_ids = [] - - # Setup preferences - self.config_file = deluge.common.CONFIG_DIR + "/firstlast_priorty.conf" - self.config = deluge.pref.Preferences(filename=deluge.common.CONFIG_DIR + "/firstlast_priority.conf", global_defaults=False, defaults=DEFAULT_PREFS) - try: - self.config.load(self.config_file) - except IOError: - # File does not exist - pass - print self.config.get - # Connect to events for the torrent menu so we know when to build and remove our sub-menu - self.callback_ids.append(self.interface.torrent_menu.connect_after("realize", self.torrent_menu_show)) - self.callback_ids.append(self.interface.torrent_menu.connect("show", self.torrent_menu_show)) - self.callback_ids.append(self.interface.torrent_menu.connect("hide", self.torrent_menu_hide)) - - def torrent_menu_show(self, widget, data=None): - # Get the selected torrent - self.unique_ID = self.interface.get_selected_torrent() - - # Make the sub-menu for the torrent menu - self.flp_menuitem = gtk.MenuItem(_("_First/Last Priority")) - - self.flp_menu = self.interface.build_menu_radio_list(self.config.get("flpriorities"), self.flp_clicked, self.get_torrent_flp(), None, True, _("_Not Set"), 1, None, True) - - self.flp_menuitem.set_submenu(self.flp_menu) - self.interface.torrent_menu.append(self.flp_menuitem) - - self.flp_menuitem.show_all() - - def torrent_menu_hide(self, widget): - try: - self.interface.torrent_menu.remove(self.flp_menuitem) - except AttributeError: - pass - - def update(self): - pass - - def unload(self): - self.config.save(self.config_file) - # Disconnect all callbacks - for callback_id in self.callback_ids: - self.interface.torrent_menu.disconnect(callback_id) - - self.callback_ids = [] - - # Reset all desired flpriorities in the core - for unique_ID, flp in self.set_flpriorities.items(): - if flp > 1: - self.core.set_flp(unique_ID, flp) - - self.set_flpriorities = {} - - def flp_clicked(self, widget): - value = widget.get_children()[0].get_text() - if value == _("Not Set"): - value = 1 - - if value == _("Activated"): - value = 7 - - value = int(value) # Make sure the value is an int - - # Set the flp in the core and remember the setting - self.core.set_flp(self.unique_ID, value) - self.set_flpriorities[self.unique_ID] = value - - def get_torrent_flp(self): - if self.set_flpriorities.has_key(self.unique_ID): - return self.set_flpriorities[self.unique_ID] - else: - return 1 diff --git a/src/common.py b/src/common.py index c690dfd74..3440e6d54 100644 --- a/src/common.py +++ b/src/common.py @@ -168,7 +168,7 @@ class ProxyType: PRIORITY_DONT_DOWNLOAD = 0 PRIORITY_NORMAL = 1 PRIORITY_HIGH = 2 -PRIORITY_HIGHEST = 6 +PRIORITY_HIGHEST = 5 PRIORITY_DICT = {PRIORITY_DONT_DOWNLOAD: N_("Don't download"), PRIORITY_NORMAL: N_("Normal"), diff --git a/src/core.py b/src/core.py index 162239636..7c46499d5 100644 --- a/src/core.py +++ b/src/core.py @@ -76,7 +76,7 @@ PREF_FUNCTIONS = { "auto_seed_ratio" : None, # no need for a function, applied constantly "max_download_speed_bps" : deluge_core.set_download_rate_limit, "max_upload_speed_bps" : deluge_core.set_upload_rate_limit, - "enable_dht" : None, # not a normal pref in that is is applied only on start + "enable_dht" : None, # not a normal pref in that is is applied only on start "use_upnp" : deluge_core.use_upnp, "use_natpmp" : deluge_core.use_natpmp, "use_utpex" : deluge_core.use_utpex, @@ -250,10 +250,6 @@ class Manager: # unique_IDs self.sync(True) - # Apply all the file priorities, right after adding the - # torrents - self.apply_all_file_priorities() - # Apply the queue at this time, after all is loaded and ready self.apply_queue() except IOError: @@ -627,6 +623,9 @@ class Manager: self.unique_IDs[unique_ID].priorities = priorities[:] deluge_core.prioritize_files(unique_ID, priorities) + + if self.get_pref('prioritize_first_last_pieces'): + self.prioritize_first_last_pieces(unique_ID) def get_priorities(self, unique_ID): try: @@ -637,14 +636,15 @@ class Manager: num_files = self.get_core_torrent_state(unique_ID)['num_files'] return [PRIORITY_NORMAL] * num_files - # Called when a session starts, to apply existing priorities - def apply_all_file_priorities(self): - for unique_ID in self.unique_IDs.keys(): - try: - self.prioritize_files(unique_ID, - self.get_priorities(unique_ID)) - except AttributeError: - pass + def prioritize_first_last_pieces(self, unique_ID): + """Try to prioritize first and last pieces of each file in torrent + + Currently it tries to prioritize 1% in the beginning and in the end + of each file in the torrent + + """ + deluge_core.prioritize_first_last_pieces(unique_ID, + self.unique_IDs[unique_ID].priorities) # Advanced statistics - these may be SLOW. The client should call these only # when needed, and perhaps only once in a long while (they are mostly just @@ -832,10 +832,14 @@ class Manager: def apply_prefs(self): print "Applying preferences" - for pref in PREF_FUNCTIONS.keys(): + for pref in PREF_FUNCTIONS: if PREF_FUNCTIONS[pref] is not None: PREF_FUNCTIONS[pref](self.get_pref(pref)) - + + # We need to reapply priorities to files after preferences were + # changed + for unique_ID in self.unique_IDs: + self.prioritize_files(unique_ID, self.get_priorities(unique_ID)) def set_DHT(self, start=False): if start == True and self.dht_running != True: diff --git a/src/deluge_core.cpp b/src/deluge_core.cpp index 25c40e9b6..4ec08ea19 100644 --- a/src/deluge_core.cpp +++ b/src/deluge_core.cpp @@ -1517,8 +1517,103 @@ static PyObject *torrent_prioritize_files(PyObject *self, PyObject *args) t.handle.prioritize_files(priorities_vector); + #ifndef NDEBUG + int num_pieces = t.handle.get_torrent_info().num_pieces(); + + std::vector priorities_pieces_vector(num_pieces); + priorities_pieces_vector = t.handle.piece_priorities(); + + std::cout << "after files prioritization\n"; + for (long i = 0; i < num_pieces; i++) { + std::cout << priorities_pieces_vector.at(i); + } + std::cout << "\n"; + #endif + return Py_None; } + +static PyObject *torrent_prioritize_first_last_pieces(PyObject *self, + PyObject *args) +{ +#define FIRST_LAST_PRIO 6 + + // Prioritize first and last 1% of file size bytes in each file of torrent + // with unique_ID + python_long unique_ID; + PyObject *priorities_list_object; + + // We need priorities_list_object to see whether file is marked to + // download(has priority > 0) or not. + if (!PyArg_ParseTuple(args, "iO", &unique_ID, &priorities_list_object)) + return NULL; + long index = get_index_from_unique_ID(unique_ID); + if (PyErr_Occurred()) + return NULL; + + torrent_t &t = M_torrents->at(index); + const torrent_info &tor_info = t.handle.get_torrent_info(); + int num_files = tor_info.num_files(); + assert(PyList_Size(priorities_list_object) == num_files); + int num_pieces = tor_info.num_pieces(); + + std::vector priorities_vector(num_pieces); + priorities_vector = t.handle.piece_priorities(); + + #ifndef NDEBUG + std::cout << "priority distribution in torrent_prioritize_first_last_pieces()\n"; + std::cout << "before prioritization\n"; + for (long i = 0; i < num_pieces; i++) { + std::cout << priorities_vector.at(i); + } + std::cout << "\n"; + #endif + + for (long i = 0; i < num_files; i++) { + file_entry const &file = tor_info.file_at(i); + if(file.size == 0) { + continue; + } + + // Check if file has priority 0 - means don't download - skip it + // and move to next file + int file_prio = PyInt_AsLong(PyList_GetItem(priorities_list_object, + i)); + if(file_prio == 0) { + continue; + } + + int start_piece = tor_info.map_file(i, 0, 0).piece; + int end_piece = tor_info.map_file(i, file.size, 0).piece; + // Set prio_size to 1% of the file size + int prio_size = file.size / 100; + int prio_pieces = tor_info.map_file(i, prio_size, 0).piece - + start_piece + 1; + + #ifndef NDEBUG + std::cout << "s=" << start_piece << ", e=" << end_piece << ", p=" << prio_pieces << "\n"; + #endif + + for (int piece = 0; piece < prio_pieces; piece++) { + priorities_vector.at(start_piece + piece) = FIRST_LAST_PRIO; + priorities_vector.at(end_piece - piece) = FIRST_LAST_PRIO; + } + } + + t.handle.prioritize_pieces(priorities_vector); + + #ifndef NDEBUG + std::cout << "after prioritization\n"; + for (long i = 0; i < num_pieces; i++) { + std::cout << priorities_vector.at(i); + } + std::cout << "\n"; + #endif + + return Py_None; +} + + static PyObject *torrent_set_priv(PyObject *self, PyObject *args) { using namespace libtorrent; @@ -1545,51 +1640,52 @@ 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, "."}, - {"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, "."}, + {"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, "."}, + {"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, "."}, {NULL} }; diff --git a/src/dialogs.py b/src/dialogs.py index fde87b824..a37657d6d 100644 --- a/src/dialogs.py +++ b/src/dialogs.py @@ -75,6 +75,7 @@ class PreferencesDlg: self.glade.get_widget("finished_path_button").set_filename(self.preferences.get("default_finished_path")) self.glade.get_widget("download_path_button").set_filename(self.preferences.get("default_download_path")) self.glade.get_widget("chk_enable_files_dialog").set_active(self.preferences.get("enable_files_dialog")) + self.glade.get_widget("chk_prioritize_first_last_pieces").set_active(self.preferences.get("prioritize_first_last_pieces")) self.glade.get_widget("chk_compact").set_active(self.preferences.get("use_compact_storage")) self.glade.get_widget("active_port_label").set_text(str(self.active_port)) self.glade.get_widget("spin_port_min").set_value(self.preferences.get("listen_on")[0]) @@ -148,6 +149,7 @@ class PreferencesDlg: self.preferences.set("enable_move_completed", self.glade.get_widget("chk_move_completed").get_active()) self.preferences.set("default_finished_path", self.glade.get_widget("finished_path_button").get_filename()) self.preferences.set("enable_files_dialog", self.glade.get_widget("chk_enable_files_dialog").get_active()) + self.preferences.set("prioritize_first_last_pieces", self.glade.get_widget("chk_prioritize_first_last_pieces").get_active()) self.preferences.set("auto_end_seeding", self.glade.get_widget("chk_autoseed").get_active()) self.preferences.set("auto_seed_ratio", self.glade.get_widget("ratio_spinner").get_value()) self.preferences.set("use_compact_storage", self.glade.get_widget("chk_compact").get_active()) diff --git a/src/files.py b/src/files.py index be5237f1c..d7ba1d566 100644 --- a/src/files.py +++ b/src/files.py @@ -165,7 +165,6 @@ class FilesTabManager(FilesBaseManager): def priority_clicked(self, widget): state = self.manager.get_torrent_state(self.file_unique_id) - print state["compact_mode"] if state["compact_mode"]: self.compact_allocation_warning() else: diff --git a/src/pref.py b/src/pref.py index 2b56dbe76..37e6f1569 100644 --- a/src/pref.py +++ b/src/pref.py @@ -70,6 +70,7 @@ DEFAULT_PREFS = { "max_upload_speed_bps" : -1, "max_uploads" : 2, "pref_rc4" : True, + "prioritize_first_last_pieces" : True, "proxy_type" : common.ProxyType.none, "peer_proxy" : False, "tracker_proxy" : False,