$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) :
+ pos = self.logfile.tell()
+ self.logfile.seek(0)
+ ret = m(self, *args, **kw)
+ self.logfile.seek(pos)
+ return ret
+ return readinplace
+
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
firstline = self.next()
assert firstline == SUPPORTED_FILE_HEADER
-
+
+ @inplaceread
def getSongFile(self) :
"retourne le chemin d'accès au fichier musicxml de la chanson"
- f = self.logfile
- pos = f.tell()
-
- f.seek(0)
for l in self :
if l.startswith('APP chanson :') :
break
songfile = l.split(':', 1)[1].strip()
- f.seek(pos)
return songfile
+ @inplaceread
def getSoundFontFile(self) :
"retourne le chemin d'accès au fichier de la soundfont (*.sf2)"
- f = self.logfile
- pos = f.tell()
- f.seek(0)
for l in self :
if l.startswith('ENV soundfont :') :
break
soundFontFile = l.split(':', 1)[1].strip()
- f.seek(pos)
return soundFontFile
-
+
+ @inplaceread
def getBank(self) :
"retourne le paramètre bank du synthétiseur (entier)"
- f = self.logfile
- pos = f.tell()
- f.seek(0)
for l in self :
if l.startswith('APP bank :') :
break
- f.seek(pos)
bank = l.split(':', 1)[1].strip()
return int(bank)
+ @inplaceread
def getPreset(self) :
"retourne le paramètre preset du synthétiseur (entier)"
- f = self.logfile
- pos = f.tell()
- f.seek(0)
for l in self :
if l.startswith('APP preset :') :
break
- f.seek(pos)
preset = l.split(':', 1)[1].strip()
return int(preset)
+ @inplaceread
def getScreenResolution(self) :
"retourne la résolution écran (tuple de deux entiers)"
- f = self.logfile
- pos = f.tell()
- f.seek(0)
for l in self :
if l.startswith('ENV résolution écran :') :
break
screenResolution = eval(l.split(':', 1)[1].strip())
- f.seek(pos)
return screenResolution
+ @inplaceread
def getMode(self) :
"retourne le niveau de difficulté"
- f = self.logfile
- pos = f.tell()
for l in self :
if l.startswith('APP mode :') :
break
mode = l.split(':', 1)[1].strip()
- f.geek(pos)
return mode
+ @inplaceread
def getFirstEventTicks(self) :
"retourne le timecode du premier événement (entier)"
- f = self.logfile
- pos = f.tell()
- f.seek(0)
for l in self :
if l.startswith('EVT ') :
break
firstTicks = int(l.split(None, 2)[1])
- f.seek(pos)
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
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()
+ after = 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) :
previousTicks = ticks
self.stop()
-
\ No newline at end of file