From 52550acb7519502679bb16826286f214f9eb1c05 Mon Sep 17 00:00:00 2001 From: David Sansome Date: Sat, 15 Jan 2011 13:59:58 +0000 Subject: [PATCH] Add support for Premium streams in di.fm --- scripts/digitallyimported-radio/common.py | 11 ++++ scripts/digitallyimported-radio/main.py | 4 +- scripts/digitallyimported-radio/service.py | 64 +++++++++++-------- .../digitallyimported-radio/settingsdialog.py | 27 +++++++- .../digitallyimported-radio/settingsdialog.ui | 8 +-- 5 files changed, 80 insertions(+), 34 deletions(-) create mode 100644 scripts/digitallyimported-radio/common.py diff --git a/scripts/digitallyimported-radio/common.py b/scripts/digitallyimported-radio/common.py new file mode 100644 index 000000000..a746121f9 --- /dev/null +++ b/scripts/digitallyimported-radio/common.py @@ -0,0 +1,11 @@ +# These have to be in the same order as in the settings dialog +PLAYLISTS = [ + {"premium": False, "url": "http://listen.di.fm/public3/%s.pls"}, + {"premium": True, "url": "http://www.di.fm/listen/%s/premium.pls"}, + {"premium": False, "url": "http://listen.di.fm/public2/%s.pls"}, + {"premium": True, "url": "http://www.di.fm/listen/%s/64k.pls"}, + {"premium": True, "url": "http://www.di.fm/listen/%s/128k.pls"}, + {"premium": False, "url": "http://listen.di.fm/public5/%s.asx"}, + {"premium": True, "url": "http://www.di.fm/listen/%s/64k.asx"}, + {"premium": True, "url": "http://www.di.fm/listen/%s/128k.asx"}, +] diff --git a/scripts/digitallyimported-radio/main.py b/scripts/digitallyimported-radio/main.py index 71697b6fa..7961c06e2 100644 --- a/scripts/digitallyimported-radio/main.py +++ b/scripts/digitallyimported-radio/main.py @@ -18,11 +18,11 @@ class Plugin: self.service.SettingsDialogRequested.connect(self.ShowSettings) def ShowSettings(self): - # Create the dialog the first time it's shown if not self.settings_dialog: + # Create the dialog the first time it's shown self.settings_dialog = SettingsDialog() + self.settings_dialog.accepted.connect(self.service.ReloadSettings) - # Show the dialog self.settings_dialog.show() plugin = Plugin() diff --git a/scripts/digitallyimported-radio/service.py b/scripts/digitallyimported-radio/service.py index b01751aac..1c18971a8 100644 --- a/scripts/digitallyimported-radio/service.py +++ b/scripts/digitallyimported-radio/service.py @@ -1,9 +1,11 @@ +import common + import clementine from PyQt4.QtCore import QSettings, QUrl from PyQt4.QtGui import QAction, QDesktopServices, QIcon, QMenu, \ QStandardItem -from PyQt4.QtNetwork import QNetworkRequest +from PyQt4.QtNetwork import QNetworkCookie, QNetworkCookieJar, QNetworkRequest import PyQt4.QtCore import json @@ -15,18 +17,6 @@ class DigitallyImportedService(clementine.RadioService): HOMEPAGE_URL = QUrl("http://www.di.fm/") STREAM_LIST_URL = QUrl("http://listen.di.fm/") - # These have to be in the same order as in the settings dialog - PLAYLISTS = [ - {"premium": False, "url": "http://listen.di.fm/public3/%s.pls"}, - {"premium": True, "url": "http://www.di.fm/listen/%s/premium.pls"}, - {"premium": False, "url": "http://listen.di.fm/public2/%s.pls"}, - {"premium": True, "url": "http://www.di.fm/listen/%s/64k.pls"}, - {"premium": True, "url": "http://www.di.fm/listen/%s/128k.pls"}, - {"premium": False, "url": "http://listen.di.fm/public5/%s.asx"}, - {"premium": True, "url": "http://www.di.fm/listen/%s/64k.asx"}, - {"premium": True, "url": "http://www.di.fm/listen/%s/128k.asx"}, - ] - SettingsDialogRequested = PyQt4.QtCore.pyqtSignal() def __init__(self, model): @@ -36,6 +26,7 @@ class DigitallyImportedService(clementine.RadioService): self.path = os.path.dirname(__file__) self.audio_type = 0 + self.context_index = None self.last_original_url = None self.menu = None @@ -50,6 +41,20 @@ class DigitallyImportedService(clementine.RadioService): settings.beginGroup(self.SERVICE_NAME) self.audio_type = int(settings.value("audio_type", 0).toPyObject()) + username = unicode(settings.value("username", "").toPyObject().toUtf8()) + password = unicode(settings.value("password", "").toPyObject().toUtf8()) + + # If a username and password were set by the user then set them in the + # cookies we pass to www.di.fm + cookie_jar = None + if len(username) and len(password): + cookie_jar = QNetworkCookieJar() + cookie_jar.setCookiesFromUrl([ + QNetworkCookie("_amember_ru", username), + QNetworkCookie("_amember_rp", password), + ], QUrl("http://www.di.fm/")) + + self.network.setCookieJar(cookie_jar) def CreateRootItem(self): self.root = QStandardItem(QIcon(os.path.join(self.path, "icon-small.png")), @@ -80,7 +85,7 @@ class DigitallyImportedService(clementine.RadioService): self.menu.addSeparator() self.menu.addAction(clementine.IconLoader.Load("configure"), - self.tr("Configure Digitally Imported..."), self.SettingsDialogRequested) + self.tr("Configure Digitally Imported..."), self.SettingsDialogRequested.emit) self.context_index = index self.menu.popup(global_pos) @@ -152,12 +157,12 @@ class DigitallyImportedService(clementine.RadioService): return result key = original_url.host() - playlist_url = self.PLAYLISTS[self.audio_type]["url"] % key + playlist_url = common.PLAYLISTS[self.audio_type]["url"] % key - # Start fetching the playlist - self.song_loader = clementine.SongLoader(clementine.library) - self.song_loader.LoadFinished.connect(self.LoadPlaylistFinished) - self.song_loader.Load(QUrl(playlist_url)) + # Start fetching the playlist. Can't use a SongLoader to do this because + # we have to use the cookies we set in ReloadSettings() + reply = self.network.get(QNetworkRequest(QUrl(playlist_url))) + reply.finished.connect(self.LoadPlaylistFinished) # Save the original URL so we can emit it in the finished signal later self.last_original_url = original_url @@ -167,10 +172,13 @@ class DigitallyImportedService(clementine.RadioService): result.type_ = clementine.PlaylistItem.SpecialLoadResult.WillLoadAsynchronously result.original_url_ = original_url - print result return result - def LoadPlaylistFinished(self, success): + def LoadPlaylistFinished(self): + # Get the QNetworkReply that called this slot + reply = self.sender() + reply.deleteLater() + if self.task_id is None: return @@ -178,16 +186,20 @@ class DigitallyImportedService(clementine.RadioService): clementine.task_manager.SetTaskFinished(self.task_id) self.task_id = None + # Try to parse the playlist + parser = clementine.PlaylistParser(clementine.library) + songs = parser.Load(reply) + # Failed to get the playlist? - if not success: + if len(songs) == 0: self.StreamError.emit("Error loading playlist '%s'" % self.song_loader.url().toString()) return result = clementine.PlaylistItem.SpecialLoadResult() result.original_url_ = self.last_original_url - if len(self.song_loader.songs()) > 0: - # Take the first track in the playlist - result.type_ = clementine.PlaylistItem.SpecialLoadResult.TrackAvailable - result.media_url_ = QUrl(self.song_loader.songs()[0].filename()) + + # Take the first track in the playlist + result.type_ = clementine.PlaylistItem.SpecialLoadResult.TrackAvailable + result.media_url_ = QUrl(songs[0].filename()) self.AsyncLoadFinished.emit(result) diff --git a/scripts/digitallyimported-radio/settingsdialog.py b/scripts/digitallyimported-radio/settingsdialog.py index 9b1ebf48e..a0be723bc 100644 --- a/scripts/digitallyimported-radio/settingsdialog.py +++ b/scripts/digitallyimported-radio/settingsdialog.py @@ -1,4 +1,7 @@ -from PyQt4.QtGui import QDialog, QIcon +from service import DigitallyImportedService + +from PyQt4.QtCore import QSettings +from PyQt4.QtGui import QDialog, QIcon import PyQt4.uic import os.path @@ -12,5 +15,25 @@ class SettingsDialog(QDialog): # Set up the user interface PyQt4.uic.loadUi(os.path.join(self.path, "settingsdialog.ui"), self) - # Set the icon + # Set the window icon self.setWindowIcon(QIcon(os.path.join(self.path, "icon-small.png"))) + + def showEvent(self, event): + # Load the settings + settings = QSettings() + settings.beginGroup(DigitallyImportedService.SERVICE_NAME) + self.type.setCurrentIndex(int(settings.value("audio_type", 0).toPyObject())) + self.username.setText(settings.value("username", "").toPyObject()) + self.password.setText(settings.value("password", "").toPyObject()) + + QDialog.showEvent(self, event) + + def accept(self): + # Save the settings + settings = QSettings() + settings.beginGroup(DigitallyImportedService.SERVICE_NAME) + settings.setValue("audio_type", self.type.currentIndex()) + settings.setValue("username", self.username.text()) + settings.setValue("password", self.password.text()) + + QDialog.accept(self) diff --git a/scripts/digitallyimported-radio/settingsdialog.ui b/scripts/digitallyimported-radio/settingsdialog.ui index 43960a673..1882241af 100644 --- a/scripts/digitallyimported-radio/settingsdialog.ui +++ b/scripts/digitallyimported-radio/settingsdialog.ui @@ -16,9 +16,6 @@ - - false - 0 @@ -63,7 +60,7 @@ - + <a href="http://www.di.fm/premium/">Upgrade to Premium now</a> @@ -71,6 +68,9 @@ true + + Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse +