X-Git-Url: https://scm.cri.mines-paristech.fr/git/minwii.git/blobdiff_plain/03cc372eac638f066800c45d6929b2b50701f36e..21d52be27b76c9db94e784393f1748e403dd0c47:/src/minwii/logfilereader.py diff --git a/src/minwii/logfilereader.py b/src/minwii/logfilereader.py index a08855a..57cdc60 100755 --- a/src/minwii/logfilereader.py +++ b/src/minwii/logfilereader.py @@ -6,20 +6,23 @@ $Id$ $URL$ """ +from types import StringTypes from widgets.playingscreen import PlayingScreenBase from eventutils import EventDispatcher from events import eventCodes from synth import Synth from musicxml import musicXml2Song import pygame +from backwardsfilereader import BackwardsReader SUPPORTED_FILE_HEADER = 'ENV winwii log format version : 1.0' def inplaceread(m) : def readinplace(self, *args, **kw) : - self.savePos() + pos = self.logfile.tell() + self.logfile.seek(0) ret = m(self, *args, **kw) - self.recallPos() + self.logfile.seek(pos) return ret return readinplace @@ -28,27 +31,19 @@ class LogFileReader(object) : classe utilitaire pour l'accès aux données d'un fichier de log MinWii. """ - def __init__(self, logfile) : + def __init__(self, logfile, mode='r') : """ logfile : chemin d'accès au fichier de log MinWii. le format supporté est actuellement la version 1.0 uniquement. """ - if isinstance(logfile, str) : - self.logfile = open(logfile, 'r') + if isinstance(logfile, StringTypes) : + self.logfile = open(logfile, mode) else : self.logfile = logfile - self.__pos = 0 - firstline = self.next() assert firstline == SUPPORTED_FILE_HEADER - def savePos(self) : - self.__pos = self.logfile.tell() - self.logfile.seek(0) - - def recallPos(self) : - self.logfile.seek(self.__pos) - + @inplaceread def getSongFile(self) : "retourne le chemin d'accès au fichier musicxml de la chanson" @@ -104,6 +99,16 @@ class LogFileReader(object) : mode = l.split(':', 1)[1].strip() return mode + @inplaceread + def getHID(self) : + "retourne l'interface homme-machine utilisée" + for l in self : + if l.startswith('APP HID :') : + break + + mode = l.split(':', 1)[1].strip() + return mode + @inplaceread def getFirstEventTicks(self) : "retourne le timecode du premier événement (entier)" @@ -113,8 +118,20 @@ class LogFileReader(object) : firstTicks = int(l.split(None, 2)[1]) return firstTicks + @inplaceread + def getLastEventTicks(self) : + "retourne le timecode du dernier événement (entier)" + for l in self.getBackwardLineIterator() : + if l.startswith('EVT ') : + break + else : + return None + + lastTicks = int(l.split(None, 2)[1]) + return lastTicks + def __del__(self) : - self.logfile.close() + self.close() def __iter__(self) : return self @@ -146,6 +163,47 @@ class LogFileReader(object) : ticks, eventName = l.split(None, 3)[1:] ticks = int(ticks) yield ticks, eventName, '' + + def getBackwardLineIterator(self) : + br = BackwardsReader(self.logfile, BLKSIZE=128) + line = br.readline() + while line : + yield line.strip() + line = br.readline() + + @inplaceread + def getMetadata(self) : + metadata = {} + self.next() # skip identification line. + line = self.next() + while line.startswith('METADATA ') : + line = line.split(None, 1)[1] + name, value = [v.strip() for v in line.split(':', 1)] + metadata[name] = value + line = self.next() + return metadata + + def setMetadata(self, metadata) : + f = self.logfile + f.seek(0) + before = f.readline() + line = f.readline() + while line.startswith('METADATA ') : + line = f.readline() + after = line + f.read() + + lines = [] + for name, value in metadata : + lines.append('METADATA %s : %s' % (name, value.encode('utf-8'))) + metadata = '\n'.join(lines) + f.seek(0) + f.write(before) + f.write(metadata) + f.write(after) + + def close(self) : + self.logfile.close() + class LogFilePlayer(PlayingScreenBase) : @@ -217,5 +275,4 @@ class LogFilePlayer(PlayingScreenBase) : previousTicks = ticks self.stop() - \ No newline at end of file