From 08fa4bacd1450ef11e57319e664a154a3d842b4c Mon Sep 17 00:00:00 2001 From: Casey Link Date: Thu, 12 Apr 2012 16:24:29 -0500 Subject: [PATCH] New TomahawkCache utility class. A simple, generic cache utility that various bits and bobs can use. --- src/libtomahawk/CMakeLists.txt | 1 + src/libtomahawk/utils/tomahawkcache.cpp | 140 ++++++++++++++++++++++++ src/libtomahawk/utils/tomahawkcache.h | 72 ++++++++++++ src/tomahawkapp.cpp | 7 +- 4 files changed, 219 insertions(+), 1 deletion(-) create mode 100644 src/libtomahawk/utils/tomahawkcache.cpp create mode 100644 src/libtomahawk/utils/tomahawkcache.h diff --git a/src/libtomahawk/CMakeLists.txt b/src/libtomahawk/CMakeLists.txt index e76a53f04..2a2716829 100644 --- a/src/libtomahawk/CMakeLists.txt +++ b/src/libtomahawk/CMakeLists.txt @@ -291,6 +291,7 @@ set( libSources utils/logger.cpp utils/qnr_iodevicestream.cpp utils/xspfloader.cpp + utils/tomahawkcache.cpp thirdparty/kdsingleapplicationguard/kdsingleapplicationguard.cpp thirdparty/kdsingleapplicationguard/kdsharedmemorylocker.cpp diff --git a/src/libtomahawk/utils/tomahawkcache.cpp b/src/libtomahawk/utils/tomahawkcache.cpp new file mode 100644 index 000000000..9859720c1 --- /dev/null +++ b/src/libtomahawk/utils/tomahawkcache.cpp @@ -0,0 +1,140 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2012, Casey Link + * + * Tomahawk is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Tomahawk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tomahawk. If not, see . + */ + +#include "tomahawkcache.h" + +#include "tomahawksettings.h" + +#include +#include + +using namespace TomahawkUtils; + +TomahawkCache*TomahawkCache::s_instance = 0; + +TomahawkCache* TomahawkCache::instance() +{ + if ( !s_instance ) + s_instance = new TomahawkCache(); + + return s_instance; +} + +TomahawkCache::TomahawkCache() + : QObject ( 0 ) + , m_cacheBaseDir ( TomahawkSettings::instance()->storageCacheLocation() + "/GenericCache/" ) + , m_cacheManifest ( m_cacheBaseDir + "cachemanifest.ini", QSettings::IniFormat ) +{ + m_pruneTimer.setInterval ( 300000 ); + m_pruneTimer.setSingleShot ( false ); + connect ( &m_pruneTimer, SIGNAL ( timeout() ), SLOT ( pruneTimerFired() ) ); + m_pruneTimer.start(); +} + +TomahawkCache::~TomahawkCache() +{ + +} + +void TomahawkCache::pruneTimerFired() +{ + qDebug() << Q_FUNC_INFO << "Pruning tomahawkcache"; + qlonglong currentMSecsSinceEpoch = QDateTime::currentMSecsSinceEpoch(); + + QVariantList clients = m_cacheManifest.value ( "clients" ).toList(); + foreach ( const QVariant &client, clients ) { + const QString client_identifier = client.toString(); + const QString cache_dir = m_cacheBaseDir + client_identifier; + + QSettings cached_settings ( cache_dir, QSettings::IniFormat ); + const QStringList keys = cached_settings.allKeys(); + foreach ( const QString &key, keys ) { + CacheData data = cached_settings.value ( key ).value(); + if ( data.maxAge < currentMSecsSinceEpoch ) { + cached_settings.remove ( key ); + tLog() << Q_FUNC_INFO << "Removed stale entry: " << client_identifier << key; + } + } + cached_settings.sync(); + if ( cached_settings.allKeys().size() == 0 ) + removeClient ( client_identifier ); + } +} + + +QVariant TomahawkCache::getData ( const QString& identifier, const QString& key ) +{ + const QString cacheDir = m_cacheBaseDir + identifier; + QSettings cached_settings ( cacheDir, QSettings::IniFormat ); + + if ( cached_settings.contains ( key ) ) { + CacheData data = cached_settings.value ( key ).value(); + + if ( data.maxAge < QDateTime::currentMSecsSinceEpoch() ) { + cached_settings.remove ( key ); + tLog() << Q_FUNC_INFO << "Removed stale entry: " << identifier << key; + return QVariant(); + } + return data.data; + + } + return QVariant(); +} + +void TomahawkCache::putData ( const QString& identifier, qint64 maxAge, const QString& key, const QVariant& value ) +{ + const QString cacheDir = m_cacheBaseDir + identifier; + addClient ( identifier ); + QSettings cached_settings ( cacheDir, QSettings::IniFormat ); + cached_settings.setValue ( key, QVariant::fromValue ( CacheData ( maxAge, value ) ) ); +} + +void TomahawkCache::addClient ( const QString& identifier ) +{ + QVariantList clients = m_cacheManifest.value ( "clients" ).toList(); + foreach ( const QVariant &client, clients ) { + const QString client_identifier = client.toString(); + if ( identifier == client_identifier ) return; + } + + tLog() << Q_FUNC_INFO << "adding client" << identifier; + clients.append ( identifier ); + m_cacheManifest.setValue ( "clients", clients ); + m_cacheManifest.sync(); +} + +void TomahawkCache::removeClient ( const QString& identifier ) +{ + QVariantList clients = m_cacheManifest.value ( "clients" ).toList(); + QVariantList::iterator it = clients.begin(); + while ( it != clients.end() ) { + const QString client_identifier = it->toString(); + if ( identifier == client_identifier ) { + tLog() << Q_FUNC_INFO << "removing client" << identifier; + clients.erase ( it ); + break; + } + ++it; + } + m_cacheManifest.setValue ( "clients", clients ); + m_cacheManifest.sync(); +} + + + + diff --git a/src/libtomahawk/utils/tomahawkcache.h b/src/libtomahawk/utils/tomahawkcache.h new file mode 100644 index 000000000..175fb2e4f --- /dev/null +++ b/src/libtomahawk/utils/tomahawkcache.h @@ -0,0 +1,72 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2012, Casey Link + * + * Tomahawk is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Tomahawk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tomahawk. If not, see . + */ + +#ifndef TOMAHAWKCACHE_H +#define TOMAHAWKCACHE_H + +#include "dllmacro.h" +#include "utils/tomahawkutils.h" + +#include +#include +#include + +namespace TomahawkUtils { + +struct CacheData { + CacheData(){} + CacheData( qint64 maxAg, QVariant dat ) + : maxAge( maxAg ) + , data( dat ) + {} + + qint64 maxAge; + QVariant data; +}; + +class DLLEXPORT TomahawkCache : public QObject +{ +Q_OBJECT + +public: + static TomahawkCache* instance(); + virtual ~TomahawkCache(); + + void putData( const QString &identifier, qint64 maxAge, const QString &key, const QVariant& value ); + QVariant getData( const QString &identifier, const QString &key ); + +private slots: + void pruneTimerFired(); + +private: + TomahawkCache(); + static TomahawkCache* s_instance; + + void addClient( const QString &identifier ); + void removeClient( const QString &identifier ); + + QString m_cacheBaseDir; + QSettings m_cacheManifest; + QTimer m_pruneTimer; +}; + +} + +Q_DECLARE_METATYPE( TomahawkUtils::CacheData ); + +#endif // TOMAHAWKCACHE_H diff --git a/src/tomahawkapp.cpp b/src/tomahawkapp.cpp index 3d7d5b529..044395aae 100644 --- a/src/tomahawkapp.cpp +++ b/src/tomahawkapp.cpp @@ -62,6 +62,7 @@ #include "utils/jspfloader.h" #include "utils/logger.h" #include "utils/tomahawkutilsgui.h" +#include "utils/tomahawkcache.h" #include "config.h" @@ -228,7 +229,7 @@ TomahawkApp::init() tDebug() << "Init AccountManager."; m_accountManager = QWeakPointer< Tomahawk::Accounts::AccountManager >( new Tomahawk::Accounts::AccountManager( this ) ); connect( m_accountManager.data(), SIGNAL( ready() ), SLOT( accountManagerReady() ) ); - + Echonest::Config::instance()->setNetworkAccessManager( TomahawkUtils::nam() ); #ifndef ENABLE_HEADLESS EchonestGenerator::setupCatalogs(); @@ -318,6 +319,7 @@ TomahawkApp::~TomahawkApp() delete m_audioEngine.data(); delete Tomahawk::Accounts::AccountManager::instance(); + delete TomahawkUtils::TomahawkCache::instance(); #ifndef ENABLE_HEADLESS delete m_mainwindow; @@ -449,6 +451,9 @@ TomahawkApp::registerMetaTypes() qRegisterMetaType< QPersistentModelIndex >( "QPersistentModelIndex" ); qRegisterMetaType< Tomahawk::PlaylistInterface::LatchMode >( "Tomahawk::PlaylistInterface::LatchMode" ); + + qRegisterMetaType< TomahawkUtils::CacheData>( "TomahawkUtils::CacheData" ); + }