add installer script
[nephilim.git] / nephilim / common.py
blobb0dac331fb85613c2245e8c5384e40ca89420bc5
2 # Copyright (C) 2008 jerous <jerous@gmail.com>
3 # Copyright (C) 2009 Anton Khirnov <wyskas@gmail.com>
5 # Nephilim is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation, either version 3 of the License, or
8 # (at your option) any later version.
10 # Nephilim is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with Nephilim. If not, see <http://www.gnu.org/licenses/>.
19 from PyQt4 import QtCore, QtGui, QtNetwork
20 import socket
21 import logging
22 import os
24 socket.setdefaulttimeout(8)
26 appIcon = ':icons/nephilim_small.png'
27 APPNAME = 'nephilim'
28 ORGNAME = 'nephilim'
30 def sec2min(secs):
31 """Converts seconds to min:sec."""
32 min=int(secs/60)
33 sec=secs%60
34 if sec<10:sec='0'+str(sec)
35 return str(min)+':'+str(sec)
37 class Button(QtGui.QPushButton):
38 iconSize=32
39 """A simple Button class which calls $onClick when clicked."""
40 def __init__(self, caption, onClick=None, iconPath=None, iconOnly=False, parent=None):
41 QtGui.QPushButton.__init__(self, parent)
43 if onClick:
44 self.clicked.connect(onClick)
45 if iconPath:
46 self.changeIcon(iconPath)
48 if not(iconPath and iconOnly):
49 QtGui.QPushButton.setText(self, caption)
51 self.setToolTip(caption)
53 def setText(self, caption):
54 self.setToolTip(caption)
55 if self.icon()==None:
56 self.setText(caption)
58 def changeIcon(self, iconPath):
59 icon=QtGui.QIcon()
60 icon.addFile(iconPath, QtCore.QSize(self.iconSize, self.iconSize))
61 self.setIcon(icon)
63 def expand_tags(str, expanders):
64 #ensure that str is QString
65 str = QtCore.QString(str)
66 for expander in expanders:
67 str = expander.expand_tags(str)
69 #remove unexpanded tags
70 return str.replace(QtCore.QRegExp('\\$\\w+'), '')
72 def generate_metadata_path(song, dir_tag, file_tag):
73 """Generate dirname and (db files only) full file path for reading/writing metadata files
74 (cover, lyrics) from $tags in dir/filename."""
75 if QtCore.QDir.isAbsolutePath(song['file']):
76 dirname = os.path.dirname(song['file'])
77 filepath = ''
78 elif '://' in song['file']: # we are streaming
79 dirname = ''
80 filepath = ''
81 else:
82 dirname = expand_tags(dir_tag, (QtGui.QApplication.instance(), song))
83 filepath = '%s/%s'%(dirname, expand_tags(file_tag, (QtGui.QApplication.instance(), song)).replace('/', '_'))
85 return dirname, filepath
87 class MetadataFetcher(QtCore.QObject):
88 """A basic class for metadata fetchers. Provides a fetch(song) function,
89 emits a finished(song, metadata) signal when done; lyrics is either a QString,
90 Python unicode string or None if not found."""
91 #public, read-only
92 logger = None
93 name = ''
95 #private
96 nam = None # NetworkAccessManager
97 rep = None # current NetworkReply.
98 song = None # current song
100 # SIGNALS
101 finished = QtCore.pyqtSignal(['song', 'metadata'])
103 #### private ####
104 def __init__(self, plugin):
105 QtCore.QObject.__init__(self, plugin)
107 self.nam = QtNetwork.QNetworkAccessManager()
108 self.logger = plugin.logger
110 def fetch2(self, song, url):
111 """A private convenience function to initiate fetch process."""
112 # abort any existing connections
113 self.abort()
114 self.song = song
116 self.logger.info('Searching %s: %s.'%(self. name, url))
117 self.rep = self.nam.get(QtNetwork.QNetworkRequest(url))
119 def finish(self, metadata = None):
120 """A private convenience function to clean up and emit finished().
121 Feel free to reimplement/not use it."""
122 self.rep = None
123 self.rep = None
124 self.finished.emit(self.song, metadata)
125 self.song = None
127 #### public ####
128 def fetch(self, song):
129 """Reimplement this in subclasses."""
130 pass
132 def abort(self):
133 """Abort all downloads currently in progress."""
134 if self.rep:
135 self.rep.finished.disconnect()
136 self.rep.abort()
137 self.rep = None