From: benoit.pin Date: Fri, 19 Nov 2010 09:17:48 +0000 (+0000) Subject: Ajout, dans le navigateur des chansons, du la taille du clavier, et du niveau de... X-Git-Url: https://svn.cri.ensmp.fr/git/minwii.git/commitdiff_plain/00c7d2ee288d92de01920b31c968ada18651d2a4?hp=ebf72d7fe428b8af78d5b5906c4c01e4ef59447c Ajout, dans le navigateur des chansons, du la taille du clavier, et du niveau de difficulté basé sur les fréquences d'intervalles. git-svn-id: https://svn.cri.ensmp.fr/svn/minwii/trunk@316 fe552daf-6dbe-4428-90eb-1537e0879342 --- diff --git a/src/minwii/widgets/songfilebrowser.py b/src/minwii/widgets/songfilebrowser.py index 99f81da..e4ecf1b 100755 --- a/src/minwii/widgets/songfilebrowser.py +++ b/src/minwii/widgets/songfilebrowser.py @@ -8,7 +8,11 @@ $URL$ from pgu.gui import FileDialog import os +import tempfile from xml.etree import ElementTree +from minwii.musicxml import musicXml2Song + +INDEX_TXT = 'index.txt' class FileOpenDialog(FileDialog): @@ -41,25 +45,148 @@ class FileOpenDialog(FileDialog): files.sort() for i in dirs: self.list.add(i, image=self.dir_img, value=i) - + + xmlFiles = [] for i in files: - if not i.endswith('.xml') : + if not i.endswith('.xml') : continue filepath = os.path.join(self.curdir, i) - self.list.add(FileOpenDialog.getSongTitle(filepath), value=i) + xmlFiles.append(filepath) + # self.list.add(FileOpenDialog.getSongTitle(filepath), value=i) + + if xmlFiles : + printableLines = self.getPrintableLines(xmlFiles) + for l in printableLines : + self.list.add(l[0], value = l[1]) self.list.set_vertical_scroll(0) + def getPrintableLines(self, xmlFiles) : + index = self.getUpdatedIndex(xmlFiles) + + printableLines = [] + for l in index : + l = l.strip() + l = l.split('\t') + printableLines.append(('%s - %s / %s' % (l[2], l[3], l[4]), l[0])) + + return printableLines + + @staticmethod def getSongTitle(file) : it = ElementTree.iterparse(file, ['start', 'end']) creditFound = False + title = os.path.basename(file) for evt, el in it : if el.tag == 'credit' : creditFound = True if el.tag == 'credit-words' and creditFound: - return el.text.encode('iso-8859-1') + title = el.text + break if el.tag == 'part-list' : - # plus de chance de trouver un titre - return os.path.basename(file) \ No newline at end of file + # au delà de ce tag : aucune chance de trouver un titre + break + return title + + @staticmethod + def getSongMetadata(file) : + metadata = {} + metadata['title'] = FileOpenDialog.getSongTitle(file).encode('iso-8859-1') + metadata['mtime'] = str(os.stat(file).st_mtime) + metadata['file'] = os.path.basename(file) + song = musicXml2Song(file) + metadata['distinctNotes'] = len(song.distinctNotes) + + histo = song.intervalsHistogram + coeffInter = reduce(lambda a, b : a + b, + [abs(k) * v for k, v in histo.items()]) + + totInter = reduce(lambda a, b: a+b, histo.values()) + totInter = totInter - histo.get(0, 0) + difficulty = int(round(float(coeffInter) / totInter, 0)) + metadata['difficulty'] = difficulty + + return metadata + + def getUpdatedIndex(self, xmlFiles) : + indexTxtPath = os.path.join(self.curdir, INDEX_TXT) + index = [] + + if not os.path.exists(indexTxtPath) : + musicXmlFound = False + tmp = tempfile.TemporaryFile(mode='r+') + for file in xmlFiles : + try : + metadata = FileOpenDialog.getSongMetadata(file) + musicXmlFound = True + except ValueError, e : + print e + if e.args and e.args[0] == 'not a musicxml file' : + continue + + line = '%(file)s\t%(mtime)s\t%(title)s\t%(distinctNotes)d\t%(difficulty)d\n' % metadata + index.append(line) + tmp.write(line) + + if musicXmlFound : + tmp.seek(0) + indexFile = open(indexTxtPath, 'w') + indexFile.write(tmp.read()) + indexFile.close() + tmp.close() + else : + indexedFiles = {} + indexTxt = open(indexTxtPath, 'r') + + # check if index is up to date, and update entries if so. + for l in filter(None, indexTxt.readlines()) : + parts = l.split('\t') + fileBaseName, modificationTime = parts[0], parts[1] + filePath = os.path.join(self.curdir, fileBaseName) + + if not os.path.exists(filePath) : + continue + + indexedFiles[fileBaseName] = l + currentMtime = str(os.stat(filePath).st_mtime) + + # check modification time missmatch + if currentMtime != modificationTime : + try : + metadata = FileOpenDialog.getSongMetadata(filePath) + musicXmlFound = True + except ValueError, e : + print e + if e.args and e.args[0] == 'not a musicxml file' : + continue + + metadata = FileOpenDialog.getSongMetadata(filePath) + line = '%(file)s\t%(mtime)s\t%(title)s\t%(distinctNotes)d\t%(difficulty)d\n' % metadata + indexedFiles[fileBaseName] = line + + # check for new files. + for file in xmlFiles : + fileBaseName = os.path.basename(file) + if not indexedFiles.has_key(fileBaseName) : + try : + metadata = FileOpenDialog.getSongMetadata(filePath) + musicXmlFound = True + except ValueError, e : + print e + if e.args and e.args[0] == 'not a musicxml file' : + continue + + metadata = FileOpenDialog.getSongMetadata(file) + line = '%(file)s\t%(mtime)s\t%(title)s\t%(distinctNotes)d\t%(difficulty)d\n' % metadata + indexedFiles[fileBaseName] = line + + # ok, the index is up to date ! + + index = indexedFiles.values() + index.sort() + + + return index + \ No newline at end of file