#!@TARGET_PYTHON@
import sys
+import optparse
-sys.path.insert (0, 'python')
import safeeval
+
X_AXIS = 0
Y_AXIS = 1
INFTY = 1e6
for (g1,g2s) in self.link_list_dict.items ():
if len (g2s) != 1:
- print g1, g2s
d += ORPHAN_GROB_PENALTY
return d
-
+
+################################################################
+# Files/directories
+
+import glob
+import shutil
+import re
+
def read_signature_file (name):
+ print 'reading', name
exp_str = ("[%s]" % open (name).read ())
entries = safeeval.safe_eval (exp_str)
return sig
+def compare_signature_files (f1, f2):
+ s1 = read_signature_file (f1)
+ s2 = read_signature_file (f2)
+
+ return SystemLink (s1, s2).distance ()
+
+def paired_files (dir1, dir2, pattern):
+ """
+ Search DIR1 and DIR2 for PATTERN.
+
+ Return (PAIRED, MISSING-FROM-2, MISSING-FROM-1)
+
+ """
+
+ files1 = dict ((os.path.split (f)[1], 1) for f in glob.glob (dir1 + '/' + pattern))
+ files2 = dict ((os.path.split (f)[1], 1) for f in glob.glob (dir2 + '/' + pattern))
+
+ pairs = []
+ missing = []
+ for f in files1.keys ():
+ try:
+ files2.pop (f)
+ pairs.append (f)
+ except KeyError:
+ missing.append (f)
+
+ return (pairs, files2.keys (), missing)
+
+class ComparisonData:
+ def __init__ (self):
+ self.result_dict = {}
+ self.missing = []
+ self.added = []
+
+ def compare_trees (self, dir1, dir2):
+ self.compare_directories (dir1, dir2)
+
+ (root, files, dirs) = os.walk (dir1).next ()
+ for d in dirs:
+ d1 = os.path.join (dir1, d)
+ d2 = os.path.join (dir2, d)
+
+ if os.path.isdir (d2):
+ self.compare_trees (d1, d2)
+
+ def compare_directories (self, dir1, dir2):
+
+ (paired, m1, m2) = paired_files (dir1, dir2, '*.signature')
+
+ self.missing += [(dir1, m) for m in m1]
+ self.added += [(dir2, m) for m in m2]
+ for p in paired:
+ f2 = dir2 + '/' + p
+ f1 = dir1 + '/' + p
+ distance = compare_signature_files (f1, f2)
+ self.result_dict[f2] = (distance, f1)
+
+ def create_text_result_page (self, dir1, dir2):
+ self.write_text_result_page (dir2 + '/' + os.path.split (dir1)[1] + '.txt')
+
+ def write_text_result_page (self, filename):
+ print 'writing "%s"' % filename
+ out = None
+ if filename == '':
+ out = sys.stdout
+ else:
+ out = open (filename, 'w')
+
+ results = [(score, oldfile, file) for (file, (score, oldfile)) in self.result_dict.items ()]
+ results.sort ()
+ results.reverse ()
-def compare_directories (dir1, dir2):
+ for (s, oldfile, f) in results:
+ out.write ('%-30f %-20s\n' % (s, f))
- pass
+ for (dir, file) in self.missing:
+ out.write ('%10s%-20s %s\n' % ('', 'missing',os.path.join (dir, file)))
+ for (dir, file) in self.added:
+ out.write ('%20s%-10s %s\n' % ('','added', os.path.join (dir, file)))
+ def print_results (self):
+ self.write_text_result_page ('')
+
+ def create_html_result_page (self, dir1, dir2):
+ dir1 = dir1.replace ('//', '/')
+ dir2 = dir2.replace ('//', '/')
+
+ threshold = 1.0
+
+ results = [(score, oldfile, file) for (file, (score, oldfile)) in self.result_dict.items ()
+ if score > threshold]
+
+ results.sort ()
+ results.reverse ()
+
+ html = ''
+ old_prefix = os.path.split (dir1)[1]
+ os.mkdir (dir2 + '/' + old_prefix)
+ for (score, oldfile, newfile) in results:
+ old_base = re.sub ("-[0-9]+.signature", '', os.path.split (oldfile)[1])
+ new_base = re.sub ("-[0-9]+.signature", '', newfile)
+
+ for ext in 'png', 'ly':
+ shutil.copy2 (old_base + '.' + ext, dir2 + '/' + old_prefix)
+
+ img_1 = os.path.join (old_prefix, old_base + '.png')
+ ly_1 = os.path.join (old_prefix, old_base + '.ly')
+
+ img_2 = new_base.replace (dir2, '') + '.png'
+ img_2 = re.sub ("^/*", '', img_2)
+
+ ly_2 = img_2.replace ('.png','.ly')
+
+ def img_cell (ly, img):
+ return '''
+<td align="center">
+<a href="%(img)s">
+<img src="%(img)s" style="border-style: none; max-width: 500px;">
+</a><br>
+<font size="-2">(<a href="%(ly)s">source</a>)
+</font>
+</td>
+''' % locals ()
+
+ html_entry = '''
+<tr>
+<td>
+%f
+</td>
+
+%s
+%s
+</tr>
+''' % (score, img_cell (ly_1, img_1), img_cell (ly_2, img_2))
+
+
+ html += html_entry
+
+ html = '''<html>
+<table>
+<tr>
+<th>distance</th>
+<th>old</th>
+<th>new</th>
+</tr>
+%(html)s
+</table>
+</html>''' % locals()
+
+ open (os.path.join (dir2, old_prefix) + '.html', 'w').write (html)
+
+
+def compare_trees (dir1, dir2):
+ data = ComparisonData ()
+ data.compare_trees (dir1, dir2)
+ data.print_results ()
+ data.create_html_result_page (dir1, dir2)
+ data.create_text_result_page (dir1, dir2)
+
################################################################
# TESTING
-def test ():
- def system (x):
- print 'invoking', x
- stat = os.system (x)
- assert stat == 0
-
- import os
- dir = 'output-distance-test'
+import os
+def system (x):
+
+ print 'invoking', x
+ stat = os.system (x)
+ assert stat == 0
- print 'test results in dir'
- system ('rm -rf ' + dir)
- os.mkdir (dir)
- os.chdir (dir)
+
+def test_paired_files ():
+ print paired_files (os.environ["HOME"] + "/src/lilypond/scripts/",
+ os.environ["HOME"] + "/src/lilypond-stable/buildscripts/", '*.py')
+
+
+def test_compare_trees ():
+ system ('rm -rf dir1 dir2')
+ system ('mkdir dir1 dir2')
+ system ('cp 20{-0.signature,.ly,.png} dir1')
+ system ('cp 20{-0.signature,.ly,.png} dir2')
+ system ('cp 20expr{-0.signature,.ly,.png} dir1')
+ system ('cp 19{-0.signature,.ly,.png} dir2/')
+ system ('cp 19{-0.signature,.ly,.png} dir1/')
+ system ('cp 20grob{-0.signature,.ly,.png} dir2/')
+
+ ## introduce difference
+ system ('cp 19-0.signature dir2/20-0.signature')
+
+ compare_trees ('dir1', 'dir2')
+
+
+def test_basic_compare ():
ly_template = r"""#(set! toplevel-score-handler print-score-with-defaults)
#(set! toplevel-music-handler
(lambda (p m)
(print-score-with-defaults
p (scorify-music m p)))))
-#(ly:set-option 'point-and-click)
-
-
-
%(papermod)s
\relative c {
}
"""
-
dicts = [{ 'papermod' : '',
'name' : '20',
'extragrob': '',
'extragrob': 'c4',
'userstring': 'test' }]
-
for d in dicts:
open (d['name'] + '.ly','w').write (ly_template % d)
names = [d['name'] for d in dicts]
- system ('lilypond -ddump-signatures -b eps ' + ' '.join (names))
+ system ('lilypond -ddump-signatures --png -b eps ' + ' '.join (names))
sigs = dict ((n, read_signature_file ('%s-0.signature' % n)) for n in names)
-
combinations = {}
for (n1, s1) in sigs.items():
for (n2, s2) in sigs.items():
combinations['%s-%s' % (n1, n2)] = SystemLink (s1,s2).distance ()
-
- results = combinations.items ()
+ results = combinations.items ()
results.sort ()
for k,v in results:
print '%-20s' % k, v
link = SystemLink (sa, sb)
print link.distance()
-if __name__ == '__main__':
- if sys.argv[1:]:
- test_sigs (sys.argv[1],
- sys.argv[2])
- else:
- test ()
+def run_tests ():
+ do_clean = 1
+ dir = 'output-distance-test'
+
+ print 'test results in ', dir
+ if do_clean:
+ system ('rm -rf ' + dir)
+ system ('mkdir ' + dir)
+
+ os.chdir (dir)
+
+ test_basic_compare ()
+ test_compare_trees ()
+
+################################################################
+#
+
+def main ():
+ p = optparse.OptionParser ("output-distance - compare LilyPond formatting runs")
+ p.usage = 'output-distance.py [options] tree1 tree2'
+
+ p.add_option ('', '--test',
+ dest="run_test",
+ action="store_true",
+ help='run test method')
+
+ (o,a) = p.parse_args ()
+
+ if o.run_test:
+ run_tests ()
+ sys.exit (0)
+
+ if len (a) != 2:
+ p.print_usage()
+ sys.exit (2)
+
+ compare_trees (a[0], a[1])
+
+if __name__ == '__main__':
+ main()