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>] " 0280 "[<a href='" + favoritesUrl + "' >Favorites</a>] " 0281 "[<a href='" + recommendationsUrl + "' >Recommendations</a>] " 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>] " 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