オーディオプレーヤ "Exaile"の曲情報取得プラグイン(pyGrabCDInfo)
Exaileのプラグインを作ってみました。(Linux環境でのみ動作確認を行っています)
pyGrabCDInfo.pyというファイルのみです。
pyGrabCDInfo.pyを ~/.exaile/plugins/に置き、Exaileを再起動してください。
pyGrabCDInfo.pyを ~/.exaile/plugins/に置き、Exaileを再起動してください。
Exaile起動後、PluginManagerを開いて、Enableチェックボックスを
ONにすることで有効になります。
ONにすることで有効になります。
このプラグインが有効になっている状態でExaileが起動すると、
Exaileのウインドウに”grabCDDB”というボタンが追加されています。
Exaileのウインドウに”grabCDDB”というボタンが追加されています。
ネットワークに接続されている状態で、PCにCDをトレイに挿入し、
CDの曲名を表示してください(FileメニューのOpenDiscを選択)。
CDの曲名を表示してください(FileメニューのOpenDiscを選択)。
CDの情報がExaileのウインドウに表示された後、もし文字化けが
あった場合には、grabCDDBボタンをおせば、ネットワーク経由で情報を
再取得し、文字化けを解消してくれます。(きっと)
あった場合には、grabCDDBボタンをおせば、ネットワーク経由で情報を
再取得し、文字化けを解消してくれます。(きっと)
実行するためには、以下のものが必要です。
- exaile
- python
- pygtk
- CDDB
- DiscID
- httplib
- xml.sax
ソースコードは以下の通りです。
(実際のスクリプトファイルはこのページの一番下に添付してあります)
(実際のスクリプトファイルはこのページの一番下に添付してあります)
import gtk import plugins import CDDB import DiscID import httplib import xml.sax from xml.sax.handler import ContentHandler PLUGIN_NAME = 'CD InfoGraber' PLUGIN_AUTHORS = ['kani <jkani4@gmail.com>'] PLUGIN_VERSION = '0.1' PLUGIN_ENABLED = False PLUGIN_DESCRIPTION = r'''Get CD Information such as album name from freedb2.org.''' b = gtk.Button() PLUGIN_ICON = b.render_icon(gtk.STOCK_MEDIA_PLAY, gtk.ICON_SIZE_MENU) b.destroy() URL_CDDB_TRACKTYPE_ORG = 'http://tracktype.org:80/~cddb/cddb.cgi' URL_FREEDB2_ORG = 'www.freedb2.org' CONNS = plugins.SignalContainer() ## def get_conf_str(name, defStr): return APP.settings.get_str(name, default=defStr, plugin=plugins.name(__file__)) ## def set_conf_str(name, someStr): APP.settings.set_str(name, someStr, plugin=plugins.name(__file__)) # # class Freedb2XMLHandler(ContentHandler): ## def __init__(self): ContentHandler.__init__(self) self.album = '' self.artist = '' self.year = '' self.genre = '' self.trackNames = {} self.tmpStr = '' self.inTrack = False self.trackNo = '' self.tagDict = {'artist': 0, 'title': 1, 'year': 2, 'genre': 3, 'track': 4, 'number': 5 } ## def startElement(self, name, attrs): self.tmpStr = '' if name in self.tagDict: if self.tagDict[name] == self.tagDict['track']: self.inTrack = True self.trackNo = '' ## def endElement(self, name): if not name in self.tagDict: return tagType = self.tagDict[name] if tagType == self.tagDict['artist']: self.artist += self.tmpStr elif tagType == self.tagDict['title']: if self.inTrack: self.trackNames[int(self.trackNo)] = self.tmpStr else: self.album += self.tmpStr elif tagType == self.tagDict['number']: self.trackNo += self.tmpStr elif tagType == self.tagDict['year']: self.year += self.tmpStr elif tagType == self.tagDict['genre']: self.genre += self.tmpStr if tagType == self.tagDict['track']: self.inTrack = False ## def characters(self, content): self.tmpStr += content ## def count_tracks(self): return len(self.trackNames) ## def get_track_name(self, trackNo): if trackNo in self.trackNames: return self.trackNames[trackNo] return '' ## def get_track_name_dict(self): return self.trackNames ## def get_artist(self): return self.artist ## def get_album(self): return self.album ## def get_year(self): return self.year ## def get_genre(self): return self.genre # # def showErrorMsg(msgStr): if len(msgStr) == 0: return dialog = gtk.MessageDialog(APP.window, buttons=gtk.BUTTONS_OK, type=gtk.MESSAGE_INFO, message_format=msgStr) dialog.run() dialog.destroy() # # def update_track_info(trackList, artist, album, year, genre, trackNames): if trackList == None: return trkCnt = len(trackNames) if trkCnt == 0: showErrorMsg('Current playlist has no tracks..') return songs = trackList.get_songs() if songs == None: return if len(songs) != trkCnt: showErrorMsg("The number of track in the current playlist is different from CDDB's one ") return for i in range(trkCnt): songs[i].title = trackNames[i+1] songs[i].album = album songs[i].artist = artist songs[i].year = year songs[i].genre = genre trackList.set_songs(songs) # # def get_cd_category_and_discid(cdDevice, serverURL): category = '' discID = '' try: disc = DiscID.open(cdDevice) disc_info = DiscID.disc_id(disc) (status, info) = CDDB.query(disc_info, serverURL) except: showErrorMsg('can not get cddb information. ') return (category, discID) # status # 200 : success # 210 : multiple inexact maches ware found # 211 : multiple exact maches ware found # other: error if status in [210, 211]: info = info[0] status = 200 if status == 200: category = info['category'] discID = info['disc_id'] return (category, discID) # # def grab_cd_info(widget, app): if app == None: return if app.tracks == None or len(app.tracks.get_songs()) == 0: showErrorMsg('There are no tracks selected.') return # # Get categroy and disc_id of CD that is in the cd drive. # device = APP.settings.get_str('cd_device', '/dev/cdrom') try: (category, discID) = get_cd_category_and_discid(device, URL_CDDB_TRACKTYPE_ORG) if category == '' or discID == '': raise -1 except: showErrorMsg('Can not get category or disc_id.') progWind.close() return # # Connect to www.freedb2.org, and get cd information in xml format. # try: con = httplib.HTTPConnection(URL_FREEDB2_ORG) con.request('GET','/xml/%s/%s' % (category, discID), body='', headers={'User-Agent': 'Python/2.5'}) except: showErrorMsg('Can not get xml from www.freedb2.org') progWind.close() return # # Parse xml # try: handler = Freedb2XMLHandler() response = con.getresponse() xmldata = response.read() parser = xml.sax.make_parser() parser.setContentHandler(handler) parser.feed(xmldata) except: showErrorMsg('Can not parse xml.') progWind.close() return if handler.count_tracks() == 0: showErrorMsg('there is no tracks.') progWind.close() return # # Update the current playlist with grabbed information. # update_track_info(app.tracks, handler.get_artist(), handler.get_album(), handler.get_year(), handler.get_genre(), handler.get_track_name_dict()) ### # # Below describes functions for exaile plugin. # ### gToolBar = None gCnvButton = None # # def initialize(): ''' Called when the plugin is enabled. ''' # # Append custom button to reload audio cd track information # from CDDB global gToolBar global gCnvButton if gCnvButton == None: gToolBar = APP.xml.get_widget('play_toolbar') gCnvButton = gtk.Button('grabCDDB') gToolBar.pack_start(gCnvButton, True, False, 0) gToolBar.show_all() gCnvButton.connect('clicked', grab_cd_info, APP) return True # # def destroy(): ''' Called when the plugin is disabled. ''' pass
添付ファイル