source: deluge/ui/tracker_icons.py@ 2542745

2.0.x develop extjs4-port
Last change on this file since 2542745 was 2542745, checked in by Andrew Resch <andrewresch@gmail.com>, 16 years ago

Add tracker icon to Tracker column

  • Property mode set to 100644
File size: 5.8 KB
Line 
1#
2# tracker_icons.py
3#
4# Copyright (C) 2008 Martijn Voncken <mvoncken@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
25
26
27import threading
28import gobject
29from urllib import urlopen
30from deluge.log import LOG as log
31from deluge.common import get_pixmap
32import os
33import deluge.configmanager
34
35#some servers don't have their favicon at the expected location
36RENAMES = {
37 "legaltorrents.com":"beta.legaltorrents.com",
38 "aelitis.com":"www.vuze.com"
39 }
40
41VALID_ICO_TYPES = ["octet-stream", "x-icon", "image/vnd.microsoft.icon", "vnd.microsoft.icon"]
42VALID_PNG_TYPES = ["octet-stream", "png"]
43
44def fetch_url(url, valid_subtypes=None):
45 """
46 returns: data or None
47 """
48 try:
49 url_file = urlopen(url)
50 data = url_file.read()
51
52 #validate:
53 if valid_subtypes and (url_file.info().getsubtype() not in valid_subtypes):
54 raise Exception("Unexpected type for %s : %s" % (url, url_file.info().getsubtype()))
55 if not data:
56 raise Exception("No data")
57 except Exception, e:
58 log.debug("%s %s" % (url, e))
59 return None
60
61 return data
62
63class TrackerIcons(object):
64 def __init__(self):
65 #set image cache dir
66 self.image_dir = os.path.join(deluge.configmanager.get_config_dir(), "icons")
67 if not os.path.exists(self.image_dir):
68 os.mkdir(self.image_dir)
69
70 #self.images : {tracker_host:filename}
71 self.images = {"DHT":get_pixmap("dht16.png" )}
72
73 #load image-names in cache-dir
74 for icon in os.listdir(self.image_dir):
75 if icon.endswith(".ico"):
76 self.images[icon[:-4]] = os.path.join(self.image_dir, icon)
77 if icon.endswith(".png"):
78 self.images[icon[:-4]] = os.path.join(self.image_dir, icon)
79
80 def _fetch_icon(self, tracker_host):
81 """
82 returns (ext, data)
83 """
84 host_name = RENAMES.get(tracker_host, tracker_host) #HACK!
85
86 ico = fetch_url("http://%s/favicon.ico" % host_name, VALID_ICO_TYPES)
87 if ico:
88 return ("ico", ico)
89
90 png = fetch_url("http://%s/favicon.png" % host_name, VALID_PNG_TYPES)
91 if png:
92 return ("png", png)
93
94 # FIXME: This should be cleaned up and not copy the top code
95
96 try:
97 html = urlopen("http://%s/" % (host_name,))
98 except Exception, e:
99 log.debug(e)
100 html = None
101
102 if html:
103 icon_path = ""
104 line = html.readline()
105 while line:
106 if '<link rel="icon"' in line or '<link rel="shortcut icon"' in line:
107 log.debug("line: %s", line)
108 icon_path = line[line.find("href"):].split("\"")[1]
109 break
110 line = html.readline()
111 if icon_path:
112 ico = fetch_url(("http://%s/" + icon_path) % host_name, VALID_ICO_TYPES)
113 if ico:
114 return ("ico", ico)
115 png = fetch_url(("http://%s/" + icon_path) % host_name, VALID_PNG_TYPES)
116 if png:
117 return ("png", png)
118
119 """
120 TODO: need a test-site first...
121 html = fetch_url("http://%s/" % (host_name,))
122 if html:
123 for line in html:
124 print line
125 """
126 return (None, None)
127
128 def _fetch_icon_thread(self, tracker_host, callback):
129 """
130 gets new icon from the internet.
131 used by get().
132 calls callback on sucess
133 assumes dicts,urllib and logging are threadsafe.
134 """
135
136 ext, icon_data = self._fetch_icon(tracker_host)
137
138 if icon_data:
139 filename = os.path.join(self.image_dir, "%s.%s" % (tracker_host, ext))
140 f = open(filename,"wb")
141 f.write(icon_data)
142 f.close()
143 self.images[tracker_host] = filename
144 else:
145 filename = None
146
147 if callback:
148 gobject.idle_add(callback, filename)
149
150 def get_async(self, tracker_host, callback):
151 if tracker_host in self.images:
152 callback(self.images[tracker_host])
153 elif "." in tracker_host:
154 #only find icon if there's a dot in the name.
155 self.images[tracker_host] = None
156 threading.Thread(target=self. _fetch_icon_thread,
157 args=(tracker_host, callback)).start()
158
159 def get(self, tracker_host):
160 """
161 returns None if the icon is not fetched(yet) or not fond.
162 """
163 if tracker_host in self.images:
164 return self.images[tracker_host]
165 else:
166 self.get_async(tracker_host, None)
167 return None
168
169if __name__ == "__main__":
170 import time
171 def del_old():
172 filename = os.path.join(deluge.configmanager.get_config_dir(),"legaltorrents.com.ico")
173 if os.path.exists(filename):
174 os.remove(filename)
175
176 def test_get():
177 del_old()
178 trackericons = TrackerIcons()
179 print trackericons.images
180 print trackericons.get("unknown2")
181 print trackericons.get("ntorrents.net")
182 print trackericons.get("google.com")
183 print trackericons.get("legaltorrents.com")
184 time.sleep(5.0)
185 print trackericons.get("legaltorrents.com")
186
187 test_get()
188 #test_async()
Note: See TracBrowser for help on using the repository browser.