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):
button_txt="Ouvrir",
path=path,
)
+ self.list.style.width = 700
+ self.list.style.height = 250
def _list_dir_(self):
self.input_dir.value = self.curdir
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