1 /* This file is part of Clementine. 2 Copyright 2012, David Sansome <me@davidsansome.com> 3 Copyright 2014, John Maguire <john.maguire@gmail.com> 4 Copyright 2014, Krzysztof Sobiecki <sobkas@gmail.com> 5 6 Clementine is free software: you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation, either version 3 of the License, or 9 (at your option) any later version. 10 11 Clementine is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with Clementine. If not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 #ifndef INTERNET_PODCASTS_PODCASTURLLOADER_H_ 21 #define INTERNET_PODCASTS_PODCASTURLLOADER_H_ 22 23 #include <QObject> 24 #include <QRegExp> 25 26 #include "opmlcontainer.h" 27 #include "podcast.h" 28 29 class PodcastParser; 30 31 class QNetworkAccessManager; 32 class QNetworkReply; 33 34 class PodcastUrlLoaderReply : public QObject { 35 Q_OBJECT 36 37 public: 38 PodcastUrlLoaderReply(const QUrl& url, QObject* parent); 39 40 enum ResultType { Type_Podcast, Type_Opml }; 41 url()42 const QUrl& url() const { return url_; } is_finished()43 bool is_finished() const { return finished_; } is_success()44 bool is_success() const { return error_text_.isEmpty(); } error_text()45 const QString& error_text() const { return error_text_; } 46 result_type()47 ResultType result_type() const { return result_type_; } podcast_results()48 const PodcastList& podcast_results() const { return podcast_results_; } opml_results()49 const OpmlContainer& opml_results() const { return opml_results_; } 50 51 void SetFinished(const QString& error_text); 52 void SetFinished(const PodcastList& results); 53 void SetFinished(const OpmlContainer& results); 54 55 signals: 56 void Finished(bool success); 57 58 private: 59 QUrl url_; 60 bool finished_; 61 QString error_text_; 62 63 ResultType result_type_; 64 PodcastList podcast_results_; 65 OpmlContainer opml_results_; 66 }; 67 68 class PodcastUrlLoader : public QObject { 69 Q_OBJECT 70 71 public: 72 explicit PodcastUrlLoader(QObject* parent = nullptr); 73 ~PodcastUrlLoader(); 74 75 static const int kMaxRedirects; 76 77 PodcastUrlLoaderReply* Load(const QString& url_text); 78 PodcastUrlLoaderReply* Load(const QUrl& url); 79 80 // Both the FixPodcastUrl functions replace common podcatcher URL schemes 81 // like itpc:// or zune:// with their http:// equivalents. The QString 82 // overload also cleans up user-entered text a bit - stripping whitespace and 83 // applying shortcuts like sc:tag. 84 static QUrl FixPodcastUrl(const QString& url_text); 85 static QUrl FixPodcastUrl(const QUrl& url); 86 87 private: 88 struct RequestState { 89 int redirects_remaining_; 90 PodcastUrlLoaderReply* reply_; 91 }; 92 93 typedef QPair<QString, QString> QuickPrefix; 94 typedef QList<QuickPrefix> QuickPrefixList; 95 96 private slots: 97 void RequestFinished(RequestState* state, QNetworkReply* reply); 98 99 private: 100 void SendErrorAndDelete(const QString& error_text, RequestState* state); 101 void NextRequest(const QUrl& url, RequestState* state); 102 103 private: 104 QNetworkAccessManager* network_; 105 PodcastParser* parser_; 106 107 QRegExp html_link_re_; 108 QRegExp whitespace_re_; 109 QRegExp html_link_rel_re_; 110 QRegExp html_link_type_re_; 111 QRegExp html_link_href_re_; 112 }; 113 114 #endif // INTERNET_PODCASTS_PODCASTURLLOADER_H_ 115