Mutagen (http://code.google.com/p/mutagen/) is a Python module to handle
audio metadata. It supports ASF, FLAC, M4A, Monkey's Audio, MP3,
Musepack, Ogg FLAC, Ogg Speex, Ogg Theora, Ogg Vorbis, True Audio,
WavPack and OptimFROG audio files. All versions of ID3v2 are supported,
and all standard ID3v2.4 frames are parsed.
This is a preliminary version, it only works with ID3 tags.
diff --git a/sonata/main.py b/sonata/main.py
index 871d791..324b690 100644
--- a/sonata/main.py
+++ b/sonata/main.py
@@ -267,6 +267,7 @@ class Base(object):
]
keyactions = [
+ ('tagkey2', None, 'Edit Tags', '<Ctrl>e', None, self.on_tags_edit),
('expandkey', None, 'Expand Key', '<Alt>Down', None, self.on_expand),
('collapsekey', None, 'Collapse Key', '<Alt>Up', None, self.on_collapse),
('ppkey', None, 'Play/Pause Key', '<Ctrl>p', None, self.mpd_pp),
diff --git a/sonata/tagedit.py b/sonata/tagedit.py
index 05e040d..c5b7d5e 100644
--- a/sonata/tagedit.py
+++ b/sonata/tagedit.py
@@ -13,11 +13,10 @@ import os
import re
import gtk, gobject
-tagpy = None # module loaded when needed
+EasyID3 = None # module loaded when needed
import ui, misc
-
class TagEditor():
"""This class implements a dialog for editing music metadata tags.
@@ -53,23 +52,14 @@ class TagEditor():
def on_tags_edit(self, files, temp_mpdpaths, music_dir):
"""Display the editing dialog"""
# Try loading module
- global tagpy
- if tagpy is None:
+ global EasyID3
+ if EasyID3 is None:
try:
- import tagpy
+ from mutagen.easyid3 import EasyID3
except ImportError:
- ui.show_msg(self.window, _("Taglib and/or tagpy not found, tag editing support disabled."), _("Edit Tags"), 'editTagsError', gtk.BUTTONS_CLOSE, response_cb=ui.dialog_destroy)
+ ui.show_msg(self.window, _("Mutagen not found, tag editing support disabled."), _("Edit Tags"), 'editTagsError', gtk.BUTTONS_CLOSE, response_cb=ui.dialog_destroy)
ui.change_cursor(None)
return
- # Set default tag encoding to utf8.. fixes some reported bugs.
- import tagpy.id3v2 as id3v2
- id3v2.FrameFactory.instance().setDefaultTextEncoding(tagpy.StringType.UTF8)
-
- # Make sure tagpy is at least 0.91
- if hasattr(tagpy.Tag.title, '__call__'):
- ui.show_msg(self.window, _("Tagpy version < 0.91. Please upgrade to a newer version, tag editing support disabled."), _("Edit Tags"), 'editTagsError', gtk.BUTTONS_CLOSE, response_cb=ui.dialog_destroy)
- ui.change_cursor(None)
- return
if not os.path.isdir(misc.file_from_utf8(music_dir)):
ui.show_msg(self.window, _("The path %s does not exist. Please specify a valid music directory in preferences.") % music_dir, _("Edit Tags"), 'editTagsError', gtk.BUTTONS_CLOSE, response_cb=ui.dialog_destroy)
@@ -85,10 +75,10 @@ class TagEditor():
# Initialize:
self.tagnum = -1
- tags = [{'title':'', 'artist':'', 'album':'', 'year':'', 'track':'',
- 'genre':'', 'comment':'', 'title-changed':False,
+ tags = [{'title':'', 'artist':'', 'album':'', 'date':'', 'tracknumber':'',
+ 'genre':'', 'title-changed':False,
'artist-changed':False, 'album-changed':False,
- 'year-changed':False, 'track-changed':False,
+ 'date-changed':False, 'tracknumber-changed':False,
'genre-changed':False, 'comment-changed':False,
'fullpath':misc.file_from_utf8(filename),
'mpdpath':path}
@@ -102,8 +92,8 @@ class TagEditor():
ui.change_cursor(None)
ui.show_msg(self.window, _("No music files with editable tags found."), _("Edit Tags"), 'editTagsError', gtk.BUTTONS_CLOSE, response_cb=ui.dialog_destroy)
return
- editwindow = ui.dialog(parent=self.window, flags=gtk.DIALOG_MODAL, role='editTags', resizable=False, separator=False)
- editwindow.set_size_request(375, -1)
+ editwindow = ui.dialog(parent=self.window, flags=gtk.DIALOG_MODAL, role='editTags', resizable=True, separator=False)
+ editwindow.set_size_request(875, -1)
table = gtk.Table(9, 2, False)
table.set_row_spacings(2)
self.filelabel = ui.label(select=True, wrap=True)
@@ -147,11 +137,10 @@ class TagEditor():
genrehbox.pack_start(genrecombo, True, True, 2)
genrehbox.pack_start(genrebuttonvbox, False, False, 2)
- commentlabel, commententry, commentbutton, commenthbox = self._create_label_entry_button_hbox(_("Comment:"))
-
- ui.set_widths_equal([titlelabel, artistlabel, albumlabel, yearlabel, genrelabel, commentlabel, sonataicon])
+ titlelabel.set_size_request(50,-1)
+ ui.set_widths_equal([titlelabel, artistlabel, albumlabel, yearlabel, genrelabel, sonataicon])
genrecombo.set_size_request(-1, titleentry.size_request()[1])
- tablewidgets = [ui.label(), filehbox, ui.label(), titlehbox, artisthbox, albumhbox, yearandtrackhbox, genrehbox, commenthbox, ui.label()]
+ tablewidgets = [ui.label(), filehbox, ui.label(), titlehbox, artisthbox, albumhbox, yearandtrackhbox, genrehbox, ui.label()]
for i, widget in enumerate(tablewidgets):
table.attach(widget, 1, 2, i+1, i+2, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 2, 0)
editwindow.vbox.pack_start(table)
@@ -163,9 +152,9 @@ class TagEditor():
editwindow.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT)
editwindow.add_button(gtk.STOCK_SAVE, gtk.RESPONSE_ACCEPT)
editwindow.connect('delete_event', self.tags_win_hide, tags)
- entries = [titleentry, artistentry, albumentry, yearentry, trackentry, genreentry, commententry]
- buttons = [titlebutton, artistbutton, albumbutton, yearbutton, trackbutton, genrebutton, commentbutton]
- entries_names = ["title", "artist", "album", "year", "track", "genre", "comment"]
+ entries = [titleentry, artistentry, albumentry, yearentry, trackentry, genreentry]
+ buttons = [titlebutton, artistbutton, albumbutton, yearbutton, trackbutton, genrebutton]
+ entries_names = ["title", "artist", "album", "date", "tracknumber", "genre"]
editwindow.connect('response', self.tags_win_response, tags, entries, entries_names)
if saveall_button:
saveall_button.connect('clicked', self.tags_win_save_all, editwindow, tags, entries, entries_names)
@@ -186,8 +175,8 @@ class TagEditor():
self.tagnum = self.tagnum + 1
if os.path.exists(tags[self.tagnum]['fullpath']):
try:
- fileref = tagpy.FileRef(tags[self.tagnum]['fullpath'])
- if not fileref.isNull():
+ fileref = EasyID3(tags[self.tagnum]['fullpath'])
+ if fileref:
return True
except:
pass
@@ -215,33 +204,35 @@ class TagEditor():
def tags_win_apply_all(self, _button, item, tags, entry):
for tagnum, tag in enumerate(tags):
tagnum = tagnum + 1
- if item in ("title", "album", "artist", "genre", "comment"):
+ if item in ("title", "album", "artist", "genre",):
tag[item] = entry.get_text()
tag[item + '-changed'] = True
- elif item == "year":
+ elif item == "date":
if len(entry.get_text()) > 0:
- tag['year'] = int(entry.get_text())
+ tag['date'] = int(entry.get_text())
else:
- tag['year'] = 0
- tag['year-changed'] = True
+ tag['date'] = 0
+ tag['date-changed'] = True
elif item == "track":
if tagnum >= self.tagnum-1:
# Start the current song at track 1, as opposed to the first
# song in the list.
- tag['track'] = tagnum - self.tagnum
- tag['track-changed'] = True
- if item == "track":
+ tag['tracknember'] = tagnum - self.tagnum
+ tag['tracknumber-changed'] = True
+ if item == "tracknumber":
# Update the entry for the current song:
- entry.set_text(str(tags[self.tagnum]['track']))
+ entry.set_text(str(tags[self.tagnum]['tracknumber']))
def tags_win_update(self, window, tags, entries, entries_names):
current_tag = tags[self.tagnum]
- tag = tagpy.FileRef(current_tag['fullpath']).tag()
+ tag = EasyID3(current_tag['fullpath'])
# Update interface:
for entry, entry_name in zip(entries, entries_names):
# Only retrieve info from the file if the info hasn't changed
if not current_tag[entry_name + "-changed"]:
- current_tag[entry_name] = getattr(tag, entry_name, '')
+ ulist = tag.get(entry_name, '')
+ if isinstance(ulist, list) and len(ulist) > 0:
+ current_tag[entry_name] = ulist[0]
tag_value = current_tag[entry_name]
if tag_value == 0:
tag_value = ''
@@ -281,21 +272,19 @@ class TagEditor():
window.action_area.set_sensitive(False)
while window.action_area.get_property("sensitive") or gtk.events_pending():
gtk.main_iteration()
- filetag = tagpy.FileRef(tags[self.tagnum]['fullpath'])
- tag = filetag.tag()
+ tag = EasyID3(tags[self.tagnum]['fullpath'])
# Set tag fields according to entry text
for entry, field in zip(entries, entries_names):
tag_value = entry.get_text().strip()
- if field in ('year', 'track'):
- if len(tag_value) == 0:
- tag_value = '0'
- tag_value = int(tag_value)
- if field is 'comment':
- if len(tag_value) == 0:
- tag_value = ' '
- setattr(tag, field, tag_value)
-
- save_success = filetag.save()
+ tag[field] = tag_value
+
+ save_success = True
+ try:
+ tag.save()
+ except:
+ print "Error saving tag into '%s':" % tags[self.tagnum]['fullpath']
+ traceback.print_exc()
+ save_success = False
if not (save_success): # FIXME: was (save_success and self.conn and self.status):
ui.show_msg(self.window, _("Unable to save tag to music file."), _("Edit Tags"), 'editTagsError', gtk.BUTTONS_CLOSE, response_cb=ui.dialog_destroy)
if self.tags_next_tag(tags):
_______________________________________________
Sonata-users mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/sonata-users