Example2 - listtests.cpp showing listing of tracks, playlist and creating smart playlists

tests/listtests.cpp:
/***************************************************************************
 *   Copyright (C) 2006 by Michael Schulze   *
 *   mike.s@genion.de   *
 *                                                                         *
 *   This program 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 2 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 General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/


#include <stdio.h>
#include <qfile.h>
#include <qstringlist.h>

#include <qobject.h>

#include "listtests.h"

#include "ipod.h"



#define RECENTLYPLAYEDTITLE "KPOD:Recently Played"
#define RECENTLYSKIPPEDTITLE "KPOD:Recently Skipped"
#define RECENTLYADDEDTITLE "KPOD:Recently added"
#define FAVORITES "KPOD:Most Played"
#define NEVERPLAYEDBEFORETITLE "KPOD:Never Played Before"
#define HIGHESTRATEDLIST "KPOD:Highest Rated"

using namespace itunesdb;

/**
 * Creates a smart playlist with a rule for the matching the songs played in
 * the last 2 weeks and a limit for the 30 last played songs.
 */
void ListTests::createRecentlyPlayedList( ITunesDB& itunesdb ) {
    printf( "creating new smart playlist: %s\n", RECENTLYPLAYEDTITLE );

    // create a new playlist
    ITunesDBPlaylist * recentlyPlayed = itunesdb.createNewPlaylist( RECENTLYPLAYEDTITLE );

    recentlyPlayed->setSortOrder( Playlist::SORTORDER_TIME_PLAYED );

    // make it a smart playlist and get the ruleset
    SmartPlaylistRuleSet& ruleSet = recentlyPlayed->enableSmartPlaylist();

    // add the rule "last played in the last 2 weeks"
    ruleSet.addInTheLastRule( FIELD_LASTPLAYED, false, -2, IN_THE_LAST_WEEKS );

    // limit to the first 30 songs, sorted by last played date
    ruleSet.setLimits( LIMIT_SORT_LASTPLAYED, LIMIT_TYPE_SONGS, 30 );

    // match ANY rule (doesn't really matter since we only have one rule)
    ruleSet.setMatchAnyFlag( true );

    // enable live update (updates the playlist on the go)
    ruleSet.setLiveUpdateFlag( true );

    // finally add the playlist to the database
    if ( !itunesdb.addPlaylist( recentlyPlayed ) ) {
        delete recentlyPlayed;
    }
}

/**
 * Creates a smart playlist with a rule for the matching the songs played in
 * the last 2 weeks and a limit for the 30 last played songs.
 */
void ListTests::createRecentlySkippedList( ITunesDB& itunesdb ) {
    printf( "creating new smart playlist: %s\n", RECENTLYSKIPPEDTITLE );

    // create a new playlist
    ITunesDBPlaylist * recentlySkipped = itunesdb.createNewPlaylist( RECENTLYSKIPPEDTITLE );

    recentlySkipped->setSortOrder( Playlist::SORTORDER_TIME_PLAYED );

    // make it a smart playlist and get the ruleset
    SmartPlaylistRuleSet& ruleSet = recentlySkipped->enableSmartPlaylist();

    // add the rule "last played in the last 2 weeks"
    ruleSet.addInTheLastRule( FIELD_LAST_SKIPPED, false, -2, IN_THE_LAST_WEEKS );

    // limit to the first 30 songs, sorted by last played date
    ruleSet.setLimits( LIMIT_SORT_LASTPLAYED, LIMIT_TYPE_SONGS, 30 );

    // match ANY rule (doesn't really matter since we only have one rule)
    ruleSet.setMatchAnyFlag( true );

    // enable live update (updates the playlist on the go)
    ruleSet.setLiveUpdateFlag( true );

    // finally add the playlist to the database
    if ( !itunesdb.addPlaylist( recentlySkipped ) ) {
        delete recentlySkipped;
    }
}


/**
 * Creates a smart playlist for the 25 most often played tracks
 */
void ListTests::createTop25List( ITunesDB& itunesdb ) {
    printf( "creating new smart playlist: %s\n", FAVORITES );

    // create a new playlist
    ITunesDBPlaylist * favorites = itunesdb.createNewPlaylist( FAVORITES );

    // sort by playcount
    favorites->setSortOrder( ITunesDBPlaylist::SORTORDER_PLAYCOUNT );

    // make it a smart playlist and get the ruleset
    SmartPlaylistRuleSet& ruleSet = favorites->enableSmartPlaylist();

    // only tracks that were played at least once
    ruleSet.addUIntRule( itunesdb::FIELD_PLAYCOUNT, itunesdb::ACTION_GREATER_THAN, 0, 0 );

    // limit to the 25 most played songs
    ruleSet.setLimits( LIMIT_SORT_PLAYCOUNT, LIMIT_TYPE_SONGS, 25 );

    // enable live update (updates the playlist on the go)
    ruleSet.setLiveUpdateFlag( true );

    // finally add the playlist to the database
    if ( !itunesdb.addPlaylist( favorites ) ) {
        delete favorites;
    }

}


void ListTests::createNeverPlayedBeforeList( ITunesDB& itunesdb ) {
    printf( "creating new smart playlist: %s\n", NEVERPLAYEDBEFORETITLE );

    // create a new playlist
    ITunesDBPlaylist * neverplayed = itunesdb.createNewPlaylist( NEVERPLAYEDBEFORETITLE );

    neverplayed->setSortOrder( itunesdb::Playlist::SORTORDER_TIME_ADDED );

    SmartPlaylistRuleSet& ruleSet = neverplayed->enableSmartPlaylist();
    ruleSet.setMatchAnyFlag( false );
    ruleSet.addUIntRule( FIELD_LASTPLAYED, ACTION_IS_UINT, 0, 0 );
    ruleSet.addUIntRule( FIELD_LAST_SKIPPED, ACTION_IS_UINT, 0, 0 );
    ruleSet.setLimits( LIMIT_SORT_RECENTLYADDED, LIMIT_TYPE_SONGS, 50, true );
    ruleSet.setLiveUpdateFlag( true );

    if ( !itunesdb.addPlaylist( neverplayed ) ) {
        delete neverplayed;
    }
}


void ListTests::createHighestRated( ITunesDB& itunesdb ) {
    printf( "creating new smart playlist: %s\n", HIGHESTRATEDLIST );

    // create a new playlist
    ITunesDBPlaylist * highestrated = itunesdb.createNewPlaylist( HIGHESTRATEDLIST );

    highestrated->setSortOrder( itunesdb::Playlist::SORTORDER_RANDOM );

    SmartPlaylistRuleSet& ruleSet = highestrated->enableSmartPlaylist();
    ruleSet.setMatchAnyFlag( false );
    ruleSet.addUIntRule( itunesdb::FIELD_RATING, ACTION_IS_UINT, 100, 100 );
    ruleSet.setLiveUpdateFlag( true );

    if ( !itunesdb.addPlaylist( highestrated ) ) {
        delete highestrated;
    }
}


/**
 * Creates a playlist with the tracks added in the last 2 weeks
 */
void ListTests::createNewestAdditionsList( ITunesDB& itunesdb ) {
    printf( "creating new smart playlist: %s\n", RECENTLYADDEDTITLE );

    // create a new playlist
    ITunesDBPlaylist * recentlyAdded = itunesdb.createNewPlaylist( RECENTLYADDEDTITLE );

    // sort the playlist by artist
    recentlyAdded->setSortOrder( itunesdb::Playlist::SORTORDER_ARTIST );

    // make it smart and get a reference to the still empty ruleset
    SmartPlaylistRuleSet& ruleSet = recentlyAdded->enableSmartPlaylist();

    // add a rule matching all the tracks added in the last 2 weeks
    ruleSet.addInTheLastRule( FIELD_DATEADDED, false, -2, IN_THE_LAST_WEEKS );

    // enable live update
    ruleSet.setLiveUpdateFlag( true );

    // add the playlist to the database
    if ( !itunesdb.addPlaylist( recentlyAdded ) ) {
        delete recentlyAdded;
    }

}


/**
 * Prints the contents of a playlist in the desired order to stdout.
 */
void ListTests::printSortedBy( ITunesDBPlaylist& playlist, Playlist::Sortorder order ) {
    // save the old sort order
    Playlist::Sortorder origOrder = playlist.getSortOrder();
    // set the desired order
    playlist.setSortOrder( order );

    // iterate over the playlist
    Playlist::Iterator trackIter = playlist.getElements();
    while( trackIter.hasNext() ) {
        Track * track = playlist.getTrack( *trackIter.next() );

        if ( track ) {
            fprintf( stdout, "\t%s\t\t%d,%d\t\t%s\t\t%s\n",
                    track->getArtist().ascii(), track->getPlayCount(), track->getSkipCount(), track->getAlbum().ascii(), track->getTitle().ascii() );
        } else {
            // this only happens if the database is inconsistent
            // this will be fixed when saving back the database
            fprintf( stdout, "\ttrack not found\n" );
        }
    }

    // restore the original sort order
    playlist.setSortOrder( origOrder );
}


/**
 * prints out all the tracks grouped by artist and album
 */
void ListTests::printTracksByArtist( const ITunesDB& itunesdb ) {
    // get a list of all artist names
    QStringList artistlist;
    if( !itunesdb.getArtists( artistlist ) ) {
        printf("NO ARTISTS!!!!");
    }

    // iterate over the artist names
    for( QStringList::iterator artistiterator = artistlist.begin(); artistiterator!= artistlist.end(); ++artistiterator ) {
        // print out the artist
        printf("%s\n", (*artistiterator).ascii());


        // get a list of albums by the artist
        QStringList albums;
        if( ! itunesdb.getAlbumsByArtist( *artistiterator, albums ) ) {
            // doesn't happen
            printf("ARTIST NOT FOUND!!!");
        } else {
            QStringList::iterator albumiterator = albums.begin();
            for( ; albumiterator != albums.end(); ++albumiterator) {

                // get the tracks in the album
                TrackPtrList album;
                // get the album by artistname, albumname
                itunesdb.getAlbum( *artistiterator, *albumiterator, album );
                // sort by default sort order (track number)
                album.sort();

                // print out the albumname, number of tracks and if a track
                // of the album was played recently
                printf("\t%s (%d)%s\n", (*albumiterator).ascii(), album.count(), album.hasRecentlyPlayedTracks() ? " played recently" : "");

                // iterate over the tracks
                TrackPtrList::Iterator trackiterator = album.iterator();
                // ITunesDB::AlbumIterator trackiterator = itunesdb.getAlbum( *artistiterator, *albumiterator );
                while ( trackiterator.hasNext() ) {
                    itunesdb::Track * track = trackiterator.next();

                    QDateTime added;
                    added.setTime_t( track->getDateAdded(), Qt::UTC );

                    QDateTime played;
                    played.setTime_t( track->getLastPlayed(), Qt::UTC );

                    // print out number and title, last played date and
                    // the date the track was added to the database
                    printf("\t\t%d - %s - played %s, added %s\n",
                        track->getTrackNumber(), track->getTitle().ascii(),
                        played.toString().ascii(), added.toString().ascii() );
                }
            }
            printf("\tall Tracks ...\n");


            /******************************************************************
            *
            * list all the tracks by the given artist, regardless of the album
            *
            *****************************************************************/

            // list all the tracks by the artist
            TrackPtrList artisttracks;
            // get all the tracks by the given artistname
            itunesdb.getTracksByArtist( *artistiterator, artisttracks );

            // sort the tracks by album
            artisttracks.setComparator( TrackComparators::BY_ALBUM );
            artisttracks.sort();

            TrackPtrList::Iterator trackiterator = artisttracks.iterator();
            while ( trackiterator.hasNext() ) {
                itunesdb::Track * track = trackiterator.next();
                printf("\t\t%s - %d - %s\n", track->getAlbum().ascii(), track->getTrackNumber(), track->getTitle().ascii());
            }
        }
    }
}

/**
 * Print out all the playlists.
 */
void ListTests::printPlaylists( const ITunesDB& itunesdb ) {

    // get all the playlist titles
    QStringList playlistTitles;
    itunesdb.getPlaylistTitles( playlistTitles );

    fprintf( stdout, "PLAYLISTS\n" );

    // iterate over all the playlists
    for ( unsigned int i = 0; i < playlistTitles.count(); ++i ) {
        ITunesDBPlaylist * playlist = itunesdb.getPlaylistByTitle( playlistTitles[ i ] );

        if ( playlist ) {   // would be weird if not, but who knows
            if ( playlist->isSmartPlaylist() ) {
                // print out the ruleset
                fprintf( stdout, "%s\n", playlist->getSmartPlaylistRules()->toString().ascii() );

                // forced update of the playlists entries
                playlist->updateSmartPlaylist( true );
            }

            fprintf( stdout, "%s (%d) - original order\n", playlist->getTitle().ascii(), playlist->getNumTracks() );
            printSortedBy( *playlist, playlist->getSortOrder() );

            fprintf( stdout, "%s - ordered by title\n", playlist->getTitle().ascii() );
            printSortedBy( *playlist, Playlist::SORTORDER_TITLE );

            fprintf( stdout, "%s - ordered by artist\n", playlist->getTitle().ascii() );
            printSortedBy( *playlist, Playlist::SORTORDER_ARTIST );

            fprintf( stdout, "%s - randomly\n", playlist->getTitle().ascii() );
            printSortedBy( *playlist, Playlist::SORTORDER_RANDOM );

            fprintf( stdout, "%s - ordered by time played\n", playlist->getTitle().ascii() );
            printSortedBy( *playlist, Playlist::SORTORDER_PLAYCOUNT );
        }
    }

    printf( "number of playlists: %u\n", itunesdb.getNumPlaylists() );
}


int ListTests::run( QStringList arguments ) {
    IPod * ipod = findFirstIPod();
    if ( !ipod ) {
        return -1;
    }

    // get the iTunesDB instance
    ITunesDB& itunesdb = ipod->getITunesDB();

    // print out all the tracks
    printTracksByArtist( itunesdb );

    // test smart playlist stuff

    ITunesDBPlaylist * spl = itunesdb.getPlaylistByTitle( RECENTLYPLAYEDTITLE );
    if ( spl == NULL ) {
        createRecentlyPlayedList( itunesdb );
    }

    spl = itunesdb.getPlaylistByTitle( FAVORITES );
    if ( spl == NULL ) {
        createTop25List( itunesdb );
    }

    spl = itunesdb.getPlaylistByTitle( NEVERPLAYEDBEFORETITLE );
    if ( spl == NULL ) {
        createNeverPlayedBeforeList( itunesdb );
    }

    spl = itunesdb.getPlaylistByTitle( RECENTLYADDEDTITLE );
    if ( spl == NULL ) {
        createNewestAdditionsList( itunesdb );
    }

    spl = itunesdb.getPlaylistByTitle( RECENTLYSKIPPEDTITLE );
    if ( spl == NULL ) {
        createRecentlySkippedList( itunesdb );
    }

    spl = itunesdb.getPlaylistByTitle( HIGHESTRATEDLIST );
    if ( spl == NULL ) {
        createHighestRated( itunesdb );
    }

    printPlaylists( itunesdb );

    printf( "%s is %s\n", ipod->getName().ascii(), ipod->isDirty() ? "dirty" : "clean" );

    // try to write
#ifdef WIN32
    ipod->getITunesDB().writeDatabase( "c:/iTunesDB" );
#else
    ipod->getITunesDB().writeDatabase( "/tmp/iTunesDB" );
#endif
    printf("closing ipod instance\n");
    ipod->close();
    delete ipod;

    return 0;
}

QString ListTests::getName() {
    return "list";
}



Generated on Wed Nov 28 02:33:57 2007 for libqtpod by  doxygen 1.5.0