Commit e61b302d authored by Hugo Beauzée-Luyssen's avatar Hugo Beauzée-Luyssen

Rework stream history

It's now using the regular Media table & requests
parent 8575a814
...@@ -26,7 +26,6 @@ libmedialibrary_la_HEADERS = \ ...@@ -26,7 +26,6 @@ libmedialibrary_la_HEADERS = \
include/medialibrary/IAudioTrack.h \ include/medialibrary/IAudioTrack.h \
include/medialibrary/IFile.h \ include/medialibrary/IFile.h \
include/medialibrary/IGenre.h \ include/medialibrary/IGenre.h \
include/medialibrary/IHistoryEntry.h \
include/medialibrary/ILabel.h \ include/medialibrary/ILabel.h \
include/medialibrary/ILogger.h \ include/medialibrary/ILogger.h \
include/medialibrary/IMedia.h \ include/medialibrary/IMedia.h \
...@@ -68,7 +67,6 @@ libmedialibrary_la_SOURCES = \ ...@@ -68,7 +67,6 @@ libmedialibrary_la_SOURCES = \
src/File.cpp \ src/File.cpp \
src/Folder.cpp \ src/Folder.cpp \
src/Genre.cpp \ src/Genre.cpp \
src/History.cpp \
src/Label.cpp \ src/Label.cpp \
src/Media.cpp \ src/Media.cpp \
src/MediaLibrary.cpp \ src/MediaLibrary.cpp \
...@@ -140,7 +138,6 @@ noinst_HEADERS = \ ...@@ -140,7 +138,6 @@ noinst_HEADERS = \
src/filesystem/win32/File.h \ src/filesystem/win32/File.h \
src/Folder.h \ src/Folder.h \
src/Genre.h \ src/Genre.h \
src/History.h \
src/Label.h \ src/Label.h \
src/logging/IostreamLogger.h \ src/logging/IostreamLogger.h \
src/logging/Logger.h \ src/logging/Logger.h \
...@@ -293,7 +290,6 @@ unittest_SOURCES = \ ...@@ -293,7 +290,6 @@ unittest_SOURCES = \
test/unittest/FsUtilsTests.cpp \ test/unittest/FsUtilsTests.cpp \
test/unittest/UrlTests.cpp \ test/unittest/UrlTests.cpp \
test/unittest/GenreTests.cpp \ test/unittest/GenreTests.cpp \
test/unittest/HistoryTests.cpp \
test/unittest/LabelTests.cpp \ test/unittest/LabelTests.cpp \
test/unittest/MediaTests.cpp \ test/unittest/MediaTests.cpp \
test/unittest/MovieTests.cpp \ test/unittest/MovieTests.cpp \
......
/*****************************************************************************
* Media Library
*****************************************************************************
* Copyright (C) 2015 Hugo Beauzée-Luyssen, Videolabs
*
* Authors: Hugo Beauzée-Luyssen<hugo@beauzee.fr>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#pragma once
#include <string>
#include "medialibrary/Types.h"
namespace medialibrary
{
class IHistoryEntry
{
public:
virtual ~IHistoryEntry() = default;
virtual MediaPtr media() const = 0;
virtual unsigned int insertionDate() const = 0;
};
}
...@@ -311,9 +311,8 @@ class IMediaLibrary ...@@ -311,9 +311,8 @@ class IMediaLibrary
/** /**
* History * History
*/ */
virtual bool addToStreamHistory( MediaPtr media ) = 0; virtual Query<IMedia> history() const = 0;
virtual Query<IHistoryEntry> lastStreamsPlayed() const = 0; virtual Query<IMedia> streamHistory() const = 0;
virtual Query<IMedia> lastMediaPlayed() const = 0;
/** /**
* @brief clearHistory will clear both streams history & media history. * @brief clearHistory will clear both streams history & media history.
* @return true in case of success, false otherwise. The database will stay untouched in case * @return true in case of success, false otherwise. The database will stay untouched in case
......
...@@ -32,7 +32,6 @@ class IAlbumTrack; ...@@ -32,7 +32,6 @@ class IAlbumTrack;
class IAudioTrack; class IAudioTrack;
class IFile; class IFile;
class IGenre; class IGenre;
class IHistoryEntry;
class IMedia; class IMedia;
class ILabel; class ILabel;
class IMetadataService; class IMetadataService;
...@@ -64,7 +63,6 @@ using ArtistPtr = std::shared_ptr<IArtist>; ...@@ -64,7 +63,6 @@ using ArtistPtr = std::shared_ptr<IArtist>;
using AudioTrackPtr = std::shared_ptr<IAudioTrack>; using AudioTrackPtr = std::shared_ptr<IAudioTrack>;
using FilePtr = std::shared_ptr<IFile>; using FilePtr = std::shared_ptr<IFile>;
using GenrePtr = std::shared_ptr<IGenre>; using GenrePtr = std::shared_ptr<IGenre>;
using HistoryPtr = std::shared_ptr<IHistoryEntry>;
using LabelPtr = std::shared_ptr<ILabel>; using LabelPtr = std::shared_ptr<ILabel>;
using MediaPtr = std::shared_ptr<IMedia>; using MediaPtr = std::shared_ptr<IMedia>;
using MoviePtr = std::shared_ptr<IMovie>; using MoviePtr = std::shared_ptr<IMovie>;
......
/*****************************************************************************
* Media Library
*****************************************************************************
* Copyright (C) 2015 Hugo Beauzée-Luyssen, Videolabs
*
* Authors: Hugo Beauzée-Luyssen<hugo@beauzee.fr>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include "History.h"
#include "Media.h"
#include "database/SqliteTools.h"
#include "database/SqliteQuery.h"
namespace medialibrary
{
namespace policy
{
const std::string HistoryTable::Name = "History";
const std::string HistoryTable::PrimaryKeyColumn = "id_media";
int64_t History::* const HistoryTable::PrimaryKey = &History::m_mediaId;
}
constexpr unsigned int History::MaxEntries;
History::History( MediaLibraryPtr ml, sqlite::Row& row )
: m_media( Media::load( ml, row ) )
{
// In case we load the media from cache, we won't advance in columns
row.advanceToColumn( row.nbColumns() - 1 );
row >> m_date;
}
void History::createTable( sqlite::Connection* dbConnection )
{
const std::string req = "CREATE TABLE IF NOT EXISTS " + policy::HistoryTable::Name +
"("
"id_media INTEGER PRIMARY KEY,"
"insertion_date UNSIGNED INT NOT NULL,"
"FOREIGN KEY (id_media) REFERENCES " + policy::MediaTable::Name +
"(id_media) ON DELETE CASCADE"
")";
// Don't index the id_media field, we don't want to select history records using the media_id
sqlite::Tools::executeRequest( dbConnection, req );
}
void History::createTriggers(sqlite::Connection* dbConnection)
{
const std::string triggerReq = "CREATE TRIGGER IF NOT EXISTS limit_nb_records AFTER INSERT ON "
+ policy::HistoryTable::Name +
" BEGIN "
"DELETE FROM " + policy::HistoryTable::Name + " WHERE id_media in "
"(SELECT id_media FROM " + policy::HistoryTable::Name +
" ORDER BY insertion_date DESC LIMIT -1 OFFSET " + std::to_string( MaxEntries ) + ");"
" END";
sqlite::Tools::executeRequest( dbConnection, triggerReq );
}
bool History::insert( sqlite::Connection* dbConn, int64_t mediaId )
{
static const std::string req = "INSERT OR REPLACE INTO " + policy::HistoryTable::Name +
"(id_media, insertion_date) VALUES(?, strftime('%s', 'now'))";
return sqlite::Tools::executeInsert( dbConn, req, mediaId ) != 0;
}
Query<IHistoryEntry> History::fetch( MediaLibraryPtr ml )
{
static const std::string req = "FROM " + policy::MediaTable::Name + " f "
"INNER JOIN " + policy::HistoryTable::Name + " h ON h.id_media = f.id_media "
"ORDER BY h.insertion_date DESC";
return make_query<History, IHistoryEntry>( ml, "f.*, h.insertion_date", req );
}
void History::clearStreams( MediaLibraryPtr ml )
{
static const std::string req = "DELETE FROM " + policy::HistoryTable::Name;
sqlite::Tools::executeRequest( ml->getConn(), req );
}
MediaPtr History::media() const
{
return m_media;
}
unsigned int History::insertionDate() const
{
return m_date;
}
}
/*****************************************************************************
* Media Library
*****************************************************************************
* Copyright (C) 2015 Hugo Beauzée-Luyssen, Videolabs
*
* Authors: Hugo Beauzée-Luyssen<hugo@beauzee.fr>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#pragma once
#include "Types.h"
#include "database/DatabaseHelpers.h"
#include "medialibrary/IHistoryEntry.h"
#include <vector>
#include <string>
namespace medialibrary
{
class History;
class Media;
namespace policy
{
struct HistoryTable
{
static const std::string Name;
static const std::string PrimaryKeyColumn;
static int64_t History::* const PrimaryKey;
};
}
class History : public IHistoryEntry, public DatabaseHelpers<History, policy::HistoryTable, cachepolicy::Uncached<History>>
{
public:
History( MediaLibraryPtr ml, sqlite::Row& row );
static void createTable( sqlite::Connection* dbConnection );
static void createTriggers( sqlite::Connection* dbConnection );
static bool insert( sqlite::Connection* dbConn, int64_t mediaId );
static Query<IHistoryEntry> fetch( MediaLibraryPtr ml );
static void clearStreams( MediaLibraryPtr ml );
virtual MediaPtr media() const override;
virtual unsigned int insertionDate() const override;
static constexpr unsigned int MaxEntries = 20u;
private:
MediaPtr m_media;
int64_t m_mediaId;
unsigned int m_date;
friend policy::HistoryTable;
};
}
...@@ -732,16 +732,26 @@ Query<IMedia> Media::searchInPlaylist( MediaLibraryPtr ml, const std::string& pa ...@@ -732,16 +732,26 @@ Query<IMedia> Media::searchInPlaylist( MediaLibraryPtr ml, const std::string& pa
Query<IMedia> Media::fetchHistory( MediaLibraryPtr ml ) Query<IMedia> Media::fetchHistory( MediaLibraryPtr ml )
{ {
static const std::string req = "FROM " + policy::MediaTable::Name + " WHERE last_played_date IS NOT NULL" static const std::string req = "FROM " + policy::MediaTable::Name +
" WHERE last_played_date IS NOT NULL"
" AND type != ?"
" ORDER BY last_played_date DESC LIMIT 100"; " ORDER BY last_played_date DESC LIMIT 100";
return make_query<Media, IMedia>( ml, "*", req ); return make_query<Media, IMedia>( ml, "*", req, IMedia::Type::Stream );
}
Query<IMedia> Media::fetchStreamHistory(MediaLibraryPtr ml)
{
static const std::string req = "FROM " + policy::MediaTable::Name +
" WHERE last_played_date IS NOT NULL"
" AND type = ?"
" ORDER BY last_played_date DESC LIMIT 100";
return make_query<Media, IMedia>( ml, "*", req, IMedia::Type::Stream );
} }
void Media::clearHistory( MediaLibraryPtr ml ) void Media::clearHistory( MediaLibraryPtr ml )
{ {
auto dbConn = ml->getConn(); auto dbConn = ml->getConn();
// There should already be an active transaction, from MediaLibrary::clearHistory auto t = dbConn->newTransaction();
assert( sqlite::Transaction::transactionInProgress() == true );
static const std::string req = "UPDATE " + policy::MediaTable::Name + " SET " static const std::string req = "UPDATE " + policy::MediaTable::Name + " SET "
"play_count = 0," "play_count = 0,"
"last_played_date = NULL"; "last_played_date = NULL";
...@@ -753,6 +763,7 @@ void Media::clearHistory( MediaLibraryPtr ml ) ...@@ -753,6 +763,7 @@ void Media::clearHistory( MediaLibraryPtr ml )
static_cast<MDType>( IMedia::MetadataType::Progress ) ); static_cast<MDType>( IMedia::MetadataType::Progress ) );
sqlite::Tools::executeUpdate( dbConn, req ); sqlite::Tools::executeUpdate( dbConn, req );
t->commit();
} }
} }
...@@ -140,6 +140,7 @@ class Media : public IMedia, public DatabaseHelpers<Media, policy::MediaTable> ...@@ -140,6 +140,7 @@ class Media : public IMedia, public DatabaseHelpers<Media, policy::MediaTable>
static Query<IMedia> searchInPlaylist( MediaLibraryPtr ml, const std::string& pattern, static Query<IMedia> searchInPlaylist( MediaLibraryPtr ml, const std::string& pattern,
int64_t playlistId, const QueryParameters* params ); int64_t playlistId, const QueryParameters* params );
static Query<IMedia> fetchHistory( MediaLibraryPtr ml ); static Query<IMedia> fetchHistory( MediaLibraryPtr ml );
static Query<IMedia> fetchStreamHistory( MediaLibraryPtr ml );
static void clearHistory( MediaLibraryPtr ml ); static void clearHistory( MediaLibraryPtr ml );
......
...@@ -41,7 +41,6 @@ ...@@ -41,7 +41,6 @@
#include "File.h" #include "File.h"
#include "Folder.h" #include "Folder.h"
#include "Genre.h" #include "Genre.h"
#include "History.h"
#include "Media.h" #include "Media.h"
#include "MediaLibrary.h" #include "MediaLibrary.h"
#include "Label.h" #include "Label.h"
...@@ -138,7 +137,6 @@ void MediaLibrary::clearCache() ...@@ -138,7 +137,6 @@ void MediaLibrary::clearCache()
Device::clear(); Device::clear();
File::clear(); File::clear();
Playlist::clear(); Playlist::clear();
History::clear();
Genre::clear(); Genre::clear();
Thumbnail::clear(); Thumbnail::clear();
} }
...@@ -167,7 +165,6 @@ void MediaLibrary::createAllTables() ...@@ -167,7 +165,6 @@ void MediaLibrary::createAllTables()
AudioTrack::createTable( m_dbConnection.get() ); AudioTrack::createTable( m_dbConnection.get() );
Artist::createTable( m_dbConnection.get() ); Artist::createTable( m_dbConnection.get() );
Artist::createDefaultArtists( m_dbConnection.get() ); Artist::createDefaultArtists( m_dbConnection.get() );
History::createTable( m_dbConnection.get() );
Settings::createTable( m_dbConnection.get() ); Settings::createTable( m_dbConnection.get() );
parser::Task::createTable( m_dbConnection.get() ); parser::Task::createTable( m_dbConnection.get() );
Metadata::createTable( m_dbConnection.get() ); Metadata::createTable( m_dbConnection.get() );
...@@ -184,7 +181,6 @@ void MediaLibrary::createAllTriggers() ...@@ -184,7 +181,6 @@ void MediaLibrary::createAllTriggers()
File::createTriggers( m_dbConnection.get() ); File::createTriggers( m_dbConnection.get() );
Genre::createTriggers( m_dbConnection.get() ); Genre::createTriggers( m_dbConnection.get() );
Playlist::createTriggers( m_dbConnection.get() ); Playlist::createTriggers( m_dbConnection.get() );
History::createTriggers( m_dbConnection.get() );
Label::createTriggers( m_dbConnection.get() ); Label::createTriggers( m_dbConnection.get() );
Show::createTriggers( m_dbConnection.get() ); Show::createTriggers( m_dbConnection.get() );
} }
...@@ -675,27 +671,14 @@ bool MediaLibrary::deletePlaylist( int64_t playlistId ) ...@@ -675,27 +671,14 @@ bool MediaLibrary::deletePlaylist( int64_t playlistId )
} }
} }
bool MediaLibrary::addToStreamHistory( MediaPtr media ) Query<IMedia> MediaLibrary::history() const
{ {
try return Media::fetchHistory( this );
{
return History::insert( getConn(), media->id() );
}
catch ( const sqlite::errors::Generic& ex )
{
LOG_ERROR( "Failed to add stream to history: ", ex.what() );
return false;
}
}
Query<IHistoryEntry> MediaLibrary::lastStreamsPlayed() const
{
return History::fetch( this );
} }
Query<IMedia> MediaLibrary::lastMediaPlayed() const Query<IMedia> MediaLibrary::streamHistory() const
{ {
return Media::fetchHistory( this ); return Media::fetchStreamHistory( this );
} }
bool MediaLibrary::clearHistory() bool MediaLibrary::clearHistory()
...@@ -703,10 +686,7 @@ bool MediaLibrary::clearHistory() ...@@ -703,10 +686,7 @@ bool MediaLibrary::clearHistory()
try try
{ {
return sqlite::Tools::withRetries( 3, [this]() { return sqlite::Tools::withRetries( 3, [this]() {
auto t = getConn()->newTransaction();
Media::clearHistory( this ); Media::clearHistory( this );
History::clearStreams( this );
t->commit();
return true; return true;
}); });
} }
......
...@@ -113,9 +113,8 @@ class MediaLibrary : public IMediaLibrary, public IDeviceListerCb ...@@ -113,9 +113,8 @@ class MediaLibrary : public IMediaLibrary, public IDeviceListerCb
virtual PlaylistPtr playlist( int64_t id ) const override; virtual PlaylistPtr playlist( int64_t id ) const override;
virtual bool deletePlaylist( int64_t playlistId ) override; virtual bool deletePlaylist( int64_t playlistId ) override;
virtual bool addToStreamHistory( MediaPtr media ) override; virtual Query<IMedia> history() const override;
virtual Query<IHistoryEntry> lastStreamsPlayed() const override; virtual Query<IMedia> streamHistory() const override;
virtual Query<IMedia> lastMediaPlayed() const override;
virtual bool clearHistory() override; virtual bool clearHistory() override;
virtual Query<IMedia> searchMedia( const std::string& title, virtual Query<IMedia> searchMedia( const std::string& title,
......
/*****************************************************************************
* Media Library
*****************************************************************************
* Copyright (C) 2015 Hugo Beauzée-Luyssen, Videolabs
*
* Authors: Hugo Beauzée-Luyssen<hugo@beauzee.fr>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include "Tests.h"
#include "medialibrary/IHistoryEntry.h"
#include "History.h"
#include "Media.h"
#include "compat/Thread.h"
class HistoryTest : public Tests
{
};
TEST_F( HistoryTest, InsertMrl )
{
auto m = ml->addMedia( "upnp://stream" );
ml->addToStreamHistory( m );
auto hList = ml->lastStreamsPlayed()->all();
ASSERT_EQ( 1u, hList.size() );
auto h = hList[0];
ASSERT_EQ( h->media()->files()[0]->mrl(), "upnp://stream" );
ASSERT_NE( 0u, h->insertionDate() );
}
TEST_F( HistoryTest, MaxEntries )
{
for ( auto i = 0u; i < History::MaxEntries; ++i )
{
auto m = ml->addMedia( "http://media" + std::to_string( i ) );
ml->addToStreamHistory( m );
}
auto hList = ml->lastStreamsPlayed()->all();
ASSERT_EQ( History::MaxEntries, hList.size() );
auto m = ml->addMedia("smb://new-media" );
ml->addToStreamHistory( m );
hList = ml->lastStreamsPlayed()->all();
ASSERT_EQ( History::MaxEntries, hList.size() );
}
TEST_F( HistoryTest, Ordering )
{
auto m = ml->addMedia( "first-stream" );
ml->addToStreamHistory( m );
compat::this_thread::sleep_for( std::chrono::seconds( 1 ) );
auto m2 = ml->addMedia( "second-stream" );
ml->addToStreamHistory( m2 );
auto hList = ml->lastStreamsPlayed()->all();
ASSERT_EQ( 2u, hList.size() );
ASSERT_EQ( hList[0]->media()->id(), m2->id() );
ASSERT_EQ( hList[1]->media()->id(), m->id() );
}
TEST_F( HistoryTest, UpdateInsertionDate )
{
auto m = ml->addMedia( "stream" );
ml->addToStreamHistory( m );
auto hList = ml->lastStreamsPlayed()->all();
ASSERT_EQ( 1u, hList.size() );
auto date = hList[0]->insertionDate();
compat::this_thread::sleep_for( std::chrono::seconds( 1 ) );
ml->addToStreamHistory( m );
hList = ml->lastStreamsPlayed()->all();
ASSERT_EQ( 1u, hList.size() );
ASSERT_NE( date, hList[0]->insertionDate() );
}
TEST_F( HistoryTest, ClearStreamHistory )
{
auto m = ml->addMedia( "f00" );
ml->addToStreamHistory( m );
auto m2 = ml->addMedia( "bar" );
ml->addToStreamHistory( m2 );
auto history = ml->lastStreamsPlayed()->all();
ASSERT_EQ( 2u, history.size() );
ml->clearHistory();
history = ml->lastStreamsPlayed()->all();
ASSERT_EQ( 0u, history.size() );
Reload();
history = ml->lastStreamsPlayed()->all();
ASSERT_EQ( 0u, history.size() );
}
...@@ -330,12 +330,12 @@ TEST_F( Medias, History ) ...@@ -330,12 +330,12 @@ TEST_F( Medias, History )
{ {
auto m = std::static_pointer_cast<Media>( ml->addMedia( "media.mkv" ) ); auto m = std::static_pointer_cast<Media>( ml->addMedia( "media.mkv" ) );
auto history = ml->lastMediaPlayed()->all(); auto history = ml->history()->all();
ASSERT_EQ( 0u, history.size() ); ASSERT_EQ( 0u, history.size() );
m->increasePlayCount(); m->increasePlayCount();
m->save(); m->save();
history = ml->lastMediaPlayed()->all(); history = ml->history()->all();
ASSERT_EQ( 1u, history.size() ); ASSERT_EQ( 1u, history.size() );
ASSERT_EQ( m->id(), history[0]->id() ); ASSERT_EQ( m->id(), history[0]->id() );
...@@ -343,32 +343,49 @@ TEST_F( Medias, History ) ...@@ -343,32 +343,49 @@ TEST_F( Medias, History )
auto m2 = std::static_pointer_cast<Media>( ml->addMedia( "media2.mkv" ) ); auto m2 = std::static_pointer_cast<Media>( ml->addMedia( "media2.mkv" ) );
m2->increasePlayCount(); m2->increasePlayCount();
history = ml->lastMediaPlayed()->all(); history = ml->history()->all();
ASSERT_EQ( 2u, history.size() ); ASSERT_EQ( 2u, history.size() );
ASSERT_EQ( m2->id(), history[0]->id() ); ASSERT_EQ( m2->id(), history[0]->id() );
ASSERT_EQ( m->id(), history[1]->id() ); ASSERT_EQ( m->id(), history[1]->id() );
} }
TEST_F( Medias, StreamHistory )
{
auto m1 = std::static_pointer_cast<Media>( ml->addStream( "http://media.org/sample.mkv" ) );
auto m2 = std::static_pointer_cast<Media>( ml->addStream( "http://media.org/sample2.mkv" ) );
auto m3 = std::static_pointer_cast<Media>( ml->addMedia( "localfile.mkv" ) );
m1->increasePlayCount();
m2->increasePlayCount();
m3->increasePlayCount();
auto history = ml->streamHistory()->all();
ASSERT_EQ( 2u, history.size() );
history = ml->history()->all();
ASSERT_EQ( 1u, history.size() );
}
TEST_F( Medias, ClearHistory ) TEST_F( Medias, ClearHistory )
{ {
auto m = std::static_pointer_cast<Media>( ml->addMedia( "media.mkv" ) ); auto m = std::static_pointer_cast<Media>( ml->addMedia( "media.mkv" ) );
auto history = ml->lastMediaPlayed()->all(); auto history = ml->history()->all();
ASSERT_EQ( 0u, history.size() ); ASSERT_EQ( 0u, history.size() );
m->increasePlayCount(); m->increasePlayCount();
m->save(); m->save();
history = ml->lastMediaPlayed()->all(); history = ml->history()->all();
ASSERT_EQ( 1u, history.size() ); ASSERT_EQ( 1u, history.size() );
ASSERT_TRUE( ml->clearHistory() ); ASSERT_TRUE( ml->clearHistory() );
history = ml->lastMediaPlayed()->all(); history = ml->history()->all();
ASSERT_EQ( 0u, history.size() ); ASSERT_EQ( 0u, history.size() );
Reload(); Reload();
history = ml->lastMediaPlayed()->all(); history = ml->history()->all();
ASSERT_EQ( 0u, history.size() ); ASSERT_EQ( 0u, history.size() );
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment