29 #include <kdatastream.h>
30 #include <kicontheme.h>
32 #include <ksimpleconfig.h>
33 #include <kstandarddirs.h>
34 #include <tdeio/job.h>
36 #include "favicons.moc"
38 struct FaviconsModulePrivate
40 virtual ~FaviconsModulePrivate() {
delete config; }
48 TQMap<TDEIO::Job *, DownloadInfo> downloads;
49 TQStringList failedDownloads;
50 KSimpleConfig *config;
51 TQPtrList<TDEIO::Job> killJobs;
52 TDEIO::MetaData metaData;
54 TQCache<TQString> faviconsCache;
57 FaviconsModule::FaviconsModule(
const TQCString &obj)
61 d =
new FaviconsModulePrivate;
62 d->faviconsDir = TDEGlobal::dirs()->saveLocation(
"cache",
"favicons/" );
63 d->faviconsDir.truncate(d->faviconsDir.length()-9);
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);
74 FaviconsModule::~FaviconsModule()
79 TQString removeSlash(TQString result)
81 for (
unsigned int i = result.length() - 1; i > 0; --i)
84 result.truncate(i + 1);
94 if (url.host().isEmpty())
95 return TQString::null;
98 TQString simplifiedURL = simplifyURL(url);
100 TQString *iconURL = d->faviconsCache.find( removeSlash(simplifiedURL) );
104 icon = d->config->readEntry( removeSlash(simplifiedURL) );
107 icon = iconNameFromURL(KURL( icon ));
111 icon =
"favicons/" + icon;
113 if (TQFile::exists(d->faviconsDir+icon+
".png"))
116 return TQString::null;
119 TQString FaviconsModule::simplifyURL(
const KURL &url)
122 TQString result = url.host() + url.path();
123 for (
unsigned int i = 0; i < result.length(); ++i)
124 if (result[i] ==
'=')
129 TQString FaviconsModule::iconNameFromURL(
const KURL &iconURL)
131 if (iconURL.path() ==
"/favicon.ico")
132 return iconURL.host();
134 TQString result = simplifyURL(iconURL);
136 for (
unsigned int i = 0; i < result.length(); ++i)
137 if (result[i] ==
'/')
140 TQString ext = result.right(4);
141 if (ext ==
".ico" || ext ==
".png" || ext ==
".xpm")
142 result.remove(result.length() - 4, 4);
147 bool FaviconsModule::isIconOld(
const TQString &icon)
150 if (stat(TQFile::encodeName(icon), &st) != 0)
153 return (time(0) - st.st_mtime) > 604800;
158 TQString simplifiedURL = simplifyURL(url);
160 d->faviconsCache.insert(removeSlash(simplifiedURL),
new TQString(iconURL.url()) );
162 TQString iconName =
"favicons/" + iconNameFromURL(iconURL);
163 TQString iconFile = d->faviconsDir + iconName +
".png";
165 if (!isIconOld(iconFile)) {
166 emit iconChanged(
false, simplifiedURL, iconName);
170 startDownload(simplifiedURL,
false, iconURL);
175 TQString iconFile = d->faviconsDir +
"favicons/" + url.host() +
".png";
176 if (!isIconOld(iconFile))
179 startDownload(url.host(),
true, KURL(url,
"/favicon.ico"));
182 void FaviconsModule::startDownload(
const TQString &hostOrURL,
bool isHost,
const KURL &iconURL)
184 if (d->failedDownloads.contains(iconURL.url()))
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);
198 void FaviconsModule::slotData(TDEIO::Job *job,
const TQByteArray &data)
200 FaviconsModulePrivate::DownloadInfo &download = d->downloads[job];
201 unsigned int oldSize = download.iconData.size();
202 if (oldSize > 0x10000)
204 d->killJobs.append(job);
205 TQTimer::singleShot(0,
this, TQ_SLOT(slotKill()));
207 download.iconData.resize(oldSize + data.size());
208 memcpy(download.iconData.data() + oldSize, data.data(), data.size());
211 void FaviconsModule::slotResult(TDEIO::Job *job)
213 FaviconsModulePrivate::DownloadInfo download = d->downloads[job];
214 d->downloads.remove(job);
215 KURL iconURL =
static_cast<TDEIO::TransferJob *
>(job)->url();
219 TQBuffer buffer(download.iconData);
220 buffer.open(IO_ReadOnly);
222 io.setIODevice(&buffer);
223 io.setParameters(
"size=16");
232 if (io.image().width() != TDEIcon::SizeSmall || io.image().height() != TDEIcon::SizeSmall)
233 io.setImage(io.image().smoothScale(TDEIcon::SizeSmall, TDEIcon::SizeSmall));
236 iconName = download.hostOrURL;
238 iconName = iconNameFromURL(iconURL);
240 iconName =
"favicons/" + iconName;
243 io.setFileName(d->faviconsDir + iconName +
".png");
246 iconName = TQString::null;
247 else if (!download.isHost)
248 d->config->writeEntry( removeSlash(download.hostOrURL), iconURL.url());
251 if (iconName.isEmpty())
252 d->failedDownloads.append(iconURL.url());
254 emit iconChanged(download.isHost, download.hostOrURL, iconName);
257 void FaviconsModule::slotInfoMessage(TDEIO::Job *job,
const TQString &msg)
259 emit infoMessage(
static_cast<TDEIO::TransferJob *
>( job )->url(), msg);
262 void FaviconsModule::slotKill()
268 TDE_EXPORT KDEDModule *create_favicons(
const TQCString &obj)
270 KImageIO::registerFormats();
KDED Module to handle shortcut icons ("favicons") FaviconsModule implements a KDED Module that handle...
ASYNC setIconForURL(const KURL &url, const KURL &iconURL)
Assiciates an icon with the given URL.
TQString iconForURL(const KURL &url)
Looks up an icon name for a given URL.
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.