1 # -*- coding: utf-8 -*-
3 Boîte de dialogue pour sélection des chansons.
9 from pgu
.gui
import FileDialog
12 from xml
.etree
import ElementTree
13 from minwii
.musicxml
import musicXml2Song
15 INDEX_TXT
= 'index.txt'
17 class FileOpenDialog(FileDialog
):
21 def __init__(self
, path
):
22 FileDialog
.__init
__(self
,
23 title_txt
="Ouvrir une chanson",
29 self
.input_dir
.value
= self
.curdir
30 self
.input_dir
.pos
= len(self
.curdir
)
31 self
.input_dir
.vpos
= 0
35 for i
in os
.listdir(self
.curdir
):
36 if i
.startswith('.') : continue
37 if os
.path
.isdir(os
.path
.join(self
.curdir
, i
)): dirs
.append(i
)
40 self
.input_file
.value
= "Dossier innacessible !"
47 self
.list.add(i
, image
=self
.dir_img
, value
=i
)
51 if not i
.endswith('.xml') :
53 filepath
= os
.path
.join(self
.curdir
, i
)
54 xmlFiles
.append(filepath
)
55 # self.list.add(FileOpenDialog.getSongTitle(filepath), value=i)
58 printableLines
= self
.getPrintableLines(xmlFiles
)
59 for l
in printableLines
:
60 self
.list.add(l
[0], value
= l
[1])
62 self
.list.set_vertical_scroll(0)
64 def getPrintableLines(self
, xmlFiles
) :
65 index
= self
.getUpdatedIndex(xmlFiles
)
71 printableLines
.append(('%s - %s / %s' % (l
[2], l
[3], l
[4]), l
[0]))
77 def getSongTitle(file) :
78 it
= ElementTree
.iterparse(file, ['start', 'end'])
80 title
= os
.path
.basename(file)
83 if el
.tag
== 'credit' :
85 if el
.tag
== 'credit-words' and creditFound
:
88 if el
.tag
== 'part-list' :
89 # au delà de ce tag : aucune chance de trouver un titre
94 def getSongMetadata(file) :
96 metadata
['title'] = FileOpenDialog
.getSongTitle(file).encode('iso-8859-1')
97 metadata
['mtime'] = str(os
.stat(file).st_mtime
)
98 metadata
['file'] = os
.path
.basename(file)
99 song
= musicXml2Song(file)
100 metadata
['distinctNotes'] = len(song
.distinctNotes
)
102 histo
= song
.intervalsHistogram
103 coeffInter
= reduce(lambda a
, b
: a
+ b
,
104 [abs(k
) * v
for k
, v
in histo
.items()])
106 totInter
= reduce(lambda a
, b
: a
+b
, histo
.values())
107 totInter
= totInter
- histo
.get(0, 0)
108 difficulty
= int(round(float(coeffInter
) / totInter
, 0))
109 metadata
['difficulty'] = difficulty
113 def getUpdatedIndex(self
, xmlFiles
) :
114 indexTxtPath
= os
.path
.join(self
.curdir
, INDEX_TXT
)
117 if not os
.path
.exists(indexTxtPath
) :
118 musicXmlFound
= False
119 tmp
= tempfile
.TemporaryFile(mode
='r+')
120 for file in xmlFiles
:
122 metadata
= FileOpenDialog
.getSongMetadata(file)
124 except ValueError, e
:
126 if e
.args
and e
.args
[0] == 'not a musicxml file' :
129 line
= '%(file)s\t%(mtime)s\t%(title)s\t%(distinctNotes)d\t%(difficulty)d\n' % metadata
135 indexFile
= open(indexTxtPath
, 'w')
136 indexFile
.write(tmp
.read())
141 indexTxt
= open(indexTxtPath
, 'r')
143 # check if index is up to date, and update entries if so.
144 for l
in filter(None, indexTxt
.readlines()) :
145 parts
= l
.split('\t')
146 fileBaseName
, modificationTime
= parts
[0], parts
[1]
147 filePath
= os
.path
.join(self
.curdir
, fileBaseName
)
149 if not os
.path
.exists(filePath
) :
152 indexedFiles
[fileBaseName
] = l
153 currentMtime
= str(os
.stat(filePath
).st_mtime
)
155 # check modification time missmatch
156 if currentMtime
!= modificationTime
:
158 metadata
= FileOpenDialog
.getSongMetadata(filePath
)
160 except ValueError, e
:
162 if e
.args
and e
.args
[0] == 'not a musicxml file' :
165 metadata
= FileOpenDialog
.getSongMetadata(filePath
)
166 line
= '%(file)s\t%(mtime)s\t%(title)s\t%(distinctNotes)d\t%(difficulty)d\n' % metadata
167 indexedFiles
[fileBaseName
] = line
169 # check for new files.
170 for file in xmlFiles
:
171 fileBaseName
= os
.path
.basename(file)
172 if not indexedFiles
.has_key(fileBaseName
) :
174 metadata
= FileOpenDialog
.getSongMetadata(filePath
)
176 except ValueError, e
:
178 if e
.args
and e
.args
[0] == 'not a musicxml file' :
181 metadata
= FileOpenDialog
.getSongMetadata(file)
182 line
= '%(file)s\t%(mtime)s\t%(title)s\t%(distinctNotes)d\t%(difficulty)d\n' % metadata
183 indexedFiles
[fileBaseName
] = line
185 # ok, the index is up to date !
187 index
= indexedFiles
.values()