common: split MetadataFetcher into its own file
[nephilim.git] / nephilim / metadata_fetcher.py
blob9e18aacb6e9da6d7357773eac74bf01b115e1f98
2 # Copyright (C) 2010 Anton Khirnov <anton@khirnov.net>
4 # Nephilim is free software: you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation, either version 3 of the License, or
7 # (at your option) any later version.
9 # Nephilim is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
14 # You should have received a copy of the GNU General Public License
15 # along with Nephilim. If not, see <http://www.gnu.org/licenses/>.
18 from PyQt4 import QtCore, QtNetwork
19 from PyQt4.QtCore import pyqtSignal as Signal
21 from song import Song
23 class MetadataFetcher(QtCore.QObject):
24 """A basic class for metadata fetchers. Provides a fetch(song) function,
25 emits a finished(song, metadata) signal when done; lyrics is either a Python
26 unicode string or None if not found."""
27 #public, read-only
28 logger = None
29 name = ''
31 #private
32 nam = None # NetworkAccessManager
33 rep = None # current NetworkReply.
34 song = None # current song
36 # SIGNALS
37 finished = Signal([Song, object])
39 #### private ####
40 def __init__(self, plugin):
41 QtCore.QObject.__init__(self, plugin)
43 self.nam = QtNetwork.QNetworkAccessManager()
44 self.logger = plugin.logger
46 def fetch2(self, song, url):
47 """A private convenience function to initiate fetch process."""
48 # abort any existing connections
49 self.abort()
50 self.song = song
52 self.logger.info('Searching %s: %s.'%(self. name, url.toString()))
53 self.rep = self.nam.get(QtNetwork.QNetworkRequest(url))
54 self.rep.error.connect(self.handle_error)
56 def finish(self, metadata = None):
57 """A private convenience function to clean up and emit finished().
58 Feel free to reimplement/not use it."""
59 self.rep = None
60 self.finished.emit(self.song, metadata)
61 self.song = None
63 def handle_error(self):
64 """Print the error and abort."""
65 self.logger.error(self.rep.errorString())
66 self.abort()
67 self.finish()
69 #### public ####
70 def fetch(self, song):
71 """Reimplement this in subclasses."""
72 pass
74 def abort(self):
75 """Abort all downloads currently in progress."""
76 if self.rep:
77 self.rep.blockSignals(True)
78 self.rep.abort()
79 self.rep = None