rpms/solfege/F-10 solfege-3.14.1-desktop.patch, NONE, 1.1 solfege-3.14.1-no-x.patch, NONE, 1.1 solfege.spec, 1.15, 1.16 sources, 1.7, 1.8
Sindre Pedersen Bjørdal
sindrepb at fedoraproject.org
Tue Apr 7 14:21:01 UTC 2009
- Previous message (by thread): rpms/rcssmonitor/devel .cvsignore, 1.3, 1.4 rcssmonitor.spec, 1.5, 1.6 sources, 1.3, 1.4
- Next message (by thread): rpms/rcssserver/F-10 .cvsignore, 1.7, 1.8 rcssserver.spec, 1.6, 1.7 sources, 1.7, 1.8
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Author: sindrepb
Update of /cvs/pkgs/rpms/solfege/F-10
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv21176
Modified Files:
solfege.spec sources
Added Files:
solfege-3.14.1-desktop.patch solfege-3.14.1-no-x.patch
Log Message:
new upstream, fixes
solfege-3.14.1-desktop.patch:
--- NEW FILE solfege-3.14.1-desktop.patch ---
diff -up ./solfege.desktop.orig ./solfege.desktop
--- ./solfege.desktop.orig 2009-04-07 15:19:17.000000000 +0200
+++ ./solfege.desktop 2009-04-07 15:19:24.000000000 +0200
@@ -3,5 +3,5 @@ Name=GNU Solfege
Exec=solfege
Terminal=false
Type=Application
-Icon=solfege.png
+Icon=solfege
Categories=GNOME;Application;AudioVideo;Audio;Education;
solfege-3.14.1-no-x.patch:
--- NEW FILE solfege-3.14.1-no-x.patch ---
=== modified file 'Makefile.in'
--- Makefile.in 2009-03-11 18:47:36 +0000
+++ Makefile.in 2009-04-06 22:03:08 +0000
@@ -107,7 +107,7 @@
# We need src/_version.py because solfege imports it at runtime.
solfege.1: solfege.1.txt src/_version.py
- cat $< | sed -e "s/XXOPTIONS/LANGUAGE=C .\/solfege.py --help|sed -n '5,999p'/e" | txt2man -t Solfege -s 1 > $@
+ LANGUAGE=C $(PYTHON) -c "import tools.buildutil; tools.buildutil.create_manpage()" | txt2man -t Solfege -s 1 > $@
rsync-manual: $(foreach lang,$(USER_MANUAL_LANGUAGES),help/$(lang)/one-big-page.html) help/C/one-big-page.html
rm -rf tmp-build
=== modified file 'src/abstract.py'
--- src/abstract.py 2009-04-05 20:22:16 +0000
+++ src/abstract.py 2009-04-06 19:48:52 +0000
@@ -29,6 +29,7 @@
import cfg
import lessonfile
import osutils
+import const
class QstatusDefs:
QSTATUS_NO = 0
@@ -219,24 +220,6 @@
class RhythmAddOnClass:
- RHYTHMS = ("c4", "c8 c8", "c16 c16 c16 c16", "c8 c16 c16",
- "c16 c16 c8", "c16 c8 c16", "c8. c16", "c16 c8.",
- "r4", "r8c8", "r8 c16 c16", "r16 c16 c8", "r16c8c16",
- "r16 c16 c16 c16", "r8 r16 c16", "r16 c8.",
- "c12 c12 c12", "r12 c12 c12",
- "c12 r12 c12", "c12 c12 r12", "r12 r12 c12", "r12 c12 r12",
- "c4.", "c4 c8", # 22, 23
- "c8 c4", "c8 c8 c8", # 24, 25
- "c4 c16 c16", # 26
- "c16 c16 c4", # 27
- "c8 c8 c16 c16", #28
- "c8 c16 c16 c8", #29
- "c16 c16 c8 c8", #30
- "c8 c16 c16 c16 c16", #31
- "c16 c16 c8 c16 c16", #32
- "c16 c16 c16 c16 c8", #33
- "c16 c16 c16 c16 c16 c16", #34
- )
def new_question(self):
"""returns:
self.ERR_PICKY : if the question is not yet solved and the
@@ -258,7 +241,7 @@
norest_v = []
v = []
for x in self.m_P.header.rhythm_elements:
- if not (self.RHYTHMS[x][0] == "r"
+ if not (const.RHYTHMS[x][0] == "r"
and self.get_bool("not_start_with_rest")):
norest_v.append(x)
v.append(x)
@@ -283,7 +266,7 @@
else:
count_in_notelen = "4"
s = "d%s " % count_in_notelen * self.get_int("count_in")
- s += " ".join([self.RHYTHMS[k] for k in self.m_question])
+ s += " ".join([const.RHYTHMS[k] for k in self.m_question])
return s
def get_music_string(self):
"""
@@ -572,7 +555,7 @@
table.show_all()
def pngcheckbutton(self, i):
btn = gtk.CheckButton()
- btn.add(gu.create_rhythm_image(RhythmAddOnClass.RHYTHMS[i]))
+ btn.add(gu.create_rhythm_image(const.RHYTHMS[i]))
btn.show()
btn.connect('clicked', self.select_element_cb, i)
return btn
=== modified file 'src/app.py'
--- src/app.py 2009-04-04 18:28:28 +0000
+++ src/app.py 2009-04-06 22:11:51 +0000
@@ -33,6 +33,7 @@
import reportlib
import filesystem
import osutils
+from optionparser import SolfegeOptionParser
def check_rcfile():
"""See default.config for rcfileversion values, meanings and
=== added file 'src/const.py'
--- src/const.py 1970-01-01 00:00:00 +0000
+++ src/const.py 2009-04-06 19:48:52 +0000
@@ -0,0 +1,38 @@
+# GNU Solfege - free ear training software
+# Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Tom Cato Amundsen
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# Moved RHYTHMS here because is should be available from a module that does
+# not pull in the gtk module.
+
+RHYTHMS = ("c4", "c8 c8", "c16 c16 c16 c16", "c8 c16 c16",
+ "c16 c16 c8", "c16 c8 c16", "c8. c16", "c16 c8.",
+ "r4", "r8c8", "r8 c16 c16", "r16 c16 c8", "r16c8c16",
+ "r16 c16 c16 c16", "r8 r16 c16", "r16 c8.",
+ "c12 c12 c12", "r12 c12 c12",
+ "c12 r12 c12", "c12 c12 r12", "r12 r12 c12", "r12 c12 r12",
+ "c4.", "c4 c8", # 22, 23
+ "c8 c4", "c8 c8 c8", # 24, 25
+ "c4 c16 c16", # 26
+ "c16 c16 c4", # 27
+ "c8 c8 c16 c16", #28
+ "c8 c16 c16 c8", #29
+ "c16 c16 c8 c8", #30
+ "c8 c16 c16 c16 c16", #31
+ "c16 c16 c8 c16 c16", #32
+ "c16 c16 c16 c16 c8", #33
+ "c16 c16 c16 c16 c16 c16", #34
+)
+
=== modified file 'src/learning_tree_editor.py'
--- src/learning_tree_editor.py 2008-06-01 09:44:59 +0000
+++ src/learning_tree_editor.py 2009-04-06 19:48:52 +0000
@@ -17,7 +17,6 @@
import gtk
import gobject
-import pprint
import copy
import sys
import os
@@ -26,473 +25,8 @@
import lessonfilegui
from gpath import Path
import filesystem
-
-def get_learning_tree_list(debug):
- """
- Return a list of tuples with info about the learning trees found.
- Tuple objects:
- 1. The string "user" or "solfege"
- 2. The filename, not including the name of the directory
- 3. Full path to the learning tree.
- """
- trees = []
- for cls, dir in (('solfege', u'learningtrees'),
- ('user', os.path.join(filesystem.user_data(), "learningtrees"))):
- try:
- v = os.listdir(dir)
- except OSError:
- v = []
- for fn in v:
- if cls == 'solfege':
- fullpath = os.path.join("learningtrees", fn)
- else:
- fullpath = os.path.join(filesystem.user_data(), "learningtrees", fn)
- trees.append((cls, fn, fullpath))
- if not debug:
- try:
- trees.remove(('solfege', 'debugtree.txt', os.path.join('learningtrees', 'debugtree.txt')))
- except ValueError:
- # The debugtree.txtfile is for some reason missing
- pass
- return trees
-
-class Menu(dict):
- def new_from_name(name):
- m = Menu({'name': name, 'children': []})
- return m
- new_from_name = staticmethod(new_from_name)
- def get_name(self):
- return self['name']
- def set_name(self, name):
- self['name'] = name
- name = property(get_name, set_name)
- def get_children(self):
- return self['children']
- def set_children(self, children):
- self['children'] = children
- children = property(get_children, set_children)
- def pformat(self, indent):
- return "%(indent)s{'name': %(name)r,\n" \
- "%(indent)s 'nametotranslate': _(%(name)r),\n" \
- "%(indent)s 'children': [\n" \
- "%(children)s ]\n" \
- "%(indent)s}," % {
- 'indent': " " * indent,
- 'name': self.name,
- 'children': self.pformat_children(indent + 4)
- }
- def pformat_children(self, indent):
- v = []
- for child in self.children:
- if isinstance(child, basestring):
- v.append("%s%r," % (" " * indent, child))
- else:
- v.append(child.pformat(indent))
- return "\n".join(v)
-
-
-class LearningTree:
- def __init__(self, lessonfile_manager):
- self.lessonfile_manager = lessonfile_manager
- self.m_menus = []
- self.m_deps = {}
- self.m_modified = False
- self.m_title = ''
- self.m_learning_tree_version = 3
- self.m_visibility = 0
- def load(self, filename):
- self.read_file(filename)
- self.post_load()
- def read_file(self, filename):
- self.m_visibility = 0
- self.m_learning_tree_version = 0
- g = {'_': lambda s: s}
- v = eval(open(filename, 'rU').read(), g)
- if type(v) == dict:
- self.m_menus = v['menu']
- self.m_deps = v['deps']
- self.m_title = v.get('title', '')
- self.m_visibility = v['visibility']
- self.m_learning_tree_version = v['version']
- # The different lengths of v below is to be able to read
- # old formats of the learning tree.
- elif len(v) == 2:
- self.m_menus, self.m_deps = v
- elif len(v) == 3:
- self.m_menus, self.m_deps, self.m_visibility = v
- elif len(v) == 4:
- self.m_learning_tree_version, self.m_menus, self.m_deps, self.m_visibility = v
- if self.m_learning_tree_version == 0:
- # Change from old style with one menu to multiple exercise
- # menus on the menu bar. If version == 0, then the tree only
- # have one menu "Exercises"
- self.m_menus = [
- {'name': "_Practise",
- 'submenus': self.m_menus},
- ]
- self.m_menus[0]['children'] = [{'name': n['name'], 'children': n['lessons']} for n in self.m_menus[0]['submenus']]
- del self.m_menus[0]['submenus']
- if not self.m_title:
- self.m_title = filename
- def post_load(self):
- self.m_menus = [Menu(d) for d in self.m_menus]
- for idx, menu in enumerate(self.m_menus):
- self.m_menus[idx].children = [Menu(s) for s in menu.children]
- self.m_learning_tree_version = 2
- junk_id = []
- # FIXME here we are assuming that there are only two levels of menus
- if self.lessonfile_manager:
- # lessonfile_manager is None in some test cases
- for menu in self.m_menus:
- for topic in menu.children:
- for j in topic.children:
- if j not in self.lessonfile_manager.m_uiddb:
- print >> sys.stderr, "Junking the registration of lesson_id '%s'\nfrom learning tree. File not found." % j
- junk_id.append(j)
- for j in junk_id:
- for menu in self.m_menus:
- for topic in menu.children:
- if j in topic.children:
- del topic.children[topic.children.index(j)]
- if j in self.m_deps:
- del self.m_deps[j]
- for d in self.m_deps:
- if j in self.m_deps[d]:
- self.m_deps[d].remove(j)
- self.sort_topics()
- self.calculate_visibilities()
- self.m_modified = False
- def save(self, filename):
- self.m_learning_tree_version = 3
- ofile = open(filename, 'w')
- print >> ofile, "# GNU Solfege learning tree"
- print >> ofile, "{"
- print >> ofile, " 'version': %i," % self.m_learning_tree_version
- print >> ofile, " 'title': '%s'," % self.m_title.replace("'", r"\'")
- print >> ofile, " 'titletotranslate': _('%s')," % self.m_title.replace("'", r"\'")
- print >> ofile, " 'visibility': %i," % self.m_visibility
- print >> ofile, " 'menu': [ # start of list of menus"
- for menu in self.m_menus:
- print >> ofile, menu.pformat(4)
- print >> ofile, " ], # end of list of menus"
- # Delete dependency info about lesson files that are not in the
- # learning tree.
- lesson_ids = list(self.iterate_all_lessons())
- for dep in [d for d in self.m_deps if d not in lesson_ids]:
- del self.m_deps[dep]
- print >> ofile, " 'deps':",
- print >> ofile, "%s," % pprint.pformat(self.m_deps)
- print >> ofile, "# End of dict mappding dependencies."
- print >> ofile, "}"
- ofile.close()
- self.m_modified = False
- def new_menu(self, menuname):
- self.m_menus.append(Menu({'name': menuname, 'children': []}))
- self.m_modified = True
- def new_topic(self, menu_idx, topicname):
- assert topicname not in [s.name for s in self.m_menus[menu_idx].children]
- self.m_menus[menu_idx].children.append(Menu.new_from_name(topicname))
- self.m_modified = True
- def sort_topics(self):
- """
- Sort the lessons in each topic.
- """
- for menu in self.m_menus:
- for topic in menu.children:
- topic.children.sort(lambda a, b: self.cmp(a, b))
- def move_elem_up(self, path):
- """
- Move elem up. Return True if success.
- Return False if we are the first elem.
- This function only moves the element within the menu.
- """
- if path[-1] == 0:
- return False
- p = path[:-1]
- new_path = path[:-1] + (path[-1],)
- try:
- self.get(p).children[path[-1]], self.get(p).children[path[-1]-1] = \
- self.get(p).children[path[-1]-1], self.get(p).children[path[-1]]
- except IndexError:
- return False
- self.m_modified = True
- return True
- def move_elem_to_prev_menu(self, path):
- """
- Move the element pointed to by path to the prev menu.
- Return None if we are on the first menu.
- """
- assert path[-2] > 0
- to_path = list(path[:-1])
- to_path[-1] -= 1
- to_path = tuple(to_path)
- self.get(to_path).children.append(self.get(path))
- del self.get(path[:-1]).children[path[-1]]
- self.m_modified = True
- return to_path + (len(self.get(to_path).children)-1,)
- def move_elem_down(self, path):
- """
- Move move the element (submenu or lesson) one step down on the menu
- containing it, and return True if successfull. Return False and do
- nothing if the element path points to are the last element.
- """
- p = path[:-1]
- try:
- self.get(p).children[path[-1]], \
- self.get(p).children[path[-1]+1] = \
- self.get(p).children[path[-1]+1], \
- self.get(p).children[path[-1]]
- except IndexError:
- return False
- self.m_modified = True
- return True
- def move_elem_to_next_menu(self, path):
- """
- Move the element pointed to by path to the next menu.
- Faild miserably if we are on the last menu, because the
- gui checks this right now. Return the path to the new
- position.
- """
- pn = list(path[:-1])
- pn[0] += 1
- pn = tuple(pn)
- self.get(pn).children.insert(0, self.get(path))
- del self.get(path[:-1]).children[path[-1]]
- self.m_modified = True
- return pn + (0,)
- def move_lesson_up(self, path):
- """
- Return True if successful, else False.
- The tree is unchanged if we return False.
- """
- if path[-1] == 0:
- # We are the first lesson
- return False
- move_id = self.get(path)
- prev_id = self.get(Path(path).prev())
- if prev_id not in list(self.iter_subdeps(move_id)):
- self.move_elem_up(path)
- self.m_modified = True
- return True
- return False
- def move_lesson_down(self, path):
- """
- Return True if successful, else None.
- The tree is unchanged if we return None.
- """
- p = path[:-1]
- i = path[-1]
- move_id = self.get(path)
- try:
- next_id = self.get(Path(path).next())
- except IndexError:
- return
- if move_id not in list(self.iter_subdeps(next_id)):
- try:
- self.get(p).children[i], self.get(p).children[i + 1] = \
- self.get(p).children[i + 1], self.get(p).children[i]
- except IndexError:
- return False
- self.m_modified = True
- return True
- return False
- def add_lesson(self, path, lesson_id):
- """
- Each lesson can only be once in a topic.
- Return True if sucessful, False if not
- """
- menu = self.get(path)
- if lesson_id not in menu.children:
- if not lesson_id in self.m_deps:
- self.m_deps[lesson_id] = []
- menu.children.append(lesson_id)
- menu.children.sort(lambda a, b: self.cmp(a, b))
- else:
- return False
- self.m_modified = True
- return True
- def delete_lesson(self, path):
- menu = self.get(path[:-1])
- del menu.children[path[-1]]
- self.m_modified = True
- def add_dependency(self, lesson_id, dep_id):
- assert dep_id not in self.m_deps[lesson_id]
- self.m_deps[lesson_id].append(dep_id)
- self.sort_topics()
- self.m_modified = True
- def delete_dependency(self, lesson_id, id_to_delete):
- i = self.m_deps[lesson_id].index(id_to_delete)
- del self.m_deps[lesson_id][i]
- self.sort_topics()
- self.m_modified = True
- def iterate_all_lessons2(self):
- """
- Iterate all lessons that are added to the learning tree.
- Yields the tuple (lesson_ids, path,)
- """
- def do_children(item, path):
- # path == (0,) is the first menu on the menubar
- path = path.child()
- for c in item.children:
- if isinstance(c, Menu):
- for x in do_children(c, path):
- yield x
- else:
- assert isinstance(c, basestring)
- yield c, path
- path = path.next()
- path = Path((0,))
- for menu in self.m_menus:
- for x in do_children(menu, path):
- yield x
- path = path.next()
- def iterate_all_lessons(self):
- """
- Iterate all lessons that are added to the learning tree.
- Yields lesson_ids
- """
- def do_children(item):
- for c in item.children:
- if isinstance(c, Menu):
- for x in do_children(c):
- yield x
- else:
- assert isinstance(c, basestring)
- yield c
- for menu in self.m_menus:
- for x in do_children(menu):
- yield x
- def iterate_topics_for_id(self, lesson_id):
- """
- Yield a string with the name of the submenu containing
- the lesson_id.
- """
- def do_menu(menu):
- if lesson_id in menu.children:
- yield menu.name
- for child in menu.children:
- if isinstance(child, Menu):
- for n in do_menu(child):
- yield n
- for menu in self.m_menus:
- for n in do_menu(menu):
- yield n
- def iterate_deps_for_id(self, lesson_id):
- """
- Iterate all the direct dependencies for lesson_id.
- It does not iterate the sub-dependencies.
- """
- for dep in self.m_deps[lesson_id]:
- yield dep
- def iterate_possible_deps_for(self, path):
- """
- All lessons, except those on the x-list.
- You get on the x-list if:
- 1. is OBJECT
- 2. already in the depends list of OBJECT
- 3. depend on anything in the x-list
- 4. is a dep (of dep)* of OBJ
-
-
- Filter out lessons that
- 1. is OBJECT
- 2. is in depends tree below OBJECT
- 3. has OBJECT in its depends tree
- """
- # The lesson_id we are finding possible deps for
- this_id = self.get(path)
- # First, lets make a list of all lessons that currently are in a topic
- used = {}
- for lesson_id in self.iterate_all_lessons():
- used[lesson_id] = True
- # Filter out this_id (point 1 in the list in the docstring)
- del used[this_id]
- def check(lesson_id):
- # Filter out according to #2 and #3 in the docstring
- if lesson_id in list(self.iter_subdeps(this_id)) \
- or this_id in list(self.iter_subdeps(lesson_id)):
- return False
- return True
- for i in [k for k in used.keys() if check(k)]:
- yield i
- def iter_subdeps(self, lesson_id):
- for n in self.m_deps[lesson_id]:
- yield n
- for nn in self.iter_subdeps(n):
- yield nn
- def is_practisable(self, lesson_id):
- for i in self.iterate_deps_for_id(lesson_id):
- if not self.lessonfile_manager.is_test_passed(i):
- return False
- return True
- def calculate_visibilities(self):
- self.m_visibilities = {}
- v = self.m_deps.keys()
- v.sort(lambda a, b: self.cmp(a, b))
- for i in v:
- if i not in self.lessonfile_manager.m_uiddb:
- continue
- if not self.lessonfile_manager.get(i, 'test'):
- self.m_visibilities[i] = 0
- elif not list(self.iterate_deps_for_id(i)):
- self.m_visibilities[i] = 0
- elif self.is_practisable(i):
- self.m_visibilities[i] = 0
- else:
- self.m_visibilities[i] = max([self.m_visibilities[x] for x in self.m_deps[i]]) + 1
- def cmp(self, id_a, id_b):
- """
- Return -1, 0, 1, like a cmp function.
- """
- deps_a = list(self.iter_subdeps(id_b))
- if id_a in deps_a:
- return -1
- deps_b = list(self.iter_subdeps(id_a))
- if id_b in deps_b:
- return 1
- return cmp(len(deps_b), len(deps_a))
- def get_use_dict(self):
- """
- return a dict mapping lesson_id to the number of times the lesson
- has been added to the learning tree.
- """
- retval = {}
- for lesson_id in self.iterate_all_lessons():
- retval[lesson_id] = retval.get(lesson_id, 0) + 1
- return retval
- def get_use_count(self, lesson_id):
- """
- Return an integer telling how many times the lesson lesson_id
- is used as an exercise.
- """
- count = 0
- for i in self.iterate_all_lessons():
- if i == lesson_id:
- count += 1
- return count
- def get_dep_use_count(self, lesson_id):
- """
- Return an integer telling how many lessons that depends on lesson_id.
- """
- count = 0
- for v in self.m_deps.values():
- for i in v:
- if i == lesson_id:
- count += 1
- return count
- def remove_all_deps_of(self, del_id):
- for v in self.m_deps.values():
- if del_id in v:
- del v[v.index(del_id)]
- self.m_modified = True
- def get(self, path):
- """
- Return the element pointed to by path.
- """
- elem = self.m_menus[path[0]]
- for idx in path[1:]:
- elem = elem.children[idx]
- return elem
+from learningtree import LearningTree, get_learning_tree_list, Menu
+
class LessonFileDialogCommon(gtk.Dialog):
def __init__(self, app, tree, path):
=== added file 'src/learningtree.py'
--- src/learningtree.py 1970-01-01 00:00:00 +0000
+++ src/learningtree.py 2009-04-06 19:48:52 +0000
@@ -0,0 +1,490 @@
+# GNU Solfege - free ear training software
+# Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Tom Cato Amundsen
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+import pprint
+import os
+
+import filesystem
+from gpath import Path
+
+def get_learning_tree_list(debug):
+ """
+ Return a list of tuples with info about the learning trees found.
+ Tuple objects:
+ 1. The string "user" or "solfege"
+ 2. The filename, not including the name of the directory
+ 3. Full path to the learning tree.
+ """
+ trees = []
+ for cls, dir in (('solfege', u'learningtrees'),
+ ('user', os.path.join(filesystem.user_data(), "learningtrees"))):
+ try:
+ v = os.listdir(dir)
+ except OSError:
+ v = []
+ for fn in v:
+ if cls == 'solfege':
+ fullpath = os.path.join("learningtrees", fn)
+ else:
+ fullpath = os.path.join(filesystem.user_data(), "learningtrees", fn)
+ trees.append((cls, fn, fullpath))
+ if not debug:
+ try:
+ trees.remove(('solfege', 'debugtree.txt', os.path.join('learningtrees', 'debugtree.txt')))
+ except ValueError:
+ # The debugtree.txtfile is for some reason missing
+ pass
+ return trees
+
+class Menu(dict):
+ def new_from_name(name):
+ m = Menu({'name': name, 'children': []})
+ return m
+ new_from_name = staticmethod(new_from_name)
+ def get_name(self):
+ return self['name']
+ def set_name(self, name):
+ self['name'] = name
+ name = property(get_name, set_name)
+ def get_children(self):
+ return self['children']
+ def set_children(self, children):
+ self['children'] = children
+ children = property(get_children, set_children)
+ def pformat(self, indent):
+ return "%(indent)s{'name': %(name)r,\n" \
+ "%(indent)s 'nametotranslate': _(%(name)r),\n" \
+ "%(indent)s 'children': [\n" \
+ "%(children)s ]\n" \
+ "%(indent)s}," % {
+ 'indent': " " * indent,
+ 'name': self.name,
+ 'children': self.pformat_children(indent + 4)
+ }
+ def pformat_children(self, indent):
+ v = []
+ for child in self.children:
+ if isinstance(child, basestring):
+ v.append("%s%r," % (" " * indent, child))
+ else:
+ v.append(child.pformat(indent))
+ return "\n".join(v)
+
+
+class LearningTree:
+ def __init__(self, lessonfile_manager):
+ self.lessonfile_manager = lessonfile_manager
+ self.m_menus = []
+ self.m_deps = {}
+ self.m_modified = False
+ self.m_title = ''
+ self.m_learning_tree_version = 3
+ self.m_visibility = 0
+ def load(self, filename):
+ self.read_file(filename)
+ self.post_load()
+ def read_file(self, filename):
+ self.m_visibility = 0
+ self.m_learning_tree_version = 0
+ g = {'_': lambda s: s}
+ v = eval(open(filename, 'rU').read(), g)
+ if type(v) == dict:
+ self.m_menus = v['menu']
+ self.m_deps = v['deps']
+ self.m_title = v.get('title', '')
+ self.m_visibility = v['visibility']
+ self.m_learning_tree_version = v['version']
+ # The different lengths of v below is to be able to read
+ # old formats of the learning tree.
+ elif len(v) == 2:
+ self.m_menus, self.m_deps = v
+ elif len(v) == 3:
+ self.m_menus, self.m_deps, self.m_visibility = v
+ elif len(v) == 4:
+ self.m_learning_tree_version, self.m_menus, self.m_deps, self.m_visibility = v
+ if self.m_learning_tree_version == 0:
+ # Change from old style with one menu to multiple exercise
+ # menus on the menu bar. If version == 0, then the tree only
+ # have one menu "Exercises"
+ self.m_menus = [
+ {'name': "_Practise",
+ 'submenus': self.m_menus},
+ ]
+ self.m_menus[0]['children'] = [{'name': n['name'], 'children': n['lessons']} for n in self.m_menus[0]['submenus']]
+ del self.m_menus[0]['submenus']
+ if not self.m_title:
+ self.m_title = filename
+ def post_load(self):
+ self.m_menus = [Menu(d) for d in self.m_menus]
+ for idx, menu in enumerate(self.m_menus):
+ self.m_menus[idx].children = [Menu(s) for s in menu.children]
+ self.m_learning_tree_version = 2
+ junk_id = []
+ # FIXME here we are assuming that there are only two levels of menus
+ if self.lessonfile_manager:
+ # lessonfile_manager is None in some test cases
+ for menu in self.m_menus:
+ for topic in menu.children:
+ for j in topic.children:
+ if j not in self.lessonfile_manager.m_uiddb:
+ print >> sys.stderr, "Junking the registration of lesson_id '%s'\nfrom learning tree. File not found." % j
+ junk_id.append(j)
+ for j in junk_id:
+ for menu in self.m_menus:
+ for topic in menu.children:
+ if j in topic.children:
+ del topic.children[topic.children.index(j)]
+ if j in self.m_deps:
+ del self.m_deps[j]
+ for d in self.m_deps:
+ if j in self.m_deps[d]:
+ self.m_deps[d].remove(j)
+ self.sort_topics()
+ self.calculate_visibilities()
+ self.m_modified = False
+ def save(self, filename):
+ self.m_learning_tree_version = 3
+ ofile = open(filename, 'w')
+ print >> ofile, "# GNU Solfege learning tree"
+ print >> ofile, "{"
+ print >> ofile, " 'version': %i," % self.m_learning_tree_version
+ print >> ofile, " 'title': '%s'," % self.m_title.replace("'", r"\'")
+ print >> ofile, " 'titletotranslate': _('%s')," % self.m_title.replace("'", r"\'")
+ print >> ofile, " 'visibility': %i," % self.m_visibility
+ print >> ofile, " 'menu': [ # start of list of menus"
+ for menu in self.m_menus:
+ print >> ofile, menu.pformat(4)
+ print >> ofile, " ], # end of list of menus"
+ # Delete dependency info about lesson files that are not in the
+ # learning tree.
+ lesson_ids = list(self.iterate_all_lessons())
+ for dep in [d for d in self.m_deps if d not in lesson_ids]:
+ del self.m_deps[dep]
+ print >> ofile, " 'deps':",
+ print >> ofile, "%s," % pprint.pformat(self.m_deps)
+ print >> ofile, "# End of dict mappding dependencies."
+ print >> ofile, "}"
+ ofile.close()
+ self.m_modified = False
+ def new_menu(self, menuname):
+ self.m_menus.append(Menu({'name': menuname, 'children': []}))
+ self.m_modified = True
+ def new_topic(self, menu_idx, topicname):
+ assert topicname not in [s.name for s in self.m_menus[menu_idx].children]
+ self.m_menus[menu_idx].children.append(Menu.new_from_name(topicname))
+ self.m_modified = True
+ def sort_topics(self):
+ """
+ Sort the lessons in each topic.
+ """
+ for menu in self.m_menus:
+ for topic in menu.children:
+ topic.children.sort(lambda a, b: self.cmp(a, b))
+ def move_elem_up(self, path):
+ """
+ Move elem up. Return True if success.
+ Return False if we are the first elem.
+ This function only moves the element within the menu.
+ """
+ if path[-1] == 0:
+ return False
+ p = path[:-1]
+ new_path = path[:-1] + (path[-1],)
+ try:
+ self.get(p).children[path[-1]], self.get(p).children[path[-1]-1] = \
+ self.get(p).children[path[-1]-1], self.get(p).children[path[-1]]
+ except IndexError:
+ return False
+ self.m_modified = True
+ return True
+ def move_elem_to_prev_menu(self, path):
+ """
+ Move the element pointed to by path to the prev menu.
+ Return None if we are on the first menu.
+ """
+ assert path[-2] > 0
+ to_path = list(path[:-1])
+ to_path[-1] -= 1
+ to_path = tuple(to_path)
+ self.get(to_path).children.append(self.get(path))
+ del self.get(path[:-1]).children[path[-1]]
+ self.m_modified = True
+ return to_path + (len(self.get(to_path).children)-1,)
+ def move_elem_down(self, path):
+ """
+ Move move the element (submenu or lesson) one step down on the menu
+ containing it, and return True if successfull. Return False and do
+ nothing if the element path points to are the last element.
+ """
+ p = path[:-1]
+ try:
+ self.get(p).children[path[-1]], \
+ self.get(p).children[path[-1]+1] = \
+ self.get(p).children[path[-1]+1], \
+ self.get(p).children[path[-1]]
+ except IndexError:
+ return False
+ self.m_modified = True
+ return True
+ def move_elem_to_next_menu(self, path):
+ """
+ Move the element pointed to by path to the next menu.
+ Faild miserably if we are on the last menu, because the
+ gui checks this right now. Return the path to the new
+ position.
+ """
+ pn = list(path[:-1])
+ pn[0] += 1
+ pn = tuple(pn)
+ self.get(pn).children.insert(0, self.get(path))
+ del self.get(path[:-1]).children[path[-1]]
+ self.m_modified = True
+ return pn + (0,)
+ def move_lesson_up(self, path):
+ """
+ Return True if successful, else False.
+ The tree is unchanged if we return False.
+ """
+ if path[-1] == 0:
+ # We are the first lesson
+ return False
+ move_id = self.get(path)
+ prev_id = self.get(Path(path).prev())
+ if prev_id not in list(self.iter_subdeps(move_id)):
+ self.move_elem_up(path)
+ self.m_modified = True
+ return True
+ return False
+ def move_lesson_down(self, path):
+ """
+ Return True if successful, else None.
+ The tree is unchanged if we return None.
+ """
+ p = path[:-1]
+ i = path[-1]
+ move_id = self.get(path)
+ try:
+ next_id = self.get(Path(path).next())
+ except IndexError:
+ return
+ if move_id not in list(self.iter_subdeps(next_id)):
+ try:
+ self.get(p).children[i], self.get(p).children[i + 1] = \
+ self.get(p).children[i + 1], self.get(p).children[i]
+ except IndexError:
+ return False
+ self.m_modified = True
+ return True
+ return False
+ def add_lesson(self, path, lesson_id):
+ """
+ Each lesson can only be once in a topic.
+ Return True if sucessful, False if not
+ """
+ menu = self.get(path)
+ if lesson_id not in menu.children:
+ if not lesson_id in self.m_deps:
+ self.m_deps[lesson_id] = []
+ menu.children.append(lesson_id)
+ menu.children.sort(lambda a, b: self.cmp(a, b))
+ else:
+ return False
+ self.m_modified = True
+ return True
+ def delete_lesson(self, path):
+ menu = self.get(path[:-1])
+ del menu.children[path[-1]]
+ self.m_modified = True
+ def add_dependency(self, lesson_id, dep_id):
+ assert dep_id not in self.m_deps[lesson_id]
+ self.m_deps[lesson_id].append(dep_id)
+ self.sort_topics()
+ self.m_modified = True
+ def delete_dependency(self, lesson_id, id_to_delete):
+ i = self.m_deps[lesson_id].index(id_to_delete)
+ del self.m_deps[lesson_id][i]
+ self.sort_topics()
+ self.m_modified = True
+ def iterate_all_lessons2(self):
+ """
+ Iterate all lessons that are added to the learning tree.
+ Yields the tuple (lesson_ids, path,)
+ """
+ def do_children(item, path):
+ # path == (0,) is the first menu on the menubar
+ path = path.child()
+ for c in item.children:
+ if isinstance(c, Menu):
+ for x in do_children(c, path):
+ yield x
+ else:
+ assert isinstance(c, basestring)
+ yield c, path
+ path = path.next()
+ path = Path((0,))
+ for menu in self.m_menus:
+ for x in do_children(menu, path):
+ yield x
+ path = path.next()
+ def iterate_all_lessons(self):
+ """
+ Iterate all lessons that are added to the learning tree.
+ Yields lesson_ids
+ """
+ def do_children(item):
+ for c in item.children:
+ if isinstance(c, Menu):
+ for x in do_children(c):
+ yield x
+ else:
+ assert isinstance(c, basestring)
+ yield c
+ for menu in self.m_menus:
+ for x in do_children(menu):
+ yield x
+ def iterate_topics_for_id(self, lesson_id):
+ """
+ Yield a string with the name of the submenu containing
+ the lesson_id.
+ """
+ def do_menu(menu):
+ if lesson_id in menu.children:
+ yield menu.name
+ for child in menu.children:
+ if isinstance(child, Menu):
+ for n in do_menu(child):
+ yield n
+ for menu in self.m_menus:
+ for n in do_menu(menu):
+ yield n
+ def iterate_deps_for_id(self, lesson_id):
+ """
+ Iterate all the direct dependencies for lesson_id.
+ It does not iterate the sub-dependencies.
+ """
+ for dep in self.m_deps[lesson_id]:
+ yield dep
+ def iterate_possible_deps_for(self, path):
+ """
+ All lessons, except those on the x-list.
+ You get on the x-list if:
+ 1. is OBJECT
+ 2. already in the depends list of OBJECT
+ 3. depend on anything in the x-list
+ 4. is a dep (of dep)* of OBJ
+
+
+ Filter out lessons that
+ 1. is OBJECT
+ 2. is in depends tree below OBJECT
+ 3. has OBJECT in its depends tree
+ """
+ # The lesson_id we are finding possible deps for
+ this_id = self.get(path)
+ # First, lets make a list of all lessons that currently are in a topic
+ used = {}
+ for lesson_id in self.iterate_all_lessons():
+ used[lesson_id] = True
+ # Filter out this_id (point 1 in the list in the docstring)
+ del used[this_id]
+ def check(lesson_id):
+ # Filter out according to #2 and #3 in the docstring
+ if lesson_id in list(self.iter_subdeps(this_id)) \
+ or this_id in list(self.iter_subdeps(lesson_id)):
+ return False
+ return True
+ for i in [k for k in used.keys() if check(k)]:
+ yield i
+ def iter_subdeps(self, lesson_id):
+ for n in self.m_deps[lesson_id]:
+ yield n
+ for nn in self.iter_subdeps(n):
+ yield nn
+ def is_practisable(self, lesson_id):
+ for i in self.iterate_deps_for_id(lesson_id):
+ if not self.lessonfile_manager.is_test_passed(i):
+ return False
+ return True
+ def calculate_visibilities(self):
+ self.m_visibilities = {}
+ v = self.m_deps.keys()
+ v.sort(lambda a, b: self.cmp(a, b))
+ for i in v:
+ if i not in self.lessonfile_manager.m_uiddb:
+ continue
+ if not self.lessonfile_manager.get(i, 'test'):
+ self.m_visibilities[i] = 0
+ elif not list(self.iterate_deps_for_id(i)):
+ self.m_visibilities[i] = 0
+ elif self.is_practisable(i):
+ self.m_visibilities[i] = 0
+ else:
+ self.m_visibilities[i] = max([self.m_visibilities[x] for x in self.m_deps[i]]) + 1
+ def cmp(self, id_a, id_b):
+ """
+ Return -1, 0, 1, like a cmp function.
+ """
+ deps_a = list(self.iter_subdeps(id_b))
+ if id_a in deps_a:
+ return -1
+ deps_b = list(self.iter_subdeps(id_a))
+ if id_b in deps_b:
+ return 1
+ return cmp(len(deps_b), len(deps_a))
+ def get_use_dict(self):
+ """
+ return a dict mapping lesson_id to the number of times the lesson
+ has been added to the learning tree.
+ """
+ retval = {}
+ for lesson_id in self.iterate_all_lessons():
+ retval[lesson_id] = retval.get(lesson_id, 0) + 1
+ return retval
+ def get_use_count(self, lesson_id):
+ """
+ Return an integer telling how many times the lesson lesson_id
+ is used as an exercise.
+ """
+ count = 0
+ for i in self.iterate_all_lessons():
+ if i == lesson_id:
+ count += 1
+ return count
+ def get_dep_use_count(self, lesson_id):
+ """
+ Return an integer telling how many lessons that depends on lesson_id.
+ """
+ count = 0
+ for v in self.m_deps.values():
+ for i in v:
+ if i == lesson_id:
+ count += 1
+ return count
+ def remove_all_deps_of(self, del_id):
+ for v in self.m_deps.values():
+ if del_id in v:
+ del v[v.index(del_id)]
+ self.m_modified = True
+ def get(self, path):
+ """
+ Return the element pointed to by path.
+ """
+ elem = self.m_menus[path[0]]
+ for idx in path[1:]:
+ elem = elem.children[idx]
+ return elem
+
=== added file 'src/optionparser.py'
--- src/optionparser.py 1970-01-01 00:00:00 +0000
+++ src/optionparser.py 2009-04-06 22:12:02 +0000
@@ -0,0 +1,44 @@
+import optparse
+
+class SolfegeOptionParser(optparse.OptionParser):
+ def __init__(self):
+ optparse.OptionParser.__init__(self)
+ self.add_option('-v', '--version', action='store_true', dest='version')
+ self.add_option('-w', '--warranty', action='store_true', dest='warranty',
+ help=_('Show warranty and copyright.'))
+ self.add_option('--no-splash', action='store_false', dest='no_splash',
+ help=_('Do not show the startup window.'),
+ default=False)
+ self.add_option('--verbose-sound-init', action='store_true',
+ default=False,
+ dest='verbose_sound_init',
+ help=_('Display more info about the sound setup.'))
+ self.add_option('--no-sound', action='store_true', dest='no_sound',
+ default=False,
+ help=_('Do not play any sounds. Instead some data is printed to standard output. Use this for debugging and porting.'))
+ self.add_option('--debug', action='store_true', dest='debug',
+ help=_('Include features used by the Solfege developers to debug the program.'))
+ self.add_option('--disable-exception-handler', action='store_true',
+ dest='disable_exception_handler',
+ help=_("Disable the exception handling in Gui.standard_exception_handler."))
+ self.add_option('--no-random', action='store_true', dest='no_random',
+ help=_('For debugging only: Select questions from lesson files in sequential order.'))
+ self.add_option('--enable-gtkhtml', action='store_true',
+ dest='enable_gtkhtml',
+ help=_('Run using gtkhtml2 instead of the built in HTML viewer.'))
+ self.add_option('--no-cairo-widgets', action='store_true',
+ dest='no_cairo_widgets',
+ help=_("Do not use the cairo version of input widgets, even if we run gtk+ 2.8.0 or newer."))
+ self.add_option('--show-gtk-warnings', action='store_true',
+ dest='show_gtk_warnings',
+ help=_('Show GtkWarnings and PangoWarnings in the traceback window.'))
+ def print_help(self, outfile=None):
+ if outfile is None:
+ outfile = sys.stdout
+ encoding = outfile.encoding
+ if not encoding:
+ encoding = "iso-8859-1"
+ outfile.write(self.format_help().encode(encoding, 'replace'))
+
+
+
=== modified file 'src/rhythm.py'
--- src/rhythm.py 2008-02-05 20:06:45 +0000
+++ src/rhythm.py 2009-04-06 19:48:52 +0000
@@ -18,7 +18,7 @@
import gtk, gobject
import abstract, gu
import lessonfile
-
+import const
class Teacher(abstract.Teacher, abstract.RhythmAddOnClass):
OK = 0
@@ -99,7 +99,7 @@
self.g_box.get_children()[self.m_num_beats-1].destroy()
vbox = gtk.VBox()
vbox.show()
- im = gu.create_rhythm_image(abstract.RhythmAddOnClass.RHYTHMS[i])
+ im = gu.create_rhythm_image(const.RHYTHMS[i])
vbox.pack_start(im)
vbox.pack_start(gu.create_png_image('rhythm-wrong'), False, False)
vbox.get_children()[-1].hide()
@@ -230,13 +230,13 @@
def pngbutton(self, i):
"used by the constructor"
btn = gtk.Button()
- if i > len(abstract.RhythmAddOnClass.RHYTHMS):
+ if i > len(const.RHYTHMS):
im = gtk.Image()
im.set_from_stock("gtk-missing-image", gtk.ICON_SIZE_LARGE_TOOLBAR)
im.show()
btn.add(im)
else:
- btn.add(gu.create_rhythm_image(abstract.RhythmAddOnClass.RHYTHMS[i]))
+ btn.add(gu.create_rhythm_image(const.RHYTHMS[i]))
btn.show()
btn.connect('clicked', self.guess_element, i)
return btn
@@ -251,7 +251,7 @@
self.g_backspace.set_sensitive(False)
def play_users_answer(self, widget):
if self.g_rhythm_viewer.m_data:
- rhythm = " ".join([abstract.RhythmAddOnClass.RHYTHMS[c] for c in self.g_rhythm_viewer.m_data])
+ rhythm = " ".join([const.RHYTHMS[c] for c in self.g_rhythm_viewer.m_data])
self.m_t.play_rhythm(r"\staff{ %s }" % rhythm)
def guess_element(self, sender, i):
if self.m_t.q_status == self.QSTATUS_NO:
=== modified file 'tools/buildutil.py'
--- tools/buildutil.py 2008-03-13 08:08:01 +0000
+++ tools/buildutil.py 2009-04-06 22:13:15 +0000
@@ -18,6 +18,7 @@
import glob
import os.path
import sys
+import re
sys.path.append(".")
def create_languages_py():
@@ -33,3 +34,19 @@
print >> f, "]"
f.close()
+def create_manpage():
+ sys.argv = ['solfege']
+ import src.i18n
+ src.i18n.setup(".")
+ import src.optionparser
+ options = src.optionparser.SolfegeOptionParser().format_help().encode('iso-8859-1', 'replace')
+ v = options.split("\n")
+ del v[0]
+ del v[0]
+ del v[0]
+ options = "\n".join(v)
+ # This option is so long that it messes with the columns, and it confuses txt2man.
+ options = re.sub('--disable-exception-handler\s*', '--disable-exception-handler ', options)
+ s = open("solfege.1.txt", "r").read()
+ s = s.replace('XXOPTIONS', options)
+ print >> sys.stdout, s
=== modified file 'tools/gen_rhythms_table.py'
--- tools/gen_rhythms_table.py 2007-11-02 20:36:55 +0000
+++ tools/gen_rhythms_table.py 2009-04-06 19:48:52 +0000
@@ -9,7 +9,7 @@
os.path.join(filesystem.rcfile()))
import src.i18n
src.i18n.setup(".")
-import src.abstract
+import src.const
img_str = """%i:<inlinemediaobject>
<imageobject>
@@ -21,9 +21,9 @@
</inlinemediaobject>"""
f = open("help/C/rhythmtable.xml", "w")
print >> f, "<para>"
-for i, r in enumerate(src.abstract.RhythmAddOnClass.RHYTHMS):
+for i, r in enumerate(src.const.RHYTHMS):
print >> f, img_str % (i, r.replace(" ", ""), r),
- if i != len(src.abstract.RhythmAddOnClass.RHYTHMS) - 1:
+ if i != len(src.const.RHYTHMS) - 1:
print >> f, ", "
print >> f, "</para>"
f.close()
=== modified file 'tools/generate_lessonfiles.py'
--- tools/generate_lessonfiles.py 2008-11-06 21:43:44 +0000
+++ tools/generate_lessonfiles.py 2009-04-06 19:48:52 +0000
@@ -12,8 +12,13 @@
sys.path.insert(0, ".")
import src.i18n
src.i18n.setup(".")
-from src.learning_tree_editor import LearningTree
-import mpd
+
+from src.learningtree import LearningTree
+
+# We do this sys.path trick to dragging in dependencies on gtk
+sys.path.insert(0, "mpd")
+from musicalpitch import MusicalPitch
+from interval import Interval
header = """
header {
@@ -32,9 +37,9 @@
def question(f, b, c):
low = 60
- tone_a = mpd.MusicalPitch.new_from_int(low)
- tone_b = mpd.MusicalPitch.new_from_int(low + b)
- tone_c = mpd.MusicalPitch.new_from_int(low + c)
+ tone_a = MusicalPitch.new_from_int(low)
+ tone_b = MusicalPitch.new_from_int(low + b)
+ tone_c = MusicalPitch.new_from_int(low + c)
print >> f, 'question {'
print >> f, ' question_text = _("Sing the three tones")'
print >> f, ' music = voice("< %s2 %s %s >")' % (
@@ -135,7 +140,7 @@
return s.replace("m", "min").replace("M", "maj")
def csound_intonation2(harmonic, interval_name, cent):
- i = mpd.Interval(interval_name)
+ i = Interval(interval_name)
if harmonic:
hs = "harmonic-"
else:
@@ -196,7 +201,7 @@
tree.new_menu("_Melodic intervals")
for idx, cname in enumerate(("m2", "M2", "m3", "M3", "p4", "p5",
"m6", "M6", "m7", "M7")):
- tree.new_topic(0, mpd.Interval(cname).get_cname())
+ tree.new_topic(0, Interval(cname).get_cname())
for cent in (40, 30, 20, 15, 10, 8, 6, 5):
csound_intonation2(False, cname, cent)
tree.add_lesson((0, idx), "csound-intonation-%s-%icent" % (
@@ -204,7 +209,7 @@
tree.new_menu("_Harmonic intervals")
for idx, cname in enumerate(("m2", "M2", "m3", "M3", "p4", "p5",
"m6", "M6", "m7", "M7")):
- tree.new_topic(1, mpd.Interval(cname).get_cname())
+ tree.new_topic(1, Interval(cname).get_cname())
for cent in (40, 30, 20, 15, 10, 8, 6, 5):
csound_intonation2(True, cname, cent)
tree.add_lesson((1, idx), "csound-intonation-harmonic-%s-%icent" % (
Index: solfege.spec
===================================================================
RCS file: /cvs/pkgs/rpms/solfege/F-10/solfege.spec,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- solfege.spec 5 May 2008 12:39:51 -0000 1.15
+++ solfege.spec 7 Apr 2009 14:20:30 -0000 1.16
@@ -1,5 +1,5 @@
Name: solfege
-Version: 3.10.4
+Version: 3.14.1
Release: 1%{?dist}
Summary: Music education software
@@ -8,14 +8,21 @@
URL: http://www.solfege.org/
Source0: http://dl.sourceforge.net/solfege/%{name}-%{version}.tar.gz
Source1: solfege.sh.in
+#don't require X to build from Tom Cato Amundsen, to be merged upstream
+Patch0: solfege-%{version}-no-x.patch
+#make sure desktop file is sane, don't use extension without path in Icon=
+Patch1: solfege-%{version}-desktop.patch
+
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
BuildRequires: texinfo, swig, gettext, docbook-style-xsl
-BuildRequires: pygtk2-devel, libxslt
-BuildRequires: desktop-file-utils
-
-Requires: timidity++, gnome-python2-gtkhtml2, esound
-Requires: pygtk2
+BuildRequires: pygtk2-devel >= 2.12, libxslt
+BuildRequires: lilypond, swig
+BuildRequires: desktop-file-utils, gettext
+
+Requires: timidity++, lilypond
+Requires: gnome-python2-gtkhtml2, esound
+Requires: pygtk2 >= 2.12
%description
Solfege is free music education software. Use it to train your rhythm,
@@ -23,9 +30,15 @@
%prep
%setup -q
+%patch0 -p0
+%patch1 -p0
+
#preserve timestamps
%{__sed} -i.stamp -e 's|shutil\.copy|shutil.copy2|' tools/pcopy.py
+#fix permissios for debuginfo package
+chmod 0755 $RPM_BUILD_DIR/%{name}-%{version}/src/_version.py
+
%build
export INSTALL="%{__install} -c -p"
#override hardocded path
@@ -75,8 +88,20 @@
%{_mandir}/man?/*
-
%changelog
+* Wed Apr 7 2009 Sindre Pedersen Bjørdal <sindrepb at fedoraproject.org> - 3.14.1-1
+- New upstream release
+- Add patch to not require X to build
+- Add patch to fix desktop file, don't use extensions without path in Icon=
+- Add lilypond dependency
+- Make sure permissions in debuginfo are sane
+
+* Wed Feb 25 2009 Fedora Release Engineering <rel-eng at lists.fedoraproject.org> - 3.10.4-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild
+
+* Mon Dec 01 2008 Ignacio Vazquez-Abrams <ivazqueznet+rpm at gmail.com> - 3.10.4-2
+- Rebuild for Python 2.6
+
* Tue Mar 18 2008 Sindre Pedersen Bjørdal <sindrepb at fedoraproject.org> - 3.10.4-1
- New bugfix release
Index: sources
===================================================================
RCS file: /cvs/pkgs/rpms/solfege/F-10/sources,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- sources 5 May 2008 12:39:51 -0000 1.7
+++ sources 7 Apr 2009 14:20:30 -0000 1.8
@@ -1 +1 @@
-74705388c446a10ed574e68bcd3134d4 solfege-3.10.4.tar.gz
+bb7720a9c847232fad6c8cd462fa1dcc solfege-3.14.1.tar.gz
- Previous message (by thread): rpms/rcssmonitor/devel .cvsignore, 1.3, 1.4 rcssmonitor.spec, 1.5, 1.6 sources, 1.3, 1.4
- Next message (by thread): rpms/rcssserver/F-10 .cvsignore, 1.7, 1.8 rcssserver.spec, 1.6, 1.7 sources, 1.7, 1.8
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the fedora-extras-commits
mailing list