diff --git a/mode/mp3.py b/mode/mp3.py new file mode 100644 index 0000000..fb0aa77 --- /dev/null +++ b/mode/mp3.py @@ -0,0 +1,113 @@ +import commands, dirutil, grp, mailbox, method, mode, os.path, pwd, re, sys +import buffer, default, window +from mode.mutt import MuttGrammar +from lex import Grammar, PatternRule, RegionRule, PatternGroupRule +from point import Point +from buffer import Buffer +from method import Method, Argument, arg + +try: + import eyeD3 + has_eyed3 = True +except ImportError: + has_eyed3 = False + +def _str_info(s): + if s: + return str(s) + else: + return '' +def _num_pair_info(t): + if t[0] and t[1]: + return '%s/%s' % t + elif t[0]: + return str(t[0]) + elif t[1]: + return '/%s' % t[1] + else: + return '' +class Mp3Buffer(Buffer): + btype = 'mp3' + def __init__(self, path): + Buffer.__init__(self) + self.path = os.path.realpath(path) + self.base = os.path.basename(self.path) + self.tag = eyeD3.Tag() + self.tag.link(self.path) + def changed(self): return False + def readonly(self): return True + def path_exists(self): raise Exception + def _make_path(self, name): raise Exception + def save(self, force=False): raise Exception, "can't save an mbox" + def save_as(self, path): raise Exception, "can't save an mbox" + def name(self): return 'mp3:%s' % (self.base) + def open(self): + self.lines = self._get_lines() + def reload(self): + lines = self._get_lines() + self.set_lines(lines, force=True) + def _get_lines(self): + lines = [ + '# INFO', + 'Size: 666KB', + '# ID3', + 'Artist: ' + _str_info(self.tag.getArtist()), + 'Album: ' + _str_info(self.tag.getAlbum()), + 'BPM: ' + _str_info(self.tag.getBPM()), + #'CDID: ' + str(self.tag.getCDID()), #xyz + 'Comment: ' + _str_info(self.tag.getComment()), + 'DiscNum: ' + _num_pair_info(self.tag.getDiscNum()), + 'Genre: ' + _str_info(self.tag.getGenre()), + 'Publisher: ' + _str_info(self.tag.getPublisher()), + 'Title: ' + _str_info(self.tag.getTitle()), + 'TrackNum: ' + _num_pair_info(self.tag.getTrackNum()), + #'Version: ' + _str_info(self.tag.getVersion()), + 'Year: ' + _str_info(self.tag.getYear()), + '', + ] + return lines + +class TagGrammar(Grammar): + rules = [ + PatternRule(r'data', r'[^\\\n]+'), + PatternRule(r'escaped', r'\\x[0-9a-fA-F]{2}'), + ] +class Mp3Grammar(Grammar): + rules = [ + PatternRule(r'comment', r'#.*\n$'), + PatternRule(r'mp3_label', r'^[^:]+(?=: )'), + RegionRule(r'mp3_tag', r': ', TagGrammar, r'\n$'), + ] + +class Mp3Refresh(Method): + def _execute(self, w, **vargs): + w.buffer.reload() + +class Mp3OpenPath(Method): + args = [arg('mp3', dt="path", p="Open MP3: ", dv=default.path_dirname, + ld=True, h="mp3 to open")] + def _execute(self, w, **vargs): + b = Mp3Buffer(vargs['mp3']) + b.open() + window.Window(b, w.application, height=0, width=0, mode_name='mp3') + w.application.add_buffer(b) + w.application.switch_buffer(b) + +class Mp3(mode.Fundamental): + modename = 'Mp3' + grammar = Mp3Grammar + actions = [Mp3Refresh, Mp3OpenPath] + colors = { + 'mp3_label': ('blue', 'default', 'bold'), + 'mp3_tag.start': ('default', 'default', 'bold'), + 'mp3_tag.data': ('green', 'default', 'bold'), + 'mp3_tag.escaped': ('magenta', 'default', 'bold'), + } + def __init__(self, w): + mode.Fundamental.__init__(self, w) + self.add_bindings('mp3-refresh', ('C-c r',)) + +if has_eyed3: + install = Mp3.install +else: + install = lambda *args: None