mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-08-01 03:40:16 +02:00
Add a penalty score to tracks with low playcount in the last weeks.
This commit is contained in:
@@ -22,6 +22,8 @@
|
|||||||
#include "database/TomahawkSqlQuery.h"
|
#include "database/TomahawkSqlQuery.h"
|
||||||
#include "Track.h"
|
#include "Track.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
namespace Tomahawk {
|
namespace Tomahawk {
|
||||||
|
|
||||||
DatabaseCommand_TrendingTracks::DatabaseCommand_TrendingTracks( QObject* parent )
|
DatabaseCommand_TrendingTracks::DatabaseCommand_TrendingTracks( QObject* parent )
|
||||||
@@ -39,7 +41,6 @@ void
|
|||||||
DatabaseCommand_TrendingTracks::exec( DatabaseImpl* dbi )
|
DatabaseCommand_TrendingTracks::exec( DatabaseImpl* dbi )
|
||||||
{
|
{
|
||||||
Q_D( DatabaseCommand_TrendingTracks );
|
Q_D( DatabaseCommand_TrendingTracks );
|
||||||
TomahawkSqlQuery query = dbi->newquery();
|
|
||||||
|
|
||||||
QString limit;
|
QString limit;
|
||||||
if ( d->amount > 0 )
|
if ( d->amount > 0 )
|
||||||
@@ -50,10 +51,28 @@ DatabaseCommand_TrendingTracks::exec( DatabaseImpl* dbi )
|
|||||||
QDateTime now = QDateTime::currentDateTime();
|
QDateTime now = QDateTime::currentDateTime();
|
||||||
QDateTime _1WeekAgo = now.addDays( -7 );
|
QDateTime _1WeekAgo = now.addDays( -7 );
|
||||||
QDateTime _2WeeksAgo = now.addDays( -14 );
|
QDateTime _2WeeksAgo = now.addDays( -14 );
|
||||||
QDateTime _3WeeksAgo = now.addDays( -21 );
|
|
||||||
|
|
||||||
// TODO:
|
uint peersLastWeek = 1; // Use a default of 1 to be able to do certain mathematical computations without Div-by-0 Errors.
|
||||||
// -> Look at absolute playcount, an increase from 1 to 4 plays per week is currently considered very high
|
{
|
||||||
|
// Get the number of active peers in the last week.
|
||||||
|
// We could just use the number of peers instead but that would include old peers that may have been inactive for a long while.
|
||||||
|
|
||||||
|
QString peersLastWeekSql = QString(
|
||||||
|
" SELECT COUNT(DISTINCT source ) "
|
||||||
|
" FROM playback_log "
|
||||||
|
" WHERE playback_log.source IS NOT NULL " // exclude self
|
||||||
|
" AND playback_log.playtime >= %1 "
|
||||||
|
).arg( _1WeekAgo.toTime_t() );
|
||||||
|
TomahawkSqlQuery query = dbi->newquery();
|
||||||
|
query.prepare( peersLastWeekSql );
|
||||||
|
query.exec();
|
||||||
|
while ( query.next() )
|
||||||
|
{
|
||||||
|
peersLastWeek = std::max( 1u, query.value( 0 ).toUInt() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
QString timespanSql = QString(
|
QString timespanSql = QString(
|
||||||
" SELECT COUNT(*) as counter, track "
|
" SELECT COUNT(*) as counter, track "
|
||||||
" FROM playback_log "
|
" FROM playback_log "
|
||||||
@@ -63,16 +82,20 @@ DatabaseCommand_TrendingTracks::exec( DatabaseImpl* dbi )
|
|||||||
);
|
);
|
||||||
QString lastWeekSql = timespanSql.arg( _1WeekAgo.toTime_t() ).arg( now.toTime_t() );
|
QString lastWeekSql = timespanSql.arg( _1WeekAgo.toTime_t() ).arg( now.toTime_t() );
|
||||||
QString _1BeforeLastWeekSql = timespanSql.arg( _2WeeksAgo.toTime_t() ).arg( _1WeekAgo.toTime_t() );
|
QString _1BeforeLastWeekSql = timespanSql.arg( _2WeeksAgo.toTime_t() ).arg( _1WeekAgo.toTime_t() );
|
||||||
QString _2BeforeLastWeekSql = timespanSql.arg( _3WeeksAgo.toTime_t() ).arg( _2WeeksAgo.toTime_t() );
|
QString formula = QString(
|
||||||
|
" ( lastweek.counter / weekbefore.counter ) "
|
||||||
|
" * "
|
||||||
|
" max(0, 1 - (%1 / (4*min(lastweek.counter, weekbefore.counter )) ) )"
|
||||||
|
).arg( peersLastWeek );
|
||||||
QString sql = QString(
|
QString sql = QString(
|
||||||
" SELECT track.name, artist.name, ( lastweek.counter - weekbefore.counter ) as slope1, max( weekbefore.counter - week2before.counter, 1 ) as slope2, ( ( lastweek.counter - weekbefore.counter ) / max( weekbefore.counter - week2before.counter, 1 ) ) as trending "
|
" SELECT track.name, artist.name, ( %4 ) as trending "
|
||||||
" FROM ( %1 ) lastweek, ( %2 ) weekbefore, ( %3 ) week2before, track, artist "
|
" FROM ( %1 ) lastweek, ( %2 ) weekbefore, track, artist "
|
||||||
" WHERE lastweek.track = weekbefore.track AND weekbefore.track = week2before.track "
|
" WHERE lastweek.track = weekbefore.track "
|
||||||
" AND track.id = lastweek.track AND artist.id = track.artist "
|
" AND track.id = lastweek.track AND artist.id = track.artist "
|
||||||
" AND ( lastweek.counter - weekbefore.counter ) > 0"
|
" AND ( lastweek.counter - weekbefore.counter ) > 0"
|
||||||
" ORDER BY slope1 DESC %4 "
|
" ORDER BY trending DESC %3 "
|
||||||
).arg( lastWeekSql ).arg( _1BeforeLastWeekSql ).arg( _2BeforeLastWeekSql ).arg( limit );
|
).arg( lastWeekSql ).arg( _1BeforeLastWeekSql ).arg( limit ).arg( formula );
|
||||||
|
TomahawkSqlQuery query = dbi->newquery();
|
||||||
query.prepare( sql );
|
query.prepare( sql );
|
||||||
query.exec();
|
query.exec();
|
||||||
|
|
||||||
@@ -85,7 +108,7 @@ DatabaseCommand_TrendingTracks::exec( DatabaseImpl* dbi )
|
|||||||
if ( !track )
|
if ( !track )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
tracks << QPair< double, track_ptr >( query.value( 4 ).toDouble(), track );
|
tracks << QPair< double, track_ptr >( query.value( 2 ).toDouble(), track );
|
||||||
}
|
}
|
||||||
|
|
||||||
emit done( tracks );
|
emit done( tracks );
|
||||||
|
@@ -29,7 +29,15 @@ class DatabaseCommand_TrendingTracksPrivate;
|
|||||||
* Find tracks that trend among your friends.
|
* Find tracks that trend among your friends.
|
||||||
*
|
*
|
||||||
* At the moment the most trending tracks are those with the highest quotient of
|
* At the moment the most trending tracks are those with the highest quotient of
|
||||||
* plays in the last week and the week before.
|
* plays in the last week and the week before with a penalty applied to those with
|
||||||
|
* a low playcount.
|
||||||
|
*
|
||||||
|
* The exact calculation is done as follows:
|
||||||
|
*
|
||||||
|
* w_1(t) := playcount this week of track t
|
||||||
|
* w_2(t) := playcount one week before of track t
|
||||||
|
* p := active peers (with at least one play) in the last week
|
||||||
|
* trending(track) = (w_1(t) / w_2(t)) * (1 - p / (4 * min(w_1(t), w_2(t))))
|
||||||
*/
|
*/
|
||||||
class DLLEXPORT DatabaseCommand_TrendingTracks : public Tomahawk::DatabaseCommand
|
class DLLEXPORT DatabaseCommand_TrendingTracks : public Tomahawk::DatabaseCommand
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user