75
75
self.loadConfigData()
77
77
def loadConfigData(self):
80
80
self.config = ExaileConfig()
82
82
if self.options.config != None:
83
83
# load the config based on options passed in from the main app
84
84
configfilepath = self.options.config
86
86
# load plugin config from home directory of the user
87
87
configfilepath = os.path.join(os.path.expanduser('~'), ".config/"+app_name+"/"+module_name+".config")
89
89
if os.path.exists(configfilepath):
91
91
self.logger.info("Loading config settings from \"%s\""%configfilepath)
94
94
for line in fileinput.input(os.path.expanduser(configfilepath)):
95
95
line = line.strip()
96
96
if len(line) > 0 and line[0:1] != "#": # ignore commented lines or empty ones
98
98
name = line.split("=")[0].strip().upper() # config setting name on the left of =
99
99
value = line.split("=")[1].split("#")[0].strip() # config value on the right of = (minus any trailing comments)
101
101
if len(value) > 0:
102
102
if name == "HEADERTEMPLATE":
103
self.config.HEADERTEMPLATE = self.getTypedValue(value, "string")
103
self.config.HEADERTEMPLATE = getTypedValue(value, "string")
104
104
if name == "TEMPLATE":
105
self.config.TEMPLATE = self.getTypedValue(value, "string")
105
self.config.TEMPLATE = getTypedValue(value, "string")
106
106
elif name == "STATUSTEXT":
107
self.config.STATUSTEXT = self.getTypedValue(value, "string")
107
self.config.STATUSTEXT = getTypedValue(value, "string")
108
108
elif name == "NOUNKNOWNOUTPUT":
109
self.config.NOUNKNOWNOUTPUT = self.getTypedValue(value, "boolean")
109
self.config.NOUNKNOWNOUTPUT = getTypedValue(value, "boolean")
111
self.logger.error("Unknown option in config file: " + name)
111
self.logger.error("Unknown option in config file: " + name)
113
113
self.logger.info("Config data file %s not found, using defaults and setting up config file for next time" % configfilepath)
115
115
userconfigpath = os.path.join(os.path.expanduser('~'), ".config/"+app_name+"/")
116
116
configsource = os.path.join(app_path, "config/"+module_name+".config")
118
118
if os.path.exists(userconfigpath) == False:
119
119
os.makedirs(userconfigpath)
123
123
except Exception, e:
124
124
self.logger.error(e.__str__()+"\n"+traceback.format_exc())
126
def getTypedValue(self, value, expectedtype):
129
if len(value.strip(" ")) == 0:
132
elif value.lower() == "true":
133
if expectedtype == "boolean":
136
self.logger.error("Expected type was '%s', but the value '%s' was given"%(expectedtype, value))
138
elif value.lower() == "false":
139
if expectedtype == "boolean":
142
self.logger.error("Expected type was '%s', but the value '%s' was given"%(expectedtype, value))
144
elif self.isNumeric(value) == True:
145
if expectedtype == "integer":
148
self.logger.error("Expected type was '%s', but the value '%s' was given"%(expectedtype, value))
153
except (TypeError, ValueError):
154
self.logger.error("Cannot convert '%s' to expected type of '%s'"%(value,expectedtype))
157
126
def testDBus(self, bus, interface):
158
127
obj = bus.get_object('org.freedesktop.DBus', '/org/freedesktop/DBus')
159
128
dbus_iface = dbus.Interface(obj, 'org.freedesktop.DBus')
160
129
avail = dbus_iface.ListNames()
161
130
return interface in avail
163
132
def getOutputData(self, datatype, statustext, nounknownoutput):
166
135
if DBUS_AVAIL == True:
168
137
if nounknownoutput == True:
169
138
unknown_time = ""
170
139
unknown_number = ""
177
146
unknown_string = "Unknown"
178
147
unknown_coverart = "file://"+urllib.quote(os.path.join(app_path,"images/"+module_name+".png"))
179
148
unknown_rating = "file://"+urllib.quote(os.path.join(app_path,"images/ratingicons/0.png"))
183
152
bus = dbus.SessionBus()
184
153
if self.musicData == None:
186
155
if self.testDBus(bus, 'org.exaile.DBusInterface'):
190
159
self.logger.info("Setting up dbus interface")
192
161
remote_object = bus.get_object("org.exaile.DBusInterface","/DBusInterfaceObject")
193
162
iface = dbus.Interface(remote_object, "org.exaile.DBusInterface")
195
164
self.logger.info("Calling dbus interface for music data")
197
166
# grab the data for use
199
168
status = self.getStatusText(iface.status(), statustext)
201
170
coverart = iface.get_cover_path()
203
172
# if cover art found then use it, otherwise use default coverart image for this plugin
204
173
if len(coverart) > 0 and coverart.find("nocover.png") == -1:
205
174
coverart ="file://"+urllib.quote(coverart.encode("utf-8"))
207
176
coverart = unknown_coverart
209
178
length = iface.get_length()
210
179
title = iface.get_title()
211
180
album = iface.get_album()
224
193
current_position_percent = "0"
225
194
current_position = "0:00"
227
196
volume = str(int(iface.get_volume().split(".")[0]))
228
197
rating = str(int(iface.get_rating()))
230
199
self.musicData = MusicData(status,coverart,title,album,length,artist,tracknumber,genre,year,filename,current_position_percent,current_position,rating,volume)
232
201
except Exception, e:
233
202
self.logger.error("Issue calling the dbus service:"+e.__str__()+"\n"+traceback.format_exc())
235
204
if self.musicData != None:
237
206
self.logger.info("Preparing output for datatype:"+datatype)
239
208
if datatype == "ST": #status
240
209
if self.musicData.status == None or len(self.musicData.status) == 0:
243
output = self.getHTMLText(self.musicData.status)
212
output = getHTMLText(self.musicData.status)
245
214
elif datatype == "CA": #coverart
246
215
if self.musicData.coverart == None or len(self.musicData.coverart) == 0:
249
218
output = self.musicData.coverart
251
220
elif datatype == "TI": #title
252
221
if self.musicData.title == None or len(self.musicData.title) == 0:
255
output = self.getHTMLText(self.musicData.title)
224
output = getHTMLText(self.musicData.title)
257
226
elif datatype == "AL": #album
258
227
if self.musicData.album == None or len(self.musicData.album) == 0:
261
output = self.getHTMLText(self.musicData.album)
230
output = getHTMLText(self.musicData.album)
263
232
elif datatype == "AR": #artist
264
233
if self.musicData.artist == None or len(self.musicData.artist) == 0:
267
output = self.getHTMLText(self.musicData.artist)
236
output = getHTMLText(self.musicData.artist)
269
238
elif datatype == "GE": #genre
270
239
if self.musicData.title == genre or len(self.musicData.genre) == 0:
273
output = self.getHTMLText(self.musicData.genre)
242
output = getHTMLText(self.musicData.genre)
275
244
elif datatype == "YR": #year
276
245
if self.musicData.year == None or len(self.musicData.year) == 0:
279
248
output = self.musicData.year
281
250
elif datatype == "TN": #tracknumber
282
251
if self.musicData.tracknumber == None or len(self.musicData.tracknumber) == 0:
285
254
output = self.musicData.tracknumber
287
256
elif datatype == "FN": #filename
288
257
if self.musicData.filename == None or len(self.musicData.filename) == 0:
291
output = self.getHTMLText(self.musicData.filename)
260
output = getHTMLText(self.musicData.filename)
293
262
elif datatype == "LE": # length
294
263
if self.musicData.length == None or len(self.musicData.length) == 0:
297
266
output = self.musicData.length
299
268
elif datatype == "PP": #current position in percent
300
269
if self.musicData.current_position_percent == None or len(self.musicData.current_position_percent) == 0:
303
272
output = self.musicData.current_position_percent
305
274
elif datatype == "PT": #current position in time
306
275
if self.musicData.current_position == None or len(self.musicData.current_position) == 0:
309
278
output = self.musicData.current_position
311
280
elif datatype == "VO": #volume
312
281
if self.musicData.volume == None or len(self.musicData.volume) == 0:
315
284
output = self.musicData.volume
317
286
elif datatype == "RT": #rating
318
287
if self.musicData.rating == None or self.isNumeric(self.musicData.rating) == False:
341
310
output = unknown_rating
343
312
output = unknown_string
347
316
def getStatusText(self, status, statustext):
350
319
statustextparts = statustext.split(",")
352
321
if status == "playing":
353
322
return statustextparts[0]
354
323
elif status == "paused":
355
324
return statustextparts[1]
356
325
elif status == "stopped":
357
326
return statustextparts[2]
363
332
def getTemplateItemOutput(self, template_text):
365
334
# keys to template data
366
335
DATATYPE_KEY = "datatype"
367
336
STATUSTEXT_KEY = "statustext"
368
337
NOUNKNOWNOUTPUT_KEY = "nounknownoutput"
371
340
statustext = self.config.STATUSTEXT #default to command line option
372
341
nounknownoutput = self.config.NOUNKNOWNOUTPUT #default to command line option
374
343
for option in template_text.split('--'):
375
344
if len(option) == 0 or option.isspace():
378
347
# not using split here...it can't assign both key and value in one call, this should be faster
379
348
x = option.find('=')
545
519
if __name__ == "__main__":
547
521
parser = OptionParser()
548
parser.add_option("--noheader", dest="noheader", default=False, action="store_true", help=u"Turn off header output. This will override any header template setting to be nothing")
522
parser.add_option("--noheader", dest="noheader", default=False, action="store_true", help=u"Turn off header output. This will override any header template setting to be nothing")
549
523
parser.add_option("--headertemplate", dest="headertemplate", type="string", metavar="FILE", help=u"Override the header template for the plugin, default or config based template ignored.")
550
524
parser.add_option("--template", dest="template", type="string", metavar="FILE", help=u"Override the template for the plugin, default or config based template ignored.")
551
525
parser.add_option("--verbose", dest="verbose", default=False, action="store_true", help=u"Outputs verbose info to the terminal")
552
526
parser.add_option("--version", dest="version", default=False, action="store_true", help=u"Displays the version of the script.")
553
parser.add_option("--logfile", dest="logfile", type="string", metavar="FILE", help=u"If a filepath is set, the script logs to the filepath.")
527
parser.add_option("--logfile", dest="logfile", type="string", metavar="FILE", help=u"If a filepath is set, the script logs to the filepath.")
555
529
(options, args) = parser.parse_args()
557
531
output = Output(options)
558
532
html = output.getOutput()