PageRenderTime 288ms CodeModel.GetById 70ms app.highlight 112ms RepoModel.GetById 61ms app.codeStats 0ms

/src/libtomahawk/database/DatabaseCommand_LogPlayback.cpp

http://github.com/tomahawk-player/tomahawk
C++ | 134 lines | 85 code | 28 blank | 21 comment | 23 complexity | 8b2c71aacf920e2892c79b7f0115a2a1 MD5 | raw file
  1/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
  2 *
  3 *   Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
  4 *   Copyright 2010-2011, Jeff Mitchell <jeff@tomahawk-player.org>
  5 *
  6 *   Tomahawk is free software: you can redistribute it and/or modify
  7 *   it under the terms of the GNU General Public License as published by
  8 *   the Free Software Foundation, either version 3 of the License, or
  9 *   (at your option) any later version.
 10 *
 11 *   Tomahawk is distributed in the hope that it will be useful,
 12 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 13 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 14 *   GNU General Public License for more details.
 15 *
 16 *   You should have received a copy of the GNU General Public License
 17 *   along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
 18 */
 19
 20#include "DatabaseCommand_LogPlayback.h"
 21
 22#include "collection/Collection.h"
 23#include "database/Database.h"
 24#include "network/Servent.h"
 25#include "utils/Logger.h"
 26
 27#include "DatabaseImpl.h"
 28#include "PlaylistEntry.h"
 29
 30#include <QDateTime>
 31#include <QSqlQuery>
 32
 33#define STARTED_THRESHOLD 600   // Don't advertise tracks older than X seconds as currently playing
 34#define FINISHED_THRESHOLD 10   // Don't store tracks played less than X seconds in the playback log
 35#define SUBMISSION_THRESHOLD 20 // Don't broadcast playback logs when a track was played less than X seconds
 36
 37using namespace Tomahawk;
 38
 39
 40void
 41DatabaseCommand_LogPlayback::postCommitHook()
 42{
 43    connect( this, SIGNAL( trackPlaying( Tomahawk::track_ptr, unsigned int ) ),
 44             source().data(), SLOT( onPlaybackStarted( Tomahawk::track_ptr, unsigned int ) ), Qt::QueuedConnection );
 45    connect( this, SIGNAL( trackPlayed( Tomahawk::track_ptr, Tomahawk::PlaybackLog ) ),
 46             source().data(), SLOT( onPlaybackFinished( Tomahawk::track_ptr, Tomahawk::PlaybackLog ) ), Qt::QueuedConnection );
 47
 48    track_ptr track = Track::get( m_artist, m_track, QString() );
 49    if ( !track )
 50        return;
 51
 52    if ( m_action == Finished )
 53    {
 54        PlaybackLog log;
 55        log.source = source();
 56        log.timestamp = m_playtime;
 57        log.secsPlayed = m_secsPlayed;
 58
 59        emit trackPlayed( track, log );
 60    }
 61    // if the play time is more than 10 minutes in the past, ignore
 62    else if ( m_action == Started && QDateTime::fromTime_t( playtime() ).secsTo( QDateTime::currentDateTime() ) < STARTED_THRESHOLD )
 63    {
 64        emit trackPlaying( track, m_trackDuration );
 65    }
 66
 67    if ( source()->isLocal() )
 68    {
 69        Servent::instance()->triggerDBSync();
 70    }
 71}
 72
 73
 74void
 75DatabaseCommand_LogPlayback::exec( DatabaseImpl* dbi )
 76{
 77    Q_ASSERT( !source().isNull() );
 78
 79    unsigned int pt = m_playtime;
 80    if ( m_playtime == 0 )
 81        m_playtime = QDateTime::currentDateTimeUtc().toTime_t();
 82
 83    if ( m_action != Finished )
 84        return;
 85    if ( m_secsPlayed < FINISHED_THRESHOLD && m_trackDuration > 0 )
 86        return;
 87    if ( m_artist.isEmpty() || m_track.isEmpty() )
 88        return;
 89
 90    QVariant srcid = source()->isLocal() ? QVariant( QVariant::Int ) : source()->id();
 91    TomahawkSqlQuery query = dbi->newquery();
 92
 93    if ( pt > 0 && source()->isLocal() )
 94    {
 95        query.prepare( QString( "SELECT * FROM playback_log WHERE source %1 AND playtime = %2" ).arg( srcid.isNull() ? "IS NULL" : srcid.toString() ).arg( m_playtime ) );
 96        query.exec();
 97        if ( query.next() )
 98        {
 99            tDebug() << "Ignoring dupe playback log for source" << srcid << "with timestamp" << m_playtime;
100            return;
101        }
102    }
103
104//    tDebug() << "Logging playback of" << m_artist << "-" << m_track << "for source" << srcid << "- timestamp:" << m_playtime;
105
106    query.prepare( "INSERT INTO playback_log(source, track, playtime, secs_played) VALUES (?, ?, ?, ?)" );
107    query.bindValue( 0, srcid );
108
109    // If there's no artist, because it's a resolver result with bad metadata for example, don't save it
110    int artid = dbi->artistId( m_artist, true );
111    if( artid < 1 )
112        return;
113
114    int trkid = dbi->trackId( artid, m_track, true );
115    if( trkid < 1 )
116        return;
117
118    query.bindValue( 1, trkid );
119    query.bindValue( 2, m_playtime );
120    query.bindValue( 3, m_secsPlayed );
121
122    query.exec();
123}
124
125
126bool
127DatabaseCommand_LogPlayback::localOnly() const
128{
129    if ( m_action == Finished )
130        return m_secsPlayed < SUBMISSION_THRESHOLD;
131
132    return false;
133}
134