Esempio n. 1
0
void AllMusic::resync()
{
    m_done_loading = false;

    QString aquery = "SELECT music_songs.song_id, music_artists.artist_name, music_comp_artists.artist_name AS compilation_artist, "
                     "music_albums.album_name, music_songs.name, music_genres.genre, music_songs.year, "
                     "music_songs.track, music_songs.length, CONCAT_WS('/', "
                     "music_directories.path, music_songs.filename) AS filename, "
                     "music_songs.rating, music_songs.numplays, music_songs.lastplay, music_albums.compilation, "
                     "music_songs.format "
                     "FROM music_songs "
                     "LEFT JOIN music_directories ON music_songs.directory_id=music_directories.directory_id "
                     "LEFT JOIN music_artists ON music_songs.artist_id=music_artists.artist_id "
                     "LEFT JOIN music_albums ON music_songs.album_id=music_albums.album_id "
                     "LEFT JOIN music_artists AS music_comp_artists ON music_albums.artist_id=music_comp_artists.artist_id "
                     "LEFT JOIN music_genres ON music_songs.genre_id=music_genres.genre_id "
                     "ORDER BY music_songs.song_id;";

    QString filename, artist, album, title, compartist;

    MSqlQuery query(MSqlQuery::InitCon());
    if (!query.exec(aquery))
        MythDB::DBError("AllMusic::resync", query);

    m_root_node->clear();
    m_all_music.clear();

    m_numPcs = query.size() * 2;
    m_numLoaded = 0;

    if (query.isActive() && query.size() > 0)
    {
        while (query.next())
        {
            filename = query.value(9).toString();
            if (!filename.contains("://"))
                filename = m_startdir + filename;

            Metadata *temp = new Metadata(
                filename,
                query.value(1).toString(),     // artist
                query.value(2).toString(),     // compilation artist
                query.value(3).toString(),     // album
                query.value(4).toString(),     // title
                query.value(5).toString(),     // genre
                query.value(6).toInt(),        // year
                query.value(7).toInt(),        // track no.
                query.value(8).toInt(),        // length
                query.value(0).toInt(),        // id
                query.value(10).toInt(),       // rating
                query.value(11).toInt(),       // playcount
                query.value(12).toDateTime(),  // lastplay
                (query.value(13).toInt() > 0), // compilation
                query.value(14).toString());   // format

            //  Don't delete temp, as PtrList now owns it
            m_all_music.append(temp);

            // compute max/min playcount,lastplay for all music
            if (query.at() == 0)
            {   // first song
                m_playcountMin = m_playcountMax = temp->PlayCount();
                m_lastplayMin  = m_lastplayMax  = temp->LastPlay().toTime_t();
            }
            else
            {
                int playCount = temp->PlayCount();
                double lastPlay = temp->LastPlay().toTime_t();

                m_playcountMin = min(playCount, m_playcountMin);
                m_playcountMax = max(playCount, m_playcountMax);
                m_lastplayMin  = min(lastPlay,  m_lastplayMin);
                m_lastplayMax  = max(lastPlay,  m_lastplayMax);
            }
            m_numLoaded++;
        }
    }
    else
    {
        VERBOSE(VB_IMPORTANT, "MythMusic hasn't found any tracks! "
                "That's ok with me if it's ok with you.");
    }

    //  To find this data quickly, build a map
    //  (a map to pointers!)
    music_map.clear();
    MetadataPtrList::iterator it = m_all_music.begin();
    for (; it != m_all_music.end(); ++it)
        music_map[(*it)->ID()] = *it;

    //  Build a tree to reflect current state of
    //  the metadata. Once built, sort it.

    buildTree();
    sortTree();
    m_done_loading = true;
}
Esempio n. 2
0
int Playlist::writeTree(GenericTree *tree_to_write_to, int a_counter)
{
    // compute max/min playcount,lastplay for this playlist
    int playcountMin = 0;
    int playcountMax = 0;
    double lastplayMin = 0.0;
    double lastplayMax = 0.0;

    typedef map<QString, uint32_t> AlbumMap;
    AlbumMap                       album_map;
    AlbumMap::iterator             Ialbum;
    QString                        album;

    typedef map<QString, uint32_t> ArtistMap;
    ArtistMap                      artist_map;
    ArtistMap::iterator            Iartist;
    QString                        artist;

    uint idx = 0;
    SongList::const_iterator it = songs.begin();
    for (; it != songs.end(); ++it, ++idx)
    {
        if (!(*it)->getCDFlag())
        {
            if ((*it)->getValue() == 0)
            {
                VERBOSE(VB_IMPORTANT, LOC_ERR + kID0err);
            }
            if ((*it)->getValue() > 0)
            {
                // Normal track
                Metadata *tmpdata =
                    all_available_music->getMetadata((*it)->getValue());
                if (tmpdata)
                {
                    if (tmpdata->isVisible())
                    {
                        if (0 == idx)
                        { // first song
                            playcountMin = playcountMax = tmpdata->PlayCount();
                            lastplayMin = lastplayMax = tmpdata->LastPlay().toTime_t();
                        }
                        else
                        {
                            if (tmpdata->PlayCount() < playcountMin)
                                playcountMin = tmpdata->PlayCount();
                            else if (tmpdata->PlayCount() > playcountMax)
                                playcountMax = tmpdata->PlayCount();

                            if (tmpdata->LastPlay().toTime_t() < lastplayMin)
                                lastplayMin = tmpdata->LastPlay().toTime_t();
                            else if (tmpdata->LastPlay().toTime_t() > lastplayMax)
                                lastplayMax = tmpdata->LastPlay().toTime_t();
                        }
                    }
                    // pre-fill the album-map with the album name.
                    // This allows us to do album mode in album order
                    album = tmpdata->Album();
                    // pre-fill the artist map with the artist name and song title
                    artist = tmpdata->Artist() + "~" + tmpdata->Title();
                }
                if ((Ialbum = album_map.find(album)) == album_map.end())
                    album_map.insert(AlbumMap::value_type(album,0));

                if ((Iartist = artist_map.find(artist)) == artist_map.end())
                    artist_map.insert(ArtistMap::value_type(artist,0));
            }
        }
    }
    // populate the sort id into the album map
    uint32_t album_count = 1;
    for (Ialbum = album_map.begin(); Ialbum != album_map.end(); Ialbum++)
    {
        Ialbum->second = album_count;
        album_count++;
    }

    // populate the sort id into the artist map
    uint32_t count = 1;
    for (Iartist = artist_map.begin(); Iartist != artist_map.end(); Iartist++)
    {
        Iartist->second = count;
        count++;
    }

    int RatingWeight = 2;
    int PlayCountWeight = 2;
    int LastPlayWeight = 2;
    int RandomWeight = 2;

    parent->FillIntelliWeights(RatingWeight, PlayCountWeight, LastPlayWeight,
                               RandomWeight);

    for (it = songs.begin(); it != songs.end(); ++it)
    {
        if (!(*it)->getCDFlag())
        {
            if ((*it)->getValue() == 0)
            {
                VERBOSE(VB_IMPORTANT, LOC_ERR + kID0err);
            }
            if ((*it)->getValue() > 0)
            {
                // Normal track
                Metadata *tmpdata =
                    all_available_music->getMetadata((*it)->getValue());
                if (tmpdata && tmpdata->isVisible())
                {
                    QString a_string = QString("%1 ~ %2")
                                       .arg(tmpdata->FormatArtist())
                                       .arg(tmpdata->FormatTitle());
                    GenericTree *added_node = tree_to_write_to->addNode(
                        a_string, (*it)->getValue(), true);
                    ++a_counter;
                    added_node->setAttribute(0, 1);
                    added_node->setAttribute(1, a_counter); //  regular order
                    added_node->setAttribute(2, rand()); //  random order

                    //
                    //  Compute "intelligent" weighting
                    //

                    int rating = tmpdata->Rating();
                    int playcount = tmpdata->PlayCount();
                    double lastplaydbl = tmpdata->LastPlay().toTime_t();
                    double ratingValue = (double)(rating) / 10;
                    double playcountValue, lastplayValue;

                    if (playcountMax == playcountMin)
                        playcountValue = 0;
                    else
                        playcountValue = ((playcountMin - (double)playcount)
                                         / (playcountMax - playcountMin) + 1);

                    if (lastplayMax == lastplayMin)
                        lastplayValue = 0;
                    else
                        lastplayValue = ((lastplayMin - lastplaydbl)
                                        / (lastplayMax - lastplayMin) + 1);

                    double rating_value =  (RatingWeight * ratingValue +
                                            PlayCountWeight * playcountValue +
                                            LastPlayWeight * lastplayValue +
                                            RandomWeight * (double)rand() /
                                            (RAND_MAX + 1.0));
                    uint32_t integer_rating = (int) (4000001 -
                                                     rating_value * 10000);
                    //  "intelligent" order
                    added_node->setAttribute(3, integer_rating);

                    // "intellegent/album" order
                    uint32_t album_order;
                    album = tmpdata->Album();
                    if ((Ialbum = album_map.find(album)) == album_map.end())
                    {
                        // we didn't find this album in the map,
                        // yet we pre-loaded them all. we are broken,
                        // but we just set the track order to 1, since there
                        // is no real point in reporting an error
                        album_order = 1;
                    }
                    else
                    {
                        album_order = Ialbum->second * 100;
                    }
                    album_order += tmpdata->Track();
                    added_node->setAttribute(4, album_order);

                    // "artist" order, sorts by artist name then track title
                    // uses the pre-prepared artist map to do this
                    uint32_t integer_order;
                    artist = tmpdata->Artist() + "~" + tmpdata->Title();
                    if ((Iartist = artist_map.find(artist)) == artist_map.end())
                    {
                        // we didn't find this track in the map,
                        // yet we pre-loaded them all. we are broken,
                        // but we just set the track order to 1, since there
                        // is no real point in reporting an error
                        integer_order = 1;
                    }
                    else
                    {
                        integer_order = Iartist->second;
                    }
                    added_node->setAttribute(5, integer_order);
                }
            }
            if ((*it)->getValue() < 0)
            {
                // it's a playlist, recurse (mildly)
                Playlist *level_down
                    = parent->getPlaylist(((*it)->getValue()) * -1);
                if (level_down)
                {
                    a_counter = level_down->writeTree(tree_to_write_to,
                                                      a_counter);
                }
            }
        }
        else
        {
            Metadata *tmpdata =
                all_available_music->getMetadata((*it)->getValue());
            if (tmpdata)
            {
                QString a_string = QString("(CD) %1 ~ %2")
                  .arg(tmpdata->FormatArtist()).arg(tmpdata->FormatTitle());

                if (tmpdata->FormatArtist().length() < 1 ||
                   tmpdata->FormatTitle().length() < 1)
                {
                    a_string = QString("(CD) Track %1").arg(tmpdata->Track());
                }
                GenericTree *added_node =
                    tree_to_write_to->addNode(a_string, (*it)->getValue(), true);
                ++a_counter;
                added_node->setAttribute(0, 1);
                added_node->setAttribute(1, a_counter); //  regular order
                added_node->setAttribute(2, rand()); //  random order
                added_node->setAttribute(3, rand()); //  "intelligent" order
            }
        }
    }
    return a_counter;
}