1 | #
|
---|
2 | # edittrackersdialog.py
|
---|
3 | #
|
---|
4 | # Copyright (C) 2007, 2008 Andrew Resch <andrewresch@gmail.com>
|
---|
5 | #
|
---|
6 | # Deluge is free software.
|
---|
7 | #
|
---|
8 | # You may redistribute it and/or modify it under the terms of the
|
---|
9 | # GNU General Public License, as published by the Free Software
|
---|
10 | # Foundation; either version 3 of the License, or (at your option)
|
---|
11 | # any later version.
|
---|
12 | #
|
---|
13 | # deluge is distributed in the hope that it will be useful,
|
---|
14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
---|
16 | # See the GNU General Public License for more details.
|
---|
17 | #
|
---|
18 | # You should have received a copy of the GNU General Public License
|
---|
19 | # along with deluge. If not, write to:
|
---|
20 | # The Free Software Foundation, Inc.,
|
---|
21 | # 51 Franklin Street, Fifth Floor
|
---|
22 | # Boston, MA 02110-1301, USA.
|
---|
23 | #
|
---|
24 | # In addition, as a special exception, the copyright holders give
|
---|
25 | # permission to link the code of portions of this program with the OpenSSL
|
---|
26 | # library.
|
---|
27 | # You must obey the GNU General Public License in all respects for all of
|
---|
28 | # the code used other than OpenSSL. If you modify file(s) with this
|
---|
29 | # exception, you may extend this exception to your version of the file(s),
|
---|
30 | # but you are not obligated to do so. If you do not wish to do so, delete
|
---|
31 | # this exception statement from your version. If you delete this exception
|
---|
32 | # statement from all source files in the program, then also delete it here.
|
---|
33 | #
|
---|
34 | #
|
---|
35 |
|
---|
36 |
|
---|
37 | import gtk, gtk.glade
|
---|
38 | import pkg_resources
|
---|
39 | import urllib
|
---|
40 |
|
---|
41 | import deluge.common
|
---|
42 | import common
|
---|
43 | from deluge.ui.client import client
|
---|
44 | import deluge.component as component
|
---|
45 | from deluge.log import LOG as log
|
---|
46 |
|
---|
47 | class EditTrackersDialog:
|
---|
48 | def __init__(self, torrent_id, parent=None):
|
---|
49 | self.torrent_id = torrent_id
|
---|
50 | self.glade = gtk.glade.XML(
|
---|
51 | pkg_resources.resource_filename("deluge.ui.gtkui",
|
---|
52 | "glade/edit_trackers.glade"))
|
---|
53 |
|
---|
54 | self.dialog = self.glade.get_widget("edit_trackers_dialog")
|
---|
55 | self.treeview = self.glade.get_widget("tracker_treeview")
|
---|
56 | self.add_tracker_dialog = self.glade.get_widget("add_tracker_dialog")
|
---|
57 | self.add_tracker_dialog.set_transient_for(self.dialog)
|
---|
58 | self.edit_tracker_entry = self.glade.get_widget("edit_tracker_entry")
|
---|
59 | self.edit_tracker_entry.set_transient_for(self.dialog)
|
---|
60 | self.dialog.set_icon(common.get_deluge_icon())
|
---|
61 |
|
---|
62 | if parent != None:
|
---|
63 | self.dialog.set_transient_for(parent)
|
---|
64 |
|
---|
65 | # Connect the signals
|
---|
66 | self.glade.signal_autoconnect({
|
---|
67 | "on_button_up_clicked": self.on_button_up_clicked,
|
---|
68 | "on_button_add_clicked": self.on_button_add_clicked,
|
---|
69 | "on_button_edit_clicked": self.on_button_edit_clicked,
|
---|
70 | "on_button_edit_cancel_clicked": self.on_button_edit_cancel_clicked,
|
---|
71 | "on_button_edit_ok_clicked": self.on_button_edit_ok_clicked,
|
---|
72 | "on_button_remove_clicked": self.on_button_remove_clicked,
|
---|
73 | "on_button_down_clicked": self.on_button_down_clicked,
|
---|
74 | "on_button_ok_clicked": self.on_button_ok_clicked,
|
---|
75 | "on_button_cancel_clicked": self.on_button_cancel_clicked,
|
---|
76 | "on_button_add_ok_clicked": self.on_button_add_ok_clicked,
|
---|
77 | "on_button_add_cancel_clicked": self.on_button_add_cancel_clicked
|
---|
78 | })
|
---|
79 |
|
---|
80 | # Create a liststore for tier, url
|
---|
81 | self.liststore = gtk.ListStore(int, str)
|
---|
82 |
|
---|
83 | # Create the columns
|
---|
84 | self.treeview.append_column(
|
---|
85 | gtk.TreeViewColumn(_("Tier"), gtk.CellRendererText(), text=0))
|
---|
86 | self.treeview.append_column(
|
---|
87 | gtk.TreeViewColumn(_("Tracker"), gtk.CellRendererText(), text=1))
|
---|
88 |
|
---|
89 | self.treeview.set_model(self.liststore)
|
---|
90 | self.liststore.set_sort_column_id(0, gtk.SORT_ASCENDING)
|
---|
91 |
|
---|
92 | def run(self):
|
---|
93 | # Make sure we have a torrent_id.. if not just return
|
---|
94 | if self.torrent_id == None:
|
---|
95 | return
|
---|
96 |
|
---|
97 | # Get the trackers for this torrent
|
---|
98 | session = component.get("SessionProxy")
|
---|
99 | session.get_torrent_status(self.torrent_id, ["trackers"]).addCallback(self._on_get_torrent_status)
|
---|
100 | client.force_call()
|
---|
101 |
|
---|
102 | def _on_get_torrent_status(self, status):
|
---|
103 | """Display trackers dialog"""
|
---|
104 | for tracker in status["trackers"]:
|
---|
105 | self.add_tracker(tracker["tier"], urllib.unquote(tracker["url"]))
|
---|
106 |
|
---|
107 | self.dialog.show()
|
---|
108 |
|
---|
109 | def add_tracker(self, tier, url):
|
---|
110 | """Adds a tracker to the list"""
|
---|
111 | self.liststore.append([tier, url])
|
---|
112 |
|
---|
113 | def get_selected(self):
|
---|
114 | """Returns the selected tracker"""
|
---|
115 | return self.treeview.get_selection().get_selected()[1]
|
---|
116 |
|
---|
117 | def on_button_add_clicked(self, widget):
|
---|
118 | log.debug("on_button_add_clicked")
|
---|
119 | # Show the add tracker dialog
|
---|
120 | self.add_tracker_dialog.show()
|
---|
121 | self.glade.get_widget("textview_trackers").grab_focus()
|
---|
122 |
|
---|
123 | def on_button_remove_clicked(self, widget):
|
---|
124 | log.debug("on_button_remove_clicked")
|
---|
125 | selected = self.get_selected()
|
---|
126 | if selected != None:
|
---|
127 | self.liststore.remove(selected)
|
---|
128 |
|
---|
129 | def on_button_edit_clicked(self, widget):
|
---|
130 | """edits an existing tracker"""
|
---|
131 | log.debug("on_button_edit_clicked")
|
---|
132 | selected = self.get_selected()
|
---|
133 | if selected:
|
---|
134 | tracker = self.liststore.get_value(selected, 1)
|
---|
135 | self.glade.get_widget("entry_edit_tracker").set_text(tracker)
|
---|
136 | self.edit_tracker_entry.show()
|
---|
137 | self.glade.get_widget("edit_tracker_entry").grab_focus()
|
---|
138 |
|
---|
139 | def on_button_edit_cancel_clicked(self, widget):
|
---|
140 | log.debug("on_button_edit_cancel_clicked")
|
---|
141 | self.edit_tracker_entry.hide()
|
---|
142 |
|
---|
143 | def on_button_edit_ok_clicked(self, widget):
|
---|
144 | log.debug("on_button_edit_ok_clicked")
|
---|
145 | selected = self.get_selected()
|
---|
146 | tracker = self.glade.get_widget("entry_edit_tracker").get_text()
|
---|
147 | self.liststore.set_value(selected, 1, tracker)
|
---|
148 | self.edit_tracker_entry.hide()
|
---|
149 |
|
---|
150 | def on_button_up_clicked(self, widget):
|
---|
151 | log.debug("on_button_up_clicked")
|
---|
152 | selected = self.get_selected()
|
---|
153 | num_rows = self.liststore.iter_n_children(None)
|
---|
154 | if selected != None and num_rows > 1:
|
---|
155 | tier = self.liststore.get_value(selected, 0)
|
---|
156 | if not tier > 0:
|
---|
157 | return
|
---|
158 | new_tier = tier - 1
|
---|
159 | # Now change the tier for this tracker
|
---|
160 | self.liststore.set_value(selected, 0, new_tier)
|
---|
161 |
|
---|
162 | def on_button_down_clicked(self, widget):
|
---|
163 | log.debug("on_button_down_clicked")
|
---|
164 | selected = self.get_selected()
|
---|
165 | num_rows = self.liststore.iter_n_children(None)
|
---|
166 | if selected != None and num_rows > 1:
|
---|
167 | tier = self.liststore.get_value(selected, 0)
|
---|
168 | new_tier = tier + 1
|
---|
169 | # Now change the tier for this tracker
|
---|
170 | self.liststore.set_value(selected, 0, new_tier)
|
---|
171 |
|
---|
172 | def on_button_ok_clicked(self, widget):
|
---|
173 | log.debug("on_button_ok_clicked")
|
---|
174 | self.trackers = []
|
---|
175 | def each(model, path, iter, data):
|
---|
176 | tracker = {}
|
---|
177 | tracker["tier"] = model.get_value(iter, 0)
|
---|
178 | tracker["url"] = model.get_value(iter, 1)
|
---|
179 | self.trackers.append(tracker)
|
---|
180 | self.liststore.foreach(each, None)
|
---|
181 | # Set the torrens trackers
|
---|
182 | client.core.set_torrent_trackers(self.torrent_id, self.trackers)
|
---|
183 | self.dialog.destroy()
|
---|
184 |
|
---|
185 | def on_button_cancel_clicked(self, widget):
|
---|
186 | log.debug("on_button_cancel_clicked")
|
---|
187 | self.dialog.destroy()
|
---|
188 |
|
---|
189 | def on_button_add_ok_clicked(self, widget):
|
---|
190 | log.debug("on_button_add_ok_clicked")
|
---|
191 |
|
---|
192 | # Create a list of trackers from the textview widget
|
---|
193 | textview = self.glade.get_widget("textview_trackers")
|
---|
194 | trackers = []
|
---|
195 | b = textview.get_buffer()
|
---|
196 | lines = b.get_text(b.get_start_iter(), b.get_end_iter()).strip().split("\n")
|
---|
197 | for l in lines:
|
---|
198 | if deluge.common.is_url(l):
|
---|
199 | trackers.append(l)
|
---|
200 |
|
---|
201 | for tracker in trackers:
|
---|
202 | # Figure out what tier number to use.. it's going to be the highest+1
|
---|
203 | # Also check for duplicates
|
---|
204 | # Check if there are any entries
|
---|
205 | duplicate = False
|
---|
206 | highest_tier = -1
|
---|
207 | for row in self.liststore:
|
---|
208 | tier = row[0]
|
---|
209 | if tier > highest_tier:
|
---|
210 | highest_tier = tier
|
---|
211 | if tracker == row[1]:
|
---|
212 | duplicate = True
|
---|
213 | break
|
---|
214 |
|
---|
215 | # If not a duplicate, then add it to the list
|
---|
216 | if not duplicate:
|
---|
217 | # Add the tracker to the list
|
---|
218 | self.add_tracker(highest_tier + 1, tracker)
|
---|
219 |
|
---|
220 | # Clear the entry widget and hide the dialog
|
---|
221 | textview.get_buffer().set_text("")
|
---|
222 | self.add_tracker_dialog.hide()
|
---|
223 |
|
---|
224 | def on_button_add_cancel_clicked(self, widget):
|
---|
225 | log.debug("on_button_add_cancel_clicked")
|
---|
226 | # Clear the entry widget and hide the dialog
|
---|
227 | b = gtk.TextBuffer()
|
---|
228 | self.glade.get_widget("textview_trackers").set_buffer(b)
|
---|
229 | self.add_tracker_dialog.hide()
|
---|