File indexing completed on 2024-05-19 04:50:18

0001 /****************************************************************************************
0002  * Copyright (c) 2007 Nikolaj Hald Nielsen <nhn@kde.org>                                *
0003  *                                                                                      *
0004  * This program is free software; you can redistribute it and/or modify it under        *
0005  * the terms of the GNU General Public License as published by the Free Software        *
0006  * Foundation; either version 2 of the License, or (at your option) any later           *
0007  * version.                                                                             *
0008  *                                                                                      *
0009  * This program is distributed in the hope that it will be useful, but WITHOUT ANY      *
0010  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A      *
0011  * PARTICULAR PURPOSE. See the GNU General Public License for more details.             *
0012  *                                                                                      *
0013  * You should have received a copy of the GNU General Public License along with         *
0014  * this program.  If not, see <http://www.gnu.org/licenses/>.                           *
0015  ****************************************************************************************/
0016 
0017 #include "MagnatuneInfoParser.h"
0018 
0019 #include "core/support/Components.h"
0020 #include "core/logger/Logger.h"
0021 #include "MagnatuneConfig.h"
0022 
0023 #include <KLocalizedString>
0024 
0025 
0026 using namespace Meta;
0027 
0028 void MagnatuneInfoParser::getInfo(const ArtistPtr &artist)
0029 {
0030 
0031     showLoading( i18n( "Loading artist info..." ) );
0032 
0033     MagnatuneArtist * magnatuneArtist = dynamic_cast<MagnatuneArtist *>( artist.data() );
0034     if ( !magnatuneArtist ) return;
0035 
0036     // first get the entire artist html page
0037    /* QString tempFile;
0038     QString orgHtml;*/
0039 
0040     m_infoDownloadJob = KIO::storedGet( magnatuneArtist->magnatuneUrl(), KIO::Reload, KIO::HideProgressInfo );
0041     Amarok::Logger::newProgressOperation( m_infoDownloadJob, i18n( "Fetching %1 Artist Info", magnatuneArtist->prettyName() ) );
0042     connect( m_infoDownloadJob, &KJob::result, this, &MagnatuneInfoParser::artistInfoDownloadComplete );
0043 
0044 }
0045 
0046 
0047 void MagnatuneInfoParser::getInfo(const AlbumPtr &album)
0048 {
0049 
0050     showLoading( i18n( "Loading album info..." ) );
0051     
0052     MagnatuneAlbum * magnatuneAlbum = dynamic_cast<MagnatuneAlbum *>( album.data() );
0053 
0054     const QString artistName = album->albumArtist()->name();
0055 
0056     QString infoHtml = "<HTML><HEAD><META HTTP-EQUIV=\"Content-Type\" "
0057                        "CONTENT=\"text/html; charset=utf-8\"></HEAD><BODY>";
0058 
0059     infoHtml += generateHomeLink();
0060     infoHtml += "<div align=\"center\"><strong>";
0061     infoHtml += artistName;
0062     infoHtml += "</strong><br><em>";
0063     infoHtml += magnatuneAlbum->name();
0064     infoHtml += "</em><br><br>";
0065     infoHtml += "<img src=\"" + magnatuneAlbum->coverUrl() +
0066                 "\" align=\"middle\" border=\"1\">";
0067 
0068     // Disable Genre line in Magnatune applet since, well, it doesn't actually put a genre there...
0069     // Nikolaj, FYI: either the thumbnails aren't working, or they aren't getting through the proxy here.  That would be odd, however, as the database and
0070     // all HTML are coming through the proxy
0071     //infoHtml += "<br><br>" + i18n( "Genre: ");// + magnatuneAlbum->
0072     infoHtml += "<br>" + i18n( "Release Year: %1", QString::number( magnatuneAlbum->launchYear() ) );
0073 
0074     if ( !magnatuneAlbum->description().isEmpty() ) {
0075 
0076         //debug() << "MagnatuneInfoParser: Writing description: '" << album->getDescription() << "'";
0077         infoHtml += "<br><br><b>" + i18n( "Description:" ) + "</b><br><p align=\"left\" >" + magnatuneAlbum->description();
0078 
0079     }
0080 
0081     infoHtml += "</p><br><br>" + i18n( "From Magnatune.com" ) + "</div>";
0082     infoHtml += "</BODY></HTML>";
0083 
0084     Q_EMIT ( info( infoHtml ) );
0085 }
0086 
0087 void MagnatuneInfoParser::getInfo(const TrackPtr &track)
0088 {
0089     Q_UNUSED( track );
0090     return;
0091 }
0092 
0093 
0094 
0095 
0096 void
0097 MagnatuneInfoParser::artistInfoDownloadComplete( KJob *downLoadJob )
0098 {
0099 
0100     if ( downLoadJob->error() != 0 )
0101     {
0102         //TODO: error handling here
0103         return ;
0104     }
0105     if ( downLoadJob != m_infoDownloadJob )
0106         return ; //not the right job, so let's ignore it
0107 
0108 
0109 
0110     QString infoString = ( (KIO::StoredTransferJob* ) downLoadJob )->data();
0111     //debug() << "MagnatuneInfoParser: Artist info downloaded: " << infoString;
0112     infoString = extractArtistInfo( infoString );
0113 
0114     //debug() << "html: " << trimmedInfo;
0115 
0116     Q_EMIT ( info( infoString ) );
0117 
0118 }
0119 
0120 QString
0121 MagnatuneInfoParser::extractArtistInfo( const QString &artistPage )
0122 {
0123     QString trimmedHtml;
0124 
0125 
0126     int sectionStart = artistPage.indexOf( "<!-- ARTISTBODY -->" );
0127     int sectionEnd = artistPage.indexOf( "<!-- /ARTISTBODY -->", sectionStart );
0128 
0129     trimmedHtml = artistPage.mid( sectionStart, sectionEnd - sectionStart );
0130 
0131     int buyStartIndex = trimmedHtml.indexOf( "<!-- PURCHASE -->" );
0132     int buyEndIndex;
0133 
0134     //we are going to integrate the buying of music (I hope) so remove these links
0135 
0136     while ( buyStartIndex != -1 )
0137     {
0138         buyEndIndex = trimmedHtml.indexOf( "<!-- /PURCHASE -->", buyStartIndex ) + 18;
0139         trimmedHtml.remove( buyStartIndex, buyEndIndex - buyStartIndex );
0140         buyStartIndex = trimmedHtml.indexOf( "<!-- PURCHASE -->", buyStartIndex );
0141     }
0142 
0143 
0144     QString infoHtml = "<HTML><HEAD><META HTTP-EQUIV=\"Content-Type\" "
0145                        "CONTENT=\"text/html; charset=iso-8859-1\"></HEAD><BODY>";
0146     infoHtml += generateHomeLink();
0147     infoHtml += trimmedHtml;
0148     infoHtml += "</BODY></HTML>";
0149 
0150 
0151     return infoHtml;
0152 }
0153 
0154 void MagnatuneInfoParser::getFrontPage()
0155 {
0156 
0157     if( !m_cachedFrontpage.isEmpty() )
0158     {
0159         Q_EMIT ( info( m_cachedFrontpage ) );
0160         return;
0161     }
0162 
0163     showLoading( i18n( "Loading Magnatune.com frontpage..." ) );
0164     
0165     m_pageDownloadJob = KIO::storedGet( QUrl("http://magnatune.com/amarok_frontpage.html"), KIO::Reload, KIO::HideProgressInfo );
0166     Amarok::Logger::newProgressOperation( m_pageDownloadJob, i18n( "Fetching Magnatune.com front page" ) );
0167     connect( m_pageDownloadJob, &KJob::result, this, &MagnatuneInfoParser::frontpageDownloadComplete );
0168 }
0169 
0170 void MagnatuneInfoParser::getFavoritesPage()
0171 {
0172     MagnatuneConfig config;
0173 
0174     if ( !config.isMember() )
0175         return;
0176 
0177     showLoading( i18n( "Loading your Magnatune.com favorites page..." ) );
0178 
0179     QString type;
0180     if( config.membershipType() == MagnatuneConfig::STREAM )
0181         type = "stream";
0182     else
0183          type = "download";
0184 
0185     QString user = config.username();
0186     QString password = config.password();
0187 
0188     QUrl url = QUrl::fromUserInput( "http://" + user + ":" + password + "@" + type.toLower() + ".magnatune.com/member/amarok_favorites.php" );
0189 
0190     m_pageDownloadJob = KIO::storedGet( url, KIO::Reload, KIO::HideProgressInfo );
0191     Amarok::Logger::newProgressOperation( m_pageDownloadJob, i18n( "Loading your Magnatune.com favorites page..." ) );
0192     connect( m_pageDownloadJob, &KJob::result, this, &MagnatuneInfoParser::userPageDownloadComplete );
0193 }
0194 
0195 void MagnatuneInfoParser::getRecommendationsPage()
0196 {
0197     MagnatuneConfig config;
0198 
0199     if ( !config.isMember() )
0200         return;
0201 
0202     showLoading( i18n( "Loading your personal Magnatune.com recommendations page..." ) );
0203 
0204     QString type;
0205     if( config.membershipType() == MagnatuneConfig::STREAM )
0206         type = "stream";
0207     else
0208          type = "download";
0209 
0210     QString user = config.username();
0211     QString password = config.password();
0212 
0213     QUrl url = QUrl::fromUserInput( "http://" + user + ":" + password + "@" + type.toLower() + ".magnatune.com/member/amarok_recommendations.php" );
0214 
0215     m_pageDownloadJob = KIO::storedGet( url, KIO::Reload, KIO::HideProgressInfo );
0216     Amarok::Logger::newProgressOperation( m_pageDownloadJob, i18n( "Loading your personal Magnatune.com recommendations page..." ) );
0217     connect( m_pageDownloadJob, &KJob::result, this, &MagnatuneInfoParser::userPageDownloadComplete );
0218 }
0219 
0220 void MagnatuneInfoParser::frontpageDownloadComplete( KJob * downLoadJob )
0221 {
0222     if ( downLoadJob->error() != 0 )
0223     {
0224         //TODO: error handling here
0225         return ;
0226     }
0227     if ( downLoadJob != m_pageDownloadJob )
0228         return ; //not the right job, so let's ignore it
0229 
0230     QString infoString = ((KIO::StoredTransferJob* )downLoadJob)->data();
0231 
0232     //insert menu
0233     MagnatuneConfig config;
0234     if( config.isMember() )
0235         infoString.replace( "<!--MENU_TOKEN-->", generateMemberMenu() );
0236 
0237     //insert fancy amarok url links to the artists
0238     infoString = createArtistLinks( infoString );
0239 
0240     if( m_cachedFrontpage.isEmpty() )
0241         m_cachedFrontpage = infoString;
0242 
0243     Q_EMIT ( info( infoString ) );
0244 }
0245 
0246 void MagnatuneInfoParser::userPageDownloadComplete( KJob * downLoadJob )
0247 {
0248     if ( downLoadJob->error() )
0249     {
0250         //TODO: error handling here
0251         return ;
0252     }
0253     if ( downLoadJob != m_pageDownloadJob )
0254         return ; //not the right job, so let's ignore it
0255 
0256 
0257 
0258     QString infoString = ((KIO::StoredTransferJob* )downLoadJob)->data();
0259 
0260     //insert menu
0261     MagnatuneConfig config;
0262     if( config.isMember() )
0263         infoString.replace( "<!--MENU_TOKEN-->", generateMemberMenu() );
0264 
0265     //make sure that any pages that use the old command name "service_magnatune" replaces it with "service-magnatune"
0266     infoString.replace( "service_magnatune", "service-magnatune" );
0267 
0268     Q_EMIT ( info( infoString ) );
0269 }
0270 
0271 
0272 QString MagnatuneInfoParser::generateMemberMenu()
0273 {
0274     QString homeUrl = "amarok://service-magnatune?command=show_home";
0275     QString favoritesUrl = "amarok://service-magnatune?command=show_favorites";
0276     QString recommendationsUrl = "amarok://service-magnatune?command=show_recommendations";
0277 
0278     QString menu = "<div align='right'>"
0279                        "[<a href='" + homeUrl + "' >Home</a>]&nbsp;"
0280                        "[<a href='" + favoritesUrl + "' >Favorites</a>]&nbsp;"
0281                        "[<a href='" + recommendationsUrl + "' >Recommendations</a>]&nbsp;"
0282                     "</div>";
0283 
0284     return menu;
0285 }
0286 
0287 QString
0288 MagnatuneInfoParser::generateHomeLink()
0289 {
0290     QString homeUrl = "amarok://service-magnatune?command=show_home";
0291     QString link = "<div align='right'>"
0292                     "[<a href='" + homeUrl + "' >Home</a>]&nbsp;"
0293                    "</div>";
0294 
0295     return link;
0296 }
0297 
0298 QString
0299 MagnatuneInfoParser::createArtistLinks( const QString &page )
0300 {
0301     //the artist name is wrapped in <!--ARTIST_TOKEN-->artist<!--/ARTIST_TOKEN-->
0302 
0303     QString returnPage = page;
0304 
0305     int startTokenLength = QStringLiteral( "<!--ARTIST_TOKEN-->" ).length();
0306 
0307     int offset = 0;
0308     int startTokenIndex = page.indexOf( "<!--ARTIST_TOKEN-->", offset );
0309     int endTokenIndex = 0;
0310 
0311     while( startTokenIndex != -1 )
0312     {
0313         endTokenIndex = page.indexOf( "<!--/ARTIST_TOKEN-->", startTokenIndex );
0314         if( endTokenIndex == -1 )
0315             break; //bail out
0316 
0317         offset = endTokenIndex;
0318 
0319         //get the artist namespace
0320 
0321         int artistLength = endTokenIndex - ( startTokenIndex + startTokenLength );
0322         QString artist = page.mid( startTokenIndex + startTokenLength, artistLength );
0323 
0324         //replace in the artist amarok url
0325 
0326         QString replaceString = "<!--ARTIST_TOKEN-->" + artist + "<!--/ARTIST_TOKEN-->";
0327         QString artistLink = "<a href='amarok://navigate/internet/Magnatune.com?filter=artist:%22" + AmarokUrl::escape( artist ) + "%22&levels=artist-album'>" + artist + "</a>";
0328 
0329         returnPage = returnPage.replace( replaceString, artistLink );
0330 
0331         startTokenIndex = page.indexOf( "<!--ARTIST_TOKEN-->", offset );
0332     }
0333 
0334     return returnPage;
0335 }
0336 
0337 
0338