Imported Upstream version 1.3.1
Cristian Greco
13 years ago
0 | === Deluge 1.3.1 (31 October 2010) === | |
1 | ==== Core ==== | |
2 | * #1369: Fix non-ascii config folders not working in windows | |
3 | ||
4 | ==== GtkUI ==== | |
5 | * #1365: Fix sidebar not updating show/hide trackers | |
6 | * #1247: Fix hang on quit | |
7 | ||
8 | ==== WebUI ==== | |
9 | * #1364: Fix preferences not saving when the web ui plugin is enabled in classic mode | |
10 | * #1377: Fix bug when enabling plugins | |
11 | * #1370: Fix issues with preferences | |
12 | * #1312: Fix deluge-web using 100% CPU | |
13 | ||
0 | 14 | === Deluge 1.3.0 (18 September 2010) === |
15 | ==== Core ==== | |
1 | 16 | * Fix issue where the save_timer is cancelled when it's not active |
2 | 17 | * Fix unhandled exception when adding a torrent to the session |
3 | 18 | * Moved xdg import so it is not called on Windows, where it is unused. fixes #1343 |
4 | 19 | * Fix key error after enabling a plugin that introduces a new status key |
20 | * Ignore global stop ratio related settings in logic, so per torrent ones are used. | |
21 | * Ensure preferencesmanager only changes intended libtorrent session settings. | |
22 | * Fix issue when adding torrents without a 'session'. This can happen when a plugin adds a torrent, like how the AutoAdd plugin works. The user that adds this torrent will be an empty string. | |
23 | * Add TorrentFileCompleted event | |
24 | ||
25 | ==== GtkUI ==== | |
26 | * Increase max piece size to 8 MiB in create torrent dialog (closes #1358) | |
27 | ||
28 | ==== Scheduler ==== | |
5 | 29 | * Add max active downloading and seeding options to scheduler. |
6 | * Ignore global stop ratio related settings in logic, so per torrent ones are used. | |
7 | 30 | * Fix scheduler so that it keeps current state, even after global settings change. |
8 | * Ensure preferencesmanager only changes intended libtorrent session settings. | |
9 | * Fix issue when adding torrents without a 'session'. This can happen when | |
10 | a plugin adds a torrent, like how the AutoAdd plugin works. The user that | |
11 | adds this torrent will be an empty string. | |
12 | * Add TorrentFileCompleted event | |
31 | ||
32 | ==== AutoAdd ==== | |
13 | 33 | * AutoAdd plugin can now recover when one of the watchfolders has an unhandled exception. |
14 | * Increase max piece size to 8 MiB in create torrent dialog (closes #1358) | |
15 | 34 | * Fix bug in AutoAdd plugin where watchdirs would not display in gtkui when first enabled. |
16 | 35 | * Fix bugs with unicode torrents in AutoAdd plugin. |
17 | 36 | |
19 | 38 | ==== Core ==== |
20 | 39 | * Fix tracker_icons failing on windows |
21 | 40 | * Fix #1302 an uncaught exception in an state_changed event handler in SessionProxy was preventing the TorrentManager's stop method from properly saving all the resume data |
22 | * Fix issue with SessionProxy not updating the torrent status correctly when | |
23 | get_torrent_status calls take place within the cache_expiry time | |
41 | * Fix issue with SessionProxy not updating the torrent status correctly when get_torrent_status calls take place within the cache_expiry time | |
24 | 42 | |
25 | 43 | ==== ConsoleUI ==== |
26 | 44 | * #1307: Fix not being able to add torrents |
6 | 6 | * setuptools |
7 | 7 | * gettext |
8 | 8 | * pyxdg |
9 | * chardet | |
9 | 10 | * geoip-database (optional) |
10 | 11 | |
11 | 12 | * libtorrent >= 0.14, or build the included version |
14 | 15 | * boost >= 1.34.1 |
15 | 16 | * openssl |
16 | 17 | * zlib |
17 | ||
18 | === UIs === | |
19 | * chardet | |
20 | 18 | |
21 | 19 | === Gtk === |
22 | 20 | * python-notify (libnotify python wrapper) |
40 | 40 | import subprocess |
41 | 41 | import platform |
42 | 42 | import sys |
43 | import chardet | |
43 | 44 | |
44 | 45 | try: |
45 | 46 | import json |
473 | 474 | sectors, bytes, free, total = map(long, win32file.GetDiskFreeSpace(path)) |
474 | 475 | return (free * sectors * bytes) |
475 | 476 | else: |
476 | disk_data = os.statvfs(path) | |
477 | disk_data = os.statvfs(path.encode("utf8")) | |
477 | 478 | block_size = disk_data.f_bsize |
478 | 479 | return disk_data.f_bavail * block_size |
479 | 480 | |
559 | 560 | string = string.replace(char, escape) |
560 | 561 | return string |
561 | 562 | |
563 | def decode_string(s, encoding="utf8"): | |
564 | """ | |
565 | Decodes a string and re-encodes it in utf8. If it cannot decode using | |
566 | `:param:encoding` then it will try to detect the string encoding and | |
567 | decode it. | |
568 | ||
569 | :param s: string to decode | |
570 | :type s: string | |
571 | :keyword encoding: the encoding to use in the decoding | |
572 | :type encoding: string | |
573 | ||
574 | """ | |
575 | ||
576 | try: | |
577 | s = s.decode(encoding).encode("utf8", "ignore") | |
578 | except UnicodeDecodeError: | |
579 | s = s.decode(chardet.detect(s)["encoding"], "ignore").encode("utf8", "ignore") | |
580 | return s | |
581 | ||
582 | def utf8_encoded(s): | |
583 | """ | |
584 | Returns a utf8 encoded string of s | |
585 | ||
586 | :param s: (unicode) string to (re-)encode | |
587 | :type s: basestring | |
588 | :returns: a utf8 encoded string of s | |
589 | :rtype: str | |
590 | ||
591 | """ | |
592 | if isinstance(s, str): | |
593 | s = decode_string(s, locale.getpreferredencoding()) | |
594 | elif isinstance(s, unicode): | |
595 | s = s.encode("utf8", "ignore") | |
596 | return s | |
597 | ||
562 | 598 | class VersionSplit(object): |
563 | 599 | """ |
564 | 600 | Used for comparing version numbers. |
145 | 145 | self._save_timer = None |
146 | 146 | |
147 | 147 | if defaults: |
148 | self.__config = dict(defaults) | |
148 | for key, value in defaults.iteritems(): | |
149 | self.set_item(key, value) | |
149 | 150 | |
150 | 151 | # Load the config from file in the config_dir |
151 | 152 | if config_dir: |
186 | 187 | 5 |
187 | 188 | |
188 | 189 | """ |
190 | if isinstance(value, basestring): | |
191 | value = deluge.common.utf8_encoded(value) | |
192 | ||
193 | ||
189 | 194 | if not self.__config.has_key(key): |
190 | 195 | self.__config[key] = value |
191 | 196 | log.debug("Setting '%s' to %s of %s", key, value, type(value)) |
199 | 204 | |
200 | 205 | if value is not None and oldtype != type(None) and oldtype != newtype: |
201 | 206 | try: |
202 | value = oldtype(value) | |
207 | if oldtype == unicode: | |
208 | value = oldtype(value, "utf8") | |
209 | else: | |
210 | value = oldtype(value) | |
203 | 211 | except ValueError: |
204 | 212 | log.warning("Type '%s' invalid for '%s'", newtype, key) |
205 | 213 | raise |
249 | 257 | 5 |
250 | 258 | |
251 | 259 | """ |
252 | return self.__config[key] | |
260 | if isinstance(self.__config[key], str): | |
261 | return self.__config[key].decode("utf8") | |
262 | else: | |
263 | return self.__config[key] | |
253 | 264 | |
254 | 265 | def register_change_callback(self, callback): |
255 | 266 | """ |
399 | 410 | # The config has not changed so lets just return |
400 | 411 | if self._save_timer and self._save_timer.active(): |
401 | 412 | self._save_timer.cancel() |
402 | return | |
413 | return True | |
403 | 414 | except IOError, e: |
404 | 415 | log.warning("Unable to open config file: %s because: %s", filename, e) |
405 | 416 |
195 | 195 | value = status[field] |
196 | 196 | items[field][value] = items[field].get(value, 0) + 1 |
197 | 197 | |
198 | items["tracker_host"]["All"] = len(torrent_ids) | |
199 | ||
200 | 198 | if "tracker_host" in items: |
199 | items["tracker_host"]["All"] = len(torrent_ids) | |
201 | 200 | items["tracker_host"]["Error"] = len(tracker_error_filter(torrent_ids, ("Error",))) |
202 | 201 | |
203 | 202 | if "state" in tree_keys and not show_zero_hits: |
178 | 178 | else: |
179 | 179 | self.time_added = time.time() |
180 | 180 | |
181 | # Keep track if we're forcing a recheck of the torrent so that we can | |
182 | # repause it after its done if necessary | |
183 | self.forcing_recheck = False | |
184 | self.forcing_recheck_paused = False | |
185 | ||
181 | 186 | log.debug("Torrent object created.") |
182 | 187 | |
183 | 188 | ## Options methods ## |
858 | 863 | |
859 | 864 | def force_recheck(self): |
860 | 865 | """Forces a recheck of the torrents pieces""" |
866 | paused = self.handle.is_paused() | |
861 | 867 | try: |
862 | 868 | self.handle.force_recheck() |
863 | 869 | self.handle.resume() |
864 | 870 | except Exception, e: |
865 | 871 | log.debug("Unable to force recheck: %s", e) |
866 | 872 | return False |
873 | self.forcing_recheck = True | |
874 | self.forcing_recheck_paused = paused | |
867 | 875 | return True |
868 | 876 | |
869 | 877 | def rename_files(self, filenames): |
46 | 46 | |
47 | 47 | from deluge._libtorrent import lt |
48 | 48 | |
49 | ||
50 | 49 | from deluge.event import * |
51 | 50 | from deluge.error import * |
52 | import deluge.common | |
53 | 51 | import deluge.component as component |
54 | 52 | from deluge.configmanager import ConfigManager, get_config_dir |
55 | 53 | from deluge.core.torrent import Torrent |
56 | 54 | from deluge.core.torrent import TorrentOptions |
57 | 55 | import deluge.core.oldstateupgrader |
58 | from deluge.ui.common import utf8_encoded | |
56 | from deluge.common import utf8_encoded | |
59 | 57 | |
60 | 58 | from deluge.log import LOG as log |
61 | 59 | |
850 | 848 | torrent = self.torrents[str(alert.handle.info_hash())] |
851 | 849 | except: |
852 | 850 | return |
853 | ||
851 | ||
852 | # Check to see if we're forcing a recheck and set it back to paused | |
853 | # if necessary | |
854 | if torrent.forcing_recheck: | |
855 | torrent.forcing_recheck = False | |
856 | if torrent.forcing_recheck_paused: | |
857 | torrent.handle.pause() | |
858 | ||
854 | 859 | # Set the torrent state |
855 | 860 | torrent.update_state() |
856 | 861 |
81 | 81 | self.is_importing = False |
82 | 82 | self.has_imported = False |
83 | 83 | self.up_to_date = False |
84 | self.need_to_resume_session = False | |
84 | 85 | self.num_blocked = 0 |
85 | 86 | self.file_progress = 0.0 |
86 | 87 | |
94 | 95 | |
95 | 96 | update_now = False |
96 | 97 | if self.config["load_on_start"]: |
97 | self.pause_transfers() | |
98 | self.pause_session() | |
98 | 99 | if self.config["last_update"]: |
99 | 100 | last_update = datetime.fromtimestamp(self.config["last_update"]) |
100 | 101 | check_period = timedelta(days=self.config["check_after_days"]) |
103 | 104 | else: |
104 | 105 | d = self.import_list(deluge.configmanager.get_config_dir("blocklist.cache")) |
105 | 106 | d.addCallbacks(self.on_import_complete, self.on_import_error) |
106 | d.addBoth(self.resume_transfers) | |
107 | if self.need_to_resume_session: | |
108 | d.addBoth(self.resume_session) | |
107 | 109 | |
108 | 110 | # This function is called every 'check_after_days' days, to download |
109 | 111 | # and import a new list if needed. |
149 | 151 | else: |
150 | 152 | d = self.import_list(self.config["url"]) |
151 | 153 | d.addCallbacks(self.on_import_complete, self.on_import_error) |
152 | d.addBoth(self.resume_transfers) | |
154 | if self.need_to_resume_session: | |
155 | d.addBoth(self.resume_session) | |
153 | 156 | |
154 | 157 | return d |
155 | 158 | |
417 | 420 | else: |
418 | 421 | self.reader = create_reader(self.config["list_type"], self.config["list_compression"]) |
419 | 422 | |
420 | def pause_transfers(self): | |
421 | self.session_was_paused = self.core.session.is_paused() | |
422 | if not self.session_was_paused: | |
423 | def pause_session(self): | |
424 | if not self.core.session.is_paused(): | |
423 | 425 | self.core.session.pause() |
424 | ||
425 | def resume_transfers(self, result): | |
426 | if not self.session_was_paused: | |
427 | self.session_was_paused = True | |
428 | self.core.session.resume() | |
426 | self.need_to_resume_session = True | |
427 | else: | |
428 | self.need_to_resume_session = False | |
429 | ||
430 | def resume_session(self, result): | |
431 | self.core.session.resume() | |
432 | self.need_to_resume_session = False | |
429 | 433 | return result |
41 | 41 | import sys |
42 | 42 | import urlparse |
43 | 43 | |
44 | import chardet | |
45 | 44 | import locale |
46 | 45 | |
47 | 46 | try: |
49 | 48 | except ImportError: |
50 | 49 | from sha import sha |
51 | 50 | |
52 | from deluge import bencode, common | |
51 | from deluge import bencode | |
52 | from deluge.common import decode_string, path_join | |
53 | 53 | from deluge.log import LOG as log |
54 | 54 | import deluge.configmanager |
55 | ||
56 | def decode_string(s, encoding="utf8"): | |
57 | """ | |
58 | Decodes a string and re-encodes it in utf8. If it cannot decode using | |
59 | `:param:encoding` then it will try to detect the string encoding and | |
60 | decode it. | |
61 | ||
62 | :param s: string to decode | |
63 | :type s: string | |
64 | :keyword encoding: the encoding to use in the decoding | |
65 | :type encoding: string | |
66 | ||
67 | """ | |
68 | ||
69 | try: | |
70 | s = s.decode(encoding).encode("utf8", "ignore") | |
71 | except UnicodeDecodeError: | |
72 | s = s.decode(chardet.detect(s)["encoding"], "ignore").encode("utf8", "ignore") | |
73 | return s | |
74 | ||
75 | def utf8_encoded(s): | |
76 | """ | |
77 | Returns a utf8 encoded string of s | |
78 | ||
79 | :param s: (unicode) string to (re-)encode | |
80 | :type s: basestring | |
81 | :returns: a utf8 encoded string of s | |
82 | :rtype: str | |
83 | ||
84 | """ | |
85 | if isinstance(s, str): | |
86 | s = decode_string(s, locale.getpreferredencoding()) | |
87 | elif isinstance(s, unicode): | |
88 | s = s.encode("utf8", "ignore") | |
89 | return s | |
90 | 55 | |
91 | 56 | class TorrentInfo(object): |
92 | 57 | """ |
335 | 300 | """ |
336 | 301 | def walk(directory, parent_path): |
337 | 302 | for path in directory["contents"].keys(): |
338 | full_path = common.path_join(parent_path, path) | |
303 | full_path = path_join(parent_path, path) | |
339 | 304 | if directory["contents"][path]["type"] == "dir": |
340 | 305 | directory["contents"][path] = callback(full_path, directory["contents"][path]) or \ |
341 | 306 | directory["contents"][path] |
121 | 121 | self.label_view.set_show_expanders(True) |
122 | 122 | self.label_view.set_headers_visible(False) |
123 | 123 | self.label_view.set_level_indentation(-35) |
124 | ||
124 | # Force the theme to use an expander-size of 15 so that we don't cut out | |
125 | # entries due to our indentation hack. | |
126 | gtk.rc_parse_string('style "treeview-style" { GtkTreeView::expander-size = 15 } class "GtkTreeView" style "treeview-style"') | |
127 | ||
125 | 128 | self.label_view.set_model(self.treestore) |
126 | 129 | self.label_view.get_selection().connect("changed", self.on_selection_changed) |
127 | 130 | self.create_model_filter() |
46 | 46 | |
47 | 47 | # Initialize gettext |
48 | 48 | try: |
49 | locale.setlocale(locale.LC_ALL, '') | |
49 | 50 | if hasattr(locale, "bindtextdomain"): |
50 | 51 | locale.bindtextdomain("deluge", pkg_resources.resource_filename("deluge", "i18n")) |
51 | 52 | if hasattr(locale, "textdomain"): |
151 | 151 | """Returns a reference to the main window glade object.""" |
152 | 152 | return self.main_glade |
153 | 153 | |
154 | def quit(self): | |
155 | if client.is_classicmode(): | |
156 | gtk.main_quit() | |
157 | else: | |
158 | reactor.stop() | |
154 | def quit(self, shutdown=False): | |
155 | """ | |
156 | Quits the GtkUI | |
157 | ||
158 | :param shutdown: whether or not to shutdown the daemon as well | |
159 | :type shutdown: boolean | |
160 | """ | |
161 | if shutdown: | |
162 | client.daemon.shutdown() | |
163 | reactor.stop() | |
159 | 164 | |
160 | 165 | def load_window_state(self): |
161 | 166 | x = self.config["window_x_pos"] |
252 | 252 | |
253 | 253 | def on_menuitem_quitdaemon_activate(self, data=None): |
254 | 254 | log.debug("on_menuitem_quitdaemon_activate") |
255 | # Tell the core to shutdown | |
256 | def on_shutdown(result): | |
257 | self.window.quit() | |
258 | client.daemon.shutdown().addCallback(on_shutdown) | |
255 | self.window.quit(shutdown=True) | |
259 | 256 | |
260 | 257 | def on_menuitem_quit_activate(self, data=None): |
261 | 258 | log.debug("on_menuitem_quit_activate") |
322 | 322 | if self.config["lock_tray"] and not self.window.visible(): |
323 | 323 | self.unlock_tray() |
324 | 324 | |
325 | if self.config["classic_mode"]: | |
326 | client.daemon.shutdown() | |
327 | ||
328 | 325 | self.window.quit() |
329 | 326 | |
330 | 327 | def on_menuitem_quitdaemon_activate(self, menuitem): |
332 | 329 | if self.config["lock_tray"] and not self.window.visible(): |
333 | 330 | self.unlock_tray() |
334 | 331 | |
335 | client.daemon.shutdown() | |
336 | self.window.quit() | |
332 | self.window.quit(shutdown=True) | |
337 | 333 | |
338 | 334 | def tray_setbwdown(self, widget, data=None): |
339 | 335 | self.setbwlimit(widget, _("Set Maximum Download Speed"), "max_download_speed", |
30 | 30 | </script> |
31 | 31 | </head> |
32 | 32 | <body> |
33 | <div style="background-image: url('${base}themes/default/tree/loading.gif');"></div> | |
33 | <div style="background-image: url('${base}themes/images/default/tree/loading.gif');"></div> | |
34 | 34 | |
35 | 35 | <!-- Preload icon classes --> |
36 | 36 | <div class="ext-mb-error"></div> |
173 | 173 | this.stored[this.currentId][option] = value; |
174 | 174 | |
175 | 175 | if (!this.isDirty(option)) { |
176 | this.fireEvent('changed', this.currentId, option, value, oldValue); | |
176 | this.fireEvent('changed', option, value, oldValue); | |
177 | 177 | } |
178 | 178 | } |
179 | 179 | }, |
231 | 231 | }, |
232 | 232 | |
233 | 233 | onPluginEnabled: function(pluginName) { |
234 | var index = this.grid.getStore().find('plugin', pluginName); | |
234 | var index = this.list.getStore().find('plugin', pluginName); | |
235 | 235 | if (index == -1) return; |
236 | var plugin = this.grid.getStore().getAt(index); | |
236 | var plugin = this.list.getStore().getAt(index); | |
237 | 237 | plugin.set('enabled', true); |
238 | 238 | plugin.commit(); |
239 | 239 | }, |
0 | /*! | |
1 | * Ext.ux.form.SpinnerField.js | |
2 | * | |
3 | * Copyright (c) Damien Churchill 2010 <damoxc@gmail.com> | |
4 | * | |
5 | * This program is free software; you can redistribute it and/or modify | |
6 | * it under the terms of the GNU General Public License as published by | |
7 | * the Free Software Foundation; either version 3, or (at your option) | |
8 | * any later version. | |
9 | * | |
10 | * This program is distributed in the hope that it will be useful, | |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | * GNU General Public License for more details. | |
14 | * | |
15 | * You should have received a copy of the GNU General Public License | |
16 | * along with this program. If not, write to: | |
17 | * The Free Software Foundation, Inc., | |
18 | * 51 Franklin Street, Fifth Floor | |
19 | * Boston, MA 02110-1301, USA. | |
20 | * | |
21 | * In addition, as a special exception, the copyright holders give | |
22 | * permission to link the code of portions of this program with the OpenSSL | |
23 | * library. | |
24 | * You must obey the GNU General Public License in all respects for all of | |
25 | * the code used other than OpenSSL. If you modify file(s) with this | |
26 | * exception, you may extend this exception to your version of the file(s), | |
27 | * but you are not obligated to do so. If you do not wish to do so, delete | |
28 | * this exception statement from your version. If you delete this exception | |
29 | * statement from all source files in the program, then also delete it here. | |
30 | */ | |
31 | ||
32 | Ext.override(Ext.ux.form.SpinnerField, { | |
33 | onBlur: Ext.form.Field.prototype.onBlur | |
34 | }); |
149 | 149 | return d |
150 | 150 | |
151 | 151 | def disable(self): |
152 | client.disconnect() | |
152 | if not client.is_classicmode(): | |
153 | client.disconnect() | |
153 | 154 | |
154 | 155 | def enable(self): |
155 | 156 | if component.get("DelugeWeb").config["default_daemon"]: |
380 | 381 | |
381 | 382 | # Create a deferred to and check again in 100ms |
382 | 383 | d = Deferred() |
383 | reactor.callLater(0.5, self._get_events, listener_id, d) | |
384 | reactor.callLater(0.1, self._get_events, listener_id, 0, d) | |
384 | 385 | return d |
385 | 386 | |
386 | def _get_events(self, listener_id, d): | |
387 | def _get_events(self, listener_id, count, d): | |
387 | 388 | if listener_id in self.__queue: |
388 | 389 | queue = self.__queue[listener_id] |
389 | 390 | del self.__queue[listener_id] |
390 | 391 | d.callback(queue) |
391 | 392 | else: |
392 | reactor.callLater(0.1, self._get_events, listener_id, d) | |
393 | # Prevent this loop going on indefinitely incase a client leaves | |
394 | # the page or disconnects uncleanly. | |
395 | if count >= 3000: | |
396 | d.callback(None) | |
397 | else: | |
398 | reactor.callLater(0.1, self._get_events, listener_id, count + 1, d) | |
393 | 399 | |
394 | 400 | def remove_listener(self, listener_id, event): |
395 | 401 | """ |
0 | #!/usr/bin/env python | |
1 | ||
2 | import os | |
3 | import sys | |
4 | import cPickle as pickle | |
5 | if sys.version_info > (2, 6): | |
6 | import json | |
7 | else: | |
8 | import simplejson as json | |
9 | ||
10 | from deluge.common import get_default_config_dir | |
11 | ||
12 | config_dir = get_default_config_dir() | |
13 | files = [] | |
14 | for filename in os.listdir(config_dir): | |
15 | filename = os.path.join(config_dir, filename) | |
16 | if not os.path.isfile(filename): | |
17 | continue | |
18 | if filename.endswith(".log"): | |
19 | continue | |
20 | ||
21 | basename = os.path.basename(filename) | |
22 | sys.stdout.write("Converting %s..." % (basename) + ' '*(20-len(basename))) | |
23 | try: | |
24 | config = json.load(open(filename, "r")) | |
25 | pickle.dump(config, open(filename, "wb")) | |
26 | print "\033[032mdone\033[0m" | |
27 | except: | |
28 | try: | |
29 | pickle.load(open(filename, "rb")) | |
30 | print "\033[032malready converted\033[0m" | |
31 | except: | |
32 | print "\033[031mfailed\033[1;m" |
421 | 421 | 'docs/man/deluge-console.1']) |
422 | 422 | ] |
423 | 423 | |
424 | entry_points = { | |
425 | "console_scripts": [ | |
426 | "deluge-console = deluge.ui.console:start", | |
427 | "deluge-web = deluge.ui.web:start", | |
428 | "deluged = deluge.main:start_daemon" | |
429 | ], | |
430 | "gui_scripts": [ | |
431 | "deluge = deluge.main:start_ui", | |
432 | "deluge-gtk = deluge.ui.gtkui:start" | |
433 | ] | |
434 | } | |
435 | ||
436 | ||
437 | if windows_check(): | |
438 | entry_points["console_scripts"].append("deluge-debug = deluge.main:start_ui") | |
439 | ||
424 | 440 | # Main setup |
425 | 441 | setup( |
426 | 442 | name = "deluge", |
427 | version = "1.3.0", | |
443 | version = "1.3.1", | |
428 | 444 | fullname = "Deluge Bittorrent Client", |
429 | 445 | description = "Bittorrent Client", |
430 | 446 | author = "Andrew Resch, Damien Churchill", |
468 | 484 | "ui/web/themes/images/*/*/*.png" |
469 | 485 | ]}, |
470 | 486 | packages = find_packages(exclude=["plugins", "docs", "tests"]), |
471 | entry_points = """ | |
472 | [console_scripts] | |
473 | deluge = deluge.main:start_ui | |
474 | deluge-console = deluge.ui.console:start | |
475 | deluge-gtk = deluge.ui.gtkui:start | |
476 | deluge-web = deluge.ui.web:start | |
477 | deluged = deluge.main:start_daemon | |
478 | """, | |
487 | entry_points = entry_points | |
479 | 488 | ) |