2 * Bittorrent Client using Qt and libtorrent.
3 * Copyright (C) 2009 Christophe Dumez <chris@qbittorrent.org>
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
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.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 * In addition, as a special exception, the copyright holders give permission to
20 * link this program with the OpenSSL project's "OpenSSL" library (or with
21 * modified versions of it that use the same license as the "OpenSSL" library),
22 * and distribute the linked executables. You must obey the GNU General Public
23 * License in all respects for all of the code used other than "OpenSSL". If you
24 * modify file(s), you may extend this exception to your version of the file(s),
25 * but you are not obligated to do so. If you do not wish to do so, delete this
26 * exception statement from your version.
31 window
.qBittorrent
??= {};
32 window
.qBittorrent
.PropTrackers
??= (() => {
33 const exports
= () => {
35 updateData
: updateData
,
40 let current_hash
= "";
42 const torrentTrackersTable
= new window
.qBittorrent
.DynamicTable
.TorrentTrackersTable();
43 let loadTrackersDataTimer
= -1;
45 const loadTrackersData
= () => {
46 if ($("propTrackers").hasClass("invisible")
47 || $("propertiesPanel_collapseToggle").hasClass("panel-expand")) {
48 // Tab changed, don't do anything
51 const new_hash
= torrentsTable
.getCurrentTorrentID();
52 if (new_hash
=== "") {
53 torrentTrackersTable
.clear();
54 clearTimeout(loadTrackersDataTimer
);
57 if (new_hash
!== current_hash
) {
58 torrentTrackersTable
.clear();
59 current_hash
= new_hash
;
61 const url
= new URI("api/v2/torrents/trackers?hash=" + current_hash
);
67 clearTimeout(loadTrackersDataTimer
);
68 loadTrackersDataTimer
= loadTrackersData
.delay(10000);
70 onSuccess
: (trackers
) => {
71 const selectedTrackers
= torrentTrackersTable
.selectedRowsIds();
72 torrentTrackersTable
.clear();
75 trackers
.each((tracker
) => {
77 switch (tracker
.status
) {
79 status
= "QBT_TR(Disabled)QBT_TR[CONTEXT=TrackerListWidget]";
82 status
= "QBT_TR(Not contacted yet)QBT_TR[CONTEXT=TrackerListWidget]";
85 status
= "QBT_TR(Working)QBT_TR[CONTEXT=TrackerListWidget]";
88 status
= "QBT_TR(Updating...)QBT_TR[CONTEXT=TrackerListWidget]";
91 status
= "QBT_TR(Not working)QBT_TR[CONTEXT=TrackerListWidget]";
97 tier
: (tracker
.tier
>= 0) ? tracker
.tier
: "",
100 peers
: (tracker
.num_peers
>= 0) ? tracker
.num_peers
: "QBT_TR(N/A)QBT_TR[CONTEXT=TrackerListWidget]",
101 seeds
: (tracker
.num_seeds
>= 0) ? tracker
.num_seeds
: "QBT_TR(N/A)QBT_TR[CONTEXT=TrackerListWidget]",
102 leeches
: (tracker
.num_leeches
>= 0) ? tracker
.num_leeches
: "QBT_TR(N/A)QBT_TR[CONTEXT=TrackerListWidget]",
103 downloaded
: (tracker
.num_downloaded
>= 0) ? tracker
.num_downloaded
: "QBT_TR(N/A)QBT_TR[CONTEXT=TrackerListWidget]",
104 message
: tracker
.msg
,
105 _sortable
: !tracker
.url
.startsWith("** [")
108 torrentTrackersTable
.updateRowData(row
);
111 torrentTrackersTable
.updateTable(false);
113 if (selectedTrackers
.length
> 0)
114 torrentTrackersTable
.reselectRows(selectedTrackers
);
120 const updateData
= () => {
121 clearTimeout(loadTrackersDataTimer
);
122 loadTrackersDataTimer
= -1;
126 const torrentTrackersContextMenu
= new window
.qBittorrent
.ContextMenu
.ContextMenu({
127 targets
: "#torrentTrackersTableDiv",
128 menu
: "torrentTrackersMenu",
130 AddTracker
: (element
, ref
) => {
133 EditTracker
: (element
, ref
) => {
134 // only allow editing of one row
135 element
.firstChild
.click();
136 editTrackerFN(element
);
138 RemoveTracker
: (element
, ref
) => {
139 removeTrackerFN(element
);
147 const selectedTrackers
= torrentTrackersTable
.selectedRowsIds();
148 const containsStaticTracker
= selectedTrackers
.some((tracker
) => {
149 return (tracker
.indexOf("** [") === 0);
152 if (containsStaticTracker
|| (selectedTrackers
.length
=== 0)) {
153 this.hideItem("EditTracker");
154 this.hideItem("RemoveTracker");
155 this.hideItem("CopyTrackerUrl");
158 this.showItem("EditTracker");
159 this.showItem("RemoveTracker");
160 this.showItem("CopyTrackerUrl");
165 const addTrackerFN
= () => {
166 if (current_hash
.length
=== 0)
170 icon
: "images/qbittorrent-tray.svg",
171 title
: "QBT_TR(Add trackers)QBT_TR[CONTEXT=TrackersAdditionDialog]",
172 loadMethod
: "iframe",
173 contentURL
: "addtrackers.html?hash=" + current_hash
,
179 paddingHorizontal
: 0,
182 onCloseComplete
: () => {
188 const editTrackerFN
= (element
) => {
189 if (current_hash
.length
=== 0)
192 const trackerUrl
= encodeURIComponent(element
.childNodes
[1].textContent
);
195 icon
: "images/qbittorrent-tray.svg",
196 title
: "QBT_TR(Tracker editing)QBT_TR[CONTEXT=TrackerListWidget]",
197 loadMethod
: "iframe",
198 contentURL
: "edittracker.html?hash=" + current_hash
+ "&url=" + trackerUrl
,
204 paddingHorizontal
: 0,
207 onCloseComplete
: () => {
213 const removeTrackerFN
= (element
) => {
214 if (current_hash
.length
=== 0)
217 const selectedTrackers
= torrentTrackersTable
.selectedRowsIds();
219 url
: "api/v2/torrents/removeTrackers",
223 urls
: selectedTrackers
.map(encodeURIComponent
).join("|")
231 const clear
= () => {
232 torrentTrackersTable
.clear();
235 new ClipboardJS("#CopyTrackerUrl", {
237 return torrentTrackersTable
.selectedRowsIds().join("\n");
241 torrentTrackersTable
.setup("torrentTrackersTableDiv", "torrentTrackersTableFixedHeaderDiv", torrentTrackersContextMenu
);
245 Object
.freeze(window
.qBittorrent
.PropTrackers
);