1
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
3
* Copyright 2012, Casey Link <unnamedrambler@gmail.com>
5
* Tomahawk is free software: you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation, either version 3 of the License, or
8
* (at your option) any later version.
10
* Tomahawk is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
19
#include "TomahawkCache.h"
21
#include "TomahawkSettings.h"
23
#include "utils/Logger.h"
27
#include <QMutexLocker>
29
using namespace TomahawkUtils;
31
Cache*Cache::s_instance = 0;
33
Cache* Cache::instance()
36
s_instance = new Cache();
43
, m_cacheBaseDir ( TomahawkSettings::instance()->storageCacheLocation() + "/GenericCache/" )
44
, m_cacheManifest ( m_cacheBaseDir + "cachemanifest.ini", QSettings::IniFormat )
46
m_pruneTimer.setInterval ( 300000 );
47
m_pruneTimer.setSingleShot ( false );
48
connect ( &m_pruneTimer, SIGNAL ( timeout() ), SLOT ( pruneTimerFired() ) );
57
void Cache::pruneTimerFired()
59
QMutexLocker mutex_locker( &m_mutex );
61
qDebug() << Q_FUNC_INFO << "Pruning tomahawkcache";
62
qlonglong currentMSecsSinceEpoch = QDateTime::currentMSecsSinceEpoch();
64
QVariantList clients = m_cacheManifest.value ( "clients" ).toList();
65
foreach ( const QVariant &client, clients ) {
66
const QString client_identifier = client.toString();
67
const QString cache_dir = m_cacheBaseDir + client_identifier;
69
QSettings cached_settings ( cache_dir, QSettings::IniFormat );
70
const QStringList keys = cached_settings.allKeys();
71
foreach ( const QString &key, keys ) {
72
CacheData data = cached_settings.value ( key ).value<TomahawkUtils::CacheData>();
73
if ( data.maxAge < currentMSecsSinceEpoch ) {
74
cached_settings.remove ( key );
75
tLog() << Q_FUNC_INFO << "Removed stale entry: " << client_identifier << key;
78
cached_settings.sync();
79
if ( cached_settings.allKeys().size() == 0 )
80
removeClient ( client_identifier );
85
QVariant Cache::getData ( const QString& identifier, const QString& key )
87
QMutexLocker mutex_locker( &m_mutex );
89
const QString cacheDir = m_cacheBaseDir + identifier;
90
QSettings cached_settings ( cacheDir, QSettings::IniFormat );
92
if ( cached_settings.contains ( key ) ) {
93
CacheData data = cached_settings.value ( key ).value<TomahawkUtils::CacheData>();
95
if ( data.maxAge < QDateTime::currentMSecsSinceEpoch() ) {
96
cached_settings.remove ( key );
97
tLog() << Q_FUNC_INFO << "Removed stale entry: " << identifier << key;
100
tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "Fetched data for" << identifier << key;
104
tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "No such key" << key;
108
void Cache::putData ( const QString& identifier, qint64 maxAge, const QString& key, const QVariant& value )
110
QMutexLocker mutex_locker( &m_mutex );
112
const QString cacheDir = m_cacheBaseDir + identifier;
113
addClient ( identifier );
114
QSettings cached_settings ( cacheDir, QSettings::IniFormat );
115
cached_settings.setValue ( key, QVariant::fromValue ( CacheData ( QDateTime::currentMSecsSinceEpoch() + maxAge, value ) ) );
116
tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "Storing from client " << identifier << maxAge << key << value;
119
void Cache::addClient ( const QString& identifier )
121
QVariantList clients = m_cacheManifest.value ( "clients" ).toList();
122
foreach ( const QVariant &client, clients ) {
123
const QString client_identifier = client.toString();
124
if ( identifier == client_identifier ) return;
127
tLog() << Q_FUNC_INFO << "adding client" << identifier;
128
clients.append ( identifier );
129
m_cacheManifest.setValue ( "clients", clients );
130
m_cacheManifest.sync();
133
void Cache::removeClient ( const QString& identifier )
135
QVariantList clients = m_cacheManifest.value ( "clients" ).toList();
136
QVariantList::iterator it = clients.begin();
137
while ( it != clients.end() ) {
138
const QString client_identifier = it->toString();
139
if ( identifier == client_identifier ) {
140
tLog() << Q_FUNC_INFO << "removing client" << identifier;
141
clients.erase ( it );
146
m_cacheManifest.setValue ( "clients", clients );
147
m_cacheManifest.sync();