Author: duncan
Date: Fri Mar 9 18:17:01 2007
New Revision: 9311
Added:
branches/rel-1/freevo/src/audio/plugins/musicip.py (contents, props
changed)
Log:
[ 1676991 ] MusicIP Mixer Plugin
Plug-in by Dobes Vandermeer added
Added: branches/rel-1/freevo/src/audio/plugins/musicip.py
==============================================================================
--- (empty file)
+++ branches/rel-1/freevo/src/audio/plugins/musicip.py Fri Mar 9 18:17:01 2007
@@ -0,0 +1,325 @@
+# -*- coding: iso-8859-1 -*-
+# -----------------------------------------------------------------------
+# musicip.py - MusicIP Mixer plugin
+# -----------------------------------------------------------------------
+# $Id$
+#
+# Author:
+# Dobes Vandermeer <[EMAIL PROTECTED]>
+# Notes:
+# HACK - sadly there's no way to import from the playlist module
+# since there's another playlis module in this same package.
+# Todo:
+#
+# -----------------------------------------------------------------------
+# Freevo - A Home Theater PC framework
+# Copyright (C) 2002 Krister Lagerstrom, et al.
+# Please see the file freevo/Docs/CREDITS for a complete list of authors.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MER-
+# CHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+# Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# -----------------------------------------------------------------------
+
+
+from gui.PopupBox import PopupBox
+from directory import Playlist
+import plugin
+import config
+import time
+
+from urllib import urlencode
+from httplib import HTTPConnection
+
+class MusicIPException(Exception):
+ pass
+
+class MusicIPClient:
+ def __init__(self, host):
+ self.host = host
+ self.connection = HTTPConnection(host)
+
+ def callApi(self, func, args=None):
+ url = '/api/'+func
+ if args:
+ url += '?' + urlencode(args)
+ #print '[MusicIP Mixer] Fetching', url, 'from', self.host
+ self.connection.request("GET", url)
+ response = self.connection.getresponse()
+ if response.status != 200:
+ raise MusicIPException(response.read())
+ return response.read()
+
+ def getArtists(self, filter=None, showCounts=False):
+ """
+ Returns a list of all the artists.
+
+ Parameters are:
+
+ filter=name Use the named filter when creating the list (default none)
+ If there is no such filter the name may refer to a genre as an
implicit filter. 1.5
+ showCount Prefix each artist with the number of songs by that artist
+ """
+ args = {}
+ if filter: args["filter"] = filter
+ if showCounts: args["showCounts"] = 1
+ return self.callApi("artists", args).split('\n')
+
+ def getAlbums(self, artist=None, bysong=False, extended=False,
filter=None, showCount=None):
+ """
+ Returns a list of all the albums.
+
+ Parameters are:
+
+ artist=name Only include albums with at least one song by the named
artist
+ bysong Return key song from each album (useful for other api calls) 1.5
+ extended Return album in artist@@name format 1.5
+ filter=name Use the named filter when creating the list (default none)
+ If there is no such filter the name may refer to a genre as an
implicit filter. 1.5
+ showCount Prefix each album with the number of songs on that album
+ """
+ args = {}
+ if artist: args["artist"] = artist
+ if bysong: args["bysong"] = 1
+ if extended: args["extended"] = 1
+ if filter: args["filter"] = filter
+ if showCount: args["showCount"] = 1
+ return self.callApi("albums", args).split('\n')
+
+ def getGenres(self, filter=None, showCount=False):
+ """
+ Returns a list of all the genres. Parameters are: filter=name Use the
+ named filter when creating the list (default none) 1.6 showCount
Prefix each
+ genres with the number of songs in that genre
+ """
+ args = {}
+ if filter: args["filter"] = filter
+ if showCount: args["showCount"] = 1
+ return self.callApi("genres", args).split('\n')
+
+ def getMix(self, song=None, artist=None, album=None, mixgenre=None,
mood=None, playlist=None, rejectsize=None,
+ rejecttype=None, size=None, sizetype=None, style=None,
variety=None, filter=None,
+ content=None):
+ """
+ Return a dynamic playlist. Parameters are: song=fullpath Choose a seed
song
+ artist=name Choose a seed artist
+ album=fullpath Choose a seed album. fullpath is any song from the album
+ album=artistname@@albumname Choose a seed album. (example: "The
Beatles@@The White Album")
+ mixgenre=boolean Restrict mix to the genre of the seed 1.1.6
+ mood=name Make a mood mix based on the given mood 1.5
+ playlist=name||fullpath Choose all songs in the playlist as seeds
1.1.5.1
+ rejectsize=# Set the number of items to skip before repeating artists
1.1.6
+ rejecttype=(tracks|min|mbytes) Set the units for rejectsize (default
tracks) 1.1.6
+ size=# Set the size of the list (default 12)
+ sizetype=(tracks|min|mbytes) Set the units for size (default tracks)
+ style=# Set the style slider (default 20, range is 0..200)
+ variety=# Set the variety slider (default 0, range is 0..9))
+ filter=name Use the named filter when creating the playlist (default
none)
+ If there is no such filter, the name may refer to a genre as an
implicit filter.
+ content=(json|m3u|text|xspf) Set the returned mime type (default text)
+ json|xspf requires 1.5
+ short Return short-style names (Windows only) 1.1.4
+ You may specify any number of songs, artists or albums as seeds, but
+ you may not mix different types in a single request. If no seeds are
set, a
+ random song will be chosen from within the current filter.
+
+ As of version 1.1.4, the above default values are replaced with the
+ current application settings from the mix preferences.
+ """
+ args = {}
+ if song: args["song"] = song
+ if album: args["album"] = album
+ if artist: args["artist"] = artist
+ if mixgenre: args["mixgenre"] = mixgenre
+ if mood: args["mood"] = mood
+ if playlist: args["playlist"] = playlist
+ if rejectsize: args["rejectsize"] = rejectsize
+ if rejecttype: args["rejecttype"] = rejecttype
+ if size: args["size"] = size
+ if sizetype: args["sizetype"] = sizetype
+ if style: args["style"] = style
+ if variety: args["variety"] = variety
+ if filter: args["filter"] = filter
+ if content: args["content"] = content
+ data = self.callApi("mix", args)
+ if content is None or content == "text":
+ return data.split('\n')
+ elif content == 'json':
+ import simplejson
+ return simplejson.loads(data)
+ else:
+ return data
+
+ def getMoods(self):
+ """
+ Returns a list of all the moods. Call this without parameters. This
+ will only return information on platforms supporting the Moods menu.
+ """
+ return self.callApi("moods").split()
+
+ def getSongs(self, album=None, artist=None, content=None, filter=None,
extended=None):
+ """
+ Returns a list of all the songs (as a playlist). As of version 1.5, if
+ you pass no artists or albums, all songs are returned. Parameters are:
+ album=fullpath Only include songs from the named album. fullpath is
any song
+ from the album album=artistname@@albumname Only include songs from the
named
+ album. (example: "Pink Floyd@@Dark Side of the Moon")
+ artist=name Only include songs by the named artist
+ content=(json|m3u|text|xspf) Set the returned mime type (default text)
+ json|xspf requires 1.5
+ filter=name Use the named filter when creating the playlist (default
none)
+ If there is no such filter the name may refer to a genre as an
implicit filter. 1.5
+ extended Return extended info for each song (as in the getSong
+ command). This ignores the content and short options.1.5 short Return
+ short-style names (Windows only)
+ """
+ args = {}
+ if album: args["album"] = album
+ if artist: args["artist"] = artist
+ if filter: args["filter"] = filter
+ if content: args["content"] = content
+ data = self.callApi("songs", args)
+ if content is None or content == "text":
+ return data.split('\n')
+ elif content == 'json':
+ import simplejson
+ return simplejson.loads(data)
+ else:
+ return data
+
+ def getSongInfo(self, index=None, file=None):
+ """
+ Returns information about the indicated song. Parameters are: index
+ Choose a song by index file Choose a song by file
+ Returned value is a list of attributes, 1 per line. The first word is
+ the field name, and the rest of the line is the field value. Some
fields may
+ not be present if there is no associated value. Current fields are:
name,
+ artist, album, album-id, file, genre, track, active, seconds,
+ bytes, year, bitrate, composer, conductor, orchestra, lyricist,
+ rating, modified, lastplayed, playcount, added
+
+ """
+ assert index or file, 'Must specify a file or an index'
+ args = {}
+ if index: args["index"] = index
+ if file: args["file"] = file
+ info = {}
+ for line in self.callApi("getSong", args).split('\n'):
+ words = line.split(None,1)
+ if len(words) < 2: continue
+ k,v = words
+ info[k] = v
+ return info
+
+if __name__ == "__main__":
+ client = MusicIPClient("minipc:10002")
+ print client.getMix(artist="Aural Float", size=50, content='json')
+
+class PluginInterface(plugin.ItemPlugin):
+ """
+ This plugin allows you to create a new mix based on MusicIP's automatic
+ mixing feature.
+
+ You may set config.MUSICIP_SERVER to the host:port of the MusicIP service;
+ 127.0.0.1:10002 is the default.
+ """
+
+ def __init__(self):
+ try: server = config.MUSICIP_SERVER
+ except AttributeError: server = "127.0.0.1:10002"
+ self.service = MusicIPClient(server)
+ plugin.ItemPlugin.__init__(self)
+
+
+ def actions(self, item):
+ self.item = item
+
+ items = []
+ if item.type in ('audio', 'playlist'):
+ items.append((self.file_mix, _('MusicIP Mix'), 'musicip_file_mix'))
+ if item.type == 'audio':
+ items.append((self.file_play_album, _('Songs From Same Album'),
'musicip_file_play_album'))
+ items.append((self.file_play_all_by_artist, _('Songs From Same
Artist'), \
+ 'musicip_file_play_all_by_artist'))
+
+
+ return items
+
+ def file_mix(self, arg=None, menuw=None):
+ kwargs = {}
+ try:
+ if self.item.type == 'playlist':
+ filenames = self.service.getMix(playlist=self.item.filename)
+ elif self.item.type == 'audio':
+ filenames = self.service.getMix(song=self.item.filename)
+ else:
+ print 'Bad file type', self.item.type, self.item.filename,
'for MusicIP mix'
+ except MusicIPException, x:
+ pop = PopupBox(text=_(str(x)))
+ pop.show()
+ time.sleep(2)
+ pop.destroy()
+ return
+
+ #file = NamedTemporaryFile(prefix="freevo-musicip-playlist",
suffix=".tmp")
+ #file.write(m3u)
+ #print '\n'.join(filenames)
+ #items = [kaa.beacon.query(filename=f) for f in filenames]
+ playlist = Playlist('MusicIP Mix', playlist=filenames,
display_type="audio", autoplay=True)
+ playlist.browse(arg=arg, menuw=menuw)
+
+ def file_play_album(self, arg=None, menuw=None):
+ kwargs = {}
+ try:
+ if self.item.type == 'audio':
+ songInfo = self.service.getSongInfo(file=self.item.filename)
+ filenames =
self.service.getSongs(album=songInfo['artist']+'@@'+songInfo['album'])
+ else:
+ print 'Bad file type', self.item.type, self.item.filename,
'for MusicIP mix'
+ except MusicIPException, x:
+ pop = PopupBox(text=_(str(x)))
+ pop.show()
+ time.sleep(2)
+ pop.destroy()
+ return
+
+ #file = NamedTemporaryFile(prefix="freevo-musicip-playlist",
suffix=".tmp")
+ #file.write(m3u)
+ #print '\n'.join(filenames)
+ #items = [kaa.beacon.query(filename=f) for f in filenames]
+ playlist = Playlist('%s - %s'%(songInfo['artist'], songInfo['album']),
\
+ playlist=filenames, display_type="audio", autoplay=True)
+ playlist.browse(arg=arg, menuw=menuw)
+
+ def file_play_all_by_artist(self, arg=None, menuw=None):
+ kwargs = {}
+ try:
+ if self.item.type == 'audio':
+ songInfo = self.service.getSongInfo(file=self.item.filename)
+ filenames = self.service.getSongs(artist=songInfo['artist'])
+ else:
+ print 'Bad file type', self.item.type, self.item.filename,
'for MusicIP mix'
+ except MusicIPException, x:
+ pop = PopupBox(text=_(str(x)))
+ pop.show()
+ time.sleep(2)
+ pop.destroy()
+ return
+
+ #file = NamedTemporaryFile(prefix="freevo-musicip-playlist",
suffix=".tmp")
+ #file.write(m3u)
+ #print '\n'.join(filenames)
+ #items = [kaa.beacon.query(filename=f) for f in filenames]
+ playlist = Playlist('Music by '+songInfo['artist'],
playlist=filenames, display_type="audio", autoplay=True)
+ playlist.browse(arg=arg, menuw=menuw)
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Freevo-cvslog mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/freevo-cvslog