+
+ 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:
+ title = el.text
+ break
+ if el.tag == 'part-list' :
+ # 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()
+
+
+ if self._current_sort == 'alpha' :
+ def s(a, b) :
+ da = desacc(a.split('\t')[2]).lower()
+ db = desacc(b.split('\t')[2]).lower()
+ return cmp(da, db)
+
+ elif self._current_sort == 'num' :
+ def s(a, b) :
+ da = int(a.split('\t')[3])
+ db = int(b.split('\t')[3])
+ return cmp(da, db)
+ else :
+ s = cmp
+
+ index.sort(s)
+ return index
+
+ def _set_current_sort_(self, arg) :
+ self._current_sort = arg
+ self.list.clear()
+ self._list_dir_()
+
+ def _check_dbl_click_(self, arg) :
+ if pygame.time.get_ticks() - self._last_time_click < 300 :
+ self._button_okay_clicked_(None)
+ else :
+ self._last_time_click = pygame.time.get_ticks()
+
+ def event(self, e) :
+ FileDialog.event(self, e)
+
+ if e.type == CLICK and \
+ e.button == 1 and \
+ self.list.rect.collidepoint(e.pos) :
+ self._check_dbl_click_(e)
+
+ if e.type == KEYDOWN and e.key == K_RETURN :
+ self._button_okay_clicked_(None)
+
+
+# utils
+from unicodedata import decomposition
+from string import printable
+_printable = dict([(c, True) for c in printable])
+isPrintable = _printable.has_key
+
+def _recurseDecomposition(uc):
+ deco = decomposition(uc).split()
+ fullDeco = []
+ if deco :
+ while (deco) :
+ code = deco.pop()
+ if code.startswith('<') :
+ continue
+ c = unichr(int(code, 16))
+ subDeco = decomposition(c).split()
+ if subDeco :
+ deco.extend(subDeco)
+ else :
+ fullDeco.append(c)
+ fullDeco.reverse()
+ else :
+ fullDeco.append(uc)
+
+ fullDeco = u''.join(filter(lambda c : isPrintable(c), fullDeco))
+ return fullDeco