• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • libkonq
 

libkonq

  • libkonq
  • favicons
favicons.cpp
1 /* This file is part of the KDE project
2  Copyright (C) 2001 Malte Starostik <malte@kde.org>
3 
4  This library is free software; you can redistribute it and/or
5  modify it under the terms of the GNU Library General Public
6  License as published by the Free Software Foundation; either
7  version 2 of the License, or (at your option) any later version.
8 
9  This library is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  Library General Public License for more details.
13 
14  You should have received a copy of the GNU Library General Public License
15  along with this library; see the file COPYING.LIB. If not, write to
16  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  Boston, MA 02110-1301, USA.
18 */
19 
20 #include <string.h>
21 #include <time.h>
22 
23 #include <tqbuffer.h>
24 #include <tqfile.h>
25 #include <tqcache.h>
26 #include <tqimage.h>
27 #include <tqtimer.h>
28 
29 #include <kdatastream.h> // DO NOT REMOVE, otherwise bool marshalling breaks
30 #include <kicontheme.h>
31 #include <kimageio.h>
32 #include <ksimpleconfig.h>
33 #include <kstandarddirs.h>
34 #include <tdeio/job.h>
35 
36 #include "favicons.moc"
37 
38 struct FaviconsModulePrivate
39 {
40  virtual ~FaviconsModulePrivate() { delete config; }
41 
42  struct DownloadInfo
43  {
44  TQString hostOrURL;
45  bool isHost;
46  TQByteArray iconData;
47  };
48  TQMap<TDEIO::Job *, DownloadInfo> downloads;
49  TQStringList failedDownloads;
50  KSimpleConfig *config;
51  TQPtrList<TDEIO::Job> killJobs;
52  TDEIO::MetaData metaData;
53  TQString faviconsDir;
54  TQCache<TQString> faviconsCache;
55 };
56 
57 FaviconsModule::FaviconsModule(const TQCString &obj)
58  : KDEDModule(obj)
59 {
60  // create our favicons folder so that TDEIconLoader knows about it
61  d = new FaviconsModulePrivate;
62  d->faviconsDir = TDEGlobal::dirs()->saveLocation( "cache", "favicons/" );
63  d->faviconsDir.truncate(d->faviconsDir.length()-9); // Strip off "favicons/"
64  d->metaData.insert("ssl_no_client_cert", "TRUE");
65  d->metaData.insert("ssl_militant", "TRUE");
66  d->metaData.insert("UseCache", "false");
67  d->metaData.insert("cookies", "none");
68  d->metaData.insert("no-auth", "true");
69  d->config = new KSimpleConfig(locateLocal("data", "konqueror/faviconrc"));
70  d->killJobs.setAutoDelete(true);
71  d->faviconsCache.setAutoDelete(true);
72 }
73 
74 FaviconsModule::~FaviconsModule()
75 {
76  delete d;
77 }
78 
79 TQString removeSlash(TQString result)
80 {
81  for (unsigned int i = result.length() - 1; i > 0; --i)
82  if (result[i] != '/')
83  {
84  result.truncate(i + 1);
85  break;
86  }
87 
88  return result;
89 }
90 
91 
92 TQString FaviconsModule::iconForURL(const KURL &url)
93 {
94  if (url.host().isEmpty())
95  return TQString::null;
96 
97  TQString icon;
98  TQString simplifiedURL = simplifyURL(url);
99 
100  TQString *iconURL = d->faviconsCache.find( removeSlash(simplifiedURL) );
101  if (iconURL)
102  icon = *iconURL;
103  else
104  icon = d->config->readEntry( removeSlash(simplifiedURL) );
105 
106  if (!icon.isEmpty())
107  icon = iconNameFromURL(KURL( icon ));
108  else
109  icon = url.host();
110 
111  icon = "favicons/" + icon;
112 
113  if (TQFile::exists(d->faviconsDir+icon+".png"))
114  return icon;
115 
116  return TQString::null;
117 }
118 
119 TQString FaviconsModule::simplifyURL(const KURL &url)
120 {
121  // splat any = in the URL so it can be safely used as a config key
122  TQString result = url.host() + url.path();
123  for (unsigned int i = 0; i < result.length(); ++i)
124  if (result[i] == '=')
125  result[i] = '_';
126  return result;
127 }
128 
129 TQString FaviconsModule::iconNameFromURL(const KURL &iconURL)
130 {
131  if (iconURL.path() == "/favicon.ico")
132  return iconURL.host();
133 
134  TQString result = simplifyURL(iconURL);
135  // splat / so it can be safely used as a file name
136  for (unsigned int i = 0; i < result.length(); ++i)
137  if (result[i] == '/')
138  result[i] = '_';
139 
140  TQString ext = result.right(4);
141  if (ext == ".ico" || ext == ".png" || ext == ".xpm")
142  result.remove(result.length() - 4, 4);
143 
144  return result;
145 }
146 
147 bool FaviconsModule::isIconOld(const TQString &icon)
148 {
149  struct stat st;
150  if (stat(TQFile::encodeName(icon), &st) != 0)
151  return true; // Trigger a new download on error
152 
153  return (time(0) - st.st_mtime) > 604800; // arbitrary value (one week)
154 }
155 
156 void FaviconsModule::setIconForURL(const KURL &url, const KURL &iconURL)
157 {
158  TQString simplifiedURL = simplifyURL(url);
159 
160  d->faviconsCache.insert(removeSlash(simplifiedURL), new TQString(iconURL.url()) );
161 
162  TQString iconName = "favicons/" + iconNameFromURL(iconURL);
163  TQString iconFile = d->faviconsDir + iconName + ".png";
164 
165  if (!isIconOld(iconFile)) {
166  emit iconChanged(false, simplifiedURL, iconName);
167  return;
168  }
169 
170  startDownload(simplifiedURL, false, iconURL);
171 }
172 
173 void FaviconsModule::downloadHostIcon(const KURL &url)
174 {
175  TQString iconFile = d->faviconsDir + "favicons/" + url.host() + ".png";
176  if (!isIconOld(iconFile))
177  return;
178 
179  startDownload(url.host(), true, KURL(url, "/favicon.ico"));
180 }
181 
182 void FaviconsModule::startDownload(const TQString &hostOrURL, bool isHost, const KURL &iconURL)
183 {
184  if (d->failedDownloads.contains(iconURL.url()))
185  return;
186 
187  TDEIO::Job *job = TDEIO::get(iconURL, false, false);
188  job->addMetaData(d->metaData);
189  connect(job, TQ_SIGNAL(data(TDEIO::Job *, const TQByteArray &)), TQ_SLOT(slotData(TDEIO::Job *, const TQByteArray &)));
190  connect(job, TQ_SIGNAL(result(TDEIO::Job *)), TQ_SLOT(slotResult(TDEIO::Job *)));
191  connect(job, TQ_SIGNAL(infoMessage(TDEIO::Job *, const TQString &)), TQ_SLOT(slotInfoMessage(TDEIO::Job *, const TQString &)));
192  FaviconsModulePrivate::DownloadInfo download;
193  download.hostOrURL = hostOrURL;
194  download.isHost = isHost;
195  d->downloads.insert(job, download);
196 }
197 
198 void FaviconsModule::slotData(TDEIO::Job *job, const TQByteArray &data)
199 {
200  FaviconsModulePrivate::DownloadInfo &download = d->downloads[job];
201  unsigned int oldSize = download.iconData.size();
202  if (oldSize > 0x10000)
203  {
204  d->killJobs.append(job);
205  TQTimer::singleShot(0, this, TQ_SLOT(slotKill()));
206  }
207  download.iconData.resize(oldSize + data.size());
208  memcpy(download.iconData.data() + oldSize, data.data(), data.size());
209 }
210 
211 void FaviconsModule::slotResult(TDEIO::Job *job)
212 {
213  FaviconsModulePrivate::DownloadInfo download = d->downloads[job];
214  d->downloads.remove(job);
215  KURL iconURL = static_cast<TDEIO::TransferJob *>(job)->url();
216  TQString iconName;
217  if (!job->error())
218  {
219  TQBuffer buffer(download.iconData);
220  buffer.open(IO_ReadOnly);
221  TQImageIO io;
222  io.setIODevice(&buffer);
223  io.setParameters("size=16");
224  // Check here too, the job might have had no error, but the downloaded
225  // file contains just a 404 message sent with a 200 status.
226  // microsoft.com does that... (malte)
227  if (io.read())
228  {
229  // Some sites have nasty 32x32 icons, according to the MS docs
230  // IE ignores them, well, we scale them, otherwise the location
231  // combo / menu will look quite ugly
232  if (io.image().width() != TDEIcon::SizeSmall || io.image().height() != TDEIcon::SizeSmall)
233  io.setImage(io.image().smoothScale(TDEIcon::SizeSmall, TDEIcon::SizeSmall));
234 
235  if (download.isHost)
236  iconName = download.hostOrURL;
237  else
238  iconName = iconNameFromURL(iconURL);
239 
240  iconName = "favicons/" + iconName;
241 
242  io.setIODevice(0);
243  io.setFileName(d->faviconsDir + iconName + ".png");
244  io.setFormat("PNG");
245  if (!io.write())
246  iconName = TQString::null;
247  else if (!download.isHost)
248  d->config->writeEntry( removeSlash(download.hostOrURL), iconURL.url());
249  }
250  }
251  if (iconName.isEmpty())
252  d->failedDownloads.append(iconURL.url());
253 
254  emit iconChanged(download.isHost, download.hostOrURL, iconName);
255 }
256 
257 void FaviconsModule::slotInfoMessage(TDEIO::Job *job, const TQString &msg)
258 {
259  emit infoMessage(static_cast<TDEIO::TransferJob *>( job )->url(), msg);
260 }
261 
262 void FaviconsModule::slotKill()
263 {
264  d->killJobs.clear();
265 }
266 
267 extern "C" {
268  KDE_EXPORT KDEDModule *create_favicons(const TQCString &obj)
269  {
270  KImageIO::registerFormats();
271  return new FaviconsModule(obj);
272  }
273 }
FaviconsModule
KDED Module to handle shortcut icons ("favicons") FaviconsModule implements a KDED Module that handle...
Definition: favicons.h:46
FaviconsModule::setIconForURL
ASYNC setIconForURL(const KURL &url, const KURL &iconURL)
Assiciates an icon with the given URL.
Definition: favicons.cpp:156
FaviconsModule::iconForURL
TQString iconForURL(const KURL &url)
Looks up an icon name for a given URL.
Definition: favicons.cpp:92
FaviconsModule::downloadHostIcon
ASYNC downloadHostIcon(const KURL &url)
Downloads the icon for a given host if it was not downloaded before or the download was too long ago.
Definition: favicons.cpp:173

libkonq

Skip menu "libkonq"
  • Main Page
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Class Members
  • Related Pages

libkonq

Skip menu "libkonq"
  • kate
  • libkonq
  • twin
  •   lib
Generated for libkonq by doxygen 1.9.1
This website is maintained by Timothy Pearson.