• Skip to content
  • Skip to link menu
KDE 4.6 API Reference
  • KDE API Reference
  • kdelibs
  • KDE Home
  • Contact Us
 

KNewStuff

cache.cpp

Go to the documentation of this file.
00001 /*
00002     Copyright (c) 2009 Frederik Gladhorn <gladhorn@kde.org>
00003     Copyright (c) 2010 Matthias Fuchs <mat69@gmx.net>
00004 
00005     This library is free software; you can redistribute it and/or
00006     modify it under the terms of the GNU Lesser General Public
00007     License as published by the Free Software Foundation; either
00008     version 2.1 of the License, or (at your option) any later version.
00009 
00010     This library is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013     Lesser General Public License for more details.
00014 
00015     You should have received a copy of the GNU Lesser General Public
00016     License along with this library.  If not, see <http://www.gnu.org/licenses/>.
00017 */
00018 
00019 #include "cache.h"
00020 
00021 #include <QtCore/QFile>
00022 #include <QtCore/QDir>
00023 #include <QtCore/QFileInfo>
00024 #include <QtCore/QXmlStreamReader>
00025 #include <kstandarddirs.h>
00026 #include <kdebug.h>
00027 
00028 using namespace KNS3;
00029 
00030 typedef QHash<QString, QWeakPointer<Cache> > CacheHash;
00031 K_GLOBAL_STATIC(CacheHash, s_caches)
00032 
00033 Cache::Cache(const QString &appName): QObject(0)
00034 {
00035     m_kns2ComponentName = appName;
00036 
00037     registryFile = KStandardDirs::locateLocal("data", "knewstuff3/" + appName + ".knsregistry");
00038     kDebug() << "Using registry file: " << registryFile;
00039 }
00040 
00041 QSharedPointer<Cache> Cache::getCache(const QString &appName)
00042 {
00043     CacheHash::const_iterator it = s_caches->find(appName);
00044     if ((it != s_caches->end()) && !(*it).isNull()) {
00045         return QSharedPointer<Cache>(*it);
00046     }
00047 
00048     QSharedPointer<Cache> p(new Cache(appName));
00049     s_caches->insert(appName, QWeakPointer<Cache>(p));
00050 
00051     return p;
00052 }
00053 
00054 Cache::~Cache()
00055 {
00056 }
00057 
00058 void Cache::readRegistry()
00059 {
00060     // read KNS2 registry first to migrate it
00061     readKns2MetaFiles();
00062 
00063     QFile f(registryFile);
00064     if (!f.open(QIODevice::ReadOnly)) {
00065         kWarning() << "The file " << registryFile << " could not be opened.";
00066         return;
00067     }
00068 
00069     QDomDocument doc;
00070     if (!doc.setContent(&f)) {
00071         kWarning() << "The file could not be parsed.";
00072         return;
00073     }
00074 
00075     QDomElement root = doc.documentElement();
00076     if (root.tagName() != "hotnewstuffregistry") {
00077         kWarning() << "The file doesn't seem to be of interest.";
00078         return;
00079     }
00080 
00081     QDomElement stuff = root.firstChildElement("stuff");
00082     while (!stuff.isNull()) {
00083         EntryInternal e;
00084         e.setEntryXML(stuff);
00085         e.setSource(EntryInternal::Cache);
00086         cache.insert(e);
00087         stuff = stuff.nextSiblingElement("stuff");
00088     }
00089 
00090     kDebug() << "Cache read... entries: " << cache.size();
00091 }
00092 
00093 void Cache::readKns2MetaFiles()
00094 {
00095     KStandardDirs d;
00096     kDebug() << "Loading KNS2 registry of files for the component: " << m_kns2ComponentName;
00097 
00098     QString realAppName = m_kns2ComponentName.split(':')[0];
00099 
00100     const QStringList dirs = d.findDirs("data", "knewstuff2-entries.registry");
00101     for (QStringList::ConstIterator it = dirs.begin(); it != dirs.end(); ++it) {
00102         //kDebug() << " + Load from directory '" + (*it) + "'.";
00103         QDir dir((*it));
00104         const QStringList files = dir.entryList(QDir::Files | QDir::Readable);
00105         for (QStringList::const_iterator fit = files.begin(); fit != files.end(); ++fit) {
00106             QString filepath = (*it) + '/' + (*fit);
00107 
00108             kDebug() << " Load from file '" + filepath + "'.";
00109 
00110             QFileInfo info(filepath);
00111             QFile f(filepath);
00112 
00113             // first see if this file is even for this app
00114             // because the registry contains entries for all apps
00115             // FIXMEE: should be able to do this with a filter on the entryList above probably
00116             QString thisAppName = QString::fromUtf8(QByteArray::fromBase64(info.baseName().toUtf8()));
00117 
00118             // NOTE: the ":" needs to always coincide with the separator character used in
00119             // the id(Entry*) method
00120             thisAppName = thisAppName.split(':')[0];
00121 
00122             if (thisAppName != realAppName) {
00123                 continue;
00124             }
00125 
00126             if (!f.open(QIODevice::ReadOnly)) {
00127                 kWarning() << "The file: " << filepath << " could not be opened.";
00128                 continue;
00129             }
00130 
00131             QDomDocument doc;
00132             if (!doc.setContent(&f)) {
00133                 kWarning() << "The file could not be parsed.";
00134                 return;
00135             }
00136             kDebug() << "found entry: " << doc.toString();
00137 
00138             QDomElement root = doc.documentElement();
00139             if (root.tagName() != "ghnsinstall") {
00140                 kWarning() << "The file doesn't seem to be of interest.";
00141                 return;
00142             }
00143 
00144             // The .meta files only contain one entry
00145             QDomElement stuff = root.firstChildElement("stuff");
00146             EntryInternal e;
00147             e.setEntryXML(stuff);
00148             e.setSource(EntryInternal::Cache);
00149 
00150             if (e.payload().startsWith(QLatin1String("http://download.kde.org/khotnewstuff"))) {
00151                 // This is 99% sure a opendesktop file, make it a real one.
00152                 e.setProviderId(QLatin1String("https://api.opendesktop.org/v1/"));
00153                 e.setHomepage(QString(QLatin1String("http://opendesktop.org/content/show.php?content=") + e.uniqueId()));
00154 
00155             } else if (e.payload().startsWith(QLatin1String("http://edu.kde.org/contrib/kvtml/"))) {
00156                 // kvmtl-1
00157                 e.setProviderId("http://edu.kde.org/contrib/kvtml/kvtml.xml");
00158             } else if (e.payload().startsWith(QLatin1String("http://edu.kde.org/contrib/kvtml2/"))) {
00159                 // kvmtl-2
00160                 e.setProviderId("http://edu.kde.org/contrib/kvtml2/provider41.xml");
00161             } else {
00162                 // we failed, skip
00163                 kWarning() << "Could not load entry: " << filepath;
00164                 continue;
00165             }
00166 
00167             e.setStatus(Entry::Installed);
00168 
00169             cache.insert(e);
00170             QDomDocument tmp("yay");
00171             tmp.appendChild(e.entryXML());
00172             kDebug() << "new entry: " << tmp.toString();
00173 
00174             f.close();
00175 
00176             QDir dir;
00177             if (!dir.remove(filepath)) {
00178                 kWarning() << "could not delete old kns2 .meta file: " << filepath;
00179             } else {
00180                 kDebug() << "Migrated KNS2 entry to KNS3.";
00181             }
00182 
00183         }
00184     }
00185 }
00186 
00187 EntryInternal::List Cache::registryForProvider(const QString& providerId)
00188 {
00189     EntryInternal::List entries;
00190     foreach (const EntryInternal& e, cache) {
00191         if (e.providerId() == providerId) {
00192             entries.append(e);
00193         }
00194     }
00195     return entries;
00196 }
00197 
00198 
00199 void Cache::writeRegistry()
00200 {
00201     kDebug() << "Write registry";
00202 
00203     QFile f(registryFile);
00204     if (!f.open(QIODevice::WriteOnly | QIODevice::Text)) {
00205         kWarning() << "Cannot write meta information to '" << registryFile << "'." << endl;
00206         return;
00207     }
00208 
00209     QDomDocument doc("khotnewstuff3");
00210     doc.appendChild(doc.createProcessingInstruction( "xml", "version=\"1.0\" encoding=\"UTF-8\"" ));
00211     QDomElement root = doc.createElement("hotnewstuffregistry");
00212     doc.appendChild(root);
00213 
00214     foreach (const EntryInternal& entry, cache) {
00215         // Write the entry, unless the policy is CacheNever and the entry is not installed.
00216         if (entry.status() == Entry::Installed || entry.status() == Entry::Updateable) {
00217             QDomElement exml = entry.entryXML();
00218             root.appendChild(exml);
00219         }
00220     }
00221 
00222     QTextStream metastream(&f);
00223     metastream << doc.toByteArray();
00224     
00225     f.close();
00226 }
00227 
00228 void Cache::registerChangedEntry(const KNS3::EntryInternal& entry)
00229 {
00230     cache.insert(entry);
00231 }
00232 
00233 void Cache::insertRequest(const KNS3::Provider::SearchRequest& request, const KNS3::EntryInternal::List& entries)
00234 {
00235     // append new entries
00236     requestCache[request.hashForRequest()].append(entries);
00237     kDebug() << request.hashForRequest() << " add: " << entries.size() << " keys: " << requestCache.keys();
00238 }
00239 
00240 EntryInternal::List Cache::requestFromCache(const KNS3::Provider::SearchRequest& request)
00241 {
00242     kDebug() << request.hashForRequest();
00243     return requestCache.value(request.hashForRequest());
00244 }
00245 
00246 #include "cache.moc"

KNewStuff

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

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.7.3
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal