schooltool.cando-2.6.2/0000755000175000017500000000000012322040274016115 5ustar menesismenesis00000000000000schooltool.cando-2.6.2/base.cfg0000644000175000017500000000322212270520445017514 0ustar menesismenesis00000000000000[buildout] extends = http://ftp.schooltool.org/schooltool/trunk/versions.cfg versions = versions newest = false find-links = http://ftp.schooltool.org/schooltool/trunk/ http://ftp.schooltool.org/schooltool/trunk/dev/ parts = package test supervisor celery scripts ctags omelette [package] recipe = zc.recipe.egg:eggs unzip = true # set eggs to package name in buildout.cfg eggs = [scripts] recipe = zc.recipe.egg:scripts unzip = true eggs = ${package:eggs} ZODB3 redis schooltool schooltool.devtools scripts = # ZODB3: runzeo zeopack # schooltool.devtools: i18nextract runfdoctests # schooltool: make-schooltool-instance start-schooltool-instance schooltool-server interpreter = python [supervisor] recipe = zc.recipe.egg:scripts unzip = true eggs = supervisor scripts = supervisord supervisorctl pidproxy # Useful script if you want to toy with supervisor settings #echo_supervisord_conf initialization = import os if os.path.exists('instance'): os.chdir('instance') [celery] recipe = zc.recipe.egg:scripts unzip = true eggs = ${package:eggs} celery redis scripts = # celery: #celerybeat celeryd celeryev celeryctl #camqadm #celeryd-multi [test] recipe = schooltool.devtools:testrunner eggs = ${package:eggs} defaults = ['--tests-pattern', '^f?s?tests$', '-v', '--auto-color'] [ctags] recipe = z3c.recipe.tag:tags eggs = ${test:eggs} [omelette] recipe = collective.recipe.omelette eggs = ${test:eggs} ignores = roman zope.ucol site schooltool.cando-2.6.2/buildout.cfg0000644000175000017500000000030412322040274020422 0ustar menesismenesis00000000000000[buildout] extends = base.cfg develop = . [versions] # Unset versions of packages you want to develop schooltool.cando = [package] eggs = schooltool.cando [test] eggs = schooltool.cando [test] schooltool.cando-2.6.2/develop.cfg0000644000175000017500000000017612270520445020245 0ustar menesismenesis00000000000000[buildout] extends = deploy.cfg parts += coverage [coverage] recipe = zc.recipe.egg:scripts unzip = true eggs = z3c.coverage schooltool.cando-2.6.2/src/0000755000175000017500000000000012322040274016704 5ustar menesismenesis00000000000000schooltool.cando-2.6.2/src/schooltool.cando.egg-info/0000755000175000017500000000000012322040274023646 5ustar menesismenesis00000000000000schooltool.cando-2.6.2/src/schooltool.cando.egg-info/SOURCES.txt0000644000175000017500000001653512322040274025544 0ustar menesismenesis00000000000000CHANGES.txt GPL.txt MANIFEST.in Makefile README.txt base.cfg bootstrap.py buildout.cfg deploy.cfg develop.cfg setup.py version.txt.in src/schooltool/__init__.py src/schooltool.cando.egg-info/PKG-INFO src/schooltool.cando.egg-info/SOURCES.txt src/schooltool.cando.egg-info/dependency_links.txt src/schooltool.cando.egg-info/entry_points.txt src/schooltool.cando.egg-info/namespace_packages.txt src/schooltool.cando.egg-info/not-zip-safe src/schooltool.cando.egg-info/requires.txt src/schooltool.cando.egg-info/top_level.txt src/schooltool/cando/__init__.py src/schooltool/cando/configure.zcml src/schooltool/cando/course.py src/schooltool/cando/course.zcml src/schooltool/cando/gradebook.py src/schooltool/cando/gradebook.zcml src/schooltool/cando/iep.py src/schooltool/cando/iep.zcml src/schooltool/cando/interfaces.py src/schooltool/cando/model.py src/schooltool/cando/model.zcml src/schooltool/cando/plugin.zcml src/schooltool/cando/project.py src/schooltool/cando/project.zcml src/schooltool/cando/security.zcml src/schooltool/cando/skill.py src/schooltool/cando/skill.zcml src/schooltool/cando/stesting.py src/schooltool/cando/stesting.zcml src/schooltool/cando/translations.zcml src/schooltool/cando/browser/__init__.py src/schooltool/cando/browser/breadcrumbs.py src/schooltool/cando/browser/breadcrumbs.zcml src/schooltool/cando/browser/configure.zcml src/schooltool/cando/browser/course.py src/schooltool/cando/browser/document.py src/schooltool/cando/browser/document.zcml src/schooltool/cando/browser/gradebook.py src/schooltool/cando/browser/gradebook.zcml src/schooltool/cando/browser/iep.py src/schooltool/cando/browser/iep.zcml src/schooltool/cando/browser/importer.py src/schooltool/cando/browser/model.py src/schooltool/cando/browser/report.py src/schooltool/cando/browser/report.zcml src/schooltool/cando/browser/request_reports.py src/schooltool/cando/browser/skill.py src/schooltool/cando/browser/xls_views.py src/schooltool/cando/browser/resources/cando.css src/schooltool/cando/browser/resources/cando.js src/schooltool/cando/browser/resources/empty_skills_data.xls src/schooltool/cando/browser/resources/ui-icons_222222_256x240.png src/schooltool/cando/browser/resources/ui-icons_ffffff_256x240.png src/schooltool/cando/browser/rml/competency_certificate_signature.pt src/schooltool/cando/browser/rml/competency_certificate_styles.pt src/schooltool/cando/browser/rml/section_student_scr.pt src/schooltool/cando/browser/rml/student_competency_report_styles.pt src/schooltool/cando/browser/stests/__init__.py src/schooltool/cando/browser/stests/add_skills.txt src/schooltool/cando/browser/stests/cando_tab.txt src/schooltool/cando/browser/stests/course_nodes.xls src/schooltool/cando/browser/stests/course_skills.txt src/schooltool/cando/browser/stests/course_skills.xls src/schooltool/cando/browser/stests/delete_current_worksheet.txt src/schooltool/cando/browser/stests/deprecate.txt src/schooltool/cando/browser/stests/gradebook_grade_student.txt src/schooltool/cando/browser/stests/gradebook_management.txt src/schooltool/cando/browser/stests/gradebook_multiple_term.txt src/schooltool/cando/browser/stests/gradebook_skill_labels.txt src/schooltool/cando/browser/stests/iep.txt src/schooltool/cando/browser/stests/iep_scr.txt src/schooltool/cando/browser/stests/import_skills.txt src/schooltool/cando/browser/stests/label_constraints.txt src/schooltool/cando/browser/stests/label_title_sorting.txt src/schooltool/cando/browser/stests/layer_hierarchy.txt src/schooltool/cando/browser/stests/nodes_layers.txt src/schooltool/cando/browser/stests/per_student_skills_report.txt src/schooltool/cando/browser/stests/per_student_skills_report_multiple_term.txt src/schooltool/cando/browser/stests/projects.txt src/schooltool/cando/browser/stests/sample_data.xls src/schooltool/cando/browser/stests/skill_events.txt src/schooltool/cando/browser/stests/skill_events_importer.txt src/schooltool/cando/browser/stests/skill_events_importer.xls src/schooltool/cando/browser/stests/skill_scoresystems.txt src/schooltool/cando/browser/stests/skillsets_skills.txt src/schooltool/cando/browser/stests/test_selenium.py src/schooltool/cando/browser/templates/aggregate_filter.pt src/schooltool/cando/browser/templates/cando_resources.pt src/schooltool/cando/browser/templates/cando_third_nav.pt src/schooltool/cando/browser/templates/colorcodes_help.pt src/schooltool/cando/browser/templates/course_assign_skills_table_filter.pt src/schooltool/cando/browser/templates/course_assign_skillsets_dialog.pt src/schooltool/cando/browser/templates/course_remove_skills.pt src/schooltool/cando/browser/templates/course_skills_edit.pt src/schooltool/cando/browser/templates/course_skills_edit_table_buttons.pt src/schooltool/cando/browser/templates/course_skills_overview.pt src/schooltool/cando/browser/templates/course_skillset.pt src/schooltool/cando/browser/templates/courses_skills_assignment.pt src/schooltool/cando/browser/templates/dialog_button_column.pt src/schooltool/cando/browser/templates/document.pt src/schooltool/cando/browser/templates/document_add.pt src/schooltool/cando/browser/templates/document_skill.pt src/schooltool/cando/browser/templates/document_skillset.pt src/schooltool/cando/browser/templates/edit_course_skills.pt src/schooltool/cando/browser/templates/f_import_related.pt src/schooltool/cando/browser/templates/filldown_dialog.pt src/schooltool/cando/browser/templates/form.pt src/schooltool/cando/browser/templates/gradebook_iep_students.pt src/schooltool/cando/browser/templates/gradebook_skills_dialog.pt src/schooltool/cando/browser/templates/iep_details.pt src/schooltool/cando/browser/templates/iep_sections.pt src/schooltool/cando/browser/templates/layer.pt src/schooltool/cando/browser/templates/node.pt src/schooltool/cando/browser/templates/nodes_table_filter.pt src/schooltool/cando/browser/templates/project_skill_table_filter.pt src/schooltool/cando/browser/templates/projects.pt src/schooltool/cando/browser/templates/request_competency_certificate.pt src/schooltool/cando/browser/templates/retire_nodes_save_button.pt src/schooltool/cando/browser/templates/retire_nodes_script.pt src/schooltool/cando/browser/templates/scoresystem_help.pt src/schooltool/cando/browser/templates/section_report_charts_column.pt src/schooltool/cando/browser/templates/section_report_details.pt src/schooltool/cando/browser/templates/section_report_score_colors.pt src/schooltool/cando/browser/templates/section_report_score_colors_column.pt src/schooltool/cando/browser/templates/section_report_script.pt src/schooltool/cando/browser/templates/skill.pt src/schooltool/cando/browser/templates/skill_edit.pt src/schooltool/cando/browser/templates/skillset.pt src/schooltool/cando/browser/templates/skillsets.pt src/schooltool/cando/browser/tests/__init__.py src/schooltool/cando/generations/__init__.py src/schooltool/cando/generations/evolve1.py src/schooltool/cando/generations/evolve2.py src/schooltool/cando/generations/evolve3.py src/schooltool/cando/generations/install.py src/schooltool/cando/locales/__init__.py src/schooltool/cando/locales/es_SV.po src/schooltool/cando/locales/nl.po src/schooltool/cando/locales/schooltool.cando.pot src/schooltool/cando/locales/th.po src/schooltool/cando/locales/es_SV/LC_MESSAGES/schooltool.cando.mo src/schooltool/cando/locales/nl/LC_MESSAGES/schooltool.cando.mo src/schooltool/cando/locales/th/LC_MESSAGES/schooltool.cando.mo src/schooltool/cando/tests/__init__.py src/schooltool/cando/tests/test_model.py src/schooltool/cando/tests/test_skill.pyschooltool.cando-2.6.2/src/schooltool.cando.egg-info/top_level.txt0000644000175000017500000000001312322040274026372 0ustar menesismenesis00000000000000schooltool schooltool.cando-2.6.2/src/schooltool.cando.egg-info/entry_points.txt0000644000175000017500000000010612322040274027141 0ustar menesismenesis00000000000000 [z3c.autoinclude.plugin] target = schooltool schooltool.cando-2.6.2/src/schooltool.cando.egg-info/PKG-INFO0000644000175000017500000001745312322040274024755 0ustar menesismenesis00000000000000Metadata-Version: 1.1 Name: schooltool.cando Version: 2.6.2 Summary: CanDo plugin for SchoolTool Home-page: http://www.schooltool.org Author: SchoolTool Developers Author-email: schooltool-developers@lists.launchpad.net License: GPL Description: ======= CHANGES ======= 2.6.2 (2014-04-11) ------------------ - Fixed access to scoresDict property (https://launchpad.net/bugs/1306778) 2.6.1 (2013-11-24) ------------------ - Fixed equivalent lookup in the skills gradebook. - Fix Total points external activity to return a percentage of total possible points. 2.6.0 (2013-10-10) ------------------ - Add student's view for projects (https://launchpad.net/bugs/1070278) - Fix student and teacher sorting in some reports. - Allow sorting gradebook by first or last name (https://launchpad.net/bugs/1234284) - Fix navigation when schoolear has non-ascii chars (https://launchpad.net/bugs/1234690) - Fix forbidden attribute error on login after timeout (https://launchpad.net/bugs/1154662) 0.8.2 (2013-09-14) ------------------ - Add a view to batch-deprecate skills, skill sets and nodes. - Added field to node search table to filter by common text - Fixed Save button in deprecate skills view when there's only one result - Changed wording and functionality of Visible/Active/Retired to Deprecated - Changed wording attribute to field in batch assign view - Fixed score student view for projects 0.8.1 (2013-08-23) ------------------ - Nodes and skill sets can now be retired. - Allow clerks and managers to access skills and reports. - Update GPL license and file headers from gnu.org (https://launchpad.net/bugs/1211145) 0.8.0 (2013-08-01) ------------------ - Background PDF reports - Moved in Per Student Skills Report and Skills Completion Report from schooltool.virginia - Added Student skill completion (by section) pdf archive report. 0.7.1 (2013-05-29) ------------------ - Renamed Section Competencies reports to Student Skill Reports - Fixed Add Skill exception when z3c.form >= 2.9 is used (https://launchpad.net/bugs/1185433) 0.7.0 (2013-04-18) ------------------ - Fixed column title in SkillSets worksheet in sample data xls (https://launchpad.net/bugs/1126624) - Added Label column to SkillSets worksheet in the exporter - Changed required widget terms to Required and Optional (https://launchpad.net/bugs/1123471) - Made label and descriptions fields uniform for nodes, skill sets and skills (https://launchpad.net/bugs/1103708) - Added "Submit and add" action to "New skill set" form (https://launchpad.net/bugs/1103710) - Changed Skills selector to Skill Sets in the gradebook (https://launchpad.net/bugs/1154425) - Fixed worksheet order in Skills Export xls (https://launchpad.net/bugs/1126612) - Updated translations 0.6.2 (2013-03-25) ------------------ - Added section student competency report - Fixed skills sorting in Set Required/Visible view - Fixed permissions of project view 0.6.1 (2013-03-20) ------------------ - Fixed permissions of popup menus and competency report - Updated translations, added Thai 0.6 (2013-02-25) ---------------- - Fix section skills with no equivalent course skill - Sorted by label and title in add skill view for projects - Moved "Skills Export" option from School to Documents view (https://launchpad.net/bugs/1126577) - Moved "Import Skill Data" option from School to Documents view (https://launchpad.net/bugs/1131436) - Changed string "skillset" to "skill set" (https://launchpad.net/bugs/1131376) - Removed title from tables in index views for document and node (https://launchpad.net/bugs/1049966) 0.5.1 (2013-02-18) ------------------ - New-style CanDo Gradebook report. - Added student's Section Competencies report. - Added student's Certificate of Competency report. 0.4.4 (2013-02-18) ------------------ - Fixed error when current skillset for the user has been removed. - Sorted tables for adding/removing nodes by label and title. 0.4.3 (2013-02-11) ------------------ - Fixed submit of Set Required/Visible course skills page. 0.4.2 (2013-01-29) ------------------ - Skills now have their own scoresystem. Old skills that had no scoresystem set, system default is used. - Add IEP (Individualized Educational Plan) functionality. - Added Dutch and Spanish (El Salvador) translations. 0.4.1 (2012-11-29) ------------------ - Fixed skills sorting in more teacher and student views. - Update section worksheets on global skill or skillset change (https://launchpad.net/bugs/1066940) 0.4 (2012-11-27) ---------------- - Search skills, skillsets, or nodes. - Sorted components (skills, skill sets, layers, etc) by label and title 0.3.2 (2012-11-09) ------------------ - Fix for the missing scores fix 0.3.1 (2012-11-08) ------------------ - Sorted skills by label in the skills gradebook - Fixed validation in score student view - Removed subscriber that prevented section deleting - Restored scores that disappeared after upgrade to 0.3 0.3 (2012-10-19) ---------------- - New sections don't get existing course skills (https://launchpad.net/bugs/1065128) - Allow users to add existing skills to projects gradebook - Allow users to move/delete project skills - Show previous scores in multiple term section gradebooks 0.2.1 (2012-09-27) ------------------ - Sorted worksheets in third-nav of the gradebook views - Edit document hierarchy view now sorts by hierarchy order - Nodes table filter now orders layer checkboxes by hierarchy order - I can't set a node label through the web (https://launchpad.net/bugs/1049442) 0.2 (2012-09-13) ---------------- - Added CourseNodes sheet to skills importer - Made Batch Assign Skills view to associate several nodes at once - Skills Document table views need cyclic relationship check (https://launchpad.net/bugs/1030865) - Added Skill Sets tab back to skills tertiary 0.1 (2012-08-08) ---------------- Initial release. Platform: any Classifier: Development Status :: 4 - Beta Classifier: Environment :: Web Environment Classifier: Intended Audience :: End Users/Desktop Classifier: License :: OSI Approved :: GNU General Public License (GPL) Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 2.6 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Zope Classifier: Topic :: Education schooltool.cando-2.6.2/src/schooltool.cando.egg-info/requires.txt0000644000175000017500000000020412322040274026242 0ustar menesismenesis00000000000000schooltool >= 2.6 schooltool.gradebook >= 2.6 setuptools zope.i18n zope.i18nmessageid [test] schooltool.devtools>=0.6 z3c.form>=2.6schooltool.cando-2.6.2/src/schooltool.cando.egg-info/dependency_links.txt0000644000175000017500000000000112322040274027714 0ustar menesismenesis00000000000000 schooltool.cando-2.6.2/src/schooltool.cando.egg-info/namespace_packages.txt0000644000175000017500000000001312322040274030173 0ustar menesismenesis00000000000000schooltool schooltool.cando-2.6.2/src/schooltool.cando.egg-info/not-zip-safe0000644000175000017500000000000112270520476026105 0ustar menesismenesis00000000000000 schooltool.cando-2.6.2/src/schooltool/0000755000175000017500000000000012322040274021071 5ustar menesismenesis00000000000000schooltool.cando-2.6.2/src/schooltool/__init__.py0000644000175000017500000000007012270520445023204 0ustar menesismenesis00000000000000__import__('pkg_resources').declare_namespace(__name__) schooltool.cando-2.6.2/src/schooltool/cando/0000755000175000017500000000000012322040274022155 5ustar menesismenesis00000000000000schooltool.cando-2.6.2/src/schooltool/cando/stesting.py0000644000175000017500000001174412270520445024403 0ustar menesismenesis00000000000000# # SchoolTool - common information systems platform for school administration # Copyright (c) 2012 Shuttleworth Foundation # # 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 2 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 . # """ Selenium Functional Testing Utilities for skills. """ import os from schooltool.testing.selenium import SeleniumLayer dir = os.path.abspath(os.path.dirname(__file__)) filename = os.path.join(dir, 'stesting.zcml') skill_selenium_layer = SeleniumLayer(filename, __name__, 'skill_selenium_layer') def registerSeleniumSetup(): try: import selenium except ImportError: return from schooltool.testing import registry import schooltool.testing.selenium def importGlobalSkills(browser, filename): browser.query.link('School').click() browser.query.link('Skills').click() browser.query.link('Import Skill Data').click() if filename: browser.query.name('xlsfile').type(filename) page = browser.query.tag('html') browser.query.button('Submit').click() browser.wait(lambda: page.expired) registry.register('SeleniumHelpers', lambda: schooltool.testing.selenium.registerBrowserUI( 'skill.import_xls', importGlobalSkills)) def addSkillSet(browser, title, label=None): browser.query.link('School').click() browser.query.link('Skills').click() browser.query.link('Skill Sets').click() browser.query.link('Skill Set').click() browser.query.name('form.widgets.title').type(title) if label is not None: browser.query.name('form.widgets.label').type(label) page = browser.query.tag('html') browser.query.button('Submit').click() browser.wait(lambda: page.expired) registry.register('SeleniumHelpers', lambda: schooltool.testing.selenium.registerBrowserUI( 'skillset.add', addSkillSet)) def addSkill(browser, skillset, title, label=None, required=True, external_id=None, scoresystem=None): browser.query.link('School').click() browser.query.link('Skills').click() browser.query.link('Skill Sets').click() browser.query.link(skillset).click() browser.query.link('Skill').click() browser.query.name('form.widgets.title').type(title) if label is not None: browser.query.name('form.widgets.label').type(label) if required: browser.query.id('form-widgets-required-0').click() else: browser.query.id('form-widgets-required-1').click() if external_id is not None: browser.query.name('form.widgets.external_id').type(external_id) if scoresystem is not None: browser.query.name('form.widgets.scoresystem:list').ui.set_value(scoresystem) else: browser.query.name('form.widgets.scoresystem:list').ui.set_value('Competency') page = browser.query.tag('html') browser.query.button('Submit').click() browser.wait(lambda: page.expired) registry.register('SeleniumHelpers', lambda: schooltool.testing.selenium.registerBrowserUI( 'skill.add', addSkill)) def addLayer(browser, title): browser.query.link('School').click() browser.query.link('Skills').click() browser.query.link('Layers').click() browser.query.link('Layer').click() browser.query.name('form.widgets.title').type(title) page = browser.query.tag('html') browser.query.button('Submit').click() browser.wait(lambda: page.expired) registry.register('SeleniumHelpers', lambda: schooltool.testing.selenium.registerBrowserUI( 'layer.add', addLayer)) def addNode(browser, title, label=None): browser.query.link('School').click() browser.query.link('Skills').click() browser.query.link('Search').click() browser.query.link('Node').click() browser.query.name('form.widgets.title').type(title) if label is not None: browser.query.name('form.widgets.label').type(label) page = browser.query.tag('html') browser.query.button('Submit').click() browser.wait(lambda: page.expired) registry.register('SeleniumHelpers', lambda: schooltool.testing.selenium.registerBrowserUI( 'node.add', addNode)) registerSeleniumSetup() del registerSeleniumSetup schooltool.cando-2.6.2/src/schooltool/cando/model.zcml0000644000175000017500000001002012270520445024142 0ustar menesismenesis00000000000000 schooltool.cando-2.6.2/src/schooltool/cando/project.py0000644000175000017500000003111512270520445024203 0ustar menesismenesis00000000000000# # SchoolTool - common information systems platform for school administration # Copyright (c) 2012 Shuttleworth Foundation # # 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 2 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 . # """Gradebook projects.""" from decimal import Decimal from persistent.dict import PersistentDict from zope.annotation.interfaces import IAnnotations from zope.interface import implements, implementer from zope.event import notify from zope.component import (adapter, adapts, getUtility, getAdapters, queryAdapter) from zope.container.contained import containedEvent from zope.container.interfaces import INameChooser from zope.i18n import translate from zope.intid.interfaces import IIntIds from zope.keyreference.interfaces import IKeyReference from zope.proxy import sameProxiedObjects from schooltool.requirement.requirement import Requirement from schooltool.requirement.scoresystem import UNSCORED from schooltool.gradebook.activity import Worksheets, Worksheet from schooltool.gradebook.interfaces import IExternalActivity from schooltool.gradebook.interfaces import IExternalActivities from schooltool.cando.interfaces import IProjects, IProject, IProjectsGradebook from schooltool.cando.interfaces import ICourseProjects, ICourseProject from schooltool.cando.interfaces import ISectionSkills, ISkillsGradebook from schooltool.cando.skill import SkillSet from schooltool.course.interfaces import ISection, ICourse from schooltool.cando import CanDoMessage as _ SECTION_PROJECTS_KEY = 'schooltool.cando.project.sectionprojects' COURSE_PROJECTS_KEY = 'schooltool.cando.project.courseprojects' class Projects(Worksheets): implements(IProjects) annotations_current_worksheet_key = 'schooltool.cando.project.currentworksheet' class Project(SkillSet, Worksheet): implements(IProject) class CourseProjects(Requirement): implements(ICourseProjects) deployed_projects = None def __init__(self, *args, **kw): self.deployed_projects = PersistentDict() def isDeployed(self, project, section): if (project.__name__ not in self or not sameProxiedObjects(project.__parent__, self)): raise KeyError(project.__name__) project_hash = hash(IKeyReference(project)) section_hash = hash(IKeyReference(section)) if project_hash not in self.deployed_projects: return False if section_hash not in self.deployed_projects[project_hash]: return False return True def markDeployed(self, project, deployed_project): if (project.__name__ not in self or not sameProxiedObjects(project.__parent__, self)): raise KeyError(project.__name__) project_hash = hash(IKeyReference(project)) section = ISection(deployed_project.__parent__) section_hash = hash(IKeyReference(section)) if project_hash not in self.deployed_projects: self.deployed_projects[project_hash] = PersistentDict() deployed_hash = hash(IKeyReference(deployed_project)) self.deployed_projects[project_hash][section_hash] = deployed_hash deployed_project.deployed = True def deploy(self, project, section): if (project.__name__ not in self or not sameProxiedObjects(project.__parent__, self)): raise KeyError(project.__name__) if self.isDeployed(project, section): return section_projects = IProjects(section) deployed_project = Project(title=project.title, description=project.description) chooser = INameChooser(section_projects) name = chooser.chooseName(project.__name__, deployed_project) section_projects[name] = deployed_project for skill in project.values(): new_skill = deployed_project.add(skill) skill.equivalent.add(new_skill) self.markDeployed(project, deployed_project) class CourseProject(SkillSet): implements(ICourseProject) @property def deployed(self): course_projects = self.__parent__ course = ICourse(course_projects) for section in course.sections: if not course_projects.isDeployed(self, section): return False return True @adapter(ICourse) @implementer(ICourseProjects) def getCourseProjects(course): annotations = IAnnotations(course) try: return annotations[COURSE_PROJECTS_KEY] except KeyError: projects = CourseProjects(_('Course Projects')) annotations[COURSE_PROJECTS_KEY] = projects # Sigh, this is not good. projects, event = containedEvent(projects, course, 'projects') notify(event) return projects # Convention to make adapter introspectable getCourseProjects.factory = CourseProjects @adapter(ICourseProjects) @implementer(ICourse) def getCourseFromProjects(projects): annotations = projects.__parent__ course = annotations.__parent__ return course @adapter(ISection) @implementer(IProjects) def getSectionProjects(section): annotations = IAnnotations(section) try: return annotations[SECTION_PROJECTS_KEY] except KeyError: projects = Projects(_('Projects')) annotations[SECTION_PROJECTS_KEY] = projects # Sigh, this is not good. projects, event = containedEvent(projects, section, 'projects') notify(event) return projects getSectionProjects.factory = Projects @adapter(IProjects) @implementer(ISection) def getSectionFromProjects(projects): annotations = projects.__parent__ section = annotations.__parent__ return section class CanDoExternalActivityProject(object): implements(IExternalActivity) adapts(IProject) def __init__(self, context): self.project = context self.gradebook = IProjectsGradebook(context) self.__parent__ = context self.source = "" self.external_activity_id = "" @property def description(self): return self.project.description def __eq__(self, other): return IExternalActivity.providedBy(other) and \ self.source == other.source and \ self.external_activity_id == other.external_activity_id class CanDoExternalActivityProjectTotal(CanDoExternalActivityProject): @property def title(self): msg = _('${project} total points', mapping={'project': self.project.title}) return translate(msg) def getGrade(self, student): numComps = totalPoints = 0 ss = None for competency in self.project.values(): numComps += 1 ev = self.gradebook.getScore(student, competency) if ev is None or ev.value == UNSCORED: continue value = ev.scoreSystem.getNumericalValue(ev.value) totalPoints += value if not ss: ss = ev.scoreSystem if numComps: if not totalPoints: return Decimal(0) bestScore = ss.getNumericalValue(ss.getBestScore()) return Decimal(totalPoints) / Decimal(numComps) / bestScore return None class CanDoExternalActivityProjectPercentPassed(CanDoExternalActivityProject): @property def title(self): msg = _('${project} percent passed', mapping={'project': self.project.title}) return translate(msg) def getGrade(self, student): numComps = totalPassed = 0 for competency in self.project.values(): numComps += 1 ev = self.gradebook.getScore(student, competency) if ev is None or ev.value == UNSCORED: continue if ev.scoreSystem.isPassingScore(ev.value): totalPassed += 1 if numComps: return Decimal(totalPassed) / Decimal(numComps) return None class CanDoExternalActivitySection(object): implements(IExternalActivity) adapts(ISection) def __init__(self, context): self.section = context self.courses = ', '.join([c.title for c in self.section.courses]) self.__parent__ = context self.source = "" self.external_activity_id = "" @property def description(self): return self.section.description def __eq__(self, other): return IExternalActivity.providedBy(other) and \ self.source == other.source and \ self.external_activity_id == other.external_activity_id class CanDoExternalActivitySectionTotal(CanDoExternalActivitySection): @property def title(self): msg = _('${course} total points', mapping={'course': self.courses}) return translate(msg) def getGrade(self, student): numComps = totalPoints = 0 ss = None for skillset in ISectionSkills(self.section).values(): gradebook = ISkillsGradebook(skillset) for competency in skillset.values(): numComps += 1 ev = gradebook.getScore(student, competency) if ev is None or ev.value == UNSCORED: continue value = ev.scoreSystem.getNumericalValue(ev.value) totalPoints += value if not ss: ss = ev.scoreSystem if numComps: if not totalPoints: return Decimal(0) bestScore = ss.getNumericalValue(ss.getBestScore()) return Decimal(totalPoints) / Decimal(numComps) / bestScore return None class CanDoExternalActivitySectionPercentPassed(CanDoExternalActivitySection): @property def title(self): msg = _('${course} percent passed', mapping={'course': self.courses}) return translate(msg) def getGrade(self, student): numComps = totalPassed = 0 for skillset in ISectionSkills(self.section).values(): gradebook = ISkillsGradebook(skillset) for competency in skillset.values(): numComps += 1 ev = gradebook.getScore(student, competency) if ev is None or ev.value == UNSCORED: continue if ev.scoreSystem.isPassingScore(ev.value): totalPassed += 1 if numComps: return Decimal(totalPassed) / Decimal(numComps) return None class CanDoExternalActivities(object): implements(IExternalActivities) title = u"CanDo" source = "cando.external_activities" def __init__(self, context): self.context = context self.__parent__ = context def getExternalActivities(self): result = [] intids = getUtility(IIntIds) section_projects = IProjects(self.context) for project in section_projects.values(): for name, activity in getAdapters([project], IExternalActivity): external_activity = activity external_activity.source = self.source external_id = '%s_%s' % (name, intids.getId(project)) external_activity.external_activity_id = external_id result.append(external_activity) for name, activity in getAdapters([self.context], IExternalActivity): external_activity = activity external_activity.source = self.source external_id = '%s_%s' % (name, intids.getId(self.context)) external_activity.external_activity_id = external_id result.append(external_activity) return result def getExternalActivity(self, external_activity_id): parts = external_activity_id.split('_') if len(parts) != 2: return None name, context_intid = parts try: context_intid = int(context_intid) except (ValueError,): return None context = getUtility(IIntIds).queryObject(context_intid) if context is None: return None activity = queryAdapter(context, IExternalActivity, name=name) if activity is None: return None activity.source = self.source activity.external_activity_id = external_activity_id return activity schooltool.cando-2.6.2/src/schooltool/cando/iep.py0000644000175000017500000000716512270520445023322 0ustar menesismenesis00000000000000# # SchoolTool - common information systems platform for school administration # Copyright (c) 2012 Shuttleworth Foundation # # 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 2 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 . # """Student Individualized Education Plan (IEP)""" from persistent import Persistent from persistent.dict import PersistentDict from zope.annotation.interfaces import IAnnotations from zope.component import adapter, getUtility from zope.intid.interfaces import IIntIds from zope.interface import implementer from schooltool.basicperson.interfaces import IBasicPerson from schooltool.cando.interfaces import ISectionSkills from schooltool.cando.interfaces import IStudentIEP STUDENT_IEP_KEY = 'schooltool.cando.iep' class StudentIEP(Persistent): active = False description = None def __init__(self): super(StudentIEP, self).__init__() self.iep_skills = PersistentDict({}) def getIEPSkills(self, section): result = {} int_ids = getUtility(IIntIds) section_id = int_ids.getId(section) section_iep_skills = self.iep_skills.get(section_id) if section_iep_skills is not None: section_skills = ISectionSkills(section) for skillset_id, skill_ids in section_iep_skills.items(): skillset = section_skills.get(skillset_id) if skillset is not None: result[skillset] = [] for skill_id in skill_ids: skill = skillset.get(skill_id) if skill is not None: result[skillset].append(skill) return result def addSkill(self, section, skill): int_ids = getUtility(IIntIds) section_id = int_ids.getId(section) section_skills = ISectionSkills(section) skillset = skill.__parent__ skillset_id = skillset.__name__ if skillset_id in section_skills: if section_id not in self.iep_skills: self.iep_skills[section_id] = {} section_iep_skills = self.iep_skills.get(section_id) if skillset_id not in section_iep_skills: section_iep_skills[skillset_id] = set() section_iep_skills[skillset_id].add(skill.__name__) def removeSkill(self, section, skill): int_ids = getUtility(IIntIds) section_id = int_ids.getId(section) section_iep_skills = self.iep_skills.get(section_id) if section_iep_skills is not None: skill_id = skill.__name__ skillset = skill.__parent__ skillset_id = skillset.__name__ if skillset_id in section_iep_skills and \ skill_id in section_iep_skills[skillset_id]: section_iep_skills[skillset_id].remove(skill_id) @implementer(IStudentIEP) @adapter(IBasicPerson) def getStudentIEP(person): annotations = IAnnotations(person) try: return annotations[STUDENT_IEP_KEY] except KeyError: iep = StudentIEP() iep.__parent__ = person annotations[STUDENT_IEP_KEY] = iep return iep schooltool.cando-2.6.2/src/schooltool/cando/gradebook.py0000644000175000017500000002546312270520445024503 0ustar menesismenesis00000000000000# # SchoolTool - common information systems platform for school administration # Copyright (c) 2012 Shuttleworth Foundation # # 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 2 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 . # """CanDo Gradebook.""" from zope.annotation.interfaces import IAnnotations from zope.cachedescriptors.property import Lazy from zope.component import adapts, adapter, queryMultiAdapter from zope.component import getMultiAdapter from zope.interface import implements, implementer, implementsOnly from zope.location.location import LocationProxy from zope.publisher.interfaces import IPublishTraverse from zope.security import proxy from schooltool.app.interfaces import ISchoolToolApplication from schooltool.basicperson.interfaces import IBasicPerson from schooltool.course.interfaces import ISection from schooltool.gradebook.activity import ensureAtLeastOneWorksheet from schooltool.gradebook.gradebook import Gradebook from schooltool.gradebook.gradebook import StudentGradebook from schooltool.gradebook.gradebook import getActivityScore from schooltool.gradebook.gradebook import CURRENT_SECTION_TAUGHT_KEY from schooltool.gradebook.gradebook import CURRENT_SECTION_ATTENDED_KEY from schooltool.requirement.interfaces import IHaveEvaluations from schooltool.requirement.interfaces import IScore from schooltool.cando.interfaces import ICanDoGradebook from schooltool.cando.interfaces import IMySkillsGrades from schooltool.cando.interfaces import IMyProjectsGrades from schooltool.cando.interfaces import IProject from schooltool.cando.interfaces import IProjects from schooltool.cando.interfaces import IProjectsGradebook from schooltool.cando.interfaces import ISectionSkills from schooltool.cando.interfaces import ISkillsGradebook from schooltool.cando.interfaces import ISectionSkillSet from schooltool.cando.interfaces import ISkill from schooltool.cando.interfaces import ICanDoStudentGradebook from schooltool.cando.project import Project from schooltool.cando import CanDoMessage as _ def ensureAtLeastOneProject(worksheets): ensureAtLeastOneWorksheet(worksheets, Project, _('Project1')) class ProjectsGradebook(Gradebook): implements(IProjectsGradebook) adapts(IProject) # XXX: Merge with Gradebook and GradebookBase def __init__(self, context): self.context = context # To make URL creation happy self.__parent__ = context self.section = self.context.__parent__.__parent__ # Establish worksheets and all activities worksheets = IProjects(self.section) ensureAtLeastOneProject(worksheets) self.worksheets = list(worksheets.values()) self.activities = [] for activity in context.values(): self.activities.append(activity) self.students = list(self.section.members) self.__name__ = 'gradebook-projects' def getCurrentWorksheet(self, person): section = self.section worksheets = IProjects(section) current = worksheets.getCurrentWorksheet(person) return current def setCurrentWorksheet(self, person, worksheet): section = self.section worksheets = IProjects(section) worksheet = proxy.removeSecurityProxy(worksheet) worksheets.setCurrentWorksheet(person, worksheet) def filterEquivalent(self, equivalent): # select only equivalent skills that belong to this section return filter( lambda e: ISection(e.__parent__, None) is self.section, equivalent) def evaluate(self, student, activity, score, evaluator=None): super(ProjectsGradebook, self).evaluate( student, activity, score, evaluator) equivalent = self.filterEquivalent(activity.findAllEquivalent()) for skill in equivalent: worksheet = skill.__parent__ gradebook = ISkillsGradebook(worksheet, None) if gradebook is not None: gradebook.evaluate(student, skill, score, evaluator) def removeEvaluation(self, student, activity, evaluator=None): super(ProjectsGradebook, self).removeEvaluation( student, activity, evaluator) equivalent = self.filterEquivalent(activity.findAllEquivalent()) for skill in equivalent: worksheet = skill.__parent__ gradebook = ISkillsGradebook(worksheet, None) if gradebook is not None: gradebook.removeEvaluation(student, skill, evaluator) class SkillsGradebook(Gradebook): implements(ISkillsGradebook) adapts(ISectionSkillSet) # XXX: Merge with Gradebook and GradebookBase def __init__(self, context): self.context = context # To make URL creation happy self.__parent__ = context self.section = self.context.__parent__.__parent__ # Establish worksheets and all activities worksheets = ISectionSkills(self.section) self.worksheets = list(worksheets.values()) self.activities = [] for activity in context.values(): self.activities.append(activity) self.students = list(self.section.members) self.__name__ = 'gradebook-skills' def getCurrentWorksheet(self, person): section = self.section worksheets = ISectionSkills(section) current = worksheets.getCurrentWorksheet(person) return current def setCurrentWorksheet(self, person, worksheet): section = self.section worksheets = ISectionSkills(section) worksheet = proxy.removeSecurityProxy(worksheet) worksheets.setCurrentWorksheet(person, worksheet) def getScore(self, student, activity): score = super(SkillsGradebook, self).getScore(student, activity) if score is not None: return score if self.section.previous is not None: return self.getPreviousScore(student, activity, self.section.previous) def getPreviousScore(self, student, activity, section): equivalent = self.findEquivalent(activity, section) if equivalent is not None: skill = proxy.removeSecurityProxy(equivalent) worksheet = skill.__parent__ gradebook = ISkillsGradebook(worksheet, None) if gradebook is not None: try: score = gradebook.getScore(student, skill) except (ValueError,): score = None if score is not None: return score def findEquivalent(self, activity, section): current_skillset_id = activity.__parent__.__name__ skillsets = ISectionSkills(section) skillset = skillsets.get(current_skillset_id) if skillset is not None: return skillset.get(activity.__name__) class MySkillsGrades(SkillsGradebook): implementsOnly(IMySkillsGrades) adapts(ISectionSkillSet) def __init__(self, context): super(MySkillsGrades, self).__init__(context) # To make URL creation happy self.__name__ = 'mygrades-skills' class MyProjectsGrades(ProjectsGradebook): implementsOnly(IMyProjectsGrades) adapts(IProject) def __init__(self, context): super(MyProjectsGrades, self).__init__(context) # To make URL creation happy self.__name__ = 'mygrades-projects' @adapter(IHaveEvaluations, ISkill) @implementer(IScore) def getSkillScore(evaluatee, skill): return getActivityScore(evaluatee, skill) class ProjectGradebookTraverser(object): implements(IPublishTraverse) def __init__(self, context, request): self.context = context self.request = request def publishTraverse(self, request, name): context = proxy.removeSecurityProxy(self.context) try: activity = context[name] return activity except KeyError: if name == 'gradebook': gb = IProjectsGradebook(context) gb = LocationProxy(gb, self.context, name) gb.__setattr__('__parent__', gb.__parent__) return gb elif name == 'mygrades': gb = IMyProjectsGrades(context) gb = LocationProxy(gb, self.context, name) gb.__setattr__('__parent__', gb.__parent__) return gb else: return queryMultiAdapter((self.context, request), name=name) class SkillsGradebookTraverser(object): implements(IPublishTraverse) def __init__(self, context, request): self.context = context self.request = request def publishTraverse(self, request, name): context = proxy.removeSecurityProxy(self.context) try: activity = context[name] return activity except KeyError: if name == 'gradebook': gb = ISkillsGradebook(context) gb = LocationProxy(gb, self.context, name) gb.__setattr__('__parent__', gb.__parent__) return gb elif name == 'mygrades': gb = IMySkillsGrades(context) gb = LocationProxy(gb, self.context, name) gb.__setattr__('__parent__', gb.__parent__) return gb else: return queryMultiAdapter((self.context, request), name=name) def getCourseSkillSetSection(worksheet): return worksheet.__parent__.__parent__ class CanDoStudentGradebook(StudentGradebook): implements(ICanDoStudentGradebook) adapts(IBasicPerson, ICanDoGradebook) @property def __parent__(self): return self.gradebook.__parent__ class CanDoStudentGradebookTraverser(object): implements(IPublishTraverse) def __init__(self, context, request): self.context = context self.request = request def publishTraverse(self, request, name): app = ISchoolToolApplication(None) context = proxy.removeSecurityProxy(self.context) try: student = app['persons'][name] except KeyError: return queryMultiAdapter((self.context, request), name=name) try: gb = getMultiAdapter((student, context), ICanDoStudentGradebook) except ValueError: return queryMultiAdapter((self.context, request), name=name) # location looks like http://host/path/to/gradebook/studentsUsername gb = LocationProxy(gb, self.context, name) return gb schooltool.cando-2.6.2/src/schooltool/cando/project.zcml0000644000175000017500000001220312270520445024515 0ustar menesismenesis00000000000000 schooltool.cando-2.6.2/src/schooltool/cando/__init__.py0000644000175000017500000000201612270520445024272 0ustar menesismenesis00000000000000# # SchoolTool - common information systems platform for school administration # Copyright (c) 2012 Shuttleworth Foundation # # 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 2 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 . # from zope.i18nmessageid import MessageFactory CanDoMessage = MessageFactory("schooltool.cando") import interfaces import model import skill import project import stesting import schooltool.common schooltool.common.register_lauchpad_project(__package__, 'schooltool.cando') schooltool.cando-2.6.2/src/schooltool/cando/plugin.zcml0000644000175000017500000000026312270520445024350 0ustar menesismenesis00000000000000 schooltool.cando-2.6.2/src/schooltool/cando/stesting.zcml0000644000175000017500000000057212270520445024715 0ustar menesismenesis00000000000000 schooltool.cando-2.6.2/src/schooltool/cando/security.zcml0000644000175000017500000000122612270520445024721 0ustar menesismenesis00000000000000 schooltool.cando-2.6.2/src/schooltool/cando/skill.py0000644000175000017500000002402112270520445023651 0ustar menesismenesis00000000000000# # SchoolTool - common information systems platform for school administration # Copyright (c) 2012 Shuttleworth Foundation # # 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 2 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 . # from decimal import Decimal from zope.annotation.interfaces import IAnnotations import zc.catalog.extentcatalog from zope.catalog.text import TextIndex from zope.index.text.interfaces import ISearchableText from zope.interface import implements, implementer from zope.component import adapter, adapts from zope.container.btree import BTreeContainer from zope.container.interfaces import INameChooser from zope.security.proxy import removeSecurityProxy from schooltool.app.app import InitBase, StartUpBase from schooltool.app.catalog import AttributeCatalog from schooltool.app.interfaces import ISchoolToolApplication from schooltool.cando import interfaces from schooltool.relationship import URIObject from schooltool.relationship import RelationshipSchema, RelationshipProperty from schooltool.requirement.interfaces import IScoreSystemContainer from schooltool.requirement.requirement import Requirement from schooltool.requirement.scoresystem import CustomScoreSystem from schooltool.requirement.scoresystem import GlobalDiscreteValuesScoreSystem DEFAULT_SCORESYSTEM_KEY = 'schooltool.cando.defaultscoresystem' URISkill = URIObject( 'http://schooltool.org/ns/cando/skill', 'Skill', 'A single skill.') URISkillSet = URIObject( 'http://schooltool.org/ns/cando/skillset', 'Skillset', 'A set of skills.') URIEquivalent = URIObject( 'http://schooltool.org/ns/cando/skill/equivalent', 'Equivalent', 'All equivalend skills.') EquivalentSkills = RelationshipSchema( URIEquivalent, skill=URISkill, equivalent=URISkill) class Skill(Requirement): implements(interfaces.ISkill) external_id = u'' label = u'' description = u'' required = False retired = False custom_scoresystem = None equivalent = RelationshipProperty(URIEquivalent, URISkill, URISkill) def __init__(self, title, required=False, external_id=u'', label=u'', scoresystem=None): Requirement.__init__(self, title) self.required = required self.external_id = external_id self.label = label self.custom_scoresystem = scoresystem @property def scoresystem(self): if self.custom_scoresystem is not None: return self.custom_scoresystem return querySkillScoreSystem() @scoresystem.setter def scoresystem(self, new_scoresystem): self.custom_scoresystem = new_scoresystem def findAllEquivalent(self): """Find indirectly equivalent skills.""" visited = set() result = list() open = set(self.equivalent) while open: skill = open.pop() # XXX: proxies! if (skill not in visited and skill is not self): visited.add(skill) result.append(skill) open.update(set(skill.equivalent).difference(set(visited))) return result def copy(self): return Skill(title=self.title, required=self.required, external_id=self.external_id, label=self.label) def __repr__(self): desc = unicode(self.title) if len(desc) > 40: desc = desc[:17]+'...'+desc[-20:] return '' % unicode(desc) class SkillSetContainer(BTreeContainer): """Container of skill sets.""" implements(interfaces.ISkillSetContainer) class SkillSet(Requirement): implements(interfaces.ISkillSet) description = u'' label = u'' retired = False def __init__(self, title, description=u'', label=u''): Requirement.__init__(self, title) self.description = description self.label = label def add(self, skill): skill_copy = skill.copy() chooser = INameChooser(self) name = chooser.chooseName(skill.__name__, skill_copy) self[name] = skill_copy return skill_copy class SkillInit(InitBase): def __call__(self): self.app['schooltool.cando.skillset'] = SkillSetContainer() class SkillAppStartup(StartUpBase): def __call__(self): if 'schooltool.cando.skillset' not in self.app: self.app['schooltool.cando.skillset'] = SkillSetContainer() @implementer(interfaces.ISkillSetContainer) @adapter(ISchoolToolApplication) def getSkillSetContainer(app): return app['schooltool.cando.skillset'] SkillScoreSystem = GlobalDiscreteValuesScoreSystem( 'SkillScoreSystem', u'Competency', u'Skill Competency Score', [('4', u'Expert', Decimal(4), Decimal(90)), ('3', u'Competent', Decimal(3), Decimal(70)), ('2', u'Practicing', Decimal(2), Decimal(50)), ('1', u'Beginning', Decimal(1), Decimal(30)), ('0', u'Uninformed', Decimal(0), Decimal(0))], '4', '3') class ScoreSystemAppStartup(StartUpBase): after = ('schooltool.requirement.scoresystem', ) def __call__(self): ssc = IScoreSystemContainer(self.app) if SkillScoreSystem.__name__ in ssc: return ssc[SkillScoreSystem.__name__] = CustomScoreSystem( SkillScoreSystem.title, SkillScoreSystem.description, SkillScoreSystem.scores, SkillScoreSystem._bestScore, SkillScoreSystem._minPassingScore) def querySkillScoreSystem(): """Get default skill score system for evaluations.""" app = ISchoolToolApplication(None) ssc = IScoreSystemContainer(app) ss = ssc.get(SkillScoreSystem.__name__, None) if ss is not None: return ss if len(ssc) > 0: return ssc.values()[0] return None def getDefaultSkillScoreSystem(person): default_ss = querySkillScoreSystem() if default_ss is None: return None default = [default_ss.__name__.encode('punycode')] if person is None: return default ann = IAnnotations(removeSecurityProxy(person)) if DEFAULT_SCORESYSTEM_KEY not in ann: return default return ann[DEFAULT_SCORESYSTEM_KEY] def setDefaultSkillScoreSystem(person, scoresystem): if person is None: return person = removeSecurityProxy(person) ann = IAnnotations(person) ann[DEFAULT_SCORESYSTEM_KEY] = scoresystem def is_global_skillset(index, docid, item): if (not interfaces.ISkillSet.providedBy(item) or not interfaces.ISkillSetContainer.providedBy(item.__parent__) or not ISchoolToolApplication.providedBy(item.__parent__.__parent__)): return False return True def is_global_skill(index, docid, item): if (not interfaces.ISkill.providedBy(item) or not interfaces.ISkillSet.providedBy(item.__parent__) or not interfaces.ISkillSetContainer.providedBy(item.__parent__.__parent__) or not ISchoolToolApplication.providedBy(item.__parent__.__parent__.__parent__)): return False return True searchable_common_indexes = { 'text_ID': 'getSearchableID', 'text_title': 'getSearchableTitle', 'text_label': 'getSearchableLabel', } def setSearchableIndexes(catalog): catalog['text'] = TextIndex('getSearchableText', ISearchableText, True) for index_id, method_name in searchable_common_indexes.items(): catalog[index_id] = TextIndex(method_name, ISearchableText, True) class SkillCatalog(AttributeCatalog): version = '1.3 - add __name__ to text index' interface = interfaces.ISkill attributes = ('title', 'external_id', 'label', 'description', 'required', 'retired') def createCatalog(self): return zc.catalog.extentcatalog.Catalog( zc.catalog.extentcatalog.FilterExtent(is_global_skill)) def setIndexes(self, catalog): super(SkillCatalog, self).setIndexes(catalog) setSearchableIndexes(catalog) getSkillCatalog = SkillCatalog.get class SearchableTextMixin(object): def getSearchableID(self): return self.context.__name__ def getSearchableTitle(self): return self.context.title def getSearchableLabel(self): return self.context.label or '' class SearchableTextSkill(SearchableTextMixin): adapts(interfaces.ISkill) implements(ISearchableText) def __init__(self, context): self.context = context def getSearchableText(self): result = [ self.context.__name__, self.context.title, self.context.external_id or '', self.context.label or '', self.context.description or '', ] return ' '.join(result) class SkillSetCatalog(AttributeCatalog): version = '1.3 - add __name__ to text index' interface = interfaces.ISkillSet attributes = ('title', 'label', 'description', 'retired') def createCatalog(self): return zc.catalog.extentcatalog.Catalog( zc.catalog.extentcatalog.FilterExtent(is_global_skillset)) def setIndexes(self, catalog): super(SkillSetCatalog, self).setIndexes(catalog) setSearchableIndexes(catalog) getSkillSetCatalog = SkillSetCatalog.get class SearchableTextSkillSet(SearchableTextMixin): adapts(interfaces.ISkillSet) implements(ISearchableText) def __init__(self, context): self.context = context def getSearchableText(self): result = [ self.context.__name__, self.context.title, self.context.label or '', self.context.description or '', ] return ' '.join(result) # + directly equivalent # + all equivalent schooltool.cando-2.6.2/src/schooltool/cando/skill.zcml0000644000175000017500000000450512270520445024173 0ustar menesismenesis00000000000000 schooltool.cando-2.6.2/src/schooltool/cando/course.py0000644000175000017500000003230312270520445024035 0ustar menesismenesis00000000000000# # SchoolTool - common information systems platform for school administration # Copyright (c) 2012 Shuttleworth Foundation # # 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 2 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 . # """Integration with SchoolTool course""" from persistent.dict import PersistentDict import zope.lifecycleevent from zope.annotation.interfaces import IAnnotations from zope.event import notify from zope.interface import implements, implementer from zope.intid.interfaces import IIntIds from zope.cachedescriptors.property import Lazy from zope.component import adapts, adapter, getUtility from zope.container.contained import containedEvent from zope.lifecycleevent.interfaces import IObjectAddedEvent from zope.lifecycleevent.interfaces import IObjectRemovedEvent from zope.lifecycleevent.interfaces import IObjectModifiedEvent from zope.lifecycleevent import ObjectModifiedEvent from zope.proxy.decorator import SpecificationDecoratorBase from zope.proxy import getProxiedObject from zope.security.proxy import removeSecurityProxy from schooltool.app.interfaces import ISchoolToolApplication from schooltool.app.relationships import CourseSections from schooltool.app.relationships import URICourseSections from schooltool.app.relationships import URISectionOfCourse, URICourse from schooltool.cando.interfaces import ICourseSkills from schooltool.cando.interfaces import ICourseSkillSet, ICourseSkill from schooltool.cando.interfaces import ISectionSkills, ISectionSkillSet from schooltool.cando.interfaces import ISkillSetContainer, ISkillSet, ISkill from schooltool.cando.skill import Skill, is_global_skillset from schooltool.course.interfaces import ISection, ICourse from schooltool.course.interfaces import ICourseContainer from schooltool.gradebook.activity import Worksheets, GenericWorksheet from schooltool.requirement.requirement import Requirement from schooltool.schoolyear.interfaces import ISchoolYearContainer from schooltool.schoolyear.subscriber import ObjectEventAdapterSubscriber from schooltool.cando import CanDoMessage as _ COURSE_SKILLS_KEY = 'schooltool.cando.project.courseskills' SECTION_SKILLS_KEY = 'schooltool.cando.project.sectionskills' class CourseSkills(Requirement): implements(ICourseSkills) class ReadOnlyContainer(KeyError): pass class SectionSkillSet(GenericWorksheet): implements(ISectionSkillSet) skillset = None def __init__(self, skillset): self.skillset = skillset super(SectionSkillSet, self).__init__(skillset.title) @property def deployed(self): return False @property def title(self): return self.skillset.title @title.setter def title(self, value): pass @property def description(self): course_skillset = self.skillset return course_skillset.skillset.description @property def label(self): course_skillset = self.skillset return course_skillset.skillset.label def all_keys(self): return super(SectionSkillSet, self).keys() def keys(self): return [key for key in self.all_keys() if not self[key].retired] def __contains__(self, key): return key in self.all_keys() class CourseSkillSet(GenericWorksheet): implements(ICourseSkillSet) required = None retired = None def __init__(self, skillset): super(CourseSkillSet, self).__init__(skillset.title) self.required = PersistentDict() self.retired = PersistentDict() @Lazy def skillset(self): if self.__name__ is None: return None app = ISchoolToolApplication(None) ssc = ISkillSetContainer(app) return ssc.get(self.__name__) def all_keys(self): return list(self.skillset.keys()) def keys(self): skillset = self.skillset return [key for key in skillset.keys() if not self.retired.get(key)] def __getitem__(self, key): skillset = self.skillset skill = skillset[key] cs = CourseSkill(skill) cs.__parent__ = self return cs def __setitem__(self, key, newobject): raise ReadOnlyContainer(key) def __delitem__(self, key): raise ReadOnlyContainer(key) class CourseSkill(SpecificationDecoratorBase): """A skill proxy that allows overriding of required/retired attributes.""" implements(ICourseSkill) __slots__ = ('__parent__', ) @property def required(self): if self.__name__ not in self.__parent__.required: unproxied = getProxiedObject(self) return unproxied.required return self.__parent__.required[self.__name__] @required.setter def required(self, value): self.__parent__.required[self.__name__] = value @property def retired(self): if self.__name__ not in self.__parent__.retired: unproxied = getProxiedObject(self) return unproxied.retired return self.__parent__.retired[self.__name__] @retired.setter def retired(self, value): self.__parent__.retired[self.__name__] = value @adapter(ICourse) @implementer(ICourseSkills) def getCourseSkills(course): annotations = IAnnotations(course) try: return annotations[COURSE_SKILLS_KEY] except KeyError: skills = CourseSkills(_('Course Skills')) annotations[COURSE_SKILLS_KEY] = skills # Sigh, this is not good. skills, event = containedEvent(skills, course, 'skills') notify(event) return skills getCourseSkills.factory = CourseSkills @adapter(ICourseSkills) @implementer(ICourse) def getCourseSkillsCourse(skills): return skills.__parent__ class SectionSkills(Worksheets): implements(ISectionSkills) annotations_current_worksheet_key = 'schooltool.cando.project.sectionskills' class SectionSkill(Skill): section_intid = None source_skillset_name = None source_skill_name = None @property def section(self): if self.section_intid is None: return None int_ids = getUtility(IIntIds) section = int_ids.queryObject(self.section_intid) return section @adapter(ISection) @implementer(ISectionSkills) def getSectionSkills(section): annotations = IAnnotations(section) try: return annotations[SECTION_SKILLS_KEY] except KeyError: skills = SectionSkills(_('Section Skills')) annotations[SECTION_SKILLS_KEY] = skills # Sigh, this is not good. skills, event = containedEvent(skills, section, 'skills') notify(event) return skills getSectionSkills.factory = SectionSkills class CourseWorksheetEventSubscriber(ObjectEventAdapterSubscriber): @property def sections(self): skillset = self.object course = removeSecurityProxy(ICourse(skillset.__parent__)) sections = list(CourseSections.query(course=course)) return sections class CourseWorksheetRemoved(CourseWorksheetEventSubscriber): adapts(IObjectRemovedEvent, ICourseSkillSet) def __call__(self): skillset = self.object for section in self.sections: worksheets = ISectionSkills(section) if self.object.__name__ in worksheets: del worksheets[skillset.__name__] class ICustomObjectModifiedEvent(IObjectModifiedEvent): pass class CustomObjectModifiedEvent(ObjectModifiedEvent): implements(ICustomObjectModifiedEvent) class GlobalSkillSetUpdateMixin(object): def yearsToUpdate(self): app = ISchoolToolApplication(None) syc = ISchoolYearContainer(app) active = syc.getActiveSchoolYear() if active is None: return list(syc.values()) idx = removeSecurityProxy(syc.sorted_schoolyears).index(removeSecurityProxy(active)) years = syc.sorted_schoolyears[idx:] return years def updateSkillSet(self, skillset): years = self.yearsToUpdate() for year in years: courses = ICourseContainer(year) for course in courses.values(): annotations = IAnnotations(course) if COURSE_SKILLS_KEY not in annotations: continue course_skills = annotations[COURSE_SKILLS_KEY] for course_skillset in course_skills.values(): if course_skillset.__name__ == skillset.__name__: notify(CustomObjectModifiedEvent(course_skillset)) class GlobalSkillSetModified(ObjectEventAdapterSubscriber, GlobalSkillSetUpdateMixin): adapts(IObjectModifiedEvent, ISkillSet) def __call__(self): skillset = self.object if not is_global_skillset(None, None, skillset): return self.updateSkillSet(skillset) if skillset.retired: self.retireSkills(skillset) def retireSkills(self, skillset): for skill_id in skillset: skill = skillset[skill_id] if not skill.retired: skill.retired = True zope.lifecycleevent.modified(skill) class GlobalSkillModified(ObjectEventAdapterSubscriber, GlobalSkillSetUpdateMixin): adapts(IObjectModifiedEvent, ISkill) def __call__(self): skillset = self.object.__parent__ if not is_global_skillset(None, None, skillset): return self.updateSkillSet(skillset) def updateCourseSkillSet(skillset, section, update_all_attrs=True): attrs = ('external_id', 'label', 'description', 'title') if update_all_attrs: attrs += ('required', 'retired', 'scoresystem') int_ids = getUtility(IIntIds) worksheets = ISectionSkills(section) section_intid = int_ids.getId(section) unproxied_skillset = removeSecurityProxy(skillset) if skillset.__name__ not in worksheets: worksheet = worksheets[skillset.__name__] = SectionSkillSet(unproxied_skillset) else: worksheet = worksheets[skillset.__name__] delete_skills = list(worksheet.all_keys()) for skill_name in skillset.all_keys(): skill = skillset[skill_name] if skill_name not in worksheet.all_keys(): target_skill = worksheet[skill_name] = SectionSkill(skill.title) target_skill.equivalent.add(removeSecurityProxy(skill)) else: if skill_name in delete_skills: delete_skills.remove(skill_name) target_skill = worksheet[skill_name] for attr in attrs: val = getattr(skill, attr, None) if getattr(target_skill, attr, None) != val: setattr(target_skill, attr, val) if target_skill.section_intid != section_intid: target_skill.section_intid = section_intid if target_skill.source_skill_name != skill.__name__: target_skill.source_skill_name = skill.__name__ if target_skill.source_skillset_name != skill.__parent__.__name__: target_skill.source_skillset_name = skill.__parent__.__name__ available = worksheet.all_keys() for skill_name in delete_skills: if skill_name in available: del worksheet[skill_name] class CourseSkillSetModified(CourseWorksheetEventSubscriber): adapts(IObjectModifiedEvent, ICourseSkillSet) def __call__(self): skillset = removeSecurityProxy(self.object) skillset.title = skillset.skillset.title for section in self.sections: updateCourseSkillSet(skillset, section) class CustomCourseSkillSetModified(CourseWorksheetEventSubscriber): adapts(ICustomObjectModifiedEvent, ICourseSkillSet) def __call__(self): skillset = removeSecurityProxy(self.object) skillset.title = skillset.skillset.title for section in self.sections: updateCourseSkillSet(skillset, section, update_all_attrs=False) class CourseWorksheetAdded(CourseSkillSetModified): adapts(IObjectAddedEvent, ICourseSkillSet) class DeploySkillsToNewSection(ObjectEventAdapterSubscriber): adapts(IObjectAddedEvent, ISection) def __call__(self): section = self.object for course in section.courses: courseskills = ICourseSkills(course) for skillset in courseskills.values(): updateCourseSkillSet(skillset, section) def updateSectionSkillsOnCourseChange(event): if event.rel_type != URICourseSections: return section = event[URISectionOfCourse] course = event[URICourse] courseskills = ICourseSkills(course) for skillset in courseskills.values(): updateCourseSkillSet(skillset, section) # XXX: maybe course-skillset relationship views # XXX: helper: linking of all node skillsets to course # XXX: helper: copying (with resetting required=False) of skillsets # (and linking to course) schooltool.cando-2.6.2/src/schooltool/cando/configure.zcml0000644000175000017500000000116212270520445025032 0ustar menesismenesis00000000000000 schooltool.cando-2.6.2/src/schooltool/cando/course.zcml0000644000175000017500000000572212270520445024357 0ustar menesismenesis00000000000000 schooltool.cando-2.6.2/src/schooltool/cando/locales/0000755000175000017500000000000012322040274023577 5ustar menesismenesis00000000000000schooltool.cando-2.6.2/src/schooltool/cando/locales/es_SV/0000755000175000017500000000000012322040274024616 5ustar menesismenesis00000000000000schooltool.cando-2.6.2/src/schooltool/cando/locales/es_SV/LC_MESSAGES/0000755000175000017500000000000012322040274026403 5ustar menesismenesis00000000000000schooltool.cando-2.6.2/src/schooltool/cando/locales/es_SV/LC_MESSAGES/schooltool.cando.mo0000644000175000017500000001310512322040274032210 0ustar menesismenesis00000000000000Þ•a$ƒ,89 N\vˆ ” ¡ ®¸Á× èö  + 1 A H [ d p  Ÿ "¹ !Ü þ   & + 9 N k € Œ — § ³ À Å Ì Ï ï     / 6 G X d n |  “ © ® ´ Ä Ì Ô ä í û   ) 0 > +F r { ™ ¤ « » Ì Ú â é î ô ù   ' 1 < Q V ÀZ 4&Fmˆ‘™ª ¼ É"Öù+BTsy’›°¶È,ã)-:(h ‘› µÀ ÇÔ#î ,9Lj~–œ £/±á !6<Pjy‹§ª&Äëðö  /9 NX` w˜Ÿ ³7½õ (> Ub|— °¼ÃÌÔ Øåü<A@!D5;L`1K ?'7_ MOaB03%SV86> Y, /)J\[Q4 WT]#X*2UG&=.<+FPZN"H^E(9 :$RI-CA${layer} Information${layer} list${section} Project Skills${section} SkillsActionsAddAdd ${layer}Add DocumentAdd LayerAdd NodeAssign Courses SkillsAssign Skill SetAssign SkillsAssigned SkillsAvailable layersBatch Assign SkillsCanDoCanDo GradebookCancelChange informationChildrenColor CodesColor Codes HelpCouldn't find a matching nodeCourse attribute is emptyCourse has skills assigned alreadyCurrent document hierarchy layersDocumentDocument InformationDocumentsEditEdit ChildrenEdit Hierarchy LayerEdit Hierarchy Layer ParentsEdit Layer HierarchyEdit LayersEdit SkillEdit Skill SetsEdit SkillsEnter SkillsHelpHiddenIDID, title, label or descriptionImport Skill DataLabelLayerLayer HierarchyLayer InformationLayersLayers ContainerMy Skills GradesNew ProjectNew SkillNew Skill SetNoNo Visible ProjectsNo Visible Skill SetsNodeNodesNodes ContainerParentsProjectProject DetailsProjectsRemove SkillsRequiredScoreScore SystemScore System HelpSearchSearch SkillsSectionSelect Skill Sets from ${node} (${node_id})SettingsSkillSkill DetailsSkill SetSkill SetsSkillsSkills DocumentSkills DocumentsSkills Pop-upSort bySubmitTermTitleViewView ${layer}View Hierarchy LayerView LayerView NodeView SkillView Skills DocumentYearYesProject-Id-Version: schooltool.cando Report-Msgid-Bugs-To: FULL NAME POT-Creation-Date: 2013-10-10 16:06+0300 PO-Revision-Date: 2013-07-31 17:09+0000 Last-Translator: Douglas Cerna Language-Team: Spanish (El Salvador) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Launchpad-Export-Date: 2013-10-11 05:28+0000 X-Generator: Launchpad (build 16799) Información de ${layer}Lista de ${layer}Competencias de Proyecto de ${section}Competencias de ${section}AccionesAñadirAñadir ${layer}Añadir DocumentoAñadir CapaAñadir NodoAsignar Competencias de AsignaturaAsignar Grupo de CompetenciaAsignar CompetenciasCompetencias AsignadasCapas disponiblesAsignar Competencias por LotesCanDoCuadro de Notas de CanDoCancelarCambiar informaciónHijosCódigos de ColorAyuda de Códigos de ColorNo se pudo encontrar un nodo que correspondaEl atributo de la asignatura está vacíoLa asignatura ya tiene competencias asignadasCapas de jerarquía del documento actualDocumentoInformación de DocumentoDocumentosEditarEditar HijosEditar Jerarquía de CapaEditar Padres de Jerarquía de CapaEditar Jerarquía de CapaEditar CapasEditar CompetenciaEditar Grupos de CompetenciasEditar CompetenciasIntroducir CompetenciasAyudaOcultaIdentificadorIdentificador, título, etiqueta o descripciónImportar Datos de CompetenciasEtiquetaCapaJerarquía de CapaInformación de CapaCapasContenedor de CapasMis Notas de CompetenciasProyecto NuevoNueva CompetenciaNuevo Grupo de CompetenciasNoNo hay Proyectos VisiblesNo hay Grupos de Competencias VisiblesNodoNodosContenedor de NodosPadresProyectoDetalles de ProyectoProyectosRemover CompetenciasRequeridaPuntajeSistema de PuntuaciónAyuda del Sistema de PuntuaciónBuscarBuscar CompetenciasSeccioÌnSeleccionar Grupos de Competencias ${node} (${node_id})ConfiguraciónCompetenciaDetalles de CompetenciaGrupo de CompetenciasGrupos de CompetenciasCompetenciasDocumento de CompetenciasDocumentos de CompetenciasDiálogo de CompetenciasOrdenar porEnviarPeríodoTítuloVerVer ${layer}Ver Jerarquía de CapaVer CapaVer NodoVer CompetenciaVer Documento de CompetenciasAñoSíschooltool.cando-2.6.2/src/schooltool/cando/locales/__init__.py0000644000175000017500000000002112270520445025706 0ustar menesismenesis00000000000000# Make a package schooltool.cando-2.6.2/src/schooltool/cando/locales/es_SV.po0000644000175000017500000010555212322023754025172 0ustar menesismenesis00000000000000# Spanish (El Salvador) translation for schooltool.cando # Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012 # This file is distributed under the same license as the schooltool.cando package. # FIRST AUTHOR , 2012. # msgid "" msgstr "" "Project-Id-Version: schooltool.cando\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2013-10-10 16:06+0300\n" "PO-Revision-Date: 2013-07-31 17:09+0000\n" "Last-Translator: Douglas Cerna \n" "Language-Team: Spanish (El Salvador) \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2013-10-11 05:28+0000\n" "X-Generator: Launchpad (build 16799)\n" #: /src/schooltool/cando/browser/breadcrumbs.zcml:9 #: /src/schooltool/cando/browser/breadcrumbs.zcml:67 #: /src/schooltool/cando/browser/breadcrumbs.zcml:72 #: /src/schooltool/cando/browser/configure.zcml:135 #: /src/schooltool/cando/browser/configure.zcml:336 #: /src/schooltool/cando/browser/configure.zcml:779 #: /src/schooltool/cando/browser/course.py:162 #: /src/schooltool/cando/browser/document.py:815 #: /src/schooltool/cando/browser/document.zcml:26 #: /src/schooltool/cando/browser/gradebook.py:275 #: /src/schooltool/cando/browser/skill.py:76 #: /src/schooltool/cando/browser/templates/course_assign_skillsets_dialog.pt:30 #: /src/schooltool/cando/browser/templates/course_remove_skills.pt:20 #: /src/schooltool/cando/browser/templates/course_skills_overview.pt:4 #: /src/schooltool/cando/browser/templates/skillset.pt:77 msgid "Skills" msgstr "Competencias" #: /src/schooltool/cando/browser/breadcrumbs.zcml:14 #: /src/schooltool/cando/browser/configure.zcml:40 #: /src/schooltool/cando/browser/course.py:292 #: /src/schooltool/cando/browser/document.py:122 #: /src/schooltool/cando/browser/gradebook.zcml:115 msgid "Skill Sets" msgstr "Grupos de Competencias" #: /src/schooltool/cando/browser/breadcrumbs.zcml:21 #: /src/schooltool/cando/browser/course.py:287 #: /src/schooltool/cando/browser/document.py:121 #: /src/schooltool/cando/browser/model.py:439 #: /src/schooltool/cando/browser/templates/course_assign_skills_table_filter.pt:34 #: /src/schooltool/cando/browser/templates/node.pt:155 #: /src/schooltool/cando/browser/templates/nodes_table_filter.pt:34 msgid "Layers" msgstr "Capas" #: /src/schooltool/cando/browser/breadcrumbs.zcml:28 msgid "Nodes" msgstr "Nodos" #: /src/schooltool/cando/browser/configure.zcml:107 #: /src/schooltool/cando/browser/configure.zcml:162 #: /src/schooltool/cando/browser/configure.zcml:515 #: /src/schooltool/cando/browser/configure.zcml:642 #: /src/schooltool/cando/browser/course.py:223 #: /src/schooltool/cando/browser/course.py:225 #: /src/schooltool/cando/browser/document.zcml:61 #: /src/schooltool/cando/browser/document.zcml:185 #: /src/schooltool/cando/browser/document.zcml:220 #: /src/schooltool/cando/browser/document.zcml:303 #: /src/schooltool/cando/browser/gradebook.zcml:63 #: /src/schooltool/cando/browser/templates/course_assign_skillsets_dialog.pt:32 msgid "Add" msgstr "Añadir" #: /src/schooltool/cando/browser/configure.zcml:117 #: /src/schooltool/cando/browser/configure.zcml:260 #: /src/schooltool/cando/browser/configure.zcml:795 msgid "Actions" msgstr "Acciones" #: /src/schooltool/cando/browser/configure.zcml:127 msgid "Skill Set" msgstr "Grupo de Competencias" #: /src/schooltool/cando/browser/configure.zcml:135 msgid "New Skill Set" msgstr "Nuevo Grupo de Competencias" #: /src/schooltool/cando/browser/configure.zcml:145 #: /src/schooltool/cando/browser/configure.zcml:199 #: /src/schooltool/cando/browser/configure.zcml:552 #: /src/schooltool/cando/browser/configure.zcml:679 #: /src/schooltool/cando/browser/document.zcml:98 #: /src/schooltool/cando/browser/document.zcml:194 #: /src/schooltool/cando/browser/document.zcml:253 #: /src/schooltool/cando/browser/document.zcml:312 #: /src/schooltool/cando/browser/document.zcml:345 #: /src/schooltool/cando/browser/gradebook.zcml:322 #: /src/schooltool/cando/browser/templates/document.pt:9 #: /src/schooltool/cando/browser/templates/layer.pt:109 #: /src/schooltool/cando/browser/templates/node.pt:21 #: /src/schooltool/cando/browser/templates/node.pt:126 #: /src/schooltool/cando/browser/templates/node.pt:164 #: /src/schooltool/cando/browser/templates/node.pt:201 msgid "Edit" msgstr "Editar" #: /src/schooltool/cando/browser/configure.zcml:171 #: /src/schooltool/cando/browser/document.py:166 #: /src/schooltool/cando/browser/document.py:388 #: /src/schooltool/cando/browser/document.py:397 #: /src/schooltool/cando/browser/gradebook.py:182 #: /src/schooltool/cando/browser/gradebook.py:197 #: /src/schooltool/cando/browser/gradebook.py:298 #: /src/schooltool/cando/browser/gradebook.py:924 #: /src/schooltool/cando/browser/model.py:137 #: /src/schooltool/cando/browser/skill.py:221 #: /src/schooltool/cando/browser/skill.py:279 #: /src/schooltool/cando/browser/skill.py:307 #: /src/schooltool/cando/browser/templates/edit_course_skills.pt:7 #: /src/schooltool/cando/browser/templates/student_competency_record.pt:9 msgid "Skill" msgstr "Competencia" #: /src/schooltool/cando/browser/configure.zcml:181 #: /src/schooltool/cando/browser/gradebook.py:838 #: /src/schooltool/cando/browser/gradebook.zcml:187 msgid "New Skill" msgstr "Nueva Competencia" #: /src/schooltool/cando/browser/configure.zcml:190 #: /src/schooltool/cando/browser/configure.zcml:461 msgid "View Skill" msgstr "Ver Competencia" #: /src/schooltool/cando/browser/configure.zcml:228 #: /src/schooltool/cando/browser/configure.zcml:395 msgid "Assigned Skills" msgstr "Competencias Asignadas" #: /src/schooltool/cando/browser/configure.zcml:270 #: /src/schooltool/cando/browser/configure.zcml:345 msgid "Assign Skills" msgstr "Asignar Competencias" #: /src/schooltool/cando/browser/configure.zcml:278 #: /src/schooltool/cando/browser/configure.zcml:353 msgid "Remove Skills" msgstr "Remover Competencias" #: /src/schooltool/cando/browser/configure.zcml:298 #: /src/schooltool/cando/browser/configure.zcml:315 msgid "Set Required / Deprecated" msgstr "" #: /src/schooltool/cando/browser/configure.zcml:347 msgid "Assign Skill Set" msgstr "Asignar Grupo de Competencia" #: /src/schooltool/cando/browser/configure.zcml:404 msgid "Edit Skills" msgstr "Editar Competencias" #: /src/schooltool/cando/browser/configure.zcml:488 #: /src/schooltool/cando/browser/configure.zcml:533 msgid "Layers Container" msgstr "Contenedor de Capas" #: /src/schooltool/cando/browser/configure.zcml:524 #: /src/schooltool/cando/browser/model.py:174 msgid "Layer" msgstr "Capa" #: /src/schooltool/cando/browser/configure.zcml:533 msgid "Add Layer" msgstr "Añadir Capa" #: /src/schooltool/cando/browser/configure.zcml:543 msgid "View Layer" msgstr "Ver Capa" #: /src/schooltool/cando/browser/configure.zcml:561 #: /src/schooltool/cando/browser/configure.zcml:688 msgid "Edit Children" msgstr "Editar Hijos" #: /src/schooltool/cando/browser/configure.zcml:605 #: /src/schooltool/cando/browser/configure.zcml:660 msgid "Nodes Container" msgstr "Contenedor de Nodos" #: /src/schooltool/cando/browser/configure.zcml:605 #: /src/schooltool/cando/browser/document.py:123 #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:77 #: /src/schooltool/cando/browser/templates/nodes_table_filter.pt:53 msgid "Search" msgstr "Buscar" #: /src/schooltool/cando/browser/configure.zcml:625 msgid "Deprecate" msgstr "" #: /src/schooltool/cando/browser/configure.zcml:625 msgid "Documents and Skills" msgstr "" #: /src/schooltool/cando/browser/configure.zcml:766 #: /src/schooltool/cando/browser/model.py:398 #: /src/schooltool/cando/browser/model.py:427 #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:109 msgid "Node" msgstr "Nodo" #: /src/schooltool/cando/browser/configure.zcml:660 msgid "Add Node" msgstr "Añadir Nodo" #: /src/schooltool/cando/browser/configure.zcml:670 msgid "View Node" msgstr "Ver Nodo" #: /src/schooltool/cando/browser/configure.zcml:714 msgid "Edit Layers" msgstr "Editar Capas" #: /src/schooltool/cando/browser/configure.zcml:785 msgid "Edit Skill Sets" msgstr "Editar Grupos de Competencias" #: /src/schooltool/cando/browser/configure.zcml:825 #: /src/schooltool/cando/browser/configure.zcml:833 msgid "Import Skill Data" msgstr "Importar Datos de Competencias" #: /src/schooltool/cando/browser/configure.zcml:919 msgid "Deprecate Skills" msgstr "" #: /src/schooltool/cando/browser/configure.zcml:974 msgid "Batch Assign Skills" msgstr "Asignar Competencias por Lotes" #: /src/schooltool/cando/browser/configure.zcml:814 msgid "Assign Courses Skills" msgstr "Asignar Competencias de Asignatura" #: /src/schooltool/cando/browser/course.py:156 #: /src/schooltool/cando/browser/course.py:277 #: /src/schooltool/cando/browser/course.py:571 #: /src/schooltool/cando/browser/document.py:869 #: /src/schooltool/cando/browser/model.py:432 #: /src/schooltool/cando/browser/templates/course_assign_skillsets_dialog.pt:29 #: /src/schooltool/cando/browser/templates/course_remove_skills.pt:19 #: /src/schooltool/cando/browser/templates/projects.pt:10 #: /src/schooltool/cando/browser/templates/skillsets.pt:10 #: /src/schooltool/cando/interfaces.py:72 #: /src/schooltool/cando/interfaces.py:89 msgid "Title" msgstr "Título" #: /src/schooltool/cando/browser/course.py:260 msgid "Select Skill Sets from ${node} (${node_id})" msgstr "Seleccionar Grupos de Competencias ${node} (${node_id})" #: /src/schooltool/cando/browser/course.py:282 msgid "ID" msgstr "Identificador" #: /src/schooltool/cando/browser/course.py:314 #: /src/schooltool/cando/browser/model.py:454 msgid "ID, title, label or description" msgstr "Identificador, título, etiqueta o descripción" #: /src/schooltool/cando/browser/course.py:576 #: /src/schooltool/cando/browser/course.py:635 #: /src/schooltool/cando/browser/document.py:880 #: /src/schooltool/cando/browser/model.py:427 #: /src/schooltool/cando/browser/skill.py:80 #: /src/schooltool/cando/browser/skill.py:209 #: /src/schooltool/cando/interfaces.py:63 #: /src/schooltool/cando/interfaces.py:96 msgid "Label" msgstr "Etiqueta" #: /src/schooltool/cando/browser/course.py:581 #: /src/schooltool/cando/browser/document.py:875 #: /src/schooltool/cando/browser/templates/colorcodes_help.pt:10 #: /src/schooltool/cando/browser/templates/edit_course_skills.pt:9 #: /src/schooltool/cando/browser/templates/student_competency_record.pt:8 #: /src/schooltool/cando/interfaces.py:39 msgid "Required" msgstr "Requerida" #: /src/schooltool/cando/browser/course.py:587 msgid "Hidden" msgstr "Oculta" #: /src/schooltool/cando/browser/course.py:790 msgid "Course has skills assigned already" msgstr "La asignatura ya tiene competencias asignadas" #: /src/schooltool/cando/browser/course.py:810 msgid "Couldn't find a matching node" msgstr "No se pudo encontrar un nodo que corresponda" #: /src/schooltool/cando/browser/course.py:816 msgid "Course attribute is empty" msgstr "El atributo de la asignatura está vacío" #: /src/schooltool/cando/browser/document.py:120 msgid "Documents" msgstr "Documentos" #: /src/schooltool/cando/browser/document.py:148 msgid "Document Information" msgstr "Información de Documento" #: /src/schooltool/cando/browser/document.py:198 #: /src/schooltool/cando/browser/document.py:524 #: /src/schooltool/cando/browser/document.py:708 #: /src/schooltool/cando/browser/document.py:769 #: /src/schooltool/cando/browser/gradebook.py:352 #: /src/schooltool/cando/browser/gradebook.py:471 #: /src/schooltool/cando/browser/iep.py:131 #: /src/schooltool/cando/browser/model.py:103 #: /src/schooltool/cando/browser/model.py:177 #: /src/schooltool/cando/browser/model.py:321 #: /src/schooltool/cando/browser/model.py:396 #: /src/schooltool/cando/browser/skill.py:179 #: /src/schooltool/cando/browser/skill.py:235 #: /src/schooltool/cando/browser/skill.py:327 #: /src/schooltool/cando/browser/templates/course_skills_edit_table_buttons.pt:5 msgid "Submit" msgstr "Enviar" #: /src/schooltool/cando/browser/document.py:186 #: /src/schooltool/cando/browser/document.py:465 #: /src/schooltool/cando/browser/document.py:645 #: /src/schooltool/cando/browser/document.py:709 #: /src/schooltool/cando/browser/gradebook.py:321 #: /src/schooltool/cando/browser/gradebook.py:444 #: /src/schooltool/cando/browser/model.py:106 #: /src/schooltool/cando/browser/model.py:183 #: /src/schooltool/cando/browser/model.py:324 #: /src/schooltool/cando/browser/model.py:403 #: /src/schooltool/cando/browser/skill.py:180 #: /src/schooltool/cando/browser/skill.py:238 #: /src/schooltool/cando/browser/skill.py:316 #: /src/schooltool/cando/browser/templates/course_skills_edit_table_buttons.pt:8 #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:79 #: /src/schooltool/cando/browser/templates/grade_student.pt:39 msgid "Cancel" msgstr "Cancelar" #: /src/schooltool/cando/browser/document.py:429 #: /src/schooltool/cando/browser/document.py:571 #: /src/schooltool/cando/browser/document.py:816 msgid "${layer} list" msgstr "Lista de ${layer}" #: /src/schooltool/cando/browser/document.py:450 #: /src/schooltool/cando/browser/document.zcml:70 msgid "Document" msgstr "Documento" #: /src/schooltool/cando/browser/document.py:477 msgid "Current document hierarchy layers" msgstr "Capas de jerarquía del documento actual" #: /src/schooltool/cando/browser/document.py:478 msgid "Available layers" msgstr "Capas disponibles" #: /src/schooltool/cando/browser/document.py:566 #: /src/schooltool/cando/browser/document.py:808 #: /src/schooltool/cando/browser/document.py:961 msgid "View ${layer}" msgstr "Ver ${layer}" #: /src/schooltool/cando/browser/document.py:624 #: /src/schooltool/cando/browser/document.py:744 #: /src/schooltool/cando/browser/document.py:921 msgid "Add ${layer}" msgstr "Añadir ${layer}" #: /src/schooltool/cando/browser/document.py:629 #: /src/schooltool/cando/browser/document.py:916 msgid "${layer} Information" msgstr "Información de ${layer}" #: /src/schooltool/cando/browser/document.py:673 msgid "Skills Document" msgstr "Documento de Competencias" #: /src/schooltool/cando/browser/document.py:695 msgid "Change information" msgstr "Cambiar información" #: /src/schooltool/cando/browser/document.py:928 #: /src/schooltool/cando/browser/gradebook.py:1594 msgid "No" msgstr "No" #: /src/schooltool/cando/browser/document.py:928 #: /src/schooltool/cando/browser/gradebook.py:1594 msgid "Yes" msgstr "Sí" #: /src/schooltool/cando/browser/document.zcml:35 #: /src/schooltool/cando/browser/document.zcml:79 msgid "Skills Documents" msgstr "Documentos de Competencias" #: /src/schooltool/cando/browser/document.zcml:79 msgid "Add Document" msgstr "Añadir Documento" #: /src/schooltool/cando/browser/document.zcml:89 msgid "View Skills Document" msgstr "Ver Documento de Competencias" #: /src/schooltool/cando/browser/document.zcml:107 msgid "Edit Layer Hierarchy" msgstr "Editar Jerarquía de Capa" #: /src/schooltool/cando/browser/document.zcml:133 msgid "View Hierarchy Layer" msgstr "Ver Jerarquía de Capa" #: /src/schooltool/cando/browser/document.zcml:142 msgid "Edit Hierarchy Layer" msgstr "Editar Jerarquía de Capa" #: /src/schooltool/cando/browser/document.zcml:151 msgid "Edit Hierarchy Layer Parents" msgstr "Editar Padres de Jerarquía de Capa" #: /src/schooltool/cando/browser/document.zcml:211 msgid "Layer Hierarchy" msgstr "Jerarquía de Capa" #: /src/schooltool/cando/browser/gradebook.py:189 msgid "No Visible Projects" msgstr "No hay Proyectos Visibles" #: /src/schooltool/cando/browser/gradebook.py:191 #: /src/schooltool/cando/browser/gradebook.py:206 msgid "Enter Skills" msgstr "Introducir Competencias" #: /src/schooltool/cando/browser/gradebook.py:204 msgid "No Visible Skill Sets" msgstr "No hay Grupos de Competencias Visibles" #: /src/schooltool/cando/browser/gradebook.py:281 #: /src/schooltool/cando/browser/gradebook.zcml:98 #: /src/schooltool/cando/browser/gradebook.zcml:106 #: /src/schooltool/cando/project.py:163 msgid "Projects" msgstr "Proyectos" #: /src/schooltool/cando/browser/gradebook.py:315 msgid "Project Details" msgstr "Detalles de Proyecto" #: /src/schooltool/cando/browser/gradebook.py:358 msgid "Sort by" msgstr "Ordenar por" #: /src/schooltool/cando/browser/gradebook.py:423 msgid "Skill Details" msgstr "Detalles de Competencia" #: /src/schooltool/cando/browser/gradebook.py:518 msgid "${section} Skills" msgstr "Competencias de ${section}" #: /src/schooltool/cando/browser/gradebook.py:520 msgid "${section} Project Skills" msgstr "Competencias de Proyecto de ${section}" #: /src/schooltool/cando/browser/gradebook.py:529 msgid "Score System Help" msgstr "Ayuda del Sistema de Puntuación" #: /src/schooltool/cando/browser/gradebook.py:537 msgid "Color Codes Help" msgstr "Ayuda de Códigos de Color" #: /src/schooltool/cando/browser/gradebook.py:953 msgid "No layer assigned" msgstr "" #: /src/schooltool/cando/browser/gradebook.py:1236 msgid "Changes saved" msgstr "" #: /src/schooltool/cando/browser/gradebook.py:1392 #: /src/schooltool/cando/browser/gradebook.zcml:140 msgid "Search Skills" msgstr "Buscar Competencias" #: /src/schooltool/cando/browser/gradebook.py:1450 msgid "Save" msgstr "" #: /src/schooltool/cando/browser/gradebook.py:1466 #: /src/schooltool/cando/browser/templates/scoresystem_help.pt:5 msgid "Score" msgstr "Puntaje" #: /src/schooltool/cando/browser/gradebook.py:1561 #: /src/schooltool/cando/browser/gradebook.zcml:520 msgid "CanDo Gradebook" msgstr "Cuadro de Notas de CanDo" #: /src/schooltool/cando/browser/gradebook.py:1677 msgid "Date" msgstr "" #: /src/schooltool/cando/browser/gradebook.py:1606 #: /src/schooltool/cando/browser/templates/scoresystem_help.pt:6 msgid "Rating" msgstr "" #: /src/schooltool/cando/browser/gradebook.py:1736 #: /src/schooltool/cando/browser/gradebook.py:1951 #: /src/schooltool/cando/browser/gradebook.zcml:770 msgid "Student Skill Report" msgstr "" #: /src/schooltool/cando/browser/gradebook.py:1759 msgid "Teacher(s): ${teachers}" msgstr "" #: /src/schooltool/cando/browser/gradebook.py:1755 #: /src/schooltool/cando/browser/gradebook.py:1870 msgid "Course: ${courses}" msgstr "" #: /src/schooltool/cando/browser/gradebook.py:1847 #: /src/schooltool/cando/browser/gradebook.zcml:782 msgid "Certificate of Competency" msgstr "" #: /src/schooltool/cando/browser/gradebook.py:2288 msgid "skill gradebooks archive" msgstr "" #: /src/schooltool/cando/browser/gradebook.zcml:10 #: /src/schooltool/cando/browser/gradebook.zcml:26 #: /src/schooltool/cando/browser/gradebook.zcml:128 #: /src/schooltool/cando/browser/gradebook.zcml:223 #: /src/schooltool/cando/browser/gradebook.zcml:321 #: /src/schooltool/cando/browser/gradebook.zcml:431 msgid "CanDo" msgstr "CanDo" #: /src/schooltool/cando/browser/gradebook.zcml:45 msgid "View" msgstr "Ver" #: /src/schooltool/cando/browser/gradebook.zcml:80 msgid "Project" msgstr "Proyecto" #: /src/schooltool/cando/browser/gradebook.zcml:88 msgid "Settings" msgstr "Configuración" #: /src/schooltool/cando/browser/gradebook.zcml:126 msgid "New Project" msgstr "Proyecto Nuevo" #: /src/schooltool/cando/browser/gradebook.zcml:310 msgid "Edit Skill" msgstr "Editar Competencia" #: /src/schooltool/cando/browser/gradebook.zcml:373 #: /src/schooltool/cando/browser/gradebook.zcml:637 #: /src/schooltool/cando/browser/gradebook.zcml:660 msgid "Help" msgstr "Ayuda" #: /src/schooltool/cando/browser/gradebook.zcml:383 msgid "Score System" msgstr "Sistema de Puntuación" #: /src/schooltool/cando/browser/gradebook.zcml:391 msgid "Color Codes" msgstr "Códigos de Color" #: /src/schooltool/cando/browser/gradebook.zcml:492 msgid "Skills Pop-up" msgstr "Diálogo de Competencias" #: /src/schooltool/cando/browser/gradebook.zcml:546 msgid "My Skills Grades" msgstr "Mis Notas de Competencias" #: /src/schooltool/cando/browser/gradebook.zcml:579 msgid "My Projects Grades" msgstr "" #: /src/schooltool/cando/browser/gradebook.zcml:596 #: /src/schooltool/cando/browser/gradebook.zcml:827 #: /src/schooltool/cando/browser/gradebook.zcml:839 #: /src/schooltool/cando/browser/report.py:878 #: /src/schooltool/cando/browser/report.zcml:47 #: /src/schooltool/cando/browser/report.zcml:58 msgid "Section" msgstr "SeccioÌn" #: /src/schooltool/cando/browser/gradebook.zcml:557 msgid "Term" msgstr "Período" #: /src/schooltool/cando/browser/gradebook.zcml:568 msgid "Year" msgstr "Año" #: /src/schooltool/cando/browser/gradebook.zcml:760 msgid "Reports" msgstr "" #: /src/schooltool/cando/browser/gradebook.zcml:770 msgid "" "Summary of a student's scores for all the skills assigned to a section." msgstr "" #: /src/schooltool/cando/browser/gradebook.zcml:770 #: /src/schooltool/cando/browser/gradebook.zcml:782 msgid "Student" msgstr "" #: /src/schooltool/cando/browser/gradebook.zcml:782 msgid "" "Summary of a student scores in a section exceeding a selected minimum score. " "Formatted for presentation to an potential employer or other person outside " "of the school." msgstr "" #: /src/schooltool/cando/browser/gradebook.zcml:794 #: /src/schooltool/cando/browser/gradebook.zcml:806 msgid "Aggregated Student Skill Reports" msgstr "" #: /src/schooltool/cando/browser/gradebook.zcml:794 msgid "" "Summary of all students' scores for all the skills assigned to a section." msgstr "" #: /src/schooltool/cando/browser/iep.py:122 msgid "IEP Details" msgstr "" #: /src/schooltool/cando/browser/iep.py:176 msgid "IEP Skills for ${section}" msgstr "" #: /src/schooltool/cando/browser/iep.py:322 msgid "Edit IEP Skills for ${section}" msgstr "" #: /src/schooltool/cando/browser/iep.py:354 msgid "Optional IEP" msgstr "" #: /src/schooltool/cando/browser/iep.py:424 msgid "IEP Information" msgstr "" #: /src/schooltool/cando/browser/iep.zcml:8 msgid "IEP" msgstr "" #: /src/schooltool/cando/browser/iep.zcml:17 #: /src/schooltool/cando/browser/iep.zcml:52 msgid "Individualized Educational Plan" msgstr "" #: /src/schooltool/cando/browser/importer.py:44 msgid "has an invalid document id" msgstr "" #: /src/schooltool/cando/browser/importer.py:45 msgid "has an invalid parent id" msgstr "" #: /src/schooltool/cando/browser/importer.py:46 msgid "has an invalid layer id" msgstr "" #: /src/schooltool/cando/browser/importer.py:47 msgid "has an invalid skillset id" msgstr "" #: /src/schooltool/cando/browser/importer.py:48 msgid "is missing a skillset id" msgstr "" #: /src/schooltool/cando/browser/importer.py:49 msgid "has an invalid equivalent skill id" msgstr "" #: /src/schooltool/cando/browser/importer.py:50 msgid "node label has more than seven characters" msgstr "" #: /src/schooltool/cando/browser/importer.py:51 msgid "has an invalid scoresystem" msgstr "" #: /src/schooltool/cando/browser/importer.py:52 msgid "has an invalid node id" msgstr "" #: /src/schooltool/cando/browser/model.py:94 msgid "Layer Information" msgstr "Información de Capa" #: /src/schooltool/cando/browser/model.py:209 msgid "Parents" msgstr "Padres" #: /src/schooltool/cando/browser/model.py:214 msgid "Children" msgstr "Hijos" #: /src/schooltool/cando/browser/model.py:257 msgid "Current child layers" msgstr "" #: /src/schooltool/cando/browser/model.py:258 msgid "Available child layers" msgstr "" #: /src/schooltool/cando/browser/model.py:307 msgid "Node Information" msgstr "" #: /src/schooltool/cando/browser/model.py:546 msgid "Current child nodes" msgstr "" #: /src/schooltool/cando/browser/model.py:547 msgid "Available child nodes" msgstr "" #: /src/schooltool/cando/browser/model.py:584 msgid "Current node layers" msgstr "" #: /src/schooltool/cando/browser/model.py:585 msgid "Available node layers" msgstr "" #: /src/schooltool/cando/browser/model.py:641 msgid "Current node skill sets" msgstr "" #: /src/schooltool/cando/browser/model.py:642 msgid "Available node skill sets" msgstr "" #: /src/schooltool/cando/browser/report.py:199 msgid "All" msgstr "" #: /src/schooltool/cando/browser/report.py:199 msgid "Evaluated" msgstr "" #: /src/schooltool/cando/browser/report.py:380 msgid "% of Skills Below and Above Passing" msgstr "" #: /src/schooltool/cando/browser/report.py:406 msgid "Students (${count})" msgstr "" #: /src/schooltool/cando/browser/report.py:480 msgid "Student ID #" msgstr "" #: /src/schooltool/cando/browser/report.py:640 #: /src/schooltool/cando/browser/templates/section_report_score_colors.pt:19 msgid "Score Colors" msgstr "" #: /src/schooltool/cando/browser/report.py:814 msgid "Totals" msgstr "" #: /src/schooltool/cando/browser/report.py:866 #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:88 #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:107 #: /src/schooltool/cando/browser/templates/section_report_details.pt:8 msgid "Course" msgstr "" #: /src/schooltool/cando/browser/report.py:874 #: /src/schooltool/cando/browser/templates/section_report_details.pt:16 msgid "Teachers" msgstr "" #: /src/schooltool/cando/browser/report.zcml:21 msgid "Export global skills data for the school." msgstr "" #: /src/schooltool/cando/browser/report.zcml:10 msgid "School" msgstr "" #: /src/schooltool/cando/browser/report.zcml:10 msgid "Skills Export" msgstr "" #: /src/schooltool/cando/browser/report.zcml:47 #: /src/schooltool/cando/browser/report.zcml:58 msgid "" "An overview of each student's achievement of skills within the section." msgstr "" #: /src/schooltool/cando/browser/report.zcml:47 #: /src/schooltool/cando/browser/report.zcml:58 #: /src/schooltool/cando/browser/report.zcml:88 #: /src/schooltool/cando/browser/report.zcml:244 msgid "Per Student Skills" msgstr "" #: /src/schooltool/cando/browser/report.zcml:70 msgid "An overview of each section's aggregate achievement of skills." msgstr "" #: /src/schooltool/cando/browser/report.zcml:70 msgid "Skills Completion" msgstr "" #: /src/schooltool/cando/browser/report.zcml:191 msgid "Passing Score" msgstr "" #: /src/schooltool/cando/browser/report.zcml:208 msgid "Type" msgstr "" #: /src/schooltool/cando/browser/report.zcml:226 #: /src/schooltool/cando/browser/templates/section_report_score_colors.pt:28 msgid "% Passing Target" msgstr "" #: /src/schooltool/cando/browser/report.zcml:252 msgid "Skills Completion Report" msgstr "" #: /src/schooltool/cando/browser/report.zcml:298 msgid "Location" msgstr "" #: /src/schooltool/cando/browser/report.zcml:360 msgid "Skill Gradebooks" msgstr "" #: /src/schooltool/cando/browser/report.zcml:369 msgid "Archive all student skill gradebooks." msgstr "" #: /src/schooltool/cando/browser/report.zcml:369 msgid "Skill Gradebook Archive" msgstr "" #: /src/schooltool/cando/browser/skill.py:98 msgid "Title, description or label" msgstr "" #: /src/schooltool/cando/browser/skill.py:125 #: /src/schooltool/cando/browser/skill.py:171 msgid "Skill set" msgstr "" #: /src/schooltool/cando/browser/skill.py:232 msgid "Submit and add" msgstr "" #: /src/schooltool/cando/browser/skill.py:386 #: /src/schooltool/cando/browser/templates/colorcodes_help.pt:13 msgid "Optional" msgstr "" #: /src/schooltool/cando/browser/templates/cando_third_nav.pt:2 msgid "Scroll over a skill ID to see its description here" msgstr "" #: /src/schooltool/cando/browser/templates/colorcodes_help.pt:5 msgid "Skill Color Code" msgstr "" #: /src/schooltool/cando/browser/templates/colorcodes_help.pt:16 msgid "Optional (IEP)" msgstr "" #: /src/schooltool/cando/browser/templates/course_assign_skills_table_filter.pt:12 #: /src/schooltool/cando/browser/templates/nodes_table_filter.pt:12 msgid "Showing ${count} of ${total} items" msgstr "" #: /src/schooltool/cando/browser/templates/course_assign_skillsets_dialog.pt:20 msgid "You must select at least one skill set." msgstr "" #. Default: "Submit" #: /src/schooltool/cando/browser/templates/course_assign_skillsets_dialog.pt:69 #: /src/schooltool/cando/browser/templates/course_remove_skills.pt:59 #: /src/schooltool/cando/browser/templates/edit_course_skills.pt:45 msgid "submit-button" msgstr "" #. Default: "Cancel" #: /src/schooltool/cando/browser/templates/course_assign_skillsets_dialog.pt:73 #: /src/schooltool/cando/browser/templates/course_remove_skills.pt:62 #: /src/schooltool/cando/browser/templates/edit_course_skills.pt:48 msgid "cancel-button" msgstr "" #: /src/schooltool/cando/browser/templates/course_remove_skills.pt:22 msgid "Remove" msgstr "" #: /src/schooltool/cando/browser/templates/course_skills_overview.pt:4 msgid "Assign Course Skills" msgstr "" #: /src/schooltool/cando/browser/templates/course_skills_overview.pt:13 msgid "There are ${count} sets of skills assigned." msgstr "" #: /src/schooltool/cando/browser/templates/course_skills_overview.pt:16 msgid "There are no skills assigned." msgstr "" #: /src/schooltool/cando/browser/templates/course_skillset.pt:4 #: /src/schooltool/cando/browser/templates/document_skillset.pt:4 #: /src/schooltool/cando/browser/templates/skillset.pt:4 #: /src/schooltool/cando/browser/templates/skillsets.pt:34 msgid "Edit this skill set" msgstr "" #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:10 msgid "Course Matching" msgstr "" #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:15 msgid "Course field" msgstr "" #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:21 #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:63 msgid "Select a field" msgstr "" #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:36 msgid "Node layer" msgstr "" #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:42 msgid "Select a layer" msgstr "" #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:57 msgid "Node field" msgstr "" #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:83 msgid "Courses not matched" msgstr "" #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:87 #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:106 #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:108 msgid "Field" msgstr "" #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:89 msgid "Reason" msgstr "" #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:102 msgid "Courses matched" msgstr "" #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:122 msgid "Assign" msgstr "" #: /src/schooltool/cando/browser/templates/document.pt:5 msgid "Edit this Document" msgstr "" #: /src/schooltool/cando/browser/templates/document_skill.pt:4 #: /src/schooltool/cando/browser/templates/skill.pt:4 msgid "Edit this skill" msgstr "" #: /src/schooltool/cando/browser/templates/edit_course_skills.pt:15 #: /src/schooltool/cando/interfaces.py:70 #: /src/schooltool/cando/interfaces.py:99 #: /src/schooltool/cando/interfaces.py:134 msgid "Deprecated" msgstr "" #: /src/schooltool/cando/browser/templates/gradebook_skills_dialog.pt:33 #: /src/schooltool/cando/browser/templates/gradebook_skills_dialog.pt:43 msgid "There are no skills." msgstr "" #: /src/schooltool/cando/browser/templates/iep_details.pt:5 msgid "Edit this plan information" msgstr "" #: /src/schooltool/cando/browser/templates/layer.pt:4 msgid "Edit this Layer" msgstr "" #: /src/schooltool/cando/browser/templates/layer.pt:78 msgid "Parent layers" msgstr "" #: /src/schooltool/cando/browser/templates/layer.pt:104 msgid "Child layers" msgstr "" #: /src/schooltool/cando/browser/templates/layer.pt:107 msgid "Edit children" msgstr "" #: /src/schooltool/cando/browser/templates/node.pt:13 msgid "General Information" msgstr "" #: /src/schooltool/cando/browser/templates/node.pt:17 msgid "Edit this Node" msgstr "" #: /src/schooltool/cando/browser/templates/node.pt:89 #: /src/schooltool/cando/browser/templates/node.pt:92 msgid "Parent nodes" msgstr "" #: /src/schooltool/cando/browser/templates/node.pt:118 #: /src/schooltool/cando/browser/templates/node.pt:121 msgid "Child nodes" msgstr "" #: /src/schooltool/cando/browser/templates/node.pt:122 msgid "Edit child nodes" msgstr "" #: /src/schooltool/cando/browser/templates/node.pt:160 msgid "Edit layers" msgstr "" #: /src/schooltool/cando/browser/templates/node.pt:201 msgid "Edit skill sets" msgstr "" #: /src/schooltool/cando/browser/templates/projects.pt:5 msgid "Reorder or Hide Projects" msgstr "" #: /src/schooltool/cando/browser/templates/projects.pt:9 #: /src/schooltool/cando/browser/templates/skillsets.pt:9 msgid "Order" msgstr "" #: /src/schooltool/cando/browser/templates/projects.pt:11 #: /src/schooltool/cando/browser/templates/skillsets.pt:11 msgid "Visible" msgstr "" #: /src/schooltool/cando/browser/templates/projects.pt:34 msgid "Edit this project" msgstr "" #: /src/schooltool/cando/browser/templates/request_competency_certificate.pt:5 #: /src/schooltool/cando/interfaces.py:99 #: /src/schooltool/cando/interfaces.py:238 msgid "Description" msgstr "" #: /src/schooltool/cando/browser/templates/request_competency_certificate.pt:11 msgid "File Type" msgstr "" #: /src/schooltool/cando/browser/templates/request_competency_certificate.pt:23 msgid "Select a minimum display score for ${scoresystem}" msgstr "" #: /src/schooltool/cando/browser/templates/section_report_details.pt:3 msgid "Details" msgstr "" #: /src/schooltool/cando/browser/templates/section_report_details.pt:12 msgid "Government ID" msgstr "" #: /src/schooltool/cando/browser/templates/section_report_score_colors.pt:33 msgid "Meets target" msgstr "" #: /src/schooltool/cando/browser/templates/skillsets.pt:5 msgid "Reorder or Hide Skill Sets" msgstr "" #: /src/schooltool/cando/browser/xls_views.py:183 msgid "Skill definitions" msgstr "" #: /src/schooltool/cando/browser/xls_views.py:186 #: /src/schooltool/cando/course.py:187 msgid "Course Skills" msgstr "" #: /src/schooltool/cando/browser/xls_views.py:193 msgid "Exporting skills" msgstr "" #: /src/schooltool/cando/browser/xls_views.py:212 msgid "Export complete" msgstr "" #: /src/schooltool/cando/course.py:231 msgid "Section Skills" msgstr "" #: /src/schooltool/cando/gradebook.py:56 msgid "Project1" msgstr "" #: /src/schooltool/cando/interfaces.py:60 msgid "Limit to 7 characters or less." msgstr "" #: /src/schooltool/cando/interfaces.py:68 msgid "External ID" msgstr "" #: /src/schooltool/cando/interfaces.py:70 msgid "Required?" msgstr "" #: /src/schooltool/cando/interfaces.py:71 msgid "Skill is no longer used" msgstr "" #: /src/schooltool/cando/interfaces.py:79 msgid "Scoresystem" msgstr "" #: /src/schooltool/cando/interfaces.py:52 msgid "The skill scoresystem." msgstr "" #: /src/schooltool/cando/interfaces.py:100 msgid "Skill set is no longer used" msgstr "" #: /src/schooltool/cando/interfaces.py:135 msgid "Node is no longer used" msgstr "" #: /src/schooltool/cando/interfaces.py:186 msgid "Project deployed" msgstr "" #: /src/schooltool/cando/interfaces.py:151 msgid "Is this project deployed to course sections" msgstr "" #: /src/schooltool/cando/interfaces.py:200 msgid "Section intID" msgstr "" #: /src/schooltool/cando/interfaces.py:208 msgid "Skill set ID" msgstr "" #: /src/schooltool/cando/interfaces.py:209 msgid "Skill ID" msgstr "" #: /src/schooltool/cando/interfaces.py:235 msgid "Active" msgstr "" #: /src/schooltool/cando/project.py:137 msgid "Course Projects" msgstr "" #: /src/schooltool/cando/project.py:207 msgid "${project} total points" msgstr "" #: /src/schooltool/cando/project.py:229 msgid "${project} percent passed" msgstr "" #: /src/schooltool/cando/project.py:273 msgid "${course} total points" msgstr "" #: /src/schooltool/cando/project.py:297 msgid "${course} percent passed" msgstr "" schooltool.cando-2.6.2/src/schooltool/cando/locales/schooltool.cando.pot0000644000175000017500000010305612270520445027605 0ustar menesismenesis00000000000000# SchoolTool - common information systems platform for school administration # Copyright (c) 2007 Shuttleworth Foundation # # 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 2 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 . msgid "" msgstr "" "Project-Id-Version: schooltool.cando\n" "POT-Creation-Date: 2013-10-10 16:06+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: Schooltool Development Team \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: i18nextract.py\n" #: /src/schooltool/cando/browser/breadcrumbs.zcml:9 #: /src/schooltool/cando/browser/breadcrumbs.zcml:67 #: /src/schooltool/cando/browser/breadcrumbs.zcml:72 #: /src/schooltool/cando/browser/configure.zcml:135 #: /src/schooltool/cando/browser/configure.zcml:336 #: /src/schooltool/cando/browser/configure.zcml:779 #: /src/schooltool/cando/browser/course.py:162 #: /src/schooltool/cando/browser/document.py:815 #: /src/schooltool/cando/browser/document.zcml:26 #: /src/schooltool/cando/browser/gradebook.py:275 #: /src/schooltool/cando/browser/skill.py:76 #: /src/schooltool/cando/browser/templates/course_assign_skillsets_dialog.pt:30 #: /src/schooltool/cando/browser/templates/course_remove_skills.pt:20 #: /src/schooltool/cando/browser/templates/course_skills_overview.pt:4 #: /src/schooltool/cando/browser/templates/skillset.pt:77 msgid "Skills" msgstr "" #: /src/schooltool/cando/browser/breadcrumbs.zcml:14 #: /src/schooltool/cando/browser/configure.zcml:40 #: /src/schooltool/cando/browser/course.py:292 #: /src/schooltool/cando/browser/document.py:122 #: /src/schooltool/cando/browser/gradebook.zcml:115 msgid "Skill Sets" msgstr "" #: /src/schooltool/cando/browser/breadcrumbs.zcml:21 #: /src/schooltool/cando/browser/course.py:287 #: /src/schooltool/cando/browser/document.py:121 #: /src/schooltool/cando/browser/model.py:439 #: /src/schooltool/cando/browser/templates/course_assign_skills_table_filter.pt:34 #: /src/schooltool/cando/browser/templates/node.pt:155 #: /src/schooltool/cando/browser/templates/nodes_table_filter.pt:34 msgid "Layers" msgstr "" #: /src/schooltool/cando/browser/breadcrumbs.zcml:28 msgid "Nodes" msgstr "" #: /src/schooltool/cando/browser/configure.zcml:107 #: /src/schooltool/cando/browser/configure.zcml:162 #: /src/schooltool/cando/browser/configure.zcml:515 #: /src/schooltool/cando/browser/configure.zcml:642 #: /src/schooltool/cando/browser/course.py:223 #: /src/schooltool/cando/browser/course.py:225 #: /src/schooltool/cando/browser/document.zcml:61 #: /src/schooltool/cando/browser/document.zcml:185 #: /src/schooltool/cando/browser/document.zcml:220 #: /src/schooltool/cando/browser/document.zcml:303 #: /src/schooltool/cando/browser/gradebook.zcml:63 #: /src/schooltool/cando/browser/templates/course_assign_skillsets_dialog.pt:32 msgid "Add" msgstr "" #: /src/schooltool/cando/browser/configure.zcml:117 #: /src/schooltool/cando/browser/configure.zcml:260 #: /src/schooltool/cando/browser/configure.zcml:795 msgid "Actions" msgstr "" #: /src/schooltool/cando/browser/configure.zcml:127 msgid "Skill Set" msgstr "" #: /src/schooltool/cando/browser/configure.zcml:135 msgid "New Skill Set" msgstr "" #: /src/schooltool/cando/browser/configure.zcml:145 #: /src/schooltool/cando/browser/configure.zcml:199 #: /src/schooltool/cando/browser/configure.zcml:552 #: /src/schooltool/cando/browser/configure.zcml:679 #: /src/schooltool/cando/browser/document.zcml:98 #: /src/schooltool/cando/browser/document.zcml:194 #: /src/schooltool/cando/browser/document.zcml:253 #: /src/schooltool/cando/browser/document.zcml:312 #: /src/schooltool/cando/browser/document.zcml:345 #: /src/schooltool/cando/browser/gradebook.zcml:322 #: /src/schooltool/cando/browser/templates/document.pt:9 #: /src/schooltool/cando/browser/templates/layer.pt:109 #: /src/schooltool/cando/browser/templates/node.pt:21 #: /src/schooltool/cando/browser/templates/node.pt:126 #: /src/schooltool/cando/browser/templates/node.pt:164 #: /src/schooltool/cando/browser/templates/node.pt:201 msgid "Edit" msgstr "" #: /src/schooltool/cando/browser/configure.zcml:171 #: /src/schooltool/cando/browser/document.py:166 #: /src/schooltool/cando/browser/document.py:388 #: /src/schooltool/cando/browser/document.py:397 #: /src/schooltool/cando/browser/gradebook.py:182 #: /src/schooltool/cando/browser/gradebook.py:197 #: /src/schooltool/cando/browser/gradebook.py:298 #: /src/schooltool/cando/browser/gradebook.py:924 #: /src/schooltool/cando/browser/model.py:137 #: /src/schooltool/cando/browser/skill.py:221 #: /src/schooltool/cando/browser/skill.py:279 #: /src/schooltool/cando/browser/skill.py:307 #: /src/schooltool/cando/browser/templates/edit_course_skills.pt:7 #: /src/schooltool/cando/browser/templates/student_competency_record.pt:9 msgid "Skill" msgstr "" #: /src/schooltool/cando/browser/configure.zcml:181 #: /src/schooltool/cando/browser/gradebook.py:838 #: /src/schooltool/cando/browser/gradebook.zcml:187 msgid "New Skill" msgstr "" #: /src/schooltool/cando/browser/configure.zcml:190 #: /src/schooltool/cando/browser/configure.zcml:461 msgid "View Skill" msgstr "" #: /src/schooltool/cando/browser/configure.zcml:228 #: /src/schooltool/cando/browser/configure.zcml:395 msgid "Assigned Skills" msgstr "" #: /src/schooltool/cando/browser/configure.zcml:270 #: /src/schooltool/cando/browser/configure.zcml:345 msgid "Assign Skills" msgstr "" #: /src/schooltool/cando/browser/configure.zcml:278 #: /src/schooltool/cando/browser/configure.zcml:353 msgid "Remove Skills" msgstr "" #: /src/schooltool/cando/browser/configure.zcml:298 #: /src/schooltool/cando/browser/configure.zcml:315 msgid "Set Required / Deprecated" msgstr "" #: /src/schooltool/cando/browser/configure.zcml:347 msgid "Assign Skill Set" msgstr "" #: /src/schooltool/cando/browser/configure.zcml:404 msgid "Edit Skills" msgstr "" #: /src/schooltool/cando/browser/configure.zcml:488 #: /src/schooltool/cando/browser/configure.zcml:533 msgid "Layers Container" msgstr "" #: /src/schooltool/cando/browser/configure.zcml:524 #: /src/schooltool/cando/browser/model.py:174 msgid "Layer" msgstr "" #: /src/schooltool/cando/browser/configure.zcml:533 msgid "Add Layer" msgstr "" #: /src/schooltool/cando/browser/configure.zcml:543 msgid "View Layer" msgstr "" #: /src/schooltool/cando/browser/configure.zcml:561 #: /src/schooltool/cando/browser/configure.zcml:688 msgid "Edit Children" msgstr "" #: /src/schooltool/cando/browser/configure.zcml:605 #: /src/schooltool/cando/browser/configure.zcml:660 msgid "Nodes Container" msgstr "" #: /src/schooltool/cando/browser/configure.zcml:605 #: /src/schooltool/cando/browser/document.py:123 #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:77 #: /src/schooltool/cando/browser/templates/nodes_table_filter.pt:53 msgid "Search" msgstr "" #: /src/schooltool/cando/browser/configure.zcml:625 msgid "Deprecate" msgstr "" #: /src/schooltool/cando/browser/configure.zcml:625 msgid "Documents and Skills" msgstr "" #: /src/schooltool/cando/browser/configure.zcml:766 #: /src/schooltool/cando/browser/model.py:398 #: /src/schooltool/cando/browser/model.py:427 #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:109 msgid "Node" msgstr "" #: /src/schooltool/cando/browser/configure.zcml:660 msgid "Add Node" msgstr "" #: /src/schooltool/cando/browser/configure.zcml:670 msgid "View Node" msgstr "" #: /src/schooltool/cando/browser/configure.zcml:714 msgid "Edit Layers" msgstr "" #: /src/schooltool/cando/browser/configure.zcml:785 msgid "Edit Skill Sets" msgstr "" #: /src/schooltool/cando/browser/configure.zcml:825 #: /src/schooltool/cando/browser/configure.zcml:833 msgid "Import Skill Data" msgstr "" #: /src/schooltool/cando/browser/configure.zcml:919 msgid "Deprecate Skills" msgstr "" #: /src/schooltool/cando/browser/configure.zcml:974 msgid "Batch Assign Skills" msgstr "" #: /src/schooltool/cando/browser/configure.zcml:814 msgid "Assign Courses Skills" msgstr "" #: /src/schooltool/cando/browser/course.py:156 #: /src/schooltool/cando/browser/course.py:277 #: /src/schooltool/cando/browser/course.py:571 #: /src/schooltool/cando/browser/document.py:869 #: /src/schooltool/cando/browser/model.py:432 #: /src/schooltool/cando/browser/templates/course_assign_skillsets_dialog.pt:29 #: /src/schooltool/cando/browser/templates/course_remove_skills.pt:19 #: /src/schooltool/cando/browser/templates/projects.pt:10 #: /src/schooltool/cando/browser/templates/skillsets.pt:10 #: /src/schooltool/cando/interfaces.py:72 #: /src/schooltool/cando/interfaces.py:89 msgid "Title" msgstr "" #: /src/schooltool/cando/browser/course.py:260 msgid "Select Skill Sets from ${node} (${node_id})" msgstr "" #: /src/schooltool/cando/browser/course.py:282 msgid "ID" msgstr "" #: /src/schooltool/cando/browser/course.py:314 #: /src/schooltool/cando/browser/model.py:454 msgid "ID, title, label or description" msgstr "" #: /src/schooltool/cando/browser/course.py:576 #: /src/schooltool/cando/browser/course.py:635 #: /src/schooltool/cando/browser/document.py:880 #: /src/schooltool/cando/browser/model.py:427 #: /src/schooltool/cando/browser/skill.py:80 #: /src/schooltool/cando/browser/skill.py:209 #: /src/schooltool/cando/interfaces.py:63 #: /src/schooltool/cando/interfaces.py:96 msgid "Label" msgstr "" #: /src/schooltool/cando/browser/course.py:581 #: /src/schooltool/cando/browser/document.py:875 #: /src/schooltool/cando/browser/templates/colorcodes_help.pt:10 #: /src/schooltool/cando/browser/templates/edit_course_skills.pt:9 #: /src/schooltool/cando/browser/templates/student_competency_record.pt:8 #: /src/schooltool/cando/interfaces.py:39 msgid "Required" msgstr "" #: /src/schooltool/cando/browser/course.py:587 msgid "Hidden" msgstr "" #: /src/schooltool/cando/browser/course.py:790 msgid "Course has skills assigned already" msgstr "" #: /src/schooltool/cando/browser/course.py:810 msgid "Couldn't find a matching node" msgstr "" #: /src/schooltool/cando/browser/course.py:816 msgid "Course attribute is empty" msgstr "" #: /src/schooltool/cando/browser/document.py:120 msgid "Documents" msgstr "" #: /src/schooltool/cando/browser/document.py:148 msgid "Document Information" msgstr "" #: /src/schooltool/cando/browser/document.py:198 #: /src/schooltool/cando/browser/document.py:524 #: /src/schooltool/cando/browser/document.py:708 #: /src/schooltool/cando/browser/document.py:769 #: /src/schooltool/cando/browser/gradebook.py:352 #: /src/schooltool/cando/browser/gradebook.py:471 #: /src/schooltool/cando/browser/iep.py:131 #: /src/schooltool/cando/browser/model.py:103 #: /src/schooltool/cando/browser/model.py:177 #: /src/schooltool/cando/browser/model.py:321 #: /src/schooltool/cando/browser/model.py:396 #: /src/schooltool/cando/browser/skill.py:179 #: /src/schooltool/cando/browser/skill.py:235 #: /src/schooltool/cando/browser/skill.py:327 #: /src/schooltool/cando/browser/templates/course_skills_edit_table_buttons.pt:5 msgid "Submit" msgstr "" #: /src/schooltool/cando/browser/document.py:186 #: /src/schooltool/cando/browser/document.py:465 #: /src/schooltool/cando/browser/document.py:645 #: /src/schooltool/cando/browser/document.py:709 #: /src/schooltool/cando/browser/gradebook.py:321 #: /src/schooltool/cando/browser/gradebook.py:444 #: /src/schooltool/cando/browser/model.py:106 #: /src/schooltool/cando/browser/model.py:183 #: /src/schooltool/cando/browser/model.py:324 #: /src/schooltool/cando/browser/model.py:403 #: /src/schooltool/cando/browser/skill.py:180 #: /src/schooltool/cando/browser/skill.py:238 #: /src/schooltool/cando/browser/skill.py:316 #: /src/schooltool/cando/browser/templates/course_skills_edit_table_buttons.pt:8 #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:79 #: /src/schooltool/cando/browser/templates/grade_student.pt:39 msgid "Cancel" msgstr "" #: /src/schooltool/cando/browser/document.py:429 #: /src/schooltool/cando/browser/document.py:571 #: /src/schooltool/cando/browser/document.py:816 msgid "${layer} list" msgstr "" #: /src/schooltool/cando/browser/document.py:450 #: /src/schooltool/cando/browser/document.zcml:70 msgid "Document" msgstr "" #: /src/schooltool/cando/browser/document.py:477 msgid "Current document hierarchy layers" msgstr "" #: /src/schooltool/cando/browser/document.py:478 msgid "Available layers" msgstr "" #: /src/schooltool/cando/browser/document.py:566 #: /src/schooltool/cando/browser/document.py:808 #: /src/schooltool/cando/browser/document.py:961 msgid "View ${layer}" msgstr "" #: /src/schooltool/cando/browser/document.py:624 #: /src/schooltool/cando/browser/document.py:744 #: /src/schooltool/cando/browser/document.py:921 msgid "Add ${layer}" msgstr "" #: /src/schooltool/cando/browser/document.py:629 #: /src/schooltool/cando/browser/document.py:916 msgid "${layer} Information" msgstr "" #: /src/schooltool/cando/browser/document.py:673 msgid "Skills Document" msgstr "" #: /src/schooltool/cando/browser/document.py:695 msgid "Change information" msgstr "" #: /src/schooltool/cando/browser/document.py:928 #: /src/schooltool/cando/browser/gradebook.py:1594 msgid "No" msgstr "" #: /src/schooltool/cando/browser/document.py:928 #: /src/schooltool/cando/browser/gradebook.py:1594 msgid "Yes" msgstr "" #: /src/schooltool/cando/browser/document.zcml:35 #: /src/schooltool/cando/browser/document.zcml:79 msgid "Skills Documents" msgstr "" #: /src/schooltool/cando/browser/document.zcml:79 msgid "Add Document" msgstr "" #: /src/schooltool/cando/browser/document.zcml:89 msgid "View Skills Document" msgstr "" #: /src/schooltool/cando/browser/document.zcml:107 msgid "Edit Layer Hierarchy" msgstr "" #: /src/schooltool/cando/browser/document.zcml:133 msgid "View Hierarchy Layer" msgstr "" #: /src/schooltool/cando/browser/document.zcml:142 msgid "Edit Hierarchy Layer" msgstr "" #: /src/schooltool/cando/browser/document.zcml:151 msgid "Edit Hierarchy Layer Parents" msgstr "" #: /src/schooltool/cando/browser/document.zcml:211 msgid "Layer Hierarchy" msgstr "" #: /src/schooltool/cando/browser/gradebook.py:189 msgid "No Visible Projects" msgstr "" #: /src/schooltool/cando/browser/gradebook.py:191 #: /src/schooltool/cando/browser/gradebook.py:206 msgid "Enter Skills" msgstr "" #: /src/schooltool/cando/browser/gradebook.py:204 msgid "No Visible Skill Sets" msgstr "" #: /src/schooltool/cando/browser/gradebook.py:281 #: /src/schooltool/cando/browser/gradebook.zcml:98 #: /src/schooltool/cando/browser/gradebook.zcml:106 #: /src/schooltool/cando/project.py:163 msgid "Projects" msgstr "" #: /src/schooltool/cando/browser/gradebook.py:315 msgid "Project Details" msgstr "" #: /src/schooltool/cando/browser/gradebook.py:358 msgid "Sort by" msgstr "" #: /src/schooltool/cando/browser/gradebook.py:423 msgid "Skill Details" msgstr "" #: /src/schooltool/cando/browser/gradebook.py:518 msgid "${section} Skills" msgstr "" #: /src/schooltool/cando/browser/gradebook.py:520 msgid "${section} Project Skills" msgstr "" #: /src/schooltool/cando/browser/gradebook.py:529 msgid "Score System Help" msgstr "" #: /src/schooltool/cando/browser/gradebook.py:537 msgid "Color Codes Help" msgstr "" #: /src/schooltool/cando/browser/gradebook.py:953 msgid "No layer assigned" msgstr "" #: /src/schooltool/cando/browser/gradebook.py:1236 msgid "Changes saved" msgstr "" #: /src/schooltool/cando/browser/gradebook.py:1392 #: /src/schooltool/cando/browser/gradebook.zcml:140 msgid "Search Skills" msgstr "" #: /src/schooltool/cando/browser/gradebook.py:1450 msgid "Save" msgstr "" #: /src/schooltool/cando/browser/gradebook.py:1466 #: /src/schooltool/cando/browser/templates/scoresystem_help.pt:5 msgid "Score" msgstr "" #: /src/schooltool/cando/browser/gradebook.py:1561 #: /src/schooltool/cando/browser/gradebook.zcml:520 msgid "CanDo Gradebook" msgstr "" #: /src/schooltool/cando/browser/gradebook.py:1677 msgid "Date" msgstr "" #: /src/schooltool/cando/browser/gradebook.py:1606 #: /src/schooltool/cando/browser/templates/scoresystem_help.pt:6 msgid "Rating" msgstr "" #: /src/schooltool/cando/browser/gradebook.py:1736 #: /src/schooltool/cando/browser/gradebook.py:1951 #: /src/schooltool/cando/browser/gradebook.zcml:770 msgid "Student Skill Report" msgstr "" #: /src/schooltool/cando/browser/gradebook.py:1759 msgid "Teacher(s): ${teachers}" msgstr "" #: /src/schooltool/cando/browser/gradebook.py:1755 #: /src/schooltool/cando/browser/gradebook.py:1870 msgid "Course: ${courses}" msgstr "" #: /src/schooltool/cando/browser/gradebook.py:1847 #: /src/schooltool/cando/browser/gradebook.zcml:782 msgid "Certificate of Competency" msgstr "" #: /src/schooltool/cando/browser/gradebook.py:2288 msgid "skill gradebooks archive" msgstr "" #: /src/schooltool/cando/browser/gradebook.zcml:10 #: /src/schooltool/cando/browser/gradebook.zcml:26 #: /src/schooltool/cando/browser/gradebook.zcml:128 #: /src/schooltool/cando/browser/gradebook.zcml:223 #: /src/schooltool/cando/browser/gradebook.zcml:321 #: /src/schooltool/cando/browser/gradebook.zcml:431 msgid "CanDo" msgstr "" #: /src/schooltool/cando/browser/gradebook.zcml:45 msgid "View" msgstr "" #: /src/schooltool/cando/browser/gradebook.zcml:80 msgid "Project" msgstr "" #: /src/schooltool/cando/browser/gradebook.zcml:88 msgid "Settings" msgstr "" #: /src/schooltool/cando/browser/gradebook.zcml:126 msgid "New Project" msgstr "" #: /src/schooltool/cando/browser/gradebook.zcml:310 msgid "Edit Skill" msgstr "" #: /src/schooltool/cando/browser/gradebook.zcml:373 #: /src/schooltool/cando/browser/gradebook.zcml:637 #: /src/schooltool/cando/browser/gradebook.zcml:660 msgid "Help" msgstr "" #: /src/schooltool/cando/browser/gradebook.zcml:383 msgid "Score System" msgstr "" #: /src/schooltool/cando/browser/gradebook.zcml:391 msgid "Color Codes" msgstr "" #: /src/schooltool/cando/browser/gradebook.zcml:492 msgid "Skills Pop-up" msgstr "" #: /src/schooltool/cando/browser/gradebook.zcml:546 msgid "My Skills Grades" msgstr "" #: /src/schooltool/cando/browser/gradebook.zcml:579 msgid "My Projects Grades" msgstr "" #: /src/schooltool/cando/browser/gradebook.zcml:596 #: /src/schooltool/cando/browser/gradebook.zcml:827 #: /src/schooltool/cando/browser/gradebook.zcml:839 #: /src/schooltool/cando/browser/report.py:878 #: /src/schooltool/cando/browser/report.zcml:47 #: /src/schooltool/cando/browser/report.zcml:58 msgid "Section" msgstr "" #: /src/schooltool/cando/browser/gradebook.zcml:557 msgid "Term" msgstr "" #: /src/schooltool/cando/browser/gradebook.zcml:568 msgid "Year" msgstr "" #: /src/schooltool/cando/browser/gradebook.zcml:760 msgid "Reports" msgstr "" #: /src/schooltool/cando/browser/gradebook.zcml:770 msgid "Summary of a student's scores for all the skills assigned to a section." msgstr "" #: /src/schooltool/cando/browser/gradebook.zcml:770 #: /src/schooltool/cando/browser/gradebook.zcml:782 msgid "Student" msgstr "" #: /src/schooltool/cando/browser/gradebook.zcml:782 msgid "Summary of a student scores in a section exceeding a selected minimum score. Formatted for presentation to an potential employer or other person outside of the school." msgstr "" #: /src/schooltool/cando/browser/gradebook.zcml:794 #: /src/schooltool/cando/browser/gradebook.zcml:806 msgid "Aggregated Student Skill Reports" msgstr "" #: /src/schooltool/cando/browser/gradebook.zcml:794 msgid "Summary of all students' scores for all the skills assigned to a section." msgstr "" #: /src/schooltool/cando/browser/iep.py:122 msgid "IEP Details" msgstr "" #: /src/schooltool/cando/browser/iep.py:176 msgid "IEP Skills for ${section}" msgstr "" #: /src/schooltool/cando/browser/iep.py:322 msgid "Edit IEP Skills for ${section}" msgstr "" #: /src/schooltool/cando/browser/iep.py:354 msgid "Optional IEP" msgstr "" #: /src/schooltool/cando/browser/iep.py:424 msgid "IEP Information" msgstr "" #: /src/schooltool/cando/browser/iep.zcml:8 msgid "IEP" msgstr "" #: /src/schooltool/cando/browser/iep.zcml:17 #: /src/schooltool/cando/browser/iep.zcml:52 msgid "Individualized Educational Plan" msgstr "" #: /src/schooltool/cando/browser/importer.py:44 msgid "has an invalid document id" msgstr "" #: /src/schooltool/cando/browser/importer.py:45 msgid "has an invalid parent id" msgstr "" #: /src/schooltool/cando/browser/importer.py:46 msgid "has an invalid layer id" msgstr "" #: /src/schooltool/cando/browser/importer.py:47 msgid "has an invalid skillset id" msgstr "" #: /src/schooltool/cando/browser/importer.py:48 msgid "is missing a skillset id" msgstr "" #: /src/schooltool/cando/browser/importer.py:49 msgid "has an invalid equivalent skill id" msgstr "" #: /src/schooltool/cando/browser/importer.py:50 msgid "node label has more than seven characters" msgstr "" #: /src/schooltool/cando/browser/importer.py:51 msgid "has an invalid scoresystem" msgstr "" #: /src/schooltool/cando/browser/importer.py:52 msgid "has an invalid node id" msgstr "" #: /src/schooltool/cando/browser/model.py:94 msgid "Layer Information" msgstr "" #: /src/schooltool/cando/browser/model.py:209 msgid "Parents" msgstr "" #: /src/schooltool/cando/browser/model.py:214 msgid "Children" msgstr "" #: /src/schooltool/cando/browser/model.py:257 msgid "Current child layers" msgstr "" #: /src/schooltool/cando/browser/model.py:258 msgid "Available child layers" msgstr "" #: /src/schooltool/cando/browser/model.py:307 msgid "Node Information" msgstr "" #: /src/schooltool/cando/browser/model.py:546 msgid "Current child nodes" msgstr "" #: /src/schooltool/cando/browser/model.py:547 msgid "Available child nodes" msgstr "" #: /src/schooltool/cando/browser/model.py:584 msgid "Current node layers" msgstr "" #: /src/schooltool/cando/browser/model.py:585 msgid "Available node layers" msgstr "" #: /src/schooltool/cando/browser/model.py:641 msgid "Current node skill sets" msgstr "" #: /src/schooltool/cando/browser/model.py:642 msgid "Available node skill sets" msgstr "" #: /src/schooltool/cando/browser/report.py:199 msgid "All" msgstr "" #: /src/schooltool/cando/browser/report.py:199 msgid "Evaluated" msgstr "" #: /src/schooltool/cando/browser/report.py:380 msgid "% of Skills Below and Above Passing" msgstr "" #: /src/schooltool/cando/browser/report.py:406 msgid "Students (${count})" msgstr "" #: /src/schooltool/cando/browser/report.py:480 msgid "Student ID #" msgstr "" #: /src/schooltool/cando/browser/report.py:640 #: /src/schooltool/cando/browser/templates/section_report_score_colors.pt:19 msgid "Score Colors" msgstr "" #: /src/schooltool/cando/browser/report.py:814 msgid "Totals" msgstr "" #: /src/schooltool/cando/browser/report.py:866 #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:88 #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:107 #: /src/schooltool/cando/browser/templates/section_report_details.pt:8 msgid "Course" msgstr "" #: /src/schooltool/cando/browser/report.py:874 #: /src/schooltool/cando/browser/templates/section_report_details.pt:16 msgid "Teachers" msgstr "" #: /src/schooltool/cando/browser/report.zcml:21 msgid "Export global skills data for the school." msgstr "" #: /src/schooltool/cando/browser/report.zcml:10 msgid "School" msgstr "" #: /src/schooltool/cando/browser/report.zcml:10 msgid "Skills Export" msgstr "" #: /src/schooltool/cando/browser/report.zcml:47 #: /src/schooltool/cando/browser/report.zcml:58 msgid "An overview of each student's achievement of skills within the section." msgstr "" #: /src/schooltool/cando/browser/report.zcml:47 #: /src/schooltool/cando/browser/report.zcml:58 #: /src/schooltool/cando/browser/report.zcml:88 #: /src/schooltool/cando/browser/report.zcml:244 msgid "Per Student Skills" msgstr "" #: /src/schooltool/cando/browser/report.zcml:70 msgid "An overview of each section's aggregate achievement of skills." msgstr "" #: /src/schooltool/cando/browser/report.zcml:70 msgid "Skills Completion" msgstr "" #: /src/schooltool/cando/browser/report.zcml:191 msgid "Passing Score" msgstr "" #: /src/schooltool/cando/browser/report.zcml:208 msgid "Type" msgstr "" #: /src/schooltool/cando/browser/report.zcml:226 #: /src/schooltool/cando/browser/templates/section_report_score_colors.pt:28 msgid "% Passing Target" msgstr "" #: /src/schooltool/cando/browser/report.zcml:252 msgid "Skills Completion Report" msgstr "" #: /src/schooltool/cando/browser/report.zcml:298 msgid "Location" msgstr "" #: /src/schooltool/cando/browser/report.zcml:360 msgid "Skill Gradebooks" msgstr "" #: /src/schooltool/cando/browser/report.zcml:369 msgid "Archive all student skill gradebooks." msgstr "" #: /src/schooltool/cando/browser/report.zcml:369 msgid "Skill Gradebook Archive" msgstr "" #: /src/schooltool/cando/browser/skill.py:98 msgid "Title, description or label" msgstr "" #: /src/schooltool/cando/browser/skill.py:125 #: /src/schooltool/cando/browser/skill.py:171 msgid "Skill set" msgstr "" #: /src/schooltool/cando/browser/skill.py:232 msgid "Submit and add" msgstr "" #: /src/schooltool/cando/browser/skill.py:386 #: /src/schooltool/cando/browser/templates/colorcodes_help.pt:13 msgid "Optional" msgstr "" #: /src/schooltool/cando/browser/templates/cando_third_nav.pt:2 msgid "Scroll over a skill ID to see its description here" msgstr "" #: /src/schooltool/cando/browser/templates/colorcodes_help.pt:5 msgid "Skill Color Code" msgstr "" #: /src/schooltool/cando/browser/templates/colorcodes_help.pt:16 msgid "Optional (IEP)" msgstr "" #: /src/schooltool/cando/browser/templates/course_assign_skills_table_filter.pt:12 #: /src/schooltool/cando/browser/templates/nodes_table_filter.pt:12 msgid "Showing ${count} of ${total} items" msgstr "" #: /src/schooltool/cando/browser/templates/course_assign_skillsets_dialog.pt:20 msgid "You must select at least one skill set." msgstr "" #: /src/schooltool/cando/browser/templates/course_assign_skillsets_dialog.pt:69 #: /src/schooltool/cando/browser/templates/course_remove_skills.pt:59 #: /src/schooltool/cando/browser/templates/edit_course_skills.pt:45 #. Default: "Submit" msgid "submit-button" msgstr "" #: /src/schooltool/cando/browser/templates/course_assign_skillsets_dialog.pt:73 #: /src/schooltool/cando/browser/templates/course_remove_skills.pt:62 #: /src/schooltool/cando/browser/templates/edit_course_skills.pt:48 #. Default: "Cancel" msgid "cancel-button" msgstr "" #: /src/schooltool/cando/browser/templates/course_remove_skills.pt:22 msgid "Remove" msgstr "" #: /src/schooltool/cando/browser/templates/course_skills_overview.pt:4 msgid "Assign Course Skills" msgstr "" #: /src/schooltool/cando/browser/templates/course_skills_overview.pt:13 msgid "There are ${count} sets of skills assigned." msgstr "" #: /src/schooltool/cando/browser/templates/course_skills_overview.pt:16 msgid "There are no skills assigned." msgstr "" #: /src/schooltool/cando/browser/templates/course_skillset.pt:4 #: /src/schooltool/cando/browser/templates/document_skillset.pt:4 #: /src/schooltool/cando/browser/templates/skillset.pt:4 #: /src/schooltool/cando/browser/templates/skillsets.pt:34 msgid "Edit this skill set" msgstr "" #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:10 msgid "Course Matching" msgstr "" #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:15 msgid "Course field" msgstr "" #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:21 #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:63 msgid "Select a field" msgstr "" #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:36 msgid "Node layer" msgstr "" #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:42 msgid "Select a layer" msgstr "" #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:57 msgid "Node field" msgstr "" #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:83 msgid "Courses not matched" msgstr "" #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:87 #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:106 #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:108 msgid "Field" msgstr "" #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:89 msgid "Reason" msgstr "" #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:102 msgid "Courses matched" msgstr "" #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:122 msgid "Assign" msgstr "" #: /src/schooltool/cando/browser/templates/document.pt:5 msgid "Edit this Document" msgstr "" #: /src/schooltool/cando/browser/templates/document_skill.pt:4 #: /src/schooltool/cando/browser/templates/skill.pt:4 msgid "Edit this skill" msgstr "" #: /src/schooltool/cando/browser/templates/edit_course_skills.pt:15 #: /src/schooltool/cando/interfaces.py:70 #: /src/schooltool/cando/interfaces.py:99 #: /src/schooltool/cando/interfaces.py:134 msgid "Deprecated" msgstr "" #: /src/schooltool/cando/browser/templates/gradebook_skills_dialog.pt:33 #: /src/schooltool/cando/browser/templates/gradebook_skills_dialog.pt:43 msgid "There are no skills." msgstr "" #: /src/schooltool/cando/browser/templates/iep_details.pt:5 msgid "Edit this plan information" msgstr "" #: /src/schooltool/cando/browser/templates/layer.pt:4 msgid "Edit this Layer" msgstr "" #: /src/schooltool/cando/browser/templates/layer.pt:78 msgid "Parent layers" msgstr "" #: /src/schooltool/cando/browser/templates/layer.pt:104 msgid "Child layers" msgstr "" #: /src/schooltool/cando/browser/templates/layer.pt:107 msgid "Edit children" msgstr "" #: /src/schooltool/cando/browser/templates/node.pt:13 msgid "General Information" msgstr "" #: /src/schooltool/cando/browser/templates/node.pt:17 msgid "Edit this Node" msgstr "" #: /src/schooltool/cando/browser/templates/node.pt:89 #: /src/schooltool/cando/browser/templates/node.pt:92 msgid "Parent nodes" msgstr "" #: /src/schooltool/cando/browser/templates/node.pt:118 #: /src/schooltool/cando/browser/templates/node.pt:121 msgid "Child nodes" msgstr "" #: /src/schooltool/cando/browser/templates/node.pt:122 msgid "Edit child nodes" msgstr "" #: /src/schooltool/cando/browser/templates/node.pt:160 msgid "Edit layers" msgstr "" #: /src/schooltool/cando/browser/templates/node.pt:201 msgid "Edit skill sets" msgstr "" #: /src/schooltool/cando/browser/templates/projects.pt:5 msgid "Reorder or Hide Projects" msgstr "" #: /src/schooltool/cando/browser/templates/projects.pt:9 #: /src/schooltool/cando/browser/templates/skillsets.pt:9 msgid "Order" msgstr "" #: /src/schooltool/cando/browser/templates/projects.pt:11 #: /src/schooltool/cando/browser/templates/skillsets.pt:11 msgid "Visible" msgstr "" #: /src/schooltool/cando/browser/templates/projects.pt:34 msgid "Edit this project" msgstr "" #: /src/schooltool/cando/browser/templates/request_competency_certificate.pt:5 #: /src/schooltool/cando/interfaces.py:99 #: /src/schooltool/cando/interfaces.py:238 msgid "Description" msgstr "" #: /src/schooltool/cando/browser/templates/request_competency_certificate.pt:11 msgid "File Type" msgstr "" #: /src/schooltool/cando/browser/templates/request_competency_certificate.pt:23 msgid "Select a minimum display score for ${scoresystem}" msgstr "" #: /src/schooltool/cando/browser/templates/section_report_details.pt:3 msgid "Details" msgstr "" #: /src/schooltool/cando/browser/templates/section_report_details.pt:12 msgid "Government ID" msgstr "" #: /src/schooltool/cando/browser/templates/section_report_score_colors.pt:33 msgid "Meets target" msgstr "" #: /src/schooltool/cando/browser/templates/skillsets.pt:5 msgid "Reorder or Hide Skill Sets" msgstr "" #: /src/schooltool/cando/browser/xls_views.py:183 msgid "Skill definitions" msgstr "" #: /src/schooltool/cando/browser/xls_views.py:186 #: /src/schooltool/cando/course.py:187 msgid "Course Skills" msgstr "" #: /src/schooltool/cando/browser/xls_views.py:193 msgid "Exporting skills" msgstr "" #: /src/schooltool/cando/browser/xls_views.py:212 msgid "Export complete" msgstr "" #: /src/schooltool/cando/course.py:231 msgid "Section Skills" msgstr "" #: /src/schooltool/cando/gradebook.py:56 msgid "Project1" msgstr "" #: /src/schooltool/cando/interfaces.py:60 msgid "Limit to 7 characters or less." msgstr "" #: /src/schooltool/cando/interfaces.py:68 msgid "External ID" msgstr "" #: /src/schooltool/cando/interfaces.py:70 msgid "Required?" msgstr "" #: /src/schooltool/cando/interfaces.py:71 msgid "Skill is no longer used" msgstr "" #: /src/schooltool/cando/interfaces.py:79 msgid "Scoresystem" msgstr "" #: /src/schooltool/cando/interfaces.py:52 msgid "The skill scoresystem." msgstr "" #: /src/schooltool/cando/interfaces.py:100 msgid "Skill set is no longer used" msgstr "" #: /src/schooltool/cando/interfaces.py:135 msgid "Node is no longer used" msgstr "" #: /src/schooltool/cando/interfaces.py:186 msgid "Project deployed" msgstr "" #: /src/schooltool/cando/interfaces.py:151 msgid "Is this project deployed to course sections" msgstr "" #: /src/schooltool/cando/interfaces.py:200 msgid "Section intID" msgstr "" #: /src/schooltool/cando/interfaces.py:208 msgid "Skill set ID" msgstr "" #: /src/schooltool/cando/interfaces.py:209 msgid "Skill ID" msgstr "" #: /src/schooltool/cando/interfaces.py:235 msgid "Active" msgstr "" #: /src/schooltool/cando/project.py:137 msgid "Course Projects" msgstr "" #: /src/schooltool/cando/project.py:207 msgid "${project} total points" msgstr "" #: /src/schooltool/cando/project.py:229 msgid "${project} percent passed" msgstr "" #: /src/schooltool/cando/project.py:273 msgid "${course} total points" msgstr "" #: /src/schooltool/cando/project.py:297 msgid "${course} percent passed" msgstr "" schooltool.cando-2.6.2/src/schooltool/cando/locales/nl.po0000644000175000017500000010601512322023754024557 0ustar menesismenesis00000000000000# Dutch translation for schooltool.cando # Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012 # This file is distributed under the same license as the schooltool.cando package. # FIRST AUTHOR , 2012. # msgid "" msgstr "" "Project-Id-Version: schooltool.cando\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2013-10-10 16:06+0300\n" "PO-Revision-Date: 2013-03-20 04:32+0000\n" "Last-Translator: rob \n" "Language-Team: Dutch \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2013-10-11 05:27+0000\n" "X-Generator: Launchpad (build 16799)\n" #: /src/schooltool/cando/browser/breadcrumbs.zcml:9 #: /src/schooltool/cando/browser/breadcrumbs.zcml:67 #: /src/schooltool/cando/browser/breadcrumbs.zcml:72 #: /src/schooltool/cando/browser/configure.zcml:135 #: /src/schooltool/cando/browser/configure.zcml:336 #: /src/schooltool/cando/browser/configure.zcml:779 #: /src/schooltool/cando/browser/course.py:162 #: /src/schooltool/cando/browser/document.py:815 #: /src/schooltool/cando/browser/document.zcml:26 #: /src/schooltool/cando/browser/gradebook.py:275 #: /src/schooltool/cando/browser/skill.py:76 #: /src/schooltool/cando/browser/templates/course_assign_skillsets_dialog.pt:30 #: /src/schooltool/cando/browser/templates/course_remove_skills.pt:20 #: /src/schooltool/cando/browser/templates/course_skills_overview.pt:4 #: /src/schooltool/cando/browser/templates/skillset.pt:77 msgid "Skills" msgstr "Vaardigheden" #: /src/schooltool/cando/browser/breadcrumbs.zcml:14 #: /src/schooltool/cando/browser/configure.zcml:40 #: /src/schooltool/cando/browser/course.py:292 #: /src/schooltool/cando/browser/document.py:122 #: /src/schooltool/cando/browser/gradebook.zcml:115 msgid "Skill Sets" msgstr "" #: /src/schooltool/cando/browser/breadcrumbs.zcml:21 #: /src/schooltool/cando/browser/course.py:287 #: /src/schooltool/cando/browser/document.py:121 #: /src/schooltool/cando/browser/model.py:439 #: /src/schooltool/cando/browser/templates/course_assign_skills_table_filter.pt:34 #: /src/schooltool/cando/browser/templates/node.pt:155 #: /src/schooltool/cando/browser/templates/nodes_table_filter.pt:34 msgid "Layers" msgstr "Lagen" #: /src/schooltool/cando/browser/breadcrumbs.zcml:28 msgid "Nodes" msgstr "" #: /src/schooltool/cando/browser/configure.zcml:107 #: /src/schooltool/cando/browser/configure.zcml:162 #: /src/schooltool/cando/browser/configure.zcml:515 #: /src/schooltool/cando/browser/configure.zcml:642 #: /src/schooltool/cando/browser/course.py:223 #: /src/schooltool/cando/browser/course.py:225 #: /src/schooltool/cando/browser/document.zcml:61 #: /src/schooltool/cando/browser/document.zcml:185 #: /src/schooltool/cando/browser/document.zcml:220 #: /src/schooltool/cando/browser/document.zcml:303 #: /src/schooltool/cando/browser/gradebook.zcml:63 #: /src/schooltool/cando/browser/templates/course_assign_skillsets_dialog.pt:32 msgid "Add" msgstr "Toevoegen" #: /src/schooltool/cando/browser/configure.zcml:117 #: /src/schooltool/cando/browser/configure.zcml:260 #: /src/schooltool/cando/browser/configure.zcml:795 msgid "Actions" msgstr "Acties" #: /src/schooltool/cando/browser/configure.zcml:127 msgid "Skill Set" msgstr "" #: /src/schooltool/cando/browser/configure.zcml:135 msgid "New Skill Set" msgstr "" #: /src/schooltool/cando/browser/configure.zcml:145 #: /src/schooltool/cando/browser/configure.zcml:199 #: /src/schooltool/cando/browser/configure.zcml:552 #: /src/schooltool/cando/browser/configure.zcml:679 #: /src/schooltool/cando/browser/document.zcml:98 #: /src/schooltool/cando/browser/document.zcml:194 #: /src/schooltool/cando/browser/document.zcml:253 #: /src/schooltool/cando/browser/document.zcml:312 #: /src/schooltool/cando/browser/document.zcml:345 #: /src/schooltool/cando/browser/gradebook.zcml:322 #: /src/schooltool/cando/browser/templates/document.pt:9 #: /src/schooltool/cando/browser/templates/layer.pt:109 #: /src/schooltool/cando/browser/templates/node.pt:21 #: /src/schooltool/cando/browser/templates/node.pt:126 #: /src/schooltool/cando/browser/templates/node.pt:164 #: /src/schooltool/cando/browser/templates/node.pt:201 msgid "Edit" msgstr "Bewerken" #: /src/schooltool/cando/browser/configure.zcml:171 #: /src/schooltool/cando/browser/document.py:166 #: /src/schooltool/cando/browser/document.py:388 #: /src/schooltool/cando/browser/document.py:397 #: /src/schooltool/cando/browser/gradebook.py:182 #: /src/schooltool/cando/browser/gradebook.py:197 #: /src/schooltool/cando/browser/gradebook.py:298 #: /src/schooltool/cando/browser/gradebook.py:924 #: /src/schooltool/cando/browser/model.py:137 #: /src/schooltool/cando/browser/skill.py:221 #: /src/schooltool/cando/browser/skill.py:279 #: /src/schooltool/cando/browser/skill.py:307 #: /src/schooltool/cando/browser/templates/edit_course_skills.pt:7 #: /src/schooltool/cando/browser/templates/student_competency_record.pt:9 msgid "Skill" msgstr "Vaardigheid" #: /src/schooltool/cando/browser/configure.zcml:181 #: /src/schooltool/cando/browser/gradebook.py:838 #: /src/schooltool/cando/browser/gradebook.zcml:187 msgid "New Skill" msgstr "Nieuwe vaardigheid" #: /src/schooltool/cando/browser/configure.zcml:190 #: /src/schooltool/cando/browser/configure.zcml:461 msgid "View Skill" msgstr "Vaardigheid bekijken" #: /src/schooltool/cando/browser/configure.zcml:228 #: /src/schooltool/cando/browser/configure.zcml:395 msgid "Assigned Skills" msgstr "Toegewezen vaardigheden" #: /src/schooltool/cando/browser/configure.zcml:270 #: /src/schooltool/cando/browser/configure.zcml:345 msgid "Assign Skills" msgstr "Vaardigheden toewijzen" #: /src/schooltool/cando/browser/configure.zcml:278 #: /src/schooltool/cando/browser/configure.zcml:353 msgid "Remove Skills" msgstr "Vaardigheden verwijderen" #: /src/schooltool/cando/browser/configure.zcml:298 #: /src/schooltool/cando/browser/configure.zcml:315 msgid "Set Required / Deprecated" msgstr "" #: /src/schooltool/cando/browser/configure.zcml:347 msgid "Assign Skill Set" msgstr "" #: /src/schooltool/cando/browser/configure.zcml:404 msgid "Edit Skills" msgstr "Vaardigheden bewerken" #: /src/schooltool/cando/browser/configure.zcml:488 #: /src/schooltool/cando/browser/configure.zcml:533 msgid "Layers Container" msgstr "" #: /src/schooltool/cando/browser/configure.zcml:524 #: /src/schooltool/cando/browser/model.py:174 msgid "Layer" msgstr "Laag" #: /src/schooltool/cando/browser/configure.zcml:533 msgid "Add Layer" msgstr "Laag toevoegen" #: /src/schooltool/cando/browser/configure.zcml:543 msgid "View Layer" msgstr "Laag bekijken" #: /src/schooltool/cando/browser/configure.zcml:561 #: /src/schooltool/cando/browser/configure.zcml:688 msgid "Edit Children" msgstr "Onderliggende bewerken" #: /src/schooltool/cando/browser/configure.zcml:605 #: /src/schooltool/cando/browser/configure.zcml:660 msgid "Nodes Container" msgstr "" #: /src/schooltool/cando/browser/configure.zcml:605 #: /src/schooltool/cando/browser/document.py:123 #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:77 #: /src/schooltool/cando/browser/templates/nodes_table_filter.pt:53 msgid "Search" msgstr "Zoeken" #: /src/schooltool/cando/browser/configure.zcml:625 msgid "Deprecate" msgstr "" #: /src/schooltool/cando/browser/configure.zcml:625 msgid "Documents and Skills" msgstr "" #: /src/schooltool/cando/browser/configure.zcml:766 #: /src/schooltool/cando/browser/model.py:398 #: /src/schooltool/cando/browser/model.py:427 #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:109 msgid "Node" msgstr "" #: /src/schooltool/cando/browser/configure.zcml:660 msgid "Add Node" msgstr "" #: /src/schooltool/cando/browser/configure.zcml:670 msgid "View Node" msgstr "" #: /src/schooltool/cando/browser/configure.zcml:714 msgid "Edit Layers" msgstr "Lagen bewerken" #: /src/schooltool/cando/browser/configure.zcml:785 msgid "Edit Skill Sets" msgstr "" #: /src/schooltool/cando/browser/configure.zcml:825 #: /src/schooltool/cando/browser/configure.zcml:833 msgid "Import Skill Data" msgstr "Vaardigheidsgegevens importeren" #: /src/schooltool/cando/browser/configure.zcml:919 msgid "Deprecate Skills" msgstr "" #: /src/schooltool/cando/browser/configure.zcml:974 msgid "Batch Assign Skills" msgstr "" #: /src/schooltool/cando/browser/configure.zcml:814 msgid "Assign Courses Skills" msgstr "Vak-vaardigheden toewijzen" #: /src/schooltool/cando/browser/course.py:156 #: /src/schooltool/cando/browser/course.py:277 #: /src/schooltool/cando/browser/course.py:571 #: /src/schooltool/cando/browser/document.py:869 #: /src/schooltool/cando/browser/model.py:432 #: /src/schooltool/cando/browser/templates/course_assign_skillsets_dialog.pt:29 #: /src/schooltool/cando/browser/templates/course_remove_skills.pt:19 #: /src/schooltool/cando/browser/templates/projects.pt:10 #: /src/schooltool/cando/browser/templates/skillsets.pt:10 #: /src/schooltool/cando/interfaces.py:72 #: /src/schooltool/cando/interfaces.py:89 msgid "Title" msgstr "Titel" #: /src/schooltool/cando/browser/course.py:260 msgid "Select Skill Sets from ${node} (${node_id})" msgstr "" #: /src/schooltool/cando/browser/course.py:282 msgid "ID" msgstr "ID" #: /src/schooltool/cando/browser/course.py:314 #: /src/schooltool/cando/browser/model.py:454 msgid "ID, title, label or description" msgstr "ID, titel, label of omschrijving" #: /src/schooltool/cando/browser/course.py:576 #: /src/schooltool/cando/browser/course.py:635 #: /src/schooltool/cando/browser/document.py:880 #: /src/schooltool/cando/browser/model.py:427 #: /src/schooltool/cando/browser/skill.py:80 #: /src/schooltool/cando/browser/skill.py:209 #: /src/schooltool/cando/interfaces.py:63 #: /src/schooltool/cando/interfaces.py:96 msgid "Label" msgstr "Label" #: /src/schooltool/cando/browser/course.py:581 #: /src/schooltool/cando/browser/document.py:875 #: /src/schooltool/cando/browser/templates/colorcodes_help.pt:10 #: /src/schooltool/cando/browser/templates/edit_course_skills.pt:9 #: /src/schooltool/cando/browser/templates/student_competency_record.pt:8 #: /src/schooltool/cando/interfaces.py:39 msgid "Required" msgstr "Verplicht" #: /src/schooltool/cando/browser/course.py:587 msgid "Hidden" msgstr "Verborgen" #: /src/schooltool/cando/browser/course.py:790 msgid "Course has skills assigned already" msgstr "Er zijn reeds vaardigheden toegewezen aan dit vak" #: /src/schooltool/cando/browser/course.py:810 msgid "Couldn't find a matching node" msgstr "" #: /src/schooltool/cando/browser/course.py:816 msgid "Course attribute is empty" msgstr "Vak-kenmerk is leeg" #: /src/schooltool/cando/browser/document.py:120 msgid "Documents" msgstr "Documenten" #: /src/schooltool/cando/browser/document.py:148 msgid "Document Information" msgstr "Documentinformatie" #: /src/schooltool/cando/browser/document.py:198 #: /src/schooltool/cando/browser/document.py:524 #: /src/schooltool/cando/browser/document.py:708 #: /src/schooltool/cando/browser/document.py:769 #: /src/schooltool/cando/browser/gradebook.py:352 #: /src/schooltool/cando/browser/gradebook.py:471 #: /src/schooltool/cando/browser/iep.py:131 #: /src/schooltool/cando/browser/model.py:103 #: /src/schooltool/cando/browser/model.py:177 #: /src/schooltool/cando/browser/model.py:321 #: /src/schooltool/cando/browser/model.py:396 #: /src/schooltool/cando/browser/skill.py:179 #: /src/schooltool/cando/browser/skill.py:235 #: /src/schooltool/cando/browser/skill.py:327 #: /src/schooltool/cando/browser/templates/course_skills_edit_table_buttons.pt:5 msgid "Submit" msgstr "Indienen" #: /src/schooltool/cando/browser/document.py:186 #: /src/schooltool/cando/browser/document.py:465 #: /src/schooltool/cando/browser/document.py:645 #: /src/schooltool/cando/browser/document.py:709 #: /src/schooltool/cando/browser/gradebook.py:321 #: /src/schooltool/cando/browser/gradebook.py:444 #: /src/schooltool/cando/browser/model.py:106 #: /src/schooltool/cando/browser/model.py:183 #: /src/schooltool/cando/browser/model.py:324 #: /src/schooltool/cando/browser/model.py:403 #: /src/schooltool/cando/browser/skill.py:180 #: /src/schooltool/cando/browser/skill.py:238 #: /src/schooltool/cando/browser/skill.py:316 #: /src/schooltool/cando/browser/templates/course_skills_edit_table_buttons.pt:8 #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:79 #: /src/schooltool/cando/browser/templates/grade_student.pt:39 msgid "Cancel" msgstr "Annuleren" #: /src/schooltool/cando/browser/document.py:429 #: /src/schooltool/cando/browser/document.py:571 #: /src/schooltool/cando/browser/document.py:816 msgid "${layer} list" msgstr "${layer}-lijst" #: /src/schooltool/cando/browser/document.py:450 #: /src/schooltool/cando/browser/document.zcml:70 msgid "Document" msgstr "Document" #: /src/schooltool/cando/browser/document.py:477 msgid "Current document hierarchy layers" msgstr "Huidige hiërarchische documentlagen" #: /src/schooltool/cando/browser/document.py:478 msgid "Available layers" msgstr "Beshikbare lagen" #: /src/schooltool/cando/browser/document.py:566 #: /src/schooltool/cando/browser/document.py:808 #: /src/schooltool/cando/browser/document.py:961 msgid "View ${layer}" msgstr "${layer} bekijken" #: /src/schooltool/cando/browser/document.py:624 #: /src/schooltool/cando/browser/document.py:744 #: /src/schooltool/cando/browser/document.py:921 msgid "Add ${layer}" msgstr "${layer} toevoegen" #: /src/schooltool/cando/browser/document.py:629 #: /src/schooltool/cando/browser/document.py:916 msgid "${layer} Information" msgstr "${layer}-informatie" #: /src/schooltool/cando/browser/document.py:673 msgid "Skills Document" msgstr "Vaardigheidsdocument" #: /src/schooltool/cando/browser/document.py:695 msgid "Change information" msgstr "Informatie wijzigen" #: /src/schooltool/cando/browser/document.py:928 #: /src/schooltool/cando/browser/gradebook.py:1594 msgid "No" msgstr "Nee" #: /src/schooltool/cando/browser/document.py:928 #: /src/schooltool/cando/browser/gradebook.py:1594 msgid "Yes" msgstr "Ja" #: /src/schooltool/cando/browser/document.zcml:35 #: /src/schooltool/cando/browser/document.zcml:79 msgid "Skills Documents" msgstr "Vaardigheidsdocumenten" #: /src/schooltool/cando/browser/document.zcml:79 msgid "Add Document" msgstr "Document toevoegen" #: /src/schooltool/cando/browser/document.zcml:89 msgid "View Skills Document" msgstr "Vaardigheidsdocument bekijken" #: /src/schooltool/cando/browser/document.zcml:107 msgid "Edit Layer Hierarchy" msgstr "" #: /src/schooltool/cando/browser/document.zcml:133 msgid "View Hierarchy Layer" msgstr "" #: /src/schooltool/cando/browser/document.zcml:142 msgid "Edit Hierarchy Layer" msgstr "" #: /src/schooltool/cando/browser/document.zcml:151 msgid "Edit Hierarchy Layer Parents" msgstr "" #: /src/schooltool/cando/browser/document.zcml:211 msgid "Layer Hierarchy" msgstr "" #: /src/schooltool/cando/browser/gradebook.py:189 msgid "No Visible Projects" msgstr "Geen zichtbare projecten" #: /src/schooltool/cando/browser/gradebook.py:191 #: /src/schooltool/cando/browser/gradebook.py:206 msgid "Enter Skills" msgstr "Vaardigheden invoeren" #: /src/schooltool/cando/browser/gradebook.py:204 msgid "No Visible Skill Sets" msgstr "" #: /src/schooltool/cando/browser/gradebook.py:281 #: /src/schooltool/cando/browser/gradebook.zcml:98 #: /src/schooltool/cando/browser/gradebook.zcml:106 #: /src/schooltool/cando/project.py:163 msgid "Projects" msgstr "Projecten" #: /src/schooltool/cando/browser/gradebook.py:315 msgid "Project Details" msgstr "Projectdetails" #: /src/schooltool/cando/browser/gradebook.py:358 msgid "Sort by" msgstr "Sorteren op" #: /src/schooltool/cando/browser/gradebook.py:423 msgid "Skill Details" msgstr "Vaardigheidsdetails" #: /src/schooltool/cando/browser/gradebook.py:518 msgid "${section} Skills" msgstr "${section}-vaardigheden" #: /src/schooltool/cando/browser/gradebook.py:520 msgid "${section} Project Skills" msgstr "${section}-projectvaardigheden" #: /src/schooltool/cando/browser/gradebook.py:529 msgid "Score System Help" msgstr "Scoresysteem-hulp" #: /src/schooltool/cando/browser/gradebook.py:537 msgid "Color Codes Help" msgstr "" #: /src/schooltool/cando/browser/gradebook.py:953 msgid "No layer assigned" msgstr "" #: /src/schooltool/cando/browser/gradebook.py:1236 msgid "Changes saved" msgstr "" #: /src/schooltool/cando/browser/gradebook.py:1392 #: /src/schooltool/cando/browser/gradebook.zcml:140 msgid "Search Skills" msgstr "Vaardigheden zoeken" #: /src/schooltool/cando/browser/gradebook.py:1450 msgid "Save" msgstr "Opslaan" #: /src/schooltool/cando/browser/gradebook.py:1466 #: /src/schooltool/cando/browser/templates/scoresystem_help.pt:5 msgid "Score" msgstr "Score" #: /src/schooltool/cando/browser/gradebook.py:1561 #: /src/schooltool/cando/browser/gradebook.zcml:520 msgid "CanDo Gradebook" msgstr "CanDo-cijferlijst" #: /src/schooltool/cando/browser/gradebook.py:1677 msgid "Date" msgstr "Datum" #: /src/schooltool/cando/browser/gradebook.py:1606 #: /src/schooltool/cando/browser/templates/scoresystem_help.pt:6 msgid "Rating" msgstr "" #: /src/schooltool/cando/browser/gradebook.py:1736 #: /src/schooltool/cando/browser/gradebook.py:1951 #: /src/schooltool/cando/browser/gradebook.zcml:770 msgid "Student Skill Report" msgstr "" #: /src/schooltool/cando/browser/gradebook.py:1759 msgid "Teacher(s): ${teachers}" msgstr "" #: /src/schooltool/cando/browser/gradebook.py:1755 #: /src/schooltool/cando/browser/gradebook.py:1870 msgid "Course: ${courses}" msgstr "" #: /src/schooltool/cando/browser/gradebook.py:1847 #: /src/schooltool/cando/browser/gradebook.zcml:782 msgid "Certificate of Competency" msgstr "" #: /src/schooltool/cando/browser/gradebook.py:2288 msgid "skill gradebooks archive" msgstr "" #: /src/schooltool/cando/browser/gradebook.zcml:10 #: /src/schooltool/cando/browser/gradebook.zcml:26 #: /src/schooltool/cando/browser/gradebook.zcml:128 #: /src/schooltool/cando/browser/gradebook.zcml:223 #: /src/schooltool/cando/browser/gradebook.zcml:321 #: /src/schooltool/cando/browser/gradebook.zcml:431 msgid "CanDo" msgstr "CanDo" #: /src/schooltool/cando/browser/gradebook.zcml:45 msgid "View" msgstr "" #: /src/schooltool/cando/browser/gradebook.zcml:80 msgid "Project" msgstr "Project" #: /src/schooltool/cando/browser/gradebook.zcml:88 msgid "Settings" msgstr "Instellingen" #: /src/schooltool/cando/browser/gradebook.zcml:126 msgid "New Project" msgstr "Nieuw project" #: /src/schooltool/cando/browser/gradebook.zcml:310 msgid "Edit Skill" msgstr "Vaardigheid bewerken" #: /src/schooltool/cando/browser/gradebook.zcml:373 #: /src/schooltool/cando/browser/gradebook.zcml:637 #: /src/schooltool/cando/browser/gradebook.zcml:660 msgid "Help" msgstr "Hulp" #: /src/schooltool/cando/browser/gradebook.zcml:383 msgid "Score System" msgstr "Scoresysteem" #: /src/schooltool/cando/browser/gradebook.zcml:391 msgid "Color Codes" msgstr "Kleurcodes" #: /src/schooltool/cando/browser/gradebook.zcml:492 msgid "Skills Pop-up" msgstr "" #: /src/schooltool/cando/browser/gradebook.zcml:546 msgid "My Skills Grades" msgstr "" #: /src/schooltool/cando/browser/gradebook.zcml:579 msgid "My Projects Grades" msgstr "" #: /src/schooltool/cando/browser/gradebook.zcml:596 #: /src/schooltool/cando/browser/gradebook.zcml:827 #: /src/schooltool/cando/browser/gradebook.zcml:839 #: /src/schooltool/cando/browser/report.py:878 #: /src/schooltool/cando/browser/report.zcml:47 #: /src/schooltool/cando/browser/report.zcml:58 msgid "Section" msgstr "Sectie" #: /src/schooltool/cando/browser/gradebook.zcml:557 msgid "Term" msgstr "Termijn" #: /src/schooltool/cando/browser/gradebook.zcml:568 msgid "Year" msgstr "Jaar" #: /src/schooltool/cando/browser/gradebook.zcml:760 msgid "Reports" msgstr "" #: /src/schooltool/cando/browser/gradebook.zcml:770 msgid "" "Summary of a student's scores for all the skills assigned to a section." msgstr "" #: /src/schooltool/cando/browser/gradebook.zcml:770 #: /src/schooltool/cando/browser/gradebook.zcml:782 msgid "Student" msgstr "" #: /src/schooltool/cando/browser/gradebook.zcml:782 msgid "" "Summary of a student scores in a section exceeding a selected minimum score. " "Formatted for presentation to an potential employer or other person outside " "of the school." msgstr "" #: /src/schooltool/cando/browser/gradebook.zcml:794 #: /src/schooltool/cando/browser/gradebook.zcml:806 msgid "Aggregated Student Skill Reports" msgstr "" #: /src/schooltool/cando/browser/gradebook.zcml:794 msgid "" "Summary of all students' scores for all the skills assigned to a section." msgstr "" #: /src/schooltool/cando/browser/iep.py:122 msgid "IEP Details" msgstr "" #: /src/schooltool/cando/browser/iep.py:176 msgid "IEP Skills for ${section}" msgstr "" #: /src/schooltool/cando/browser/iep.py:322 msgid "Edit IEP Skills for ${section}" msgstr "" #: /src/schooltool/cando/browser/iep.py:354 msgid "Optional IEP" msgstr "" #: /src/schooltool/cando/browser/iep.py:424 msgid "IEP Information" msgstr "" #: /src/schooltool/cando/browser/iep.zcml:8 msgid "IEP" msgstr "" #: /src/schooltool/cando/browser/iep.zcml:17 #: /src/schooltool/cando/browser/iep.zcml:52 msgid "Individualized Educational Plan" msgstr "" #: /src/schooltool/cando/browser/importer.py:44 msgid "has an invalid document id" msgstr "" #: /src/schooltool/cando/browser/importer.py:45 msgid "has an invalid parent id" msgstr "" #: /src/schooltool/cando/browser/importer.py:46 msgid "has an invalid layer id" msgstr "" #: /src/schooltool/cando/browser/importer.py:47 msgid "has an invalid skillset id" msgstr "" #: /src/schooltool/cando/browser/importer.py:48 msgid "is missing a skillset id" msgstr "" #: /src/schooltool/cando/browser/importer.py:49 msgid "has an invalid equivalent skill id" msgstr "" #: /src/schooltool/cando/browser/importer.py:50 msgid "node label has more than seven characters" msgstr "" #: /src/schooltool/cando/browser/importer.py:51 msgid "has an invalid scoresystem" msgstr "" #: /src/schooltool/cando/browser/importer.py:52 msgid "has an invalid node id" msgstr "" #: /src/schooltool/cando/browser/model.py:94 msgid "Layer Information" msgstr "Laag-informatie" #: /src/schooltool/cando/browser/model.py:209 msgid "Parents" msgstr "Bovenliggende" #: /src/schooltool/cando/browser/model.py:214 msgid "Children" msgstr "Onderliggende" #: /src/schooltool/cando/browser/model.py:257 msgid "Current child layers" msgstr "Huidige onderliggende lagen" #: /src/schooltool/cando/browser/model.py:258 msgid "Available child layers" msgstr "Beschikbare onderliggende lagen" #: /src/schooltool/cando/browser/model.py:307 msgid "Node Information" msgstr "" #: /src/schooltool/cando/browser/model.py:546 msgid "Current child nodes" msgstr "" #: /src/schooltool/cando/browser/model.py:547 msgid "Available child nodes" msgstr "" #: /src/schooltool/cando/browser/model.py:584 msgid "Current node layers" msgstr "" #: /src/schooltool/cando/browser/model.py:585 msgid "Available node layers" msgstr "" #: /src/schooltool/cando/browser/model.py:641 msgid "Current node skill sets" msgstr "" #: /src/schooltool/cando/browser/model.py:642 msgid "Available node skill sets" msgstr "" #: /src/schooltool/cando/browser/report.py:199 msgid "All" msgstr "" #: /src/schooltool/cando/browser/report.py:199 msgid "Evaluated" msgstr "" #: /src/schooltool/cando/browser/report.py:380 msgid "% of Skills Below and Above Passing" msgstr "" #: /src/schooltool/cando/browser/report.py:406 msgid "Students (${count})" msgstr "" #: /src/schooltool/cando/browser/report.py:480 msgid "Student ID #" msgstr "" #: /src/schooltool/cando/browser/report.py:640 #: /src/schooltool/cando/browser/templates/section_report_score_colors.pt:19 msgid "Score Colors" msgstr "" #: /src/schooltool/cando/browser/report.py:814 msgid "Totals" msgstr "" #: /src/schooltool/cando/browser/report.py:866 #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:88 #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:107 #: /src/schooltool/cando/browser/templates/section_report_details.pt:8 msgid "Course" msgstr "Vak" #: /src/schooltool/cando/browser/report.py:874 #: /src/schooltool/cando/browser/templates/section_report_details.pt:16 msgid "Teachers" msgstr "" #: /src/schooltool/cando/browser/report.zcml:21 msgid "Export global skills data for the school." msgstr "Algemene vaardigheidsgegevens van de school exporteren." #: /src/schooltool/cando/browser/report.zcml:10 msgid "School" msgstr "School" #: /src/schooltool/cando/browser/report.zcml:10 msgid "Skills Export" msgstr "vaardigheden exporteren" #: /src/schooltool/cando/browser/report.zcml:47 #: /src/schooltool/cando/browser/report.zcml:58 msgid "" "An overview of each student's achievement of skills within the section." msgstr "" #: /src/schooltool/cando/browser/report.zcml:47 #: /src/schooltool/cando/browser/report.zcml:58 #: /src/schooltool/cando/browser/report.zcml:88 #: /src/schooltool/cando/browser/report.zcml:244 msgid "Per Student Skills" msgstr "" #: /src/schooltool/cando/browser/report.zcml:70 msgid "An overview of each section's aggregate achievement of skills." msgstr "" #: /src/schooltool/cando/browser/report.zcml:70 msgid "Skills Completion" msgstr "" #: /src/schooltool/cando/browser/report.zcml:191 msgid "Passing Score" msgstr "" #: /src/schooltool/cando/browser/report.zcml:208 msgid "Type" msgstr "" #: /src/schooltool/cando/browser/report.zcml:226 #: /src/schooltool/cando/browser/templates/section_report_score_colors.pt:28 msgid "% Passing Target" msgstr "" #: /src/schooltool/cando/browser/report.zcml:252 msgid "Skills Completion Report" msgstr "" #: /src/schooltool/cando/browser/report.zcml:298 msgid "Location" msgstr "" #: /src/schooltool/cando/browser/report.zcml:360 msgid "Skill Gradebooks" msgstr "" #: /src/schooltool/cando/browser/report.zcml:369 msgid "Archive all student skill gradebooks." msgstr "" #: /src/schooltool/cando/browser/report.zcml:369 msgid "Skill Gradebook Archive" msgstr "" #: /src/schooltool/cando/browser/skill.py:98 msgid "Title, description or label" msgstr "Titel, omschrijving of label" #: /src/schooltool/cando/browser/skill.py:125 #: /src/schooltool/cando/browser/skill.py:171 msgid "Skill set" msgstr "" #: /src/schooltool/cando/browser/skill.py:232 msgid "Submit and add" msgstr "Indienen en toevoegen" #: /src/schooltool/cando/browser/skill.py:386 #: /src/schooltool/cando/browser/templates/colorcodes_help.pt:13 msgid "Optional" msgstr "Optioneel" #: /src/schooltool/cando/browser/templates/cando_third_nav.pt:2 msgid "Scroll over a skill ID to see its description here" msgstr "" #: /src/schooltool/cando/browser/templates/colorcodes_help.pt:5 msgid "Skill Color Code" msgstr "Vaardigheidskleurcode" #: /src/schooltool/cando/browser/templates/colorcodes_help.pt:16 msgid "Optional (IEP)" msgstr "" #: /src/schooltool/cando/browser/templates/course_assign_skills_table_filter.pt:12 #: /src/schooltool/cando/browser/templates/nodes_table_filter.pt:12 msgid "Showing ${count} of ${total} items" msgstr "${count} van ${total} items worden getoond" #: /src/schooltool/cando/browser/templates/course_assign_skillsets_dialog.pt:20 msgid "You must select at least one skill set." msgstr "" #. Default: "Submit" #: /src/schooltool/cando/browser/templates/course_assign_skillsets_dialog.pt:69 #: /src/schooltool/cando/browser/templates/course_remove_skills.pt:59 #: /src/schooltool/cando/browser/templates/edit_course_skills.pt:45 msgid "submit-button" msgstr "Indienen" #. Default: "Cancel" #: /src/schooltool/cando/browser/templates/course_assign_skillsets_dialog.pt:73 #: /src/schooltool/cando/browser/templates/course_remove_skills.pt:62 #: /src/schooltool/cando/browser/templates/edit_course_skills.pt:48 msgid "cancel-button" msgstr "Annuleren" #: /src/schooltool/cando/browser/templates/course_remove_skills.pt:22 msgid "Remove" msgstr "Verwijderen" #: /src/schooltool/cando/browser/templates/course_skills_overview.pt:4 msgid "Assign Course Skills" msgstr "Vak-vaardigheden toewijzen" #: /src/schooltool/cando/browser/templates/course_skills_overview.pt:13 msgid "There are ${count} sets of skills assigned." msgstr "" #: /src/schooltool/cando/browser/templates/course_skills_overview.pt:16 msgid "There are no skills assigned." msgstr "Er zijn geen vaardigheden toegewezen." #: /src/schooltool/cando/browser/templates/course_skillset.pt:4 #: /src/schooltool/cando/browser/templates/document_skillset.pt:4 #: /src/schooltool/cando/browser/templates/skillset.pt:4 #: /src/schooltool/cando/browser/templates/skillsets.pt:34 msgid "Edit this skill set" msgstr "" #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:10 msgid "Course Matching" msgstr "" #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:15 msgid "Course field" msgstr "" #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:21 #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:63 msgid "Select a field" msgstr "" #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:36 msgid "Node layer" msgstr "" #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:42 msgid "Select a layer" msgstr "Selecteer een laag" #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:57 msgid "Node field" msgstr "" #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:83 msgid "Courses not matched" msgstr "" #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:87 #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:106 #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:108 msgid "Field" msgstr "" #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:89 msgid "Reason" msgstr "Reden" #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:102 msgid "Courses matched" msgstr "" #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:122 msgid "Assign" msgstr "Toewijzen" #: /src/schooltool/cando/browser/templates/document.pt:5 msgid "Edit this Document" msgstr "Dit document bewerken" #: /src/schooltool/cando/browser/templates/document_skill.pt:4 #: /src/schooltool/cando/browser/templates/skill.pt:4 msgid "Edit this skill" msgstr "Deze vaardigheid bewerken" #: /src/schooltool/cando/browser/templates/edit_course_skills.pt:15 #: /src/schooltool/cando/interfaces.py:70 #: /src/schooltool/cando/interfaces.py:99 #: /src/schooltool/cando/interfaces.py:134 msgid "Deprecated" msgstr "" #: /src/schooltool/cando/browser/templates/gradebook_skills_dialog.pt:33 #: /src/schooltool/cando/browser/templates/gradebook_skills_dialog.pt:43 msgid "There are no skills." msgstr "Er zijn geen vaardigheden" #: /src/schooltool/cando/browser/templates/iep_details.pt:5 msgid "Edit this plan information" msgstr "" #: /src/schooltool/cando/browser/templates/layer.pt:4 msgid "Edit this Layer" msgstr "Deze laag bewerken" #: /src/schooltool/cando/browser/templates/layer.pt:78 msgid "Parent layers" msgstr "Bovenliggende lagen" #: /src/schooltool/cando/browser/templates/layer.pt:104 msgid "Child layers" msgstr "Onderliggende lagen" #: /src/schooltool/cando/browser/templates/layer.pt:107 msgid "Edit children" msgstr "Onderliggende bewerken" #: /src/schooltool/cando/browser/templates/node.pt:13 msgid "General Information" msgstr "Algemene informatie" #: /src/schooltool/cando/browser/templates/node.pt:17 msgid "Edit this Node" msgstr "" #: /src/schooltool/cando/browser/templates/node.pt:89 #: /src/schooltool/cando/browser/templates/node.pt:92 msgid "Parent nodes" msgstr "" #: /src/schooltool/cando/browser/templates/node.pt:118 #: /src/schooltool/cando/browser/templates/node.pt:121 msgid "Child nodes" msgstr "" #: /src/schooltool/cando/browser/templates/node.pt:122 msgid "Edit child nodes" msgstr "" #: /src/schooltool/cando/browser/templates/node.pt:160 msgid "Edit layers" msgstr "Lagen bewerken" #: /src/schooltool/cando/browser/templates/node.pt:201 msgid "Edit skill sets" msgstr "" #: /src/schooltool/cando/browser/templates/projects.pt:5 msgid "Reorder or Hide Projects" msgstr "Volgorde projecten wijzigen of projecten verbergen" #: /src/schooltool/cando/browser/templates/projects.pt:9 #: /src/schooltool/cando/browser/templates/skillsets.pt:9 msgid "Order" msgstr "Volgorde" #: /src/schooltool/cando/browser/templates/projects.pt:11 #: /src/schooltool/cando/browser/templates/skillsets.pt:11 msgid "Visible" msgstr "Zichtbaar" #: /src/schooltool/cando/browser/templates/projects.pt:34 msgid "Edit this project" msgstr "Dit project bewerken" #: /src/schooltool/cando/browser/templates/request_competency_certificate.pt:5 #: /src/schooltool/cando/interfaces.py:99 #: /src/schooltool/cando/interfaces.py:238 msgid "Description" msgstr "Omschrijving" #: /src/schooltool/cando/browser/templates/request_competency_certificate.pt:11 msgid "File Type" msgstr "" #: /src/schooltool/cando/browser/templates/request_competency_certificate.pt:23 msgid "Select a minimum display score for ${scoresystem}" msgstr "" #: /src/schooltool/cando/browser/templates/section_report_details.pt:3 msgid "Details" msgstr "" #: /src/schooltool/cando/browser/templates/section_report_details.pt:12 msgid "Government ID" msgstr "" #: /src/schooltool/cando/browser/templates/section_report_score_colors.pt:33 msgid "Meets target" msgstr "" #: /src/schooltool/cando/browser/templates/skillsets.pt:5 msgid "Reorder or Hide Skill Sets" msgstr "" #: /src/schooltool/cando/browser/xls_views.py:183 msgid "Skill definitions" msgstr "" #: /src/schooltool/cando/browser/xls_views.py:186 #: /src/schooltool/cando/course.py:187 msgid "Course Skills" msgstr "Vak-vaardigheden" #: /src/schooltool/cando/browser/xls_views.py:193 msgid "Exporting skills" msgstr "" #: /src/schooltool/cando/browser/xls_views.py:212 msgid "Export complete" msgstr "" #: /src/schooltool/cando/course.py:231 msgid "Section Skills" msgstr "Vaardigheden-sectie" #: /src/schooltool/cando/gradebook.py:56 msgid "Project1" msgstr "Project1" #: /src/schooltool/cando/interfaces.py:60 msgid "Limit to 7 characters or less." msgstr "Limiteren tot 7 tekens of minder" #: /src/schooltool/cando/interfaces.py:68 msgid "External ID" msgstr "Externe-ID" #: /src/schooltool/cando/interfaces.py:70 msgid "Required?" msgstr "" #: /src/schooltool/cando/interfaces.py:71 msgid "Skill is no longer used" msgstr "Vaardigheid wordt niet meer gebruikt" #: /src/schooltool/cando/interfaces.py:79 msgid "Scoresystem" msgstr "" #: /src/schooltool/cando/interfaces.py:52 msgid "The skill scoresystem." msgstr "" #: /src/schooltool/cando/interfaces.py:100 msgid "Skill set is no longer used" msgstr "" #: /src/schooltool/cando/interfaces.py:135 msgid "Node is no longer used" msgstr "" #: /src/schooltool/cando/interfaces.py:186 msgid "Project deployed" msgstr "" #: /src/schooltool/cando/interfaces.py:151 msgid "Is this project deployed to course sections" msgstr "" #: /src/schooltool/cando/interfaces.py:200 msgid "Section intID" msgstr "" #: /src/schooltool/cando/interfaces.py:208 msgid "Skill set ID" msgstr "" #: /src/schooltool/cando/interfaces.py:209 msgid "Skill ID" msgstr "Vaardigheids-ID" #: /src/schooltool/cando/interfaces.py:235 msgid "Active" msgstr "" #: /src/schooltool/cando/project.py:137 msgid "Course Projects" msgstr "Vak-projecten" #: /src/schooltool/cando/project.py:207 msgid "${project} total points" msgstr "Totaalscore ${project}" #: /src/schooltool/cando/project.py:229 msgid "${project} percent passed" msgstr "" #: /src/schooltool/cando/project.py:273 msgid "${course} total points" msgstr "Totaalscore ${course}" #: /src/schooltool/cando/project.py:297 msgid "${course} percent passed" msgstr "" schooltool.cando-2.6.2/src/schooltool/cando/locales/th/0000755000175000017500000000000012322040274024212 5ustar menesismenesis00000000000000schooltool.cando-2.6.2/src/schooltool/cando/locales/th/LC_MESSAGES/0000755000175000017500000000000012322040274025777 5ustar menesismenesis00000000000000schooltool.cando-2.6.2/src/schooltool/cando/locales/th/LC_MESSAGES/schooltool.cando.mo0000644000175000017500000003477612322040274031625 0ustar menesismenesis00000000000000Þ•¶Ìû| hiqx | ‰ – ©°ÅÛ ìú !7H^xŒ’™³ Æ Óß èô#*: JX r"¢µÅÙî!$8P Uaj ‰ Žœ±Î ã ïú  ' 5AQdtƒž°À Ô)á  ';@GJj nzŠœ¼ÂÈØêñ! 2 > HVYmƒ•š « ¶ÁÇ×à ïü  %-=NW`gn uƒœ·¿ÈÍÔ Úç ù28 ?MU+dŸ1®à"é  #1 : DO g q~…• ¦´¼ÄËGÚI"l„‰ ¾ÓÙõ ú  ( 2=RZ_'c ‹ ™¤§$L*qœ¬!Å$ç (0A0r*£Î$ê-*=0h0™3ÊþE03vªÀ ÖãHö??  '˜ *À $ë ?!0P!c!å!*þ!3)"0]"-Ž"E¼"3#66#m#€#™#?¬#ì#ÿ#6$*F$9q$*«$$Ö$û$-%H%$g%9Œ%Æ%-å%!&35&$i&3Ž&-Â&ð&3'C'u_''Õ'ý'($2(W( s( €(f(?ô(f4)Z›)3ö)?**j*‰*Ÿ*-»*é*-ÿ*f-+0”+0Å+*ö+-!, O,$Y,-~,0¬, Ý,ê, -(- D-$Q-0v-*§-lÒ-?.[.z.™.µ.3Ë.-ÿ.-/E/3[//¢/²/KÈ/T0i0|00¢0»0Ë0?ç0''1CO1“1£1Â1á1E2*F2*q2rœ2$3L43$3-¦3-Ô344=4H\4¥4*Ä4$ï4!5!65X5\5u5Ž5Gª5{ò5±n6" 7C7*\73‡7»7Ú78ù728H80g8*˜8!Ã8$å86 9A9]9 d9Qn9À9ß9{ª1B ³i,‚Dk)P“Sb±–6‹„\43U‡Hm#E—š@¦/o"Xp†«I¤ ´M°RA%$'…&©dtƒ^~*!K[¬¨˜•x7žŸv=:§’  `V+Q¢ˆj¡yrc²ŒfzhF”®n 2 ?-W›‘.­G; <}09L(w>8uq¥eT5Yµaœ™¯Ž_жJOCN|Zsgl‰£]€ActionsActiveAddAdd ${layer}Add DocumentAdd LayerAdd NodeAssignAssign Course SkillsAssign Courses SkillsAssign Skill SetAssign SkillsAssigned SkillsAvailable child layersAvailable child nodesAvailable layersAvailable node layersAvailable node skill setsBatch Assign SkillsCanDoCancelCertificate of CompetencyChange informationChild layersChild nodesChildrenColor CodesColor Codes HelpCouldn't find a matching nodeCourseCourse MatchingCourse ProjectsCourse SkillsCourse attribute is emptyCourse fieldCourse has skills assigned alreadyCourse: ${courses}Courses matchedCourses not matchedCurrent child layersCurrent child nodesCurrent document hierarchy layersCurrent node layersCurrent node skill setsDateDescriptionDocumentDocument InformationDocumentsEditEdit ChildrenEdit Hierarchy LayerEdit Hierarchy Layer ParentsEdit Layer HierarchyEdit LayersEdit SkillEdit Skill SetsEdit SkillsEdit child nodesEdit childrenEdit layersEdit skill setsEdit this DocumentEdit this LayerEdit this NodeEdit this plan informationEdit this projectEdit this skillEdit this skill setEnter SkillsExport global skills data for the school.External IDFieldFile TypeGeneral InformationHelpHiddenIDID, title, label or descriptionIEPIEP DetailsIEP InformationImport Skill DataIndividualized Educational PlanLabelLayerLayer HierarchyLayer InformationLayersLayers ContainerLimit to 7 characters or less.My Skills GradesNew ProjectNew SkillNew Skill SetNoNo Visible ProjectsNo Visible Skill SetsNo layer assignedNodeNode InformationNode fieldNode layerNodesNodes ContainerOptionalOptional (IEP)Optional IEPOrderParent layersParent nodesParentsProjectProject DetailsProject deployedProject1ProjectsRatingReasonRemoveRemove SkillsReorder or Hide ProjectsReorder or Hide Skill SetsReportsRequiredSaveSchoolScoreScore SystemScore System HelpScoresystemScroll over a skill ID to see its description hereSearchSearch SkillsSectionSection SkillsSelect Skill Sets from ${node} (${node_id})Select a fieldSelect a layerSelect a minimum display score for ${scoresystem}SettingsShowing ${count} of ${total} itemsSkillSkill Color CodeSkill DetailsSkill IDSkill SetSkill SetsSkill is no longer usedSkill setSkill set IDSkillsSkills DocumentSkills DocumentsSkills ExportSort byStudentSubmitSubmit and addSummary of a student's scores for all the skills assigned to a section.Summary of all students' scores for all the skills assigned to a section.Teacher(s): ${teachers}TermThe skill scoresystem.There are no skills assigned.There are no skills.TitleTitle, description or labelViewView ${layer}View Hierarchy LayerView LayerView NodeView SkillView Skills DocumentVisibleYearYesYou must select at least one skill set.cancel-buttonsubmit-buttonProject-Id-Version: schooltool.cando Report-Msgid-Bugs-To: FULL NAME POT-Creation-Date: 2013-10-10 16:06+0300 PO-Revision-Date: 2013-03-27 14:27+0000 Last-Translator: mathinan Language-Team: Thai MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Launchpad-Export-Date: 2013-10-11 05:28+0000 X-Generator: Launchpad (build 16799) à¸à¸²à¸£à¸”ำเนินà¸à¸²à¸£à¹€à¸›à¸´à¸”ใช้งานอยู่เพิ่มเพิ่ม ${layer}เพิ่มเอà¸à¸ªà¸²à¸£à¹€à¸žà¸´à¹ˆà¸¡à¸Šà¸±à¹‰à¸™à¸‡à¸²à¸™à¹€à¸žà¸´à¹ˆà¸¡à¹‚หนดà¸à¸³à¸«à¸™à¸”ใช้ระบุทัà¸à¸©à¸°à¸£à¸²à¸¢à¸§à¸´à¸Šà¸²à¸£à¸°à¸šà¸¸à¸—ัà¸à¸©à¸°à¸‚องวิชาระบุà¸à¸¥à¸¸à¹ˆà¸¡à¸—ัà¸à¸©à¸°à¸£à¸°à¸šà¸¸à¸—ัà¸à¸©à¸°à¸—ัà¸à¸©à¸°à¸—ี่ระบุระดับลูà¸à¸—ี่ว่างโหนดลูà¸à¸—ี่ว่างลำดับชั้นที่ว่างระดับโหนดที่ว่างà¸à¸¥à¸¸à¹ˆà¸¡à¸—ัà¸à¸©à¸°à¸—ี่ว่างชุดทัà¸à¸©à¸°CanDoยà¸à¹€à¸¥à¸´à¸à¸›à¸£à¸°à¸à¸²à¸¨à¸™à¸µà¸¢à¸šà¸±à¸•รความสามารถเปลี่นนà¹à¸›à¸¥à¸‡à¸‚้อมูลชั้นลูà¸à¹‚หนดลูà¸à¸šà¸¸à¸•รรหัสสีà¸à¸²à¸£à¸Šà¹ˆà¸§à¸¢à¹€à¸«à¸¥à¸·à¸­à¹€à¸£à¸·à¹ˆà¸­à¸‡à¸£à¸«à¸±à¸ªà¸ªà¸µà¹„ม่พบโหนดที่ตรงà¸à¸±à¸™à¹„ด้หลัà¸à¸ªà¸¹à¸•รà¸à¸²à¸£à¸ˆà¸±à¸šà¸„ู่วิชาโครงà¸à¸²à¸£à¸£à¸²à¸¢à¸§à¸´à¸Šà¸²à¸—ัà¸à¸©à¸°à¸£à¸²à¸¢à¸§à¸´à¸Šà¸²à¹„ม่มีคุณลัà¸à¸©à¸“ะรายวิชาคูณลัà¸à¸©à¸“ะรายวิชาวิชาได้ถูà¸à¸£à¸°à¸šà¸¸à¸—ัà¸à¸©à¸°à¹€à¸£à¸µà¸¢à¸šà¸£à¹‰à¸­à¸¢à¹à¸¥à¹‰à¸§à¹„วิชา: ${courses}หลัà¸à¸ªà¸¹à¸•รตรงà¸à¸±à¸™à¸«à¸¥à¸±à¸à¸ªà¸¹à¸•รไม่ตรงà¸à¸±à¸™à¸£à¸°à¸”ับลูà¸à¸›à¸±à¸ˆà¸ˆà¸¸à¸šà¸±à¸™à¹‚หนดลูà¸à¸›à¸±à¸ˆà¸ˆà¸¸à¸šà¸±à¸™à¸¥à¸³à¸”ับชั้นเอà¸à¸ªà¸²à¸£à¸›à¸±à¸ˆà¸ˆà¸¸à¸šà¸±à¸™à¸£à¸°à¸”ับโหนดปัจจุบันà¸à¸¥à¸¸à¹ˆà¸¡à¸—ัà¸à¸©à¸°à¸›à¸±à¸ˆà¸ˆà¸¸à¸šà¸±à¸™à¸§à¸±à¸™à¸—ี่คำอธิบายเอà¸à¸ªà¸²à¸£à¸‚้อมูลเà¸à¸µà¹ˆà¸¢à¸§à¸à¸±à¸šà¹€à¸­à¸à¸ªà¸²à¸£à¹€à¸­à¸à¸ªà¸²à¸£à¹à¸à¹‰à¹„ขà¹à¸à¹‰à¹„ขข้อมูลของเด็à¸à¹à¸à¹‰à¹„ขลำดับชั้นà¹à¸à¹‰à¹„ขลำดับช้นพ่อà¹à¸¡à¹ˆà¹à¸à¹‰à¹„ขลำดับชั้นà¹à¸à¹‰à¹„ขชั้นงานà¹à¸à¹‰à¹„ขทัà¸à¸©à¸°à¹à¸à¹‰à¹„ขà¸à¸¥à¸¸à¹ˆà¸¡à¸—ัà¸à¸©à¸°à¹à¸à¹‰à¹„ขทัà¸à¸©à¸°à¹à¸à¹‰à¹„ขโหนดลูà¸à¹à¸à¹‰à¹„ขข้อมูลนัà¸à¹€à¸£à¸µà¸¢à¸™à¹à¸à¹‰à¹„ขลำดับà¹à¸à¹‰à¹„ขà¸à¸¥à¸¸à¹ˆà¸¡à¸—ัà¸à¸©à¸°à¹à¸à¹‰à¹„ขเอà¸à¸ªà¸²à¸£à¹à¸à¹‰à¹„ขลำดับชั้นนี้à¹à¸à¹‰à¹„ขโหนดนี้à¹à¸à¹‰à¹„ขข้อมูลของà¹à¸œà¸™à¹à¸à¹‰à¹„ขโครงà¸à¸²à¸£à¸™à¸µà¹‰à¹à¸à¹‰à¹„ขทัà¸à¸©à¸°à¹à¸à¹‰à¹„ขà¸à¸¥à¸¸à¸¡à¸—ัà¸à¸©à¸°à¸™à¸µà¹‰à¸à¸£à¸­à¸à¸—ัà¸à¸©à¸°à¸™à¸³à¸‚้อมูลทัà¸à¸©à¸°à¸ªà¸³à¸«à¸£à¸±à¸šà¹‚รงเรียนออà¸à¸ªà¸¹à¹ˆà¸ à¸²à¸¢à¸™à¸­à¸à¸£à¸«à¸±à¸ªà¸ˆà¸²à¸à¸ à¸²à¸¢à¸™à¸­à¸à¸„ุณลัà¸à¸©à¸“ะชนิดไฟล์ข้อมูลทั่วไปช่วยเหลือซ่อนรหัสรหัส ชื่อเรื่อง ข้อความ หรือคำอธิบายà¹à¸œà¸™à¸à¸²à¸£à¹€à¸£à¸µà¸¢à¸™à¹€à¸‰à¸žà¸²à¸°à¸šà¸¸à¸„คลรายละเอียดของà¹à¸œà¸™à¸à¸²à¸£à¹€à¸£à¸µà¸¢à¸™à¹€à¸‰à¸žà¸²à¸°à¸šà¸¸à¸„คลข้อมูลของà¹à¸œà¸™à¸à¸²à¸£à¹€à¸£à¸µà¸¢à¸™à¹€à¸‰à¸žà¸²à¸°à¸šà¸¸à¸„คลนำเข้าข้อมูลทัà¸à¸©à¸°à¹à¸œà¸™à¸à¸²à¸£à¹€à¸£à¸µà¸¢à¸™à¹€à¸‰à¸žà¸²à¸°à¸šà¸¸à¸„คลà¹à¸–บข้อความชั้นงานลำดับชั้นลำดับชั้นข้อมูลชั้นงานที่บรรจุชั้นงานจำà¸à¸±à¸”จำนวนที่ 7 ตัวอัà¸à¸©à¸£à¸«à¸£à¸·à¸­à¸™à¹‰à¸­à¸¢à¸à¸§à¹ˆà¸²à¸£à¸°à¸”ับทัà¸à¸©à¸°à¸‚องฉันเพิ่มโครงà¸à¸²à¸£à¹ƒà¸«à¸¡à¹ˆà¹€à¸žà¸´à¹ˆà¸¡à¸—ัà¸à¸©à¸°à¹ƒà¸«à¸¡à¹ˆà¹€à¸žà¸´à¹ˆà¸¡à¸à¸¥à¸¸à¹ˆà¸¡à¸—ัà¸à¸©à¸°à¹„ม่ไม่พบโครงà¸à¸²à¸£à¹„ม่พบà¸à¸¥à¸¸à¹ˆà¸¡à¸—ัà¸à¸©à¸°à¹„ม่ระบุลำดับชั้นโหนดข้อมูลโหนดลัà¸à¸©à¸“ะโหนดระดับโหนดโหนดที่บรรจุโหนดซึ่งเป็นทางเลือà¸à¹€à¸›à¹‡à¸™à¸•ัวเลือภ(IEP)à¹à¸œà¸™à¸à¸²à¸£à¹€à¸£à¸µà¸¢à¸™à¹€à¸‰à¸žà¸²à¸°à¸šà¸¸à¸„คลสามารถยà¸à¹€à¸§à¹‰à¸™à¹„ด้ลำดับชั้นชั้นพ่อà¹à¸¡à¹ˆà¹‚หนดพ่อà¹à¸¡à¹ˆà¸œà¸¹à¹‰à¸›à¸à¸„รองโครงà¸à¸²à¸£à¸£à¸²à¸¢à¸¥à¸°à¹€à¸­à¸µà¸¢à¸”โครงà¸à¸²à¸£à¹‚ครงà¸à¸²à¸£à¸—ี่นำออà¸à¹‚ครงà¸à¸²à¸£ 1โครงà¸à¸²à¸£à¸ˆà¸±à¸”อันดับความพอใจเหตุผลลบออà¸à¸¥à¸šà¸—ัà¸à¸©à¸°à¹€à¸£à¸µà¸¢à¸‡à¸¥à¸³à¸”ับหรือซ่อนโครงà¸à¸²à¸£à¹€à¸£à¸µà¸¢à¸‡à¸¥à¸³à¸”ับหรือซ่อนà¸à¸¥à¸¸à¹ˆà¸¡à¸—ัà¸à¸©à¸°à¸£à¸²à¸¢à¸‡à¸²à¸™à¸ˆà¸³à¹€à¸›à¹‡à¸™à¸šà¸±à¸™à¸—ึà¸à¹‚รงเรียนคะà¹à¸™à¸™à¸£à¸°à¸šà¸šà¸„ะà¹à¸™à¸™à¸à¸²à¸£à¸Šà¹ˆà¸§à¸¢à¹€à¸«à¸¥à¸·à¸­à¸£à¸°à¸šà¸šà¸„ะà¹à¸™à¸™à¸£à¸°à¸šà¸šà¹à¸ªà¸”งคะà¹à¸™à¸™à¹„ปยัง skill ID เพื่อดูคอธิบายค้นหาค้นหาทัà¸à¸©à¸°à¸«à¸±à¸§à¸‚้อย่อยà¸à¸¥à¸¸à¹ˆà¸¡à¸—ัà¸à¸©à¸°à¹€à¸¥à¸·à¸­à¸à¸Šà¸¸à¸”ทัà¸à¸©à¸°à¸ˆà¸²à¸ ${node} (${node_id})เลือà¸à¸„ุณสมบัติเลือà¸à¸£à¸°à¸”ับชั้นเลือà¸à¹à¸ªà¸”งคะà¹à¸™à¸™à¸—ี่น้อยที่สุดสำหรับ ${scoresystem}ตั้งค่าต่างๆà¸à¸³à¸¥à¸±à¸‡à¹à¸ªà¸”ง ${count} ของ ${total} รายà¸à¸²à¸£à¸—ัà¸à¸©à¸°à¸„วามรู้ทัà¸à¸©à¸°à¸”้านรหัสสีรายละเอียดทัà¸à¸©à¸°à¸£à¸«à¸±à¸ªà¸—ัà¸à¸©à¸°à¸à¸¥à¸¸à¹ˆà¸¡à¸—ัà¸à¸©à¸°à¸à¸¥à¸¸à¹ˆà¸¡à¸—ัà¸à¸©à¸°à¸—ัà¸à¸©à¸°à¸—ี่ไม่ได้ใช้นานà¹à¸¥à¹‰à¸§à¸à¸¥à¸¸à¹ˆà¸¡à¸—ัà¸à¸©à¸°à¸£à¸«à¸±à¸ªà¸à¸¥à¸¸à¹‰à¸¡à¸—ัà¸à¸©à¸°à¸—ัà¸à¸©à¸°à¸„วามรู้เอà¸à¸ªà¸²à¸£à¸—ัà¸à¸©à¸°à¹€à¸­à¸à¸ªà¸²à¸£à¸—ัà¸à¸©à¸°à¸ªà¹€à¸£à¸µà¸¢à¸‡à¸•ามนัà¸à¹€à¸£à¸µà¸¢à¸™à¸ªà¹ˆà¸‡à¸‚้อมูลส่งข้อมูล à¹à¸¥à¸° เพิ่มข้อมูลสรุปผลคะà¹à¸™à¸™à¸ªà¸³à¸«à¸£à¸±à¸šà¸—ุà¸à¸—ัà¸à¸©à¸°à¸—ี่ระบุในเซà¸à¸Šà¸±à¹ˆà¸™à¸œà¸¥à¸£à¸§à¸¡à¸„ะà¹à¸™à¸™à¸‚องนัà¸à¹€à¸£à¸µà¸¢à¸™à¸—ุà¸à¸„นในทุà¸à¸—ัà¸à¸©à¸°à¸—ี่มอบให้à¸à¸±à¸šà¸¡à¸—ุà¸à¹€à¸‹à¸à¸Šà¸±à¹ˆà¸™à¸­à¸²à¸ˆà¸²à¸£à¸¢à¹Œ: ${teachers}ภาคเรียนระบบคำนวณทัà¸à¸©à¸°à¹„ม่มีà¸à¸²à¸£à¸£à¸°à¸šà¸¸à¸—ัà¸à¸©à¸°à¹„ม่มีทัà¸à¸©à¸°à¸Šà¸·à¹ˆà¸­à¹€à¸£à¸·à¹ˆà¸­à¸‡à¸Šà¸·à¹ˆà¸­à¹€à¸£à¸·à¹ˆà¸­à¸‡, คำอธิบายเรียà¸à¸”ูเรียà¸à¸”ู ${layer}เรียà¸à¸”ูลำดับชั้นเรียà¸à¸”ูชั้นงานเรียà¸à¸”ูโหนดเรียà¸à¸”ูทัà¸à¸©à¸°à¹€à¸£à¸µà¸¢à¸à¸”ูเอà¸à¸ªà¸²à¸£à¸—ัà¸à¸©à¸°à¸›à¸£à¸²à¸à¸à¹€à¸«à¹‡à¸™à¸›à¸µà¹ƒà¸Šà¹ˆà¸„ุณต้องเลือà¸à¸­à¸¢à¹ˆà¸²à¸‡à¸™à¹‰à¸­à¸¢ 1 ทัà¸à¸©à¸°à¸›à¸¸à¹ˆà¸¡à¸¢à¸à¹€à¸¥à¸´à¸à¸›à¸¸à¹ˆà¸¡à¸¢à¸­à¸¡à¸£à¸±à¸šschooltool.cando-2.6.2/src/schooltool/cando/locales/th.po0000644000175000017500000012056012322023754024562 0ustar menesismenesis00000000000000# Thai translation for schooltool.cando # Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 # This file is distributed under the same license as the schooltool.cando package. # FIRST AUTHOR , 2013. # msgid "" msgstr "" "Project-Id-Version: schooltool.cando\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2013-10-10 16:06+0300\n" "PO-Revision-Date: 2013-03-27 14:27+0000\n" "Last-Translator: mathinan \n" "Language-Team: Thai \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2013-10-11 05:28+0000\n" "X-Generator: Launchpad (build 16799)\n" #: /src/schooltool/cando/browser/breadcrumbs.zcml:9 #: /src/schooltool/cando/browser/breadcrumbs.zcml:67 #: /src/schooltool/cando/browser/breadcrumbs.zcml:72 #: /src/schooltool/cando/browser/configure.zcml:135 #: /src/schooltool/cando/browser/configure.zcml:336 #: /src/schooltool/cando/browser/configure.zcml:779 #: /src/schooltool/cando/browser/course.py:162 #: /src/schooltool/cando/browser/document.py:815 #: /src/schooltool/cando/browser/document.zcml:26 #: /src/schooltool/cando/browser/gradebook.py:275 #: /src/schooltool/cando/browser/skill.py:76 #: /src/schooltool/cando/browser/templates/course_assign_skillsets_dialog.pt:30 #: /src/schooltool/cando/browser/templates/course_remove_skills.pt:20 #: /src/schooltool/cando/browser/templates/course_skills_overview.pt:4 #: /src/schooltool/cando/browser/templates/skillset.pt:77 msgid "Skills" msgstr "ทัà¸à¸©à¸°à¸„วามรู้" #: /src/schooltool/cando/browser/breadcrumbs.zcml:14 #: /src/schooltool/cando/browser/configure.zcml:40 #: /src/schooltool/cando/browser/course.py:292 #: /src/schooltool/cando/browser/document.py:122 #: /src/schooltool/cando/browser/gradebook.zcml:115 msgid "Skill Sets" msgstr "à¸à¸¥à¸¸à¹ˆà¸¡à¸—ัà¸à¸©à¸°" #: /src/schooltool/cando/browser/breadcrumbs.zcml:21 #: /src/schooltool/cando/browser/course.py:287 #: /src/schooltool/cando/browser/document.py:121 #: /src/schooltool/cando/browser/model.py:439 #: /src/schooltool/cando/browser/templates/course_assign_skills_table_filter.pt:34 #: /src/schooltool/cando/browser/templates/node.pt:155 #: /src/schooltool/cando/browser/templates/nodes_table_filter.pt:34 msgid "Layers" msgstr "ชั้นงาน" #: /src/schooltool/cando/browser/breadcrumbs.zcml:28 msgid "Nodes" msgstr "โหนด" #: /src/schooltool/cando/browser/configure.zcml:107 #: /src/schooltool/cando/browser/configure.zcml:162 #: /src/schooltool/cando/browser/configure.zcml:515 #: /src/schooltool/cando/browser/configure.zcml:642 #: /src/schooltool/cando/browser/course.py:223 #: /src/schooltool/cando/browser/course.py:225 #: /src/schooltool/cando/browser/document.zcml:61 #: /src/schooltool/cando/browser/document.zcml:185 #: /src/schooltool/cando/browser/document.zcml:220 #: /src/schooltool/cando/browser/document.zcml:303 #: /src/schooltool/cando/browser/gradebook.zcml:63 #: /src/schooltool/cando/browser/templates/course_assign_skillsets_dialog.pt:32 msgid "Add" msgstr "เพิ่ม" #: /src/schooltool/cando/browser/configure.zcml:117 #: /src/schooltool/cando/browser/configure.zcml:260 #: /src/schooltool/cando/browser/configure.zcml:795 msgid "Actions" msgstr "à¸à¸²à¸£à¸”ำเนินà¸à¸²à¸£" #: /src/schooltool/cando/browser/configure.zcml:127 msgid "Skill Set" msgstr "à¸à¸¥à¸¸à¹ˆà¸¡à¸—ัà¸à¸©à¸°" #: /src/schooltool/cando/browser/configure.zcml:135 msgid "New Skill Set" msgstr "เพิ่มà¸à¸¥à¸¸à¹ˆà¸¡à¸—ัà¸à¸©à¸°" #: /src/schooltool/cando/browser/configure.zcml:145 #: /src/schooltool/cando/browser/configure.zcml:199 #: /src/schooltool/cando/browser/configure.zcml:552 #: /src/schooltool/cando/browser/configure.zcml:679 #: /src/schooltool/cando/browser/document.zcml:98 #: /src/schooltool/cando/browser/document.zcml:194 #: /src/schooltool/cando/browser/document.zcml:253 #: /src/schooltool/cando/browser/document.zcml:312 #: /src/schooltool/cando/browser/document.zcml:345 #: /src/schooltool/cando/browser/gradebook.zcml:322 #: /src/schooltool/cando/browser/templates/document.pt:9 #: /src/schooltool/cando/browser/templates/layer.pt:109 #: /src/schooltool/cando/browser/templates/node.pt:21 #: /src/schooltool/cando/browser/templates/node.pt:126 #: /src/schooltool/cando/browser/templates/node.pt:164 #: /src/schooltool/cando/browser/templates/node.pt:201 msgid "Edit" msgstr "à¹à¸à¹‰à¹„ข" #: /src/schooltool/cando/browser/configure.zcml:171 #: /src/schooltool/cando/browser/document.py:166 #: /src/schooltool/cando/browser/document.py:388 #: /src/schooltool/cando/browser/document.py:397 #: /src/schooltool/cando/browser/gradebook.py:182 #: /src/schooltool/cando/browser/gradebook.py:197 #: /src/schooltool/cando/browser/gradebook.py:298 #: /src/schooltool/cando/browser/gradebook.py:924 #: /src/schooltool/cando/browser/model.py:137 #: /src/schooltool/cando/browser/skill.py:221 #: /src/schooltool/cando/browser/skill.py:279 #: /src/schooltool/cando/browser/skill.py:307 #: /src/schooltool/cando/browser/templates/edit_course_skills.pt:7 #: /src/schooltool/cando/browser/templates/student_competency_record.pt:9 msgid "Skill" msgstr "ทัà¸à¸©à¸°à¸„วามรู้" #: /src/schooltool/cando/browser/configure.zcml:181 #: /src/schooltool/cando/browser/gradebook.py:838 #: /src/schooltool/cando/browser/gradebook.zcml:187 msgid "New Skill" msgstr "เพิ่มทัà¸à¸©à¸°à¹ƒà¸«à¸¡à¹ˆ" #: /src/schooltool/cando/browser/configure.zcml:190 #: /src/schooltool/cando/browser/configure.zcml:461 msgid "View Skill" msgstr "เรียà¸à¸”ูทัà¸à¸©à¸°" #: /src/schooltool/cando/browser/configure.zcml:228 #: /src/schooltool/cando/browser/configure.zcml:395 msgid "Assigned Skills" msgstr "ทัà¸à¸©à¸°à¸—ี่ระบุ" #: /src/schooltool/cando/browser/configure.zcml:270 #: /src/schooltool/cando/browser/configure.zcml:345 msgid "Assign Skills" msgstr "ระบุทัà¸à¸©à¸°" #: /src/schooltool/cando/browser/configure.zcml:278 #: /src/schooltool/cando/browser/configure.zcml:353 msgid "Remove Skills" msgstr "ลบทัà¸à¸©à¸°" #: /src/schooltool/cando/browser/configure.zcml:298 #: /src/schooltool/cando/browser/configure.zcml:315 msgid "Set Required / Deprecated" msgstr "" #: /src/schooltool/cando/browser/configure.zcml:347 msgid "Assign Skill Set" msgstr "ระบุà¸à¸¥à¸¸à¹ˆà¸¡à¸—ัà¸à¸©à¸°" #: /src/schooltool/cando/browser/configure.zcml:404 msgid "Edit Skills" msgstr "à¹à¸à¹‰à¹„ขทัà¸à¸©à¸°" #: /src/schooltool/cando/browser/configure.zcml:488 #: /src/schooltool/cando/browser/configure.zcml:533 msgid "Layers Container" msgstr "ที่บรรจุชั้นงาน" #: /src/schooltool/cando/browser/configure.zcml:524 #: /src/schooltool/cando/browser/model.py:174 msgid "Layer" msgstr "ชั้นงาน" #: /src/schooltool/cando/browser/configure.zcml:533 msgid "Add Layer" msgstr "เพิ่มชั้นงาน" #: /src/schooltool/cando/browser/configure.zcml:543 msgid "View Layer" msgstr "เรียà¸à¸”ูชั้นงาน" #: /src/schooltool/cando/browser/configure.zcml:561 #: /src/schooltool/cando/browser/configure.zcml:688 msgid "Edit Children" msgstr "à¹à¸à¹‰à¹„ขข้อมูลของเด็à¸" #: /src/schooltool/cando/browser/configure.zcml:605 #: /src/schooltool/cando/browser/configure.zcml:660 msgid "Nodes Container" msgstr "ที่บรรจุโหนด" #: /src/schooltool/cando/browser/configure.zcml:605 #: /src/schooltool/cando/browser/document.py:123 #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:77 #: /src/schooltool/cando/browser/templates/nodes_table_filter.pt:53 msgid "Search" msgstr "ค้นหา" #: /src/schooltool/cando/browser/configure.zcml:625 msgid "Deprecate" msgstr "" #: /src/schooltool/cando/browser/configure.zcml:625 msgid "Documents and Skills" msgstr "" #: /src/schooltool/cando/browser/configure.zcml:766 #: /src/schooltool/cando/browser/model.py:398 #: /src/schooltool/cando/browser/model.py:427 #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:109 msgid "Node" msgstr "โหนด" #: /src/schooltool/cando/browser/configure.zcml:660 msgid "Add Node" msgstr "เพิ่มโหนด" #: /src/schooltool/cando/browser/configure.zcml:670 msgid "View Node" msgstr "เรียà¸à¸”ูโหนด" #: /src/schooltool/cando/browser/configure.zcml:714 msgid "Edit Layers" msgstr "à¹à¸à¹‰à¹„ขชั้นงาน" #: /src/schooltool/cando/browser/configure.zcml:785 msgid "Edit Skill Sets" msgstr "à¹à¸à¹‰à¹„ขà¸à¸¥à¸¸à¹ˆà¸¡à¸—ัà¸à¸©à¸°" #: /src/schooltool/cando/browser/configure.zcml:825 #: /src/schooltool/cando/browser/configure.zcml:833 msgid "Import Skill Data" msgstr "นำเข้าข้อมูลทัà¸à¸©à¸°" #: /src/schooltool/cando/browser/configure.zcml:919 msgid "Deprecate Skills" msgstr "" #: /src/schooltool/cando/browser/configure.zcml:974 msgid "Batch Assign Skills" msgstr "ชุดทัà¸à¸©à¸°" #: /src/schooltool/cando/browser/configure.zcml:814 msgid "Assign Courses Skills" msgstr "ระบุทัà¸à¸©à¸°à¸‚องวิชา" #: /src/schooltool/cando/browser/course.py:156 #: /src/schooltool/cando/browser/course.py:277 #: /src/schooltool/cando/browser/course.py:571 #: /src/schooltool/cando/browser/document.py:869 #: /src/schooltool/cando/browser/model.py:432 #: /src/schooltool/cando/browser/templates/course_assign_skillsets_dialog.pt:29 #: /src/schooltool/cando/browser/templates/course_remove_skills.pt:19 #: /src/schooltool/cando/browser/templates/projects.pt:10 #: /src/schooltool/cando/browser/templates/skillsets.pt:10 #: /src/schooltool/cando/interfaces.py:72 #: /src/schooltool/cando/interfaces.py:89 msgid "Title" msgstr "ชื่อเรื่อง" #: /src/schooltool/cando/browser/course.py:260 msgid "Select Skill Sets from ${node} (${node_id})" msgstr "เลือà¸à¸Šà¸¸à¸”ทัà¸à¸©à¸°à¸ˆà¸²à¸ ${node} (${node_id})" #: /src/schooltool/cando/browser/course.py:282 msgid "ID" msgstr "รหัส" #: /src/schooltool/cando/browser/course.py:314 #: /src/schooltool/cando/browser/model.py:454 msgid "ID, title, label or description" msgstr "รหัส ชื่อเรื่อง ข้อความ หรือคำอธิบาย" #: /src/schooltool/cando/browser/course.py:576 #: /src/schooltool/cando/browser/course.py:635 #: /src/schooltool/cando/browser/document.py:880 #: /src/schooltool/cando/browser/model.py:427 #: /src/schooltool/cando/browser/skill.py:80 #: /src/schooltool/cando/browser/skill.py:209 #: /src/schooltool/cando/interfaces.py:63 #: /src/schooltool/cando/interfaces.py:96 msgid "Label" msgstr "à¹à¸–บข้อความ" #: /src/schooltool/cando/browser/course.py:581 #: /src/schooltool/cando/browser/document.py:875 #: /src/schooltool/cando/browser/templates/colorcodes_help.pt:10 #: /src/schooltool/cando/browser/templates/edit_course_skills.pt:9 #: /src/schooltool/cando/browser/templates/student_competency_record.pt:8 #: /src/schooltool/cando/interfaces.py:39 msgid "Required" msgstr "จำเป็น" #: /src/schooltool/cando/browser/course.py:587 msgid "Hidden" msgstr "ซ่อน" #: /src/schooltool/cando/browser/course.py:790 msgid "Course has skills assigned already" msgstr "วิชาได้ถูà¸à¸£à¸°à¸šà¸¸à¸—ัà¸à¸©à¸°à¹€à¸£à¸µà¸¢à¸šà¸£à¹‰à¸­à¸¢à¹à¸¥à¹‰à¸§à¹„" #: /src/schooltool/cando/browser/course.py:810 msgid "Couldn't find a matching node" msgstr "ไม่พบโหนดที่ตรงà¸à¸±à¸™à¹„ด้" #: /src/schooltool/cando/browser/course.py:816 msgid "Course attribute is empty" msgstr "ไม่มีคุณลัà¸à¸©à¸“ะรายวิชา" #: /src/schooltool/cando/browser/document.py:120 msgid "Documents" msgstr "เอà¸à¸ªà¸²à¸£" #: /src/schooltool/cando/browser/document.py:148 msgid "Document Information" msgstr "ข้อมูลเà¸à¸µà¹ˆà¸¢à¸§à¸à¸±à¸šà¹€à¸­à¸à¸ªà¸²à¸£" #: /src/schooltool/cando/browser/document.py:198 #: /src/schooltool/cando/browser/document.py:524 #: /src/schooltool/cando/browser/document.py:708 #: /src/schooltool/cando/browser/document.py:769 #: /src/schooltool/cando/browser/gradebook.py:352 #: /src/schooltool/cando/browser/gradebook.py:471 #: /src/schooltool/cando/browser/iep.py:131 #: /src/schooltool/cando/browser/model.py:103 #: /src/schooltool/cando/browser/model.py:177 #: /src/schooltool/cando/browser/model.py:321 #: /src/schooltool/cando/browser/model.py:396 #: /src/schooltool/cando/browser/skill.py:179 #: /src/schooltool/cando/browser/skill.py:235 #: /src/schooltool/cando/browser/skill.py:327 #: /src/schooltool/cando/browser/templates/course_skills_edit_table_buttons.pt:5 msgid "Submit" msgstr "ส่งข้อมูล" #: /src/schooltool/cando/browser/document.py:186 #: /src/schooltool/cando/browser/document.py:465 #: /src/schooltool/cando/browser/document.py:645 #: /src/schooltool/cando/browser/document.py:709 #: /src/schooltool/cando/browser/gradebook.py:321 #: /src/schooltool/cando/browser/gradebook.py:444 #: /src/schooltool/cando/browser/model.py:106 #: /src/schooltool/cando/browser/model.py:183 #: /src/schooltool/cando/browser/model.py:324 #: /src/schooltool/cando/browser/model.py:403 #: /src/schooltool/cando/browser/skill.py:180 #: /src/schooltool/cando/browser/skill.py:238 #: /src/schooltool/cando/browser/skill.py:316 #: /src/schooltool/cando/browser/templates/course_skills_edit_table_buttons.pt:8 #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:79 #: /src/schooltool/cando/browser/templates/grade_student.pt:39 msgid "Cancel" msgstr "ยà¸à¹€à¸¥à¸´à¸" #: /src/schooltool/cando/browser/document.py:429 #: /src/schooltool/cando/browser/document.py:571 #: /src/schooltool/cando/browser/document.py:816 msgid "${layer} list" msgstr "" #: /src/schooltool/cando/browser/document.py:450 #: /src/schooltool/cando/browser/document.zcml:70 msgid "Document" msgstr "เอà¸à¸ªà¸²à¸£" #: /src/schooltool/cando/browser/document.py:477 msgid "Current document hierarchy layers" msgstr "ลำดับชั้นเอà¸à¸ªà¸²à¸£à¸›à¸±à¸ˆà¸ˆà¸¸à¸šà¸±à¸™" #: /src/schooltool/cando/browser/document.py:478 msgid "Available layers" msgstr "ลำดับชั้นที่ว่าง" #: /src/schooltool/cando/browser/document.py:566 #: /src/schooltool/cando/browser/document.py:808 #: /src/schooltool/cando/browser/document.py:961 msgid "View ${layer}" msgstr "เรียà¸à¸”ู ${layer}" #: /src/schooltool/cando/browser/document.py:624 #: /src/schooltool/cando/browser/document.py:744 #: /src/schooltool/cando/browser/document.py:921 msgid "Add ${layer}" msgstr "เพิ่ม ${layer}" #: /src/schooltool/cando/browser/document.py:629 #: /src/schooltool/cando/browser/document.py:916 msgid "${layer} Information" msgstr "" #: /src/schooltool/cando/browser/document.py:673 msgid "Skills Document" msgstr "เอà¸à¸ªà¸²à¸£à¸—ัà¸à¸©à¸°" #: /src/schooltool/cando/browser/document.py:695 msgid "Change information" msgstr "เปลี่นนà¹à¸›à¸¥à¸‡à¸‚้อมูล" #: /src/schooltool/cando/browser/document.py:928 #: /src/schooltool/cando/browser/gradebook.py:1594 msgid "No" msgstr "ไม่" #: /src/schooltool/cando/browser/document.py:928 #: /src/schooltool/cando/browser/gradebook.py:1594 msgid "Yes" msgstr "ใช่" #: /src/schooltool/cando/browser/document.zcml:35 #: /src/schooltool/cando/browser/document.zcml:79 msgid "Skills Documents" msgstr "เอà¸à¸ªà¸²à¸£à¸—ัà¸à¸©à¸°" #: /src/schooltool/cando/browser/document.zcml:79 msgid "Add Document" msgstr "เพิ่มเอà¸à¸ªà¸²à¸£" #: /src/schooltool/cando/browser/document.zcml:89 msgid "View Skills Document" msgstr "เรียà¸à¸”ูเอà¸à¸ªà¸²à¸£à¸—ัà¸à¸©à¸°" #: /src/schooltool/cando/browser/document.zcml:107 msgid "Edit Layer Hierarchy" msgstr "à¹à¸à¹‰à¹„ขลำดับชั้น" #: /src/schooltool/cando/browser/document.zcml:133 msgid "View Hierarchy Layer" msgstr "เรียà¸à¸”ูลำดับชั้น" #: /src/schooltool/cando/browser/document.zcml:142 msgid "Edit Hierarchy Layer" msgstr "à¹à¸à¹‰à¹„ขลำดับชั้น" #: /src/schooltool/cando/browser/document.zcml:151 msgid "Edit Hierarchy Layer Parents" msgstr "à¹à¸à¹‰à¹„ขลำดับช้นพ่อà¹à¸¡à¹ˆ" #: /src/schooltool/cando/browser/document.zcml:211 msgid "Layer Hierarchy" msgstr "ลำดับชั้น" #: /src/schooltool/cando/browser/gradebook.py:189 msgid "No Visible Projects" msgstr "ไม่พบโครงà¸à¸²à¸£" #: /src/schooltool/cando/browser/gradebook.py:191 #: /src/schooltool/cando/browser/gradebook.py:206 msgid "Enter Skills" msgstr "à¸à¸£à¸­à¸à¸—ัà¸à¸©à¸°" #: /src/schooltool/cando/browser/gradebook.py:204 msgid "No Visible Skill Sets" msgstr "ไม่พบà¸à¸¥à¸¸à¹ˆà¸¡à¸—ัà¸à¸©à¸°" #: /src/schooltool/cando/browser/gradebook.py:281 #: /src/schooltool/cando/browser/gradebook.zcml:98 #: /src/schooltool/cando/browser/gradebook.zcml:106 #: /src/schooltool/cando/project.py:163 msgid "Projects" msgstr "โครงà¸à¸²à¸£" #: /src/schooltool/cando/browser/gradebook.py:315 msgid "Project Details" msgstr "รายละเอียดโครงà¸à¸²à¸£" #: /src/schooltool/cando/browser/gradebook.py:358 msgid "Sort by" msgstr "เรียงตาม" #: /src/schooltool/cando/browser/gradebook.py:423 msgid "Skill Details" msgstr "รายละเอียดทัà¸à¸©à¸°" #: /src/schooltool/cando/browser/gradebook.py:518 msgid "${section} Skills" msgstr "" #: /src/schooltool/cando/browser/gradebook.py:520 msgid "${section} Project Skills" msgstr "" #: /src/schooltool/cando/browser/gradebook.py:529 msgid "Score System Help" msgstr "à¸à¸²à¸£à¸Šà¹ˆà¸§à¸¢à¹€à¸«à¸¥à¸·à¸­à¸£à¸°à¸šà¸šà¸„ะà¹à¸™à¸™" #: /src/schooltool/cando/browser/gradebook.py:537 msgid "Color Codes Help" msgstr "à¸à¸²à¸£à¸Šà¹ˆà¸§à¸¢à¹€à¸«à¸¥à¸·à¸­à¹€à¸£à¸·à¹ˆà¸­à¸‡à¸£à¸«à¸±à¸ªà¸ªà¸µ" #: /src/schooltool/cando/browser/gradebook.py:953 msgid "No layer assigned" msgstr "ไม่ระบุลำดับชั้น" #: /src/schooltool/cando/browser/gradebook.py:1236 msgid "Changes saved" msgstr "" #: /src/schooltool/cando/browser/gradebook.py:1392 #: /src/schooltool/cando/browser/gradebook.zcml:140 msgid "Search Skills" msgstr "ค้นหาทัà¸à¸©à¸°" #: /src/schooltool/cando/browser/gradebook.py:1450 msgid "Save" msgstr "บันทึà¸" #: /src/schooltool/cando/browser/gradebook.py:1466 #: /src/schooltool/cando/browser/templates/scoresystem_help.pt:5 msgid "Score" msgstr "คะà¹à¸™à¸™" #: /src/schooltool/cando/browser/gradebook.py:1561 #: /src/schooltool/cando/browser/gradebook.zcml:520 msgid "CanDo Gradebook" msgstr "" #: /src/schooltool/cando/browser/gradebook.py:1677 msgid "Date" msgstr "วันที่" #: /src/schooltool/cando/browser/gradebook.py:1606 #: /src/schooltool/cando/browser/templates/scoresystem_help.pt:6 msgid "Rating" msgstr "จัดอันดับความพอใจ" #: /src/schooltool/cando/browser/gradebook.py:1736 #: /src/schooltool/cando/browser/gradebook.py:1951 #: /src/schooltool/cando/browser/gradebook.zcml:770 msgid "Student Skill Report" msgstr "" #: /src/schooltool/cando/browser/gradebook.py:1759 msgid "Teacher(s): ${teachers}" msgstr "อาจารย์: ${teachers}" #: /src/schooltool/cando/browser/gradebook.py:1755 #: /src/schooltool/cando/browser/gradebook.py:1870 msgid "Course: ${courses}" msgstr "วิชา: ${courses}" #: /src/schooltool/cando/browser/gradebook.py:1847 #: /src/schooltool/cando/browser/gradebook.zcml:782 msgid "Certificate of Competency" msgstr "ประà¸à¸²à¸¨à¸™à¸µà¸¢à¸šà¸±à¸•รความสามารถ" #: /src/schooltool/cando/browser/gradebook.py:2288 msgid "skill gradebooks archive" msgstr "" #: /src/schooltool/cando/browser/gradebook.zcml:10 #: /src/schooltool/cando/browser/gradebook.zcml:26 #: /src/schooltool/cando/browser/gradebook.zcml:128 #: /src/schooltool/cando/browser/gradebook.zcml:223 #: /src/schooltool/cando/browser/gradebook.zcml:321 #: /src/schooltool/cando/browser/gradebook.zcml:431 msgid "CanDo" msgstr "CanDo" #: /src/schooltool/cando/browser/gradebook.zcml:45 msgid "View" msgstr "เรียà¸à¸”ู" #: /src/schooltool/cando/browser/gradebook.zcml:80 msgid "Project" msgstr "โครงà¸à¸²à¸£" #: /src/schooltool/cando/browser/gradebook.zcml:88 msgid "Settings" msgstr "ตั้งค่าต่างๆ" #: /src/schooltool/cando/browser/gradebook.zcml:126 msgid "New Project" msgstr "เพิ่มโครงà¸à¸²à¸£à¹ƒà¸«à¸¡à¹ˆ" #: /src/schooltool/cando/browser/gradebook.zcml:310 msgid "Edit Skill" msgstr "à¹à¸à¹‰à¹„ขทัà¸à¸©à¸°" #: /src/schooltool/cando/browser/gradebook.zcml:373 #: /src/schooltool/cando/browser/gradebook.zcml:637 #: /src/schooltool/cando/browser/gradebook.zcml:660 msgid "Help" msgstr "ช่วยเหลือ" #: /src/schooltool/cando/browser/gradebook.zcml:383 msgid "Score System" msgstr "ระบบคะà¹à¸™à¸™" #: /src/schooltool/cando/browser/gradebook.zcml:391 msgid "Color Codes" msgstr "รหัสสี" #: /src/schooltool/cando/browser/gradebook.zcml:492 msgid "Skills Pop-up" msgstr "" #: /src/schooltool/cando/browser/gradebook.zcml:546 msgid "My Skills Grades" msgstr "ระดับทัà¸à¸©à¸°à¸‚องฉัน" #: /src/schooltool/cando/browser/gradebook.zcml:579 msgid "My Projects Grades" msgstr "" #: /src/schooltool/cando/browser/gradebook.zcml:596 #: /src/schooltool/cando/browser/gradebook.zcml:827 #: /src/schooltool/cando/browser/gradebook.zcml:839 #: /src/schooltool/cando/browser/report.py:878 #: /src/schooltool/cando/browser/report.zcml:47 #: /src/schooltool/cando/browser/report.zcml:58 msgid "Section" msgstr "หัวข้อย่อย" #: /src/schooltool/cando/browser/gradebook.zcml:557 msgid "Term" msgstr "ภาคเรียน" #: /src/schooltool/cando/browser/gradebook.zcml:568 msgid "Year" msgstr "ปี" #: /src/schooltool/cando/browser/gradebook.zcml:760 msgid "Reports" msgstr "รายงาน" #: /src/schooltool/cando/browser/gradebook.zcml:770 msgid "" "Summary of a student's scores for all the skills assigned to a section." msgstr "สรุปผลคะà¹à¸™à¸™à¸ªà¸³à¸«à¸£à¸±à¸šà¸—ุà¸à¸—ัà¸à¸©à¸°à¸—ี่ระบุในเซà¸à¸Šà¸±à¹ˆà¸™" #: /src/schooltool/cando/browser/gradebook.zcml:770 #: /src/schooltool/cando/browser/gradebook.zcml:782 msgid "Student" msgstr "นัà¸à¹€à¸£à¸µà¸¢à¸™" #: /src/schooltool/cando/browser/gradebook.zcml:782 msgid "" "Summary of a student scores in a section exceeding a selected minimum score. " "Formatted for presentation to an potential employer or other person outside " "of the school." msgstr "" #: /src/schooltool/cando/browser/gradebook.zcml:794 #: /src/schooltool/cando/browser/gradebook.zcml:806 msgid "Aggregated Student Skill Reports" msgstr "" #: /src/schooltool/cando/browser/gradebook.zcml:794 msgid "" "Summary of all students' scores for all the skills assigned to a section." msgstr "ผลรวมคะà¹à¸™à¸™à¸‚องนัà¸à¹€à¸£à¸µà¸¢à¸™à¸—ุà¸à¸„นในทุà¸à¸—ัà¸à¸©à¸°à¸—ี่มอบให้à¸à¸±à¸šà¸¡à¸—ุà¸à¹€à¸‹à¸à¸Šà¸±à¹ˆà¸™" #: /src/schooltool/cando/browser/iep.py:122 msgid "IEP Details" msgstr "รายละเอียดของà¹à¸œà¸™à¸à¸²à¸£à¹€à¸£à¸µà¸¢à¸™à¹€à¸‰à¸žà¸²à¸°à¸šà¸¸à¸„คล" #: /src/schooltool/cando/browser/iep.py:176 msgid "IEP Skills for ${section}" msgstr "" #: /src/schooltool/cando/browser/iep.py:322 msgid "Edit IEP Skills for ${section}" msgstr "" #: /src/schooltool/cando/browser/iep.py:354 msgid "Optional IEP" msgstr "à¹à¸œà¸™à¸à¸²à¸£à¹€à¸£à¸µà¸¢à¸™à¹€à¸‰à¸žà¸²à¸°à¸šà¸¸à¸„คลสามารถยà¸à¹€à¸§à¹‰à¸™à¹„ด้" #: /src/schooltool/cando/browser/iep.py:424 msgid "IEP Information" msgstr "ข้อมูลของà¹à¸œà¸™à¸à¸²à¸£à¹€à¸£à¸µà¸¢à¸™à¹€à¸‰à¸žà¸²à¸°à¸šà¸¸à¸„คล" #: /src/schooltool/cando/browser/iep.zcml:8 msgid "IEP" msgstr "à¹à¸œà¸™à¸à¸²à¸£à¹€à¸£à¸µà¸¢à¸™à¹€à¸‰à¸žà¸²à¸°à¸šà¸¸à¸„คล" #: /src/schooltool/cando/browser/iep.zcml:17 #: /src/schooltool/cando/browser/iep.zcml:52 msgid "Individualized Educational Plan" msgstr "à¹à¸œà¸™à¸à¸²à¸£à¹€à¸£à¸µà¸¢à¸™à¹€à¸‰à¸žà¸²à¸°à¸šà¸¸à¸„คล" #: /src/schooltool/cando/browser/importer.py:44 msgid "has an invalid document id" msgstr "" #: /src/schooltool/cando/browser/importer.py:45 msgid "has an invalid parent id" msgstr "" #: /src/schooltool/cando/browser/importer.py:46 msgid "has an invalid layer id" msgstr "" #: /src/schooltool/cando/browser/importer.py:47 msgid "has an invalid skillset id" msgstr "" #: /src/schooltool/cando/browser/importer.py:48 msgid "is missing a skillset id" msgstr "" #: /src/schooltool/cando/browser/importer.py:49 msgid "has an invalid equivalent skill id" msgstr "" #: /src/schooltool/cando/browser/importer.py:50 msgid "node label has more than seven characters" msgstr "" #: /src/schooltool/cando/browser/importer.py:51 msgid "has an invalid scoresystem" msgstr "" #: /src/schooltool/cando/browser/importer.py:52 msgid "has an invalid node id" msgstr "" #: /src/schooltool/cando/browser/model.py:94 msgid "Layer Information" msgstr "ลำดับชั้นข้อมูล" #: /src/schooltool/cando/browser/model.py:209 msgid "Parents" msgstr "ผู้ปà¸à¸„รอง" #: /src/schooltool/cando/browser/model.py:214 msgid "Children" msgstr "บุตร" #: /src/schooltool/cando/browser/model.py:257 msgid "Current child layers" msgstr "ระดับลูà¸à¸›à¸±à¸ˆà¸ˆà¸¸à¸šà¸±à¸™" #: /src/schooltool/cando/browser/model.py:258 msgid "Available child layers" msgstr "ระดับลูà¸à¸—ี่ว่าง" #: /src/schooltool/cando/browser/model.py:307 msgid "Node Information" msgstr "ข้อมูลโหนด" #: /src/schooltool/cando/browser/model.py:546 msgid "Current child nodes" msgstr "โหนดลูà¸à¸›à¸±à¸ˆà¸ˆà¸¸à¸šà¸±à¸™" #: /src/schooltool/cando/browser/model.py:547 msgid "Available child nodes" msgstr "โหนดลูà¸à¸—ี่ว่าง" #: /src/schooltool/cando/browser/model.py:584 msgid "Current node layers" msgstr "ระดับโหนดปัจจุบัน" #: /src/schooltool/cando/browser/model.py:585 msgid "Available node layers" msgstr "ระดับโหนดที่ว่าง" #: /src/schooltool/cando/browser/model.py:641 msgid "Current node skill sets" msgstr "à¸à¸¥à¸¸à¹ˆà¸¡à¸—ัà¸à¸©à¸°à¸›à¸±à¸ˆà¸ˆà¸¸à¸šà¸±à¸™" #: /src/schooltool/cando/browser/model.py:642 msgid "Available node skill sets" msgstr "à¸à¸¥à¸¸à¹ˆà¸¡à¸—ัà¸à¸©à¸°à¸—ี่ว่าง" #: /src/schooltool/cando/browser/report.py:199 msgid "All" msgstr "" #: /src/schooltool/cando/browser/report.py:199 msgid "Evaluated" msgstr "" #: /src/schooltool/cando/browser/report.py:380 msgid "% of Skills Below and Above Passing" msgstr "" #: /src/schooltool/cando/browser/report.py:406 msgid "Students (${count})" msgstr "" #: /src/schooltool/cando/browser/report.py:480 msgid "Student ID #" msgstr "" #: /src/schooltool/cando/browser/report.py:640 #: /src/schooltool/cando/browser/templates/section_report_score_colors.pt:19 msgid "Score Colors" msgstr "" #: /src/schooltool/cando/browser/report.py:814 msgid "Totals" msgstr "" #: /src/schooltool/cando/browser/report.py:866 #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:88 #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:107 #: /src/schooltool/cando/browser/templates/section_report_details.pt:8 msgid "Course" msgstr "หลัà¸à¸ªà¸¹à¸•ร" #: /src/schooltool/cando/browser/report.py:874 #: /src/schooltool/cando/browser/templates/section_report_details.pt:16 msgid "Teachers" msgstr "" #: /src/schooltool/cando/browser/report.zcml:21 msgid "Export global skills data for the school." msgstr "นำข้อมูลทัà¸à¸©à¸°à¸ªà¸³à¸«à¸£à¸±à¸šà¹‚รงเรียนออà¸à¸ªà¸¹à¹ˆà¸ à¸²à¸¢à¸™à¸­à¸" #: /src/schooltool/cando/browser/report.zcml:10 msgid "School" msgstr "โรงเรียน" #: /src/schooltool/cando/browser/report.zcml:10 msgid "Skills Export" msgstr "ส" #: /src/schooltool/cando/browser/report.zcml:47 #: /src/schooltool/cando/browser/report.zcml:58 msgid "" "An overview of each student's achievement of skills within the section." msgstr "" #: /src/schooltool/cando/browser/report.zcml:47 #: /src/schooltool/cando/browser/report.zcml:58 #: /src/schooltool/cando/browser/report.zcml:88 #: /src/schooltool/cando/browser/report.zcml:244 msgid "Per Student Skills" msgstr "" #: /src/schooltool/cando/browser/report.zcml:70 msgid "An overview of each section's aggregate achievement of skills." msgstr "" #: /src/schooltool/cando/browser/report.zcml:70 msgid "Skills Completion" msgstr "" #: /src/schooltool/cando/browser/report.zcml:191 msgid "Passing Score" msgstr "" #: /src/schooltool/cando/browser/report.zcml:208 msgid "Type" msgstr "" #: /src/schooltool/cando/browser/report.zcml:226 #: /src/schooltool/cando/browser/templates/section_report_score_colors.pt:28 msgid "% Passing Target" msgstr "" #: /src/schooltool/cando/browser/report.zcml:252 msgid "Skills Completion Report" msgstr "" #: /src/schooltool/cando/browser/report.zcml:298 msgid "Location" msgstr "" #: /src/schooltool/cando/browser/report.zcml:360 msgid "Skill Gradebooks" msgstr "" #: /src/schooltool/cando/browser/report.zcml:369 msgid "Archive all student skill gradebooks." msgstr "" #: /src/schooltool/cando/browser/report.zcml:369 msgid "Skill Gradebook Archive" msgstr "" #: /src/schooltool/cando/browser/skill.py:98 msgid "Title, description or label" msgstr "ชื่อเรื่อง, คำอธิบาย" #: /src/schooltool/cando/browser/skill.py:125 #: /src/schooltool/cando/browser/skill.py:171 msgid "Skill set" msgstr "à¸à¸¥à¸¸à¹ˆà¸¡à¸—ัà¸à¸©à¸°" #: /src/schooltool/cando/browser/skill.py:232 msgid "Submit and add" msgstr "ส่งข้อมูล à¹à¸¥à¸° เพิ่มข้อมูล" #: /src/schooltool/cando/browser/skill.py:386 #: /src/schooltool/cando/browser/templates/colorcodes_help.pt:13 msgid "Optional" msgstr "ซึ่งเป็นทางเลือà¸" #: /src/schooltool/cando/browser/templates/cando_third_nav.pt:2 msgid "Scroll over a skill ID to see its description here" msgstr "ไปยัง skill ID เพื่อดูคอธิบาย" #: /src/schooltool/cando/browser/templates/colorcodes_help.pt:5 msgid "Skill Color Code" msgstr "ทัà¸à¸©à¸°à¸”้านรหัสสี" #: /src/schooltool/cando/browser/templates/colorcodes_help.pt:16 msgid "Optional (IEP)" msgstr "เป็นตัวเลือภ(IEP)" #: /src/schooltool/cando/browser/templates/course_assign_skills_table_filter.pt:12 #: /src/schooltool/cando/browser/templates/nodes_table_filter.pt:12 msgid "Showing ${count} of ${total} items" msgstr "à¸à¸³à¸¥à¸±à¸‡à¹à¸ªà¸”ง ${count} ของ ${total} รายà¸à¸²à¸£" #: /src/schooltool/cando/browser/templates/course_assign_skillsets_dialog.pt:20 msgid "You must select at least one skill set." msgstr "คุณต้องเลือà¸à¸­à¸¢à¹ˆà¸²à¸‡à¸™à¹‰à¸­à¸¢ 1 ทัà¸à¸©à¸°" #. Default: "Submit" #: /src/schooltool/cando/browser/templates/course_assign_skillsets_dialog.pt:69 #: /src/schooltool/cando/browser/templates/course_remove_skills.pt:59 #: /src/schooltool/cando/browser/templates/edit_course_skills.pt:45 msgid "submit-button" msgstr "ปุ่มยอมรับ" #. Default: "Cancel" #: /src/schooltool/cando/browser/templates/course_assign_skillsets_dialog.pt:73 #: /src/schooltool/cando/browser/templates/course_remove_skills.pt:62 #: /src/schooltool/cando/browser/templates/edit_course_skills.pt:48 msgid "cancel-button" msgstr "ปุ่มยà¸à¹€à¸¥à¸´à¸" #: /src/schooltool/cando/browser/templates/course_remove_skills.pt:22 msgid "Remove" msgstr "ลบออà¸" #: /src/schooltool/cando/browser/templates/course_skills_overview.pt:4 msgid "Assign Course Skills" msgstr "ระบุทัà¸à¸©à¸°à¸£à¸²à¸¢à¸§à¸´à¸Šà¸²" #: /src/schooltool/cando/browser/templates/course_skills_overview.pt:13 msgid "There are ${count} sets of skills assigned." msgstr "" #: /src/schooltool/cando/browser/templates/course_skills_overview.pt:16 msgid "There are no skills assigned." msgstr "ไม่มีà¸à¸²à¸£à¸£à¸°à¸šà¸¸à¸—ัà¸à¸©à¸°" #: /src/schooltool/cando/browser/templates/course_skillset.pt:4 #: /src/schooltool/cando/browser/templates/document_skillset.pt:4 #: /src/schooltool/cando/browser/templates/skillset.pt:4 #: /src/schooltool/cando/browser/templates/skillsets.pt:34 msgid "Edit this skill set" msgstr "à¹à¸à¹‰à¹„ขà¸à¸¥à¸¸à¸¡à¸—ัà¸à¸©à¸°à¸™à¸µà¹‰" #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:10 msgid "Course Matching" msgstr "à¸à¸²à¸£à¸ˆà¸±à¸šà¸„ู่วิชา" #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:15 msgid "Course field" msgstr "คูณลัà¸à¸©à¸“ะรายวิชา" #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:21 #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:63 msgid "Select a field" msgstr "เลือà¸à¸„ุณสมบัติ" #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:36 msgid "Node layer" msgstr "ระดับโหนด" #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:42 msgid "Select a layer" msgstr "เลือà¸à¸£à¸°à¸”ับชั้น" #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:57 msgid "Node field" msgstr "ลัà¸à¸©à¸“ะโหนด" #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:83 msgid "Courses not matched" msgstr "หลัà¸à¸ªà¸¹à¸•รไม่ตรงà¸à¸±à¸™" #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:87 #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:106 #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:108 msgid "Field" msgstr "คุณลัà¸à¸©à¸“ะ" #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:89 msgid "Reason" msgstr "เหตุผล" #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:102 msgid "Courses matched" msgstr "หลัà¸à¸ªà¸¹à¸•รตรงà¸à¸±à¸™" #: /src/schooltool/cando/browser/templates/courses_skills_assignment.pt:122 msgid "Assign" msgstr "à¸à¸³à¸«à¸™à¸”ใช้" #: /src/schooltool/cando/browser/templates/document.pt:5 msgid "Edit this Document" msgstr "à¹à¸à¹‰à¹„ขเอà¸à¸ªà¸²à¸£" #: /src/schooltool/cando/browser/templates/document_skill.pt:4 #: /src/schooltool/cando/browser/templates/skill.pt:4 msgid "Edit this skill" msgstr "à¹à¸à¹‰à¹„ขทัà¸à¸©à¸°" #: /src/schooltool/cando/browser/templates/edit_course_skills.pt:15 #: /src/schooltool/cando/interfaces.py:70 #: /src/schooltool/cando/interfaces.py:99 #: /src/schooltool/cando/interfaces.py:134 msgid "Deprecated" msgstr "" #: /src/schooltool/cando/browser/templates/gradebook_skills_dialog.pt:33 #: /src/schooltool/cando/browser/templates/gradebook_skills_dialog.pt:43 msgid "There are no skills." msgstr "ไม่มีทัà¸à¸©à¸°" #: /src/schooltool/cando/browser/templates/iep_details.pt:5 msgid "Edit this plan information" msgstr "à¹à¸à¹‰à¹„ขข้อมูลของà¹à¸œà¸™" #: /src/schooltool/cando/browser/templates/layer.pt:4 msgid "Edit this Layer" msgstr "à¹à¸à¹‰à¹„ขลำดับชั้นนี้" #: /src/schooltool/cando/browser/templates/layer.pt:78 msgid "Parent layers" msgstr "ชั้นพ่อà¹à¸¡à¹ˆ" #: /src/schooltool/cando/browser/templates/layer.pt:104 msgid "Child layers" msgstr "ชั้นลูà¸" #: /src/schooltool/cando/browser/templates/layer.pt:107 msgid "Edit children" msgstr "à¹à¸à¹‰à¹„ขข้อมูลนัà¸à¹€à¸£à¸µà¸¢à¸™" #: /src/schooltool/cando/browser/templates/node.pt:13 msgid "General Information" msgstr "ข้อมูลทั่วไป" #: /src/schooltool/cando/browser/templates/node.pt:17 msgid "Edit this Node" msgstr "à¹à¸à¹‰à¹„ขโหนดนี้" #: /src/schooltool/cando/browser/templates/node.pt:89 #: /src/schooltool/cando/browser/templates/node.pt:92 msgid "Parent nodes" msgstr "โหนดพ่อà¹à¸¡à¹ˆ" #: /src/schooltool/cando/browser/templates/node.pt:118 #: /src/schooltool/cando/browser/templates/node.pt:121 msgid "Child nodes" msgstr "โหนดลูà¸" #: /src/schooltool/cando/browser/templates/node.pt:122 msgid "Edit child nodes" msgstr "à¹à¸à¹‰à¹„ขโหนดลูà¸" #: /src/schooltool/cando/browser/templates/node.pt:160 msgid "Edit layers" msgstr "à¹à¸à¹‰à¹„ขลำดับ" #: /src/schooltool/cando/browser/templates/node.pt:201 msgid "Edit skill sets" msgstr "à¹à¸à¹‰à¹„ขà¸à¸¥à¸¸à¹ˆà¸¡à¸—ัà¸à¸©à¸°" #: /src/schooltool/cando/browser/templates/projects.pt:5 msgid "Reorder or Hide Projects" msgstr "เรียงลำดับหรือซ่อนโครงà¸à¸²à¸£" #: /src/schooltool/cando/browser/templates/projects.pt:9 #: /src/schooltool/cando/browser/templates/skillsets.pt:9 msgid "Order" msgstr "ลำดับชั้น" #: /src/schooltool/cando/browser/templates/projects.pt:11 #: /src/schooltool/cando/browser/templates/skillsets.pt:11 msgid "Visible" msgstr "ปราà¸à¸à¹€à¸«à¹‡à¸™" #: /src/schooltool/cando/browser/templates/projects.pt:34 msgid "Edit this project" msgstr "à¹à¸à¹‰à¹„ขโครงà¸à¸²à¸£à¸™à¸µà¹‰" #: /src/schooltool/cando/browser/templates/request_competency_certificate.pt:5 #: /src/schooltool/cando/interfaces.py:99 #: /src/schooltool/cando/interfaces.py:238 msgid "Description" msgstr "คำอธิบาย" #: /src/schooltool/cando/browser/templates/request_competency_certificate.pt:11 msgid "File Type" msgstr "ชนิดไฟล์" #: /src/schooltool/cando/browser/templates/request_competency_certificate.pt:23 msgid "Select a minimum display score for ${scoresystem}" msgstr "เลือà¸à¹à¸ªà¸”งคะà¹à¸™à¸™à¸—ี่น้อยที่สุดสำหรับ ${scoresystem}" #: /src/schooltool/cando/browser/templates/section_report_details.pt:3 msgid "Details" msgstr "" #: /src/schooltool/cando/browser/templates/section_report_details.pt:12 msgid "Government ID" msgstr "" #: /src/schooltool/cando/browser/templates/section_report_score_colors.pt:33 msgid "Meets target" msgstr "" #: /src/schooltool/cando/browser/templates/skillsets.pt:5 msgid "Reorder or Hide Skill Sets" msgstr "เรียงลำดับหรือซ่อนà¸à¸¥à¸¸à¹ˆà¸¡à¸—ัà¸à¸©à¸°" #: /src/schooltool/cando/browser/xls_views.py:183 msgid "Skill definitions" msgstr "" #: /src/schooltool/cando/browser/xls_views.py:186 #: /src/schooltool/cando/course.py:187 msgid "Course Skills" msgstr "ทัà¸à¸©à¸°à¸£à¸²à¸¢à¸§à¸´à¸Šà¸²" #: /src/schooltool/cando/browser/xls_views.py:193 msgid "Exporting skills" msgstr "" #: /src/schooltool/cando/browser/xls_views.py:212 msgid "Export complete" msgstr "" #: /src/schooltool/cando/course.py:231 msgid "Section Skills" msgstr "à¸à¸¥à¸¸à¹ˆà¸¡à¸—ัà¸à¸©à¸°" #: /src/schooltool/cando/gradebook.py:56 msgid "Project1" msgstr "โครงà¸à¸²à¸£ 1" #: /src/schooltool/cando/interfaces.py:60 msgid "Limit to 7 characters or less." msgstr "จำà¸à¸±à¸”จำนวนที่ 7 ตัวอัà¸à¸©à¸£à¸«à¸£à¸·à¸­à¸™à¹‰à¸­à¸¢à¸à¸§à¹ˆà¸²" #: /src/schooltool/cando/interfaces.py:68 msgid "External ID" msgstr "รหัสจาà¸à¸ à¸²à¸¢à¸™à¸­à¸" #: /src/schooltool/cando/interfaces.py:70 msgid "Required?" msgstr "" #: /src/schooltool/cando/interfaces.py:71 msgid "Skill is no longer used" msgstr "ทัà¸à¸©à¸°à¸—ี่ไม่ได้ใช้นานà¹à¸¥à¹‰à¸§" #: /src/schooltool/cando/interfaces.py:79 msgid "Scoresystem" msgstr "ระบบà¹à¸ªà¸”งคะà¹à¸™à¸™" #: /src/schooltool/cando/interfaces.py:52 msgid "The skill scoresystem." msgstr "ระบบคำนวณทัà¸à¸©à¸°" #: /src/schooltool/cando/interfaces.py:100 msgid "Skill set is no longer used" msgstr "" #: /src/schooltool/cando/interfaces.py:135 msgid "Node is no longer used" msgstr "" #: /src/schooltool/cando/interfaces.py:186 msgid "Project deployed" msgstr "โครงà¸à¸²à¸£à¸—ี่นำออà¸" #: /src/schooltool/cando/interfaces.py:151 msgid "Is this project deployed to course sections" msgstr "" #: /src/schooltool/cando/interfaces.py:200 msgid "Section intID" msgstr "" #: /src/schooltool/cando/interfaces.py:208 msgid "Skill set ID" msgstr "รหัสà¸à¸¥à¸¸à¹‰à¸¡à¸—ัà¸à¸©à¸°" #: /src/schooltool/cando/interfaces.py:209 msgid "Skill ID" msgstr "รหัสทัà¸à¸©à¸°" #: /src/schooltool/cando/interfaces.py:235 msgid "Active" msgstr "เปิดใช้งานอยู่" #: /src/schooltool/cando/project.py:137 msgid "Course Projects" msgstr "โครงà¸à¸²à¸£à¸£à¸²à¸¢à¸§à¸´à¸Šà¸²" #: /src/schooltool/cando/project.py:207 msgid "${project} total points" msgstr "" #: /src/schooltool/cando/project.py:229 msgid "${project} percent passed" msgstr "" #: /src/schooltool/cando/project.py:273 msgid "${course} total points" msgstr "" #: /src/schooltool/cando/project.py:297 msgid "${course} percent passed" msgstr "" schooltool.cando-2.6.2/src/schooltool/cando/locales/nl/0000755000175000017500000000000012322040274024210 5ustar menesismenesis00000000000000schooltool.cando-2.6.2/src/schooltool/cando/locales/nl/LC_MESSAGES/0000755000175000017500000000000012322040274025775 5ustar menesismenesis00000000000000schooltool.cando-2.6.2/src/schooltool/cando/locales/nl/LC_MESSAGES/schooltool.cando.mo0000644000175000017500000001501312322040274031602 0ustar menesismenesis00000000000000Þ•vÌ|ð ñ   + C ] o w { ˆ • Ÿ ¦ » Ñ ß ï    - 4 G T ] i p € Ž "¨ Ë !à     1 ; @ N Z e q  ‹ ž ® À Ð )Ý   ' , 3 6 V h n t †  ¬ ¸  Å Ù â è ö þ (/ 6D]fkr x…— ž¬´ÃÒ"Ûþ #,DK[ lz‚‰˜»ÐÖ ò  +38 < JŸXø#2Ih€ ‡‘¤· ÆÐë5Ufl ~ˆœ ° ¾É ÍÛì12$Ns y† ¢­¶ÍÜñ-CVk…7› ÓÞò ÷ %EKP` f ‡•¨¬ ÅÏØ ìú $ *62O ‚Œ”› ¡®ÀÇÛâö * AMcw$‡ ¬¹Îå ý (%0Vpv“ ¥³È æðõ ølRbYd%@.123 >=nLqDGAT mQPUaO!fV`M7&_$-r\i<SFJ4hC gX^eu9HB#5"p 0IjZ'[/Nt 6:o ;]8kKWc(,*?E)+vs${course} total points${layer} Information${layer} list${project} total points${section} Project Skills${section} SkillsActionsAddAdd ${layer}Add DocumentAdd LayerAssignAssign Course SkillsAssign Courses SkillsAssign SkillsAssigned SkillsAvailable child layersAvailable layersCanDoCanDo GradebookCancelChange informationChild layersChildrenColor CodesCourseCourse ProjectsCourse SkillsCourse attribute is emptyCourse has skills assigned alreadyCurrent child layersCurrent document hierarchy layersDateDescriptionDocumentDocument InformationDocumentsEditEdit ChildrenEdit LayersEdit SkillEdit SkillsEdit childrenEdit layersEdit this DocumentEdit this LayerEdit this projectEdit this skillEnter SkillsExport global skills data for the school.External IDGeneral InformationHelpHiddenIDID, title, label or descriptionImport Skill DataLabelLayerLayer InformationLayersLimit to 7 characters or less.New ProjectNew SkillNoNo Visible ProjectsOptionalOrderParent layersParentsProjectProject DetailsProject1ProjectsReasonRemoveRemove SkillsReorder or Hide ProjectsRequiredSaveSchoolScoreScore SystemScore System HelpSearchSearch SkillsSectionSection SkillsSelect a layerSettingsShowing ${count} of ${total} itemsSkillSkill Color CodeSkill DetailsSkill IDSkill is no longer usedSkillsSkills DocumentSkills DocumentsSkills ExportSort bySubmitSubmit and addTermThere are no skills assigned.There are no skills.TitleTitle, description or labelView ${layer}View LayerView SkillView Skills DocumentVisibleYearYescancel-buttonsubmit-buttonProject-Id-Version: schooltool.cando Report-Msgid-Bugs-To: FULL NAME POT-Creation-Date: 2013-10-10 16:06+0300 PO-Revision-Date: 2013-03-20 04:32+0000 Last-Translator: rob Language-Team: Dutch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Launchpad-Export-Date: 2013-10-11 05:27+0000 X-Generator: Launchpad (build 16799) Totaalscore ${course}${layer}-informatie${layer}-lijstTotaalscore ${project}${section}-projectvaardigheden${section}-vaardighedenActiesToevoegen${layer} toevoegenDocument toevoegenLaag toevoegenToewijzenVak-vaardigheden toewijzenVak-vaardigheden toewijzenVaardigheden toewijzenToegewezen vaardighedenBeschikbare onderliggende lagenBeshikbare lagenCanDoCanDo-cijferlijstAnnulerenInformatie wijzigenOnderliggende lagenOnderliggendeKleurcodesVakVak-projectenVak-vaardighedenVak-kenmerk is leegEr zijn reeds vaardigheden toegewezen aan dit vakHuidige onderliggende lagenHuidige hiërarchische documentlagenDatumOmschrijvingDocumentDocumentinformatieDocumentenBewerkenOnderliggende bewerkenLagen bewerkenVaardigheid bewerkenVaardigheden bewerkenOnderliggende bewerkenLagen bewerkenDit document bewerkenDeze laag bewerkenDit project bewerkenDeze vaardigheid bewerkenVaardigheden invoerenAlgemene vaardigheidsgegevens van de school exporteren.Externe-IDAlgemene informatieHulpVerborgenIDID, titel, label of omschrijvingVaardigheidsgegevens importerenLabelLaagLaag-informatieLagenLimiteren tot 7 tekens of minderNieuw projectNieuwe vaardigheidNeeGeen zichtbare projectenOptioneelVolgordeBovenliggende lagenBovenliggendeProjectProjectdetailsProject1ProjectenRedenVerwijderenVaardigheden verwijderenVolgorde projecten wijzigen of projecten verbergenVerplichtOpslaanSchoolScoreScoresysteemScoresysteem-hulpZoekenVaardigheden zoekenSectieVaardigheden-sectieSelecteer een laagInstellingen${count} van ${total} items worden getoondVaardigheidVaardigheidskleurcodeVaardigheidsdetailsVaardigheids-IDVaardigheid wordt niet meer gebruiktVaardighedenVaardigheidsdocumentVaardigheidsdocumentenvaardigheden exporterenSorteren opIndienenIndienen en toevoegenTermijnEr zijn geen vaardigheden toegewezen.Er zijn geen vaardighedenTitelTitel, omschrijving of label${layer} bekijkenLaag bekijkenVaardigheid bekijkenVaardigheidsdocument bekijkenZichtbaarJaarJaAnnulerenIndienenschooltool.cando-2.6.2/src/schooltool/cando/interfaces.py0000644000175000017500000001564212270520445024667 0ustar menesismenesis00000000000000# # SchoolTool - common information systems platform for school administration # Copyright (c) 2012 Shuttleworth Foundation # # 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 2 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 . # import zope.schema from zope.annotation.interfaces import IAttributeAnnotatable from zope.container.interfaces import IContainer, IContained from zope.container.constraints import contains from zope.html.field import HtmlFragment from zope.interface import Interface, Attribute, implements from zope.schema import Choice from schooltool.requirement.interfaces import IRequirement from schooltool.gradebook.interfaces import IWorksheets, IWorksheet from schooltool.gradebook.interfaces import IGradebook from schooltool.gradebook.interfaces import IMyGrades from schooltool.gradebook.interfaces import IStudentGradebook from schooltool.cando import CanDoMessage as _ class ILabelTextLine(Interface): pass class ISkillRequiredBool(Interface): pass class LabelTextLine(zope.schema.TextLine): implements(ILabelTextLine) class SkillRequiredBool(zope.schema.Bool): implements(ISkillRequiredBool) class ILabel(Interface): label = LabelTextLine( title=_("Label"), description=_("Limit to 7 characters or less."), required=False, max_length=7, default=u'') class ISkill(IRequirement, IAttributeAnnotatable, ILabel): external_id = zope.schema.TextLine(title=_("External ID"), required=False) required = SkillRequiredBool(title=_("Required?")) retired = zope.schema.Bool(title=_("Deprecated"), description=_("Skill is no longer used"), default=False) description = HtmlFragment(title=_("Description"), required=False) equivalent = Attribute("Directly equivalent skills.") scoresystem = Choice( title=_("Scoresystem"), description=_("The skill scoresystem."), vocabulary='schooltool.requirement.discretescoresystems', required=True) def findAllEquivalent(): """Find all (including indirectly) equivalent skills.""" def copy(): """Return a copy of this skill.""" class ISkillSetContainer(IContainer): pass class ISkillSet(IRequirement, IAttributeAnnotatable, ILabel): description = HtmlFragment(title=_("Description"), required=False) retired = zope.schema.Bool(title=_("Deprecated"), description=_("Skill set is no longer used"), default=False) class ILayerContainer(IContainer): pass class ILayer(Interface): title = zope.schema.TextLine( title=_("Title")) parents = Attribute("Parent layers") children = Attribute("Child layers") class ILayerContained(ILayer, IContained, IAttributeAnnotatable): pass class INodeContainer(IContainer): pass class INode(ILabel): title = zope.schema.TextLine( title=_("Title"), required=True) description = HtmlFragment( title=_("Description"), required=False, default=u'') retired = zope.schema.Bool( title=_("Deprecated"), description=_("Node is no longer used"), default=False) layers = Attribute("Layers within this layer") parents = Attribute("Parent nodes") children = Attribute("Child nodes") skillsets = Attribute("Skill sets related to this node") def findPaths(): """ Return a list of paths (tuples) that lead (parent-to-child) to this node. """ class INodeContained(INode, IContained, IAttributeAnnotatable): pass class IDocumentContainer(IContainer): pass class IDocument(INode): hierarchy = Attribute("Hierarchy of layers for building node tree") def getOrderedHierarchy(): """ Return the ordered list of layers that represents the document hierarchy. """ class IDocumentContained(IDocument, IContained, IAttributeAnnotatable): pass class IProject(ISkillSet, IWorksheet): pass class IProjects(IWorksheets): contains('.IProject') class ICourseProject(ISkillSet): """A template project.""" contains('.ISkill') deployed = zope.schema.Bool( title=_("Project deployed"), description=_("Is this project deployed to course sections"), readonly=True, required=False ) class ICourseProjects(IRequirement): contains('.ICourseProject') def isDeployed(project, section): """Is given project deployed to that section?""" def deploy(self, key, section): """Deploy this project to that section.""" class ICourseSkills(IRequirement): contains('.ICourseSkillset') class ICourseSkillSet(IContained): skillset = Attribute(u"The global skill set.") required = zope.schema.Dict( key_type=zope.schema.TextLine(title=u"Skill __name__ in skilset."), value_type=zope.schema.Bool(title=u"Is skill required")) retired = zope.schema.Dict( key_type=zope.schema.TextLine(title=u"Skill __name__ in skilset."), value_type=zope.schema.Bool(title=u"Retired skills should not be used.")) class ICourseSkill(ISkill): """Proxy for the real global skill""" course_skillset = Attribute(u"The course skill set.") class ISectionSkills(IWorksheets): pass class ISectionSkillSet(ISkillSet, IWorksheet): skillset = Attribute(u"The global skill set.") class ISectionSkill(ISkill): section_intid = zope.schema.Int(title=_("Section intID"), required=False) section_skillset_name = zope.schema.Int(title=_("Skill set ID"), required=False) section_skill_name = zope.schema.Int(title=_("Skill ID"), required=False) class ICanDoGradebook(IGradebook): pass class IProjectsGradebook(ICanDoGradebook): pass class ISkillsGradebook(ICanDoGradebook): pass class IMySkillsGrades(IMyGrades): pass class IMyProjectsGrades(IMyGrades): pass class ICanDoStudentGradebook(IStudentGradebook): pass class IStudentIEP(Interface): active = zope.schema.Bool( title=_('Active'), default=False) description = HtmlFragment(title=_("Description"), required=False) iep_skills = Attribute('IEP Skills') def getIEPSkills(section): """Returns IEP skills""" def addSkill(section, skill): """Adds IEP skill""" def removeSkill(section, skill): """Removes IEP skill""" schooltool.cando-2.6.2/src/schooltool/cando/gradebook.zcml0000644000175000017500000000631412270520445025012 0ustar menesismenesis00000000000000 schooltool.cando-2.6.2/src/schooltool/cando/translations.zcml0000644000175000017500000000062412270520445025574 0ustar menesismenesis00000000000000 schooltool.cando-2.6.2/src/schooltool/cando/browser/0000755000175000017500000000000012322040274023640 5ustar menesismenesis00000000000000schooltool.cando-2.6.2/src/schooltool/cando/browser/document.zcml0000644000175000017500000005267712270520445026373 0ustar menesismenesis00000000000000 schooltool.cando-2.6.2/src/schooltool/cando/browser/breadcrumbs.py0000644000175000017500000001010112270520445026501 0ustar menesismenesis00000000000000# # SchoolTool - common information systems platform for school administration # Copyright (c) 2012 Shuttleworth Foundation # # 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 2 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 . # """ Breadcrumbs. """ from zope.traversing.browser.absoluteurl import absoluteURL from schooltool.app.interfaces import ISchoolToolApplication from schooltool.skin import flourish from schooltool.cando.browser import document from schooltool.cando.interfaces import IDocumentContainer from schooltool.cando import CanDoMessage as _ class LabelBreadcrumb(flourish.breadcrumbs.Breadcrumbs): @property def title(self): return self.context.label or self.context.title class CourseSkillSetBreadcrumb(flourish.breadcrumbs.Breadcrumbs): @property def title(self): ss = self.context.skillset return ss.label or ss.title class DocumentNavBreadcrumb(flourish.breadcrumbs.Breadcrumbs): @property def crumb_parent(self): return IDocumentContainer(ISchoolToolApplication(None)) @property def url(self): if not self.checkPermission(): return False app = ISchoolToolApplication(None) app_url = absoluteURL(app, self.request) link = '%s/%s' % (app_url, self.traversal_name) return link class DocumentLayerBreadcrumb(flourish.breadcrumbs.Breadcrumbs, document.DocumentNodeMixin): @property def crumb_parent(self): return self.get_document() @property def url(self): if not self.checkPermission(): return False layer_url = absoluteURL(self.context, self.request) query_string = self.build_query_string() link = '%s/document.html%s' % (layer_url, query_string) return link class DocumentNodeBreadcrumb(flourish.breadcrumbs.Breadcrumbs, document.DocumentNodeMixin): @property def crumb_parent(self): parents = tuple(self.context.parents) if not parents: return None return parents[0] @property def url(self): if not self.checkPermission(): return False node_url = absoluteURL(self.context, self.request) layers = tuple(self.context.layers) if not layers: return False query_string = self.build_query_string(layer=layers[0]) link = '%s/document.html%s' % (node_url, query_string) return link class DocumentSkillSetBreadcrumb(flourish.breadcrumbs.Breadcrumbs, document.DocumentSkillSetMixin): @property def crumb_parent(self): return self.get_node() @property def url(self): if not self.checkPermission(): return False skillset_url = absoluteURL(self.context, self.request) query_string = self.build_query_string(layer=self.get_previous_layer(), node=self.get_node()) link = '%s/document.html%s' % (skillset_url, query_string) return link class DocumentSkillBreadcrumb(flourish.breadcrumbs.Breadcrumbs, document.DocumentSkillMixin): @property def url(self): if not self.checkPermission(): return False skill_url = absoluteURL(self.context, self.request) query_string = self.build_query_string(layer=self.get_previous_layer(), node=self.get_node()) link = '%s/document.html%s' % (skill_url, query_string) return link schooltool.cando-2.6.2/src/schooltool/cando/browser/iep.py0000644000175000017500000003415312270520445025002 0ustar menesismenesis00000000000000# # SchoolTool - common information systems platform for school administration # Copyright (c) 2012 Shuttleworth Foundation # # 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 2 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 . # """IEP views""" from xml.sax.saxutils import quoteattr from zope.browserpage.viewpagetemplatefile import ViewPageTemplateFile from zope.cachedescriptors.property import Lazy from zope.component import getUtility from zope.intid.interfaces import IIntIds from zope.i18n.interfaces.locales import ICollator from zope.publisher.interfaces import NotFound from zope.security import proxy from zope.traversing.browser.absoluteurl import absoluteURL from z3c.form import field, form, button from z3c.form.interfaces import DISPLAY_MODE import zc.table from schooltool.common.inlinept import InheritTemplate from schooltool.common.inlinept import InlineViewPageTemplate from schooltool.course.interfaces import ILearner from schooltool.course.browser.course import FlourishCoursesViewlet from schooltool.skin import flourish from schooltool import table from schooltool.cando.interfaces import ISectionSkills from schooltool.cando.interfaces import IStudentIEP from schooltool.cando import CanDoMessage as _ class StudentIEPLinkViewlet(flourish.page.LinkViewlet): @property def enabled(self): return bool(list(ILearner(self.context).sections())) class StudentIEPView(flourish.page.Page): @property def iep(self): return IStudentIEP(self.context) class StudentIEPViewDetails(flourish.form.FormViewlet): template = ViewPageTemplateFile('templates/iep_details.pt') mode = DISPLAY_MODE @property def fields(self): return field.Fields(IStudentIEP) @property def title(self): return self.view.subtitle def canModify(self): return flourish.hasPermission(self.context, 'schooltool.edit') def editURL(self): person_url = absoluteURL(self.context, self.request) return '%s/iep-edit-details.html' % person_url def getContent(self): return self.context class StudentIEPViewSectionsViewlet(FlourishCoursesViewlet): template = ViewPageTemplateFile('templates/iep_sections.pt') def update(self): super(StudentIEPViewSectionsViewlet, self).update() int_ids = getUtility(IIntIds) person_url = absoluteURL(self.context, self.request) iep_url = '%s/iep_section.html?section_id=%s' for sy_info in self.learnerOf: for term_info in sy_info['terms']: for section_info in term_info['sections']: int_id = int_ids.getId(section_info['obj']) section_info.update({ 'iep_url': iep_url % (person_url, int_id), }) class StudentIEPViewDoneLink(flourish.viewlet.Viewlet): template = InlineViewPageTemplate(''' ''') @property def url(self): return absoluteURL(self.context, self.request) class StudentIEPEditView(flourish.form.Form, form.EditForm): template = InheritTemplate(flourish.page.Page.template) content_template = ViewPageTemplateFile('templates/form.pt') label = None legend = _('IEP Details') fields = field.Fields(IStudentIEP) def updateActions(self): super(StudentIEPEditView, self).updateActions() self.actions['add'].addClass('button-ok') self.actions['cancel'].addClass('button-cancel') @button.buttonAndHandler(_('Submit'), name='add') def handleApply(self, action): super(StudentIEPEditView, self).handleApply.func(self, action) # XXX: hacky sucessful submit check if (self.status == self.successMessage or self.status == self.noChangesMessage): self.request.response.redirect(self.nextURL()) @button.buttonAndHandler(_('Cancel')) def handle_cancel_action(self, action): self.request.response.redirect(self.nextURL()) def nextURL(self): person_url = absoluteURL(self.context, self.request) return '%s/iep.html' % person_url class IEPSectionSkillsMixing(flourish.page.Page): container_class = 'container widecontainer' @property def iep(self): return IStudentIEP(self.context) def isIEPSkill(self, iep_skills, skill): skillset = skill.__parent__ return skillset in iep_skills and skill in iep_skills[skillset] @Lazy def section(self): try: section_id = int(self.request.get('section_id')) except (TypeError, ValueError): section_id = None if section_id is not None: int_ids = getUtility(IIntIds) return int_ids.queryObject(section_id) raise NotFound(self.context, self.__name__, self.request) class StudentIEPSectionView(IEPSectionSkillsMixing): @property def subtitle(self): return _('IEP Skills for ${section}', mapping={'section': self.section.title}) class StudentIEPSectionSkillsViewlet(flourish.viewlet.Viewlet): template = InlineViewPageTemplate('''

IEP Skills Edit

''') def canModify(self): return flourish.hasPermission(self.context, 'schooltool.edit') def editURL(self): person_url = absoluteURL(self.context, self.request) int_ids = getUtility(IIntIds) section_id = int_ids.getId(self.view.section) return '%s/iep_edit_section_skills.html?section_id=%s' % ( person_url, section_id) class SkillSetColumn(zc.table.column.GetterColumn): def getSortKey(self, item, formatter): collator = ICollator(formatter.request.locale) skillset = item['skillset'] skillset_label = item['skillset_label'] skill = item['skill'] return (collator.key(skillset_label or ''), collator.key(skillset.title), collator.key(skill.label or ''), collator.key(skill.title)) def label_title_formatter(obj, item, formatter): title = obj.title label = getattr(obj, 'label') if label is not None: title = '%s: %s' % (label, title) return title class StudentIEPSectionSkillsTableFormatter(table.ajax.AJAXFormSortFormatter): def renderCell(self, item, column): klass = self.cssClasses.get('td', '') if column.name == 'skill' and not item['skill'].required: if klass: klass += ' ' klass += 'optional' if column.name == 'skill' and item['is_iep_skill']: if klass: klass += ' ' klass += 'iep' klass = klass and ' class=%s' % quoteattr(klass) or '' return '%s' % (klass, self.getCell(item, column),) def renderRow(self, item): klass = self.cssClasses.get('tr', '') if klass: klass += ' ' klass += '%s/gradebook' % absoluteURL(item['skillset'], self.request) klass = klass and ' class=%s' % quoteattr(klass) or '' return '%s' % ( klass, self.renderCells(item)) class StudentIEPSectionSkillsTable(table.ajax.Table): batch_size = 0 table_formatter = StudentIEPSectionSkillsTableFormatter visible_column_names = ['label', 'skill'] def columns(self): skillset = SkillSetColumn( name='skillset', title=_('Skill Set')) label = zc.table.column.GetterColumn( name='label', title='', getter=lambda item, formatter: item['skill'].label or '') skill = zc.table.column.GetterColumn( name='skill', title=_('Skill'), getter=lambda item, formatter: item['skill'].title) return [skillset, label, skill] def items(self): result = [] iep = IStudentIEP(self.context) iep_skills = iep.getIEPSkills(self.view.section) worksheets = ISectionSkills(self.view.section) for worksheet in worksheets.values(): skillset_label = worksheet.label for skill in worksheet.values(): is_iep_skill =self.view.isIEPSkill(iep_skills, skill) result.append({ 'skillset': proxy.removeSecurityProxy(worksheet), 'skillset_label': skillset_label, 'skill': skill, 'skill_id': self.getSkillId(skill), 'is_iep_skill': is_iep_skill, }) return result def sortOn(self): return (('skillset', False),) def getSkillId(self, skill): skillset = skill.__parent__ return '%s.%s' % (skillset.__name__, skill.__name__) def updateFormatter(self): if self._table_formatter is None: self.setUp(table_formatter=self.table_formatter, batch_size=self.batch_size, prefix=self.__name__, css_classes={'table': 'data color-codes'}) class StudentIEPSectionViewDoneLink(StudentIEPViewDoneLink): @property def url(self): return '%s/iep.html' % absoluteURL(self.context, self.request) class StudentIEPEditSectionSkillsView(IEPSectionSkillsMixing): @property def subtitle(self): return _('Edit IEP Skills for ${section}', mapping={'section': self.section.title}) class StudentIEPEditSectionSkillsViewlet(flourish.viewlet.Viewlet): template = InlineViewPageTemplate('''
''') def iep_value_getter(item): return False class StudentIEPEditSectionSkillsTable(StudentIEPSectionSkillsTable): visible_column_names = ['optional-iep', 'label', 'skill'] buttons = ( {'name': 'SAVE', 'label': _('Save'), 'klass': 'button-ok'}, {'name': 'CANCEL', 'label': _('Cancel'), 'klass': 'button-cancel'}, ) @property def checkbox_prefix(self): return '%s.iep' % self.prefix def columns(self): default = super(StudentIEPEditSectionSkillsTable, self).columns() iep = table.column.CheckboxColumn( self.checkbox_prefix, name='optional-iep', title=_('Optional IEP'), isDisabled=lambda i: not i['skill'].required, id_getter=lambda i: i['skill_id'], value_getter=lambda i: i['is_iep_skill']) return [iep] + default def update(self): super(StudentIEPEditSectionSkillsTable, self).update() saved = False if 'SAVE' in self.request: self.updateIEPSkills() saved = True if 'CANCEL' in self.request or saved: person_url = absoluteURL(self.context, self.request) section_id = self.request.get('section_id') url = '%s/iep_section.html?section_id=%s' % ( person_url, section_id) self.request.response.redirect(url) def updateIEPSkills(self): for item in self._items: skill = item['skill'] cell_name = '%s.%s' % (self.checkbox_prefix, item['skill_id']) if cell_name in self.request: if not item['is_iep_skill']: self.view.iep.addSkill(self.view.section, skill) else: if item['is_iep_skill']: self.view.iep.removeSkill(self.view.section, skill) class StudentIEPEditSectionSkillsButtons(flourish.viewlet.Viewlet): template = InlineViewPageTemplate('''
''') class GradebookIEPStudents(flourish.viewlet.Viewlet): template = ViewPageTemplateFile('templates/gradebook_iep_students.pt') def students(self): result = [] for student in self.view.students: if IStudentIEP(student).active: result.append(student.username) return result class GradeStudentIEPDescriptionViewlet(StudentIEPViewDetails): @property def fields(self): return field.Fields(IStudentIEP).select('description') @property def title(self): return _('IEP Information') def canModify(self): return False def getContent(self): return self.view.student @property def enabled(self): iep = IStudentIEP(self.view.student) return iep.active and iep.description def render(self, *args, **kw): if not self.enabled: return '' return super(GradeStudentIEPDescriptionViewlet, self).render( *args, **kw) schooltool.cando-2.6.2/src/schooltool/cando/browser/gradebook.py0000644000175000017500000024377212321600500026157 0ustar menesismenesis00000000000000# # SchoolTool - common information systems platform for school administration # Copyright (c) 2012 Shuttleworth Foundation # # 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 2 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 . # """ CanDo view components. """ import pytz from xml.sax.saxutils import quoteattr import zope.lifecycleevent from zope.browserpage.viewpagetemplatefile import ViewPageTemplateFile from zope.cachedescriptors.property import Lazy from zope.component import queryMultiAdapter from zope.component import getUtility, getMultiAdapter from zope.container.interfaces import INameChooser from zope.i18n import translate from zope.i18n.interfaces.locales import ICollator from zope.interface import directlyProvides from zope.intid.interfaces import IIntIds from zope.traversing.api import getName from zope.traversing.browser.absoluteurl import absoluteURL from zope.security import proxy from zope.proxy import sameProxiedObjects import zc.table.column from zc.catalog.interfaces import IExtentCatalog from zc.table.interfaces import ISortableColumn from z3c.rml import rml2pdf from z3c.form import form, field, button from schooltool.app.interfaces import ISchoolToolApplication from schooltool.app.interfaces import IApplicationPreferences from schooltool.app.catalog import buildQueryString from schooltool.course.interfaces import ISection from schooltool.course.interfaces import ISectionContainer from schooltool.common.inlinept import InheritTemplate from schooltool.common.inlinept import InlineViewPageTemplate from schooltool.gradebook.browser.gradebook import FlourishGradebookOverview from schooltool.gradebook.browser.gradebook import FlourishGradebookStartup from schooltool.gradebook.browser.gradebook import GradebookStartupNavLink from schooltool.gradebook.browser.gradebook import FlourishNamePopupMenuView from schooltool.gradebook.browser.gradebook import FlourishActivityPopupMenuView from schooltool.gradebook.browser.gradebook import FlourishStudentPopupMenuView from schooltool.gradebook.browser.gradebook import GradebookTertiaryNavigationManager from schooltool.gradebook.browser.gradebook import MyGradesTertiaryNavigationManager from schooltool.gradebook.browser.gradebook import MyGradesTable from schooltool.gradebook.browser.gradebook import FlourishGradebookYearNavigationViewlet from schooltool.gradebook.browser.gradebook import FlourishGradebookTermNavigationViewlet from schooltool.gradebook.browser.gradebook import FlourishGradebookSectionNavigationViewlet from schooltool.gradebook.browser.gradebook import FlourishMyGradesView from schooltool.gradebook.browser.gradebook import FlourishGradebookValidateScoreView from schooltool.gradebook.browser.worksheet import FlourishWorksheetEditView from schooltool.gradebook.browser.pdf_views import FlourishGradebookPDFView from schooltool.gradebook.browser.pdf_views import WorksheetGrid from schooltool.person.interfaces import IPerson from schooltool.person.interfaces import IPersonFactory from schooltool.report.browser.report import RequestRemoteReportDialog from schooltool.report.report import ReportTask from schooltool.schoolyear.interfaces import ISchoolYearContainer from schooltool.report.browser.report import FileArchiver from schooltool.report.browser.report import ReportArchivePage from schooltool.requirement.scoresystem import ScoreValidationError from schooltool.requirement.scoresystem import UNSCORED from schooltool.term.interfaces import ITerm, IDateManager from schooltool.schoolyear.interfaces import ISchoolYear import schooltool.table.catalog from schooltool.skin import flourish from schooltool import table from schooltool.cando.model import NodeLink, NodeLayer, NodeSkillSets from schooltool.cando.model import DocumentHierarchy from schooltool.cando.interfaces import IProject from schooltool.cando.interfaces import IProjects from schooltool.cando.interfaces import ISectionSkills from schooltool.cando.interfaces import IProjectsGradebook from schooltool.cando.interfaces import ISkill, ISkillSet from schooltool.cando.interfaces import ISkillSetContainer from schooltool.cando.interfaces import ILayerContainer from schooltool.cando.interfaces import INode from schooltool.cando.interfaces import INodeContainer from schooltool.cando.interfaces import ISkillsGradebook from schooltool.cando.interfaces import IMySkillsGrades from schooltool.cando.interfaces import IMyProjectsGrades from schooltool.cando.interfaces import IStudentIEP from schooltool.cando.interfaces import IDocumentContainer from schooltool.cando.interfaces import ICanDoStudentGradebook from schooltool.cando.gradebook import ensureAtLeastOneProject from schooltool.cando.browser.model import NodesTable from schooltool.cando.project import Project from schooltool.cando.model import getNodeCatalog from schooltool.cando.model import getOrderedByHierarchy from schooltool.cando.skill import getSkillCatalog, getSkillSetCatalog from schooltool.cando.skill import querySkillScoreSystem from schooltool.cando.skill import searchable_common_indexes from schooltool.cando.browser.skill import SkillAddView from schooltool.cando import CanDoMessage as _ class CanDoStartupNavLink(GradebookStartupNavLink): startup_view_name = 'cando.html' class CanDoStartupView(FlourishGradebookStartup): teacher_gradebook_view_name = 'gradebook-skills' student_gradebook_view_name = 'mygrades-skills' class SectionProjectsCanDoRedirectView(flourish.page.Page): teacher_worksheet_view_name = 'gradebook' student_worksheet_view_name = 'mygrades' # XXX: merge this with SectionGradebookRedirectView def __call__(self): person = IPerson(self.request.principal) worksheets = IProjects(self.context) ensureAtLeastOneProject(worksheets) current_worksheet = worksheets.getCurrentWorksheet(person) url = absoluteURL(worksheets, self.request) if current_worksheet is not None: url = absoluteURL(current_worksheet, self.request) if person in self.context.members: url += '/%s' % self.student_worksheet_view_name else: url += '/%s' % self.teacher_worksheet_view_name self.request.response.redirect(url) return "Redirecting..." class SectionSkillsCanDoRedirectView(flourish.page.Page): teacher_worksheet_view_name = 'gradebook' student_worksheet_view_name = 'mygrades' def getProjectGradebookURL(self, is_student): result = absoluteURL(self.context, self.request) if is_student: result += '/mygrades-projects' else: result += '/gradebook-projects' return result # XXX: merge this with SectionGradebookRedirectView def __call__(self): person = IPerson(self.request.principal) is_student = person in self.context.members worksheets = ISectionSkills(self.context) current_worksheet = worksheets.getCurrentWorksheet(person) url = absoluteURL(worksheets, self.request) if not worksheets: url = self.getProjectGradebookURL(is_student) self.request.response.redirect(url) return if current_worksheet is not None: # XXX: current worksheet may have been deleted if current_worksheet not in worksheets: collator = ICollator(self.request.locale) worksheets = sorted( worksheets.values(), key=lambda x:(collator.key(x.label or ''), collator.key(x.title))) current_worksheet = worksheets[0] url = absoluteURL(current_worksheet, self.request) if is_student: url += '/%s' % self.student_worksheet_view_name else: url += '/%s' % self.teacher_worksheet_view_name self.request.response.redirect(url) return "Redirecting..." class CanDoGradebookOverviewBase(object): def getActivityInfo(self, activity): result = super( CanDoGradebookOverviewBase, self).getActivityInfo(activity) if not activity.required: cssClass = ' '.join(filter(None, [result['cssClass'], 'optional'])) result['cssClass'] = cssClass return result def processColumnPreferences(self): self.average_hide = True self.total_hide = True self.tardies_hide = True self.absences_hide = True self.due_date_hide = True self.average_scoresystem = None def getActivityAttrs(self, activity): result = super( CanDoGradebookOverviewBase, self).getActivityAttrs(activity) shortTitle, longTitle, bestScore = result if activity.label: longTitle = '%s: %s' % (activity.label, longTitle) return shortTitle, longTitle, bestScore class ProjectsGradebookOverview(CanDoGradebookOverviewBase, FlourishGradebookOverview): labels_row_header = _('Skill') teacher_gradebook_view_name = 'gradebook-projects' student_gradebook_view_name = 'mygrades-projects' @property def title(self): if self.all_hidden: return _('No Visible Projects') else: return _('Enter Skills') class SkillsGradebookOverview(CanDoGradebookOverviewBase, FlourishGradebookOverview): labels_row_header = _('Skill') teacher_gradebook_view_name = 'gradebook-skills' student_gradebook_view_name = 'mygrades-skills' @property def title(self): if self.all_hidden: return _('No Visible Skill Sets') else: return _('Enter Skills') @Lazy def filtered_activity_info(self): result = super(SkillsGradebookOverview, self).filtered_activity_info collator = ICollator(self.request.locale) return sorted(result, key=lambda x:(collator.key(x['object'].label or ''), collator.key(x['object'].title))) class ProjectsBreadcrumbs(flourish.breadcrumbs.Breadcrumbs): @property def link(self): return '../gradebook-projects' class SkillsBreadcrumbs(flourish.breadcrumbs.Breadcrumbs): @property def link(self): return '../gradebook-skills' class StudentGradebookBreadcrumbs(flourish.breadcrumbs.Breadcrumbs): @property def title(self): return self.context.student.title @property def url(self): return '' class CanDoProjectsAddLinks(flourish.page.RefineLinksViewlet): pass class CanDoProjectsSettingsLinks(flourish.page.RefineLinksViewlet): pass class CanDoModes(flourish.page.RefineLinksViewlet): pass class CanDoModesViewlet(flourish.viewlet.Viewlet): list_class = 'filter gradebook-modes' template = InlineViewPageTemplate('''
''') def items(self): section = ISection(proxy.removeSecurityProxy(self.context)) section_url = absoluteURL(section, self.request) result = [] if ISectionSkills(section): result.append({ 'id': 'skills', 'label': _('Skill Sets'), 'url': section_url + '/gradebook-skills', 'selected': ISkillsGradebook.providedBy(self.context), }) result.append({ 'id': 'projects', 'label': _('Projects'), 'url': section_url + '/gradebook-projects', 'selected': IProjectsGradebook.providedBy(self.context), }) return result def render(self, *args, **kw): return self.template(*args, **kw) class MyGradesCanDoModes(flourish.page.RefineLinksViewlet): pass class MyGradesCanDoModesViewlet(CanDoModesViewlet): def items(self): section = ISection(proxy.removeSecurityProxy(self.context)) section_url = absoluteURL(section, self.request) result = [] if ISectionSkills(section): result.append({ 'id': 'skills', 'label': _('Skill Sets'), 'url': section_url + '/mygrades-skills', 'selected': IMySkillsGrades.providedBy(self.context), }) result.append({ 'id': 'projects', 'label': _('Projects'), 'url': section_url + '/mygrades-projects', 'selected': IMyProjectsGrades.providedBy(self.context), }) return result class SkillAddLink(flourish.page.LinkViewlet): @property def title(self): worksheet = proxy.removeSecurityProxy(self.context).context if worksheet.deployed: return '' return _("Skill") class ProjectSkillAddView(SkillAddView): def nextURL(self): url = absoluteURL(self.context, self.request) if self.add_next: return url + '/addSkillCreate.html' return url + '/gradebook' class ProjectAddView(flourish.form.AddForm): fields = field.Fields(IProject).select('title') template = InheritTemplate(flourish.page.Page.template) label = None legend = _('Project Details') @button.buttonAndHandler(_('Submit'), name='add') def handleAdd(self, action): super(ProjectAddView, self).handleAdd.func(self, action) @button.buttonAndHandler(_("Cancel")) def handle_cancel_action(self, action): person = IPerson(self.request.principal, None) if person is None: worksheet = self.context._getDefaultWorksheet() else: worksheet = self.context.getCurrentWorksheet(person) if worksheet is None: url = absoluteURL(self.context.__parent__, self.request) else: url = absoluteURL(worksheet, self.request) + '/gradebook' self.request.response.redirect(url) def create(self, data): self.worksheet = Project(data['title']) return self.worksheet def add(self, worksheet): chooser = INameChooser(self.context) name = chooser.chooseName(worksheet.title, worksheet) self.context[name] = worksheet return worksheet def nextURL(self): return absoluteURL(self.worksheet, self.request) + '/gradebook' def updateActions(self): super(ProjectAddView, self).updateActions() self.actions['add'].addClass('button-ok') self.actions['cancel'].addClass('button-cancel') class CanDoNamePopupMenuView(FlourishNamePopupMenuView): def options(self, worksheet, column_id='student'): options = [ { 'label': self.translate(_('Sort by')), 'url': '?sort_by=%s' % column_id, }, ] return options def processColumnPreferences(self): return class SkillPopupMenuView(FlourishActivityPopupMenuView): def result(self): result = {} activity_id = self.request.get('activity_id') worksheet = proxy.removeSecurityProxy(self.context).context if activity_id is not None and activity_id in worksheet: activity = worksheet[activity_id] info = self.getActivityInfo(activity) if ISkillsGradebook.providedBy(self.context): info.update({ 'canDelete': False, 'moveLeft': False, 'moveRight': False, }) else: info.update({ 'canDelete': True, 'moveLeft': True, 'moveRight': True, }) keys = worksheet.keys() if keys[0] == activity.__name__: info['moveLeft'] = False if keys[-1] == activity.__name__: info['moveRight'] = False result['header'] = info['longTitle'] result['options'] = self.options(info, worksheet) return result def getActivityAttrs(self, activity): shortTitle, longTitle, bestScore = super( SkillPopupMenuView, self).getActivityAttrs(activity) if activity.label: longTitle = '%s: %s' % (activity.label, longTitle) return shortTitle, longTitle, bestScore class StudentPopupMenuView(FlourishStudentPopupMenuView): def getStudentCompetencyReportURL(self, student): gradebook_url = absoluteURL(self.context, self.request) return '%s/%s/student_competency_report.html' % (gradebook_url, student.username) def options(self, student): default = super(StudentPopupMenuView, self).options(student) default[-1]['url'] = self.getStudentCompetencyReportURL(student) return default class SkillEditView(flourish.form.Form, form.EditForm): template = InheritTemplate(flourish.page.Page.template) label = None legend = _('Skill Details') fields = field.Fields(ISkill).select('title', 'label', 'description', 'required', 'external_id') def updateActions(self): super(SkillEditView, self).updateActions() self.actions['add'].addClass('button-ok') self.actions['cancel'].addClass('button-cancel') @button.buttonAndHandler(_('Submit'), name='add') def handleApply(self, action): super(SkillEditView, self).handleApply.func(self, action) # XXX: hacky sucessful submit check if (self.status == self.successMessage or self.status == self.noChangesMessage): self.request.response.redirect(self.nextURL()) @button.buttonAndHandler(_("Cancel")) def handle_cancel_action(self, action): self.request.response.redirect(self.nextURL()) def nextURL(self): next = self.request.get('nexturl') if next: return next worksheet = self.context.__parent__ return absoluteURL(worksheet, self.request) + '/gradebook' class CanDoGradebookTertiaryNavigationManager( GradebookTertiaryNavigationManager): template = ViewPageTemplateFile('templates/cando_third_nav.pt') @property def items(self): result = [] gradebook = proxy.removeSecurityProxy(self.context) current = gradebook.context.__name__ collator = ICollator(self.request.locale) for worksheet in gradebook.worksheets: label = None title = raw_title = worksheet.title if ISkillsGradebook.providedBy(self.context) and \ worksheet.label: title = '%s: %s' % (worksheet.label, title) label = worksheet.label url = '%s/gradebook' % absoluteURL(worksheet, self.request) classes = worksheet.__name__ == current and ['active'] or [] if worksheet.deployed: classes.append('deployed') result.append({ 'class': classes and ' '.join(classes) or None, 'viewlet': u'%s' % (title, url, title), 'title': title, 'label': label, 'raw_title': raw_title, }) # XXX: split into separate adapters for each gradebook if ISkillsGradebook.providedBy(self.context): result.sort(key=lambda x:(collator.key(x['label'] or ''), collator.key(x['raw_title']))) return result class CanDoNavigationViewletBase(object): teacher_gradebook_view_name = 'gradebook-skills' student_gradebook_view_name = 'mygrades-skills' class CanDoYearNavigationViewlet( CanDoNavigationViewletBase, FlourishGradebookYearNavigationViewlet): pass class CanDoTermNavigationViewlet( CanDoNavigationViewletBase, FlourishGradebookTermNavigationViewlet): pass class CanDoSectionNavigationViewlet( CanDoNavigationViewletBase, FlourishGradebookSectionNavigationViewlet): pass class GradebookHelpLinks(flourish.page.RefineLinksViewlet): pass class GradebookSkillsViewlet(flourish.page.ModalFormLinkViewlet): @property def dialog_title(self): section = self.context.__parent__.__parent__.__parent__ if ISkillsGradebook.providedBy(self.context): title = _('${section} Skills', mapping={'section': section.title}) else: title = _('${section} Project Skills', mapping={'section': section.title}) return translate(title, context=self.request) class ScoreSystemHelpViewlet(flourish.page.ModalFormLinkViewlet): @property def dialog_title(self): title = _(u'Score System Help') return translate(title, context=self.request) class ColorCodesHelpViewlet(flourish.page.ModalFormLinkViewlet): @property def dialog_title(self): title = _(u'Color Codes Help') return translate(title, context=self.request) class GradebookSkillsView(flourish.form.Dialog): def initDialog(self): super(GradebookSkillsView, self).initDialog() self.ajax_settings['dialog']['modal'] = False self.ajax_settings['dialog']['draggable'] = True self.ajax_settings['dialog']['maxHeight'] = 640 def update(self): collator = ICollator(self.request.locale) flourish.form.Dialog.update(self) worksheets = self.context.__parent__.__parent__ skillsets = [] for worksheet in worksheets.values(): skills = [] for skill in worksheet.values(): title = skill.title if skill.label: title = '%s: %s' % (skill.label, title) css_class = not skill.required and 'optional' or None skills.append({ 'label': skill.label, 'raw_title': skill.title, 'title': title, 'css_class': css_class, }) is_active = sameProxiedObjects(worksheet, self.context.__parent__) css_class = is_active and 'active' or None skillsets.append({ 'css_class': css_class, 'label': self.getWorksheetLabel(worksheet), 'title': worksheet.title, 'skills': sorted(skills, key=lambda x:(collator.key(x['label'] or ''), collator.key(x['raw_title']))), }) if ISkillsGradebook.providedBy(self.context): skillsets.sort(key=lambda x:(collator.key(x['label'] or ''), collator.key(x['title']))) self.skillsets = skillsets def getWorksheetLabel(self, worksheet): if ISkillsGradebook.providedBy(self.context): unproxied = proxy.removeSecurityProxy(worksheet) return unproxied.label class ScoreSystemHelpView(flourish.form.Dialog): def updateDialog(self): # XXX: fix the width of dialog content in css if self.ajax_settings['dialog'] != 'close': self.ajax_settings['dialog']['width'] = 144 + 16 def initDialog(self): self.ajax_settings['dialog'] = { 'autoOpen': True, 'modal': False, 'resizable': False, 'draggable': True, 'position': ['center','middle'], 'width': 'auto', } def items(self): result = [] scoresystem = querySkillScoreSystem() for score in scoresystem.scores: result.append({ 'score': score[0], 'rating': score[1], }) return result class ColorCodesHelpView(flourish.form.Dialog): def updateDialog(self): # XXX: fix the width of dialog content in css if self.ajax_settings['dialog'] != 'close': self.ajax_settings['dialog']['width'] = 144 + 16 def initDialog(self): self.ajax_settings['dialog'] = { 'autoOpen': True, 'modal': False, 'resizable': False, 'draggable': True, 'position': ['center','middle'], 'width': 'auto', } class ProjectSkillSearchView(flourish.page.Page): # XXX: use a step approach similar to timetable wizard! first_step_template = InlineViewPageTemplate('''
''') second_step_template = InlineViewPageTemplate('''

Child nodes

SkillSets

''') third_step_template = InlineViewPageTemplate('''

Label Title Add

There are no skills.

''') @property def content_template(self): if self.skillset is not None: return self.third_step_template if self.node is not None: return self.second_step_template return self.first_step_template @Lazy def container(self): app = ISchoolToolApplication(None) return INodeContainer(app) @Lazy def skillset_container(self): app = ISchoolToolApplication(None) return ISkillSetContainer(app) @Lazy def node(self): node = self.request.get('node') return self.container.get(node) @Lazy def skillset(self): skillset = self.request.get('skillset') return self.skillset_container.get(skillset) def skills(self): result = [] for skill in self.skillset.values(): input_name = self.getSkillId(skill) checked = self.request.get(input_name) and 'checked' or None result.append({ 'label': skill.label, 'title': skill.title, 'input_name': input_name, 'checked': checked, 'obj': skill, }) return sorted(result, key=lambda i: (self.collator.key(i['label'] or ''), self.collator.key(i['title']))) def getSkillId(self, skill): skillset = skill.__parent__ return '%s.%s' % (skillset.__name__, skill.__name__) def update(self): self.collator = ICollator(self.request.locale) if 'CANCEL' in self.request: self.request.response.redirect(self.nextURL()) return if 'SUBMIT' in self.request: chooser = INameChooser(self.context) for skill in self.skills(): if skill['input_name'] in self.request: skill_copy = skill['obj'].copy() skill_copy.scoresystem = skill['obj'].scoresystem name = chooser.chooseName('', skill_copy) self.context[name] = skill_copy skill_copy.equivalent.add(skill['obj']) self.request.response.redirect(self.nextURL()) def nextURL(self): return '%s/gradebook' % absoluteURL(self.context, self.request) def title_cell_formatter(view_url): def cell_formatter(value, item, formatter): return '%s' % ( view_url, item.__name__, value) return cell_formatter def skillset_title_cell_formatter(view_url): def cell_formatter(value, item, formatter): node = formatter.request.get('node', '') return '%s' % ( view_url, node, item.__name__, value) return cell_formatter class SkillSearchTable(NodesTable): def updateFormatter(self): view_url = '%s/%s' % (absoluteURL(self.view.context, self.request), self.view.__name__) if self._table_formatter is None: self.setUp(formatters=[lambda v,i,f: v, title_cell_formatter(view_url), lambda v,i,f: v,], table_formatter=self.table_formatter, batch_size=self.batch_size, prefix=self.__name__, css_classes={'table': 'data'}) def aggregate_search_title_formatter(view_url): def cell_formatter(value, item, formatter): if INode.providedBy(item): return '%s' % ( view_url, item.__name__, value) elif ISkillSet.providedBy(item): node = formatter.request.get('node', '') return '%s' % ( view_url, node, item.__name__, value) elif ISkill.providedBy(item): node = formatter.request.get('node', '') skill_field_id = '%s.%s' % (item.__parent__.__name__, item.__name__) return '%s' % ( view_url, node, item.__parent__.__name__, skill_field_id, value) return '%s' % value return cell_formatter def get_node_documents(node): layers = NodeLayer.query(node=node) documents = {} if not layers: parents = NodeLink.query(child=node) for parent in parents: parent_docs = get_node_documents(parent) for doc in parent_docs: documents[doc.__name__] = doc else: for layer in layers: layer_docs = DocumentHierarchy.query(layer=layer) for doc in layer_docs: documents[doc.__name__] = doc return tuple(documents.values()) def get_skillset_documents(skillset): documents = {} nodes = NodeSkillSets.query(skillset=skillset) for node in nodes: node_docs = get_node_documents(node) for doc in node_docs: documents[doc.__name__] = doc return tuple(documents.values()) def get_skillset_document_layers(skillset, index=-1): documents = get_skillset_documents(skillset) layers = [] for document in documents: hierarchy_layers = list(document.getOrderedHierarchy()) if len(hierarchy_layers) >= index: layers.append(hierarchy_layers[index]) return layers def get_aggregated_layers(item, formatter): if ISkill.providedBy(item): layers = get_skillset_document_layers(item.__parent__, -1) return u', '.join([l.title for l in layers]) if ISkillSet.providedBy(item): layers = get_skillset_document_layers(item, -2) return u', '.join([l.title for l in layers]) if INode.providedBy(item): return u', '.join([l.title for l in item.layers]) return '' def get_skillset_level_layers(): layers = set() documents = IDocumentContainer(ISchoolToolApplication(None)) for document in documents.values(): hierarchy_layers = list(document.getOrderedHierarchy()) if len(hierarchy_layers) >= 2: layers.add(hierarchy_layers[-2]) return tuple(layers) def get_skill_level_layers(): layers = set() documents = IDocumentContainer(ISchoolToolApplication(None)) for document in documents.values(): hierarchy_layers = list(document.getOrderedHierarchy()) if len(hierarchy_layers) >= 1: layers.add(hierarchy_layers[-1]) return layers class AggregateNodesTableFilter(schooltool.table.ajax.IndexedTableFilter): template = ViewPageTemplateFile('templates/aggregate_filter.pt') skill_layer_id = '__SKILL__' skillset_layer_id = '__SKILLSET__' no_layer_id = '__NOLAYER__' @property def search_id(self): return self.manager.html_id+'-search' @property def search_title_id(self): return self.manager.html_id+'-title' @property def search_index_id(self): return self.manager.html_id+'-index' @property def search_layer_ids(self): return self.manager.html_id+"-layers" def layerContainer(self): app = ISchoolToolApplication(None) return ILayerContainer(app) def layers(self): result = [] layers = getOrderedByHierarchy(self.layerContainer().values()) skillset_layers = get_skillset_level_layers() skill_layers = get_skill_level_layers() items = [(l.__name__, l.title) for l in layers if l not in skillset_layers and l not in skill_layers] skillset_title = _('Skill Set') if skillset_layers: layer_titles = ', '.join([l.title for l in skillset_layers]) skillset_title += ' (%s)' % layer_titles items.append((self.skillset_layer_id, skillset_title)) skill_title = _('Skill') if skill_layers: layer_titles = ', '.join([l.title for l in skill_layers]) skill_title += ' (%s)' % layer_titles items.append((self.skill_layer_id, skill_title)) items.append((self.no_layer_id, _('No layer assigned'))) request_layer_ids = self.request.get(self.search_layer_ids, []) if not isinstance(request_layer_ids, list): request_layer_ids = [request_layer_ids] for id, title in items: checked = (not self.manager.fromPublication or id in request_layer_ids) result.append({'id': id, 'title': title, 'checked': checked}) return result def filter(self, items): if 'aggregate_filter_submitted' not in self.request: return [] request_layer_ids = self.request.get(self.search_layer_ids, []) if not isinstance(request_layer_ids, list): request_layer_ids = [request_layer_ids] request_layer_ids = list(request_layer_ids) found_ids = set() query = buildQueryString(self.request.get('SEARCH', '')) searchable_index_id = 'text' if self.search_index_id in self.request: index_id = self.request[self.search_index_id] if index_id in searchable_common_indexes: searchable_index_id = index_id if self.skill_layer_id in request_layer_ids: catalog = getSkillCatalog() if query: index = catalog[searchable_index_id] found_in_catalog = index.apply(query) else: found_in_catalog = tuple(catalog.extent) found_in_catalog = self.removeRetired(catalog, found_in_catalog) found_ids.update(found_in_catalog) request_layer_ids.remove(self.skill_layer_id) if self.skillset_layer_id in request_layer_ids: catalog = getSkillSetCatalog() if query: index = catalog[searchable_index_id] found_in_catalog = index.apply(query) else: found_in_catalog = tuple(catalog.extent) found_in_catalog = self.removeRetired(catalog, found_in_catalog) found_ids.update(found_in_catalog) request_layer_ids.remove(self.skillset_layer_id) catalog = getNodeCatalog() if query: index = catalog[searchable_index_id] found_in_catalog = set(index.apply(query)) else: found_in_catalog = set(catalog.extent) found_in_catalog = self.removeRetired(catalog, found_in_catalog) index = getNodeCatalog()['layers'] if self.no_layer_id in request_layer_ids: found_no_layers = set(catalog.extent).difference(index.ids()) request_layer_ids.remove(self.no_layer_id) else: found_no_layers = [] found_by_layers = list(index.apply({'any_of': request_layer_ids})) found_by_layers.extend(found_no_layers) found_in_catalog.intersection_update(found_by_layers) found_ids.update(found_in_catalog) result = filter(lambda i: i['id'] in found_ids, items) return result def removeRetired(self, catalog, found_ids): retired = set() index = catalog['retired'] retired = index.values_to_documents.get(True, set()) return set(found_ids).difference(retired) @Lazy def search_indexes(self): order = ( ('text_ID', _('ID')), ('text_label', _('Label')), ('text_title', _('Title')), ) result = [] for index_id, title in order: result.append({ 'id': index_id, 'title': title, }) return result class AggregateNodesSkillsSearchTable(table.ajax.IndexedTable): @Lazy def catalog(self): catalogs = (getNodeCatalog(), getSkillSetCatalog(), getSkillCatalog()) return catalogs def columns(self): view_url = '%s/%s' % (absoluteURL(self.view.context, self.request), self.view.__name__) label = table.column.NoSortIndexedLocaleAwareGetterColumn( index='label', name='label', title=_(u'Label'), getter=lambda i, f: i.label or '' ) title = table.column.IndexedLocaleAwareGetterColumn( index='title', name='title', cell_formatter=aggregate_search_title_formatter(view_url), title=_(u'Title'), getter=lambda i, f: i.title, subsort=True) directlyProvides(title, ISortableColumn) layers = table.column.NoSortIndexedLocaleAwareGetterColumn( index='layers', name='layer_titles', title=_(u'Layers'), getter=get_aggregated_layers, ) return [label, title, layers] def updateFormatter(self): if self._table_formatter is None: self.setUp(table_formatter=self.table_formatter, batch_size=self.batch_size, prefix=self.__name__, css_classes={'table': 'data'}) def items(self): ids = set() items = [] for catalog in self.catalog: new_ids = set() if IExtentCatalog.providedBy(catalog): new_ids.update(set(catalog.extent).difference(ids)) else: for index in catalog.values(): new_ids.update( set(index.documents_to_values.keys()).difference(ids)) items += [{'id': id, 'catalog': catalog} for id in new_ids] ids.update(new_ids) return items def indexItems(self, items): """Convert a list of objects to a list of index dicts""" int_ids = getUtility(IIntIds) item_ids = [int_ids.getId(item) for item in items] catalogs = list(self.catalog) results = [] for item_id in item_ids: indexed = None for catalog in catalogs: if IExtentCatalog.providedBy(catalog): if item_id in catalog.extent: indexed = { 'id': int_ids.getId(item), 'catalog': catalog, } else: for index in catalog.values(): if item_id in index.documents_to_values: indexed = { 'id': int_ids.getId(item), 'catalog': catalog, } break if indexed is not None: results.append(indexed) break return results class NodesSearchTable(AggregateNodesSkillsSearchTable): def columns(self): label = table.column.NoSortIndexedLocaleAwareGetterColumn( index='label', name='label', title=_(u'Label'), getter=lambda i, f: i.label or '' ) title = table.column.IndexedLocaleAwareGetterColumn( index='title', name='title', cell_formatter=table.ajax.url_cell_formatter, title=_(u'Title'), getter=lambda i, f: i.title, subsort=True) directlyProvides(title, ISortableColumn) layers = table.column.NoSortIndexedLocaleAwareGetterColumn( index='layers', name='layer_titles', title=_(u'Layers'), getter=get_aggregated_layers, ) return [label, title, layers] class RetireNodeColumn(table.column.CheckboxColumn): tokens_name = None def __init__(self, *args, **kw): if 'tokens_name' in kw: self.tokens_name = kw.pop('tokens_name') else: prefix = kw.get('prefix') self.tokens_name = '.'.join(filter(None, ["displayed", prefix, "tokens"])) table.column.CheckboxColumn.__init__(self, *args, **kw) def renderHeader(self, formatter): cell = table.column.CheckboxColumn.renderHeader(self, formatter) cell += ('') return cell def renderCell(self, item, formatter): cell = table.column.CheckboxColumn.renderCell(self, item, formatter) cell += ('\n') % ( {'tokens_name': self.tokens_name, 'tokens_value': self.id_getter(item)}) return cell class RetireNodesTable(NodesSearchTable): display_success_dialog = 'DISPLAY_SUCCESS_DIALOG' def columns(self): columns = NodesSearchTable.columns(self) int_ids = getUtility(IIntIds) columns.insert(0, RetireNodeColumn( prefix="active", name="active", title='', id_getter=lambda node: str(int_ids.getId(node)), value_getter=lambda node: node.retired)) return columns @property def success_dialog_title(self): return _('Changes saved') @property def success_dialog_url(self): return '%s/retire_successful.html' % absoluteURL(self.context, self.request) class RetireNodesScript(flourish.viewlet.Viewlet): template = ViewPageTemplateFile('templates/retire_nodes_script.pt') def render(self, *args, **kw): if self.manager.display_success_dialog in self.request: return self.template(*args, **kw) return '' class RetireNodesInstructionViewlet(flourish.viewlet.Viewlet): template = InlineViewPageTemplate('''

Select items to deprecate:

''') def render(self, *args, **kw): if not self.manager._items: return '' return self.template(*args, **kw) class NodesSearchTableFilter(AggregateNodesTableFilter): pass class RetireNodesTableFilter(AggregateNodesTableFilter): def removeRetired(self, catalog, found_ids): return set(found_ids) class SaveRetiredButton(flourish.viewlet.Viewlet): template = flourish.templates.File('templates/retire_nodes_save_button.pt') button_name = 'SAVE_RESULTS' cancel_name = 'CANCEL' token_key = 'displayed.active.tokens' checkbox_key = 'active.' @property def onclick(self): return "$('#%(button_id)s').attr('disabled', 'disabled'); "\ "return ST.table.on_form_submit('%(container_id)s', '#%(button_id)s')" % ({ 'container_id': self.manager.html_id, 'button_id': self.html_id, }) @property def html_id(self): return '-'.join(filter(None, [self.manager.html_id, 'save_button'])) def saveChanges(self): changed = False checkbox_key = self.checkbox_key checked_ids = [iid[len(checkbox_key):] for iid in self.request if (iid.startswith(checkbox_key) and self.request[iid])] displayed_ids = self.request.get(self.token_key, []) if not isinstance(displayed_ids, list): displayed_ids = [displayed_ids] int_ids = getUtility(IIntIds) for sid in displayed_ids: retired = sid in checked_ids try: iid = int(sid) except (TypeError, ValueError): continue node = int_ids.queryObject(iid) if node is None: continue if node.retired != retired: node.retired = retired changed = True zope.lifecycleevent.modified(node) return changed def update(self): if self.button_name in self.request: changed = self.saveChanges() if changed: self.request.form[self.manager.display_success_dialog] = True if self.cancel_name in self.request: self.request.response.redirect(self.nextURL()) def nextURL(self): app = ISchoolToolApplication(None) container = IDocumentContainer(app) return absoluteURL(container, self.request) class NodeChildrenTable(SkillSearchTable): batch_size = 0 def items(self): return self.context.children class NodeSkillSetsTable(SkillSearchTable): batch_size = 0 def columns(self): label, title, layer = super(NodeSkillSetsTable, self).columns() return [label, title] def items(self): return self.context.skillsets def sortOn(self): return (('label', False),) def updateFormatter(self): view_url = '%s/%s' % (absoluteURL(self.view.context, self.request), self.view.__name__) if self._table_formatter is None: self.setUp(formatters=[lambda v,i,f: v, skillset_title_cell_formatter(view_url), lambda v,i,f: v,], table_formatter=self.table_formatter, batch_size=self.batch_size, prefix=self.__name__, css_classes={'table': 'data'}) class SkillAddTertiaryNavigationManager( flourish.page.TertiaryNavigationManager): template = InlineViewPageTemplate("""
""") @property def items(self): result = [] path = self.request['PATH_INFO'] current = path[path.rfind('/')+1:] actions = [ ('addSkillSearch.html', _('Search Skills')), ('addSkillCreate.html', _('New Skill')), ] for action, title in actions: url = '%s/%s' % (absoluteURL(self.context, self.request), action) title = translate(title, context=self.request) result.append({ 'class': action == current and 'active' or None, 'viewlet': u'%s' % (url, title), }) return result class MySkillsGradesView(FlourishMyGradesView): def getActivityInfo(self, activity): result = super(SkillsGradebookOverview, self).getActivityInfo( activity) if not activity.required: cssClass = ' '.join(filter(None, [result['cssClass'], 'optional'])) result['cssClass'] = cssClass return result def processColumnPreferences(self): self.average_hide = True self.total_hide = True self.tardies_hide = True self.absences_hide = True self.due_date_hide = True self.average_scoresystem = None def getActivityAttrs(self, activity): shortTitle, longTitle, bestScore = super( SkillsGradebookOverview, self).getActivityAttrs(activity) longTitle = activity.label + ': ' + longTitle return shortTitle, longTitle, bestScore class MyProjectsGradesView(MySkillsGradesView): pass class SkillSortingColumn(table.column.LocaleAwareGetterColumn): def getSortKey(self, item, formatter): collator = ICollator(formatter.request.locale) skill = item['object'] return (collator.key(skill.label or ''), collator.key(skill.title)) class MySkillsGradesTable(MyGradesTable): visible_column_names = ['skill', 'score'] def columns(self): activity, score = super(MySkillsGradesTable, self).columns() skill_sorting = SkillSortingColumn( name='skill_sorting', title='Skill Sorting Column') skill = zc.table.column.GetterColumn( name='skill', title=_('Skill'), getter=lambda i, f: i['object'], cell_formatter=label_title_formatter) return [skill_sorting, skill, score] def sortOn(self): return (('skill_sorting', False),) class MySkillsGradesYearNavigationViewlet( CanDoYearNavigationViewlet): isTeacher = False class MySkillsGradesTermNavigationViewlet( CanDoTermNavigationViewlet): isTeacher = False class MySkillsGradesSectionNavigationViewlet( CanDoSectionNavigationViewlet): isTeacher = False class MySkillsGradesTertiaryNavigationManager( MyGradesTertiaryNavigationManager): template = ViewPageTemplateFile('templates/cando_third_nav.pt') @property def items(self): result = [] gradebook = proxy.removeSecurityProxy(self.context) current = gradebook.context.__name__ collator = ICollator(self.request.locale) for worksheet in gradebook.worksheets: title = raw_title = worksheet.title label = getattr(worksheet, 'label') if label: title = '%s: %s' % (label, title) url = '%s/mygrades' % absoluteURL(worksheet, self.request) classes = worksheet.__name__ == current and ['active'] or [] if worksheet.deployed: classes.append('deployed') result.append({ 'class': classes and ' '.join(classes) or None, 'viewlet': u'%s' % (title, url, title), 'title': title, 'label': label, 'raw_title': raw_title, }) result.sort(key=lambda x:(collator.key(x['label'] or ''), collator.key(x['raw_title']))) return result class CanDoGradeStudentBase(flourish.page.Page): container_class = 'container widecontainer' @property def title(self): return self.context.student.title @property def subtitle(self): return self.gradebook.section.title @Lazy def student(self): return proxy.removeSecurityProxy(self.context.student) @Lazy def gradebook(self): return proxy.removeSecurityProxy(self.context.gradebook) @Lazy def isSkillsGradebook(self): return ISkillsGradebook.providedBy(self.gradebook) def isIEPSkill(self, iep_skills, skill): skillset = skill.__parent__ return skillset in iep_skills and skill in iep_skills[skillset] @Lazy def timezone(self): app = ISchoolToolApplication(None) prefs = IApplicationPreferences(app) timezone_name = prefs.timezone return pytz.timezone(timezone_name) class CanDoGradeStudentTableViewlet(flourish.viewlet.Viewlet): template = InlineViewPageTemplate('''
''') class CanDoGradeStudent(CanDoGradeStudentBase): @Lazy def evaluator(self): person = IPerson(self.request.principal, None) if person is not None: return getName(person) class CanDoGradeStudentTableFormatter(table.ajax.AJAXFormSortFormatter): def renderCell(self, item, column): klass = self.cssClasses.get('td', '') if column.name == 'student-score': if klass: klass += ' ' klass += 'student-score' if column.name == 'skill' and not item['skill'].required: if klass: klass += ' ' klass += 'optional' if column.name == 'skill' and item['is_iep_skill']: if klass: klass += ' ' klass += 'iep' klass = klass and ' class=%s' % quoteattr(klass) or '' return '%s' % ( item['skill_id'], klass, self.getCell(item, column),) def renderRow(self, item): klass = self.cssClasses.get('tr', '') if klass: klass += ' ' klass += '%s/gradebook' % absoluteURL(item['skillset'], self.request) klass = klass and ' class=%s' % quoteattr(klass) or '' return '%s' % ( klass, self.renderCells(item)) def label_title_formatter(obj, item, formatter): title = obj.title label = getattr(obj, 'label') if label: title = '%s: %s' % (label, title) return title def skill_score_formatter(score, item, formatter): if score is not None and score.value is not UNSCORED: return score.value return '' def get_worksheets(student_gradebook): skills_gradebook = student_gradebook.gradebook section = ISection(proxy.removeSecurityProxy(skills_gradebook)) return ISectionSkills(section) def get_projects(student_gradebook): project_gradebook = student_gradebook.gradebook section = ISection(proxy.removeSecurityProxy(project_gradebook)) return IProjects(section) class CanDoGradeStudentTableBase(table.ajax.Table): batch_size = 0 group_by_column = 'skillset' def getSkillId(self, skill): skillset = skill.__parent__ return '%s.%s' % (skillset.__name__, skill.__name__) @property def worksheets(self): if self.view.isSkillsGradebook: return get_worksheets(self.context) else: return get_projects(self.context) def items(self): result = [] iep = IStudentIEP(self.context.student) iep_skills = iep.getIEPSkills(self.view.gradebook.section) for worksheet in self.worksheets.values(): if self.view.isSkillsGradebook: gradebook = ISkillsGradebook(worksheet) skillset_label = worksheet.label else: gradebook = IProjectsGradebook(worksheet) skillset_label = None for activity in gradebook.activities: is_iep_skill = self.view.isSkillsGradebook and \ self.view.isIEPSkill(iep_skills, activity) score = gradebook.getScore(self.context.student, activity) result.append({ 'gradebook': gradebook, 'score': score, 'skillset': proxy.removeSecurityProxy(worksheet), 'skillset_label': skillset_label, 'skill': activity, 'scoresystem': activity.scoresystem, 'skill_id': self.getSkillId(activity), 'is_iep_skill': is_iep_skill, }) return result def updateFormatter(self): if self._table_formatter is None: self.setUp(table_formatter=self.table_formatter, batch_size=self.batch_size, prefix=self.__name__, css_classes={'table': self.css_classes}) class SkillSetColumn(zc.table.column.GetterColumn): def cell_formatter(self, value, item, formatter): return label_title_formatter(item['skillset'], None, None) def getSortKey(self, item, formatter): collator = ICollator(formatter.request.locale) skillset = item['skillset'] skillset_label = item['skillset_label'] skill = item['skill'] return (collator.key(skillset_label or ''), collator.key(skillset.title), collator.key(skill.label or ''), collator.key(skill.title)) class CanDoGradeStudentTable(CanDoGradeStudentTableBase): css_classes = 'grade-student' table_formatter = CanDoGradeStudentTableFormatter visible_column_names = ['skill', 'student-score'] buttons = ( {'name': 'SAVE', 'label': _('Save'), 'klass': 'button-ok'}, {'name': 'CANCEL', 'label': _('Cancel'), 'klass': 'button-cancel'}, ) def columns(self): skillset = SkillSetColumn( name='skillset', title=_('Skill Set')) skill = zc.table.column.GetterColumn( name='skill', title=_('Skill'), getter=lambda item, formatter: item['skill'], cell_formatter=label_title_formatter) score = zc.table.column.GetterColumn( name='student-score', title=_('Score'), getter=lambda item, formatter: item['score'], cell_formatter=skill_score_formatter) return [skillset, skill, score] def sortOn(self): return (('skillset', False),) def update(self): super(CanDoGradeStudentTable, self).update() saved = False if 'SAVE' in self.request: self.updateGrades() saved = True if 'CANCEL' in self.request or saved: url = absoluteURL(self.view.gradebook, self.request) self.request.response.redirect(url) return def updateGrades(self): for item in self._items: skill = item['skill'] gradebook = item['gradebook'] cell_name = self.getSkillId(skill) if cell_name in self.request: value = self.request[cell_name] try: if value is None or value == '': score = gradebook.getScore(self.context.student, skill) if score: gradebook.removeEvaluation(self.context.student, skill, self.view.evaluator) else: score_value = skill.scoresystem.fromUnicode(value) gradebook.evaluate(self.context.student, skill, score_value, self.view.evaluator) except ScoreValidationError: pass class CanDoGradeStudentTableButtons(flourish.viewlet.Viewlet): template = InlineViewPageTemplate('''
''') class CanDoGradebookPDFView(CanDoGradebookOverviewBase, FlourishGradebookPDFView): name = _('CanDo Gradebook') @Lazy def filtered_activity_info(self): result = super(CanDoGradebookPDFView, self).filtered_activity_info if ISkillsGradebook.providedBy(self.context): collator = ICollator(self.request.locale) result = sorted(result, key=lambda x:(collator.key(x['object'].label or ''), collator.key(x['object'].title))) return result class SkillSetGrid(WorksheetGrid): def updateColumns(self): self.columns = [] for info in self.gradebook_overview.filtered_activity_info: self.columns.append(schooltool.table.pdf.GridColumn( info['shortTitle'], item=info['hash'] )) class StudentCompetencyRecordView(CanDoGradeStudentBase): pass class ScoreDateColumn(table.column.DateColumn): def __init__(self, *args, **kw): self.timezone = kw.pop('timezone') super(ScoreDateColumn, self).__init__(*args, **kw) def getter(self, item, formatter): score = item['score'] if score is not None: time_utc = pytz.utc.localize(score.time) time = time_utc.astimezone(self.timezone) return time.date() def cell_formatter(self, value, item, formatter): view = queryMultiAdapter((value, formatter.request), name='mediumDate', default=lambda: '') return view() def getScoreInfo(score): label, abbr, value, percent = score return label, { 'label': label, 'abbr': abbr, 'value': value, 'percent': percent, } def getScoresByLabel(scoresystem): return dict([getScoreInfo(s) for s in scoresystem.scores]) class ScoreRatingColumn(zc.table.column.GetterColumn): def getter(self, item, formatter): result = '-' score = item['score'] if score is not None: scoresByLabel = getScoresByLabel(item['scoresystem']) score_info = scoresByLabel.get(score.value) if score_info is not None: return score_info['abbr'] or score_info['label'] return result class StudentCompetencyRecordTableFormatter(table.ajax.AJAXFormSortFormatter): def renderCell(self, item, column): klass = self.cssClasses.get('td', '') if column.name == 'required': if klass: klass += ' ' klass += 'flag' klass = klass and ' class=%s' % quoteattr(klass) or '' return '%s' % (klass, self.getCell(item, column),) def score_required_getter(item, formatter): is_required = item['skill'].required and not item['is_iep_skill'] return [_('No'), _('Yes')][is_required] class StudentCompetencyRecordTable(CanDoGradeStudentTableBase): css_classes = 'data student-scr' table_formatter = StudentCompetencyRecordTableFormatter visible_column_names = ['label', 'required', 'skill', 'date', 'rating'] def columns(self): skillset = SkillSetColumn( name='skillset', title=_('Skill Set')) label = zc.table.column.GetterColumn( name='label', title='', getter=lambda item, formatter: item['skill'].label or '') required = zc.table.column.GetterColumn( name='required', title=_('Required'), getter=score_required_getter) skill = zc.table.column.GetterColumn( name='skill', title=_('Skill'), getter=lambda item, formatter: item['skill'].title) date = ScoreDateColumn( name='date', title=_('Date'), timezone=self.view.timezone) rating = ScoreRatingColumn( name='rating', title=_('Rating')) return [skillset, label, required, skill, date, rating] def sortOn(self): return (('skillset', False), ('label', False)) class StudentCompetencyRecordDoneLink(flourish.viewlet.Viewlet): template = InlineViewPageTemplate(''' ''') class ProjectEditView(FlourishWorksheetEditView): fields = field.Fields(IProject).select('title') class CanDoGradeStudentValidateScoreView(FlourishGradebookValidateScoreView): def result(self): result = {'is_valid': True, 'is_extracredit': False} gradebook = proxy.removeSecurityProxy(self.context) score = self.request.get('score') activity_id = self.request.get('activity_id') if score and activity_id: activity = gradebook.context.get(activity_id, None) if activity is not None: scoresystem = activity.scoresystem try: score = scoresystem.fromUnicode(score) except (ScoreValidationError,): result['is_valid'] = False return result class StudentCompetencyReportPDFView(flourish.report.PlainPDFPage, StudentCompetencyRecordView): name = _('Student Skill Report') @property def scope(self): term = ITerm(self.gradebook.section) schoolyear = ISchoolYear(term) return '%s | %s' % (term.title, schoolyear.title) @property def title(self): return self.student.title @property def subtitles_left(self): section = self.gradebook.section teachers = ', '.join([teacher.title for teacher in section.instructors]) courses = ', '.join([course.title for course in section.courses]) codes = ', '.join(filter(None, [course.course_id for course in section.courses])) if codes: courses += ' (%s)' % codes return [ _('Teacher(s): ${teachers}', mapping={'teachers': teachers}), _('Course: ${courses}', mapping={'courses': courses}), ] @property def base_filename(self): return 'student_skill_report_%s_%s_%s' % ( self.student.last_name, self.student.first_name, self.student.username) class CanDoStudentGradebookReportTask(ReportTask): @property def context(self): int_ids = getUtility(IIntIds) student = int_ids.queryObject(self.student_intid) worksheet = int_ids.queryObject(self.worksheet_intid) gradebook = ISkillsGradebook(worksheet) student_gradebook = getMultiAdapter((student, gradebook), ICanDoStudentGradebook) return student_gradebook @context.setter def context(self, value): student_gradebook = proxy.removeSecurityProxy(value) student = student_gradebook.student gradebook = student_gradebook.gradebook worksheet = gradebook.context int_ids = getUtility(IIntIds) student_intid = int_ids.getId(student) worksheet_intid = int_ids.getId(worksheet) self.student_intid = student_intid self.worksheet_intid = worksheet_intid class RequestStudentCompetencyReportView(RequestRemoteReportDialog): report_builder = StudentCompetencyReportPDFView task_factory = CanDoStudentGradebookReportTask class StudentCompetencyReportSkillsTablePart(table.pdf.RMLTablePart): table_name = 'student_grades_table' def getColumnWidths(self, rml_columns): return '7% 10% 53% 15% 15%' class RMLSkillColumn(table.pdf.RMLGetterColumn): style = table.pdf.Config( para_class='skill-cell', ) def renderCell(self, item, formatter): value = self.column.getter(item, formatter) return '%s' % ( self.style.para_class, self.escape(value)) def getScoreSystems(student_gradebook): result = {} worksheets = get_worksheets(student_gradebook) for worksheet in worksheets.values(): for activity in worksheet.values(): scoresystem = proxy.removeSecurityProxy(activity.scoresystem) if scoresystem not in result: scoresByLabel = getScoresByLabel(scoresystem) is_max_passing = scoresystem._isMaxPassingScore scores = sorted(scoresByLabel.values(), key=lambda x:x['value'], reverse=not is_max_passing) scoresDict = scoresystem.scoresDict result[scoresystem] = { 'obj': scoresystem, 'scoresDict': scoresDict, 'scores': scores, 'passing_score': scoresDict[scoresystem._minPassingScore], 'is_max_passing': is_max_passing, 'name': scoresystem.__name__, } return result class CompetencyCertificatePDFView(flourish.report.PlainPDFPage, CanDoGradeStudentBase): name = _(u'Certificate of Competency') @property def title(self): return self.student.title def formatDate(self, date, format='longDate'): if date is None: return '' formatter = getMultiAdapter((date, self.request), name=format) return formatter() @property def scope(self): dtm = getUtility(IDateManager) today = dtm.today return self.formatDate(today) @property def subtitles_left(self): section = self.gradebook.section courses = ', '.join([course.title for course in section.courses]) return [ _('Course: ${courses}', mapping={'courses': courses}), ] @Lazy def scoresystems(self): result = getScoreSystems(self.context) return result @Lazy def scoresystem_filters(self): result = {} for ss_info in self.scoresystems.values(): requested_passing_score = self.request.get(ss_info['name']) scoresDict = ss_info['scoresDict'] if requested_passing_score is not None: result[ss_info['name']] = scoresDict[requested_passing_score] else: result[ss_info['name']] = ss_info['passing_score'] return result @property def base_filename(self): return 'certificate_of_competency_%s_%s_%s' % ( self.student.last_name, self.student.first_name, self.student.username) class RequestCompetencyCertificateView(RequestRemoteReportDialog): report_builder = CompetencyCertificatePDFView task_factory = CanDoStudentGradebookReportTask template = ViewPageTemplateFile( 'templates/request_competency_certificate.pt') @Lazy def scoresystems(self): result = getScoreSystems(self.context) return result def sorted_scoresystems(self): collator = ICollator(self.request.locale) return sorted(self.scoresystems.values(), key=lambda v: collator.key(v['obj'].title)) def is_selected(self, ss_info, score_info): requested_passing_score = self.request.get(ss_info['name']) if requested_passing_score is not None: return requested_passing_score == score_info['label'] return score_info['value'] == ss_info['passing_score'] def schedule(self, task): params = {} for ss_info in self.scoresystems.values(): requested_passing_score = self.request.get(ss_info['name']) if requested_passing_score is not None: params[ss_info['name']] = requested_passing_score task.request_params.update(params) task.schedule(self.request) class CompetencyCertificateSkillsTablePart(table.pdf.RMLTablePart): table_name = 'student_grades_table' visible_column_names = ['skill', 'rating'] def getColumnWidths(self, rml_columns): return '85% 15%' class CompetencyCertificateSignaturePart(flourish.report.PDFPart): template = flourish.templates.XMLFile( 'rml/competency_certificate_signature.pt') class CompetencyCertificateTableFilter(table.ajax.TableFilter): def filter(self, items): items = [item for item in items if item['score'] is not None and item['score'].value is not UNSCORED] if items: scoresystems = self.view.scoresystems result = [] for item in items: ss_info = scoresystems[item['scoresystem']] is_max_passing = ss_info['is_max_passing'] scoresDict = ss_info['scoresDict'] score_value = scoresDict[item['score'].value] passing_score = self.view.scoresystem_filters[ss_info['name']] append = False if not is_max_passing: append = score_value >= passing_score else: append = score_value <= passing_score if append: result.append(item) items = result result = super(CompetencyCertificateTableFilter, self).filter(items) return result def render(self, *args, **kw): return '' class SkillsGradebookReportTask(ReportTask): @property def context(self): int_ids = getUtility(IIntIds) worksheet = int_ids.queryObject(self.worksheet_intid) gradebook = ISkillsGradebook(worksheet) return gradebook @context.setter def context(self, value): gradebook = proxy.removeSecurityProxy(value) worksheet = gradebook.context int_ids = getUtility(IIntIds) worksheet_intid = int_ids.getId(worksheet) self.worksheet_intid = worksheet_intid class StudentCompetencySectionReportPDFView(flourish.report.PlainPDFPage, StudentCompetencyRecordView): name = _('Student Skill Report') @property def scope(self): gradebook = proxy.removeSecurityProxy(self.context) term = ITerm(gradebook.section) schoolyear = ISchoolYear(term) return '%s | %s' % (term.title, schoolyear.title) @property def base_filename(self): gradebook = proxy.removeSecurityProxy(self.context) section = gradebook.section courses = [c.__name__ for c in section.courses] return 'aggregated_student_skill_reports_%s' % '_'.join(courses) class RequestStudentCompetencySectionReportView(RequestRemoteReportDialog): report_builder = StudentCompetencySectionReportPDFView task_factory = SkillsGradebookReportTask class NoHeaderPlainPageTemplate(flourish.report.PlainPageTemplate): @property def header(self): default = super(NoHeaderPlainPageTemplate, self).header default['height'] = 0 return default class StudentCompetencySectionReportPDFStory(flourish.report.PDFStory): def render(self): result = [] collator = ICollator(self.request.locale) gradebook = proxy.removeSecurityProxy(self.context) section = gradebook.section factory = getUtility(IPersonFactory) sorting_key = lambda x: factory.getSortingKey(x, collator) for student in sorted(section.members, key=sorting_key): student_gradebook = getMultiAdapter((student, gradebook), ICanDoStudentGradebook) student_scr = getMultiAdapter( (student_gradebook, self.request, self.view, self), name="student_scr") student_scr.update() student_scr.__name__ = 'student_scr' result.append(student_scr.render()) return ''.join(result) class StudentSCRPart(flourish.report.PDFPart): template = flourish.templates.XMLFile('rml/section_student_scr.pt') def teachers(self): gradebook = proxy.removeSecurityProxy(self.context.gradebook) section = gradebook.section return ', '.join([teacher.title for teacher in section.instructors]) def courses(self): gradebook = proxy.removeSecurityProxy(self.context.gradebook) section = gradebook.section courses = ', '.join([course.title for course in section.courses]) codes = ', '.join(filter(None, [course.course_id for course in section.courses])) if codes: courses += ' (%s)' % codes return courses def scr_table(self): self.view.__name__ = 'foobar' view = getMultiAdapter( (self.context, self.request), name='student_competency_report.html') view.__name__ = 'student_competency_report.html' grades_table = getMultiAdapter( (self.context, self.request, view, self.manager), name="student_grades_table") grades_table.__name__ = 'student_grades_table' # XXX: make StudentCompetencyReportSkillsTablePart registration # more generic and get rid of this awful monkey patching rml_table = getMultiAdapter( (self.context, self.request, view, grades_table), table.interfaces.IRMLTable) rml_table.__name__ = 'rml_table' rml_table.getColumnWidths = lambda x: '7% 10% 53% 15% 15%' rml_table.update() return rml_table.render() class StudentCompetencyArchivePage(ReportArchivePage): message_title = _("skill gradebooks archive") base_filename = 'skill_gradebooks' class ArchiveCompetencySectionReports(FileArchiver): sections_by_term = None report_builder = 'student_competency_section_report.pdf' def collectTerms(self, schoolyear_id=None): app = ISchoolToolApplication(None) syc = ISchoolYearContainer(app) archive_terms = [] for year_id, year in syc.items(): if (schoolyear_id is None or year_id == schoolyear_id): for term in year.values(): archive_terms.append(term) return archive_terms def collectSections(self, terms): archive_sections = [] if not terms: return archive_sections for term in terms: sections = [] sc = ISectionContainer(term) for section in sc.values(): sections.append(section) if sections: archive_sections.append((term, sections)) return archive_sections def updateTargets(self): terms = self.collectTerms() sections = self.collectSections(terms) self.sections_by_term = sections def update(self): FileArchiver.update(self) self.updateTargets() def renderReport(self, renderer, filename, archive): renderer.update() rml = renderer.render() pdf_filename = renderer.filename pdf_stream = rml2pdf.parseString(rml, filename=pdf_filename or None) data = pdf_stream.getvalue() archive.writestr(filename, data) def renderSection(self, section, filename, archive): request = self.request if hasattr(request, 'clone'): request = request.clone() skills = ISectionSkills(section) if not skills: return worksheet = skills.values()[0] gradebook = ISkillsGradebook(worksheet) renderer = self.queryView( gradebook, request, self.report_builder) if renderer is None: return self.renderReport(renderer, filename, archive) def getFullFilename(self, year, term, section): filename = '%s/%s/%s-skills.pdf' % ( year.__name__, term.__name__, section.__name__) return filename def render(self, archive): total_files = sum([len(sections) for term, sections in self.sections_by_term]) file_n = 0 first_run = True for term, sections in self.sections_by_term: year = ISchoolYear(term) self.setTitle(u'%s, %s' % (year.title, term.title)) for section in sections: filename = self.getFullFilename(year, term, section) self.progress(filename, file_n, total_files) if first_run: # Push out update progress immediately self.view.task_progress.force() first_run = False self.renderSection(section, filename, archive) file_n += 1 self.finish() schooltool.cando-2.6.2/src/schooltool/cando/browser/__init__.py0000644000175000017500000000002112270520445025747 0ustar menesismenesis00000000000000# Make a package schooltool.cando-2.6.2/src/schooltool/cando/browser/resources/0000755000175000017500000000000012322040274025652 5ustar menesismenesis00000000000000schooltool.cando-2.6.2/src/schooltool/cando/browser/resources/ui-icons_222222_256x240.png0000644000175000017500000001042112270520445031736 0ustar menesismenesis00000000000000‰PNG  IHDRðØIJùíPLTE$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$ðÈNtRNS2P¿ƒ™."Tp@f`Í <BHJZ&0R,…4‡ÃjÉÏÇ8D½¹|«µ¥©­³(ýŸ$ï £b•¡¯lßF>n~‘hhÒHý…IDATxœí]bÛ¶ÉHªå„’-{iìZK:gó’lk×n­š-©ÓtI×õÞÿq€q? E²$ÛødK>$î>Á;”•ÊÈÈØPìZ…¢ØsÖV¯€h!˜Sy»„0E·0}H¹)-ðàæt k€íoÿܪKp”\RÎÏ  €ï.•E‹7¡¿ š)— *V;~ôPeÞâ Bx°*ò,=$z†¥Dؾ„í¢¬ úÅJ±½ÛïÒ¸Ù»¿„¶Ø9î{ ”‘‘‘‘‘‘±Ç¸ñHpÇqW@Äò"2'ðŸÛBúè[¥$ € @TàÕiºHÕ/äábÙ¥9ú6“!¡XãHq`DE¤Ç*RΖ€­ HV!Ÿ%ÙÚã…¢;ÐòÔðÁîÓá"¢ñúãò ÙiÆ]¿ ddddddddìëþÉÐ4yüµ5 ôô ‰Rb¹@(”8šÜÛCd‡öŪÐÝ¡¯,Ü@T@i¼ýÐb‰rq0alX!ô¶”ú° ¯p‰öeº, ëß=4bW ¼{¤ 5°­ÍƬhu~À(ÁQŠ^@ãó3Ú=î¢é"…bÿä5XC@J‘ޏC‡ª¤ú€Té®ï7¼ú6™‘‘‘‘‘‘q_±þ²Ô5à ©@,r šɩªDó«)°Tñ|žOœ…@å ON-Õ™ÊýÉ §÷¥’âýíò[n@ìØR¼¡™XôIm‹Ý‹(‰µá¡F Ê@”?±ð=0Þ puL‘˜;g$Òá@6η„ô „K`Êý>п» @h Õ£åüKV€nÅ"a¦"« ù%l‚@.v‰$/ðU^ôÖ GÈ:#`` ’ €u‚¬TtK©Þ~àÅ‹ÃZ Ýù5T¼¿‰%ÖkìõxÀ®ŸÉÈÈÈÈÈØkÜì]\*ìQÙÀ› ,Ò‡‹ÒëB†ª44 ÚOXKÍ|Šy‚Îgƒ¹Á+_M¤(ûlоEžO„ú V$ûT1BXõõ’b¢-Š|?@ ÔfóÕBßXràö%'@Ò¹A\ºI´á¹J,}†€BBcáó\V ñÊrÁ§£h(Ò]tIÈì^ªó¡}ÜÇÅoÎצo ¾S3ƒ ";£Ï÷Ê™ºìÑÁb}Ü"ß° —Ù){b$‘½¦¥ÆâãGwwݾŒŒŒŒŒ»ò–ßÈa‡œÞb"Þð)öïÓT@pš…F_er6JvШ¨áöÁ"mèÞ­¬M-ÁŸd7óê6”Ðx€¯¯„˰6Ó¥;Èì…/¯×ö“ìŒ`>KrP\Äö°_¸Ùë^uŒ1%“ÛOúT‚M²­è.±}¹–ðQ3æêñ€¶.Nسäã}«¡)½—ð>€÷ûäþ-âw`—ê—aƒø—ÿ+sy$ã€äÊt‡ø—)ÜN¬bFFFFÆýBeâ„jùúnNŠ¡Vn4ŒÕø,¹ÁA*õ™Xñâ*ÎÇ5«¤>ÙãP‹‡ªGæ…êa ¶ƒ3 Õõ{öoBˆ ‹&<ô”L[ §ÄÞNc.‹™­Ã¶Üi=Ã`ãQ@‰d‚¯µ ͆I¨Å.I«ëºlÀ`\tà[< èCit¡48Àù4É-rÀ Ž+ÀÌf³Øì‘±‚B€CB ÓÑMH i¤„Ÿôy }˜†Û>ÀÉÍrx¤ñ‰ÝýÄp|zø;BÀãÇ;áb±u¯‹rŒýŸc¨K¶Ÿú4t ôzÀ‘1†G~ ²þß`Ž†ØšÃùêKàÉ| Ì”>ú½Û¡²¯O$ÀØÿðìó~ ¶Ao)Š£¥0pzz ½}i´ý˜ûÓ`;ADÀ¹ÙûüÜm8n:ÁcfÚA@s7ºÁðŸ˜Lê÷ºÞ Z /..À»¨ð€êh8Ôoþ°r? Ú ÅNÇã9Œñ3BèÒ~o_ØÞ'`Àâo„€îpO-˜Ë :¸TGî L;ôÇ7ÇÝ]`ìÚ°B’€Ô%€Ë›>°î*wT´½îpMŸ©0HÝ}&t ¦ò·îÎ^1ˆÖ'Oqór'À2P«Í¡ª¦+Äz,tIW''|enÔþŒŒŒŒŒ=dzgñòRÌm˜[Nò¶Sùt÷K{›úÒ‰m²Ý娓Vžtû6¡ÉáÒ²R`úÔÑûšÎ¶NØ&}ÛöB Uå™(òr<ôqÈVyrÐrA**¿Ýدzg6ÓD#›± —–›óÑYP›`®ìîí¥áv‚Ïés€çÌ~(zûMlÞe¿|u¸ÌüQ¿a…*}ž+TŸÌ ²€ú“ºRÆùíX c"+*Ÿ NlôŸNûhc¿Ft‡ÀÛ—&àÅù‡ú¶¿Ô1%ØQ''ßê×?œlÚÃ׸•+&£r{ýj¸N‘಻® æ4ü) ÚËÃ`¨N狌€.½ Ûß­ˆ  ùüëÇ£Çÿü®•Üá—“§ôì)q ´2Ÿ?÷²ñýn¼3H€bÐÌø`ï}Ø ÷—­Âþ.`–ñõú§ìpqY1ûe_bûÕËïu÷7ùþe+NÍõ_Fö†¶Ý(êDTƒü,àÃÞL}LLžrûùmP5‹º|±x芥1Œc…ûŠx DAb ŒŒŒŒŒ`ˆ¦M(±ê7¼´ÐNEDï~žÏMzé Ðö+4ÆçÉBXd.ŽÃMzþËv͈ë¾µÓÏð¶«P×d8‰p¬ÿ<6?®Ø8ØN‘ý*xõêèÕ.»¾6Ú6G÷€­ìFåZû½ã…Å)ÝݦOéÉÉ ! ùlÅSsýÓÐh³èíæssàNðõp8Ú`'´0ö/<Æþš¤£s£ï©ß}ñ.æ@ǨÛsƒ7ξ§OÛŸVîDúú€a5ŸÏaŽvÜô]๘õúðÔm1™ø+ÝêŸÒ3äÃýyè6ðÛ õ‹ž>@ßu50ëÀPÚsÿÜÅ5‚¤1=Æë=§pý¢ *ÂKV•Ò«Ü‚Õã€ÝãøÝ»c$N®4(úX¹r2###c- ñê賟LóÓÙδÙ>޼]¯ûó5Ú.žsŸ´ÂYsÇ1ïÞf0Ã;ü'̨¦˜Yþg銛Â{“@9øà øÐÕ`aC(ލ=%bêoà2ÌÌ=­†Þnœò¤1ø jœ‡BŸ’o¨½S$nùãà#Ím“ݘú=iœê0ÁcÊÚï§ÝÈþÐÒÝi9Åö}ÔoI…Ù ¨Ýù®qãT‡š]òW%.Ãö‡(‰ËØ…æ]zÛ\ðx f³Ùö"]o°×'uÐ䫵tŠk{Àv;AëÍC3Ö†wž€w¨R_#÷±X» Þ(x§÷Ò‹/q%¶èùW¸ ¨þÅ›ÇÌÜhpíÄk_IöXŠùÇ'b§Éú/fXÞþ²Köi´"#####ã†QCL¼iÀˆ2téè àà€Ê5¬¶L0 ¶¬ÄêQiÞH“2;yÒTêOok;×¢ì Ù¶`õÃRš²Ng{z´y¼!—Kx²¢²·çmì?A(vø£UÒ~Œ°ÎmLÀ(`o/!nòÿ¤°mXŠ€-{ÀvûŽ÷[¾ € dÇw=Àn「ŒŒŒŒûøsdwåüzŽÖnê(åò}O®yŽ~­Ñó ãúmà ›ðï?XUÞ;,àš…V'+û €VŸ&ïJ¸Rê×Z]á§­§:£¥Ï×zC'ýÓ-߆ºžÝÈ@åy ö4¼­Úuó—þ §`VÛ“wö«ÑŠ#÷ýzP@Q˜ N>2/ÿý{¦\o)Žö”ëWøŒ›~a3xLÀw :_QÞ;Œì=pŠÖ¼èdt§Ãî\'8¸º¼ÂÝ~3áSRPÛ¡Ú6Æïõùy+ŸšÏÈÈÈÈXüù€”ÌQ­*¯ÚÞºr üù€”Ì—Ñ­*¯ÚÞºr gÐál™/¤\U^µ½uå$øóüœ|mbÃëVn–ÒÚòw \V½å|ù‡ÞöDËÍŠNVNåæþy‡À7ì¢ÚÙàëk<;œª/ËE}?E*dzgáO ú¨ß~ûègþœ/9¿®6˜Êæê½f c…D}% Š×g$õQî·Gž7öoŽ€)úº¡ÏU J¶ð˜˜o™,O@ú0ß¾Q(íòÀä;žbõ¹¬˜wõ“àÏ:5× úNŒwRÀåþN5ØIòöy'KË?}²¹:9‰mֽ߯®*§±í@fÝ@jU9m‡²ë†Ò«Ê´ÃÉ{öÿÓò$âØ——}öídF€âÿôp¿Ñ|%!DdF¸·>™ýû»}Gö€{ßÜ÷»@FFFFFFƦQÜžH ¹ ªÕºìÿí3 •Ðu øù¾Möo¸½·Ê~êvy»}¡mûwz<Ø7õ•ïnP9ørÆWkÿíñu= ©¯°|«ì_×n½ýëÞz쿳}@ÞþÛãIXÆn÷›‘±çø?Éæs¶@ggÿÿÿÿ » Ì dü©ñÒMbP?_€%ÿÁ*+‚&C&P&C&Fƒ„&333333Ó?'333333Ó?(-Ø‚-Ø‚ã?)[°[°×?¡" dƒ,,š™™™™™¹?š™™™™™¹?U } ” } Ë} ” ÿý ý ý ìPðH ðð0ð( ð ð>¶@ggÿÿÿÿ » Ì dü©ñÒMbP?_€%ÿÁ*+‚# &C&"Times New Roman,Normal"&12&A(%&C&"Times New Roman,Normal"&12Page &Pƒ„&333333é?'333333é?(ƒ-Ø‚-Øð?)ƒ-Ø‚-Øð?¡"d,,333333é?333333é?U } ” } o} q } a}  } ”   ý ý ý ý ý ý ý ý ý  ìPðH0ð ð0ð( ð ð >¶@ggÿÿÿÿ » Ì dü©ñÒMbP?_€%ÿÁ*+‚# &C&"Times New Roman,Normal"&12&A(%&C&"Times New Roman,Normal"&12Page &Pƒ„&333333é?'333333é?(ƒ-Ø‚-Øð?)ƒ-Ø‚-Øð?¡"d,,333333é?333333é?U } ” ý ý ý ý ý  ìPðH@ðð0ð( ð ð>¶@ggÿÿÿÿ » Ì dü©ñÒMbP?_€%ÿÁ*+‚# &C&"Times New Roman,Normal"&12&A(%&C&"Times New Roman,Normal"&12Page &Pƒ„&333333é?'333333é?(ƒ-Ø‚-Øð?)ƒ-Ø‚-Øð?¡"d,,333333é?333333é?U } ” } %} x} ” } »} ”   ý  ý  ý ý  ý ý  ý ý ý  ìPðHPðð0ð( ð ð>¶@ggÿÿÿÿ » Ì dü©ñÒMbP?_€%ÿÁ*+‚# &C&"Times New Roman,Normal"&12&A*'&C&"Times New Roman,Normal"&12Página &Pƒ„&333333é?'333333é?(ƒ-Ø‚-Øð?)ƒ-Ø‚-Øð?¡"d,,333333é?333333é?U } ˆ ý ý ý ìPðH`ðð0ð( ð ð>¶@ggÿÿÿÿ þÿÿÿþÿÿÿþÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿ ÿÿÿÿÀFMicrosoft Excel 97-TabelleBiff8þÿà…ŸòùOh«‘+'³Ù0˜@H \ h t € Œéý Douglas 65@€P8I@@@€{å¤é—ÎþÿÕÍÕœ.“—+,ù®DÕÍÕœ.“—+,ù®\éýéýRoot EntryÿÿÿÿÿÿÿÿÀF @WorkbookÿÿÿÿíCompObjÿÿÿÿÿÿÿÿIOle ÿÿÿÿÿÿÿÿÿÿÿÿSummaryInformation(ÿÿÿÿÿÿÿÿÈDocumentSummaryInformation8ÿÿÿÿÿÿÿÿÿÿÿÿtÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿschooltool.cando-2.6.2/src/schooltool/cando/browser/resources/cando.js0000644000175000017500000001212112270520445027276 0ustar menesismenesis00000000000000ST.cando = function () { return { column_select_all: function (input) { var checkbox = $(input), index = checkbox.parent().index(), table = checkbox.closest('table'), column = table.find('tbody tr').find('td:eq('+index+')'), checkboxes = column.find('input[type="checkbox"]'); checkboxes.attr('checked', checkbox.is(':checked')); } }; }(); function isScorable(td) { var columnHeader = findColumnHeader(td); if (columnHeader.length > 0 && columnHeader.hasClass('scorable')) { return true; } else { return td.hasClass('student-score'); } } function cellInputName(td) { var columnHeader = findColumnHeader(td); var rowHeader = findRowHeader(td); if (columnHeader.length > 0 && rowHeader.length > 0) { return [columnHeader.attr('id'), '_', rowHeader.attr('id')].join(''); } else { if (td.hasClass('student-score')) { return td.attr('id'); } } } $(document).ready(function() { var container = $('#skill-title'); var skill_title = container.find('p'); $('#grades-part').on('mouseover', '.popup_link', function() { var link = $(this); var th = link.parent(); skill_title.text(link.attr('title')); if (th.hasClass('optional')) { skill_title.attr('class', 'optional'); } else { skill_title.attr('class', 'required'); } }); var normal_width = 748; var wide_width = 940; $('#gradebook-controls').on('click', '.expand', function() { container.css({ left: 16 }); skill_title.css({ width: wide_width }); }); $('#gradebook-controls').on('click', '.collapse', function() { container.css({ left: 208 }); skill_title.css({ width: normal_width }); }); // tertiary navigation var third_nav_container = $('#third-nav-container'); var third_nav = third_nav_container.find('.third-nav'); var active_tab = third_nav.find('.active'); var tab_width = active_tab.outerWidth(); if (third_nav.children().length > 0) { var scrollTo = tab_width * (active_tab.index()); third_nav_container.scrollTo(scrollTo, 0, {axis: 'x'}); $('#navbar-list-worksheets').removeClass('navbar-arrow-inactive'); } third_nav.on('click', 'li', function(e) { if ($('#worksheets-list').length < 1) { var ul = createWorksheetsList(); $('#navbar-list-worksheets').after(ul); } $('#worksheets-list').slideToggle('fast'); $('#navbar-list-worksheets').toggleClass('navbar-list-worksheets-active'); e.preventDefault(); }); // student gradebook grades = $('table.grade-student').closest('.content'); grades.on('click', 'tbody td.student-score', function() { var td = $(this); if (isScorable(td)) { var input = getInput(td); input[0].select(); input.focus(); } }); grades.on('click', 'input', function() { this.select(); }); grades.on('blur', 'input', function() { var td = $(this).parent(); if ($(this).val() === td.attr('original')) { removeInput(td); } }); grades.on('keyup', 'input', function() { var input = $(this); var td = input.parent(); var tr = td.parent(); if (input.val() !== td.attr('original')) { if (this.timer) { clearTimeout(this.timer); } var data = { 'activity_id': cellInputName(td).split('.')[1], 'score': input.val() }; var url = tr.attr('class') + '/validate_student_score'; this.timer = setTimeout(function () { $.ajax({ url: url, data: data, dataType: 'json', type: 'get', success: function(data) { input.removeClass(); var css_class = 'valid'; if (!data.is_valid) { css_class = 'error'; } else if (data.is_extracredit) { css_class = 'extracredit'; } input.addClass(css_class); } }); }, 200); } }); grades.on('keydown', 'input', function(e) { var td = $(this).parent(); var tr = td.parent(); switch(e.keyCode) { case 27: // escape $(this).val(td.attr('original')); $(this).blur(); e.preventDefault(); break; case 38: // up focusInputVertically(tr.prevUntil('tbody'), td.index()); e.preventDefault(); break; case 13: // enter case 40: // down focusInputVertically(tr.nextAll(), td.index()); e.preventDefault(); break; } }); }); schooltool.cando-2.6.2/src/schooltool/cando/browser/resources/ui-icons_ffffff_256x240.png0000644000175000017500000001042112270520445032426 0ustar menesismenesis00000000000000‰PNG  IHDRðØIJùíPLTEüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþü° ¼NtRNS2P¿ƒ™."Tp@f`Í <BHJZ&0R,…4‡ÃjÉÏÇ8D½¹|«µ¥©­³(ýŸ$ï £b•¡¯lßF>n~‘hhÒHý…IDATxœí]bÛ¶ÉHªå„’-{iìZK:gó’lk×n­š-©ÓtI×õÞÿq€q? E²$ÛødK>$î>Á;”•ÊÈÈØPìZ…¢ØsÖV¯€h!˜Sy»„0E·0}H¹)-ðàæt k€íoÿܪKp”\RÎÏ  €ï.•E‹7¡¿ š)— *V;~ôPeÞâ Bx°*ò,=$z†¥Dؾ„í¢¬ úÅJ±½ÛïÒ¸Ù»¿„¶Ø9î{ ”‘‘‘‘‘‘±Ç¸ñHpÇqW@Äò"2'ðŸÛBúè[¥$ € @TàÕiºHÕ/äábÙ¥9ú6“!¡XãHq`DE¤Ç*RΖ€­ HV!Ÿ%ÙÚã…¢;ÐòÔðÁîÓá"¢ñúãò ÙiÆ]¿ ddddddddìëþÉÐ4yüµ5 ôô ‰Rb¹@(”8šÜÛCd‡öŪÐÝ¡¯,Ü@T@i¼ýÐb‰rq0alX!ô¶”ú° ¯p‰öeº, ëß=4bW ¼{¤ 5°­ÍƬhu~À(ÁQŠ^@ãó3Ú=î¢é"…bÿä5XC@J‘ޏC‡ª¤ú€Té®ï7¼ú6™‘‘‘‘‘‘q_±þ²Ô5à ©@,r šɩªDó«)°Tñ|žOœ…@å ON-Õ™ÊýÉ §÷¥’âýíò[n@ìØR¼¡™XôIm‹Ý‹(‰µá¡F Ê@”?±ð=0Þ puL‘˜;g$Òá@6η„ô „K`Êý>п» @h Õ£åüKV€nÅ"a¦"« ù%l‚@.v‰$/ðU^ôÖ GÈ:#`` ’ €u‚¬TtK©Þ~àÅ‹ÃZ Ýù5T¼¿‰%ÖkìõxÀ®ŸÉÈÈÈÈÈØkÜì]\*ìQÙÀ› ,Ò‡‹ÒëB†ª44 ÚOXKÍ|Šy‚Îgƒ¹Á+_M¤(ûlоEžO„ú V$ûT1BXõõ’b¢-Š|?@ ÔfóÕBßXràö%'@Ò¹A\ºI´á¹J,}†€BBcáó\V ñÊrÁ§£h(Ò]tIÈì^ªó¡}ÜÇÅoÎצo ¾S3ƒ ";£Ï÷Ê™ºìÑÁb}Ü"ß° —Ù){b$‘½¦¥ÆâãGwwݾŒŒŒŒŒ»ò–ßÈa‡œÞb"Þð)öïÓT@pš…F_er6JvШ¨áöÁ"mèÞ­¬M-ÁŸd7óê6”Ðx€¯¯„˰6Ó¥;Èì…/¯×ö“ìŒ`>KrP\Äö°_¸Ùë^uŒ1%“ÛOúT‚M²­è.±}¹–ðQ3æêñ€¶.Nسäã}«¡)½—ð>€÷ûäþ-âw`—ê—aƒø—ÿ+sy$ã€äÊt‡ø—)ÜN¬bFFFFÆýBeâ„jùúnNŠ¡Vn4ŒÕø,¹ÁA*õ™Xñâ*ÎÇ5«¤>ÙãP‹‡ªGæ…êa ¶ƒ3 Õõ{öoBˆ ‹&<ô”L[ §ÄÞNc.‹™­Ã¶Üi=Ã`ãQ@‰d‚¯µ ͆I¨Å.I«ëºlÀ`\tà[< èCit¡48Àù4É-rÀ Ž+ÀÌf³Øì‘±‚B€CB ÓÑMH i¤„Ÿôy }˜†Û>ÀÉÍrx¤ñ‰ÝýÄp|zø;BÀãÇ;áb±u¯‹rŒýŸc¨K¶Ÿú4t ôzÀ‘1†G~ ²þß`Ž†ØšÃùêKàÉ| Ì”>ú½Û¡²¯O$ÀØÿðìó~ ¶Ao)Š£¥0pzz ½}i´ý˜ûÓ`;ADÀ¹ÙûüÜm8n:ÁcfÚA@s7ºÁðŸ˜Lê÷ºÞ Z /..À»¨ð€êh8Ôoþ°r? Ú ÅNÇã9Œñ3BèÒ~o_ØÞ'`Àâo„€îpO-˜Ë :¸TGî L;ôÇ7ÇÝ]`ìÚ°B’€Ô%€Ë›>°î*wT´½îpMŸ©0HÝ}&t ¦ò·îÎ^1ˆÖ'Oqór'À2P«Í¡ª¦+Äz,tIW''|enÔþŒŒŒŒŒ=dzgñòRÌm˜[Nò¶Sùt÷K{›úÒ‰m²Ý娓Vžtû6¡ÉáÒ²R`úÔÑûšÎ¶NØ&}ÛöB Uå™(òr<ôqÈVyrÐrA**¿Ýدzg6ÓD#›± —–›óÑYP›`®ìîí¥áv‚Ïés€çÌ~(zûMlÞe¿|u¸ÌüQ¿a…*}ž+TŸÌ ²€ú“ºRÆùíX c"+*Ÿ NlôŸNûhc¿Ft‡ÀÛ—&àÅù‡ú¶¿Ô1%ØQ''ßê×?œlÚÃ׸•+&£r{ýj¸N‘಻® æ4ü) ÚËÃ`¨N狌€.½ Ûß­ˆ  ùüëÇ£Çÿü®•Üá—“§ôì)q ´2Ÿ?÷²ñýn¼3H€bÐÌø`ï}Ø ÷—­Âþ.`–ñõú§ìpqY1ûe_bûÕËïu÷7ùþe+NÍõ_Fö†¶Ý(êDTƒü,àÃÞL}LLžrûùmP5‹º|±x芥1Œc…ûŠx DAb ŒŒŒŒŒ`ˆ¦M(±ê7¼´ÐNEDï~žÏMzé Ðö+4ÆçÉBXd.ŽÃMzþËv͈ë¾µÓÏð¶«P×d8‰p¬ÿ<6?®Ø8ØN‘ý*xõêèÕ.»¾6Ú6G÷€­ìFåZû½ã…Å)ÝݦOéÉÉ ! ùlÅSsýÓÐh³èíæssàNðõp8Ú`'´0ö/<Æþš¤£s£ï©ß}ñ.æ@ǨÛsƒ7ξ§OÛŸVîDúú€a5ŸÏaŽvÜô]๘õúðÔm1™ø+ÝêŸÒ3äÃýyè6ðÛ õ‹ž>@ßu50ëÀPÚsÿÜÅ5‚¤1=Æë=§pý¢ *ÂKV•Ò«Ü‚Õã€ÝãøÝ»c$N®4(úX¹r2###c- ñê賟LóÓÙδÙ>޼]¯ûó5Ú.žsŸ´ÂYsÇ1ïÞf0Ã;ü'̨¦˜Yþg銛Â{“@9øà øÐÕ`aC(ލ=%bêoà2ÌÌ=­†Þnœò¤1ø jœ‡BŸ’o¨½S$nùãà#Ím“ݘú=iœê0ÁcÊÚï§ÝÈþÐÒÝi9Åö}ÔoI…Ù ¨Ýù®qãT‡š]òW%.Ãö‡(‰ËØ…æ]zÛ\ðx f³Ùö"]o°×'uÐ䫵tŠk{Àv;AëÍC3Ö†wž€w¨R_#÷±X» Þ(x§÷Ò‹/q%¶èùW¸ ¨þÅ›ÇÌÜhpíÄk_IöXŠùÇ'b§Éú/fXÞþ²Köi´"#####ã†QCL¼iÀˆ2téè àà€Ê5¬¶L0 ¶¬ÄêQiÞH“2;yÒTêOok;×¢ì Ù¶`õÃRš²Ng{z´y¼!—Kx²¢²·çmì?A(vø£UÒ~Œ°ÎmLÀ(`o/!nòÿ¤°mXŠ€-{ÀvûŽ÷[¾ € dÇw=Àn「ŒŒŒŒûøsdwåüzŽÖnê(åò}O®yŽ~­Ñó ãúmà ›ðï?XUÞ;,àš…V'+û €VŸ&ïJ¸Rê×Z]á§­§:£¥Ï×zC'ýÓ-߆ºžÝÈ@åy ö4¼­Úuó—þ §`VÛ“wö«ÑŠ#÷ýzP@Q˜ N>2/ÿý{¦\o)Žö”ëWøŒ›~a3xLÀw :_QÞ;Œì=pŠÖ¼èdt§Ãî\'8¸º¼ÂÝ~3áSRPÛ¡Ú6Æïõùy+ŸšÏÈÈÈÈXüù€”ÌQ­*¯ÚÞºr üù€”Ì—Ñ­*¯ÚÞºr gÐál™/¤\U^µ½uå$øóüœ|mbÃëVn–ÒÚòw \V½å|ù‡ÞöDËÍŠNVNåæþy‡À7ì¢ÚÙàëk<;œª/ËE}?E*dzgáO ú¨ß~ûègþœ/9¿®6˜Êæê½f c…D}% Š×g$õQî·Gž7öoŽ€)úº¡ÏU J¶ð˜˜o™,O@ú0ß¾Q(íòÀä;žbõ¹¬˜wõ“àÏ:5× úNŒwRÀåþN5ØIòöy'KË?}²¹:9‰mֽ߯®*§±í@fÝ@jU9m‡²ë†Ò«Ê´ÃÉ{öÿÓò$âØ——}öídF€âÿôp¿Ñ|%!DdF¸·>™ýû»}Gö€{ßÜ÷»@FFFFFFƦQÜžH ¹ ªÕºìÿí3 •Ðu øù¾Möo¸½·Ê~êvy»}¡mûwz<Ø7õ•ïnP9ørÆWkÿíñu= ©¯°|«ì_×n½ýëÞz쿳}@ÞþÛãIXÆn÷›‘±çø?Éæs .body > .container { margin-top: 32px; } .grades thead th, .grades tbody td { width: 3em; } .skill-title { display: table-row; overflow: hidden; position: absolute; right: 92px; top: 2px; z-index: 1; } .skill-title p { background: #F0EFEE; border-color: #dddddd; border-radius: 0 0 4px 4px; border-style: solid; border-width: 1px; color: black; display: table-cell; font-size: 11px; margin: 0px; opacity: 0.9; padding: 5px; text-align: center; vertical-align: middle; width: 598px; } .skill-title p.required, .skill-title p.optional { text-align: justify; } .grades thead th > a { display: block; } .skill-title p.required, .color-codes .required, .grades thead th > a { color: black; } .skill-title p.optional, .color-codes .optional, .color-codes .iep, .grades thead th.optional, .grades thead th.optional > a { color: black; } ul.skills li.optional, .color-codes .optional, .grade-student .optional, .grades thead th.optional, .grades thead th.optional > a { background: #ACC4E4; } .iep-student, .color-codes .iep, .grade-student .iep { background: #d1c4da; } .skillsets-selection { max-height: 550px; overflow: auto; margin-bottom: 8px; } /* XXX: ugly hack! */ .skillsets-selection-remove, .skillsets-selection-courseskills { max-height: 100000px; } .skillsets-selection ul.skills { list-style-type: disc; padding-left: 16px; } .skillsets-selection .ui-accordion .ui-accordion-header { font-weight: normal; color: #333333; background-color: transparent; border-color: transparent; } .skillsets-selection .ui-accordion .ui-state-active, .skillsets-selection .ui-accordion .ui-state-hover { background-color: #008c93; border-color: #008c93; color: #ffffff; } .gradebook-modes { margin-right: 8px; padding-bottom: 8px; border-bottom: 1px solid #cccccc; margin-bottom: 4px; } /* XXX: to make the default arrows in the skillset accordion black find a better way to do it */ .skillsets-selection .ui-accordion .ui-state-default .ui-icon { background-image: url("ui-icons_222222_256x240.png"); } .skillsets-selection .ui-accordion .ui-state-active .ui-icon, .skillsets-selection .ui-accordion .ui-state-hover .ui-icon { background-image: url("ui-icons_ffffff_256x240.png"); } input[type="checkbox"].select-all { display: block; } .grade-student { border-collapse: collapse; margin-top: 0; table-layout: fixed; } .grade-student th, .grade-student td { vertical-align: middle; box-sizing: border-box; -moz-box-sizing: border-box; } .grade-student td { min-height: 2.2em; } .grade-student input[type="text"] { width: 100%; border: none; font-size: 1em; } .grade-student .student-score { border-left: 1px solid #cccccc; width: 4em; } .grade-student td.student-score { padding: 0; } .grade-student input[type="text"]:focus { background-color: #bdd7f0; } .grade-student input[type="text"].valid { background: #009499; color: #ffffff; } .grade-student input[type="text"].error { background: #ef4444; color: #ffffff; } .grade-student input[type="text"].extracredit { background: #f6db5a; } .student-scr .date { width: 7em; } .student-scr .rating { width: 6em; } .student-scr .flag { text-align: center; } /* XXX: move this to the gradebook css? */ .grid .third-nav { width: 20000px; } .popup_menu { max-width: 400px; } .popup_menu li.header { white-space: normal; } .worksheets-list { top: 68px; max-width: 752px; width: 752px; } .optional-iep { width: 60px; } .request-competency-certificate-form select { width: 288px; } #retire-ajax-view-container-retire- div.no-batch-navigation { padding: 0 8px; margin-top: 0; } schooltool.cando-2.6.2/src/schooltool/cando/browser/breadcrumbs.zcml0000644000175000017500000001126012270520445027025 0ustar menesismenesis00000000000000 schooltool.cando-2.6.2/src/schooltool/cando/browser/rml/0000755000175000017500000000000012322040274024432 5ustar menesismenesis00000000000000schooltool.cando-2.6.2/src/schooltool/cando/browser/rml/section_student_scr.pt0000644000175000017500000000125312270520445031066 0ustar menesismenesis00000000000000 Teacher(s): Course: schooltool.cando-2.6.2/src/schooltool/cando/browser/rml/student_competency_report_styles.pt0000644000175000017500000000244212270520445033720 0ustar menesismenesis00000000000000 schooltool.cando-2.6.2/src/schooltool/cando/browser/rml/competency_certificate_signature.pt0000644000175000017500000000111012270520445033566 0ustar menesismenesis00000000000000 Instructor:   Signature:   Date:   schooltool.cando-2.6.2/src/schooltool/cando/browser/rml/competency_certificate_styles.pt0000644000175000017500000000216412270520445033122 0ustar menesismenesis00000000000000 schooltool.cando-2.6.2/src/schooltool/cando/browser/document.py0000644000175000017500000010402212270520445026034 0ustar menesismenesis00000000000000# # SchoolTool - common information systems platform for school administration # Copyright (c) 2012 Shuttleworth Foundation # # 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 2 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 . # """ Document views. """ from zope.browserpage.viewpagetemplatefile import ViewPageTemplateFile from zope.cachedescriptors.property import Lazy from zope.component import adapts, getUtility, getMultiAdapter from zope.container.interfaces import INameChooser from zope.interface import implements, directlyProvides from zope.intid.interfaces import IIntIds from zope.publisher.browser import BrowserView from zope.publisher.interfaces.browser import IBrowserRequest from zope.security.proxy import removeSecurityProxy from zope.traversing.browser.absoluteurl import absoluteURL from zope.traversing.browser.interfaces import IAbsoluteURL import zc.table.column import z3c.form.form import z3c.form.button import z3c.form.field from schooltool.skin import flourish from schooltool import table from schooltool.app.browser.app import RelationshipAddTableMixin from schooltool.app.browser.app import RelationshipRemoveTableMixin from schooltool.app.browser.app import EditRelationships from schooltool.app.interfaces import ISchoolToolApplication from schooltool.app.browser.app import ContentTitle from schooltool.common.inlinept import InlineViewPageTemplate, InheritTemplate from schooltool.schoolyear.interfaces import ISchoolYearContainer from schooltool.cando.browser.model import LayersTable, LayerView, LayerEditView from schooltool.cando.browser.model import EditChildLayersView from schooltool.cando.browser.skill import SkillAddView, SkillView from schooltool.cando.browser.skill import SkillSetEditView, SkillEditView from schooltool.cando.interfaces import ILayerContainer, ILayer from schooltool.cando.interfaces import INodeContainer, INode from schooltool.cando.interfaces import IDocumentContainer, IDocument from schooltool.cando.interfaces import ISkillSetContainer, ISkillSet from schooltool.cando.model import LayerContainer, Layer, LayerLink from schooltool.cando.model import NodeContainer, Node, NodeLink from schooltool.cando.model import DocumentContainer, Document from schooltool.cando.skill import SkillSetContainer, SkillSet, Skill from schooltool.cando import CanDoMessage as _ class DocumentContainerAbsoluteURLAdapter(BrowserView): adapts(IDocumentContainer, IBrowserRequest) implements(IAbsoluteURL) def __str__(self): app = ISchoolToolApplication(None) url = absoluteURL(app, self.request) return url + '/documents' __call__ = __str__ class DocumentsView(flourish.page.Page): content_template = InlineViewPageTemplate('''

There are no documents.

''') @Lazy def container(self): return IDocumentContainer(ISchoolToolApplication(None)) class DocumentsTable(table.ajax.Table): def columns(self): default = table.ajax.Table.columns(self) return default def updateFormatter(self): if self._table_formatter is None: self.setUp(table_formatter=self.table_formatter, batch_size=self.batch_size, prefix=self.__name__, css_classes={'table': 'data'}) class DocumentsTertiaryNavigationManager( flourish.page.TertiaryNavigationManager): template = InlineViewPageTemplate("""
""") @property def items(self): tabs = ( ((DocumentContainer, Document), 'documents', _('Documents')), ((LayerContainer, Layer), 'layers', _('Layers')), ((SkillSetContainer, SkillSet, Skill), 'skills', _('Skill Sets')), ((NodeContainer, Node), 'nodes', _('Search')), ) result = [] app = ISchoolToolApplication(None) for context_list, link, title in tabs: url = '%s/%s' % (absoluteURL(app, self.request), link) if 'Document' in str(self.view): active = (link == 'documents') else: active = (self.context.__class__ in context_list) result.append({ 'class': active and 'active' or None, 'viewlet': u'%s' % (url, title), }) return result class DocumentsAddLinks(flourish.page.RefineLinksViewlet): """Manager for Add links in DocumentsView""" class DocumentsActionsLinks(flourish.page.RefineLinksViewlet): """Manager for Actions links in DocumentsView""" class ImportSkillsLinkViewlet(flourish.page.LinkViewlet): @property def url(self): link = self.link if not link: return None app = ISchoolToolApplication(None) return "%s/%s" % (absoluteURL(app, self.request), self.link) class DocumentAddView(flourish.form.AddForm): template = InheritTemplate(flourish.page.Page.template) label = None legend = _('Document Information') fields = z3c.form.field.Fields(IDocument).select('title', 'description') @property def layer_titles(self): items = [] for key in [k for k in self.request.keys() if k.startswith('row')]: index = int(key[3:]) items.append([index, self.request[key]]) return [v for k, v in reversed(sorted(items))] @property def nonempty_titles(self): return [t for t in self.layer_titles if t] def rows(self): titles = self.layer_titles if not titles: titles = [_('Skill Set'), _('Skill')] num_titles = len(titles) rows = [] for index, title in enumerate(titles): rows.append({ 'name': 'row%d' % (num_titles - index - 1), 'value': title, 'add': index == 0, }) return rows def updateActions(self): super(DocumentAddView, self).updateActions() self.actions['add'].addClass('button-ok') self.actions['cancel'].addClass('button-cancel') @z3c.form.button.buttonAndHandler(_('Submit'), name='add') def handleAdd(self, action): super(DocumentAddView, self).handleAdd.func(self, action) @z3c.form.button.buttonAndHandler(_('Cancel')) def handle_cancel_action(self, action): app = ISchoolToolApplication(None) url = '%s/documents' % absoluteURL(app, self.request) self.request.response.redirect(url) def create(self, data): document = Document(data['title']) z3c.form.form.applyChanges(self, document, data) return document def add(self, document): chooser = INameChooser(self.context) name = chooser.chooseName(u'', document) self.context[name] = document self._document = document layers = ILayerContainer(ISchoolToolApplication(None)) chooser = INameChooser(layers) previous_layer = None for title in self.nonempty_titles: layer = Layer(title) name = chooser.chooseName(u'', layer) layers[name] = layer if previous_layer is not None: layer.parents.add(previous_layer) document.hierarchy.add(layer) previous_layer = layer return document def nextURL(self): return absoluteURL(self._document, self.request) class DocumentMixin(object): def is_document(self): return IDocument(self.context, None) is not None def get_document(self): return self.context def get_node(self): return None def get_layer_hierarchy(self): document = self.get_document() if document is None: return [] return document.getOrderedHierarchy() def get_layer(self): layer_id = self.request.get('layer', '') app = ISchoolToolApplication(None) return ILayerContainer(app).get(layer_id, None) def is_skillset_layer(self): return len(self.get_layer_hierarchy()) < 3 def get_next_layer(self): hierarchy = self.get_layer_hierarchy() if not hierarchy: return None return hierarchy[0] def get_previous_layer(self): return None def get_children(self): if INode(self.context, None) is not None: return sorted(NodeLink.query(parent=self.context), key=lambda l: l.__name__) return [] @property def layer_title(self): layer = self.get_layer() if layer is None: return _('Skill Set') return layer.title @property def next_layer_title(self): layer = self.get_next_layer() if layer is None: return _('Skill Set') return layer.title def build_query_string(self, **kw): query_string_dict = {} document = self.get_document() if document is not None: query_string_dict['document'] = document.__name__ layer = kw.get('layer', None) if layer is not None: query_string_dict['layer'] = layer.__name__ node = kw.get('node', None) if node is not None: query_string_dict['node'] = node.__name__ query_string = '' for index, (k, v) in enumerate(query_string_dict.items()): query_string += index and '&' or '?' query_string += '%s=%s' % (k, v) return query_string def make_node_item(self, node): query_string = self.build_query_string(layer=self.get_next_layer()) return { 'url': '%s/document.html%s' % (absoluteURL(node, self.request), query_string), 'obj': node, } def make_skillset_item(self, skillset): query_string = self.build_query_string(layer=self.get_next_layer(), node=self.get_node()) return { 'url': '%s/document.html%s' % (absoluteURL(skillset, self.request), query_string), 'obj': skillset, } @property def items(self): result = [] if self.is_skillset_layer(): for skillset in self.context.skillsets: result.append(self.make_skillset_item(skillset)) else: for node in self.get_children(): result.append(self.make_node_item(node)) return result @property def add_url(self): if self.is_skillset_layer(): url = 'add_document_skillset.html' query_string = self.build_query_string(layer=self.get_next_layer(), node=self.get_node()) else: url = 'add_document_node.html' query_string = self.build_query_string(layer=self.get_next_layer()) return '%s%s' % (url, query_string) class DocumentNodeMixin(DocumentMixin): def get_document(self): document_id = self.request.get('document', '') app = ISchoolToolApplication(None) return IDocumentContainer(app).get(document_id, None) def get_node(self): if INode(self.context, None) is not None: return self.context node_id = self.request.get('node', '') app = ISchoolToolApplication(None) return INodeContainer(app).get(node_id, None) def is_skillset_layer(self): hierarchy = self.get_layer_hierarchy() if len(hierarchy) < 3: return True current_layer = self.get_next_layer() if current_layer is None: return True for index, layer in enumerate(hierarchy): if layer is current_layer and index < len(hierarchy) - 2: return False return True def get_next_layer(self): hierarchy = self.get_layer_hierarchy() if hierarchy: current_layer = self.get_layer() if current_layer is None: return None for index, layer in enumerate(hierarchy): if layer is current_layer and index < len(hierarchy) - 1: return hierarchy[index + 1] return None def get_previous_layer(self): hierarchy = self.get_layer_hierarchy() if hierarchy: current_layer = self.get_layer() if current_layer is None: return None for index, layer in enumerate(hierarchy): if layer is current_layer and index > 0: return hierarchy[index - 1] return None class DocumentSkillSetMixin(DocumentNodeMixin): @property def next_layer_title(self): hierarchy = self.get_layer_hierarchy() if len(hierarchy) > 1: return hierarchy[-1].title return _('Skill') class DocumentSkillMixin(DocumentSkillSetMixin): @property def layer_title(self): layer = self.get_layer() if layer is None: return _('Skill') return layer.title class DocumentAddLinks(flourish.page.RefineLinksViewlet): """Manager for Add links in DocumentView""" class DocumentEditLinks(flourish.page.RefineLinksViewlet): """Manager for Edit links in DocumentView""" class DocumentAddNodeLink(flourish.page.LinkViewlet, DocumentMixin): @property def title(self): return self.next_layer_title @property def url(self): return self.add_url class DocumentView(flourish.form.DisplayForm, DocumentMixin): template = InheritTemplate(flourish.page.Page.template) label = None fields = z3c.form.field.Fields(IDocument).select('description') @property def legend(self): return _('${layer} list', mapping={'layer': self.next_layer_title}) @property def can_edit(self): return flourish.canEdit(self.context) @property def edit_url(self): return absoluteURL(self.context, self.request) + '/edit.html' @property def done_link(self): app = ISchoolToolApplication(None) return '%s/documents' % absoluteURL(app, self.request) def document_node_title_formatter(value, item, formatter): return '%s' % (item['url'], value) class DocumentNodesTable(table.ajax.Table): batch_size = 0 def items(self): return self.view.items def columns(self): label = table.column.LocaleAwareGetterColumn( name='label', title=_('Label'), getter=lambda i, f: i['obj'].label or '', subsort=True) title = table.column.LocaleAwareGetterColumn( name='title', title=_('Title'), getter=lambda i, f: i['obj'].title, cell_formatter=document_node_title_formatter, subsort=True) return [label, title] def sortOn(self): return (('label', False), ('title', False)) def updateFormatter(self): if self._table_formatter is None: self.setUp(table_formatter=self.table_formatter, batch_size=self.batch_size, prefix=self.__name__, css_classes={'table': 'data'}) class DocumentNodesTableParameters(flourish.viewlet.Viewlet): parameters = ['document', 'layer', 'node'] template = InlineViewPageTemplate(''' ''') class DocumentEditView(flourish.form.Form, z3c.form.form.EditForm): fields = z3c.form.field.Fields(IDocument) fields = fields.select('title', 'description') legend = _('Document') def applyChanges(self, data): if data['description'] is None: data['description'] = u'' super(DocumentEditView, self).applyChanges(data) @z3c.form.button.buttonAndHandler(_('Submit'), name='apply') def handleApply(self, action): super(DocumentEditView, self).handleApply.func(self, action) if (self.status == self.successMessage or self.status == self.noChangesMessage): url = absoluteURL(self.context, self.request) self.request.response.redirect(url) @z3c.form.button.buttonAndHandler(_("Cancel")) def handle_cancel_action(self, action): url = absoluteURL(self.context, self.request) self.request.response.redirect(url) def updateActions(self): super(DocumentEditView, self).updateActions() self.actions['apply'].addClass('button-ok') self.actions['cancel'].addClass('button-cancel') class EditDocumentHierarchyView(EditRelationships): current_title = _("Current document hierarchy layers") available_title = _("Available layers") def getCollection(self): return self.context.getOrderedHierarchy() def getAvailableItemsContainer(self): return ILayerContainer(ISchoolToolApplication(None)) def getAvailableItems(self): """Return a sequence of items that can be selected.""" container = self.getAvailableItemsContainer() selected_items = set(self.getSelectedItems()) return [p for p in container.values() if p not in selected_items] class LayerContainerSourceMixin(object): @property def source(self): return ILayerContainer(ISchoolToolApplication(None)) def sortOn(self): return [] class AvailableLayersTable(LayerContainerSourceMixin, RelationshipAddTableMixin, LayersTable): pass class RemoveLayersTable(LayerContainerSourceMixin, RelationshipRemoveTableMixin, LayersTable): pass class DocumentLayerView(LayerView, DocumentNodeMixin): @property def edit_url(self): url = absoluteURL(self.context, self.request) query_string = self.build_query_string() return '%s/edit_document_layer.html%s' % (url, query_string) @property def edit_children_url(self): url = absoluteURL(self.context, self.request) query_string = self.build_query_string() return '%s/edit_document_layer_children.html%s' % (url, query_string) @property def done_link(self): document = self.get_document() if document is None: app = ISchoolToolApplication(None) return '%s/documents' % absoluteURL(app, self.request) return absoluteURL(document, self.request) class DocumentLayerEditView(LayerEditView, DocumentNodeMixin): def nextURL(self): url = absoluteURL(self.context, self.request) query_string = self.build_query_string() return '%s/document.html%s' % (url, query_string) class EditDocumntLayerChildrenView(EditChildLayersView, DocumentNodeMixin): def nextURL(self): url = absoluteURL(self.context, self.request) query_string = self.build_query_string() return '%s/document.html%s' % (url, query_string) class DocumentNodeView(flourish.form.DisplayForm, DocumentNodeMixin): """Same as DocumentView but for a particular node""" template = InheritTemplate(flourish.page.Page.template) label = None fields = z3c.form.field.Fields(INode).select('title', 'description', 'label') @property def subtitle(self): return _('View ${layer}', mapping={'layer': self.layer_title}) @property def legend(self): return _('${layer} list', mapping={'layer': self.next_layer_title}) @property def can_edit(self): return flourish.canEdit(self.context) @property def edit_url(self): url = absoluteURL(self.context, self.request) query_string = self.build_query_string(layer=self.get_layer()) return '%s/edit_document_node.html%s' % (url, query_string) @property def done_link(self): document = self.get_document() if document is None: app = ISchoolToolApplication(None) return '%s/documents' % absoluteURL(app, self.request) layer = self.get_previous_layer() if layer is not None: for parent in self.context.parents: if layer in parent.layers: url = absoluteURL(parent, self.request) query_string = self.build_query_string(layer=layer) return '%s/document.html%s' % (url, query_string) return absoluteURL(document, self.request) class DocumentNodeAddLinks(flourish.page.RefineLinksViewlet): """Manager for Add links in DocumentView""" class DocumentNodeAddNodeLink(flourish.page.LinkViewlet, DocumentNodeMixin): @property def title(self): return self.next_layer_title @property def url(self): return self.add_url class DocumentAddNodeBase(flourish.form.AddForm): template = InheritTemplate(flourish.page.Page.template) label = None fields = z3c.form.field.Fields(INode).select('title', 'description', 'label') @property def subtitle(self): return _('Add ${layer}', mapping={'layer': self.layer_title}) @property def legend(self): return _('${layer} Information', mapping={'layer': self.layer_title}) def updateActions(self): super(DocumentAddNodeBase, self).updateActions() self.actions['add'].addClass('button-ok') self.actions['cancel'].addClass('button-cancel') @z3c.form.button.buttonAndHandler(_('Submit'), name='add') def handleAdd(self, action): super(DocumentAddNodeBase, self).handleAdd.func(self, action) @z3c.form.button.buttonAndHandler(_('Cancel')) def handle_cancel_action(self, action): self.request.response.redirect(self.nextURL()) def create(self, data): if data['description'] is None: data['description'] = u'' node = Node(data['title']) z3c.form.form.applyChanges(self, node, data) node.parents.add(removeSecurityProxy(self.context)) layer = self.get_layer() if layer is not None: node.layers.add(removeSecurityProxy(layer)) return node def add(self, node): nodes = INodeContainer(ISchoolToolApplication(None)) chooser = INameChooser(nodes) name = chooser.chooseName(u'', node) nodes[name] = node return node class DocumentAddNodeView(DocumentAddNodeBase, DocumentMixin): """Add Node from DocumentView""" @property def title(self): return _('Skills Document') def nextURL(self): return absoluteURL(self.context, self.request) class DocumentNodeAddNodeView(DocumentAddNodeBase, DocumentNodeMixin): """Add Node from DocumentNodeView""" @property def title(self): return self.context.title def nextURL(self): return absoluteURL(self.context, self.request) + '/document.html' class DocumentNodeEditView(flourish.form.Form, z3c.form.form.EditForm, DocumentNodeMixin): fields = z3c.form.field.Fields(INode) fields = fields.select('title', 'description', 'label') legend = _('Change information') def applyChanges(self, data): if data['description'] is None: data['description'] = u'' super(DocumentNodeEditView, self).applyChanges(data) @z3c.form.button.buttonAndHandler(_('Submit'), name='apply') def handleApply(self, action): super(DocumentNodeEditView, self).handleApply.func(self, action) if (self.status == self.successMessage or self.status == self.noChangesMessage): self.request.response.redirect(self.nextURL()) @z3c.form.button.buttonAndHandler(_("Cancel")) def handle_cancel_action(self, action): self.request.response.redirect(self.nextURL()) def updateActions(self): super(DocumentNodeEditView, self).updateActions() self.actions['apply'].addClass('button-ok') self.actions['cancel'].addClass('button-cancel') def nextURL(self): return absoluteURL(self.context, self.request) + '/document.html' def nextURL(self): url = absoluteURL(self.context, self.request) query_string = self.build_query_string(layer=self.get_layer()) return '%s/document.html%s' % (url, query_string) class DocumentAddSkillSetBase(flourish.form.AddForm): _skillset = None label = None fields = z3c.form.field.Fields(ISkillSet) fields = fields.select('title', 'description', 'label') @property def legend(self): return self.layer_title @property def subtitle(self): return _('Add ${layer}', mapping={'layer': self.layer_title}) def updateActions(self): super(DocumentAddSkillSetBase, self).updateActions() self.actions['add'].addClass('button-ok') self.actions['cancel'].addClass('button-cancel') def create(self, data): skillset = SkillSet(data['title']) z3c.form.form.applyChanges(self, skillset, data) self._skillset = skillset return skillset def add(self, skillset): skillsets = ISkillSetContainer(ISchoolToolApplication(None)) chooser = INameChooser(skillsets) name = unicode(skillset.title).encode('punycode') name = name[:8]+str(len(skillsets)+1) name = chooser.chooseName(name, skillset) skillsets[name] = skillset removeSecurityProxy(self.context.skillsets).add( removeSecurityProxy(skillset)) return skillset def nextURL(self): if self._skillset is not None: url = absoluteURL(self._skillset, self.request) + '/document.html' layer = self.get_layer() else: url = self.contextURL() layer = self.get_previous_layer() query_string = self.build_query_string(layer=layer, node=self.get_node()) return '%s%s' % (url, query_string) class DocumentAddSkillSetView(DocumentAddSkillSetBase, DocumentMixin): """Add SkillSet from DocumentView""" def contextURL(self): return absoluteURL(self.context, self.request) class DocumentNodeAddSkillSetView(DocumentAddSkillSetBase, DocumentNodeMixin): """Add SkillSet from DocumentNodeView""" def contextURL(self): return absoluteURL(self.context, self.request) + '/document.html' class DocumentSkillSetView(flourish.form.DisplayForm, DocumentSkillSetMixin): template = InheritTemplate(flourish.page.Page.template) fields = z3c.form.field.Fields(ISkillSet) fields = fields.select('description', 'label', 'retired') @property def subtitle(self): return _('View ${layer}', mapping={'layer': self.layer_title}) @property def legend(self): layer = self.get_next_layer() if layer is None: return _('Skills') return _('${layer} list', mapping={'layer': layer.title}) @property def can_edit(self): return flourish.canEdit(self.context) @property def edit_url(self): url = absoluteURL(self.context, self.request) query_string = self.build_query_string(layer=self.get_layer(), node=self.get_node()) return '%s/edit_document_skillset.html%s' % (url, query_string) @property def done_link(self): app = ISchoolToolApplication(None) document = self.get_document() if document is None: return '%s/skills' % absoluteURL(app, self.request) node_id = self.request.get('node', '') node = INodeContainer(app).get(node_id, None) if node is not None: previous_layer = self.get_previous_layer() query_string = self.build_query_string(layer=previous_layer) return '%s/document.html%s' % (absoluteURL(node, self.request), query_string) else: return '%s/index.html' % absoluteURL(document, self.request) class DocumentSkillSetSkillTable(table.ajax.Table, DocumentSkillSetMixin): def updateFormatter(self): if self._table_formatter is None: self.setUp(table_formatter=self.table_formatter, batch_size=self.batch_size, prefix=self.__name__, css_classes={'table': 'data'}) def sortOn(self): return (("label", False), ("title", False)) def title_url_formatter(self, value, item, formatter): query_string = self.build_query_string(layer=self.get_next_layer(), node=self.get_node()) url = '%s/document.html%s' % (absoluteURL(item, formatter.request), query_string) return '%s' % (url, value) def columns(self): title = zc.table.column.GetterColumn( name='title', title=_(u"Title"), cell_formatter=lambda v, i, f: self.title_url_formatter(v, i, f), getter=lambda i, f: i.title, subsort=True) directlyProvides(title, zc.table.interfaces.ISortableColumn) required = zc.table.column.GetterColumn( name='required', title=_(u'Required'), getter=lambda i, f: i.required and _('Yes') or _('No')) directlyProvides(required, zc.table.interfaces.ISortableColumn) label = table.column.LocaleAwareGetterColumn( name='label', title=_(u'Label'), getter=lambda i, f: i.label or '', subsort=True) return [label, title, required] class DocumentSkillSetEditView(SkillSetEditView, DocumentSkillSetMixin): def nextURL(self): url = absoluteURL(self.context, self.request) query_string = self.build_query_string(layer=self.get_layer(), node=self.get_node()) return '%s/document.html%s' % (url, query_string) class DocumentSkillSetLinks(flourish.page.RefineLinksViewlet): pass class DocumentAddSkillLink(flourish.page.LinkViewlet, DocumentSkillSetMixin): @property def title(self): return self.next_layer_title @property def url(self): url = 'add_document_skill.html' query_string = self.build_query_string(layer=self.get_next_layer(), node=self.get_node()) return '%s%s' % (url, query_string) class DocumentAddSkillView(SkillAddView, DocumentSkillSetMixin): @property def legend(self): return _('${layer} Information', mapping={'layer': self.next_layer_title}) @property def subtitle(self): return _('Add ${layer}', mapping={'layer': self.next_layer_title}) def create(self, data): skill = Skill(data['title']) z3c.form.form.applyChanges(self, skill, data) self._skill = skill return skill def add(self, skill): skillset = self.context if not skill.label: skill.label = u'%02d' % (len(skillset) + 1) chooser = INameChooser(skillset) if skill.external_id: name = skill.external_id else: name = unicode(skill.title).encode('punycode') name = name[:8]+str(len(skillset)+1) name = chooser.chooseName(name, skill) skillset[name] = skill return skill def nextURL(self): url = absoluteURL(self.context, self.request) if self.add_next: query_string = self.build_query_string(layer=self.get_layer(), node=self.get_node()) return '%s/add_document_skill.html%s' % (url, query_string) else: previous_layer = self.get_previous_layer() query_string = self.build_query_string(layer=previous_layer, node=self.get_node()) return '%s/document.html%s' % (url, query_string) class DocumentSkillView(SkillView, DocumentSkillMixin): @property def subtitle(self): return _('View ${layer}', mapping={'layer': self.layer_title}) @property def can_edit(self): return flourish.canEdit(self.context) @property def edit_url(self): url = absoluteURL(self.context, self.request) query_string = self.build_query_string(layer=self.get_layer(), node=self.get_node()) return '%s/edit_document_skill.html%s' % (url, query_string) @property def done_link(self): url = absoluteURL(self.context.__parent__, self.request) query_string = self.build_query_string(layer=self.get_previous_layer(), node=self.get_node()) return '%s/document.html%s' % (url, query_string) class DocumentSkillEditView(SkillEditView, DocumentSkillMixin): def nextURL(self): url = absoluteURL(self.context, self.request) query_string = self.build_query_string(layer=self.get_layer(), node=self.get_node()) return '%s/document.html%s' % (url, query_string) class CustomizeDocumentLink(flourish.page.LinkViewlet): pass schooltool.cando-2.6.2/src/schooltool/cando/browser/skill.py0000644000175000017500000003140212270520445025335 0ustar menesismenesis00000000000000# # SchoolTool - common information systems platform for school administration # Copyright (c) 2012 Shuttleworth Foundation # # 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 2 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 . # """ Skill views. """ from zope.browserpage.viewpagetemplatefile import ViewPageTemplateFile from zope.cachedescriptors.property import Lazy from zope.component import adapts from zope.container.interfaces import INameChooser from zope.interface import implements, Interface from zope.publisher.interfaces.browser import IBrowserRequest from zope.publisher.browser import BrowserView from zope.traversing.browser.absoluteurl import absoluteURL from zope.traversing.browser.interfaces import IAbsoluteURL import z3c.form.field import z3c.form.form import z3c.form.button from z3c.form.browser.text import TextWidget from z3c.form.widget import FieldWidget from z3c.form.term import BoolTerms from z3c.form.interfaces import IRadioWidget import zc.table.column import zc.table.interfaces from schooltool.skin import flourish from schooltool import table from schooltool.app.interfaces import ISchoolToolApplication from schooltool.person.interfaces import IPerson from schooltool.cando.interfaces import ISkillSetContainer from schooltool.cando.interfaces import ISkillSet, ISkill from schooltool.cando.interfaces import ISkillRequiredBool from schooltool.cando.skill import SkillSet, Skill from schooltool.common.inlinept import InheritTemplate from schooltool.common.inlinept import InlineViewPageTemplate from schooltool.schoolyear.interfaces import ISchoolYearContainer from schooltool.skin.flourish import IFlourishLayer from schooltool.cando import CanDoMessage as _ from schooltool.cando.skill import getDefaultSkillScoreSystem from schooltool.cando.skill import setDefaultSkillScoreSystem class SkillSetContainerView(flourish.page.Page): content_template = InlineViewPageTemplate('''

There are no skill sets.

''') @Lazy def container(self): return ISkillSetContainer(ISchoolToolApplication(None)) class SkillSetTable(table.ajax.Table): def updateFormatter(self): if self._table_formatter is None: self.setUp(table_formatter=self.table_formatter, batch_size=self.batch_size, prefix=self.__name__, css_classes={'table': 'data'}) def columns(self): default = table.ajax.Table.columns(self) skills = zc.table.column.GetterColumn( name='skills', title=_(u'Skills'), getter=lambda i, f: str(len(i))) label = table.column.LocaleAwareGetterColumn( name='label', title=_(u'Label'), getter=lambda i, f: i.label or '', subsort=True) return [label] + default + [skills] def sortOn(self): return (('label', False), ('title', False)) class SkillSetTableFilter(table.ajax.TableFilter, table.table.FilterWidget): title = _("Title, description or label") def filter(self, results): if self.ignoreRequest: return results if 'SEARCH' in self.request: searchstr = self.request['SEARCH'].lower() results = [item for item in results if searchstr in item.title.lower() or (item.label and searchstr in item.label.lower()) or (item.description and searchstr in item.description.lower())] return results class SkillSetContainerAbsoluteURLAdapter(BrowserView): adapts(ISkillSetContainer, IBrowserRequest) implements(IAbsoluteURL) def __str__(self): app = ISchoolToolApplication(None) url = absoluteURL(app, self.request) return url + '/skills' __call__ = __str__ class SkillSetContainerLinks(flourish.page.RefineLinksViewlet): pass class SkillSetContainerActionLinks(flourish.page.RefineLinksViewlet): pass class SkillSetAddView(flourish.form.AddForm): label = None legend = _('Skill set') add_next = False fields = z3c.form.field.Fields(ISkillSet) fields = fields.select('title', 'description', 'label') def updateActions(self): super(SkillSetAddView, self).updateActions() self.actions['add'].addClass('button-ok') self.actions['submitadd'].addClass('button-ok') self.actions['cancel'].addClass('button-cancel') def nextURL(self): url = absoluteURL(self.context, self.request) if self.add_next: return url + '/add.html' return url def create(self, data): skillset = SkillSet(data['title']) z3c.form.form.applyChanges(self, skillset, data) self._skillset = skillset return skillset def add(self, skillset): chooser = INameChooser(self.context) name = unicode(skillset.title).encode('punycode') name = name[:8]+str(len(self.context)+1) name = chooser.chooseName(name, skillset) self.context[name] = skillset return skillset @z3c.form.button.buttonAndHandler(_('Submit'), name='add') def handleSubmit(self, action): super(SkillSetAddView, self).handleAdd.func(self, action) @z3c.form.button.buttonAndHandler(_('Submit and add'), name='submitadd') def handleSubmitAndAdd(self, action): super(SkillSetAddView, self).handleAdd.func(self, action) if self._finishedAdd: self.add_next = True @z3c.form.button.buttonAndHandler(_('Cancel')) def handleCancel(self, action): super(SkillSetAddView, self).handleCancel.func(self, action) # XXX: after adding skillset, redirect to it's edit view. class SkillSetView(flourish.form.DisplayForm): template = InheritTemplate(flourish.page.Page.template) fields = z3c.form.field.Fields(ISkillSet) fields = fields.select('description', 'label', 'retired') class SkillSetEditView(flourish.form.Form, z3c.form.form.EditForm): fields = z3c.form.field.Fields(ISkillSet) fields = fields.select('title', 'description', 'label', 'retired') legend = _('Skill set') @z3c.form.button.buttonAndHandler(_('Submit'), name='apply') def handleApply(self, action): super(SkillSetEditView, self).handleApply.func(self, action) if (self.status == self.successMessage or self.status == self.noChangesMessage): self.request.response.redirect(self.nextURL()) @z3c.form.button.buttonAndHandler(_("Cancel")) def handle_cancel_action(self, action): self.request.response.redirect(self.nextURL()) def updateActions(self): super(SkillSetEditView, self).updateActions() self.actions['apply'].addClass('button-ok') self.actions['cancel'].addClass('button-cancel') def nextURL(self): return absoluteURL(self.context, self.request) class SkillSetSkillTable(table.ajax.Table): def updateFormatter(self): if self._table_formatter is None: self.setUp(table_formatter=self.table_formatter, batch_size=self.batch_size, prefix=self.__name__, css_classes={'table': 'data'}) def sortOn(self): return (('label', False), ('title', False)) def columns(self): default = table.ajax.Table.columns(self) label = table.column.LocaleAwareGetterColumn( name='label', title=_(u'Label'), getter=lambda i, f: i.label or '', subsort=True) return [label] + default class SkillSetLinks(flourish.page.RefineLinksViewlet): pass class SkillAddView(flourish.form.AddForm): label = None legend = _('Skill') add_next = False fields = z3c.form.field.Fields(ISkill) fields = fields.select('title', 'scoresystem', 'description', 'label', 'required', 'external_id') @z3c.form.button.buttonAndHandler(_('Submit'), name='add') def handleSubmit(self, action): super(SkillAddView, self).handleAdd.func(self, action) @z3c.form.button.buttonAndHandler(_('Submit and add'), name='submitadd') def handleSubmitAndAdd(self, action): super(SkillAddView, self).handleAdd.func(self, action) if self._finishedAdd: self.add_next = True @z3c.form.button.buttonAndHandler(_('Cancel')) def handleCancel(self, action): super(SkillAddView, self).handleCancel.func(self, action) def updateActions(self): super(SkillAddView, self).updateActions() self.actions['add'].addClass('button-ok') self.actions['submitadd'].addClass('button-ok') self.actions['cancel'].addClass('button-cancel') def updateWidgets(self): super(SkillAddView, self).updateWidgets() scoresystem = self.widgets['scoresystem'].value if scoresystem: return person = IPerson(self.request.principal, None) default = getDefaultSkillScoreSystem(person) if default is not None: self.widgets['scoresystem'].value = default def nextURL(self): url = absoluteURL(self.context, self.request) if self.add_next: return url + '/add.html' return url def create(self, data): if not data['label']: data['label'] = u'%02d' % (len(self.context) + 1) skill = Skill(data['title']) z3c.form.form.applyChanges(self, skill, data) self._skill = skill return skill def add(self, skill): chooser = INameChooser(self.context) if skill.external_id: name = skill.external_id else: name = unicode(skill.title).encode('punycode') name = name[:8]+str(len(self.context)+1) name = chooser.chooseName(name, skill) self.context[name] = skill scoresystem = self.request.get(self.widgets['scoresystem'].name, '') if scoresystem: person = IPerson(self.request.principal, None) setDefaultSkillScoreSystem(person, scoresystem) return skill class SkillView(flourish.form.DisplayForm): template = InheritTemplate(flourish.page.Page.template) label = None legend = _('Skill') fields = z3c.form.field.Fields(ISkill) fields = fields.select('scoresystem', 'description', 'label', 'required', 'retired', 'external_id') @property def title(self): return self.context.__parent__.title @property def can_edit(self): return flourish.canEdit(self.context) @property def edit_url(self): return absoluteURL(self.context, self.request) + '/edit.html' @property def done_url(self): return absoluteURL(self.context.__parent__, self.request) class SkillEditView(flourish.form.Form, z3c.form.form.EditForm): fields = z3c.form.field.Fields(ISkill) fields = fields.select('title', 'description', 'label', 'required', 'external_id') legend = _('Skill') @z3c.form.button.buttonAndHandler(_('Submit'), name='apply') def handleApply(self, action): super(SkillEditView, self).handleApply.func(self, action) if (self.status == self.successMessage or self.status == self.noChangesMessage): self.request.response.redirect(self.nextURL()) @z3c.form.button.buttonAndHandler(_("Cancel")) def handle_cancel_action(self, action): self.request.response.redirect(self.nextURL()) def updateActions(self): super(SkillEditView, self).updateActions() self.actions['apply'].addClass('button-ok') self.actions['cancel'].addClass('button-cancel') def nextURL(self): return absoluteURL(self.context, self.request) class LabelTextLineWidget(TextWidget): def update(self): super(LabelTextLineWidget, self).update() self.maxlength = self.field.max_length def LabelTextLineFieldWidget(field, request): return FieldWidget(field, LabelTextLineWidget(request)) class SkillRequiredTerms(BoolTerms): adapts(Interface, IFlourishLayer, Interface, ISkillRequiredBool, IRadioWidget) trueLabel = _('Required') falseLabel = _('Optional') schooltool.cando-2.6.2/src/schooltool/cando/browser/course.py0000644000175000017500000007712012270520445025526 0ustar menesismenesis00000000000000# # SchoolTool - common information systems platform for school administration # Copyright (c) 2012 Shuttleworth Foundation # # 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 2 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 . # """ Course skill views. """ import zope.lifecycleevent from zope.cachedescriptors.property import Lazy from zope.browserpage.viewpagetemplatefile import ViewPageTemplateFile from zope.i18n import translate from zope.i18n.interfaces.locales import ICollator from zope.interface import directlyProvides from zope.traversing.browser.absoluteurl import absoluteURL import zc.table.column from zc.table.interfaces import ISortableColumn from schooltool.app.browser.app import RelationshipAddTableMixin from schooltool.app.browser.app import ActiveSchoolYearContentMixin from schooltool.app.interfaces import ISchoolToolApplication from schooltool.course.interfaces import ICourseContainer from schooltool.cando.course import CourseSkillSet from schooltool.cando.interfaces import ICourseSkills from schooltool.cando.interfaces import ILayerContainer from schooltool.cando.interfaces import INodeContainer from schooltool.cando.interfaces import INode from schooltool.cando.interfaces import ISkillSetContainer from schooltool.cando.browser.skill import SkillSetTable, SkillSetSkillTable from schooltool.cando.browser.skill import SkillView from schooltool.cando.model import URINode, URINodeLayer from schooltool.course.interfaces import ICourse from schooltool.common.inlinept import InlineViewPageTemplate from schooltool.relationship import getRelatedObjects from schooltool.schoolyear.interfaces import ISchoolYearContainer from schooltool.schoolyear.interfaces import ISchoolYear from schooltool.skin import flourish from schooltool.table.column import getResourceURL from schooltool import table from schooltool.cando import CanDoMessage as _ class CourseSkillsOverview(flourish.page.Content): body_template = ViewPageTemplateFile( 'templates/course_skills_overview.pt') @Lazy def skills(self): return ICourseSkills(self.context) class UseCourseTitleMixin(object): @property def title(self): obj = self.context while obj is not None: if ICourse.providedBy(obj): return obj.title obj = obj.__parent__ return '' class CourseSkillsView(UseCourseTitleMixin, flourish.page.Page): content_template = InlineViewPageTemplate('''
Course ID
Alternate ID
''') @property def title(self): return self.context.__parent__.title def skillset_accordion_formatter(value, item, formatter): collator = ICollator(formatter.request.locale) skillset = item.skillset cell_template = [ '

%s

', '
', '
    ', '%s', '
', '
', ] title = skillset.title if skillset.label: title = '%s: %s' % (skillset.label, skillset.title) skills = [] for skill in sorted(item.values(), key=lambda x:(collator.key(x.label or ''), collator.key(x.title))): skill_title = skill.title if skill.label: skill_title = '%s: %s' % (skill.label, skill.title) skills.append('%s' % (not skill.required and ' class="optional"' or '', skill_title)) return ''.join(cell_template) % (title, ''.join(skills)) class CourseSkillsTable(table.ajax.Table): batch_size = 0 visible_column_names = ['title', 'skills'] def updateFormatter(self): if self._table_formatter is None: self.setUp(table_formatter=self.table_formatter, batch_size=self.batch_size, prefix=self.__name__, css_classes={'table': 'courseskills-table'}) def columns(self): label = table.column.LocaleAwareGetterColumn( name='label', title=u'Label', getter=lambda i, f: i.skillset.label or '', subsort=True) raw_title = table.column.LocaleAwareGetterColumn( name='raw_title', title=u'Raw Title', getter=lambda i, f: i.title, subsort=True) title = zc.table.column.GetterColumn( name='title', title=_('Title'), cell_formatter=skillset_accordion_formatter, getter=lambda i, f: i.title, subsort=True) skills = zc.table.column.GetterColumn( name='skills', title=_(u'Skills'), getter=lambda i, f: str(len(i))) return [label, raw_title, title, skills] def sortOn(self): return (('label', False), ('raw_title', False)) class CourseSkillsLinks(flourish.page.RefineLinksViewlet): pass class RemoveSkillsLinkViewlet(flourish.page.LinkViewlet): @property def enabled(self): return bool(self.context) class EditSkillsLinkViewlet(flourish.page.LinkViewlet): @property def enabled(self): return bool(self.context) # XXX: done link in course skills view. class CourseAssignSkillSetView(flourish.page.Page): content_template = InlineViewPageTemplate('''
''') def getKey(self, skillset): return skillset.__name__ def getOmmitedItems(self): app = ISchoolToolApplication(None) skillsets = ISkillSetContainer(app) ommit = [skillsets.get(i) for i in self.context] return [o for o in ommit if o is not None] def get_node_layers(node, formatter): return ', '.join([layer.title for layer in node.layers]) def node_layers_formatter(value, node, formatter): return '
'.join([layer.title for layer in node.layers]) class DialogButtonColumn(table.column.ImageInputColumn): content_template = ViewPageTemplateFile( 'templates/dialog_button_column.pt') def __init__(self, course_url): self.course_url = course_url kw = { 'prefix': 'add_item', 'title': _('Add'), 'name': 'action', 'alt': _('Add'), 'library': 'schooltool.skin.flourish', 'image': 'add-icon.png', 'id_getter': lambda x:x.__name__, } super(DialogButtonColumn, self).__init__(**kw) def renderCell(self, item, formatter): params = self.params(item, formatter) if not params: return '' # XXX: hack, scriplocal can't be used in inlintemplates? self.context = item self.request = formatter.request return self.content_template(params=params) def params(self, item, formatter): image_url = getResourceURL(self.library, self.image, formatter.request) if not image_url: return None dialog_url = '%s/assign-skillsets.html?node_id=%s' % ( self.course_url, item.__name__) dialog_id = '%s-container' % item.__name__ dialog_title = self.dialog_title(item, formatter) return { 'title': translate(self.title, context=formatter.request) or '', 'alt': translate(self.alt, context=formatter.request) or '', 'src': image_url, 'id': item.__name__, 'dialog_url': dialog_url, 'dialog_id': dialog_id, 'dialog_title': dialog_title, } def dialog_title(self, item, formatter): title = _('Select Skill Sets from ${node} (${node_id})', mapping={'node': item.title, 'node_id': item.__name__}) return translate(title, context=formatter.request) class SkillsetNodesTable(table.ajax.Table): def updateFormatter(self): if self._table_formatter is None: self.setUp(table_formatter=self.table_formatter, batch_size=self.batch_size, prefix=self.__name__, css_classes={'table': 'data'}) def columns(self): title = table.column.LocaleAwareGetterColumn( name='title', title=_(u"Title"), getter=lambda i, f: i.title, subsort=True) ID = table.column.LocaleAwareGetterColumn( name='ID', title=_(u'ID'), getter=lambda i, f: i.__name__, subsort=True) layers = table.column.LocaleAwareGetterColumn( name='layers', title=_('Layers'), getter=get_node_layers, cell_formatter=node_layers_formatter) skillsets = zc.table.column.GetterColumn( name='skillsets', title=_(u"Skill Sets"), getter=lambda i, f: len(i.skillsets), subsort=True) course_url = absoluteURL(self.context, self.request) action = DialogButtonColumn(course_url) directlyProvides(ID, ISortableColumn) directlyProvides(layers, ISortableColumn) return [ID, title, layers, skillsets, action] @property def source(self): app = ISchoolToolApplication(None) nodes = INodeContainer(app) result = {} for node in nodes.values(): if node.skillsets and not node.retired: result[node.__name__] = node return result class SkillsetNodesTableFilter(table.ajax.TableFilter): search_title = _("ID, title, label or description") template = ViewPageTemplateFile( 'templates/course_assign_skills_table_filter.pt') @property def search_id(self): return self.manager.html_id+'-search' @property def search_title_id(self): return self.manager.html_id+'-title' @property def search_layer_ids(self): return self.manager.html_id+"-layers" def layerContainer(self): app = ISchoolToolApplication(None) return ILayerContainer(app) def layers(self): result = [] container = self.layerContainer() collator = ICollator(self.request.locale) items = sorted(container.items(), key=lambda (lid, layer): layer.title, cmp=collator.cmp) for id, layer in items: checked = not self.manager.fromPublication if self.search_layer_ids in self.request: layer_ids = self.request[self.search_layer_ids] if not isinstance(layer_ids, list): layer_ids = [layer_ids] checked = id in layer_ids result.append({'id': id, 'title': layer.title, 'checked': checked}) return result def filter(self, items): if self.ignoreRequest: return items if self.search_layer_ids in self.request: layer_ids = self.request[self.search_layer_ids] if not isinstance(layer_ids, list): layer_ids = [layer_ids] layers = set() for layer_id in layer_ids: layer = self.layerContainer().get(layer_id) if layer is not None: layers.add(layer) if layers: items = [item for item in items if set(list(item.layers)).intersection(layers)] else: return [] if self.search_title_id in self.request: searchstr = self.request[self.search_title_id].lower() items = [item for item in items if searchstr in item.__name__.lower() or searchstr in item.title.lower() or searchstr in getattr(item, 'label', '').lower() or searchstr in getattr(item, 'description', '').lower()] return items class SkillsetNodesTableDoneLink(flourish.viewlet.Viewlet): template = InlineViewPageTemplate(''' ''') class CourseAssignSkillsView(flourish.page.Page): container_class = 'container widecontainer' content_template = InlineViewPageTemplate('''
''') @property def title(self): return self.context.__parent__.title class CourseRemoveSkillsView(flourish.page.Page): container_class = 'container widecontainer' content_template = ViewPageTemplateFile( 'templates/course_remove_skills.pt') @property def title(self): return self.context.__parent__.title def update(self): collator = ICollator(self.request.locale) if 'CANCEL' in self.request: self.request.response.redirect(self.nextURL()) return selected_skillsets = self.request.get('selected_skillsets', []) if not isinstance(selected_skillsets, list): selected_skillsets = [selected_skillsets] skillsets = [] for course_skillset in self.context.values(): skillset = course_skillset.skillset skills = [] for skill in sorted(skillset.values(), key=lambda x:(collator.key(x.label or ''), collator.key(x.title))): course_skill = course_skillset[skill.__name__] title = skill.title if skill.label: title = '%s: %s' % (skill.label, title) css_class = not course_skill.required and 'optional' or None skills.append({ 'title': title, 'css_class': css_class, }) skillsets.append({ 'label': skillset.label, 'title': skillset.title, 'skills': skills, 'id': skillset.__name__, 'checked': skillset.__name__ in selected_skillsets, }) self.skillsets = sorted(skillsets, key=lambda x:(collator.key(x['label'] or ''), collator.key(x['title']))) if 'SUBMIT_BUTTON' in self.request: for course_skillset in self.context.values(): if course_skillset.skillset.__name__ in selected_skillsets: del self.context[course_skillset.__name__] self.request.response.redirect(self.nextURL()) def nextURL(self): return absoluteURL(self.context, self.request) class CourseAssignSkillSetsDialog(flourish.form.Dialog): def initDialog(self): super(CourseAssignSkillSetsDialog, self).initDialog() self.ajax_settings['dialog']['maxHeight'] = 640 self.ajax_settings['dialog']['draggable'] = True self.ajax_settings['dialog']['dialogClass'] = 'explicit-close-dialog' self.ajax_settings['dialog']['closeOnEscape'] = False @property def error(self): return 'SUBMIT_BUTTON' in self.request and \ 'selected_skillsets' not in self.request def nextURL(self): return absoluteURL(self.context, self.request) def nodeContainer(self): app = ISchoolToolApplication(None) return INodeContainer(app) def update(self): collator = ICollator(self.request.locale) flourish.form.Dialog.update(self) node_id = self.request.get('node_id') node = self.nodeContainer().get(node_id) selected_skillsets = self.request.get('selected_skillsets', []) if not isinstance(selected_skillsets, list): selected_skillsets = [selected_skillsets] skillsets = [] if node is not None: for skillset in node.skillsets: skills = [] for skill in sorted(skillset.values(), key=lambda x:(collator.key(x.label or ''), collator.key(x.title))): title = skill.title if skill.label: title = '%s: %s' % (skill.label, title) css_class = not skill.required and 'optional' or None skills.append({ 'label': skill.label, 'raw_title': skill.title, 'title': title, 'css_class': css_class, }) skillsets.append({ 'label': skillset.label, 'title': skillset.title, 'skills': skills, 'id': skillset.__name__, 'checked': skillset.__name__ in selected_skillsets or 'SUBMIT_BUTTON' not in self.request, }) self.skillsets = sorted(skillsets, key=lambda x:(collator.key(x['label'] or ''), collator.key(x['title']))) if 'SUBMIT_BUTTON' in self.request: if not selected_skillsets: return for skillset in node.skillsets: if skillset.__name__ in selected_skillsets: self.context[skillset.__name__] = CourseSkillSet(skillset) self.request.response.redirect(self.nextURL()) class AvailableSkillSetTable(RelationshipAddTableMixin, SkillSetTable): @property def source(self): app = ISchoolToolApplication(None) return ISkillSetContainer(app) def submitItems(self): prefix = self.button_prefix + '.' for key in self.request: if not key.startswith(prefix): continue name = key[len(prefix):] self.context[name] = CourseSkillSet(self.source[name]) class CourseSkillSetView(UseCourseTitleMixin, flourish.page.Page): pass class CourseSkillSetEditView(UseCourseTitleMixin, flourish.page.Page): pass class SelectAllCheckboxColumn(table.column.CheckboxColumn): css_classes = 'select-all' script = 'return ST.cando.column_select_all(this);' def template(self): result = [ '%(title)s', '', ] return ''.join(result) def renderHeader(self, formatter): title = translate(self.title, context=formatter.request, default=self.title) name = self.prefix + '-select-all' return self.template() % { 'title': title, 'css_classes': self.css_classes, 'name': name, 'id': name, 'script': self.script, } class CourseEditSkillSetSkillsTable(table.ajax.Table): def updateFormatter(self): if self._table_formatter is None: self.setUp(table_formatter=self.table_formatter, batch_size=self.batch_size, prefix=self.__name__, css_classes={'table': 'data'}) def columns(self): title = zc.table.column.GetterColumn(name='title', title=_(u"Title"), getter=lambda i, f: i.title, subsort=True) label = zc.table.column.GetterColumn( name='label', title=_(u'Label'), getter=lambda i, f: i.label or '') required = SelectAllCheckboxColumn( self.prefix+'.required', name='required', title=_(u"Required"), id_getter=lambda i: i.__name__, value_getter=lambda i: i.required) hidden = SelectAllCheckboxColumn( self.prefix+'.hidden', name='hidden', title=_(u"Hidden"), id_getter=lambda i: i.__name__, value_getter=lambda i: i.retired) directlyProvides(title, ISortableColumn) directlyProvides(label, ISortableColumn) return [label, title, required, hidden] def items(self): source = self.source skillset = source.skillset return [source.get(k) for k in skillset] def nextURL(self): return absoluteURL(self.context, self.request) def applyChanges(self): for v in self.items(): k = v.__name__ required = bool(self.request.get(self.prefix + '.required.' + k)) hidden = bool(self.request.get(self.prefix + '.hidden.' + k)) if v.required != required: v.required = required if v.retired != hidden: v.retired = hidden def update(self): super(CourseEditSkillSetSkillsTable, self).update() if 'SUBMIT_BUTTON' in self.request: self.applyChanges() self.request.response.redirect(self.nextURL()) return if 'CANCEL_BUTTON' in self.request: self.request.response.redirect(self.nextURL()) return def sortOn(self): return (('label', False),) class CourseSkillSetSkillTable(SkillSetSkillTable): def sortOn(self): return (("label", False),) def columns(self): default = table.ajax.Table.columns(self) label = zc.table.column.GetterColumn( name='label', title=_(u'Label'), getter=lambda i, f: i.label or '') directlyProvides(label, ISortableColumn) return [label] + default class CourseSkillView(SkillView): can_edit = False class EditCourseSkillsView(UseCourseTitleMixin, flourish.page.Page): content_template = ViewPageTemplateFile( 'templates/edit_course_skills.pt') @Lazy def submitted(self): return 'SUBMIT_BUTTON' in self.request def nextURL(self): return absoluteURL(self.context, self.request) def update(self): if 'CANCEL' in self.request: self.request.response.redirect(self.nextURL()) return skillsets = [] required_prefix = 'required.' visible_prefix = 'visible.' collator = ICollator(self.request.locale) for course_skillset_id in self.context: skillset_modified = False course_skillset = self.context[course_skillset_id] skillset = course_skillset.skillset title = skillset.title if skillset.label: title = '%s: %s' % (skillset.label, title) skills = [] for skill in sorted(skillset.values(), key=lambda x:(collator.key(x.label or ''), collator.key(x.title))): course_skill = course_skillset[skill.__name__] skill_title = skill.title if skill.label: skill_title = '%s: %s' % (skill.label, skill_title) skill_id = self.getId(course_skill) required_name = required_prefix + skill_id visible_name = visible_prefix + skill_id if self.submitted: required = required_name in self.request if course_skill.required != required: course_skill.required = required skillset_modified = True deprecated = visible_name in self.request if course_skill.retired != deprecated: course_skill.retired = deprecated skillset_modified = True skills.append({ 'id': skill_id, 'title': skill_title, 'required_checked': course_skill.required, 'required_name': required_name, 'visible_checked': course_skill.retired, 'visible_name': visible_name, }) skillsets.append({ 'label': skillset.label, 'raw_title': skillset.title, 'title': title, 'skills': skills, }) if skillset_modified: zope.lifecycleevent.modified(course_skillset) if self.submitted: self.request.response.redirect(self.nextURL()) return self.skillsets = sorted(skillsets, key=lambda x:(collator.key(x['label'] or ''), collator.key(x['raw_title']))) def getId(self, skill): skillset = skill.__parent__ return '%s.%s' % (skillset.__name__, skill.__name__) class CanDoCoursesActionsLinks(flourish.page.RefineLinksViewlet): pass class CoursesSkillsAssignmentView(flourish.page.Page, ActiveSchoolYearContentMixin): matched = [] not_matched = [] container_class = 'container widecontainer' content_template = ViewPageTemplateFile( 'templates/courses_skills_assignment.pt') @property def course_attrs(self): attrs = ['__name__', 'title', 'description', 'course_id', 'government_id'] return [{'title': ICourse[attr].title, 'value': attr} for attr in attrs] @property def node_attrs(self): attrs = ['label', 'title', 'description'] return [{'title': INode[attr].title, 'value': attr} for attr in attrs] @property def courses(self): return ICourseContainer(self.context) @property def layers(self): app = ISchoolToolApplication(None) return ILayerContainer(app) @property def nodes(self): app = ISchoolToolApplication(None) return INodeContainer(app) @property def skills(self): app = ISchoolToolApplication(None) return ISkillSetContainer(app) def getSkillSetID(self, skillset): return skillset.__name__.split('-')[0] def requiredSubmitted(self): required = ['course_attr', 'layer', 'node_attr'] for attr in required: if not self.request.get(attr, ''): return False return True @property def schoolyear(self): return ISchoolYear(self.context) def nextURL(self): app = ISchoolToolApplication(None) return self.url_with_schoolyear_id(app, view_name='courses') def updateMatches(self): assignments = [] not_assigned = [] course_attr = self.request['course_attr'] layer = self.layers[self.request['layer']] node_attr = self.request['node_attr'] nodes = list(getRelatedObjects(layer, URINode, URINodeLayer)) for course in self.courses.values(): course_attr_value = getattr(course, course_attr, '') skills = ICourseSkills(course) # only use courses with no skills if skills: not_assigned.append({ 'course': course, 'course_attr': course_attr_value, 'reason': _('Course has skills assigned already'), }) continue if course_attr_value: assigned = False for node in nodes: node_attr_value = getattr(node, node_attr, '') if node_attr_value: if (node_attr_value == course_attr_value and not node.retired): assignments.append({ 'course': course, 'course_attr': course_attr_value, 'node': node, 'node_attr': node_attr_value, }) assigned = True if not assigned: not_assigned.append({ 'course': course, 'course_attr': course_attr_value, 'reason': _("Couldn't find a matching node"), }) else: not_assigned.append({ 'course': course, 'course_attr': course_attr_value, 'reason': _('Course attribute is empty'), }) self.matched = assignments self.not_matched = not_assigned def update(self): collator = ICollator(self.request.locale) if 'CANCEL' in self.request: self.request.response.redirect(self.nextURL()) return if self.requiredSubmitted(): self.updateMatches() if 'ASSIGN_BUTTON' in self.request: for info in self.matched: course = info['course'] node = info['node'] skills = ICourseSkills(course) for skillset in node.skillsets: skills[skillset.__name__] = CourseSkillSet(skillset) self.request.response.redirect(self.nextURL()) return if 'SEARCH_BUTTON' in self.request: self.matched = sorted( self.matched, key=lambda x:(x['course_attr'], collator.key(x['course'].title)) ) self.not_matched = sorted( self.not_matched, key=lambda x:(x['course_attr'], collator.key(x['course'].title)) ) class BatchAssignSkillsLinkViewlet(flourish.page.LinkViewlet): @property def schoolyear(self): schoolyears = ISchoolYearContainer(self.context) result = schoolyears.getActiveSchoolYear() if 'schoolyear_id' in self.request: schoolyear_id = self.request['schoolyear_id'] result = schoolyears.get(schoolyear_id, result) return result @property def courses(self): return ICourseContainer(self.schoolyear) @property def enabled(self): return bool(self.courses) @property def url(self): return '%s/%s' % (absoluteURL(self.courses, self.request), 'assign-courses-skills.html') schooltool.cando-2.6.2/src/schooltool/cando/browser/configure.zcml0000644000175000017500000007046612270520445026532 0ustar menesismenesis00000000000000 schooltool.cando-2.6.2/src/schooltool/cando/browser/report.zcml0000644000175000017500000003001312270520445026044 0ustar menesismenesis00000000000000 schooltool.cando-2.6.2/src/schooltool/cando/browser/importer.py0000644000175000017500000004153512270520445026070 0ustar menesismenesis00000000000000# # SchoolTool - common information systems platform for school administration # Copyright (c) 2012 Shuttleworth Foundation # # 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 2 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 . # """ Skills importer. """ import zope.lifecycleevent from zope.security.proxy import removeSecurityProxy from zope.proxy import sameProxiedObjects from zope.traversing.browser.absoluteurl import absoluteURL from schooltool.app.interfaces import ISchoolToolApplication from schooltool.course.interfaces import ICourseContainer from schooltool.export.importer import (ImporterBase, FlourishMegaImporter, ERROR_INVALID_SCHOOL_YEAR, ERROR_MISSING_YEAR_ID, ERROR_INVALID_COURSE_ID) from schooltool.schoolyear.interfaces import ISchoolYearContainer from schooltool.requirement.interfaces import IScoreSystemContainer from schooltool.cando.course import CourseSkillSet from schooltool.cando.interfaces import (ILayerContainer, INodeContainer, ISkillSetContainer, ICourseSkills, IDocumentContainer) from schooltool.cando.model import Layer, Node, Document from schooltool.cando.skill import SkillSet, Skill from schooltool.cando import CanDoMessage as _ ERROR_INVALID_DOCUMENTS = _("has an invalid document id") ERROR_INVALID_PARENTS = _("has an invalid parent id") ERROR_INVALID_LAYERS = _("has an invalid layer id") ERROR_INVALID_SKILLSET = _("has an invalid skillset id") ERROR_MISSING_SKILLSET_ID = _("is missing a skillset id") ERROR_INVALID_EQUIVALENT = _("has an invalid equivalent skill id") ERROR_NODE_LABEL_TOO_BIG = _("node label has more than seven characters") ERROR_INVALID_SCORESYSTEM = _("has an invalid scoresystem") ERROR_INVALID_NODE = _("has an invalid node id") def breakupIds(ids): return [p.strip() for p in ids.split(',') if p.strip()] class Changer(object): changed = False ignore = False def __init__(self, obj, ignore=False): self.obj = obj def __setitem__(self, attr, val): if (not hasattr(self.obj, attr) or getattr(self.obj, attr) != val): setattr(self.obj, attr, val) if not self.ignore: self.changed = True def __nonzero__(self): return self.changed def change(self, changes=None): self.changed = self.changed or bool(changes) def notify(self): if self.changed: zope.lifecycleevent.modified(self.obj) self.changed = False class SkillSetsImporter(ImporterBase): sheet_name = 'SkillSets' def process(self): sh = self.sheet skillsets = ISkillSetContainer(self.context) for row in range(1, sh.nrows): if sh.cell_value(rowx=row, colx=0) == '': break num_errors = len(self.errors) name = self.getRequiredTextFromCell(sh, row, 0) title = self.getRequiredTextFromCell(sh, row, 1) description = self.getTextFromCell(sh, row, 2) label = self.getTextFromCell(sh, row, 3) retired = self.getBoolFromCell(sh, row, 4) if num_errors < len(self.errors): continue if name in skillsets: skillset = skillsets[name] changes = Changer(skillset) changes['title'] = title else: skillset = skillsets[name] = SkillSet(title) changes = Changer(skillset, ignore=True) changes['description'] = description changes['label'] = label changes['retired'] = bool(retired) changes.notify() class SkillsImporter(ImporterBase): sheet_name = 'Skills' def process(self): sh = self.sheet skillsets = ISkillSetContainer(self.context) scoresystems = IScoreSystemContainer(self.context) skillset = None skillset_changes = dict([(k, Changer(v)) for k, v in skillsets.items()]) for row in range(1, sh.nrows): if (sh.cell_value(rowx=row, colx=0) == '' and sh.cell_value(rowx=row, colx=1) == ''): break num_errors = len(self.errors) skillset_id = self.getTextFromCell(sh, row, 0) name = self.getRequiredTextFromCell(sh, row, 1) title = self.getRequiredTextFromCell(sh, row, 2) description = self.getTextFromCell(sh, row, 4) external_id = self.getTextFromCell(sh, row, 5) label = self.getTextFromCell(sh, row, 6) required = self.getBoolFromCell(sh, row, 7) retired = self.getBoolFromCell(sh, row, 8) scoresystem = self.getTextFromCell(sh, row, 9) if num_errors < len(self.errors): continue if skillset_id: if skillset_id not in skillsets: self.error(row, 0, ERROR_INVALID_SKILLSET) continue skillset = skillsets[skillset_id] elif skillset is None: self.error(row, 0, ERROR_MISSING_SKILLSET_ID) continue if scoresystem and scoresystem not in scoresystems: self.error(row, 3, ERROR_INVALID_SCORESYSTEM) continue if name in skillset: skill = skillset[name] changes = Changer(skill) changes['title'] = title else: skill = skillset[name] = Skill(title) changes = Changer(skill) changes['description'] = description changes['external_id'] = external_id changes['label'] = label changes['required'] = bool(required) changes['retired'] = bool(retired) if scoresystem: changes['scoresystem'] = removeSecurityProxy( scoresystems[scoresystem]) skillset_changes[skillset.__name__].change(changes) skillset = None for changes in skillset_changes.values(): changes.notify() for row in range(1, sh.nrows): if (sh.cell_value(rowx=row, colx=0) == '' and sh.cell_value(rowx=row, colx=1) == ''): break skillset_id = self.getTextFromCell(sh, row, 0) name = self.getRequiredTextFromCell(sh, row, 1) equivalent = self.getTextFromCell(sh, row, 3) if skillset_id: if skillset_id not in skillsets: skillset = None else: skillset = skillsets[skillset_id] if skillset is None or name not in skillset: continue skill = skillset[name] equiv = removeSecurityProxy(skill.equivalent) for part in breakupIds(equivalent): if part not in skillset: self.error(row, 3, ERROR_INVALID_EQUIVALENT) break equiv.add(removeSecurityProxy(skillset[part])) class LayersImporter(ImporterBase): sheet_name = 'Layers' def process(self): sh = self.sheet layers = ILayerContainer(self.context) for row in range(1, sh.nrows): if sh.cell_value(rowx=row, colx=0) == '': break num_errors = len(self.errors) name = self.getRequiredTextFromCell(sh, row, 0) title = self.getRequiredTextFromCell(sh, row, 1) if num_errors < len(self.errors): continue if name in layers: layers[name].title = title else: layers[name] = Layer(title) for row in range(1, sh.nrows): if sh.cell_value(rowx=row, colx=0) == '': break name = self.getTextFromCell(sh, row, 0) parents = self.getTextFromCell(sh, row, 2) if name not in layers: continue layer = removeSecurityProxy(layers[name]) for parent in list(layer.parents): layer.parents.remove(parent) for part in breakupIds(parents): if part not in layers: self.error(row, 2, ERROR_INVALID_PARENTS) break layer.parents.add(removeSecurityProxy(layers[part])) class DocumentsImporter(ImporterBase): sheet_name = 'Documents' def process(self): sh = self.sheet layers = ILayerContainer(self.context) documents = IDocumentContainer(self.context) for row in range(1, sh.nrows): if sh.cell_value(rowx=row, colx=0) == '': break num_errors = len(self.errors) name = self.getRequiredTextFromCell(sh, row, 0) title = self.getRequiredTextFromCell(sh, row, 1) description = self.getTextFromCell(sh, row, 2) hierarchy = self.getTextFromCell(sh, row, 3) if num_errors < len(self.errors): continue if name in documents: documents[name].title = title documents[name].description = description else: documents[name] = Document(title, description) document = removeSecurityProxy(documents[name]) for layer in list(document.hierarchy): document.hierarchy.remove(layer) for part in breakupIds(hierarchy): if part not in layers: self.error(row, 4, ERROR_INVALID_LAYERS) break document.hierarchy.add(removeSecurityProxy(layers[part])) class NodesImporter(ImporterBase): sheet_name = 'Nodes' def process(self): sh = self.sheet nodes = INodeContainer(self.context) layers = ILayerContainer(self.context) skillsets = ISkillSetContainer(self.context) documents = IDocumentContainer(self.context) for row in range(1, sh.nrows): if sh.cell_value(rowx=row, colx=0) == '': break num_errors = len(self.errors) name = self.getRequiredTextFromCell(sh, row, 0) title = self.getRequiredTextFromCell(sh, row, 1) description = self.getTextFromCell(sh, row, 2) label = self.getTextFromCell(sh, row, 3) retired = self.getBoolFromCell(sh, row, 8) if num_errors < len(self.errors): continue if len(label) > 7: self.error(row, 3, ERROR_NODE_LABEL_TOO_BIG) continue if name in nodes: nodes[name].title = title nodes[name].description = description nodes[name].label = label nodes[name].retired = retired else: nodes[name] = Node(title, description, label, retired) for row in range(1, sh.nrows): if sh.cell_value(rowx=row, colx=0) == '': break name = self.getTextFromCell(sh, row, 0) node_documents = self.getTextFromCell(sh, row, 4) parents = self.getTextFromCell(sh, row, 5) node_layers = self.getTextFromCell(sh, row, 6) node_skillsets = self.getTextFromCell(sh, row, 7) if name not in nodes: continue node = removeSecurityProxy(nodes[name]) for parent in list(node.parents): node.parents.remove(parent) for part in breakupIds(node_documents): if part not in documents: self.error(row, 4, ERROR_INVALID_DOCUMENTS) break node.parents.add(removeSecurityProxy(documents[part])) for part in breakupIds(parents): if part not in nodes: self.error(row, 5, ERROR_INVALID_PARENTS) break node.parents.add(removeSecurityProxy(nodes[part])) for layer in list(node.layers): node.layers.remove(layer) for part in breakupIds(node_layers): if part not in layers: self.error(row, 6, ERROR_INVALID_LAYERS) break node.layers.add(removeSecurityProxy(layers[part])) for skillset in list(node.skillsets): node.skillsets.remove(skillset) for part in breakupIds(node_skillsets): if part not in skillsets: self.error(row, 7, ERROR_INVALID_SKILLSET) break node.skillsets.add(removeSecurityProxy(skillsets[part])) class CourseSkillsImporter(ImporterBase): sheet_name = 'CourseSkills' def process(self): sh = self.sheet skillsets = ISkillSetContainer(self.context) schoolyears = ISchoolYearContainer(self.context) year = None for row in range(1, sh.nrows): if (sh.cell_value(rowx=row, colx=0) == '' and sh.cell_value(rowx=row, colx=1) == ''): break num_errors = len(self.errors) year_id = self.getTextFromCell(sh, row, 0) course_id = self.getRequiredTextFromCell(sh, row, 1) course_skillset_ids = self.getTextFromCell(sh, row, 2) if num_errors < len(self.errors): continue if year_id: if year_id not in schoolyears: self.error(row, 0, ERROR_INVALID_SCHOOL_YEAR) year = None else: year = schoolyears[year_id] courses = ICourseContainer(year) elif year is None: self.error(row, 0, ERROR_MISSING_YEAR_ID) if year is None: continue if course_id not in courses: self.error(row, 1, ERROR_INVALID_COURSE_ID) continue course = courses[course_id] course_skills = ICourseSkills(course) for key in list(course_skills): del course_skills[key] for part in breakupIds(course_skillset_ids): if part not in skillsets: self.error(row, 2, ERROR_INVALID_SKILLSET) break course_skills[part] = CourseSkillSet(skillsets[part]) class CourseNodesImporter(ImporterBase): sheet_name = 'CourseNodes' def process(self): sh = self.sheet nodes = INodeContainer(self.context) schoolyears = ISchoolYearContainer(self.context) year = None for row in range(1, sh.nrows): if (sh.cell_value(rowx=row, colx=0) == '' and sh.cell_value(rowx=row, colx=1) == ''): break num_errors = len(self.errors) year_id = self.getTextFromCell(sh, row, 0) course_id = self.getRequiredTextFromCell(sh, row, 1) course_node_ids = self.getTextFromCell(sh, row, 2) if num_errors < len(self.errors): continue if year_id: if year_id not in schoolyears: self.error(row, 0, ERROR_INVALID_SCHOOL_YEAR) year = None else: year = schoolyears[year_id] courses = ICourseContainer(year) elif year is None: self.error(row, 0, ERROR_MISSING_YEAR_ID) if year is None: continue if course_id not in courses: self.error(row, 1, ERROR_INVALID_COURSE_ID) continue course = courses[course_id] course_skills = ICourseSkills(course) for key in list(course_skills): del course_skills[key] for part in breakupIds(course_node_ids): if part not in nodes: self.error(row, 2, ERROR_INVALID_NODE) break node = nodes[part] for skillset in node.skillsets: course_skills[skillset.__name__] = CourseSkillSet(skillset) class GlobalSkillsMegaImporter(FlourishMegaImporter): def nextURL(self): app = ISchoolToolApplication(None) container = IDocumentContainer(app) url = absoluteURL(container, self.request) return url @property def importers(self): return [ SkillSetsImporter, SkillsImporter, LayersImporter, DocumentsImporter, NodesImporter, CourseSkillsImporter, CourseNodesImporter, ] schooltool.cando-2.6.2/src/schooltool/cando/browser/stests/0000755000175000017500000000000012322040274025165 5ustar menesismenesis00000000000000schooltool.cando-2.6.2/src/schooltool/cando/browser/stests/gradebook_management.txt0000644000175000017500000000307012270520445032064 0ustar menesismenesis00000000000000CanDo Gradebook management tests ================================ We'll test how to add and score Projects and Skills in the CanDo gradebook. Let's do some set up first. Log in as manager: >>> manager = browsers.manager >>> manager.ui.login('manager', 'schooltool') Add a school year: >>> manager.ui.schoolyear.add('2012', '2012-01-01', '2012-12-31') Add a term: >>> manager.ui.term.add('2012', 'Single Year', '2012-01-01', '2012-12-31') Add some people: >>> manager.ui.person.add('Tom', 'Hoffman', 'tom', 'pwd') >>> manager.ui.person.add('Camila', 'Cerna', 'camila', 'pwd') >>> manager.ui.person.add('Mario', 'Tejada', 'mario', 'pwd') >>> manager.ui.person.add('Nestor', 'Guzman', 'nestor', 'pwd') Add a course: >>> manager.ui.course.add('2012', 'Baseball') Add a section: >>> manager.ui.section.add('2012', 'Single Year', 'Baseball') with instructors: >>> manager.ui.section.instructors.add('2012', 'Single Year', ... 'Baseball (1)', ['tom']) and students: >>> manager.ui.section.students.add('2012', 'Single Year', 'Baseball (1)', ... ['camila', 'mario', 'nestor']) Let's login as the teacher: >>> tom = browsers.tom >>> tom.ui.login('tom', 'pwd') The teacher can access CanDo's gradebook using the link in the top navigation bar: >>> sel = '//ul[@class="navigation"]//a[text()="CanDo"]' >>> tom.query.xpath(sel).click() >>> tom.url u'http://localhost/schoolyears/2012/single-year/sections/1/projects/Project/gradebook' schooltool.cando-2.6.2/src/schooltool/cando/browser/stests/test_selenium.py0000644000175000017500000000207612270520445030431 0ustar menesismenesis00000000000000# # SchoolTool - common information systems platform for school administration # Copyright (c) 2012 Shuttleworth Foundation # # 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 2 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 . # """ Functional tests for schooltool.cando """ import unittest from schooltool.testing.selenium import collect_ftests from schooltool.cando.stesting import skill_selenium_layer def test_suite(): return collect_ftests(layer=skill_selenium_layer) if __name__ == '__main__': unittest.main(defaultTest='test_suite') schooltool.cando-2.6.2/src/schooltool/cando/browser/stests/skill_events_importer.txt0000644000175000017500000002721512270520445032365 0ustar menesismenesis00000000000000Test for the skill event subscribers using the skill importer ============================================================= We'll test that modifying the skill document tree through the XLS importer propagates the changes to the course and section skills, so they're visible in the gradebook. Log in as manager: >>> manager = browsers.manager >>> manager.ui.login('manager', 'schooltool') Set up a skill document tree. Note the typos in the 'Fraktions' skill set: >>> manager.query.link('School').click() >>> manager.query.link('Skills').click() >>> manager.query.link('Document').click() >>> manager.query.id('form-widgets-title').ui.set_value('Virginia CTE') >>> manager.query.id('add-button').click() >>> manager.query.name('row2').ui.set_value('Course') >>> manager.query.id('add-button').click() >>> manager.query.name('row3').ui.set_value('Cluster') >>> manager.query.id('form-buttons-add').click() >>> manager.ui.skillset.add('Fraktions', '01') >>> manager.ui.skillset.add('Percents', '02') >>> manager.ui.skillset.add('Arithmetic of Decimals') >>> manager.query.link('Arithmetic of Decimals').click() >>> manager.query.css('a[title="Edit this skill set"]').click() >>> manager.query.id('form-widgets-label').clear() >>> manager.query.id('form-buttons-apply').click() >>> manager.ui.skill.add('Fraktions', 'Multiply two fractions.', '01') >>> manager.ui.skill.add('Fraktions', ... 'Divide a fraction by a mixed number.', '02') >>> manager.ui.skill.add('Fraktions', ... 'Divide a fraction by a whole number.', '03') >>> manager.ui.skill.add('Fraktions', 'Read and write fractions.') >>> manager.query.link('Read and write fractions.').click() >>> manager.query.css('a[title="Edit this skill"]').click() >>> manager.query.id('form-widgets-label').clear() >>> manager.query.id('form-buttons-apply').click() >>> manager.query.link('Done').click() >>> manager.ui.skill.add('Fraktions', ... 'Convert mixed numbers to improper fractions.') >>> manager.query.link('Convert mixed numbers to improper fractions.').click() >>> manager.query.css('a[title="Edit this skill"]').click() >>> manager.query.id('form-widgets-label').clear() >>> manager.query.id('form-buttons-apply').click() >>> manager.query.link('Done').click() >>> manager.ui.skill.add('Percents', 'Write fractions as percents.', '01') >>> manager.ui.skill.add('Percents', ... 'Write decimal numbers as percents.', '03') >>> manager.ui.skill.add('Percents', ... 'Write percents as decimal numbers.', '02') >>> manager.ui.skill.add('Arithmetic of Decimals', ... 'Add two decimal numbers.', '01') >>> manager.ui.skill.add('Arithmetic of Decimals', ... 'Subtract two decimal numbers.', '02') >>> manager.ui.skill.add('Arithmetic of Decimals', ... 'Add a group of decimal numbers.', '03') >>> manager.ui.node.add('Math') >>> sel = '//h2[contains(@class, "ui-accordion-header")]' >>> accordion_headers = manager.query_all.xpath(sel) >>> sel = 'div.ui-accordion-content' >>> accordion_contents = manager.query_all.css(sel) >>> information_accordion_content = accordion_contents[0] >>> skillsets_accordion_header = accordion_headers[4] >>> skillsets_accordion_header.click() >>> skillsets_accordion_content = accordion_contents[4] >>> manager.wait_no(information_accordion_content.is_displayed) >>> sel = 'a[title="Edit skill sets"]' >>> manager.query.css(sel).click() >>> manager.query.name('add_item.Fraktion1').click() >>> manager.query.name('add_item.Percents2').click() >>> manager.query.name('add_item.Arithmet3').click() Set up a section: >>> manager.ui.person.add('Jeffrey', 'Elkner', 'jeffrey', 'pwd') >>> manager.ui.person.add('Camila', 'Cerna', 'camila', 'pwd') >>> manager.ui.person.add('Liliana', 'Vividor', 'liliana', 'pwd') >>> manager.ui.person.add('Mario', 'Tejada', 'mario', 'pwd') >>> manager.ui.schoolyear.add('2012', '2012-01-01', '2012-12-31') >>> manager.ui.term.add('2012', '2012', '2012-01-01', '2012-12-31') >>> manager.ui.course.add('2012', 'Math') >>> manager.ui.section.add('2012', '2012', 'Math') >>> manager.ui.section.instructors.add('2012', '2012', 'Math (1)', ... ['jeffrey']) >>> manager.ui.section.students.add('2012', '2012', 'Math (1)', ... ['camila', 'liliana', 'mario']) And assign the skills to the its course: >>> manager.query.link('School').click() >>> manager.query.link('Courses').click() >>> manager.query.link('Math').click() >>> manager.query.link('Skills').click() >>> manager.query.link('Assign Skills').click() >>> manager.query.id('math').click() >>> dialog = manager.query.css('.ui-dialog') >>> manager.wait_page(dialog.query.name('SUBMIT_BUTTON').click) Log in as teacher and go to the CanDo gradebook: >>> teacher = browsers.teacher >>> teacher.ui.login('jeffrey', 'pwd') >>> teacher.query.link('CanDo').click() Add some scores to the Fraktions skill set: >>> sel = 'a[title="01: Fraktions"]' >>> link = teacher.query.css(sel) >>> # XXX: fix this, use clicks instead of open >>> teacher.open(link.get_attribute('href')) >>> fractions_url = teacher.url >>> teacher.ui.gradebook.worksheet.score('Camila Cerna', 'Conve', '4') >>> teacher.ui.gradebook.worksheet.score('Camila Cerna', 'Reada', '3') >>> teacher.ui.gradebook.worksheet.score('Camila Cerna', '01', '2') >>> teacher.ui.gradebook.worksheet.score('Camila Cerna', '02', '1') >>> teacher.ui.gradebook.worksheet.score('Camila Cerna', '03', '0') >>> teacher.ui.gradebook.worksheet.score('Mario Tejada', 'Conve', '0') >>> teacher.ui.gradebook.worksheet.score('Mario Tejada', 'Reada', '1') >>> teacher.ui.gradebook.worksheet.score('Mario Tejada', '02', '3') >>> teacher.ui.gradebook.worksheet.score('Liliana Vividor', 'Conve', '0') >>> teacher.ui.gradebook.worksheet.score('Liliana Vividor', '01', '4') >>> teacher.ui.gradebook.worksheet.score('Liliana Vividor', '03', '1') >>> teacher.query.name('UPDATE_SUBMIT').click() >>> teacher.ui.gradebook.worksheet.pprint() +------------------------+-----------------+--------------+ | Arithmetic of Decimals | *01: Fraktions* | 02: Percents | +------------------------+-----------------+--------------+ +-----------+------------+-------+-------+----+----+----+ | Last Name | First Name | Conve | Reada | 01 | 02 | 03 | | | | 4 | 4 | 4 | 4 | 4 | +-----------+------------+-------+-------+----+----+----+ | Cerna | Camila | 4 | 3 | 2 | 1 | 0 | | Tejada | Mario | 0 | 1 | | 3 | | | Vividor | Liliana | 0 | | 4 | | 1 | +-----------+------------+-------+-------+----+----+----+ List the skills and their types in the Percents skill set: >>> sel = 'a[title="02: Percents"]' >>> link = teacher.query.css(sel) >>> # XXX: fix this, use clicks instead of open >>> teacher.open(link.get_attribute('href')) >>> percents_url = teacher.url >>> def print_activity_columns(browser): ... sel = '#grades-part thead tr:first-child th.scorable' ... for th in browser.query_all.css(sel): ... browser.wait_no(lambda:th.query.tag('ul.popup_menu img')) ... header = th.query.css('ul.popup_menu li.header') ... optional = 'optional' in th.get_attribute('class') ... print ['required', 'optional'][optional] ... # XXX: why header.text produces BLANKLINE? ... print header >>> print_activity_columns(teacher) required
  • 01: Write fractions as percents.
  • required
  • 02: Write percents as decimal numbers.
  • required
  • 03: Write decimal numbers as percents.
  • Add some scores to the Percent skill set: >>> teacher.ui.gradebook.worksheet.score('Camila Cerna', '01', '2') >>> teacher.ui.gradebook.worksheet.score('Camila Cerna', '02', '1') >>> teacher.ui.gradebook.worksheet.score('Camila Cerna', '03', '0') >>> teacher.ui.gradebook.worksheet.score('Mario Tejada', '02', '3') >>> teacher.ui.gradebook.worksheet.score('Mario Tejada', '03', '4') >>> teacher.ui.gradebook.worksheet.score('Liliana Vividor', '01', '1') >>> teacher.ui.gradebook.worksheet.score('Liliana Vividor', '02', '2') >>> teacher.query.name('UPDATE_SUBMIT').click() >>> teacher.ui.gradebook.worksheet.pprint() +------------------------+---------------+----------------+ | Arithmetic of Decimals | 01: Fraktions | *02: Percents* | +------------------------+---------------+----------------+ +-----------+------------+----+----+----+ | Last Name | First Name | 01 | 02 | 03 | | | | 4 | 4 | 4 | +-----------+------------+----+----+----+ | Cerna | Camila | 2 | 1 | 0 | | Tejada | Mario | | 3 | 4 | | Vividor | Liliana | 1 | 2 | | +-----------+------------+----+----+----+ Let's fix the typo in the Fraktions skill set and modify some skills in the Percents skill set using the XLS importer: >>> from pkg_resources import resource_filename >>> path = resource_filename('schooltool.cando.browser.stests', ... 'skill_events_importer.xls') >>> manager.ui.skill.import_xls(path) The Fraktions skill set should be updated in the teacher's gradebook: >>> teacher.open(fractions_url) >>> teacher.ui.gradebook.worksheet.pprint() +------------------------+--------------+-----------------+ | Arithmetic of Decimals | 02: Percents | *10: Fractions* | +------------------------+--------------+-----------------+ +-----------+------------+-------+-------+----+----+----+ | Last Name | First Name | Conve | Reada | 01 | 02 | 03 | | | | 4 | 4 | 4 | 4 | 4 | +-----------+------------+-------+-------+----+----+----+ | Cerna | Camila | 4 | 3 | 2 | 1 | 0 | | Tejada | Mario | 0 | 1 | | 3 | | | Vividor | Liliana | 0 | | 4 | | 1 | +-----------+------------+-------+-------+----+----+----+ So should be the skills in the Percents skill set. Note that the XLS sets the "Write PERCENTS as decimal numbers" skill as optional, but that change doesn't propagate (XXX: test global import changes to deprecated and scoresystem attributes): >>> teacher.open(percents_url) >>> print_activity_columns(teacher) required
  • 02: Write PERCENTS as decimal numbers.
  • required
  • 03: Write decimal numbers as percents.
  • required
  • 07: Write fractions as percents.
  • >>> teacher.ui.gradebook.worksheet.pprint() +------------------------+----------------+---------------+ | Arithmetic of Decimals | *02: Percents* | 10: Fractions | +------------------------+----------------+---------------+ +-----------+------------+----+----+----+ | Last Name | First Name | 02 | 03 | 07 | | | | 4 | 4 | 4 | +-----------+------------+----+----+----+ | Cerna | Camila | 1 | 0 | 2 | | Tejada | Mario | 3 | 4 | | | Vividor | Liliana | 2 | | 1 | +-----------+------------+----+----+----+ schooltool.cando-2.6.2/src/schooltool/cando/browser/stests/import_skills.txt0000644000175000017500000001611212270520445030627 0ustar menesismenesis00000000000000Tests for the global skills xls import ====================================== Log in as manager: >>> manager = browsers.manager >>> manager.ui.login('manager', 'schooltool') We'll define a helper function for printing the form fields of any object. >>> def print_attrs(): ... sel = 'table.form-fields tbody tr' ... for row in manager.query_all.css(sel): ... label = row.query.xpath('td[1]').text ... value = row.query.xpath('td[2]').text ... print '%s: %s' % (label, value) >>> from schooltool.testing.util import format_table >>> def print_table(manager, xpath): ... table = manager.query.xpath(xpath) ... nheader = len(table.query_all.xpath('./thead/tr')) ... nrows = len(table.query_all.xpath('./tbody/tr|./tr')) ... rows = [] ... row = [] ... cells = table.query_all.xpath('.//th|.//td') ... ncols = len(cells) / (nheader + nrows) ... for n, cell in enumerate(cells): ... row.append(cell.text) ... if (n+1) % ncols == 0: ... rows.append(row) ... row = [] ... print format_table(rows, header_rows=nheader) Let's import a file containing all the skill object types: >>> import os >>> dirname = os.path.abspath(os.path.dirname(__file__)) >>> filename = os.path.join(dirname, 'sample_data.xls') >>> manager.ui.skill.import_xls(filename) There should be no errors so we should be back at the Documents view: >>> manager.url u'http://localhost/documents' Let's check the data. There is one skillset called Carpentry. >>> manager.open('http://localhost/skills') >>> print_table(manager, '//table[@class="data"]') +------------+-----------+--------+ | Label | Title | Skills | +------------+-----------+--------+ | Carp label | Carpentry | 3 | +------------+-----------+--------+ It has three skills. >>> manager.query.link('Carpentry').click() >>> print_table(manager, '//table[@class="form-fields"]') +-------------+------------+ | Description | ext_carp | | Label | Carp label | | Deprecated | No | +-------------+------------+ >>> print_table(manager, '//table[@class="data"]') +-------+-----------+ | Label | Title | +-------+-----------+ | | Pounding | | | Whacking | | Label | Hammering | +-------+-----------+ Let's visit each skill and print their attrs. >>> manager.query.link('Pounding').click() >>> print_attrs() Scoresystem: Letter Grade Description: Label: Required?: Required Deprecated: No External ID: ext_123 >>> manager.query.link('Done').click() >>> manager.query.link('Whacking').click() >>> print_attrs() Scoresystem: Pass/Fail Description: Whacking desc. Label: Required?: Optional Deprecated: No External ID: >>> manager.query.link('Done').click() >>> manager.query.link('Hammering').click() >>> print_attrs() Scoresystem: Competency Description: This is hammering. Label: Label Required?: Optional Deprecated: Yes External ID: There are five layers. >>> manager.query.link('School').click() >>> manager.query.link('Skills').click() >>> manager.query.link('Layers').click() >>> print_table(manager, '//table[@class="data"]') +--------------+---------------+---------------+ | Title | Parents | Children | +--------------+---------------+---------------+ | Branch | Craft | Topic | | Competencies | | | | Competency | | | | Craft | | Branch, Topic | | Topic | Branch, Craft | | +--------------+---------------+---------------+ There is a single sample document. >>> manager.query.link('School').click() >>> manager.query.link('Skills').click() >>> manager.query.link('Documents').click() >>> print_table(manager, '//table[@class="data"]') +------------+ | Title | +------------+ | Sample Doc | +------------+ It has five layers in its heirarchy: top three are for use with nodes, bottom two are only used to name skills and skillsets. >>> manager.query.link('Sample Doc').click() >>> manager.query.link('Layer Hierarchy').click() >>> print_table(manager, '//table[@class="data relationships-table"]') +--------------+---------------+---------------+--------+ | Title | Parents | Children | Remove | +--------------+---------------+---------------+--------+ | Craft | | Branch, Topic | | | Branch | Craft | Topic | | | Topic | Branch, Craft | | | | Competencies | | | | | Competency | | | | +--------------+---------------+---------------+--------+ The search view returns nodes mixed with skillsets and skills. >>> manager.open('http://localhost/nodes') >>> def searchAndPrintTable(manager): ... table = manager.query.xpath('//table[@class="data"]') ... manager.query.button('Search').click() ... manager.wait(lambda: table.expired) ... print_table(manager, '//table[@class="data"]') >>> searchAndPrintTable(manager) +------------+--------------+---------------+ | Label | Title | Layers | +------------+--------------+---------------+ | carp | Carpentry | Craft | | Carp label | Carpentry | Competencies | | | Conventional | Branch | | creat | Creative | Branch | | | Hammering | Topic, Branch | | Label | Hammering | Competency | | | Pounding | Topic | | | Pounding | Competency | | | Sample Doc | | | | Whacking | Topic | | | Whacking | Competency | +------------+--------------+---------------+ We can filter out some of the layers. >>> print '\n'.join([e.text for e in manager.query_all.xpath('//fieldset//div[@class="row"]//label')]) Search Field Craft Branch Topic Skill Set (Competencies) Skill (Competency) No layer assigned >>> manager.query.xpath('//label[contains(., "Competency")]').click() >>> manager.query.xpath('//label[contains(., "Branch")]').click() >>> manager.query.xpath('//label[contains(., "Craft")]').click() >>> searchAndPrintTable(manager) +------------+------------+---------------+ | Label | Title | Layers | +------------+------------+---------------+ | Carp label | Carpentry | Competencies | | | Hammering | Topic, Branch | | | Pounding | Topic | | | Sample Doc | | | | Whacking | Topic | +------------+------------+---------------+ schooltool.cando-2.6.2/src/schooltool/cando/browser/stests/skill_scoresystems.txt0000644000175000017500000002726712270520445031712 0ustar menesismenesis00000000000000Tests for the skill scoresytems =============================== These tests are a copy of the projects.txt tests but with further testing for how both the project and skills gradebooks handle skills with different scoresystems. Log in as manager: >>> manager = browsers.manager >>> manager.ui.login('manager', 'schooltool') Set up persons: >>> manager.ui.person.add('Jeffrey', 'Elkner', 'jeffrey', 'pwd') >>> manager.ui.person.add('Camila', 'Cerna', 'camila', 'pwd') >>> manager.ui.person.add('Liliana', 'Vividor', 'liliana', 'pwd') >>> manager.ui.person.add('Mario', 'Tejada', 'mario', 'pwd') Set up a section: >>> manager.ui.schoolyear.add('2012', '2012-01-01', '2012-12-31') >>> manager.ui.term.add('2012', '2012', '2012-01-01', '2012-12-31') >>> manager.ui.course.add('2012', 'Programming', course_id='PRO') >>> manager.ui.section.add('2012', '2012', 'Programming') >>> manager.ui.section.instructors.add('2012', '2012', 'Programming (1)', ... ['jeffrey']) >>> manager.ui.section.students.add('2012', '2012', 'Programming (1)', ... ['camila', 'liliana', 'mario']) Set up skills: >>> manager.ui.layer.add('Course') >>> manager.ui.node.add('Programming', label='PRO') >>> manager.ui.skillset.add('Python Environment', '01') >>> manager.ui.skillset.add('Data Types, Statements, and Expressions', '02') >>> manager.ui.skillset.add('Errors', '03') >>> manager.ui.skillset.add('Strings', '04') >>> manager.ui.skill.add( ... 'Python Environment', ... 'Use the Python shell for interactive evaluation', ... '01', scoresystem='Extended Letter Grade') >>> manager.ui.skill.add( ... 'Python Environment', ... 'Make Python scripts with a text editor', ... '02', ... required=False) >>> manager.ui.skill.add( ... 'Data Types, Statements, and Expressions', ... 'Recognize int, float, str, list, tuple, and dict.', ... '03') >>> manager.ui.skill.add( ... 'Data Types, Statements, and Expressions', ... 'Use type(...) to determine the data type of a given value.', ... '04') >>> manager.ui.skill.add( ... 'Data Types, Statements, and Expressions', ... 'Use assignment statements to assign names (variables) to values.', ... '05') >>> manager.ui.skill.add( ... 'Data Types, Statements, and Expressions', ... 'Use the input function to read user input.', ... '06') >>> manager.ui.skill.add( ... 'Data Types, Statements, and Expressions', ... 'Define keyword and recognize keywords in Python.', ... '07') >>> manager.ui.skill.add( ... 'Data Types, Statements, and Expressions', ... 'Create legal variable names and recognize illegal ones.', ... '08', ... required=False) >>> manager.ui.skill.add( ... 'Errors', ... 'Recognize and differentiate among errors.', ... '09', scoresystem='Pass/Fail') >>> manager.ui.skill.add( ... 'Errors', ... 'Read and interpret stack traceback messages.', ... '10') >>> manager.ui.skill.add( ... 'Strings', ... 'Create string literals with single, double, and triple quotes.', ... '11') >>> manager.ui.skill.add( ... 'Strings', ... 'Use the len() function to return the length of a string.', ... '12') >>> manager.ui.skill.add( ... 'Strings', ... 'Use the find(...) method to locate substrings in a string.', ... '13', ... required=False) >>> manager.ui.skill.add( ... 'Strings', ... 'Use the split() method to break a string into a list.', ... '14', ... required=False) >>> manager.query.link('Search').click() >>> manager.query.button('Search').click() >>> manager.query.link('Programming').click() >>> sel = '//h2[contains(@class, "ui-accordion-header")]' >>> accordion_headers = manager.query_all.xpath(sel) >>> sel = 'div.ui-accordion-content' >>> accordion_contents = manager.query_all.css(sel) >>> information_accordion_content = accordion_contents[0] >>> skillsets_accordion_header = accordion_headers[4] >>> skillsets_accordion_header.click() >>> skillsets_accordion_content = accordion_contents[4] >>> manager.wait_no(information_accordion_content.is_displayed) >>> sel = '//a[@title="Edit skill sets"]' >>> manager.query.xpath(sel).click() >>> manager.query.id('form-buttons-add').click() >>> manager.query.link('Done').click() >>> sel = '//h2[contains(@class, "ui-accordion-header")]' >>> accordion_headers = manager.query_all.xpath(sel) >>> sel = 'div.ui-accordion-content' >>> accordion_contents = manager.query_all.css(sel) >>> information_accordion_content = accordion_contents[0] >>> layers_accordion_header = accordion_headers[3] >>> layers_accordion_header.click() >>> layers_accordion_content = accordion_contents[3] >>> manager.wait_no(information_accordion_content.is_displayed) >>> sel = '//a[@title="Edit layers"]' >>> manager.query.xpath(sel).click() >>> manager.query.id('form-buttons-add').click() Assign the skills to the course: >>> manager.query.link('School').click() >>> manager.query.link('Courses').click() >>> manager.query.link('Batch Assign Skills').click() >>> manager.query.name('course_attr').ui.set_value('Course ID') >>> manager.query.name('layer').ui.set_value('Course') >>> manager.query.name('node_attr').ui.set_value('Label') >>> manager.query.name('SEARCH_BUTTON').click() >>> manager.query.name('ASSIGN_BUTTON').click() Log in as instructor: >>> teacher = browsers.teacher >>> teacher.ui.login('jeffrey', 'pwd') >>> teacher.query.link('CanDo').click() Set up three skills in the default project: >>> teacher.query.css('ul.gradebook-modes #projects').click() >>> teacher.query.link('Skill').click() >>> teacher.query.button('Search').click() >>> teacher.query.link('Programming').click() >>> teacher.query.link('Python Environment').click() >>> teacher.query.name('Python E1.Use the 1').click() >>> teacher.query.name('SUBMIT').click() >>> teacher.query.link('Skill').click() >>> teacher.query.button('Search').click() >>> teacher.query.link('Programming').click() >>> teacher.query.link('Errors').click() >>> teacher.query.name('Errors-3.Recogniz1').click() >>> teacher.query.name('SUBMIT').click() >>> teacher.query.link('Skill').click() >>> teacher.query.button('Search').click() >>> teacher.query.link('Programming').click() >>> teacher.query.link('Strings').click() >>> teacher.query.name('Strings-4.Use the 4').click() >>> teacher.query.name('SUBMIT').click() Grade the project skills: >>> teacher.ui.gradebook.worksheet.score('Camila Cerna', '01', 'A+') >>> teacher.ui.gradebook.worksheet.score('Mario Tejada', '01', 'B') >>> teacher.ui.gradebook.worksheet.score('Liliana Vividor', '01', 'D') >>> teacher.ui.gradebook.worksheet.score('Camila Cerna', '09', 'Pass') >>> teacher.ui.gradebook.worksheet.score('Liliana Vividor', '09', 'Fail') >>> teacher.ui.gradebook.worksheet.score('Camila Cerna', '14', '4') >>> teacher.query.name('UPDATE_SUBMIT').click() Print the project's gradebook: >>> teacher.ui.gradebook.worksheet.pprint() +------------+ | *Project1* | +------------+ +-----------+------------+----+------+----+ | Last Name | First Name | 01 | 09 | 14 | | | | A+ | Pass | 4 | +-----------+------------+----+------+----+ | Cerna | Camila | A+ | Pass | 4 | | Tejada | Mario | B | | | | Vividor | Liliana | D | Fail | | +-----------+------------+----+------+----+ Print every worksheet in the skills gradebook to see how the grades are updated from the project: >>> teacher.query.css('ul.gradebook-modes #skills').click() >>> sel = 'a[title="01: Python Environment"]' >>> link = teacher.query.css(sel) >>> # XXX: fix this, use clicks instead of open >>> teacher.open(link.get_attribute('href')) >>> teacher.ui.gradebook.worksheet.pprint() +--------------------------+---------------------------------------------+------------+-------------+ | *01: Python Environment* | 02: Data Types, Statements, and Expressions | 03: Errors | 04: Strings | +--------------------------+---------------------------------------------+------------+-------------+ +-----------+------------+----+----+ | Last Name | First Name | 01 | 02 | | | | A+ | 4 | +-----------+------------+----+----+ | Cerna | Camila | A+ | | | Tejada | Mario | B | | | Vividor | Liliana | D | | +-----------+------------+----+----+ >>> sel = 'a[title="02: Data Types, Statements, and Expressions"]' >>> link = teacher.query.css(sel) >>> # XXX: fix this, use clicks instead of open >>> teacher.open(link.get_attribute('href')) >>> teacher.ui.gradebook.worksheet.pprint() +------------------------+-----------------------------------------------+------------+-------------+ | 01: Python Environment | *02: Data Types, Statements, and Expressions* | 03: Errors | 04: Strings | +------------------------+-----------------------------------------------+------------+-------------+ +-----------+------------+----+----+----+----+----+----+ | Last Name | First Name | 03 | 04 | 05 | 06 | 07 | 08 | | | | 4 | 4 | 4 | 4 | 4 | 4 | +-----------+------------+----+----+----+----+----+----+ | Cerna | Camila | | | | | | | | Tejada | Mario | | | | | | | | Vividor | Liliana | | | | | | | +-----------+------------+----+----+----+----+----+----+ >>> sel = 'a[title="03: Errors"]' >>> link = teacher.query.css(sel) >>> # XXX: fix this, use clicks instead of open >>> teacher.open(link.get_attribute('href')) >>> teacher.ui.gradebook.worksheet.pprint() +------------------------+---------------------------------------------+--------------+-------------+ | 01: Python Environment | 02: Data Types, Statements, and Expressions | *03: Errors* | 04: Strings | +------------------------+---------------------------------------------+--------------+-------------+ +-----------+------------+------+----+ | Last Name | First Name | 09 | 10 | | | | Pass | 4 | +-----------+------------+------+----+ | Cerna | Camila | Pass | | | Tejada | Mario | | | | Vividor | Liliana | Fail | | +-----------+------------+------+----+ >>> sel = 'a[title="04: Strings"]' >>> link = teacher.query.css(sel) >>> # XXX: fix this, use clicks instead of open >>> teacher.open(link.get_attribute('href')) >>> teacher.ui.gradebook.worksheet.pprint() +------------------------+---------------------------------------------+------------+---------------+ | 01: Python Environment | 02: Data Types, Statements, and Expressions | 03: Errors | *04: Strings* | +------------------------+---------------------------------------------+------------+---------------+ +-----------+------------+----+----+----+----+ | Last Name | First Name | 11 | 12 | 13 | 14 | | | | 4 | 4 | 4 | 4 | +-----------+------------+----+----+----+----+ | Cerna | Camila | | | | 4 | | Tejada | Mario | | | | | | Vividor | Liliana | | | | | +-----------+------------+----+----+----+----+ schooltool.cando-2.6.2/src/schooltool/cando/browser/stests/label_title_sorting.txt0000644000175000017500000006065012270520445031767 0ustar menesismenesis00000000000000Sorting components by label and title ===================================== We'll test the views that list nodes, skillsets and skills and verify that everything is sorted by label + title. Log in as manager: >>> manager = browsers.manager >>> manager.ui.login('manager', 'schooltool') Set up a schoolyear: >>> manager.ui.schoolyear.add('2012', '2012-01-01', '2012-12-31') Add a document with layers: >>> manager.query.link('School').click() >>> manager.query.link('Skills').click() >>> manager.query.link('Document').click() >>> manager.query.id('form-widgets-title').ui.set_value('Virginia CTE') >>> manager.query.id('add-button').click() >>> manager.query.name('row2').ui.set_value('Course') >>> manager.query.id('add-button').click() >>> manager.query.name('row3').ui.set_value('Cluster') >>> manager.query.id('form-buttons-add').click() Add some skill sets (removing the label for two of them): >>> manager.ui.skillset.add('Fractions', '01') >>> manager.ui.skillset.add('Percents', '02') >>> manager.ui.skillset.add('Pre-algebra', '04') >>> manager.ui.skillset.add('Geometry', '03') >>> manager.ui.skillset.add('Arithmetic of Decimals') >>> manager.query.link('Arithmetic of Decimals').click() >>> manager.query.css('a[title="Edit this skill set"]').click() >>> manager.query.id('form-widgets-label').clear() >>> manager.query.id('form-buttons-apply').click() >>> manager.ui.skillset.add('Nouns and Adjective', '01') >>> manager.ui.skillset.add('Function Words', '02') >>> manager.ui.skillset.add('Verb Tenses', '03') >>> manager.ui.skillset.add('Essential Verbs', '04') >>> manager.ui.skillset.add('Word Classes') >>> manager.query.link('Word Classes').click() >>> manager.query.css('a[title="Edit this skill set"]').click() >>> manager.query.id('form-widgets-label').clear() >>> manager.query.id('form-buttons-apply').click() >>> manager.query.link('Done').click() Print labels and titles of the skill sets: >>> sel = 'table.data tbody tr' >>> for row in manager.query_all.css(sel): ... label, title, skills = row.query_all.tag('td') ... print "%s, %s" % (label.text, title.query.tag('a').text) , Arithmetic of Decimals , Word Classes 01, Fractions 01, Nouns and Adjective 02, Function Words 02, Percents 03, Geometry 03, Verb Tenses 04, Essential Verbs 04, Pre-algebra Add skills to one skill set (removing the label in two of them): >>> manager.ui.skill.add('Fractions', 'Multiply two fractions.', '01') >>> manager.ui.skill.add('Fractions', ... 'Divide a fraction by a mixed number.', '02') >>> manager.ui.skill.add('Fractions', ... 'Divide a fraction by a whole number.', '03') >>> manager.ui.skill.add('Fractions', 'Read and write fractions.') >>> manager.ui.skill.add('Fractions', ... 'Convert mixed numbers to improper fractions.') >>> manager.query.link('Read and write fractions.').click() >>> manager.query.css('a[title="Edit this skill"]').click() >>> manager.query.id('form-widgets-label').clear() >>> manager.query.id('form-buttons-apply').click() >>> manager.query.link('Done').click() >>> manager.query.link('Convert mixed numbers to improper fractions.').click() >>> manager.query.css('a[title="Edit this skill"]').click() >>> manager.query.id('form-widgets-label').clear() >>> manager.query.id('form-buttons-apply').click() >>> manager.query.link('Done').click() Print labels and titles of the skills: >>> sel = 'table.data tbody tr' >>> for row in manager.query_all.css(sel): ... label, title = row.query_all.tag('td') ... print "%s, %s" % (label.text, title.query.tag('a').text) , Convert mixed numbers to improper fractions. , Read and write fractions. 01, Multiply two fractions. 02, Divide a fraction by a mixed number. 03, Divide a fraction by a whole number. We'll add more skills to the other Math skill sets and create a node to associate them, so later it can be assigned to a SchoolTool course: >>> manager.ui.skill.add('Percents', 'Write fractions as percents.', '01') >>> manager.ui.skill.add('Percents', ... 'Write decimal numbers as percents.', '03') >>> manager.ui.skill.add('Percents', ... 'Write percents as decimal numbers.', '02') >>> manager.ui.skill.add('Arithmetic of Decimals', ... 'Add two decimal numbers.', '01') >>> manager.ui.skill.add('Arithmetic of Decimals', ... 'Subtract two decimal numbers.', '02') >>> manager.ui.skill.add('Arithmetic of Decimals', ... 'Add a group of decimal numbers.', '03') >>> manager.ui.node.add('Math') >>> sel = '//h2[contains(@class, "ui-accordion-header")]' >>> accordion_headers = manager.query_all.xpath(sel) >>> sel = 'div.ui-accordion-content' >>> accordion_contents = manager.query_all.css(sel) >>> information_accordion_content = accordion_contents[0] >>> skillsets_accordion_header = accordion_headers[4] >>> skillsets_accordion_header.click() >>> skillsets_accordion_content = accordion_contents[4] >>> manager.wait_no(information_accordion_content.is_displayed) >>> sel = 'a[title="Edit skill sets"]' >>> manager.query.css(sel).click() >>> manager.query.name('add_item.Fraction1').click() >>> manager.query.name('add_item.Percents2').click() >>> manager.query.name('add_item.Arithmet5').click() Add some clusters: >>> manager.query.link('School').click() >>> manager.query.link('Skills').click() >>> manager.query.link('Virginia CTE').click() >>> manager.query.link('Cluster').click() >>> manager.query.id('form-widgets-title').ui.set_value('Human Services') >>> manager.query.id('form-widgets-label').ui.set_value('03') >>> manager.query.id('form-buttons-add').click() >>> manager.query.link('Cluster').click() >>> manager.query.id('form-widgets-title').ui.set_value('Marketing') >>> manager.query.id('form-widgets-label').ui.set_value('01') >>> manager.query.id('form-buttons-add').click() >>> manager.query.link('Cluster').click() >>> manager.query.id('form-widgets-title').ui.set_value('Information Technology') >>> manager.query.id('form-buttons-add').click() >>> manager.query.link('Information Technology').click() >>> manager.query.css('a[title="Edit this Document"]').click() >>> manager.query.id('form-widgets-label').clear() >>> manager.query.id('form-buttons-apply').click() >>> manager.query.link('Done').click() >>> manager.query.link('Cluster').click() >>> manager.query.id('form-widgets-title').ui.set_value('Finance') >>> manager.query.id('form-buttons-add').click() >>> manager.query.link('Finance').click() >>> manager.query.css('a[title="Edit this Document"]').click() >>> manager.query.id('form-widgets-label').clear() >>> manager.query.id('form-buttons-apply').click() >>> manager.query.link('Done').click() Print label and titles of the clusters: >>> sel = 'table.data tbody tr' >>> for row in manager.query_all.css(sel): ... label, title = row.query_all.tag('td') ... print "%s, %s" % (label.text, title.query.tag('a').text) , Finance , Information Technology 01, Marketing 03, Human Services Add some courses to the Finance cluster: >>> manager.query.link('Finance').click() >>> cluster_url = manager.url >>> manager.query.link('Course').click() >>> add_course_url = manager.url >>> manager.open(add_course_url) >>> manager.query.id('form-widgets-title').ui.set_value('Business Law') >>> manager.query.id('form-buttons-add').click() >>> manager.open(add_course_url) >>> manager.query.id('form-widgets-title').ui.set_value('Accounting') >>> manager.query.id('form-widgets-label').ui.set_value('01') >>> manager.query.id('form-buttons-add').click() >>> manager.open(add_course_url) >>> manager.query.id('form-widgets-title').ui.set_value('Accounting, Advanced') >>> manager.query.id('form-buttons-add').click() >>> manager.open(add_course_url) >>> manager.query.id('form-widgets-title').ui.set_value('Notetaking') >>> manager.query.id('form-widgets-label').ui.set_value('00') >>> manager.query.id('form-buttons-add').click() Print labels and titles of the courses of the cluster: >>> manager.open(cluster_url) >>> sel = 'table.data tbody tr' >>> for row in manager.query_all.css(sel): ... label, title = row.query_all.tag('td') ... print "%s, %s" % (label.text, title.query.tag('a').text) , Accounting, Advanced , Business Law 00, Notetaking 01, Accounting Add some skill sets to the Business Law course: >>> manager.query.link('Business Law').click() >>> course_url = manager.url >>> manager.query.link('Skill Set').click() >>> add_skillset_url = manager.url >>> manager.open(add_skillset_url) >>> manager.query.id('form-widgets-title').ui.set_value('Identifying Contracts') >>> manager.query.id('form-buttons-add').click() >>> manager.query.css('a[title="Edit this skill set"]').click() >>> manager.query.id('form-widgets-label').clear() >>> manager.query.id('form-buttons-apply').click() >>> manager.open(add_skillset_url) >>> manager.query.id('form-widgets-title').ui.set_value('Exploring Tort Law') >>> manager.query.id('form-widgets-label').ui.set_value('01') >>> manager.query.id('form-buttons-add').click() >>> manager.open(add_skillset_url) >>> manager.query.id('form-widgets-title').ui.set_value('Analyzing Types of Business Organizations') >>> manager.query.id('form-buttons-add').click() >>> manager.query.css('a[title="Edit this skill set"]').click() >>> manager.query.id('form-widgets-label').clear() >>> manager.query.id('form-buttons-apply').click() >>> manager.open(add_skillset_url) >>> manager.query.id('form-widgets-title').ui.set_value('Preparing for Business Law Careers') >>> manager.query.id('form-widgets-label').ui.set_value('00') >>> manager.query.id('form-buttons-add').click() Print labels and titles of the skill sets of the course: >>> manager.open(course_url) >>> sel = 'table.data tbody tr' >>> for row in manager.query_all.css(sel): ... label, title = row.query_all.tag('td') ... print "%s, %s" % (label.text, title.query.tag('a').text) , Analyzing Types of Business Organizations , Identifying Contracts 00, Preparing for Business Law Careers 01, Exploring Tort Law Add some skills to the Identifying Contracts skill set: >>> manager.query.link('Identifying Contracts').click() >>> skillset_url = manager.url >>> manager.query.link('Skill').click() >>> add_skill_url = manager.url >>> manager.open(add_skill_url) >>> manager.query.id('form-widgets-title').ui.set_value('Analyze the need for a contract') >>> manager.query.id('form-widgets-required-0').click() >>> manager.query.id('form-buttons-add').click() >>> manager.query.link('Analyze the need for a contract').click() >>> manager.query.css('a[title="Edit this skill"]').click() >>> manager.query.id('form-widgets-label').clear() >>> manager.query.id('form-buttons-apply').click() >>> manager.open(add_skill_url) >>> manager.query.id('form-widgets-title').ui.set_value('Compare types of contracts') >>> manager.query.id('form-widgets-required-1').click() >>> manager.query.id('form-widgets-label').ui.set_value('01') >>> manager.query.id('form-buttons-add').click() >>> manager.open(add_skill_url) >>> manager.query.id('form-widgets-title').ui.set_value('Explain elements of a contract') >>> manager.query.id('form-widgets-required-0').click() >>> manager.query.id('form-buttons-add').click() >>> manager.query.link('Explain elements of a contract').click() >>> manager.query.css('a[title="Edit this skill"]').click() >>> manager.query.id('form-widgets-label').clear() >>> manager.query.id('form-buttons-apply').click() >>> manager.open(add_skill_url) >>> manager.query.id('form-widgets-title').ui.set_value('Explain the Statute of Frauds') >>> manager.query.id('form-widgets-required-1').click() >>> manager.query.id('form-widgets-label').ui.set_value('00') >>> manager.query.id('form-buttons-add').click() Print labels and titles and requirement of the skills of the skill set: >>> manager.open(skillset_url) >>> sel = 'table.data tbody tr' >>> for row in manager.query_all.css(sel): ... label, title, required = row.query_all.tag('td') ... print "%s, %s, %s" % (label.text, title.query.tag('a').text, required.text) , Analyze the need for a contract, Yes , Explain elements of a contract, Yes 00, Explain the Statute of Frauds, No 01, Compare types of contracts, No Let's visit the Business Law course node: >>> manager.query.link('Search').click() >>> manager.query.name('SEARCH_BUTTON').click() >>> manager.query.link('Business Law').click() >>> print manager.query.css('.page .header h1').text Business Law >>> print manager.query.css('.page .header h2').text View Node Print the skill sets in the Skill Sets accordion: >>> sel = '//h2[contains(@class, "ui-accordion-header")]' >>> accordion_headers = manager.query_all.xpath(sel) >>> sel = 'div.ui-accordion-content' >>> accordion_contents = manager.query_all.css(sel) >>> information_accordion_content = accordion_contents[0] >>> skillsets_accordion_header = accordion_headers[4] >>> skillsets_accordion_header.click() >>> skillsets_accordion_content = accordion_contents[4] >>> manager.wait_no(information_accordion_content.is_displayed) >>> sel = '#skillsets table.data tbody tr' >>> for row in manager.query_all.css(sel): ... label, title = row.query_all.tag('td') ... print "%s, %s" % (label.text, title.query.tag('a').text) , Analyzing Types of Business Organizations , Identifying Contracts 00, Preparing for Business Law Careers 01, Exploring Tort Law Now, let's test the skills view for SchoolTool courses. We'll add a course: >>> manager.ui.course.add('2012', 'Business law') And assign the skill sets from the Business law course node: >>> manager.query.link('Skills').click() >>> manager.query.link('Assign Skills').click() >>> manager.query.id('business-law').click() Skill sets should be sorted by label: >>> dialog = manager.query.css('.ui-dialog') >>> sel = '#business-law-container table tbody h2' >>> for title in dialog.query_all.css(sel): ... print title.text Analyzing Types of Business Organizations Identifying Contracts 00: Preparing for Business Law Careers 01: Exploring Tort Law >>> manager.wait_page(dialog.query.name('SUBMIT_BUTTON').click) The assigned skills view should be sorted the same: >>> sel = '.courseskills-table tbody h2' >>> for title in manager.query_all.css(sel): ... print title.text Analyzing Types of Business Organizations Identifying Contracts 00: Preparing for Business Law Careers 01: Exploring Tort Law Same in the Remove skills view: >>> manager.query.link('Remove Skills').click() >>> sel = 'table tbody h2' >>> for title in manager.query_all.css(sel): ... print title.text Analyzing Types of Business Organizations Identifying Contracts 00: Preparing for Business Law Careers 01: Exploring Tort Law >>> manager.query.name('CANCEL').click() and the Set Required / Deprecated view: >>> manager.query.link('Set Required / Deprecated').click() >>> sel = 'table tbody th' >>> for title in manager.query_all.css(sel): ... print title.text Analyzing Types of Business Organizations Identifying Contracts 00: Preparing for Business Law Careers 01: Exploring Tort Law The skills in the Set Required / Deprecated view should be also sorted: >>> sel = 'table tbody tr' >>> for row in manager.query_all.css(sel): ... cells = row.query_all.tag('td') ... if cells: ... print '%s' % cells[0].text Analyze the need for a contract Explain elements of a contract 00: Explain the Statute of Frauds 01: Compare types of contracts Create a Math course and assign the Fractions skill set and check the order of the skills displayed: >>> manager.ui.course.add('2012', 'Math') >>> manager.query.link('Skills').click() >>> manager.query.link('Assign Skills').click() >>> manager.query.id('math').click() >>> dialog = manager.query.css('.ui-dialog') >>> sel = '//h2[contains(@class, "ui-accordion-header")]' >>> accordion_headers = manager.query_all.xpath(sel) >>> sel = 'div.ui-accordion-content' >>> accordion_contents = manager.query_all.css(sel) >>> math_accordion_content = accordion_contents[1] >>> math_accordion_header = accordion_headers[1] >>> math_accordion_header.click() >>> manager.wait(math_accordion_content.is_displayed) >>> for item in math_accordion_content.query_all.tag('li'): ... print item.text Convert mixed numbers to improper fractions. Read and write fractions. 01: Multiply two fractions. 02: Divide a fraction by a mixed number. 03: Divide a fraction by a whole number. >>> manager.wait_page(dialog.query.name('SUBMIT_BUTTON').click) >>> sel = '//h2[contains(@class, "ui-accordion-header")]' >>> accordion_headers = manager.query_all.xpath(sel) >>> sel = 'div.ui-accordion-content' >>> accordion_contents = manager.query_all.css(sel) >>> math_accordion_content = accordion_contents[1] >>> math_accordion_header = accordion_headers[1] >>> math_accordion_header.click() >>> manager.wait(math_accordion_content.is_displayed) >>> for item in math_accordion_content.query_all.tag('li'): ... print item.text Convert mixed numbers to improper fractions. Read and write fractions. 01: Multiply two fractions. 02: Divide a fraction by a mixed number. 03: Divide a fraction by a whole number. Now, let's test the teacher views. We'll add a section: >>> manager.ui.person.add('Jeffrey', 'Elkner', 'jeffrey', 'pwd') >>> manager.ui.person.add('Camila', 'Cerna', 'camila', 'pwd') >>> manager.ui.person.add('Liliana', 'Vividor', 'liliana', 'pwd') >>> manager.ui.person.add('Mario', 'Tejada', 'mario', 'pwd') >>> manager.ui.term.add('2012', '2012', '2012-01-01', '2012-12-31') >>> manager.ui.section.add('2012', '2012', 'Math') >>> manager.ui.section.instructors.add('2012', '2012', 'Math (1)', ... ['jeffrey']) >>> manager.ui.section.students.add('2012', '2012', 'Math (1)', ... ['camila', 'liliana', 'mario']) Log in as teacher and go to the CanDo gradebook: >>> teacher = browsers.teacher >>> teacher.ui.login('jeffrey', 'pwd') >>> teacher.query.link('CanDo').click() The skill sets dropdown should be sorted the same: >>> sel = 'a[title="Arithmetic of Decimals"]' >>> link = teacher.query.css(sel) >>> # XXX: fix this, use clicks instead of open >>> teacher.open(link.get_attribute('href')) >>> teacher.ui.gradebook.worksheet.pprint() +--------------------------+---------------+--------------+ | *Arithmetic of Decimals* | 01: Fractions | 02: Percents | +--------------------------+---------------+--------------+ +-----------+------------+----+----+----+ | Last Name | First Name | 01 | 02 | 03 | | | | 4 | 4 | 4 | +-----------+------------+----+----+----+ | Cerna | Camila | | | | | Tejada | Mario | | | | | Vividor | Liliana | | | | +-----------+------------+----+----+----+ Also the skill columns: >>> sel = 'a[title="01: Fractions"]' >>> link = teacher.query.css(sel) >>> # XXX: fix this, use clicks instead of open >>> teacher.open(link.get_attribute('href')) >>> teacher.ui.gradebook.worksheet.pprint() +------------------------+-----------------+--------------+ | Arithmetic of Decimals | *01: Fractions* | 02: Percents | +------------------------+-----------------+--------------+ +-----------+------------+-------+-------+----+----+----+ | Last Name | First Name | Conve | Reada | 01 | 02 | 03 | | | | 4 | 4 | 4 | 4 | 4 | +-----------+------------+-------+-------+----+----+----+ | Cerna | Camila | | | | | | | Tejada | Mario | | | | | | | Vividor | Liliana | | | | | | +-----------+------------+-------+-------+----+----+----+ Now, let's list skill sets and skills in the Skills popup dialog: >>> teacher.query.link('Skills Pop-up').click() >>> sel = '//h2[contains(@class, "ui-accordion-header")]' >>> accordion_headers = teacher.query_all.xpath(sel) >>> sel = 'div.ui-accordion-content' >>> accordion_contents = teacher.query_all.css(sel) >>> math_accordion_content = accordion_contents[1] >>> math_accordion_header = accordion_headers[1] >>> for item in math_accordion_content.query_all.tag('li'): ... print item.text Convert mixed numbers to improper fractions. Read and write fractions. 01: Multiply two fractions. 02: Divide a fraction by a mixed number. 03: Divide a fraction by a whole number. >>> teacher.query.css('.ui-dialog-titlebar-close').click() Let's test the Score student view for Camila: >>> sel = '#students-part tbody td:first-child ul.popup_menu' >>> camila_menu, mario_menu, liliana_menu = teacher.query_all.css(sel) >>> teacher.query.link('Cerna').click() >>> camila_menu.query.link('Score').click() >>> sel = '.grade-student tbody tr th' >>> for th in teacher.query_all.css(sel): ... print th.text Arithmetic of Decimals 01: Fractions 02: Percents >>> sel = '.grade-student tbody tr td:first-child' >>> for td in teacher.query_all.css(sel): ... print td.text 01: Add two decimal numbers. 02: Subtract two decimal numbers. 03: Add a group of decimal numbers. Convert mixed numbers to improper fractions. Read and write fractions. 01: Multiply two fractions. 02: Divide a fraction by a mixed number. 03: Divide a fraction by a whole number. 01: Write fractions as percents. 02: Write percents as decimal numbers. 03: Write decimal numbers as percents. >>> teacher.query.name('CANCEL').click() Now her Student Competency Report: >>> sel = '#students-part tbody td:first-child ul.popup_menu' >>> camila_menu, mario_menu, liliana_menu = teacher.query_all.css(sel) >>> teacher.query.link('Cerna').click() >>> camila_menu.query.link('Report').click() >>> sel = 'table tbody tr th' >>> for th in teacher.query_all.css(sel): ... print th.text Arithmetic of Decimals 01: Fractions 02: Percents >>> sel = 'table tbody tr' >>> for tr in teacher.query_all.css(sel): ... tds = tr.query_all.tag('td') ... if tds: ... print '%s, %s' % (tds[0].text, tds[2].text) 01, Add two decimal numbers. 02, Subtract two decimal numbers. 03, Add a group of decimal numbers. , Convert mixed numbers to improper fractions. , Read and write fractions. 01, Multiply two fractions. 02, Divide a fraction by a mixed number. 03, Divide a fraction by a whole number. 01, Write fractions as percents. 02, Write percents as decimal numbers. 03, Write decimal numbers as percents. Let's log in as Camila and check the sorting of her grades view: >>> camila = browsers.camila >>> camila.ui.login('camila', 'pwd') >>> camila.query.link('CanDo').click() >>> sel = '.third-nav li a' >>> for a in camila.query_all.css(sel): ... print a.get_attribute('title') Arithmetic of Decimals 01: Fractions 02: Percents >>> sel = 'a[title="01: Fractions"]' >>> link = camila.query.css(sel) >>> # XXX: fix this, use clicks instead of open >>> camila.open(link.get_attribute('href')) >>> sel = 'table tbody tr td:first-child' >>> for td in camila.query_all.css(sel): ... print td.text Convert mixed numbers to improper fractions. Read and write fractions. 01: Multiply two fractions. 02: Divide a fraction by a mixed number. 03: Divide a fraction by a whole number. schooltool.cando-2.6.2/src/schooltool/cando/browser/stests/gradebook_skill_labels.txt0000644000175000017500000001203012270520445032404 0ustar menesismenesis00000000000000Skills sorted by label in skills gradebook ========================================== Log in as manager: >>> manager = browsers.manager >>> manager.ui.login('manager', 'schooltool') Set up persons: >>> manager.ui.person.add('Jeffrey', 'Elkner', 'jeffrey', 'pwd') >>> manager.ui.person.add('Camila', 'Cerna', 'camila', 'pwd') >>> manager.ui.person.add('Liliana', 'Vividor', 'liliana', 'pwd') >>> manager.ui.person.add('Mario', 'Tejada', 'mario', 'pwd') Set up a multiple term section: >>> manager.ui.schoolyear.add('2012', '2012-01-01', '2012-12-31') >>> manager.ui.term.add('2012', '2012', '2012-01-01', '2012-12-31') >>> manager.ui.course.add('2012', 'Programming', course_id='PRO') >>> manager.ui.section.add('2012', '2012', 'Programming') >>> manager.ui.section.instructors.add('2012', '2012', 'Programming (1)', ... ['jeffrey']) >>> manager.ui.section.students.add('2012', '2012', 'Programming (1)', ... ['camila', 'liliana', 'mario']) Set up skills: >>> manager.ui.layer.add('Course') >>> manager.ui.node.add('Programming', label='PRO') >>> manager.ui.skillset.add('Data Types, Statements, and Expressions', '01') >>> manager.ui.skill.add( ... 'Data Types, Statements, and Expressions', ... 'Recognize int, float, str, list, tuple, and dict.', ... '06') >>> manager.ui.skill.add( ... 'Data Types, Statements, and Expressions', ... 'Use type(...) to determine the data type of a given value.', ... '03') >>> manager.ui.skill.add( ... 'Data Types, Statements, and Expressions', ... 'Use assignment statements to assign names (variables) to values.', ... '04') >>> manager.ui.skill.add( ... 'Data Types, Statements, and Expressions', ... 'Use the input function to read user input.', ... '05') >>> manager.ui.skill.add( ... 'Data Types, Statements, and Expressions', ... 'Define keyword and recognize keywords in Python.', ... '02') >>> manager.ui.skill.add( ... 'Data Types, Statements, and Expressions', ... 'Create legal variable names and recognize illegal ones.', ... '01', ... required=False) >>> manager.query.link('Search').click() >>> manager.query.button('Search').click() >>> manager.query.link('Programming').click() >>> sel = '//h2[contains(@class, "ui-accordion-header")]' >>> accordion_headers = manager.query_all.xpath(sel) >>> sel = 'div.ui-accordion-content' >>> accordion_contents = manager.query_all.css(sel) >>> information_accordion_content = accordion_contents[0] >>> skillsets_accordion_header = accordion_headers[4] >>> skillsets_accordion_header.click() >>> skillsets_accordion_content = accordion_contents[4] >>> manager.wait_no(information_accordion_content.is_displayed) >>> sel = '//a[@title="Edit skill sets"]' >>> manager.query.xpath(sel).click() >>> manager.query.id('form-buttons-add').click() >>> manager.query.link('Done').click() >>> sel = '//h2[contains(@class, "ui-accordion-header")]' >>> accordion_headers = manager.query_all.xpath(sel) >>> sel = 'div.ui-accordion-content' >>> accordion_contents = manager.query_all.css(sel) >>> information_accordion_content = accordion_contents[0] >>> layers_accordion_header = accordion_headers[3] >>> layers_accordion_header.click() >>> layers_accordion_content = accordion_contents[3] >>> manager.wait_no(information_accordion_content.is_displayed) >>> sel = '//a[@title="Edit layers"]' >>> manager.query.xpath(sel).click() >>> manager.query.id('form-buttons-add').click() Assign the skills to the course: >>> manager.query.link('School').click() >>> manager.query.link('Courses').click() >>> manager.query.link('Batch Assign Skills').click() >>> manager.query.name('course_attr').ui.set_value('Course ID') >>> manager.query.name('layer').ui.set_value('Course') >>> manager.query.name('node_attr').ui.set_value('Label') >>> manager.query.name('SEARCH_BUTTON').click() >>> manager.query.name('ASSIGN_BUTTON').click() Log in as instructor and print the skills gradebook: >>> teacher = browsers.teacher >>> teacher.ui.login('jeffrey', 'pwd') >>> teacher.query.link('CanDo').click() >>> teacher.ui.gradebook.worksheet.pprint() +-----------------------------------------------+ | *01: Data Types, Statements, and Expressions* | +-----------------------------------------------+ +-----------+------------+----+----+----+----+----+----+ | Last Name | First Name | 01 | 02 | 03 | 04 | 05 | 06 | | | | 4 | 4 | 4 | 4 | 4 | 4 | +-----------+------------+----+----+----+----+----+----+ | Cerna | Camila | | | | | | | | Tejada | Mario | | | | | | | | Vividor | Liliana | | | | | | | +-----------+------------+----+----+----+----+----+----+ schooltool.cando-2.6.2/src/schooltool/cando/browser/stests/gradebook_multiple_term.txt0000644000175000017500000002660712270520445032645 0ustar menesismenesis00000000000000Skills gradebook for multiple term sections =========================================== Log in as manager: >>> manager = browsers.manager >>> manager.ui.login('manager', 'schooltool') Set up persons: >>> manager.ui.person.add('Jeffrey', 'Elkner', 'jeffrey', 'pwd') >>> manager.ui.person.add('Camila', 'Cerna', 'camila', 'pwd') >>> manager.ui.person.add('Liliana', 'Vividor', 'liliana', 'pwd') >>> manager.ui.person.add('Mario', 'Tejada', 'mario', 'pwd') Set up a multiple term section: >>> manager.ui.schoolyear.add('2012', '2012-01-01', '2012-12-31') >>> manager.ui.term.add('2012', 'Q1', '2012-01-01', '2012-03-31') >>> manager.ui.term.add('2012', 'Q2', '2012-04-01', '2012-06-30') >>> manager.ui.term.add('2012', 'Q3', '2012-07-01', '2012-09-30') >>> manager.ui.term.add('2012', 'Q4', '2012-10-01', '2012-12-31') >>> manager.ui.course.add('2012', 'Programming', course_id='PRO') >>> manager.ui.section.add('2012', 'Q1', 'Programming', ends='Q4') >>> manager.ui.section.instructors.add('2012', 'Q1', 'Programming (1)', ... ['jeffrey']) >>> manager.ui.section.students.add('2012', 'Q1', 'Programming (1)', ... ['camila', 'liliana', 'mario']) Set up skills: >>> manager.ui.layer.add('Course') >>> manager.ui.node.add('Programming', label='PRO') >>> manager.ui.skillset.add('Python Environment', '01') >>> manager.ui.skill.add( ... 'Python Environment', ... 'Use the Python shell for interactive evaluation', ... '01') >>> manager.ui.skill.add( ... 'Python Environment', ... 'Make Python scripts with a text editor', ... '02', ... required=False) >>> manager.query.link('Search').click() >>> manager.query.button('Search').click() >>> manager.query.link('Programming').click() >>> sel = '//h2[contains(@class, "ui-accordion-header")]' >>> accordion_headers = manager.query_all.xpath(sel) >>> sel = 'div.ui-accordion-content' >>> accordion_contents = manager.query_all.css(sel) >>> information_accordion_content = accordion_contents[0] >>> skillsets_accordion_header = accordion_headers[4] >>> skillsets_accordion_header.click() >>> skillsets_accordion_content = accordion_contents[4] >>> manager.wait_no(information_accordion_content.is_displayed) >>> sel = '//a[@title="Edit skill sets"]' >>> manager.query.xpath(sel).click() >>> manager.query.id('form-buttons-add').click() >>> manager.query.link('Done').click() >>> sel = '//h2[contains(@class, "ui-accordion-header")]' >>> accordion_headers = manager.query_all.xpath(sel) >>> sel = 'div.ui-accordion-content' >>> accordion_contents = manager.query_all.css(sel) >>> information_accordion_content = accordion_contents[0] >>> layers_accordion_header = accordion_headers[3] >>> layers_accordion_header.click() >>> layers_accordion_content = accordion_contents[3] >>> manager.wait_no(information_accordion_content.is_displayed) >>> sel = '//a[@title="Edit layers"]' >>> manager.query.xpath(sel).click() >>> manager.query.id('form-buttons-add').click() Assign the skills to the course: >>> manager.query.link('School').click() >>> manager.query.link('Courses').click() >>> manager.query.link('Batch Assign Skills').click() >>> manager.query.name('course_attr').ui.set_value('Course ID') >>> manager.query.name('layer').ui.set_value('Course') >>> manager.query.name('node_attr').ui.set_value('Label') >>> manager.query.name('SEARCH_BUTTON').click() >>> manager.query.name('ASSIGN_BUTTON').click() Log in as instructor and grade some skills in the first term section: >>> teacher = browsers.teacher >>> teacher.ui.login('jeffrey', 'pwd') >>> teacher.query.link('CanDo').click() >>> teacher.ui.gradebook.worksheet.score('Cerna, Camila', '01', '3') >>> teacher.ui.gradebook.worksheet.score('Tejada, Mario', '01', '4') >>> teacher.ui.gradebook.worksheet.score('Cerna, Camila', '02', '3') >>> teacher.ui.gradebook.worksheet.score('Tejada, Mario', '02', '3') >>> teacher.query.name('UPDATE_SUBMIT').click() >>> teacher.ui.gradebook.worksheet.pprint() +--------------------------+ | *01: Python Environment* | +--------------------------+ +-----------+------------+----+----+ | Last Name | First Name | 01 | 02 | | | | 4 | 4 | +-----------+------------+----+----+ | Cerna | Camila | 3 | 3 | | Tejada | Mario | 4 | 3 | | Vividor | Liliana | | | +-----------+------------+----+----+ Now, let's go to the following terms section and see the most recent grades: >>> navigator = teacher.query_all.css('.refine .navigator')[1] >>> page = teacher.query.tag('html') >>> navigator.ui.set_value('Q2') >>> teacher.wait(lambda: page.expired) >>> teacher.ui.gradebook.worksheet.pprint() +--------------------------+ | *01: Python Environment* | +--------------------------+ +-----------+------------+----+----+ | Last Name | First Name | 01 | 02 | | | | 4 | 4 | +-----------+------------+----+----+ | Cerna | Camila | 3 | 3 | | Tejada | Mario | 4 | 3 | | Vividor | Liliana | | | +-----------+------------+----+----+ >>> navigator = teacher.query_all.css('.refine .navigator')[1] >>> page = teacher.query.tag('html') >>> navigator.ui.set_value('Q4') >>> teacher.wait(lambda: page.expired) >>> teacher.ui.gradebook.worksheet.pprint() +--------------------------+ | *01: Python Environment* | +--------------------------+ +-----------+------------+----+----+ | Last Name | First Name | 01 | 02 | | | | 4 | 4 | +-----------+------------+----+----+ | Cerna | Camila | 3 | 3 | | Tejada | Mario | 4 | 3 | | Vividor | Liliana | | | +-----------+------------+----+----+ Let's go to the Q3 term and grade some skills there: >>> navigator = teacher.query_all.css('.refine .navigator')[1] >>> page = teacher.query.tag('html') >>> navigator.ui.set_value('Q3') >>> teacher.wait(lambda: page.expired) >>> teacher.ui.gradebook.worksheet.score('Cerna, Camila', '01', '2') >>> teacher.ui.gradebook.worksheet.score('Vividor, Liliana', '01', '1') >>> teacher.ui.gradebook.worksheet.score('Tejada, Mario', '02', '') >>> teacher.query.name('UPDATE_SUBMIT').click() >>> teacher.ui.gradebook.worksheet.pprint() +--------------------------+ | *01: Python Environment* | +--------------------------+ +-----------+------------+----+----+ | Last Name | First Name | 01 | 02 | | | | 4 | 4 | +-----------+------------+----+----+ | Cerna | Camila | 2 | 3 | | Tejada | Mario | 4 | | | Vividor | Liliana | 1 | | +-----------+------------+----+----+ If we go back to the Q4 section, we'll see some grades from the Q1 section and some from the Q3 section: >>> navigator = teacher.query_all.css('.refine .navigator')[1] >>> page = teacher.query.tag('html') >>> navigator.ui.set_value('Q4') >>> teacher.wait(lambda: page.expired) >>> teacher.ui.gradebook.worksheet.pprint() +--------------------------+ | *01: Python Environment* | +--------------------------+ +-----------+------------+----+----+ | Last Name | First Name | 01 | 02 | | | | 4 | 4 | +-----------+------------+----+----+ | Cerna | Camila | 2 | 3 | | Tejada | Mario | 4 | | | Vividor | Liliana | 1 | | +-----------+------------+----+----+ Let's add a new student and enroll him in the middle of the year: >>> manager.ui.person.add('Nestor', 'Guzman', 'nestor', 'pwd') >>> manager.ui.section.students.add('2012', 'Q3', 'Programming (1)', ... ['nestor']) Let's visit all the terms to see how the new student is handled. We'll add a score for him in Q3 and check it in Q4: >>> navigator = teacher.query_all.css('.refine .navigator')[1] >>> page = teacher.query.tag('html') >>> navigator.ui.set_value('Q1') >>> teacher.wait(lambda: page.expired) >>> teacher.ui.gradebook.worksheet.pprint() +--------------------------+ | *01: Python Environment* | +--------------------------+ +-----------+------------+----+----+ | Last Name | First Name | 01 | 02 | | | | 4 | 4 | +-----------+------------+----+----+ | Cerna | Camila | 3 | 3 | | Tejada | Mario | 4 | 3 | | Vividor | Liliana | | | +-----------+------------+----+----+ >>> navigator = teacher.query_all.css('.refine .navigator')[1] >>> page = teacher.query.tag('html') >>> navigator.ui.set_value('Q2') >>> teacher.wait(lambda: page.expired) >>> teacher.ui.gradebook.worksheet.pprint() +--------------------------+ | *01: Python Environment* | +--------------------------+ +-----------+------------+----+----+ | Last Name | First Name | 01 | 02 | | | | 4 | 4 | +-----------+------------+----+----+ | Cerna | Camila | 3 | 3 | | Tejada | Mario | 4 | 3 | | Vividor | Liliana | | | +-----------+------------+----+----+ >>> navigator = teacher.query_all.css('.refine .navigator')[1] >>> page = teacher.query.tag('html') >>> navigator.ui.set_value('Q3') >>> teacher.wait(lambda: page.expired) >>> teacher.ui.gradebook.worksheet.pprint() +--------------------------+ | *01: Python Environment* | +--------------------------+ +-----------+------------+----+----+ | Last Name | First Name | 01 | 02 | | | | 4 | 4 | +-----------+------------+----+----+ | Cerna | Camila | 2 | 3 | | Guzman | Nestor | | | | Tejada | Mario | 4 | | | Vividor | Liliana | 1 | | +-----------+------------+----+----+ >>> teacher.ui.gradebook.worksheet.score('Guzman, Nestor', '02', '0') >>> teacher.query.name('UPDATE_SUBMIT').click() >>> teacher.ui.gradebook.worksheet.pprint() +--------------------------+ | *01: Python Environment* | +--------------------------+ +-----------+------------+----+----+ | Last Name | First Name | 01 | 02 | | | | 4 | 4 | +-----------+------------+----+----+ | Cerna | Camila | 2 | 3 | | Guzman | Nestor | | 0 | | Tejada | Mario | 4 | | | Vividor | Liliana | 1 | | +-----------+------------+----+----+ >>> navigator = teacher.query_all.css('.refine .navigator')[1] >>> page = teacher.query.tag('html') >>> navigator.ui.set_value('Q4') >>> teacher.wait(lambda: page.expired) >>> teacher.ui.gradebook.worksheet.pprint() +--------------------------+ | *01: Python Environment* | +--------------------------+ +-----------+------------+----+----+ | Last Name | First Name | 01 | 02 | | | | 4 | 4 | +-----------+------------+----+----+ | Cerna | Camila | 2 | 3 | | Guzman | Nestor | | 0 | | Tejada | Mario | 4 | | | Vividor | Liliana | 1 | | +-----------+------------+----+----+ schooltool.cando-2.6.2/src/schooltool/cando/browser/stests/cando_tab.txt0000644000175000017500000001040512270520445027645 0ustar menesismenesis00000000000000CanDo tab ========= We'll test that the CanDo tab redirect teachers only to sections they teach. Helper: >>> def print_section_navigator(browser): ... sel = 'select[name="currentSection"] option' ... for option in browser.query_all.css(sel): ... print ['%s', '*%s*'][option.is_selected()] % option.text Log in as manager: >>> manager = browsers.manager >>> manager.ui.login('manager', 'schooltool') Set up persons: >>> manager.ui.person.add('Tom', 'Hoffman', 'tom', 'pwd') >>> manager.ui.person.add('Jeffrey', 'Elkner', 'jeffrey', 'pwd') >>> manager.ui.person.add('Camila', 'Cerna', 'camila', 'pwd') >>> manager.ui.person.add('Mario', 'Tejada', 'mario', 'pwd') >>> manager.ui.person.add('Nestor', 'Guzman', 'nestor', 'pwd') >>> manager.ui.person.add('Liliana', 'Vividor', 'liliana', 'pwd') >>> manager.ui.person.add('German', 'Tejada', 'german', 'pwd') Set up some courses with a section each: >>> manager.ui.schoolyear.add('2013', '2013-01-01', '2013-12-31') >>> manager.ui.term.add('2013', 'Year', '2013-01-01', '2013-12-31') >>> manager.ui.course.add('2013', 'Math') >>> manager.ui.course.add('2013', 'Physics') >>> manager.ui.course.add('2013', 'Algebra') >>> manager.ui.course.add('2013', 'Baseball') >>> manager.ui.course.add('2013', 'Soccer') >>> manager.ui.course.add('2013', 'Swimming') >>> manager.ui.section.add('2013', 'Year', 'Algebra') >>> manager.ui.section.add('2013', 'Year', 'Math') >>> manager.ui.section.add('2013', 'Year', 'Physics') >>> manager.ui.section.add('2013', 'Year', 'Baseball') >>> manager.ui.section.add('2013', 'Year', 'Soccer') >>> manager.ui.section.add('2013', 'Year', 'Swimming') >>> for section in ['Algebra (1)', 'Math (2)', 'Physics (3)']: ... manager.ui.section.instructors.add('2013', 'Year', section, ... ['jeffrey']) ... manager.ui.section.students.add('2013', 'Year', section, ... ['camila', 'mario', 'nestor']) >>> for section in ['Baseball (4)', 'Soccer (5)', 'Swimming (6)']: ... manager.ui.section.instructors.add('2013', 'Year', section, ... ['tom']) ... manager.ui.section.students.add('2013', 'Year', section, ... ['liliana', 'german']) Log in as teacher: >>> teacher = browsers.teacher >>> teacher.ui.login('jeffrey', 'pwd') Click the CanDo tab: >>> teacher.query.link('CanDo').click() List the sections navigator: >>> print_section_navigator(teacher) *Algebra (1)* Math (2) Physics (3) Switch to the Math (2) section and list the sections navigator again: >>> navigator = teacher.query_all.css('.refine .navigator')[0] >>> page = teacher.query.tag('html') >>> navigator.ui.set_value('Math (2)') >>> teacher.wait(lambda: page.expired) >>> print_section_navigator(teacher) Algebra (1) *Math (2)* Physics (3) Go to Home page and back to the CanDo tab. Current section should be Math (2): >>> teacher.query.link('Home').click() >>> teacher.query.link('CanDo').click() >>> print_section_navigator(teacher) Algebra (1) *Math (2)* Physics (3) Add teacher to the School Administrators group: >>> manager.ui.group.members.add('2013', 'School Administrators', ... ['jeffrey']) This gives the teacher ability to see other teachers' gradebooks: >>> teacher.ui.section.go('2013', 'Year', 'Baseball (4)') >>> sel = '//div[contains(@class, "sidebar")]//a[text()="CanDo Gradebook"]' >>> teacher.query.xpath(sel).click() >>> teacher.ui.gradebook.worksheet.pprint() +------------+ | *Project1* | +------------+ +-----------+------------+ | Last Name | First Name | | | | +-----------+------------+ | Tejada | German | | Vividor | Liliana | +-----------+------------+ Go to Home page and back to the CanDo tab. Again, the current section should be Math (2), not Baseball (4): >>> teacher.query.link('Home').click() >>> teacher.query.link('CanDo').click() >>> print_section_navigator(teacher) Algebra (1) *Math (2)* Physics (3) schooltool.cando-2.6.2/src/schooltool/cando/browser/stests/course_skills.txt0000644000175000017500000000422512270520445030617 0ustar menesismenesis00000000000000Tests for the course skills xls imports ======================================= Log in as manager: >>> manager = browsers.manager >>> manager.ui.login('manager', 'schooltool') We have two import files that we will test here, course_nodes.xls and course_skills.xls. Both files will have both the year and course sheets as well as the skills sheets, so we will send each file through both the core importer as well as the cando skills importer. Let's start with the course_nodes.xls file. >>> import os >>> dirname = os.path.abspath(os.path.dirname(__file__)) >>> filename = os.path.join(dirname, 'course_nodes.xls') >>> manager.query.link('School').click() >>> manager.query.link('Import XLS').click() >>> manager.query.name('xlsfile').type(filename) >>> page = manager.query.tag('html') >>> manager.query.button('Submit').click() >>> manager.wait(lambda: page.expired) >>> manager.ui.skill.import_xls(filename) Let's check the data. Our course will have the two skillsets assigned to it that were indicated in the 'building' node. >>> manager.query.link('School').click() >>> manager.query.link('Courses').click() >>> manager.query.link('Art').click() >>> manager.query.link('Skills').click() >>> print manager.query_all.css('.courseskills-table td h2').text Carpentry Electrical Now we'll import the course_skills.xls worksheet that only links the carpentry skillset to the course. >>> filename = os.path.join(dirname, 'course_skills.xls') >>> manager.query.link('School').click() >>> manager.query.link('Import XLS').click() >>> manager.query.name('xlsfile').type(filename) >>> page = manager.query.tag('html') >>> manager.query.button('Submit').click() >>> manager.wait(lambda: page.expired) >>> manager.ui.skill.import_xls(filename) Now when we check the data, the course only has the carpentry skillset. >>> manager.query.link('School').click() >>> manager.query.link('Courses').click() >>> manager.query.link('Art').click() >>> manager.query.link('Skills').click() >>> print manager.query_all.css('.courseskills-table td h2').text Carpentry schooltool.cando-2.6.2/src/schooltool/cando/browser/stests/__init__.py0000644000175000017500000000002112270520445027274 0ustar menesismenesis00000000000000# Make a package schooltool.cando-2.6.2/src/schooltool/cando/browser/stests/label_constraints.txt0000644000175000017500000001517412270520445031451 0ustar menesismenesis00000000000000Label constraints ================= Nodes, skills and skill sets in CanDo have labels. We're going to test some form constraints on these: * All labels should be limited to 7 characters or less * Labels are optional: - If they're not set by the user, instead of using None, they should be set to u'', except for skills where they should be set to a 2 digits number which depends on the quantity of existing skills in the skill set. Helpers: >>> def print_label_widget(browser): ... div = browser.query.id('form-widgets-label-row') ... label = div.query.css('label[for="form-widgets-label"] span').text ... hint = div.query.css('p.hint').text ... maxlength = div.query.id('form-widgets-label').get_attribute( ... 'maxlength') ... print 'Label: %s' % label ... print 'Hint: %s' % hint ... print 'Maximum Length: %s' % maxlength >>> def print_form_fields(browser): ... for row in browser.query_all.css('table.form-fields tbody tr'): ... label = row.query.css('td.label').text ... field = row.query.css('td.field').text ... print '%s: %s' % (label, field) Log in as manager: >>> manager = browsers.manager >>> manager.ui.login('manager', 'schooltool') Print the label widget for adding skill sets: >>> manager.query.link('School').click() >>> manager.query.link('Skills').click() >>> manager.query.link('Skill Sets').click() >>> manager.query.link('Skill Set').click() >>> print_label_widget(manager) Label: Label Hint: Limit to 7 characters or less. Maximum Length: 7 Add the skill set with no label: >>> manager.query.id('form-widgets-title').ui.set_value('My Skill Set') >>> manager.query.id('form-buttons-add').click() View the skill set: >>> manager.query.link('My Skill Set').click() >>> print_form_fields(manager) Description: Label: Deprecated: No Edit the skill set and print the label widget: >>> sel = 'a[title="Edit this skill set"]' >>> manager.query.css(sel).click() >>> print_label_widget(manager) Label: Label Hint: Limit to 7 characters or less. Maximum Length: 7 If we try to set the label with 10 characters, it will store only 7: >>> manager.query.id('form-widgets-label').ui.set_value('1234567890') >>> manager.query.id('form-buttons-apply').click() >>> print_form_fields(manager) Description: Label: 1234567 Deprecated: No Add another skill set with a long label: >>> manager.query.link('Skill Sets').click() >>> manager.query.link('Skill Set').click() >>> manager.query.id('form-widgets-title').ui.set_value( ... 'My Second Skill Set') >>> manager.query.id('form-widgets-label').ui.set_value('ABCDEFGHIJKLM') >>> manager.query.id('form-buttons-add').click() >>> manager.query.link('My Second Skill Set').click() >>> print_form_fields(manager) Description: Label: ABCDEFG Deprecated: No This checking proccess should be the same for Nodes. Let's print the label widget for adding nodes: >>> manager.query.link('School').click() >>> manager.query.link('Skills').click() >>> manager.query.link('Search').click() >>> manager.query.link('Node').click() >>> print_label_widget(manager) Label: Label Hint: Limit to 7 characters or less. Maximum Length: 7 Add the node with no label: >>> manager.query.id('form-widgets-title').ui.set_value('My Node') >>> manager.query.id('form-buttons-add').click() View the node: >>> print_form_fields(manager) Description: Label: Edit the node and print the label widget: >>> sel = 'a[title="Edit this Node"]' >>> manager.query.css(sel).click() >>> print_label_widget(manager) Label: Label Hint: Limit to 7 characters or less. Maximum Length: 7 If we try to set the label with 10 characters, it will store only 7: >>> manager.query.id('form-widgets-label').ui.set_value('1234567890') >>> manager.query.id('form-buttons-apply').click() >>> print_form_fields(manager) Description: Label: 1234567 Add another node with a long label: >>> manager.query.link('Search').click() >>> manager.query.link('Node').click() >>> manager.query.id('form-widgets-title').ui.set_value('My Second Node') >>> manager.query.id('form-widgets-label').ui.set_value('ABCDEFGHIJKLM') >>> manager.query.id('form-buttons-add').click() >>> print_form_fields(manager) Description: Label: ABCDEFG Finally, let's test labels for skills. Let's print the label widget for adding skills: >>> manager.query.link('School').click() >>> manager.query.link('Skills').click() >>> manager.query.link('Skill Sets').click() >>> manager.query.link('My Second Skill Set').click() >>> manager.query.link('Skill').click() >>> print_label_widget(manager) Label: Label Hint: Limit to 7 characters or less. Maximum Length: 7 Add the skill with no label: >>> manager.query.id('form-widgets-title').ui.set_value('My First Skill') >>> manager.query.id('form-widgets-required-0').click() >>> manager.query.id('form-buttons-add').click() View the skill. Note how the label is set differently: >>> manager.query.link('My First Skill').click() >>> print_form_fields(manager) Scoresystem: Competency Description: Label: 01 Required?: Required Deprecated: No External ID: Edit the skill and print the label widget: >>> sel = 'a[title="Edit this skill"]' >>> manager.query.css(sel).click() >>> print_label_widget(manager) Label: Label Hint: Limit to 7 characters or less. Maximum Length: 7 If we try to set the label with 10 characters, it will store only 7: >>> manager.query.id('form-widgets-label').clear() >>> manager.query.id('form-widgets-label').ui.set_value('1234567890') >>> manager.query.id('form-buttons-apply').click() >>> print_form_fields(manager) Scoresystem: Competency Description: Label: 1234567 Required?: Required Deprecated: No External ID: Add another skill with a long label: >>> manager.query.link('Done').click() >>> manager.query.link('Skill').click() >>> manager.query.id('form-widgets-title').ui.set_value('My Second Skill') >>> manager.query.id('form-widgets-label').ui.set_value('ABCDEFGHIJKLM') >>> manager.query.id('form-widgets-required-0').click() >>> manager.query.id('form-buttons-add').click() >>> manager.query.link('My Second Skill').click() >>> print_form_fields(manager) Scoresystem: Competency Description: Label: ABCDEFG Required?: Required Deprecated: No External ID: schooltool.cando-2.6.2/src/schooltool/cando/browser/stests/per_student_skills_report.txt0000644000175000017500000007510312270520445033251 0ustar menesismenesis00000000000000Per Student Skills Report ========================= Helpers: >>> from pprint import pprint >>> def gradeStudent(browser, student, scores): ... for skillset, grades in scores.items(): ... active = browser.query.css('.third-nav li.active a') ... if active.text != skillset: ... browser.query.css('#navbar-list-worksheets').click() ... sel = 'a[title="%s"]' % skillset ... link = browser.query.css(sel) ... # XXX: fix this, use clicks instead of open ... browser.open(link.get_attribute('href')) ... for label, grade in grades: ... browser.ui.gradebook.worksheet.score(student, label, grade) ... browser.query.name('UPDATE_SUBMIT').click() >>> def print_charts_info(browser): ... for chart in browser.query_all.css('.chart-container'): ... rects = [] ... for rect in chart.query_all.css('svg > g > rect'): ... info = { ... 'fill': rect.get_attribute('fill'), ... 'title': rect.query.tag('title').text, ... 'width': rect.get_attribute('width'), ... 'x': rect.get_attribute('x'), ... } ... rects.append(info) ... pprint({ ... 'id': chart.get_attribute('id'), ... 'rects': rects, ... }) >>> def print_score_colors(browser): ... result = [] ... sel = '.score-colors-table .score-color-cell' ... for cell in browser.query_all.css(sel)[:-1]: ... title = cell.query.css('span.title') ... color = cell.query.css('span.color') ... print '%s: %s' % (title.text, color.get_attribute('style')) Log in as manager: >>> manager = browsers.manager >>> manager.ui.login('manager', 'schooltool') Set up persons: >>> manager.ui.person.add('Jeffrey', 'Elkner', 'jeffrey', 'pwd') >>> manager.ui.person.add('Camila', 'Cerna', 'camila(c)', 'pwd') >>> manager.ui.person.add('Liliana', 'Vividor', 'liliana', 'pwd') >>> manager.ui.person.add('Mario', 'Tejada', 'mario', 'pwd') Set up a section: >>> manager.ui.schoolyear.add('2012', '2012-01-01', '2012-12-31') >>> manager.ui.term.add('2012', '2012', '2012-01-01', '2012-12-31') >>> manager.ui.course.add('2012', 'Programming', course_id='PRO') >>> manager.ui.section.add('2012', '2012', 'Programming') >>> manager.ui.section.instructors.add('2012', '2012', 'Programming (1)', ... ['jeffrey']) >>> manager.ui.section.students.add('2012', '2012', 'Programming (1)', ... ['camila', 'liliana', 'mario']) Set up skills: >>> manager.ui.layer.add('Course') >>> manager.ui.node.add('Programming', label='PRO') >>> manager.ui.skillset.add('Python Environment', '01') >>> manager.ui.skillset.add('Data Types, Statements, and Expressions', '02') >>> manager.ui.skillset.add('Errors', '03') >>> manager.ui.skillset.add('Strings', '04') >>> manager.ui.skill.add( ... 'Python Environment', ... 'Use the Python shell for interactive evaluation', ... '01') >>> manager.ui.skill.add( ... 'Python Environment', ... 'Make Python scripts with a text editor', ... '02', ... required=False) >>> manager.ui.skill.add( ... 'Data Types, Statements, and Expressions', ... 'Recognize int, float, str, list, tuple, and dict.', ... '03') >>> manager.ui.skill.add( ... 'Data Types, Statements, and Expressions', ... 'Use type(...) to determine the data type of a given value.', ... '04') >>> manager.ui.skill.add( ... 'Data Types, Statements, and Expressions', ... 'Use assignment statements to assign names (variables) to values.', ... '05') >>> manager.ui.skill.add( ... 'Data Types, Statements, and Expressions', ... 'Use the input function to read user input.', ... '06') >>> manager.ui.skill.add( ... 'Data Types, Statements, and Expressions', ... 'Define keyword and recognize keywords in Python.', ... '07') >>> manager.ui.skill.add( ... 'Data Types, Statements, and Expressions', ... 'Create legal variable names and recognize illegal ones.', ... '08', ... required=False) >>> manager.ui.skill.add( ... 'Errors', ... 'Recognize and differentiate among errors.', ... '09') >>> manager.ui.skill.add( ... 'Errors', ... 'Read and interpret stack traceback messages.', ... '10') >>> manager.ui.skill.add( ... 'Strings', ... 'Create string literals with single, double, and triple quotes.', ... '11') >>> manager.ui.skill.add( ... 'Strings', ... 'Use the len() function to return the length of a string.', ... '12') >>> manager.ui.skill.add( ... 'Strings', ... 'Use the find(...) method to locate substrings in a string.', ... '13', ... required=False) >>> manager.ui.skill.add( ... 'Strings', ... 'Use the split() method to break a string into a list.', ... '14', ... required=False) >>> manager.query.link('Search').click() >>> manager.query.button('Search').click() >>> manager.query.link('Programming').click() >>> sel = '//h2[contains(@class, "ui-accordion-header")]' >>> accordion_headers = manager.query_all.xpath(sel) >>> sel = 'div.ui-accordion-content' >>> accordion_contents = manager.query_all.css(sel) >>> information_accordion_content = accordion_contents[0] >>> skillsets_accordion_header = accordion_headers[4] >>> skillsets_accordion_header.click() >>> skillsets_accordion_content = accordion_contents[4] >>> manager.wait_no(information_accordion_content.is_displayed) >>> sel = '//a[@title="Edit skill sets"]' >>> manager.query.xpath(sel).click() >>> manager.query.id('form-buttons-add').click() >>> manager.query.link('Done').click() >>> sel = '//h2[contains(@class, "ui-accordion-header")]' >>> accordion_headers = manager.query_all.xpath(sel) >>> sel = 'div.ui-accordion-content' >>> accordion_contents = manager.query_all.css(sel) >>> information_accordion_content = accordion_contents[0] >>> layers_accordion_header = accordion_headers[3] >>> layers_accordion_header.click() >>> layers_accordion_content = accordion_contents[3] >>> manager.wait_no(information_accordion_content.is_displayed) >>> sel = '//a[@title="Edit layers"]' >>> manager.query.xpath(sel).click() >>> manager.query.id('form-buttons-add').click() Assign the skills to the course: >>> manager.query.link('School').click() >>> manager.query.link('Courses').click() >>> manager.query.link('Batch Assign Skills').click() >>> manager.query.name('course_attr').ui.set_value('Course ID') >>> manager.query.name('layer').ui.set_value('Course') >>> manager.query.name('node_attr').ui.set_value('Label') >>> manager.query.name('SEARCH_BUTTON').click() >>> manager.query.name('ASSIGN_BUTTON').click() Log in as instructor: >>> teacher = browsers.teacher >>> teacher.ui.login('jeffrey', 'pwd') >>> teacher.query.link('CanDo').click() Add scores for the students: >>> camila_scores = { ... '01: Python Environment': [ ... ('01', '4'), ... ('02', '3'), ... ], ... '02: Data Types, Statements, and Expressions': [ ... ('03', '2'), ... ('04', '0'), ... ('05', '3'), ... ('06', '3'), ... ('07', '3'), ... ('08', '1'), ... ], ... '03: Errors': [ ... ('09', '4'), ... ('10', '3'), ... ], ... '04: Strings': [ ... ('11', '4'), ... ('12', '3'), ... ('13', '3'), ... ('14', '3'), ... ], ... } >>> gradeStudent(teacher, 'Camila Cerna', camila_scores) >>> mario_scores = { ... '01: Python Environment': [ ... ('01', '3'), ... ('02', '4'), ... ], ... '02: Data Types, Statements, and Expressions': [ ... ('03', '1'), ... ('04', '0'), ... ('05', '0'), ... ('06', '2'), ... ('07', '2'), ... ('08', '1'), ... ], ... '03: Errors': [ ... ('09', ''), ... ('10', '3'), ... ], ... '04: Strings': [ ... ('11', '3'), ... ('12', '2'), ... ('13', '1'), ... ('14', ''), ... ], ... } >>> gradeStudent(teacher, 'Tejada, Mario', mario_scores) >>> liliana_scores = { ... '01: Python Environment': [ ... ('01', '1'), ... ('02', ''), ... ], ... '02: Data Types, Statements, and Expressions': [ ... ('03', '2'), ... ('04', '0'), ... ('05', '2'), ... ('06', '4'), ... ('07', '0'), ... ('08', '0'), ... ], ... '03: Errors': [ ... ('09', '4'), ... ('10', '4'), ... ], ... '04: Strings': [ ... ('11', '2'), ... ('12', '2'), ... ('13', ''), ... ('14', ''), ... ], ... } >>> gradeStudent(teacher, 'Liliana Vividor', liliana_scores) Print the Per Student Skills report details: >>> teacher.query.link('Per Student Skills').click() >>> print teacher.query.css('.page .header h1').text Per Student Skills >>> print teacher.query.css('.page .header h2').text Programming (1) Print the students individual charts information: >>> print_charts_info(teacher) {'id': u'skills-data-camila:40c:41-', 'rects': [{'fill': u'#f68e4d', 'title': u'Uninformed: 7.1%', 'width': u'21.42857142857143', 'x': u'78.57142857142857'}, {'fill': u'#f9b289', 'title': u'Beginning: 7.1%', 'width': u'14.285714285714292', 'x': u'85.71428571428571'}, {'fill': u'#fcd6c5', 'title': u'Practicing: 7.1%', 'width': u'7.142857142857153', 'x': u'92.85714285714285'}, {'fill': u'#6b3a89', 'title': u'Expert: 21.4%', 'width': u'78.57142857142856', 'x': u'100'}, {'fill': u'#d1c4da', 'title': u'Competent: 57.1%', 'width': u'57.14285714285714', 'x': u'100'}]} {'id': u'skills-data-mario-', 'rects': [{'fill': u'#f68e4d', 'title': u'Uninformed: 14.3%', 'width': u'57.142857142857146', 'x': u'42.857142857142854'}, {'fill': u'#f9b289', 'title': u'Beginning: 21.4%', 'width': u'42.85714285714286', 'x': u'57.14285714285714'}, {'fill': u'#fcd6c5', 'title': u'Practicing: 21.4%', 'width': u'21.42857142857143', 'x': u'78.57142857142857'}, {'fill': u'#6b3a89', 'title': u'Expert: 7.1%', 'width': u'28.571428571428555', 'x': u'100'}, {'fill': u'#d1c4da', 'title': u'Competent: 21.4%', 'width': u'21.428571428571416', 'x': u'100'}]} {'id': u'skills-data-liliana-', 'rects': [{'fill': u'#f68e4d', 'title': u'Uninformed: 21.4%', 'width': u'57.142857142857146', 'x': u'42.857142857142854'}, {'fill': u'#f9b289', 'title': u'Beginning: 7.1%', 'width': u'35.71428571428572', 'x': u'64.28571428571428'}, {'fill': u'#fcd6c5', 'title': u'Practicing: 28.6%', 'width': u'28.571428571428584', 'x': u'71.42857142857142'}, {'fill': u'#6b3a89', 'title': u'Expert: 21.4%', 'width': u'21.428571428571416', 'x': u'100'}, {'fill': u'#d1c4da', 'title': u'Competent: 0.0%', 'width': u'0', 'x': u'100'}]} Print the score colors box: >>> print_score_colors(teacher) Expert: background-color: rgb(107, 58, 137); Competent: background-color: rgb(209, 196, 218); Practicing: background-color: rgb(252, 214, 197); Beginning: background-color: rgb(249, 178, 137); Uninformed: background-color: rgb(246, 142, 77); Change the Skill Type filter to Required and print charts: >>> table = teacher.query.css('table.section-report') >>> sel = '//label[text()="Required"]' >>> teacher.query.xpath(sel).click() >>> teacher.wait(lambda: table.expired) >>> print_charts_info(teacher) {'id': u'skills-data-camila:40c:41-', 'rects': [{'fill': u'#f68e4d', 'title': u'Uninformed: 10.0%', 'width': u'20', 'x': u'80'}, {'fill': u'#f9b289', 'title': u'Beginning: 0.0%', 'width': u'10', 'x': u'90'}, {'fill': u'#fcd6c5', 'title': u'Practicing: 10.0%', 'width': u'10', 'x': u'90'}, {'fill': u'#6b3a89', 'title': u'Expert: 30.0%', 'width': u'80', 'x': u'100'}, {'fill': u'#d1c4da', 'title': u'Competent: 50.0%', 'width': u'50', 'x': u'100'}]} {'id': u'skills-data-mario-', 'rects': [{'fill': u'#f68e4d', 'title': u'Uninformed: 20.0%', 'width': u'60', 'x': u'40'}, {'fill': u'#f9b289', 'title': u'Beginning: 10.0%', 'width': u'39.99999999999999', 'x': u'60.00000000000001'}, {'fill': u'#fcd6c5', 'title': u'Practicing: 30.0%', 'width': u'30', 'x': u'70'}, {'fill': u'#6b3a89', 'title': u'Expert: 0.0%', 'width': u'30', 'x': u'100'}, {'fill': u'#d1c4da', 'title': u'Competent: 30.0%', 'width': u'30', 'x': u'100'}]} {'id': u'skills-data-liliana-', 'rects': [{'fill': u'#f68e4d', 'title': u'Uninformed: 20.0%', 'width': u'70', 'x': u'30.000000000000004'}, {'fill': u'#f9b289', 'title': u'Beginning: 10.0%', 'width': u'50', 'x': u'50'}, {'fill': u'#fcd6c5', 'title': u'Practicing: 40.0%', 'width': u'39.99999999999999', 'x': u'60.00000000000001'}, {'fill': u'#6b3a89', 'title': u'Expert: 30.0%', 'width': u'30', 'x': u'100'}, {'fill': u'#d1c4da', 'title': u'Competent: 0.0%', 'width': u'0', 'x': u'100'}]} Change the Skill Type filter to Evaluated and print charts: >>> table = teacher.query.css('table.section-report') >>> sel = '//label[text()="Evaluated"]' >>> teacher.query.xpath(sel).click() >>> teacher.wait(lambda: table.expired) >>> print_charts_info(teacher) {'id': u'skills-data-camila:40c:41-', 'rects': [{'fill': u'#f68e4d', 'title': u'Uninformed: 7.1%', 'width': u'21.42857142857143', 'x': u'78.57142857142857'}, {'fill': u'#f9b289', 'title': u'Beginning: 7.1%', 'width': u'14.285714285714292', 'x': u'85.71428571428571'}, {'fill': u'#fcd6c5', 'title': u'Practicing: 7.1%', 'width': u'7.142857142857153', 'x': u'92.85714285714285'}, {'fill': u'#6b3a89', 'title': u'Expert: 21.4%', 'width': u'78.57142857142856', 'x': u'100'}, {'fill': u'#d1c4da', 'title': u'Competent: 57.1%', 'width': u'57.14285714285714', 'x': u'100'}]} {'id': u'skills-data-mario-', 'rects': [{'fill': u'#f68e4d', 'title': u'Uninformed: 16.7%', 'width': u'66.66666666666667', 'x': u'33.33333333333333'}, {'fill': u'#f9b289', 'title': u'Beginning: 25.0%', 'width': u'50', 'x': u'50'}, {'fill': u'#fcd6c5', 'title': u'Practicing: 25.0%', 'width': u'25', 'x': u'75'}, {'fill': u'#6b3a89', 'title': u'Expert: 8.3%', 'width': u'33.333333333333314', 'x': u'100'}, {'fill': u'#d1c4da', 'title': u'Competent: 25.0%', 'width': u'25', 'x': u'100'}]} {'id': u'skills-data-liliana-', 'rects': [{'fill': u'#f68e4d', 'title': u'Uninformed: 27.3%', 'width': u'72.72727272727273', 'x': u'27.27272727272727'}, {'fill': u'#f9b289', 'title': u'Beginning: 9.1%', 'width': u'45.45454545454546', 'x': u'54.54545454545454'}, {'fill': u'#fcd6c5', 'title': u'Practicing: 36.4%', 'width': u'36.36363636363637', 'x': u'63.63636363636363'}, {'fill': u'#6b3a89', 'title': u'Expert: 27.3%', 'width': u'27.272727272727266', 'x': u'100'}, {'fill': u'#d1c4da', 'title': u'Competent: 0.0%', 'width': u'0', 'x': u'100'}]} Change Passing Score filter to Practicing and print charts: >>> table = teacher.query.css('table.section-report') >>> teacher.query.id('passing-score-filter').ui.set_value('Practicing') >>> teacher.wait(lambda: table.expired) >>> print_charts_info(teacher) {'id': u'skills-data-camila:40c:41-', 'rects': [{'fill': u'#f68e4d', 'title': u'Uninformed: 7.1%', 'width': u'14.285714285714292', 'x': u'85.71428571428571'}, {'fill': u'#fcd6c5', 'title': u'Beginning: 7.1%', 'width': u'7.142857142857153', 'x': u'92.85714285714285'}, {'fill': u'#6b3a89', 'title': u'Expert: 21.4%', 'width': u'85.7142857142857', 'x': u'100'}, {'fill': u'#9e7fb2', 'title': u'Competent: 57.1%', 'width': u'64.28571428571428', 'x': u'100'}, {'fill': u'#d1c4da', 'title': u'Practicing: 7.1%', 'width': u'7.142857142857139', 'x': u'100'}]} {'id': u'skills-data-mario-', 'rects': [{'fill': u'#f68e4d', 'title': u'Uninformed: 16.7%', 'width': u'41.66666666666667', 'x': u'58.33333333333333'}, {'fill': u'#fcd6c5', 'title': u'Beginning: 25.0%', 'width': u'25', 'x': u'75'}, {'fill': u'#6b3a89', 'title': u'Expert: 8.3%', 'width': u'58.333333333333314', 'x': u'100'}, {'fill': u'#9e7fb2', 'title': u'Competent: 25.0%', 'width': u'50', 'x': u'100'}, {'fill': u'#d1c4da', 'title': u'Practicing: 25.0%', 'width': u'25', 'x': u'100'}]} {'id': u'skills-data-liliana-', 'rects': [{'fill': u'#f68e4d', 'title': u'Uninformed: 27.3%', 'width': u'36.36363636363637', 'x': u'63.63636363636363'}, {'fill': u'#fcd6c5', 'title': u'Beginning: 9.1%', 'width': u'9.09090909090908', 'x': u'90.90909090909092'}, {'fill': u'#6b3a89', 'title': u'Expert: 27.3%', 'width': u'63.636363636363654', 'x': u'100'}, {'fill': u'#9e7fb2', 'title': u'Competent: 0.0%', 'width': u'36.363636363636374', 'x': u'100'}, {'fill': u'#d1c4da', 'title': u'Practicing: 36.4%', 'width': u'36.363636363636374', 'x': u'100'}]} Print the score colors box: >>> print_score_colors(teacher) Expert: background-color: rgb(107, 58, 137); Competent: background-color: rgb(158, 127, 178); Practicing: background-color: rgb(209, 196, 218); Beginning: background-color: rgb(252, 214, 197); Uninformed: background-color: rgb(246, 142, 77); Print students above passing target: >>> sel = '#section-report-form-container tr.above-passing-target' >>> for row in teacher.query_all.css(sel): ... print row Camila Cerna ... Change % Passing Target filter to 60% and print students above passing target: >>> table = teacher.query.css('table.section-report') >>> teacher.query.id('passing-target-filter').ui.set_value('60%') >>> teacher.wait(lambda: table.expired) >>> sel = '#section-report-form-container tr.above-passing-target' >>> for row in teacher.query_all.css(sel): ... print row Camila Cerna ... Liliana Vividor ... Print the axis of Camila's chart: >>> chart = teacher.query.id('skills-data-camila:40c:41-') >>> sel = 'svg g.axis' >>> for axis in chart.query_all.css(sel): ... print axis 0 0 20 20 40 40 60 60 80 80 100 100 Evaluated skill type option with no scores ------------------------------------------ >>> manager.ui.person.add('Tom', 'Hoffman', 'tom', 'pwd') >>> manager.ui.person.add('German', 'Tejada', 'german', 'pwd') >>> manager.ui.person.add('Karla', 'Vividor', 'karla', 'pwd') >>> manager.ui.section.add('2012', '2012', 'Programming') >>> manager.ui.section.instructors.add('2012', '2012', 'Programming (2)', ... ['tom']) >>> manager.ui.section.students.add('2012', '2012', 'Programming (2)', ... ['german', 'karla']) Log in as instructor: >>> another_teacher = browsers.another_teacher >>> another_teacher.ui.login('tom', 'pwd') >>> another_teacher.query.link('CanDo').click() >>> another_teacher.query.link('Per Student Skills').click() >>> print another_teacher.query.css('.page .header h1').text Per Student Skills >>> print another_teacher.query.css('.page .header h2').text Programming (2) >>> table = another_teacher.query.css('table.section-report') >>> sel = '//label[text()="Evaluated"]' >>> another_teacher.query.xpath(sel).click() >>> another_teacher.wait(lambda: table.expired) >>> print_charts_info(another_teacher) {'id': u'skills-data-german-', 'rects': [{'fill': u'#f68e4d', 'title': u'Uninformed: 0.0%', 'width': u'0', 'x': u'100'}, {'fill': u'#f9b289', 'title': u'Beginning: 0.0%', 'width': u'0', 'x': u'100'}, {'fill': u'#fcd6c5', 'title': u'Practicing: 0.0%', 'width': u'0', 'x': u'100'}, {'fill': u'#6b3a89', 'title': u'Expert: 0.0%', 'width': u'0', 'x': u'100'}, {'fill': u'#d1c4da', 'title': u'Competent: 0.0%', 'width': u'0', 'x': u'100'}]} {'id': u'skills-data-karla-', 'rects': [{'fill': u'#f68e4d', 'title': u'Uninformed: 0.0%', 'width': u'0', 'x': u'100'}, {'fill': u'#f9b289', 'title': u'Beginning: 0.0%', 'width': u'0', 'x': u'100'}, {'fill': u'#fcd6c5', 'title': u'Practicing: 0.0%', 'width': u'0', 'x': u'100'}, {'fill': u'#6b3a89', 'title': u'Expert: 0.0%', 'width': u'0', 'x': u'100'}, {'fill': u'#d1c4da', 'title': u'Competent: 0.0%', 'width': u'0', 'x': u'100'}]} Print the axis of Karla's chart: >>> sel = '#skills-data-karla- svg g.axis' >>> for axis in another_teacher.query_all.css(sel): ... print axis 0 0 20 20 40 40 60 60 80 80 100 100 schooltool.cando-2.6.2/src/schooltool/cando/browser/stests/add_skills.txt0000644000175000017500000002015412270520445030046 0ustar menesismenesis00000000000000Tests for the skill scoresytems =============================== Log in as manager: >>> manager = browsers.manager >>> manager.ui.login('manager', 'schooltool') We'll define a helper function for printing the form fields of any object. >>> def print_attrs(): ... sel = 'table.form-fields tbody tr' ... for row in manager.query_all.css(sel): ... label = row.query.xpath('td[1]').text ... value = row.query.xpath('td[2]').text ... print '%s: %s' % (label, value) Let's start by adding a skillset. >>> manager.open('http://localhost/skills') >>> manager.query.link('Skill Set').click() >>> manager.query.name('form.widgets.title').type('Carpentry') >>> manager.query.name('form.widgets.label').type('Carplab') >>> manager.query.button('Submit').click() We see that it was added. >>> print manager.query_all.xpath('//table[@class="data"]//a').get_attribute('href') http://localhost/skills/Carpentr1 >>> manager.query.link('Carpentry').click() >>> print_attrs() Description: Label: Carplab Deprecated: No Now, we'll add a skill to it. We see that the scoresystem field is set to the default, one the user hasn't even chosen yet. >>> manager.query.link('Skill').click() >>> print manager.query.name('form.widgets.scoresystem:list').get_attribute('value') SkillScoreSystem- We'll change it to 'Extended Letter Grade' before submitting it. >>> manager.query.name('form.widgets.title').type('Pounding') >>> manager.query.name('form.widgets.scoresystem:list').ui.set_value('Extended Letter Grade') >>> manager.query.name('form.widgets.required').click() >>> manager.query.button('Submit').click() We see that it was added. >>> print manager.query_all.xpath('//table[@class="data"]//a').get_attribute('href') http://localhost/skills/Carpentr1/Pounding1 >>> manager.query.link('Pounding').click() >>> print_attrs() Scoresystem: Extended Letter Grade Description: Label: 01 Required?: Required Deprecated: No External ID: We'll add another skill. We see that the scoresystem field is not set to the default this time. The choice we made last time we added a skill is remembered so we don't have to choose it every time. >>> manager.query.link('Done').click() >>> manager.query.link('Skill').click() >>> print manager.query.name('form.widgets.scoresystem:list').get_attribute('value') extended-letter-grade- Now we'll fill in the form and add our second skill. We see that it is there after we submit it. >>> manager.query.name('form.widgets.title').type('Hammering') >>> manager.query.name('form.widgets.scoresystem:list').ui.set_value('Pass/Fail') >>> manager.query.name('form.widgets.required').click() >>> manager.query.button('Submit').click() >>> manager.query.link('Hammering').click() >>> print_attrs() Scoresystem: Pass/Fail Description: Label: 02 Required?: Required Deprecated: No External ID: We'll add one last skill. Again, it remembered the last scoresystem we chose. >>> manager.query.link('Done').click() >>> manager.query.link('Skill').click() >>> print manager.query.name('form.widgets.scoresystem:list').get_attribute('value') passfail- >>> manager.query.name('form.widgets.title').type('Whacking') >>> manager.query.name('form.widgets.scoresystem:list').ui.set_value('Letter Grade') >>> manager.query.name('form.widgets.required').click() >>> manager.query.button('Submit').click() >>> manager.query.link('Whacking').click() >>> print_attrs() Scoresystem: Letter Grade Description: Label: 03 Required?: Required Deprecated: No External ID: We see our skillset now has three skills. >>> manager.query.link('Done').click() >>> links = manager.query_all.xpath('//table[@class="data"]//a').get_attribute('href') >>> for link in sorted(links): print link http://localhost/skills/Carpentr1/Hammerin2 http://localhost/skills/Carpentr1/Pounding1 http://localhost/skills/Carpentr1/Whacking3 Gradebook tests --------------- Now that we have shown that we can add skills with different scoresystems, let's see how the gradebook handles them. Set up persons: >>> manager.ui.person.add('Jeffrey', 'Elkner', 'jeffrey', 'pwd') >>> manager.ui.person.add('Camila', 'Cerna', 'camila', 'pwd') Set up a section: >>> manager.ui.schoolyear.add('2012', '2012-01-01', '2012-12-31') >>> manager.ui.term.add('2012', '2012', '2012-01-01', '2012-12-31') >>> manager.ui.course.add('2012', 'Programming', course_id='PRO') >>> manager.ui.section.add('2012', '2012', 'Programming') >>> manager.ui.section.instructors.add('2012', '2012', 'Programming (1)', ... ['jeffrey']) >>> manager.ui.section.students.add('2012', '2012', 'Programming (1)', ... ['camila']) Log in as instructor: >>> teacher = browsers.teacher >>> teacher.ui.login('jeffrey', 'pwd') Go to gradebook and add the carpentry skills to the project there. >>> teacher.query.link('CanDo').click() >>> teacher.query.link('Skill').click() >>> teacher.query.button('Search').click() >>> teacher.query.link('Carpentry').click() >>> teacher.query.name('Carpentr1.Pounding1').click() >>> teacher.query.name('Carpentr1.Hammerin2').click() >>> teacher.query.name('Carpentr1.Whacking3').click() >>> teacher.query.button('Submit').click() We see the labels and max scores for the three new gradebook columns. >>> print teacher.query_all.css('.grades thead th').text 01 02 03 A+ Pass A We'll start by putting some invalid scores in all three cells for our student. We see that the cells all are marked with the error class. >>> teacher.ui.gradebook.worksheet.score('Cerna, Camila', '01', '3') >>> teacher.ui.gradebook.worksheet.score('Cerna, Camila', '02', '3') >>> teacher.ui.gradebook.worksheet.score('Cerna, Camila', '03', '3') >>> import time; time.sleep(2) >>> print teacher.query_all.css('.grades tbody tr input').get_attribute('class') error error error We'll put the max possible score for each cell. Now we see the cells are valid. >>> teacher.ui.gradebook.worksheet.score('Cerna, Camila', '01', 'A+') >>> teacher.ui.gradebook.worksheet.score('Cerna, Camila', '02', 'Pass') >>> teacher.ui.gradebook.worksheet.score('Cerna, Camila', '03', 'A') >>> import time; time.sleep(2) >>> print teacher.query_all.css('.grades tbody tr input').get_attribute('class') valid valid valid Lastly, well change the first cell to be 'B' because the gradebook used to mark such cells as class, 'extracredit', even though there is no extracredit with discrete scoresystems, only with ranged values scoresystems. We verify that the cell stays as just valid. >>> teacher.ui.gradebook.worksheet.score('Cerna, Camila', '01', 'B') >>> import time; time.sleep(2) >>> print teacher.query_all.css('.grades tbody tr input').get_attribute('class') valid valid valid Student gradebook ----------------- We'll grade the student again the same three ways in the score student view. We'll need a helper for scoring. >>> def score(activity, grade): ... cell = teacher.query_all.xpath('//td[@class="student-score"]')[activity] ... cell.click() ... cell.query.tag('input').type(teacher.keys.DELETE, grade) >>> teacher.query.link('Cerna').click() >>> menu = teacher.query.css('#students-part tbody ul.popup_menu') >>> menu.query.link('Score').click() We'll enter three invalid scores, then three valid ones. This view never did show extra credit. >>> score(0, '3') >>> score(1, '3') >>> score(2, '3') >>> import time; time.sleep(2) >>> print teacher.query_all.xpath('//td[@class="student-score"]/input').get_attribute('class') error error error >>> score(0, 'A+') >>> score(1, 'Pass') >>> score(2, 'A') >>> import time; time.sleep(2) >>> print teacher.query_all.xpath('//td[@class="student-score"]/input').get_attribute('class') valid valid valid ././@LongLink0000000000000000000000000000014700000000000011217 Lustar 00000000000000schooltool.cando-2.6.2/src/schooltool/cando/browser/stests/per_student_skills_report_multiple_term.txtschooltool.cando-2.6.2/src/schooltool/cando/browser/stests/per_student_skills_report_multiple_term.t0000644000175000017500000004004512270520445035634 0ustar menesismenesis00000000000000Per Student Skills Report in Multiple Term sections =================================================== Helpers: >>> from pprint import pprint >>> def gradeStudent(browser, student, scores): ... for skillset, grades in scores.items(): ... active = browser.query.css('.third-nav li.active a') ... if active.text != skillset: ... browser.query.css('#navbar-list-worksheets').click() ... sel = 'a[title="%s"]' % skillset ... link = browser.query.css(sel) ... # XXX: fix this, use clicks instead of open ... browser.open(link.get_attribute('href')) ... for label, grade in grades: ... browser.ui.gradebook.worksheet.score(student, label, grade) ... browser.query.name('UPDATE_SUBMIT').click() >>> def print_charts_info(browser): ... for chart in browser.query_all.css('.chart-container'): ... rects = [] ... for rect in chart.query_all.css('svg > g > rect'): ... info = { ... 'fill': rect.get_attribute('fill'), ... 'title': rect.query.tag('title').text, ... 'width': rect.get_attribute('width'), ... 'x': rect.get_attribute('x'), ... } ... rects.append(info) ... pprint({ ... 'id': chart.get_attribute('id'), ... 'rects': rects, ... }) >>> def print_score_colors(browser): ... result = [] ... sel = '.score-colors-table .score-color-cell' ... for cell in browser.query_all.css(sel)[:-1]: ... title = cell.query.css('span.title') ... color = cell.query.css('span.color') ... print '%s: %s' % (title.text, color.get_attribute('style')) Log in as manager: >>> manager = browsers.manager >>> manager.ui.login('manager', 'schooltool') Set up persons: >>> manager.ui.person.add('Jeffrey', 'Elkner', 'jeffrey', 'pwd') >>> manager.ui.person.add('Camila', 'Cerna', 'camila', 'pwd') >>> manager.ui.person.add('Liliana', 'Vividor', 'liliana', 'pwd') >>> manager.ui.person.add('Mario', 'Tejada', 'mario', 'pwd') Set up multiple term sections: >>> manager.ui.schoolyear.add('2012', '2012-01-01', '2012-12-31') >>> manager.ui.term.add('2012', 'Q1', '2012-01-01', '2012-03-31') >>> manager.ui.term.add('2012', 'Q2', '2012-04-01', '2012-06-30') >>> manager.ui.term.add('2012', 'Q3', '2012-07-01', '2012-09-30') >>> manager.ui.term.add('2012', 'Q4', '2012-10-01', '2012-12-31') >>> manager.ui.course.add('2012', 'Programming', course_id='PRO') >>> manager.ui.section.add('2012', 'Q1', 'Programming', ends='Q4') >>> manager.ui.section.instructors.add('2012', 'Q1', 'Programming (1)', ... ['jeffrey']) >>> manager.ui.section.students.add('2012', 'Q1', 'Programming (1)', ... ['camila', 'liliana', 'mario']) Set up skills: >>> manager.ui.layer.add('Course') >>> manager.ui.node.add('Programming', label='PRO') >>> manager.ui.skillset.add('Python Environment', '01') >>> manager.ui.skillset.add('Data Types, Statements, and Expressions', '02') >>> manager.ui.skillset.add('Errors', '03') >>> manager.ui.skillset.add('Strings', '04') >>> manager.ui.skill.add( ... 'Python Environment', ... 'Use the Python shell for interactive evaluation', ... '01') >>> manager.ui.skill.add( ... 'Python Environment', ... 'Make Python scripts with a text editor', ... '02', ... required=False) >>> manager.ui.skill.add( ... 'Data Types, Statements, and Expressions', ... 'Recognize int, float, str, list, tuple, and dict.', ... '03') >>> manager.ui.skill.add( ... 'Data Types, Statements, and Expressions', ... 'Use type(...) to determine the data type of a given value.', ... '04') >>> manager.ui.skill.add( ... 'Data Types, Statements, and Expressions', ... 'Use assignment statements to assign names (variables) to values.', ... '05') >>> manager.ui.skill.add( ... 'Data Types, Statements, and Expressions', ... 'Use the input function to read user input.', ... '06') >>> manager.ui.skill.add( ... 'Data Types, Statements, and Expressions', ... 'Define keyword and recognize keywords in Python.', ... '07') >>> manager.ui.skill.add( ... 'Data Types, Statements, and Expressions', ... 'Create legal variable names and recognize illegal ones.', ... '08', ... required=False) >>> manager.ui.skill.add( ... 'Errors', ... 'Recognize and differentiate among errors.', ... '09') >>> manager.ui.skill.add( ... 'Errors', ... 'Read and interpret stack traceback messages.', ... '10') >>> manager.ui.skill.add( ... 'Strings', ... 'Create string literals with single, double, and triple quotes.', ... '11') >>> manager.ui.skill.add( ... 'Strings', ... 'Use the len() function to return the length of a string.', ... '12') >>> manager.ui.skill.add( ... 'Strings', ... 'Use the find(...) method to locate substrings in a string.', ... '13', ... required=False) >>> manager.ui.skill.add( ... 'Strings', ... 'Use the split() method to break a string into a list.', ... '14', ... required=False) >>> manager.query.link('Search').click() >>> manager.query.button('Search').click() >>> manager.query.link('Programming').click() >>> sel = '//h2[contains(@class, "ui-accordion-header")]' >>> accordion_headers = manager.query_all.xpath(sel) >>> sel = 'div.ui-accordion-content' >>> accordion_contents = manager.query_all.css(sel) >>> information_accordion_content = accordion_contents[0] >>> skillsets_accordion_header = accordion_headers[4] >>> skillsets_accordion_header.click() >>> skillsets_accordion_content = accordion_contents[4] >>> manager.wait_no(information_accordion_content.is_displayed) >>> sel = '//a[@title="Edit skill sets"]' >>> manager.query.xpath(sel).click() >>> manager.query.id('form-buttons-add').click() >>> manager.query.link('Done').click() >>> sel = '//h2[contains(@class, "ui-accordion-header")]' >>> accordion_headers = manager.query_all.xpath(sel) >>> sel = 'div.ui-accordion-content' >>> accordion_contents = manager.query_all.css(sel) >>> information_accordion_content = accordion_contents[0] >>> layers_accordion_header = accordion_headers[3] >>> layers_accordion_header.click() >>> layers_accordion_content = accordion_contents[3] >>> manager.wait_no(information_accordion_content.is_displayed) >>> sel = '//a[@title="Edit layers"]' >>> manager.query.xpath(sel).click() >>> manager.query.id('form-buttons-add').click() Assign the skills to the course: >>> manager.query.link('School').click() >>> manager.query.link('Courses').click() >>> manager.query.link('Batch Assign Skills').click() >>> manager.query.name('course_attr').ui.set_value('Course ID') >>> manager.query.name('layer').ui.set_value('Course') >>> manager.query.name('node_attr').ui.set_value('Label') >>> manager.query.name('SEARCH_BUTTON').click() >>> manager.query.name('ASSIGN_BUTTON').click() Log in as instructor and grade some skills in the first term section: >>> teacher = browsers.teacher >>> teacher.ui.login('jeffrey', 'pwd') >>> teacher.query.link('CanDo').click() Add scores for the students: >>> camila_scores = { ... '01: Python Environment': [ ... ('01', '4'), ... ('02', '3'), ... ], ... '02: Data Types, Statements, and Expressions': [ ... ('03', '2'), ... ('04', '0'), ... ('05', '3'), ... ('06', '3'), ... ('07', '3'), ... ('08', '1'), ... ], ... '03: Errors': [ ... ('09', '4'), ... ('10', '3'), ... ], ... '04: Strings': [ ... ('11', '4'), ... ('12', '3'), ... ('13', '3'), ... ('14', '3'), ... ], ... } >>> gradeStudent(teacher, 'Camila Cerna', camila_scores) >>> mario_scores = { ... '01: Python Environment': [ ... ('01', '3'), ... ('02', '4'), ... ], ... '02: Data Types, Statements, and Expressions': [ ... ('03', '1'), ... ('04', '0'), ... ('05', '0'), ... ('06', '2'), ... ('07', '2'), ... ('08', '1'), ... ], ... '03: Errors': [ ... ('09', ''), ... ('10', '3'), ... ], ... '04: Strings': [ ... ('11', '3'), ... ('12', '2'), ... ('13', '1'), ... ('14', ''), ... ], ... } >>> gradeStudent(teacher, 'Mario Tejada', mario_scores) >>> liliana_scores = { ... '01: Python Environment': [ ... ('01', '1'), ... ('02', ''), ... ], ... '02: Data Types, Statements, and Expressions': [ ... ('03', '2'), ... ('04', '0'), ... ('05', '2'), ... ('06', '4'), ... ('07', '0'), ... ('08', '0'), ... ], ... '03: Errors': [ ... ('09', '4'), ... ('10', '4'), ... ], ... '04: Strings': [ ... ('11', '2'), ... ('12', '2'), ... ('13', ''), ... ('14', ''), ... ], ... } >>> gradeStudent(teacher, 'Liliana Vividor', liliana_scores) Print the Per Student Skills report details: >>> print teacher.url http://localhost/schoolyears/2012/q1/sections/1/skills/.../gradebook >>> teacher.query.link('Per Student Skills').click() >>> print teacher.query.css('.page .header h1').text Per Student Skills >>> print teacher.query.css('.page .header h2').text Programming (1) Print the students individual charts information: >>> print_charts_info(teacher) {'id': u'skills-data-camila-', 'rects': [{'fill': u'#f68e4d', 'title': u'Uninformed: 7.1%', 'width': u'21.42857142857143', 'x': u'78.57142857142857'}, {'fill': u'#f9b289', 'title': u'Beginning: 7.1%', 'width': u'14.285714285714292', 'x': u'85.71428571428571'}, {'fill': u'#fcd6c5', 'title': u'Practicing: 7.1%', 'width': u'7.142857142857153', 'x': u'92.85714285714285'}, {'fill': u'#6b3a89', 'title': u'Expert: 21.4%', 'width': u'78.57142857142856', 'x': u'100'}, {'fill': u'#d1c4da', 'title': u'Competent: 57.1%', 'width': u'57.14285714285714', 'x': u'100'}]} {'id': u'skills-data-mario-', 'rects': [{'fill': u'#f68e4d', 'title': u'Uninformed: 14.3%', 'width': u'57.142857142857146', 'x': u'42.857142857142854'}, {'fill': u'#f9b289', 'title': u'Beginning: 21.4%', 'width': u'42.85714285714286', 'x': u'57.14285714285714'}, {'fill': u'#fcd6c5', 'title': u'Practicing: 21.4%', 'width': u'21.42857142857143', 'x': u'78.57142857142857'}, {'fill': u'#6b3a89', 'title': u'Expert: 7.1%', 'width': u'28.571428571428555', 'x': u'100'}, {'fill': u'#d1c4da', 'title': u'Competent: 21.4%', 'width': u'21.428571428571416', 'x': u'100'}]} {'id': u'skills-data-liliana-', 'rects': [{'fill': u'#f68e4d', 'title': u'Uninformed: 21.4%', 'width': u'57.142857142857146', 'x': u'42.857142857142854'}, {'fill': u'#f9b289', 'title': u'Beginning: 7.1%', 'width': u'35.71428571428572', 'x': u'64.28571428571428'}, {'fill': u'#fcd6c5', 'title': u'Practicing: 28.6%', 'width': u'28.571428571428584', 'x': u'71.42857142857142'}, {'fill': u'#6b3a89', 'title': u'Expert: 21.4%', 'width': u'21.428571428571416', 'x': u'100'}, {'fill': u'#d1c4da', 'title': u'Competent: 0.0%', 'width': u'0', 'x': u'100'}]} If we go to the Q2 section we should see a similar report even if there are no grades yet for the Q2 section: >>> teacher.query.link('Done').click() >>> navigator = teacher.query_all.css('.refine .navigator')[1] >>> page = teacher.query.tag('html') >>> navigator.ui.set_value('Q2') >>> teacher.wait(lambda: page.expired) >>> print teacher.url http://localhost/schoolyears/2012/q2/sections/1/skills/.../gradebook >>> teacher.query.link('Per Student Skills').click() >>> print teacher.query.css('.page .header h1').text Per Student Skills >>> print teacher.query.css('.page .header h2').text Programming (1) >>> print_charts_info(teacher) {'id': u'skills-data-camila-', 'rects': [{'fill': u'#f68e4d', 'title': u'Uninformed: 7.1%', 'width': u'21.42857142857143', 'x': u'78.57142857142857'}, {'fill': u'#f9b289', 'title': u'Beginning: 7.1%', 'width': u'14.285714285714292', 'x': u'85.71428571428571'}, {'fill': u'#fcd6c5', 'title': u'Practicing: 7.1%', 'width': u'7.142857142857153', 'x': u'92.85714285714285'}, {'fill': u'#6b3a89', 'title': u'Expert: 21.4%', 'width': u'78.57142857142856', 'x': u'100'}, {'fill': u'#d1c4da', 'title': u'Competent: 57.1%', 'width': u'57.14285714285714', 'x': u'100'}]} {'id': u'skills-data-mario-', 'rects': [{'fill': u'#f68e4d', 'title': u'Uninformed: 14.3%', 'width': u'57.142857142857146', 'x': u'42.857142857142854'}, {'fill': u'#f9b289', 'title': u'Beginning: 21.4%', 'width': u'42.85714285714286', 'x': u'57.14285714285714'}, {'fill': u'#fcd6c5', 'title': u'Practicing: 21.4%', 'width': u'21.42857142857143', 'x': u'78.57142857142857'}, {'fill': u'#6b3a89', 'title': u'Expert: 7.1%', 'width': u'28.571428571428555', 'x': u'100'}, {'fill': u'#d1c4da', 'title': u'Competent: 21.4%', 'width': u'21.428571428571416', 'x': u'100'}]} {'id': u'skills-data-liliana-', 'rects': [{'fill': u'#f68e4d', 'title': u'Uninformed: 21.4%', 'width': u'57.142857142857146', 'x': u'42.857142857142854'}, {'fill': u'#f9b289', 'title': u'Beginning: 7.1%', 'width': u'35.71428571428572', 'x': u'64.28571428571428'}, {'fill': u'#fcd6c5', 'title': u'Practicing: 28.6%', 'width': u'28.571428571428584', 'x': u'71.42857142857142'}, {'fill': u'#6b3a89', 'title': u'Expert: 21.4%', 'width': u'21.428571428571416', 'x': u'100'}, {'fill': u'#d1c4da', 'title': u'Competent: 0.0%', 'width': u'0', 'x': u'100'}]} schooltool.cando-2.6.2/src/schooltool/cando/browser/stests/gradebook_grade_student.txt0000644000175000017500000001611012270520445032577 0ustar menesismenesis00000000000000Grade student view ================== Log in as manager: >>> manager = browsers.manager >>> manager.ui.login('manager', 'schooltool') Set up persons: >>> manager.ui.person.add('Jeffrey', 'Elkner', 'jeffrey', 'pwd') >>> manager.ui.person.add('Camila', 'Cerna', 'camila', 'pwd') >>> manager.ui.person.add('Liliana', 'Vividor', 'liliana', 'pwd') >>> manager.ui.person.add('Mario', 'Tejada', 'mario', 'pwd') Set up a section: >>> manager.ui.schoolyear.add('2012', '2012-01-01', '2012-12-31') >>> manager.ui.term.add('2012', '2012', '2012-01-01', '2012-12-31') >>> manager.ui.course.add('2012', 'Programming', course_id='PRO') >>> manager.ui.section.add('2012', '2012', 'Programming') >>> manager.ui.section.instructors.add('2012', '2012', 'Programming (1)', ... ['jeffrey']) >>> manager.ui.section.students.add('2012', '2012', 'Programming (1)', ... ['camila', 'liliana', 'mario']) Set up skills: >>> manager.ui.layer.add('Course') >>> manager.ui.node.add('Programming', label='PRO') >>> manager.ui.skillset.add('Python Environment', '01') >>> manager.ui.skillset.add('Data Types, Statements, and Expressions', '02') >>> manager.ui.skillset.add('Errors', '03') >>> manager.ui.skillset.add('Strings', '04') >>> manager.ui.skill.add( ... 'Python Environment', ... 'Use the Python shell for interactive evaluation', ... '01') >>> manager.ui.skill.add( ... 'Python Environment', ... 'Make Python scripts with a text editor', ... '02', ... required=False) >>> manager.ui.skill.add( ... 'Data Types, Statements, and Expressions', ... 'Recognize int, float, str, list, tuple, and dict.', ... '03') >>> manager.ui.skill.add( ... 'Data Types, Statements, and Expressions', ... 'Use type(...) to determine the data type of a given value.', ... '04') >>> manager.ui.skill.add( ... 'Data Types, Statements, and Expressions', ... 'Use assignment statements to assign names (variables) to values.', ... '05') >>> manager.ui.skill.add( ... 'Data Types, Statements, and Expressions', ... 'Use the input function to read user input.', ... '06') >>> manager.ui.skill.add( ... 'Data Types, Statements, and Expressions', ... 'Define keyword and recognize keywords in Python.', ... '07') >>> manager.ui.skill.add( ... 'Data Types, Statements, and Expressions', ... 'Create legal variable names and recognize illegal ones.', ... '08', ... required=False) >>> manager.ui.skill.add( ... 'Errors', ... 'Recognize and differentiate among errors.', ... '09') >>> manager.ui.skill.add( ... 'Errors', ... 'Read and interpret stack traceback messages.', ... '10') >>> manager.ui.skill.add( ... 'Strings', ... 'Create string literals with single, double, and triple quotes.', ... '11') >>> manager.ui.skill.add( ... 'Strings', ... 'Use the len() function to return the length of a string.', ... '12') >>> manager.ui.skill.add( ... 'Strings', ... 'Use the find(...) method to locate substrings in a string.', ... '13', ... required=False) >>> manager.ui.skill.add( ... 'Strings', ... 'Use the split() method to break a string into a list.', ... '14', ... required=False) >>> manager.query.link('Search').click() >>> manager.query.button('Search').click() >>> manager.query.link('Programming').click() >>> sel = '//h2[contains(@class, "ui-accordion-header")]' >>> accordion_headers = manager.query_all.xpath(sel) >>> sel = 'div.ui-accordion-content' >>> accordion_contents = manager.query_all.css(sel) >>> information_accordion_content = accordion_contents[0] >>> skillsets_accordion_header = accordion_headers[4] >>> skillsets_accordion_header.click() >>> skillsets_accordion_content = accordion_contents[4] >>> manager.wait_no(information_accordion_content.is_displayed) >>> sel = '//a[@title="Edit skill sets"]' >>> manager.query.xpath(sel).click() >>> manager.query.id('form-buttons-add').click() >>> manager.query.link('Done').click() >>> sel = '//h2[contains(@class, "ui-accordion-header")]' >>> accordion_headers = manager.query_all.xpath(sel) >>> sel = 'div.ui-accordion-content' >>> accordion_contents = manager.query_all.css(sel) >>> information_accordion_content = accordion_contents[0] >>> layers_accordion_header = accordion_headers[3] >>> layers_accordion_header.click() >>> layers_accordion_content = accordion_contents[3] >>> manager.wait_no(information_accordion_content.is_displayed) >>> sel = '//a[@title="Edit layers"]' >>> manager.query.xpath(sel).click() >>> manager.query.id('form-buttons-add').click() Assign the skills to the course: >>> manager.query.link('School').click() >>> manager.query.link('Courses').click() >>> manager.query.link('Batch Assign Skills').click() >>> manager.query.name('course_attr').ui.set_value('Course ID') >>> manager.query.name('layer').ui.set_value('Course') >>> manager.query.name('node_attr').ui.set_value('Label') >>> manager.query.name('SEARCH_BUTTON').click() >>> manager.query.name('ASSIGN_BUTTON').click() Log in as instructor: >>> teacher = browsers.teacher >>> teacher.ui.login('jeffrey', 'pwd') >>> teacher.query.link('CanDo').click() Enter Camila's score view: >>> sel = '#students-part tbody td:first-child ul.popup_menu' >>> camila_menu, mario_menu, liliana_menu = teacher.query_all.css(sel) >>> teacher.query.link('Cerna').click() >>> camila_menu.query.link('Score').click() >>> print teacher.query.css('.page .header h1').text Camila Cerna >>> sel = '.grade-student tbody tr th' >>> for th in teacher.query_all.css(sel): ... print th.text 01: Python Environment 02: Data Types, Statements, and Expressions 03: Errors 04: Strings >>> sel = '.grade-student tbody tr td:first-child' >>> for td in teacher.query_all.css(sel): ... print td.text 01: Use the Python shell for interactive evaluation 02: Make Python scripts with a text editor 03: Recognize int, float, str, list, tuple, and dict. 04: Use type(...) to determine the data type of a given value. 05: Use assignment statements to assign names (variables) to values. 06: Use the input function to read user input. 07: Define keyword and recognize keywords in Python. 08: Create legal variable names and recognize illegal ones. 09: Recognize and differentiate among errors. 10: Read and interpret stack traceback messages. 11: Create string literals with single, double, and triple quotes. 12: Use the len() function to return the length of a string. 13: Use the find(...) method to locate substrings in a string. 14: Use the split() method to break a string into a list. schooltool.cando-2.6.2/src/schooltool/cando/browser/stests/iep_scr.txt0000644000175000017500000002216012270520445027360 0ustar menesismenesis00000000000000IEP functionality for the Student Competency Report =================================================== Helpers: >>> def print_report_skills(browser): ... sel = '.student-scr tbody tr' ... for row in browser.query_all.css(sel): ... tds = row.query_all.tag('td') ... if tds: ... print '%s, %s, %s' % (tds[0].text, tds[1].text, tds[2].text) Log in as manager: >>> manager = browsers.manager >>> manager.ui.login('manager', 'schooltool') Set up persons: >>> manager.ui.person.add('Jeffrey', 'Elkner', 'jeffrey', 'pwd') >>> manager.ui.person.add('Camila', 'Cerna', 'camila', 'pwd') >>> camila_url = manager.url >>> manager.ui.person.add('Liliana', 'Vividor', 'liliana', 'pwd') >>> manager.ui.person.add('Mario', 'Tejada', 'mario', 'pwd') Set up a section: >>> manager.ui.schoolyear.add('2012', '2012-01-01', '2012-12-31') >>> manager.ui.term.add('2012', '2012', '2012-01-01', '2012-12-31') >>> manager.ui.course.add('2012', 'Programming', course_id='PRO') >>> manager.ui.section.add('2012', '2012', 'Programming') >>> manager.ui.section.instructors.add('2012', '2012', 'Programming (1)', ... ['jeffrey']) >>> manager.ui.section.students.add('2012', '2012', 'Programming (1)', ... ['camila', 'liliana', 'mario']) Set up skills: >>> manager.ui.layer.add('Course') >>> manager.ui.node.add('Programming', label='PRO') >>> manager.ui.skillset.add('Python Environment', '01') >>> manager.ui.skillset.add('Data Types, Statements, and Expressions', '02') >>> manager.ui.skillset.add('Errors', '03') >>> manager.ui.skillset.add('Strings', '04') >>> manager.ui.skill.add( ... 'Python Environment', ... 'Use the Python shell for interactive evaluation', ... '01') >>> manager.ui.skill.add( ... 'Python Environment', ... 'Make Python scripts with a text editor', ... '02', ... required=False) >>> manager.ui.skill.add( ... 'Data Types, Statements, and Expressions', ... 'Recognize int, float, str, list, tuple, and dict.', ... '03') >>> manager.ui.skill.add( ... 'Data Types, Statements, and Expressions', ... 'Use type(...) to determine the data type of a given value.', ... '04') >>> manager.ui.skill.add( ... 'Data Types, Statements, and Expressions', ... 'Use assignment statements to assign names (variables) to values.', ... '05') >>> manager.ui.skill.add( ... 'Data Types, Statements, and Expressions', ... 'Use the input function to read user input.', ... '06') >>> manager.ui.skill.add( ... 'Data Types, Statements, and Expressions', ... 'Define keyword and recognize keywords in Python.', ... '07') >>> manager.ui.skill.add( ... 'Data Types, Statements, and Expressions', ... 'Create legal variable names and recognize illegal ones.', ... '08', ... required=False) >>> manager.ui.skill.add( ... 'Errors', ... 'Recognize and differentiate among errors.', ... '09') >>> manager.ui.skill.add( ... 'Errors', ... 'Read and interpret stack traceback messages.', ... '10') >>> manager.ui.skill.add( ... 'Strings', ... 'Create string literals with single, double, and triple quotes.', ... '11') >>> manager.ui.skill.add( ... 'Strings', ... 'Use the len() function to return the length of a string.', ... '12') >>> manager.ui.skill.add( ... 'Strings', ... 'Use the find(...) method to locate substrings in a string.', ... '13', ... required=False) >>> manager.ui.skill.add( ... 'Strings', ... 'Use the split() method to break a string into a list.', ... '14', ... required=False) >>> manager.query.link('Search').click() >>> manager.query.button('Search').click() >>> manager.query.link('Programming').click() >>> sel = '//h2[contains(@class, "ui-accordion-header")]' >>> accordion_headers = manager.query_all.xpath(sel) >>> sel = 'div.ui-accordion-content' >>> accordion_contents = manager.query_all.css(sel) >>> information_accordion_content = accordion_contents[0] >>> skillsets_accordion_header = accordion_headers[4] >>> skillsets_accordion_header.click() >>> skillsets_accordion_content = accordion_contents[4] >>> manager.wait_no(information_accordion_content.is_displayed) >>> sel = '//a[@title="Edit skill sets"]' >>> manager.query.xpath(sel).click() >>> manager.query.id('form-buttons-add').click() >>> manager.query.link('Done').click() >>> sel = '//h2[contains(@class, "ui-accordion-header")]' >>> accordion_headers = manager.query_all.xpath(sel) >>> sel = 'div.ui-accordion-content' >>> accordion_contents = manager.query_all.css(sel) >>> information_accordion_content = accordion_contents[0] >>> layers_accordion_header = accordion_headers[3] >>> layers_accordion_header.click() >>> layers_accordion_content = accordion_contents[3] >>> manager.wait_no(information_accordion_content.is_displayed) >>> sel = '//a[@title="Edit layers"]' >>> manager.query.xpath(sel).click() >>> manager.query.id('form-buttons-add').click() Assign the skills to the course: >>> manager.query.link('School').click() >>> manager.query.link('Courses').click() >>> manager.query.link('Batch Assign Skills').click() >>> manager.query.name('course_attr').ui.set_value('Course ID') >>> manager.query.name('layer').ui.set_value('Course') >>> manager.query.name('node_attr').ui.set_value('Label') >>> manager.query.name('SEARCH_BUTTON').click() >>> manager.query.name('ASSIGN_BUTTON').click() Log in as instructor: >>> teacher = browsers.teacher >>> teacher.ui.login('jeffrey', 'pwd') >>> teacher.query.link('CanDo').click() Check Camila's Student Competency Report and print its skills information (label, required, title): >>> sel = '#students-part tbody td:first-child ul.popup_menu' >>> camila_menu, mario_menu, liliana_menu = teacher.query_all.css(sel) >>> teacher.query.link('Cerna').click() >>> camila_menu.query.link('Report').click() >>> camila_report_url = teacher.url >>> print_report_skills(teacher) 01, Yes, Use the Python shell for interactive evaluation 02, No, Make Python scripts with a text editor 03, Yes, Recognize int, float, str, list, tuple, and dict. 04, Yes, Use type(...) to determine the data type of a given value. 05, Yes, Use assignment statements to assign names (variables) to values. 06, Yes, Use the input function to read user input. 07, Yes, Define keyword and recognize keywords in Python. 08, No, Create legal variable names and recognize illegal ones. 09, Yes, Recognize and differentiate among errors. 10, Yes, Read and interpret stack traceback messages. 11, Yes, Create string literals with single, double, and triple quotes. 12, Yes, Use the len() function to return the length of a string. 13, No, Use the find(...) method to locate substrings in a string. 14, No, Use the split() method to break a string into a list. Let's activate IEP for Camila: >>> manager.open(camila_url) >>> manager.query.link('IEP').click() >>> sel = 'a[title="Edit this plan information"]' >>> manager.query.css(sel).click() >>> manager.query.id('form-widgets-active-0').click() >>> manager.query.id('form-buttons-add').click() And customize some of the required skills: >>> manager.query.link('Programming (1)').click() >>> sel = '''a[title="Edit student's IEP skills"]''' >>> manager.query.css(sel).click() >>> sel = 'iep_section_skills.iep.Python E1.Use the 1' >>> manager.query.id(sel).click() >>> sel = 'iep_section_skills.iep.Data Typ2.Use the 4' >>> manager.query.id(sel).click() >>> sel = 'iep_section_skills.iep.Errors-3.Recogniz1' >>> manager.query.id(sel).click() >>> manager.query.name('SAVE').click() And check her report again. The IEP skills should be shown as not required now: >>> teacher.open(camila_report_url) >>> print_report_skills(teacher) 01, No, Use the Python shell for interactive evaluation 02, No, Make Python scripts with a text editor 03, Yes, Recognize int, float, str, list, tuple, and dict. 04, Yes, Use type(...) to determine the data type of a given value. 05, Yes, Use assignment statements to assign names (variables) to values. 06, No, Use the input function to read user input. 07, Yes, Define keyword and recognize keywords in Python. 08, No, Create legal variable names and recognize illegal ones. 09, No, Recognize and differentiate among errors. 10, Yes, Read and interpret stack traceback messages. 11, Yes, Create string literals with single, double, and triple quotes. 12, Yes, Use the len() function to return the length of a string. 13, No, Use the find(...) method to locate substrings in a string. 14, No, Use the split() method to break a string into a list. schooltool.cando-2.6.2/src/schooltool/cando/browser/stests/course_skills.xls0000644000175000017500000002300012270520445030576 0ustar menesismenesis00000000000000ÐÏࡱá;þÿ  þÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿÿÿ þÿÿÿþÿÿÿþÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿRoot Entryÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿ » Ìá°Áâ\pCalc B°aÀ= œ¯¼=@ 8˜@"·Ú1ÈÿArial1ÈÿArial1ÈÿArial1ÈÿArial1Èÿ¼Arial1Èÿ¼Arial ¤GENERAL¥ YYYY/MM/DDà¤õÿ À àõÿ ôÀ àõÿ ôÀ àõÿ ôÀ àõÿ ôÀ àõÿ ôÀ àõÿ ôÀ àõÿ ôÀ àõÿ ôÀ àõÿ ôÀ àõÿ ôÀ àõÿ ôÀ àõÿ ôÀ àõÿ ôÀ àõÿ ôÀ ठÀ à+õÿ ðÀ à)õÿ ðÀ à,õÿ ðÀ à*õÿ ðÀ à õÿ ðÀ ठø ठøÀ ॠüÀ ठø ठÀ “€ÿ“€ÿ“€ÿ“€ÿ“€ÿ“€ÿ`…N School Years…½ Courses…X SkillSets…ëSkills…  CourseSkillsŒÁÁTëzðrð83 ð¿ À@@ñ  ÷ü¤8$IDTitleStartEnd 2011-2012 School Year DescriptionLocal ID Government IDCreditsart_aArtLabel carpentry Carpentry electrical Electrical SkillSet IDSkill ID Equivalent External IDRequiredRetired Scoresystem hammering Hammeringextended-letter-gradepoundingPoundingwhackingWhackingpluggingPluggingYear ID Course ID Skill Setsÿ $‡ cc » Ì dü©ñÒMbP?_€%ÿÁ*+‚# &C&"Times New Roman,Normal"&12&A(%&C&"Times New Roman,Normal"&12Page &Pƒ„&333333é?'333333é?(ƒ-Ø‚-Øð?)ƒ-Ø‚-Øð?¡"d,,333333é?333333é?U } ” ÿÿý ý ý ý ý ý ½J}ÊìPðHðð0ð( ð ð>¶@ggÿÿÿÿ » Ì dü©ñÒMbP?_€%ÿÁ*+‚# &C&"Times New Roman,Normal"&12&A(%&C&"Times New Roman,Normal"&12Page &Pƒ„&333333é?'333333é?(ƒ-Ø‚-Øð?)ƒ-Ø‚-Øð?¡"d,,333333é?333333é?U } ” ÿÿý ý ý ý ý ý ý  ý ý  ý  ìPðH ðð0ð( ð ð>¶@ggÿÿÿÿ » Ì dü©ñÒMbP?_€%ÿÁ*+‚# &C&"Times New Roman,Normal"&12&A(%&C&"Times New Roman,Normal"&12Page &Pƒ„&333333é?'333333é?(ƒ-Ø‚-Øð?)ƒ-Ø‚-Øð?¡"d,,333333é?333333é?U } ” ÿÿÿý ý ý ý  ý  ý ý ý ìPðH0ð ð0ð( ð ð >¶@ggÿÿÿÿ » Ì dü©ñÒMbP?_€%ÿÁ*+‚# &C&"Times New Roman,Normal"&12&A(%&C&"Times New Roman,Normal"&12Page &Pƒ„&333333é?'333333é?(ƒ-Ø‚-Øð?)ƒ-Ø‚-Øð?¡"d,,333333é?333333é?U } ” } %} x} ” } } ”   ÿ ÿ ÿ ÿ ÿý ý ý ý ý ý ý  ý ý ý ý  ý ý ý  ý  ý ý ¾ ý  ý  ý ý ý  ý ý ý  ý  ìPðH@ðð0ð( ð ð>¶@ggÿÿÿÿ » Ì dü©ñÒMbP?_€%ÿÁ*+‚&C&P&C&Fƒ„&333333Ó?'333333Ó?(-Ø‚-Ø‚ã?)[°[°×?¡" dƒ,,š™™™™™¹?š™™™™™¹?U } ” ÿÿý !ý "ý #ý ý  ý  ìPðHPðð0ð( ð ð>¶@ggÿÿÿÿ þÿÿÿþÿÿÿþÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿ ÿÿÿÿÀFMicrosoft Excel 97-TabelleBiff8þÿà…ŸòùOh«‘+'³Ù0˜@H \ h t € Œéý Alan Elkner14@þÅë@@@€ù÷³pšÍþÿÕÍÕœ.“—+,ù®DÕÍÕœ.“—+,ù®\éýéýRoot EntryÿÿÿÿÿÿÿÿÀF@Workbookÿÿÿÿ&CompObjÿÿÿÿÿÿÿÿIOle ÿÿÿÿÿÿÿÿÿÿÿÿSummaryInformation(ÿÿÿÿÿÿÿÿÈDocumentSummaryInformation8ÿÿÿÿÿÿÿÿÿÿÿÿtÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿschooltool.cando-2.6.2/src/schooltool/cando/browser/stests/nodes_layers.txt0000644000175000017500000004027512270520445030432 0ustar menesismenesis00000000000000Tests for the layer and node views ================================== Log in as manager: >>> manager = browsers.manager >>> manager.ui.login('manager', 'schooltool') We'll define helper functions for printing the form fields of layers and nodes. >>> def print_layer_attrs(): ... sel = 'table.form-fields tbody tr' ... for row in manager.query_all.css(sel): ... label = row.query.xpath('td[1]').text ... value = row.query.xpath('td[2]').text ... print '%s: %s' % (label, value) >>> def print_node_attrs(): ... sel = 'table.form-fields tbody tr' ... for row in manager.query_all.css(sel): ... label = row.query.css('label span').text ... value = row.query.css('.widget :first-child').text ... print '%s: %s' % (label, value) We'll add some skillsets that we'll link to later. >>> manager.ui.skillset.add('Basic Algebra') >>> manager.ui.skillset.add('Continuing Algebra') >>> manager.ui.skillset.add('Basic Calculus') >>> manager.ui.skillset.add('Continuing Calculus') Layer maintenance ----------------- Let's start by going to the layers container view. We see there are no layers yet. >>> manager.query.link('School').click() >>> manager.query.link('Skills').click() >>> manager.query.link('Layers').click() >>> print manager.query_all.css('h3')[1].text There are no layers. We'll add some layers. >>> manager.ui.layer.add('Cluster') >>> manager.ui.layer.add('Course') >>> manager.ui.layer.add('DutyArea') >>> manager.ui.layer.add('Competency') Now we see them appear in the container. >>> manager.query.link('School').click() >>> manager.query.link('Skills').click() >>> manager.query.link('Layers').click() >>> print manager.query_all.css('.data a').text Cluster Competency Course DutyArea Let's inspect the Cluster layer. We see the title field and the fact that there are no parents or children. >>> manager.query.link('Cluster').click() >>> print_layer_attrs() Title: Cluster >>> print manager.query_all.css('#parents p').text There are none. >>> print manager.query_all.css('#children p').text There are none. We'll click the link to add a child. We see that there are no children again, and we see the table of links for available children. Note the fact that Cluster is not in that list as it makes no sense to be one's own child. >>> manager.query.xpath('//a[@title="Edit children"]').click() >>> print manager.query.css('#current_table-ajax-current_table- h3').text There are none. >>> print manager.query_all.css('#available_table-ajax-available_table- a').text Competency Course DutyArea After clicking the button for adding the Course layer as a child we see that it appears in the current children table and is no longer in the available children table. >>> manager.query.xpath('//button[@name="add_item.course"]').click() >>> print manager.query_all.css('#current_table-ajax-current_table- a').text Course >>> print manager.query_all.css('#available_table-ajax-available_table- a').text Competency DutyArea We can remove it and put it back. >>> manager.query.xpath('//button[@name="remove_item.course"]').click() >>> print manager.query.css('#current_table-ajax-current_table- h3').text There are none. >>> print manager.query_all.css('#available_table-ajax-available_table- a').text Competency Course DutyArea >>> manager.query.xpath('//button[@name="add_item.course"]').click() >>> print manager.query_all.css('#current_table-ajax-current_table- a').text Course >>> print manager.query_all.css('#available_table-ajax-available_table- a').text Competency DutyArea We'll leave the edit children view and return the the layer view. Now we see that there are still no parents, but the Course child has been added. >>> manager.query.link('Done').click() >>> print manager.query_all.css('#parents p').text There are none. >>> print manager.query_all.css('#children .data a').text Course Let's visit the Course layer. We see the Cluster parent and the fact that there are no children. >>> manager.query.link('Course').click() >>> print manager.query_all.css('#parents .data a').text Cluster >>> print manager.query_all.css('#children p').text There are none. Clicking the button to edit the children we again see the empty current children table and the available children table. This time we see that not only is the Course not able to be its own child, but Cluster, its parent, is also excluded from the table. Adding Cluster to the children of Course would cause a CyclicRelationship exception, so it is not available. >>> manager.query.xpath('//a[@title="Edit children"]').click() >>> print manager.query.css('#current_table-ajax-current_table- h3').text There are none. >>> print manager.query_all.css('#available_table-ajax-available_table- a').text Competency DutyArea We'll add DutyArea as the child layer of Course. >>> manager.query.xpath('//button[@name="add_item.dutyarea"]').click() >>> print manager.query_all.css('#current_table-ajax-current_table- a').text DutyArea >>> print manager.query_all.css('#available_table-ajax-available_table- a').text Competency We'll leave the edit children view and return the the layer view. We still see Cluster parent, and now, the DutyArea child. >>> manager.query.link('Done').click() >>> print manager.query_all.css('#parents .data a').text Cluster >>> print manager.query_all.css('#children .data a').text DutyArea Finally, we'll add the Competency layer as the child of DutyArea. It's the only child available. >>> manager.query.link('DutyArea').click() >>> print manager.query_all.css('#parents .data a').text Course >>> print manager.query_all.css('#children p').text There are none. >>> manager.query.xpath('//a[@title="Edit children"]').click() >>> print manager.query.css('#current_table-ajax-current_table- h3').text There are none. >>> print manager.query_all.css('#available_table-ajax-available_table- a').text Competency >>> manager.query.xpath('//button[@name="add_item.competency"]').click() >>> print manager.query_all.css('#current_table-ajax-current_table- a').text Competency >>> print manager.query.css('#available_table-ajax-available_table- h3').text There are none. Node maintenance ---------------- Now we'll go to the nodes container view. We need to click the 'Search' tab to do that. We see there are no nodes yet. >>> manager.query.link('School').click() >>> manager.query.link('Skills').click() >>> manager.query.link('Search').click() >>> manager.query.button('Search').click() >>> print manager.query_all.xpath('//table//a').get_attribute('href') http://localhost/skills/Basic%20Al1 http://localhost/skills/Basic%20Ca3 http://localhost/skills/Continui2 http://localhost/skills/Continui4 We'll add some nodes for the Math cluster. >>> manager.ui.node.add('Math') >>> manager.ui.node.add('Algebra I') >>> manager.ui.node.add('Calculus') Let's look at the Math node. It has no parents, children, layers or skillsets. >>> manager.query.link('School').click() >>> manager.query.link('Skills').click() >>> manager.query.link('Search').click() >>> manager.query.button('Search').click() >>> manager.query.link('Math').click() >>> print_node_attrs() Description: Label: >>> print manager.query_all.css('#parents p')

    There are none.

    >>> print manager.query_all.css('#children p')

    There are none.

    >>> print manager.query_all.css('#layers p')

    There are none.

    >>> print manager.query_all.css('#skillsets p')

    There are none.

    We'll add the Cluster layer. In the edit layers view, we see the current layers and the available layers. >>> href = manager.query.xpath('//a[@title="Edit layers"]').get_attribute('href') >>> manager.open(href) >>> print manager.query.css('#current_table-ajax-current_table- h3').text There are none. >>> print manager.query_all.css('#available_table-ajax-available_table- a').text Cluster Competency Course DutyArea Adding the Cluster layer, we see how the tables change. >>> manager.query.xpath('//button[@name="add_item.cluster"]').click() >>> print manager.query_all.css('#current_table-ajax-current_table- a').text Cluster >>> print manager.query_all.css('#available_table-ajax-available_table- a').text Competency Course DutyArea We can remove it and put it back. >>> manager.query.xpath('//button[@name="remove_item.cluster"]').click() >>> print manager.query.css('#current_table-ajax-current_table- h3').text There are none. >>> print manager.query_all.css('#available_table-ajax-available_table- a').text Cluster Competency Course DutyArea >>> manager.query.xpath('//button[@name="add_item.cluster"]').click() >>> print manager.query_all.css('#current_table-ajax-current_table- a').text Cluster >>> print manager.query_all.css('#available_table-ajax-available_table- a').text Competency Course DutyArea Let's add the two child nodes to Math. When we enter the view for editing the child nodes, we see there are no children yet and the nodes that are available to be added as children. Note that the Math node cannot be its own child. >>> manager.query.link('Done').click() >>> href = manager.query.xpath('//a[@title="Edit child nodes"]').get_attribute('href') >>> manager.open(href) >>> print manager.query.css('#current_table-ajax-current_table- h3').text There are none. >>> print manager.query_all.css('#available_table-ajax-available_table- a').text Algebra I Calculus After clicking the button for adding the Algebra I node as a child we see that it appears in the child table and is no longer in the available children table. >>> manager.query.xpath('//button[@name="add_item.algebra-i"]').click() >>> print manager.query_all.css('#current_table-ajax-current_table- a').text Algebra I >>> print manager.query_all.css('#available_table-ajax-available_table- a').text Calculus We can remove it and put it back again. >>> manager.query.xpath('//button[@name="remove_item.algebra-i"]').click() >>> print manager.query.css('#current_table-ajax-current_table- h3').text There are none. >>> print manager.query_all.css('#available_table-ajax-available_table- a').text Algebra I Calculus >>> manager.query.xpath('//button[@name="add_item.algebra-i"]').click() >>> print manager.query_all.css('#current_table-ajax-current_table- a').text Algebra I >>> print manager.query_all.css('#available_table-ajax-available_table- a').text Calculus We'll add Calculus as a child as well. Then we see both children and the fact that no more children are available. >>> manager.query.xpath('//button[@name="add_item.calculus"]').click() >>> print manager.query_all.css('#current_table-ajax-current_table- a').text Algebra I Calculus >>> print manager.query.css('#available_table-ajax-available_table- h3').text There are none. Before returning to the Math node, let's drill down to one of the child nodes, Algebra I. We see that it has Math as a parent node. >>> manager.query.link('Algebra I').click() >>> print manager.query_all.css('#parents a').get_attribute('href') http://localhost/nodes/math We'll go edit its children and see that there are even more limits to adding children. Not only is Algebra I itself is off the list, but also its parent, Math. Adding Math as a child of Algebra I would cause a CyclicRelationship exception, so it isn't available. >>> href = manager.query.xpath('//a[@title="Edit child nodes"]').get_attribute('href') >>> manager.open(href) >>> print manager.query.css('#current_table-ajax-current_table- h3').text There are none. >>> print manager.query_all.css('#available_table-ajax-available_table- a').text Calculus We'll add it, even though it doesn't make any sense, and then remove it. >>> manager.query.xpath('//button[@name="add_item.calculus"]').click() >>> print manager.query_all.css('#current_table-ajax-current_table- a').text Calculus >>> print manager.query.css('#available_table-ajax-available_table- h3').text There are none. >>> manager.query.xpath('//button[@name="remove_item.calculus"]').click() >>> print manager.query.css('#current_table-ajax-current_table- h3').text There are none. >>> print manager.query_all.css('#available_table-ajax-available_table- a').text Calculus Let's return the the Math node view. We see that there are still no parents or skillsets, but we see the children and the layer. >>> manager.query.link('School').click() >>> manager.query.link('Skills').click() >>> manager.query.link('Search').click() >>> manager.query.button('Search').click() >>> manager.query.link('Math').click() >>> print manager.query_all.css('#parents p')

    There are none.

    >>> print manager.query_all.css('#skillsets p')

    There are none.

    >>> print manager.query_all.css('#children .data a').get_attribute('href') http://localhost/nodes/algebra-i http://localhost/nodes/calculus >>> print manager.query_all.css('#layers .data a').get_attribute('href') http://localhost/layers/cluster Finally, we'll go to the Algebra I node where it makes sense to add skillsets. We see that there are not any there yet. >>> manager.query.link('School').click() >>> manager.query.link('Skills').click() >>> manager.query.link('Search').click() >>> manager.query.button('Search').click() >>> manager.query.link('Algebra I').click() >>> print manager.query_all.css('#skillsets p')

    There are none.

    We'll go edit its skillsets. We see no current skillsets and the list of available ones. >>> href = manager.query.xpath('//a[@title="Edit skill sets"]').get_attribute('href') >>> manager.open(href) >>> print manager.query.css('#current_table-ajax-current_table- h3').text There are none. >>> print manager.query_all.css('#available_table-ajax-available_table- a').text Basic Algebra Basic Calculus Continuing Algebra Continuing Calculus Let's add the two algebra skillsets and see how the tables have changed. >>> manager.query.xpath('//button[@name="add_item.Basic Al1"]').click() >>> manager.query.xpath('//button[@name="add_item.Continui2"]').click() >>> print manager.query_all.css('#current_table-ajax-current_table- a').text Basic Algebra Continuing Algebra >>> print manager.query_all.css('#available_table-ajax-available_table- a').text Basic Calculus Continuing Calculus We'll add the other two skillsets and then remove them to see how the empty available skillsets table looks. >>> manager.query.xpath('//button[@name="add_item.Basic Ca3"]').click() >>> manager.query.xpath('//button[@name="add_item.Continui4"]').click() >>> print manager.query_all.css('#current_table-ajax-current_table- a').text Basic Algebra Basic Calculus Continuing Algebra Continuing Calculus >>> print manager.query.css('#available_table-ajax-available_table- h3').text There are none. >>> manager.query.xpath('//button[@name="remove_item.Basic Ca3"]').click() >>> manager.query.xpath('//button[@name="remove_item.Continui4"]').click() >>> print manager.query_all.css('#current_table-ajax-current_table- a').text Basic Algebra Continuing Algebra >>> print manager.query_all.css('#available_table-ajax-available_table- a').text Basic Calculus Continuing Calculus Finally, we return to the Algebra I node view and show how the skillsets are there now. >>> manager.query.link('Done').click() >>> print manager.query_all.css('#skillsets .data a').get_attribute('href') http://localhost/skills/Basic%20Al1 http://localhost/skills/Continui2 schooltool.cando-2.6.2/src/schooltool/cando/browser/stests/skill_events_importer.xls0000644000175000017500000002100012270520445032336 0ustar menesismenesis00000000000000ÐÏࡱá;þÿ  þÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿÿÿ þÿÿÿþÿÿÿ þÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿRoot Entryÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿ » Ìá°Áâ\pCalc B°aÀ=œ¯¼=@ 8Q@"·Ú1ÈÿArial1ÈÿArial1ÈÿArial1ÈÿArial1Èÿ¼Arial ¤GENERALà¤õÿ À àõÿ ôÀ àõÿ ôÀ àõÿ ôÀ àõÿ ôÀ àõÿ ôÀ àõÿ ôÀ àõÿ ôÀ àõÿ ôÀ àõÿ ôÀ àõÿ ôÀ àõÿ ôÀ àõÿ ôÀ àõÿ ôÀ àõÿ ôÀ ठÀ à+õÿ ðÀ à)õÿ ðÀ à,õÿ ðÀ à*õÿ ðÀ à õÿ ðÀ ठø ठøÀ “€ÿ“€ÿ“€ÿ“€ÿ“€ÿ“€ÿ`…¯ SkillSets…‰ SkillsŒ÷÷ÁÁTëbðZð 3 ð¿ À@@ñ  ÷üß?+IDTitle External IDLabel Fraktion1 Fractions10 Percents2Percents02 Arithmet3Arithmetic of Decimals SkillSet IDSkill ID Equivalent DescriptionRequiredRetired Add two 1Add two decimal numbers.01 Substract2Subtract two decimal numbers. Add a gr3Add a group of decimal numbers.03 Convert 5,Convert mixed numbers to improper fractions. Read and4Read and write fractions. Multiply1Multiply two fractions. Divide a2$Divide a fraction by a mixed number. Divide a3$Divide a fraction by a whole number. Write fr1Write fractions as percents.07 Write pe3"Write PERCENTS as decimal numbers. Write de2"Write decimal numbers as percents.ÿ +­ cc » Ì dü©ñÒMbP?_€%ÿÁ*+‚&C&P&C&Fƒ„&333333Ó?'333333Ó?(-Ø‚-Ø‚ã?)[°[°×?¡" dƒ,,š™™™™™¹?š™™™™™¹?U } A} Â} ” ÿý ý ý ý ý ý ý ý ý ý  ý  ý  ¾ ìPðHðð0ð( ð ð>¶@ggÿÿÿÿ » Ì dü©ñÒMbP?_€%ÿÁ*+‚&C&P&C&Fƒ„&333333Ó?'333333Ó?(-Ø‚-Ø‚ã?)[°[°×?¡" dƒ,,š™™™™™¹?š™™™™™¹?U } ” } Ù&} ” } ” } L } ”      ý  ý  ý ý ý ý ý ý ý ý  ý ý ý ÿÿý  ý ý ý  ÿÿý  ý ý ý ÿÿý ý ý ÿÿý ý ý ÿÿý ý ý ý ÿÿý ý  ý !ý  ÿÿý ý "ý #ý ÿÿý ý $ý %ý & ÿÿý ý 'ý (ý   ÿÿý ý )ý *ý  ÿÿìPðH ðð0ð( ð ð>¶@ggÿÿÿÿ þÿÿÿþÿÿÿþÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿ ÿÿÿÿÀFMicrosoft Excel 97-TabelleBiff8þÿà…ŸòùOh«‘+'³Ù0˜@H \ h t € Œéý Douglas 2@€HëÌ@@@€è›õÍÍþÿÕÍÕœ.“—+,ù®DÕÍÕœ.“—+,ù®\éýéýRoot EntryÿÿÿÿÿÿÿÿÀF @WorkbookÿÿÿÿgCompObjÿÿÿÿÿÿÿÿIOle ÿÿÿÿÿÿÿÿÿÿÿÿSummaryInformation(ÿÿÿÿÿÿÿÿÈDocumentSummaryInformation8ÿÿÿÿÿÿÿÿÿÿÿÿtÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿschooltool.cando-2.6.2/src/schooltool/cando/browser/stests/deprecate.txt0000644000175000017500000002203212270520445027666 0ustar menesismenesis00000000000000Test for the deprecate skills view ================================== We are going to test that when skillsets are deprecated, section gradebooks keep untouched. Helpers: >>> def print_checkbox(browser, cell): ... checked = browser.driver.execute_script( ... 'return $(arguments[0]).find("input:checked").length', cell) ... is_checked = bool(checked) ... return ['[ ]', '[X]'][is_checked] >>> def print_skills_table(browser): ... for row in browser.query_all.css('table tbody tr'): ... cells = browser.driver.execute_script( ... 'return $(arguments[0]).find("td")', row) ... if cells: ... title, required, deprecated = cells ... print '%s | %s | %s' % ( ... title.text, ... print_checkbox(browser, required), ... print_checkbox(browser, deprecated)) Log in as manager: >>> manager = browsers.manager >>> manager.ui.login('manager', 'schooltool') Set up persons: >>> manager.ui.person.add('Jeffrey', 'Elkner', 'jeffrey', 'pwd') >>> manager.ui.person.add('Camila', 'Cerna', 'camila', 'pwd') >>> manager.ui.person.add('Mario', 'Tejada', 'mario', 'pwd') Set up a section: >>> manager.ui.schoolyear.add('2013', '2013-01-01', '2013-12-31') >>> manager.ui.term.add('2013', '2013', '2013-01-01', '2013-12-31') >>> manager.ui.course.add('2013', 'Programming', course_id='PRO') >>> manager.ui.section.add('2013', '2013', 'Programming') >>> manager.ui.section.instructors.add('2013', '2013', 'Programming (1)', ... ['jeffrey']) >>> manager.ui.section.students.add('2013', '2013', 'Programming (1)', ... ['camila']) Set up skills: >>> manager.ui.layer.add('Course') >>> manager.ui.node.add('Programming', label='PRO') >>> manager.ui.skillset.add('Python Environment', '01') >>> manager.ui.skillset.add('Data Types, Statements, and Expressions', '02') >>> manager.ui.skillset.add('Errors', '03') >>> manager.ui.skill.add( ... 'Python Environment', ... 'Use the Python shell for interactive evaluation', ... '01') >>> manager.ui.skill.add( ... 'Python Environment', ... 'Make Python scripts with a text editor', ... '02', ... required=False) >>> manager.ui.skill.add( ... 'Data Types, Statements, and Expressions', ... 'Recognize int, float, str, list, tuple, and dict.', ... '03') >>> manager.ui.skill.add( ... 'Data Types, Statements, and Expressions', ... 'Use type(...) to determine the data type of a given value.', ... '04') >>> manager.ui.skill.add( ... 'Data Types, Statements, and Expressions', ... 'Use assignment statements to assign names (variables) to values.', ... '05') >>> manager.ui.skill.add( ... 'Data Types, Statements, and Expressions', ... 'Use the input function to read user input.', ... '06') >>> manager.ui.skill.add( ... 'Data Types, Statements, and Expressions', ... 'Define keyword and recognize keywords in Python.', ... '07') >>> manager.ui.skill.add( ... 'Data Types, Statements, and Expressions', ... 'Create legal variable names and recognize illegal ones.', ... '08', ... required=False) >>> manager.ui.skill.add( ... 'Errors', ... 'Recognize and differentiate among errors.', ... '09') >>> manager.ui.skill.add( ... 'Errors', ... 'Read and interpret stack traceback messages.', ... '10') >>> manager.query.link('Search').click() >>> manager.query.button('Search').click() >>> manager.query.link('Programming').click() >>> sel = '//h2[contains(@class, "ui-accordion-header")]' >>> accordion_headers = manager.query_all.xpath(sel) >>> sel = 'div.ui-accordion-content' >>> accordion_contents = manager.query_all.css(sel) >>> information_accordion_content = accordion_contents[0] >>> skillsets_accordion_header = accordion_headers[4] >>> skillsets_accordion_header.click() >>> skillsets_accordion_content = accordion_contents[4] >>> manager.wait_no(information_accordion_content.is_displayed) >>> sel = '//a[@title="Edit skill sets"]' >>> manager.query.xpath(sel).click() >>> manager.query.id('form-buttons-add').click() >>> manager.query.link('Done').click() >>> sel = '//h2[contains(@class, "ui-accordion-header")]' >>> accordion_headers = manager.query_all.xpath(sel) >>> sel = 'div.ui-accordion-content' >>> accordion_contents = manager.query_all.css(sel) >>> information_accordion_content = accordion_contents[0] >>> layers_accordion_header = accordion_headers[3] >>> layers_accordion_header.click() >>> layers_accordion_content = accordion_contents[3] >>> manager.wait_no(information_accordion_content.is_displayed) >>> sel = '//a[@title="Edit layers"]' >>> manager.query.xpath(sel).click() >>> manager.query.id('form-buttons-add').click() Assign the skills to the course: >>> manager.query.link('School').click() >>> manager.query.link('Courses').click() >>> manager.query.link('Batch Assign Skills').click() >>> manager.query.name('course_attr').ui.set_value('Course ID') >>> manager.query.name('layer').ui.set_value('Course') >>> manager.query.name('node_attr').ui.set_value('Label') >>> manager.query.name('SEARCH_BUTTON').click() >>> manager.query.name('ASSIGN_BUTTON').click() Check the course skills: >>> manager.query.link('Programming').click() >>> manager.query.link('Skills').click() >>> manager.query.link('Set Required / Deprecated').click() >>> course_skills_url = manager.url >>> print_skills_table(manager) 01: Use the Python shell for interactive evaluation | [X] | [ ] 02: Make Python scripts with a text editor | [ ] | [ ] 03: Recognize int, float, str, list, tuple, and dict. | [X] | [ ] 04: Use type(...) to determine the data type of a given value. | [X] | [ ] 05: Use assignment statements to assign names (variables) to values. | [X] | [ ] 06: Use the input function to read user input. | [X] | [ ] 07: Define keyword and recognize keywords in Python. | [X] | [ ] 08: Create legal variable names and recognize illegal ones. | [ ] | [ ] 09: Recognize and differentiate among errors. | [X] | [ ] 10: Read and interpret stack traceback messages. | [X] | [ ] Log in as instructor: >>> teacher = browsers.teacher >>> teacher.ui.login('jeffrey', 'pwd') >>> teacher.query.link('CanDo').click() Set a score and print the gradebook: >>> teacher.ui.gradebook.worksheet.score('Camila Cerna', '01', '3') >>> teacher.query.name('UPDATE_SUBMIT').click() >>> sel = 'a[title="01: Python Environment"]' >>> link = teacher.query.css(sel) >>> # XXX: fix this, use clicks instead of open >>> teacher.open(link.get_attribute('href')) >>> teacher.ui.gradebook.worksheet.pprint() +--------------------------+---------------------------------------------+------------+ | *01: Python Environment* | 02: Data Types, Statements, and Expressions | 03: Errors | +--------------------------+---------------------------------------------+------------+ +-----------+------------+----+----+ | Last Name | First Name | 01 | 02 | | | | 4 | 4 | +-----------+------------+----+----+ | Cerna | Camila | 3 | | +-----------+------------+----+----+ Now, let's deprecate the Python Environment skillset: >>> manager.query.link('School').click() >>> manager.query.link('Skills').click() >>> manager.query.link('Deprecate Skills').click() >>> manager.query.id('SEARCH').ui.set_value('Python Environment') >>> selector = '#retire-ajax-view-container-retire- table' >>> table = manager.query.css(selector) >>> manager.query.name('SEARCH_BUTTON').click() >>> manager.wait(lambda: table.expired) >>> manager.query.css('th.active input[type="checkbox"]').click() >>> manager.query.name('SAVE_RESULTS').click() >>> dialog = manager.query.css('.ui-dialog') >>> print dialog.query.css('.ui-dialog-title').text Changes saved Let's print the gradebook again: >>> sel = 'a[title="01: Python Environment"]' >>> link = teacher.query.css(sel) >>> # XXX: fix this, use clicks instead of open >>> teacher.open(link.get_attribute('href')) >>> teacher.ui.gradebook.worksheet.pprint() +--------------------------+---------------------------------------------+------------+ | *01: Python Environment* | 02: Data Types, Statements, and Expressions | 03: Errors | +--------------------------+---------------------------------------------+------------+ +-----------+------------+----+----+ | Last Name | First Name | 01 | 02 | | | | 4 | 4 | +-----------+------------+----+----+ | Cerna | Camila | 3 | | +-----------+------------+----+----+ schooltool.cando-2.6.2/src/schooltool/cando/browser/stests/layer_hierarchy.txt0000644000175000017500000000657012270520445031115 0ustar menesismenesis00000000000000Tests for the layer hierachy ============================ Log in as manager: >>> manager = browsers.manager >>> manager.ui.login('manager', 'schooltool') We'll add some layers. >>> manager.ui.layer.add('Layer1') >>> manager.ui.layer.add('Layer2') >>> manager.ui.layer.add('Layer3') >>> manager.ui.layer.add('Layer4') >>> manager.ui.layer.add('Layer5') >>> manager.ui.layer.add('Layer6') First time we go to the search, we see the layers sorted by title. Since we haven't linked any layers, parent to child, they are all orphans which will always come at the end, sorted by title. >>> manager.query.link('Search').click() >>> print manager.query_all.xpath('//input[@type="checkbox"]').get_attribute('value') layer1 layer2 layer3 layer4 layer5 layer6 __SKILLSET__ __SKILL__ __NOLAYER__ First, we'll make layer4 the parent of layer2. >>> manager.query.link('Layers').click() >>> manager.query.link('Layer4').click() >>> manager.query.xpath('//a[@title="Edit children"]').click() >>> manager.query.xpath('//button[@name="add_item.layer2"]').click() Now, when we go to the search, we see layer4, then its child, layer2, then the orphans, sorted by title. >>> manager.query.link('Search').click() >>> print manager.query_all.xpath('//input[@type="checkbox"]').get_attribute('value') layer4 layer2 layer1 layer3 layer5 layer6 __SKILLSET__ __SKILL__ __NOLAYER__ Next, we'll make layer2 the parent of layer5. >>> manager.query.link('Layers').click() >>> manager.query.link('Layer2').click() >>> manager.query.xpath('//a[@title="Edit children"]').click() >>> manager.query.xpath('//button[@name="add_item.layer5"]').click() Now, when we go to the search, we see layer4, then its child, layer2, then layer2's child, layer5, then the orphans, sorted by title. >>> manager.query.link('Search').click() >>> print manager.query_all.xpath('//input[@type="checkbox"]').get_attribute('value') layer4 layer2 layer5 layer1 layer3 layer6 __SKILLSET__ __SKILL__ __NOLAYER__ Now we'll get cute and add a parent to a layer that already has one. Layer6 will also have layer5 as a child. >>> manager.query.link('Layers').click() >>> manager.query.link('Layer6').click() >>> manager.query.xpath('//a[@title="Edit children"]').click() >>> manager.query.xpath('//button[@name="add_item.layer5"]').click() Now layer6 comes before layer5 in the sort. >>> manager.query.link('Search').click() >>> print manager.query_all.xpath('//input[@type="checkbox"]').get_attribute('value') layer4 layer2 layer6 layer5 layer1 layer3 __SKILLSET__ __SKILL__ __NOLAYER__ Finally, we make Layer3 the parent of layer6. >>> manager.query.link('Layers').click() >>> manager.query.link('Layer3').click() >>> manager.query.xpath('//a[@title="Edit children"]').click() >>> manager.query.xpath('//button[@name="add_item.layer6"]').click() We see the resulting sort of layers, no layer coming after its child, and we see our last remaining orphan at the end. >>> manager.query.link('Search').click() >>> print manager.query_all.xpath('//input[@type="checkbox"]').get_attribute('value') layer4 layer2 layer3 layer6 layer5 layer1 __SKILLSET__ __SKILL__ __NOLAYER__ schooltool.cando-2.6.2/src/schooltool/cando/browser/stests/course_nodes.xls0000644000175000017500000002500012270520445030407 0ustar menesismenesis00000000000000ÐÏࡱá;þÿ þÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿÿÿ þÿÿÿþÿÿÿþÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿRoot Entryÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿ » Ìá°Áâ\pCalc B°aÀ= œ¯¼=@ 8Ó@"·Ú1ÈÿArial1ÈÿArial1ÈÿArial1ÈÿArial1Èÿ¼Arial1Èÿ¼Arial ¤GENERAL¥ YYYY/MM/DDà¤õÿ À àõÿ ôÀ àõÿ ôÀ àõÿ ôÀ àõÿ ôÀ àõÿ ôÀ àõÿ ôÀ àõÿ ôÀ àõÿ ôÀ àõÿ ôÀ àõÿ ôÀ àõÿ ôÀ àõÿ ôÀ àõÿ ôÀ àõÿ ôÀ ठÀ à+õÿ ðÀ à)õÿ ðÀ à,õÿ ðÀ à*õÿ ðÀ à õÿ ðÀ ठø ठøÀ ॠüÀ ठø ठÀ “€ÿ“€ÿ“€ÿ“€ÿ“€ÿ“€ÿ`…Ï School Years…> Courses…Ù SkillSets…lSkills… ‹Nodes…¨ CourseNodesŒÁÁTë‚ðzð@3 ð¿ À@@ñ  ÷ü D,IDTitleStartEnd 2011-2012 School Year DescriptionLocal ID Government IDCreditsart_aArtLabel carpentry Carpentry electrical Electrical SkillSet IDSkill ID Equivalent External IDRequiredRetired Scoresystem hammering Hammeringextended-letter-gradepoundingPoundingwhackingWhackingpluggingPlugging DocumentsParentsLayers SkillSetsbuildingBuildingBuidling a housecarpentry, electricalYear ID Course IDNodesÿ ,¡ cc » Ì dü©ñÒMbP?_€%ÿÁ*+‚# &C&"Times New Roman,Normal"&12&A(%&C&"Times New Roman,Normal"&12Page &Pƒ„&333333é?'333333é?(ƒ-Ø‚-Øð?)ƒ-Ø‚-Øð?¡"d,,333333é?333333é?U } ” ÿÿý ý ý ý ý ý ½J}ÊìPðHðð0ð( ð ð>¶@ggÿÿÿÿ » Ì dü©ñÒMbP?_€%ÿÁ*+‚# &C&"Times New Roman,Normal"&12&A(%&C&"Times New Roman,Normal"&12Page &Pƒ„&333333é?'333333é?(ƒ-Ø‚-Øð?)ƒ-Ø‚-Øð?¡"d,,333333é?333333é?U } ” ÿÿý ý ý ý ý ý ý  ý ý  ý  ìPðH ðð0ð( ð ð>¶@ggÿÿÿÿ » Ì dü©ñÒMbP?_€%ÿÁ*+‚# &C&"Times New Roman,Normal"&12&A(%&C&"Times New Roman,Normal"&12Page &Pƒ„&333333é?'333333é?(ƒ-Ø‚-Øð?)ƒ-Ø‚-Øð?¡"d,,333333é?333333é?U } ” ÿÿÿý ý ý ý  ý  ý ý ý ìPðH0ð ð0ð( ð ð >¶@ggÿÿÿÿ » Ì dü©ñÒMbP?_€%ÿÁ*+‚# &C&"Times New Roman,Normal"&12&A(%&C&"Times New Roman,Normal"&12Page &Pƒ„&333333é?'333333é?(ƒ-Ø‚-Øð?)ƒ-Ø‚-Øð?¡"d,,333333é?333333é?U } ” } %} x} ” } J} ”   ÿ ÿ ÿ ÿ ÿý ý ý ý ý ý ý  ý ý ý ý  ý ý ý  ý  ý ý ¾ ý  ý  ý ý ý  ý ý ý  ý  ìPðH@ðð0ð( ð ð>¶@ggÿÿÿÿ » Ì dü©ñÒMbP?_€%ÿÁ*+‚# &C&"Times New Roman,Normal"&12&A(%&C&"Times New Roman,Normal"&12Page &Pƒ„&333333é?'333333é?(ƒ-Ø‚-Øð?)ƒ-Ø‚-Øð?¡"d,,333333é?333333é?U } ” } o} q } a}  } ” } ˜} ” ÿÿý ý ý ý  ý !ý "ý #ý $ý %ý &ý 'ý (ìPðHPðð0ð( ð ð>¶@ggÿÿÿÿ » Ì dü©ñÒMbP?_€%ÿÁ*+‚&C&P&C&Fƒ„&333333Ó?'333333Ó?(-Ø‚-Ø‚ã?)[°[°×?¡" dƒ,,š™™™™™¹?š™™™™™¹?U } ” ÿÿý )ý *ý +ý ý  ý %ìPðH`ðð0ð( ð ð>¶@ggÿÿÿÿ þÿÿÿþÿÿÿþÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿ ÿÿÿÿÀFMicrosoft Excel 97-TabelleBiff8þÿà…ŸòùOh«‘+'³Ù0˜@H \ h t € Œéý Alan Elkner13@Ñ”ê@@@€®pšÍþÿÕÍÕœ.“—+,ù®DÕÍÕœ.“—+,ù®\éýéýRoot EntryÿÿÿÿÿÿÿÿÀF@WorkbookÿÿÿÿÄCompObjÿÿÿÿÿÿÿÿIOle ÿÿÿÿÿÿÿÿÿÿÿÿSummaryInformation(ÿÿÿÿÿÿÿÿÈDocumentSummaryInformation8ÿÿÿÿÿÿÿÿÿÿÿÿtÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿschooltool.cando-2.6.2/src/schooltool/cando/browser/stests/iep.txt0000644000175000017500000004125312270520445026515 0ustar menesismenesis00000000000000IEP tests ========= Helpers: >>> def query_person_links(browser): ... sel = '.refine .content' ... person_links = browser.query_all.css(sel)[0] ... return [link.text for link in person_links.query_all.tag('a')] >>> def print_details(browser): ... sel = '.form-fields tbody tr' ... for row in browser.query_all.css(sel): ... label, value = row.query_all.tag('td') ... print '%s: %s' % (label.text, value.text) >>> def print_section_skills(browser): ... sel = 'table tbody tr' ... for row in browser.query_all.css(sel): ... tds = browser.driver.execute_script( ... 'return $(arguments[0]).find("td")', row) ... if tds: ... label, title = tds ... skill_type = 'required' ... klass = title.get_attribute('class') ... if klass: ... skill_type = klass ... print '%s, %s, %s' % (label.text, title.text, skill_type) >>> def print_section_form_skills(browser): ... sel = 'table tbody tr' ... for row in browser.query_all.css(sel): ... tds = browser.driver.execute_script( ... 'return $(arguments[0]).find("td")', row) ... if tds: ... iep, label, title = tds ... checkbox, checked = browser.driver.execute_script('return [$(arguments[0]).find("input"), $(arguments[0]).find("input:checked")]', iep) ... if checkbox: ... checkbox = ['[ ]', '[X]'][bool(checked)] ... skill_type = 'required' ... klass = title.get_attribute('class') ... if klass: ... skill_type = klass ... print '%s, %s, %s, %s' % (checkbox or '', label.text, ... title.text, skill_type) >>> def print_gradebook_skills(browser): ... sel = 'table.grade-student tbody tr' ... for row in browser.query_all.css(sel): ... tds = browser.driver.execute_script( ... 'return $(arguments[0]).find("td")', row) ... if tds: ... title, score = tds ... skill_type = 'required' ... klass = title.get_attribute('class') ... if klass: ... skill_type = klass ... print '%s, %s' % (title.text, skill_type) Log in as manager: >>> manager = browsers.manager >>> manager.ui.login('manager', 'schooltool') Set up persons: >>> manager.ui.person.add('Jeffrey', 'Elkner', 'jeffrey', 'pwd') >>> jeffrey_url = manager.url >>> manager.ui.person.add('Camila', 'Cerna', 'camila', 'pwd') >>> camila_url = manager.url >>> manager.ui.person.add('Liliana', 'Vividor', 'liliana', 'pwd') >>> manager.ui.person.add('Mario', 'Tejada', 'mario', 'pwd') Set up two sections: >>> manager.ui.schoolyear.add('2012', '2012-01-01', '2012-12-31') >>> manager.ui.term.add('2012', '2012', '2012-01-01', '2012-12-31') >>> manager.ui.course.add('2012', 'Programming', course_id='PRO') >>> manager.ui.course.add('2012', 'Math') >>> manager.ui.section.add('2012', '2012', 'Programming') >>> manager.ui.section.instructors.add('2012', '2012', 'Programming (1)', ... ['jeffrey']) >>> manager.ui.section.students.add('2012', '2012', 'Programming (1)', ... ['camila', 'liliana', 'mario']) >>> manager.ui.section.add('2012', '2012', 'Math') >>> manager.ui.section.instructors.add('2012', '2012', 'Math (2)', ... ['jeffrey']) >>> manager.ui.section.students.add('2012', '2012', 'Math (2)', ... ['camila', 'liliana', 'mario']) Set up skills: >>> manager.ui.layer.add('Course') >>> manager.ui.node.add('Programming', label='PRO') >>> manager.ui.skillset.add('Python Environment', '01') >>> manager.ui.skillset.add('Data Types, Statements, and Expressions', '02') >>> manager.ui.skillset.add('Errors', '03') >>> manager.ui.skillset.add('Strings', '04') >>> manager.ui.skill.add( ... 'Python Environment', ... 'Use the Python shell for interactive evaluation', ... '01') >>> manager.ui.skill.add( ... 'Python Environment', ... 'Make Python scripts with a text editor', ... '02', ... required=False) >>> manager.ui.skill.add( ... 'Data Types, Statements, and Expressions', ... 'Recognize int, float, str, list, tuple, and dict.', ... '03') >>> manager.ui.skill.add( ... 'Data Types, Statements, and Expressions', ... 'Use type(...) to determine the data type of a given value.', ... '04') >>> manager.ui.skill.add( ... 'Data Types, Statements, and Expressions', ... 'Use assignment statements to assign names (variables) to values.', ... '05') >>> manager.ui.skill.add( ... 'Data Types, Statements, and Expressions', ... 'Use the input function to read user input.', ... '06') >>> manager.ui.skill.add( ... 'Data Types, Statements, and Expressions', ... 'Define keyword and recognize keywords in Python.', ... '07') >>> manager.ui.skill.add( ... 'Data Types, Statements, and Expressions', ... 'Create legal variable names and recognize illegal ones.', ... '08', ... required=False) >>> manager.ui.skill.add( ... 'Errors', ... 'Recognize and differentiate among errors.', ... '09') >>> manager.ui.skill.add( ... 'Errors', ... 'Read and interpret stack traceback messages.', ... '10') >>> manager.ui.skill.add( ... 'Strings', ... 'Create string literals with single, double, and triple quotes.', ... '11') >>> manager.ui.skill.add( ... 'Strings', ... 'Use the len() function to return the length of a string.', ... '12') >>> manager.ui.skill.add( ... 'Strings', ... 'Use the find(...) method to locate substrings in a string.', ... '13', ... required=False) >>> manager.ui.skill.add( ... 'Strings', ... 'Use the split() method to break a string into a list.', ... '14', ... required=False) >>> manager.query.link('Search').click() >>> manager.query.button('Search').click() >>> manager.query.link('Programming').click() >>> sel = '//h2[contains(@class, "ui-accordion-header")]' >>> accordion_headers = manager.query_all.xpath(sel) >>> sel = 'div.ui-accordion-content' >>> accordion_contents = manager.query_all.css(sel) >>> information_accordion_content = accordion_contents[0] >>> skillsets_accordion_header = accordion_headers[4] >>> skillsets_accordion_header.click() >>> skillsets_accordion_content = accordion_contents[4] >>> manager.wait_no(information_accordion_content.is_displayed) >>> sel = '//a[@title="Edit skill sets"]' >>> manager.query.xpath(sel).click() >>> manager.query.id('form-buttons-add').click() >>> manager.query.link('Done').click() >>> sel = '//h2[contains(@class, "ui-accordion-header")]' >>> accordion_headers = manager.query_all.xpath(sel) >>> sel = 'div.ui-accordion-content' >>> accordion_contents = manager.query_all.css(sel) >>> information_accordion_content = accordion_contents[0] >>> layers_accordion_header = accordion_headers[3] >>> layers_accordion_header.click() >>> layers_accordion_content = accordion_contents[3] >>> manager.wait_no(information_accordion_content.is_displayed) >>> sel = '//a[@title="Edit layers"]' >>> manager.query.xpath(sel).click() >>> manager.query.id('form-buttons-add').click() Assign the skills to the course: >>> manager.query.link('School').click() >>> manager.query.link('Courses').click() >>> manager.query.link('Batch Assign Skills').click() >>> manager.query.name('course_attr').ui.set_value('Course ID') >>> manager.query.name('layer').ui.set_value('Course') >>> manager.query.name('node_attr').ui.set_value('Label') >>> manager.query.name('SEARCH_BUTTON').click() >>> manager.query.name('ASSIGN_BUTTON').click() The IEP functionality is only available for persons who are enrolled as students in a section: >>> manager.open(jeffrey_url) >>> 'IEP' in query_person_links(manager) False >>> manager.open(camila_url) >>> 'IEP' in query_person_links(manager) True Let's activate IEP for Camila: >>> manager.query.link('IEP').click() >>> print manager.query.css('.page .header h1').text Camila Cerna >>> print manager.query.css('.page .header h2').text Individualized Educational Plan >>> print_details(manager) Active: No Description: >>> sel = 'a[title="Edit this plan information"]' >>> manager.query.css(sel).click() >>> manager.query.id('form-widgets-active-0').click() >>> frame = manager.query.tag('iframe') >>> manager.driver.switch_to_frame(frame.get_attribute('id')) >>> manager.driver.execute_script("FCKeditorAPI.Instances['form-widgets-description'].SetHTML('This is Camilas IEP')") >>> manager.driver.switch_to_default_content() >>> manager.query.id('form-buttons-add').click() >>> print_details(manager) Active: Yes Description: This is Camilas IEP We have access to her sections to customize the required skills for the section and change them to be optional just for her: >>> for link in manager.query_all.css('.info-block .leaf_url'): ... print link.text Math (2) Programming (1) >>> manager.query.link('Programming (1)').click() >>> print manager.query.css('.page .header h1').text Camila Cerna >>> print manager.query.css('.page .header h2').text IEP Skills for Programming (1) >>> print_section_skills(manager) 01, Use the Python shell for interactive evaluation, required 02, Make Python scripts with a text editor, optional 03, Recognize int, float, str, list, tuple, and dict., required 04, Use type(...) to determine the data type of a given value., required 05, Use assignment statements to assign names (variables) to values., required 06, Use the input function to read user input., required 07, Define keyword and recognize keywords in Python., required 08, Create legal variable names and recognize illegal ones., optional 09, Recognize and differentiate among errors., required 10, Read and interpret stack traceback messages., required 11, Create string literals with single, double, and triple quotes., required 12, Use the len() function to return the length of a string., required 13, Use the find(...) method to locate substrings in a string., optional 14, Use the split() method to break a string into a list., optional Let's change some of the required skills to optional: >>> sel = '''a[title="Edit student's IEP skills"]''' >>> manager.query.css(sel).click() >>> print_section_form_skills(manager) [ ], 01, Use the Python shell for interactive evaluation, required , 02, Make Python scripts with a text editor, optional [ ], 03, Recognize int, float, str, list, tuple, and dict., required [ ], 04, Use type(...) to determine the data type of a given value., required [ ], 05, Use assignment statements to assign names (variables) to values., required [ ], 06, Use the input function to read user input., required [ ], 07, Define keyword and recognize keywords in Python., required , 08, Create legal variable names and recognize illegal ones., optional [ ], 09, Recognize and differentiate among errors., required [ ], 10, Read and interpret stack traceback messages., required [ ], 11, Create string literals with single, double, and triple quotes., required [ ], 12, Use the len() function to return the length of a string., required , 13, Use the find(...) method to locate substrings in a string., optional , 14, Use the split() method to break a string into a list., optional >>> sel = 'iep_section_skills.iep.Python E1.Use the 1' >>> manager.query.id(sel).click() >>> sel = 'iep_section_skills.iep.Data Typ2.Use the 4' >>> manager.query.id(sel).click() >>> sel = 'iep_section_skills.iep.Errors-3.Recogniz1' >>> manager.query.id(sel).click() >>> manager.query.name('SAVE').click() After saving the changes, the IEP skills are shown differently: >>> print_section_skills(manager) 01, Use the Python shell for interactive evaluation, iep 02, Make Python scripts with a text editor, optional 03, Recognize int, float, str, list, tuple, and dict., required 04, Use type(...) to determine the data type of a given value., required 05, Use assignment statements to assign names (variables) to values., required 06, Use the input function to read user input., iep 07, Define keyword and recognize keywords in Python., required 08, Create legal variable names and recognize illegal ones., optional 09, Recognize and differentiate among errors., iep 10, Read and interpret stack traceback messages., required 11, Create string literals with single, double, and triple quotes., required 12, Use the len() function to return the length of a string., required 13, Use the find(...) method to locate substrings in a string., optional 14, Use the split() method to break a string into a list., optional The IEP skills are also shown differently in the edit form: >>> sel = '''a[title="Edit student's IEP skills"]''' >>> manager.query.css(sel).click() >>> print_section_form_skills(manager) [X], 01, Use the Python shell for interactive evaluation, iep , 02, Make Python scripts with a text editor, optional [ ], 03, Recognize int, float, str, list, tuple, and dict., required [ ], 04, Use type(...) to determine the data type of a given value., required [ ], 05, Use assignment statements to assign names (variables) to values., required [X], 06, Use the input function to read user input., iep [ ], 07, Define keyword and recognize keywords in Python., required , 08, Create legal variable names and recognize illegal ones., optional [X], 09, Recognize and differentiate among errors., iep [ ], 10, Read and interpret stack traceback messages., required [ ], 11, Create string literals with single, double, and triple quotes., required [ ], 12, Use the len() function to return the length of a string., required , 13, Use the find(...) method to locate substrings in a string., optional , 14, Use the split() method to break a string into a list., optional >>> manager.query.name('CANCEL').click() Log in as instructor: >>> teacher = browsers.teacher >>> teacher.ui.login('jeffrey', 'pwd') >>> teacher.query.link('CanDo').click() Students with IEP activated are shown differently in the skills gradebook: >>> sel = '#students-part tbody tr td:first-child' >>> for td in teacher.query_all.css(sel): ... print '%s%s' % (td.query.css('a.popup_link').get_attribute('title'), ... ['', ' (IEP)'][bool(td.get_attribute('class'))]) Camila Cerna (IEP) Mario Tejada Liliana Vividor and the IEP information is shown in the Score student view: >>> sel = '#students-part tbody td:first-child ul.popup_menu' >>> camila_menu, mario_menu, liliana_menu = teacher.query_all.css(sel) >>> teacher.query.link('Cerna').click() >>> camila_menu.query.link('Score').click() >>> sel = '.additional .content:first-child h3' >>> print teacher.query.css(sel).text IEP Information >>> print_details(teacher) Description: This is Camilas IEP >>> print_gradebook_skills(teacher) 01: Use the Python shell for interactive evaluation, iep 02: Make Python scripts with a text editor, optional 03: Recognize int, float, str, list, tuple, and dict., required 04: Use type(...) to determine the data type of a given value., required 05: Use assignment statements to assign names (variables) to values., required 06: Use the input function to read user input., iep 07: Define keyword and recognize keywords in Python., required 08: Create legal variable names and recognize illegal ones., optional 09: Recognize and differentiate among errors., iep 10: Read and interpret stack traceback messages., required 11: Create string literals with single, double, and triple quotes., required 12: Use the len() function to return the length of a string., required 13: Use the find(...) method to locate substrings in a string., optional 14: Use the split() method to break a string into a list., optional schooltool.cando-2.6.2/src/schooltool/cando/browser/stests/delete_current_worksheet.txt0000644000175000017500000002202712270520445033035 0ustar menesismenesis00000000000000Test for current worksheet functionality ======================================== We'll check what happens to the gradebook when the current skillset for the user is deleted. Log in as manager: >>> manager = browsers.manager >>> manager.ui.login('manager', 'schooltool') Set up persons: >>> manager.ui.person.add('Jeffrey', 'Elkner', 'jeffrey', 'pwd') >>> manager.ui.person.add('Camila', 'Cerna', 'camila', 'pwd') >>> manager.ui.person.add('Liliana', 'Vividor', 'liliana', 'pwd') >>> manager.ui.person.add('Mario', 'Tejada', 'mario', 'pwd') Set up a section: >>> manager.ui.schoolyear.add('2012', '2012-01-01', '2012-12-31') >>> manager.ui.term.add('2012', '2012', '2012-01-01', '2012-12-31') >>> manager.ui.course.add('2012', 'Programming', course_id='PRO') >>> manager.ui.section.add('2012', '2012', 'Programming') >>> manager.ui.section.instructors.add('2012', '2012', 'Programming (1)', ... ['jeffrey']) >>> manager.ui.section.students.add('2012', '2012', 'Programming (1)', ... ['camila', 'liliana', 'mario']) Set up skills: >>> manager.ui.layer.add('Course') >>> manager.ui.node.add('Programming', label='PRO') >>> manager.ui.skillset.add('Python Environment', '01') >>> manager.ui.skillset.add('Data Types, Statements, and Expressions', '02') >>> manager.ui.skillset.add('Errors', '03') >>> manager.ui.skillset.add('Strings', '04') >>> manager.ui.skill.add( ... 'Python Environment', ... 'Use the Python shell for interactive evaluation', ... '01') >>> manager.ui.skill.add( ... 'Python Environment', ... 'Make Python scripts with a text editor', ... '02', ... required=False) >>> manager.ui.skill.add( ... 'Data Types, Statements, and Expressions', ... 'Recognize int, float, str, list, tuple, and dict.', ... '03') >>> manager.ui.skill.add( ... 'Data Types, Statements, and Expressions', ... 'Use type(...) to determine the data type of a given value.', ... '04') >>> manager.ui.skill.add( ... 'Data Types, Statements, and Expressions', ... 'Use assignment statements to assign names (variables) to values.', ... '05') >>> manager.ui.skill.add( ... 'Data Types, Statements, and Expressions', ... 'Use the input function to read user input.', ... '06') >>> manager.ui.skill.add( ... 'Data Types, Statements, and Expressions', ... 'Define keyword and recognize keywords in Python.', ... '07') >>> manager.ui.skill.add( ... 'Data Types, Statements, and Expressions', ... 'Create legal variable names and recognize illegal ones.', ... '08', ... required=False) >>> manager.ui.skill.add( ... 'Errors', ... 'Recognize and differentiate among errors.', ... '09') >>> manager.ui.skill.add( ... 'Errors', ... 'Read and interpret stack traceback messages.', ... '10') >>> manager.ui.skill.add( ... 'Strings', ... 'Create string literals with single, double, and triple quotes.', ... '11') >>> manager.ui.skill.add( ... 'Strings', ... 'Use the len() function to return the length of a string.', ... '12') >>> manager.ui.skill.add( ... 'Strings', ... 'Use the find(...) method to locate substrings in a string.', ... '13', ... required=False) >>> manager.ui.skill.add( ... 'Strings', ... 'Use the split() method to break a string into a list.', ... '14', ... required=False) >>> manager.query.link('Search').click() >>> manager.query.button('Search').click() >>> manager.query.link('Programming').click() >>> sel = '//h2[contains(@class, "ui-accordion-header")]' >>> accordion_headers = manager.query_all.xpath(sel) >>> sel = 'div.ui-accordion-content' >>> accordion_contents = manager.query_all.css(sel) >>> information_accordion_content = accordion_contents[0] >>> skillsets_accordion_header = accordion_headers[4] >>> skillsets_accordion_header.click() >>> skillsets_accordion_content = accordion_contents[4] >>> manager.wait_no(information_accordion_content.is_displayed) >>> sel = '//a[@title="Edit skill sets"]' >>> manager.query.xpath(sel).click() >>> manager.query.id('form-buttons-add').click() >>> manager.query.link('Done').click() >>> sel = '//h2[contains(@class, "ui-accordion-header")]' >>> accordion_headers = manager.query_all.xpath(sel) >>> sel = 'div.ui-accordion-content' >>> accordion_contents = manager.query_all.css(sel) >>> information_accordion_content = accordion_contents[0] >>> layers_accordion_header = accordion_headers[3] >>> layers_accordion_header.click() >>> layers_accordion_content = accordion_contents[3] >>> manager.wait_no(information_accordion_content.is_displayed) >>> sel = '//a[@title="Edit layers"]' >>> manager.query.xpath(sel).click() >>> manager.query.id('form-buttons-add').click() Assign the skills to the course: >>> manager.query.link('School').click() >>> manager.query.link('Courses').click() >>> manager.query.link('Batch Assign Skills').click() >>> manager.query.name('course_attr').ui.set_value('Course ID') >>> manager.query.name('layer').ui.set_value('Course') >>> manager.query.name('node_attr').ui.set_value('Label') >>> manager.query.name('SEARCH_BUTTON').click() >>> manager.query.name('ASSIGN_BUTTON').click() Log in as instructor: >>> teacher = browsers.teacher >>> teacher.ui.login('jeffrey', 'pwd') >>> teacher.query.link('CanDo').click() Go to the Errors worksheet: >>> sel = 'a[title="03: Errors"]' >>> link = teacher.query.css(sel) >>> # XXX: fix this, use clicks instead of open >>> teacher.open(link.get_attribute('href')) >>> teacher.ui.gradebook.worksheet.pprint() +------------------------+---------------------------------------------+--------------+-------------+ | 01: Python Environment | 02: Data Types, Statements, and Expressions | *03: Errors* | 04: Strings | +------------------------+---------------------------------------------+--------------+-------------+ +-----------+------------+----+----+ | Last Name | First Name | 09 | 10 | | | | 4 | 4 | +-----------+------------+----+----+ | Cerna | Camila | | | | Tejada | Mario | | | | Vividor | Liliana | | | +-----------+------------+----+----+ Log in as student: >>> student = browsers.student >>> student.ui.login('camila', 'pwd') >>> student.query.link('CanDo').click() Go to the Errors worksheet: >>> sel = 'a[title="03: Errors"]' >>> link = student.query.css(sel) >>> # XXX: fix this, use clicks instead of open >>> student.open(link.get_attribute('href')) >>> sel = '.third-nav li a' >>> for a in student.query_all.css(sel): ... print a.get_attribute('title') 01: Python Environment 02: Data Types, Statements, and Expressions 03: Errors 04: Strings >>> sel = 'table tbody tr td:first-child' >>> for td in student.query_all.css(sel): ... print td.text 09: Recognize and differentiate among errors. 10: Read and interpret stack traceback messages. Let's delete the worksheet from the course skills: >>> manager.query.link('School').click() >>> manager.query.link('Courses').click() >>> manager.query.link('Programming').click() >>> manager.query.link('Skills').click() >>> manager.query.link('Remove Skills').click() >>> manager.query.css('input[value="Errors-3"]').click() >>> manager.query.name('SUBMIT_BUTTON').click() Let's check the new current worksheet for the teacher: >>> teacher.query.link('CanDo').click() >>> teacher.ui.gradebook.worksheet.pprint() +--------------------------+---------------------------------------------+-------------+ | *01: Python Environment* | 02: Data Types, Statements, and Expressions | 04: Strings | +--------------------------+---------------------------------------------+-------------+ +-----------+------------+----+----+ | Last Name | First Name | 01 | 02 | | | | 4 | 4 | +-----------+------------+----+----+ | Cerna | Camila | | | | Tejada | Mario | | | | Vividor | Liliana | | | +-----------+------------+----+----+ Let's check the new current worksheet for the student: >>> student.query.link('CanDo').click() >>> sel = '.third-nav li a' >>> for a in student.query_all.css(sel): ... print a.get_attribute('title') 01: Python Environment 02: Data Types, Statements, and Expressions 04: Strings >>> sel = 'table tbody tr td:first-child' >>> for td in student.query_all.css(sel): ... print td.text 01: Use the Python shell for interactive evaluation 02: Make Python scripts with a text editor schooltool.cando-2.6.2/src/schooltool/cando/browser/stests/sample_data.xls0000644000175000017500000002500012270520445030171 0ustar menesismenesis00000000000000ÐÏࡱá;þÿ þÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿÿÿ þÿÿÿþÿÿÿþÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿRoot Entryÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿ » Ìá°Áâ\pCalc B°aÀ= œ¯¼=@ 8ª@"·Ú1ÈÿArial1ÈÿArial1ÈÿArial1ÈÿArial1Èÿ¼Arial1ÈÿArial ¤GENERAL¥ YYYY/MM/DDà¤õÿ À àõÿ ôÀ àõÿ ôÀ àõÿ ôÀ àõÿ ôÀ àõÿ ôÀ àõÿ ôÀ àõÿ ôÀ àõÿ ôÀ àõÿ ôÀ àõÿ ôÀ àõÿ ôÀ àõÿ ôÀ àõÿ ôÀ àõÿ ôÀ ठÀ à+õÿ ðÀ à)õÿ ðÀ à,õÿ ðÀ à*õÿ ðÀ à õÿ ðÀ ठø ठøÀ ॠüÀ ठÀ ठøÀ “€ÿ“€ÿ“€ÿ“€ÿ“€ÿ“€ÿ`…o SkillSets…ä Skills…/Layers…M Documents… ÂNodesŒÁÁTëzðrð83 ð¿ À@@ñ  ÷üÐ\8IDTitle DescriptionLabel carpentry Carpentryext_carp Carp label SkillSet IDSkill ID Equivalent External IDRequiredRetired Score System hammering HammeringThis is hammering.poundingPoundingext_123 letter-gradewhackingWhackingpounding, hammeringWhacking desc.passfailParentscraftCraftbranchBranchtopicTopic branch, craftskillset Competenciesskill Competency Hierarchysample Sample DocDesc.%craft, branch, topic, skillset, skill DocumentsLayers SkillSetsCarpentry has a description.carpcreativeCreativecreat conventional Conventional topic, branchcreative, conventionalÿ 8| cc » Ì dü©ñÒMbP?_€%ÿÁ*+‚# &C&"Times New Roman,Normal"&12&A(%&C&"Times New Roman,Normal"&12Page &Pƒ„&333333é?'333333é?(ƒ-Ø‚-Øð?)ƒ-Ø‚-Øð?¡"d,,333333é?333333é?U } ” ÿÿý ý ý ý ý ý ý ý ìPðHðð0ð( ð ð>¶@ggÿÿÿÿ » Ì dü©ñÒMbP?_€%ÿÁ*+‚# &C&"Times New Roman,Normal"&12&A(%&C&"Times New Roman,Normal"&12Page &Pƒ„&333333é?'333333é?(ƒ-Ø‚-Øð?)ƒ-Ø‚-Øð?¡"d,,333333é?333333é?U } ” } %} x} ” } e } ”   ÿ ÿ ÿ ÿý ý  ý ý  ý ý  ý ý  ý  ý ý ý ý ý ý ÿÿý ý ý ý ÿÿÿÿý  ý ý ý ý ÿÿý  ìPðH ðð0ð( ð ð>¶@  ggÿÿÿÿ » Ì dü©ñÒMbP?_€%ÿÁ*+‚&C&P&C&Fƒ„&333333Ó?'333333Ó?(-Ø‚-Ø‚ã?)[°[°×?¡" dƒ,,š™™™™™¹?š™™™™™¹?U } ” } Ë} ” ÿÿÿÿÿÿý ý ý ý ý ý ý ý ý  ý !ý "ý #ý $ý %ý &ìPðH0ð ð0ð( ð ð >¶@ggÿÿÿÿ » Ì dü©ñÒMbP?_€%ÿÁ*+‚# &C&"Times New Roman,Normal"&12&A(%&C&"Times New Roman,Normal"&12Page &Pƒ„&333333é?'333333é?(ƒ-Ø‚-Øð?)ƒ-Ø‚-Øð?¡"d,,333333é?333333é?U } ” ÿÿý ý ý ý 'ý (ý )ý *ý +ìPðH@ðð0ð( ð ð>¶@ggÿÿÿÿ » Ì dü©ñÒMbP?_€%ÿÁ*+‚# &C&"Times New Roman,Normal"&12&A(%&C&"Times New Roman,Normal"&12Page &Pƒ„&333333é?'333333é?(ƒ-Ø‚-Øð?)ƒ-Ø‚-Øð?¡"d,,333333é?333333é?U } ” } o} q } a}  } ” ÿÿÿÿÿÿÿý ý ý ý ý ,ý ý -ý .ý ý ý /ý 0ý (ý ý ý 1ý 2ý 3ý ý ý 4ý 5ý ý ý ý ý 1ý  ý ý ý 4ý 6ý ý ý 7ý  ìPðHPðð0ð( ð ð>¶@ggÿÿÿÿ þÿÿÿþÿÿÿþÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿ ÿÿÿÿÀFMicrosoft Excel 97-TabelleBiff8þÿà…ŸòùOh«‘+'³Ù0˜@H \ h t € Œéý Alan Elkner58@šé‚B@@@€šÒ{žìÍþÿÕÍÕœ.“—+,ù®DÕÍÕœ.“—+,ù®\éýéýRoot EntryÿÿÿÿÿÿÿÿÀF@WorkbookÿÿÿÿsCompObjÿÿÿÿÿÿÿÿIOle ÿÿÿÿÿÿÿÿÿÿÿÿSummaryInformation(ÿÿÿÿÿÿÿÿÈDocumentSummaryInformation8ÿÿÿÿÿÿÿÿÿÿÿÿtÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿschooltool.cando-2.6.2/src/schooltool/cando/browser/stests/skill_events.txt0000644000175000017500000003211312270520445030435 0ustar menesismenesis00000000000000Test for the skill event subscribers ==================================== We'll test that changes in the skill document tree propagate to course skills and section skills, so they're visible in the gradebook. See: https://bugs.launchpad.net/bugs/1066940 Log in as manager: >>> manager = browsers.manager >>> manager.ui.login('manager', 'schooltool') Set up a skill document tree. Note the typos in the 'Fraktions' skill set: >>> manager.query.link('School').click() >>> manager.query.link('Skills').click() >>> manager.query.link('Document').click() >>> manager.query.id('form-widgets-title').ui.set_value('Virginia CTE') >>> manager.query.id('add-button').click() >>> manager.query.name('row2').ui.set_value('Course') >>> manager.query.id('add-button').click() >>> manager.query.name('row3').ui.set_value('Cluster') >>> manager.query.id('form-buttons-add').click() >>> manager.ui.skillset.add('Fraktions', '01') >>> manager.ui.skillset.add('Percents', '02') >>> manager.ui.skillset.add('Arithmetic of Decimals') >>> manager.query.link('Arithmetic of Decimals').click() >>> manager.query.css('a[title="Edit this skill set"]').click() >>> manager.query.id('form-widgets-label').clear() >>> manager.query.id('form-buttons-apply').click() >>> manager.ui.skill.add('Fraktions', 'Multiply two fractions.', '01') >>> manager.ui.skill.add('Fraktions', ... 'Divide a fraction by a mixed number.', '02') >>> manager.ui.skill.add('Fraktions', ... 'Divide a fraction by a whole number.', '03') >>> manager.ui.skill.add('Fraktions', 'Read and write fractions.') >>> manager.query.link('Read and write fractions.').click() >>> manager.query.css('a[title="Edit this skill"]').click() >>> manager.query.id('form-widgets-label').clear() >>> manager.query.id('form-buttons-apply').click() >>> manager.query.link('Done').click() >>> manager.ui.skill.add('Fraktions', ... 'Convert mixed numbers to improper fractions.') >>> manager.query.link('Convert mixed numbers to improper fractions.').click() >>> manager.query.css('a[title="Edit this skill"]').click() >>> manager.query.id('form-widgets-label').clear() >>> manager.query.id('form-buttons-apply').click() >>> manager.query.link('Done').click() >>> manager.ui.skill.add('Percents', 'Write fractions as percents.', '01') >>> manager.ui.skill.add('Percents', ... 'Write decimal numbers as percents.', '03') >>> manager.ui.skill.add('Percents', ... 'Write percents as decimal numbers.', '02') >>> manager.ui.skill.add('Arithmetic of Decimals', ... 'Add two decimal numbers.', '01') >>> manager.ui.skill.add('Arithmetic of Decimals', ... 'Subtract two decimal numbers.', '02') >>> manager.ui.skill.add('Arithmetic of Decimals', ... 'Add a group of decimal numbers.', '03') >>> manager.ui.node.add('Math') >>> sel = '//h2[contains(@class, "ui-accordion-header")]' >>> accordion_headers = manager.query_all.xpath(sel) >>> sel = 'div.ui-accordion-content' >>> accordion_contents = manager.query_all.css(sel) >>> information_accordion_content = accordion_contents[0] >>> skillsets_accordion_header = accordion_headers[4] >>> skillsets_accordion_header.click() >>> skillsets_accordion_content = accordion_contents[4] >>> manager.wait_no(information_accordion_content.is_displayed) >>> sel = 'a[title="Edit skill sets"]' >>> manager.query.css(sel).click() >>> manager.query.name('add_item.Fraktion1').click() >>> manager.query.name('add_item.Percents2').click() >>> manager.query.name('add_item.Arithmet3').click() Set up a section: >>> manager.ui.person.add('Jeffrey', 'Elkner', 'jeffrey', 'pwd') >>> manager.ui.person.add('Camila', 'Cerna', 'camila', 'pwd') >>> manager.ui.person.add('Liliana', 'Vividor', 'liliana', 'pwd') >>> manager.ui.person.add('Mario', 'Tejada', 'mario', 'pwd') >>> manager.ui.schoolyear.add('2012', '2012-01-01', '2012-12-31') >>> manager.ui.term.add('2012', '2012', '2012-01-01', '2012-12-31') >>> manager.ui.course.add('2012', 'Math') >>> manager.ui.section.add('2012', '2012', 'Math') >>> manager.ui.section.instructors.add('2012', '2012', 'Math (1)', ... ['jeffrey']) >>> manager.ui.section.students.add('2012', '2012', 'Math (1)', ... ['camila', 'liliana', 'mario']) And assign the skills to the its course: >>> manager.query.link('School').click() >>> manager.query.link('Courses').click() >>> manager.query.link('Math').click() >>> manager.query.link('Skills').click() >>> manager.query.link('Assign Skills').click() >>> manager.query.id('math').click() >>> dialog = manager.query.css('.ui-dialog') >>> manager.wait_page(dialog.query.name('SUBMIT_BUTTON').click) Log in as teacher and go to the CanDo gradebook: >>> teacher = browsers.teacher >>> teacher.ui.login('jeffrey', 'pwd') >>> teacher.query.link('CanDo').click() Add some scores to the Fraktions skill set: >>> sel = 'a[title="01: Fraktions"]' >>> link = teacher.query.css(sel) >>> # XXX: fix this, use clicks instead of open >>> teacher.open(link.get_attribute('href')) >>> fractions_url = teacher.url >>> teacher.ui.gradebook.worksheet.score('Camila Cerna', 'Conve', '4') >>> teacher.ui.gradebook.worksheet.score('Camila Cerna', 'Reada', '3') >>> teacher.ui.gradebook.worksheet.score('Camila Cerna', '01', '2') >>> teacher.ui.gradebook.worksheet.score('Camila Cerna', '02', '1') >>> teacher.ui.gradebook.worksheet.score('Camila Cerna', '03', '0') >>> teacher.ui.gradebook.worksheet.score('Mario Tejada', 'Conve', '0') >>> teacher.ui.gradebook.worksheet.score('Mario Tejada', 'Reada', '1') >>> teacher.ui.gradebook.worksheet.score('Mario Tejada', '02', '3') >>> teacher.ui.gradebook.worksheet.score('Liliana Vividor', 'Conve', '0') >>> teacher.ui.gradebook.worksheet.score('Liliana Vividor', '01', '4') >>> teacher.ui.gradebook.worksheet.score('Liliana Vividor', '03', '1') >>> teacher.query.name('UPDATE_SUBMIT').click() >>> teacher.ui.gradebook.worksheet.pprint() +------------------------+-----------------+--------------+ | Arithmetic of Decimals | *01: Fraktions* | 02: Percents | +------------------------+-----------------+--------------+ +-----------+------------+-------+-------+----+----+----+ | Last Name | First Name | Conve | Reada | 01 | 02 | 03 | | | | 4 | 4 | 4 | 4 | 4 | +-----------+------------+-------+-------+----+----+----+ | Cerna | Camila | 4 | 3 | 2 | 1 | 0 | | Tejada | Mario | 0 | 1 | | 3 | | | Vividor | Liliana | 0 | | 4 | | 1 | +-----------+------------+-------+-------+----+----+----+ List the skills and their types in the Percents skill set: >>> sel = 'a[title="02: Percents"]' >>> link = teacher.query.css(sel) >>> # XXX: fix this, use clicks instead of open >>> teacher.open(link.get_attribute('href')) >>> percents_url = teacher.url >>> def print_activity_columns(browser): ... sel = '#grades-part thead tr:first-child th.scorable' ... for th in browser.query_all.css(sel): ... browser.wait_no(lambda:th.query.tag('ul.popup_menu img')) ... header = th.query.css('ul.popup_menu li.header') ... optional = 'optional' in th.get_attribute('class') ... print ['required', 'optional'][optional] ... # XXX: why header.text produces BLANKLINE? ... print header >>> print_activity_columns(teacher) required
  • 01: Write fractions as percents.
  • required
  • 02: Write percents as decimal numbers.
  • required
  • 03: Write decimal numbers as percents.
  • Add some scores to the Percent skill set: >>> teacher.ui.gradebook.worksheet.score('Camila Cerna', '01', '2') >>> teacher.ui.gradebook.worksheet.score('Camila Cerna', '02', '1') >>> teacher.ui.gradebook.worksheet.score('Camila Cerna', '03', '0') >>> teacher.ui.gradebook.worksheet.score('Mario Tejada', '02', '3') >>> teacher.ui.gradebook.worksheet.score('Mario Tejada', '03', '4') >>> teacher.ui.gradebook.worksheet.score('Liliana Vividor', '01', '1') >>> teacher.ui.gradebook.worksheet.score('Liliana Vividor', '02', '2') >>> teacher.query.name('UPDATE_SUBMIT').click() >>> teacher.ui.gradebook.worksheet.pprint() +------------------------+---------------+----------------+ | Arithmetic of Decimals | 01: Fraktions | *02: Percents* | +------------------------+---------------+----------------+ +-----------+------------+----+----+----+ | Last Name | First Name | 01 | 02 | 03 | | | | 4 | 4 | 4 | +-----------+------------+----+----+----+ | Cerna | Camila | 2 | 1 | 0 | | Tejada | Mario | | 3 | 4 | | Vividor | Liliana | 1 | 2 | | +-----------+------------+----+----+----+ Let's fix the typo in the Fraktions skill set: >>> manager.query.link('School').click() >>> manager.query.link('Skills').click() >>> manager.query.link('Skill Sets').click() >>> manager.query.link('Fraktions').click() >>> sel = 'a[title="Edit this skill set"]' >>> manager.query.css(sel).click() >>> manager.query.id('form-widgets-title').clear() >>> manager.query.id('form-widgets-title').ui.set_value('Fractions') >>> manager.query.id('form-widgets-label').clear() >>> manager.query.id('form-widgets-label').ui.set_value('10') >>> manager.query.id('form-buttons-apply').click() The skill set should be updated in the teacher's gradebook: >>> teacher.open(fractions_url) >>> teacher.ui.gradebook.worksheet.pprint() +------------------------+--------------+-----------------+ | Arithmetic of Decimals | 02: Percents | *10: Fractions* | +------------------------+--------------+-----------------+ +-----------+------------+-------+-------+----+----+----+ | Last Name | First Name | Conve | Reada | 01 | 02 | 03 | | | | 4 | 4 | 4 | 4 | 4 | +-----------+------------+-------+-------+----+----+----+ | Cerna | Camila | 4 | 3 | 2 | 1 | 0 | | Tejada | Mario | 0 | 1 | | 3 | | | Vividor | Liliana | 0 | | 4 | | 1 | +-----------+------------+-------+-------+----+----+----+ Now, let's change some information of the skills in the Percents skill set: >>> manager.query.link('School').click() >>> manager.query.link('Skills').click() >>> manager.query.link('Skill Sets').click() >>> manager.query.link('Percents').click() >>> manager.query.link('Write fractions as percents.').click() >>> sel = 'a[title="Edit this skill"]' >>> manager.query.css(sel).click() >>> manager.query.id('form-widgets-label').clear() >>> manager.query.id('form-widgets-label').ui.set_value('07') >>> manager.query.id('form-buttons-apply').click() >>> manager.query.link('Done').click() >>> manager.query.link('Write percents as decimal numbers.').click() >>> sel = 'a[title="Edit this skill"]' >>> manager.query.css(sel).click() >>> manager.query.id('form-widgets-title').clear() >>> manager.query.id('form-widgets-title').ui.set_value('Write PERCENTS as decimal numbers.') >>> manager.query.id('form-buttons-apply').click() Let's change one required skill to optional in the Math course: >>> manager.query.link('School').click() >>> manager.query.link('Courses').click() >>> manager.query.link('Math').click() >>> manager.query.link('Skills').click() >>> manager.query.link('Set Required / Deprecated').click() >>> manager.query.name('required.Percents2.Write pe3').click() >>> manager.query.name('SUBMIT_BUTTON').click() The skills should be updated in the teacher's gradebook: >>> teacher.open(percents_url) >>> print_activity_columns(teacher) optional
  • 02: Write PERCENTS as decimal numbers.
  • required
  • 03: Write decimal numbers as percents.
  • required
  • 07: Write fractions as percents.
  • >>> teacher.ui.gradebook.worksheet.pprint() +------------------------+----------------+---------------+ | Arithmetic of Decimals | *02: Percents* | 10: Fractions | +------------------------+----------------+---------------+ +-----------+------------+----+----+----+ | Last Name | First Name | 02 | 03 | 07 | | | | 4 | 4 | 4 | +-----------+------------+----+----+----+ | Cerna | Camila | 1 | 0 | 2 | | Tejada | Mario | 3 | 4 | | | Vividor | Liliana | 2 | | 1 | +-----------+------------+----+----+----+ schooltool.cando-2.6.2/src/schooltool/cando/browser/stests/skillsets_skills.txt0000644000175000017500000001132012270520445031326 0ustar menesismenesis00000000000000Tests for the skillset and skill views ====================================== Log in as manager: >>> manager = browsers.manager >>> manager.ui.login('manager', 'schooltool') We'll define a helper function for printing the form fields of skillsets and skills. >>> def print_attrs(): ... print 'Title: %s' % manager.query.css('.body h3').text ... sel = 'table.form-fields tbody tr' ... for row in manager.query_all.css(sel): ... label = row.query.xpath('td[1]').text ... value = row.query.xpath('td[2]').text ... print '%s: %s' % (label, value) Let's start by going to the skillsets container view. We see there are no skillsets yet. >>> manager.query.link('School').click() >>> manager.query.link('Skills').click() >>> manager.query.link('Skill Sets').click() >>> print manager.query_all.css('h3')[1].text There are no skill sets. We'll add a skillset for Basic Algebra skills using the ui helper. Now we see it in the container view. >>> manager.ui.skillset.add('Basic Algebra', label='BA') >>> print manager.query_all.css('.data a').text Basic Algebra Clicking on the link takes us to the view for that skillset. We see the attributes that we specified. We also see that there are no skills yet. >>> manager.query.link('Basic Algebra').click() >>> print_attrs() Title: Basic Algebra Description: Label: BA Deprecated: No >>> print manager.query_all.css('.data tbody') We'll edit its attributes and see them change in the view. Then we'll change the title back. >>> manager.query.xpath('//a[@title="Edit this skill set"]').click() >>> manager.query.name('form.widgets.title').clear() >>> manager.query.name('form.widgets.title').type('Basic Algebra changed') >>> manager.query.name('form.widgets.label').clear() >>> manager.query.name('form.widgets.label').type('02') >>> page = manager.query.tag('html') >>> manager.query.button('Submit').click() >>> manager.wait(lambda: page.expired) >>> print_attrs() Title: Basic Algebra changed Description: Label: 02 Deprecated: No >>> manager.query.xpath('//a[@title="Edit this skill set"]').click() >>> manager.query.name('form.widgets.title').clear() >>> manager.query.name('form.widgets.title').type('Basic Algebra') >>> page = manager.query.tag('html') >>> manager.query.button('Submit').click() >>> manager.wait(lambda: page.expired) >>> print_attrs() Title: Basic Algebra Description: Label: 02 Deprecated: No Let's add a couple skills for Algebra. We then see them appear in the list of skills for Basic Algebra. >>> manager.ui.skill.add('Basic Algebra', 'Solve for one variable') >>> manager.ui.skill.add('Basic Algebra', 'Solve for multiple variables', ... label='L2', external_id='ext', required=False) >>> print manager.query_all.css('.data a').text Solve for one variable Solve for multiple variables We'll look at the skills and see their attributes. >>> manager.query.link('Solve for one variable').click() >>> print_attrs() Title: Solve for one variable Scoresystem: Competency Description: Label: 01 Required?: Required Deprecated: No External ID: >>> manager.query.link('Done').click() >>> manager.query.link('Solve for multiple variables').click() >>> print_attrs() Title: Solve for multiple variables Scoresystem: Competency Description: Label: L2 Required?: Optional Deprecated: No External ID: ext We can edit the attributes of one of the skills and see them change in the view. >>> manager.query.xpath('//a[@title="Edit this skill"]').click() >>> manager.query.name('form.widgets.title').clear() >>> manager.query.name('form.widgets.title').type('Solve for more than one variable') >>> manager.query.name('form.widgets.label').clear() >>> manager.query.name('form.widgets.label').type('02') >>> manager.query.id('form-widgets-required-0').click() >>> manager.query.name('form.widgets.external_id').clear() >>> manager.query.name('form.widgets.external_id').type('ext2') >>> page = manager.query.tag('html') >>> manager.query.button('Submit').click() >>> manager.wait(lambda: page.expired) >>> print_attrs() Title: Solve for more than one variable Scoresystem: Competency Description: Label: 02 Required?: Required Deprecated: No External ID: ext2 When we return to the skillset view, we see the change in the list. >>> manager.query.link('Done').click() >>> print manager.query_all.css('.data a').text Solve for one variable Solve for more than one variable schooltool.cando-2.6.2/src/schooltool/cando/browser/stests/projects.txt0000644000175000017500000002663712270520445027602 0ustar menesismenesis00000000000000Projects gradebook tests ======================== Log in as manager: >>> manager = browsers.manager >>> manager.ui.login('manager', 'schooltool') Set up persons: >>> manager.ui.person.add('Jeffrey', 'Elkner', 'jeffrey', 'pwd') >>> manager.ui.person.add('Camila', 'Cerna', 'camila', 'pwd') >>> manager.ui.person.add('Liliana', 'Vividor', 'liliana', 'pwd') >>> manager.ui.person.add('Mario', 'Tejada', 'mario', 'pwd') Set up a section: >>> manager.ui.schoolyear.add('2012', '2012-01-01', '2012-12-31') >>> manager.ui.term.add('2012', '2012', '2012-01-01', '2012-12-31') >>> manager.ui.course.add('2012', 'Programming', course_id='PRO') >>> manager.ui.section.add('2012', '2012', 'Programming') >>> manager.ui.section.instructors.add('2012', '2012', 'Programming (1)', ... ['jeffrey']) >>> manager.ui.section.students.add('2012', '2012', 'Programming (1)', ... ['camila', 'liliana', 'mario']) Set up skills: >>> manager.ui.layer.add('Course') >>> manager.ui.node.add('Programming', label='PRO') >>> manager.ui.skillset.add('Python Environment', '01') >>> manager.ui.skillset.add('Data Types, Statements, and Expressions', '02') >>> manager.ui.skillset.add('Errors', '03') >>> manager.ui.skillset.add('Strings', '04') >>> manager.ui.skill.add( ... 'Python Environment', ... 'Use the Python shell for interactive evaluation', ... '01') >>> manager.ui.skill.add( ... 'Python Environment', ... 'Make Python scripts with a text editor', ... '02', ... required=False) >>> manager.ui.skill.add( ... 'Data Types, Statements, and Expressions', ... 'Recognize int, float, str, list, tuple, and dict.', ... '03') >>> manager.ui.skill.add( ... 'Data Types, Statements, and Expressions', ... 'Use type(...) to determine the data type of a given value.', ... '04') >>> manager.ui.skill.add( ... 'Data Types, Statements, and Expressions', ... 'Use assignment statements to assign names (variables) to values.', ... '05') >>> manager.ui.skill.add( ... 'Data Types, Statements, and Expressions', ... 'Use the input function to read user input.', ... '06') >>> manager.ui.skill.add( ... 'Data Types, Statements, and Expressions', ... 'Define keyword and recognize keywords in Python.', ... '07') >>> manager.ui.skill.add( ... 'Data Types, Statements, and Expressions', ... 'Create legal variable names and recognize illegal ones.', ... '08', ... required=False) >>> manager.ui.skill.add( ... 'Errors', ... 'Recognize and differentiate among errors.', ... '09') >>> manager.ui.skill.add( ... 'Errors', ... 'Read and interpret stack traceback messages.', ... '10') >>> manager.ui.skill.add( ... 'Strings', ... 'Create string literals with single, double, and triple quotes.', ... '11') >>> manager.ui.skill.add( ... 'Strings', ... 'Use the len() function to return the length of a string.', ... '12') >>> manager.ui.skill.add( ... 'Strings', ... 'Use the find(...) method to locate substrings in a string.', ... '13', ... required=False) >>> manager.ui.skill.add( ... 'Strings', ... 'Use the split() method to break a string into a list.', ... '14', ... required=False) >>> manager.query.link('Search').click() >>> manager.query.button('Search').click() >>> manager.query.link('Programming').click() >>> sel = '//h2[contains(@class, "ui-accordion-header")]' >>> accordion_headers = manager.query_all.xpath(sel) >>> sel = 'div.ui-accordion-content' >>> accordion_contents = manager.query_all.css(sel) >>> information_accordion_content = accordion_contents[0] >>> skillsets_accordion_header = accordion_headers[4] >>> skillsets_accordion_header.click() >>> skillsets_accordion_content = accordion_contents[4] >>> manager.wait_no(information_accordion_content.is_displayed) >>> sel = '//a[@title="Edit skill sets"]' >>> manager.query.xpath(sel).click() >>> manager.query.id('form-buttons-add').click() >>> manager.query.link('Done').click() >>> sel = '//h2[contains(@class, "ui-accordion-header")]' >>> accordion_headers = manager.query_all.xpath(sel) >>> sel = 'div.ui-accordion-content' >>> accordion_contents = manager.query_all.css(sel) >>> information_accordion_content = accordion_contents[0] >>> layers_accordion_header = accordion_headers[3] >>> layers_accordion_header.click() >>> layers_accordion_content = accordion_contents[3] >>> manager.wait_no(information_accordion_content.is_displayed) >>> sel = '//a[@title="Edit layers"]' >>> manager.query.xpath(sel).click() >>> manager.query.id('form-buttons-add').click() Assign the skills to the course: >>> manager.query.link('School').click() >>> manager.query.link('Courses').click() >>> manager.query.link('Batch Assign Skills').click() >>> manager.query.name('course_attr').ui.set_value('Course ID') >>> manager.query.name('layer').ui.set_value('Course') >>> manager.query.name('node_attr').ui.set_value('Label') >>> manager.query.name('SEARCH_BUTTON').click() >>> manager.query.name('ASSIGN_BUTTON').click() Log in as instructor: >>> teacher = browsers.teacher >>> teacher.ui.login('jeffrey', 'pwd') >>> teacher.query.link('CanDo').click() Set up three skills in the default project: >>> teacher.query.css('ul.gradebook-modes #projects').click() >>> teacher.query.link('Skill').click() >>> teacher.query.button('Search').click() >>> teacher.query.link('Programming').click() >>> teacher.query.link('Python Environment').click() >>> teacher.query.name('Python E1.Use the 1').click() >>> teacher.query.name('SUBMIT').click() >>> teacher.query.link('Skill').click() >>> teacher.query.button('Search').click() >>> teacher.query.link('Programming').click() >>> teacher.query.link('Errors').click() >>> teacher.query.name('Errors-3.Recogniz1').click() >>> teacher.query.name('SUBMIT').click() >>> teacher.query.link('Skill').click() >>> teacher.query.button('Search').click() >>> teacher.query.link('Programming').click() >>> teacher.query.link('Strings').click() >>> teacher.query.name('Strings-4.Use the 4').click() >>> teacher.query.name('SUBMIT').click() Grade the project skills: >>> teacher.ui.gradebook.worksheet.score('Camila Cerna', '01', '3') >>> teacher.ui.gradebook.worksheet.score('Mario Tejada', '01', '3') >>> teacher.ui.gradebook.worksheet.score('Liliana Vividor', '01', '4') >>> teacher.ui.gradebook.worksheet.score('Camila Cerna', '09', '2') >>> teacher.ui.gradebook.worksheet.score('Liliana Vividor', '09', '1') >>> teacher.ui.gradebook.worksheet.score('Camila Cerna', '14', '4') >>> teacher.query.name('UPDATE_SUBMIT').click() Print the project's gradebook: >>> teacher.ui.gradebook.worksheet.pprint() +------------+ | *Project1* | +------------+ +-----------+------------+----+----+----+ | Last Name | First Name | 01 | 09 | 14 | | | | 4 | 4 | 4 | +-----------+------------+----+----+----+ | Cerna | Camila | 3 | 2 | 4 | | Tejada | Mario | 3 | | | | Vividor | Liliana | 4 | 1 | | +-----------+------------+----+----+----+ Print every worksheet in the skills gradebook to see how the grades are updated from the project: >>> teacher.query.css('ul.gradebook-modes #skills').click() >>> sel = 'a[title="01: Python Environment"]' >>> link = teacher.query.css(sel) >>> # XXX: fix this, use clicks instead of open >>> teacher.open(link.get_attribute('href')) >>> teacher.ui.gradebook.worksheet.pprint() +--------------------------+---------------------------------------------+------------+-------------+ | *01: Python Environment* | 02: Data Types, Statements, and Expressions | 03: Errors | 04: Strings | +--------------------------+---------------------------------------------+------------+-------------+ +-----------+------------+----+----+ | Last Name | First Name | 01 | 02 | | | | 4 | 4 | +-----------+------------+----+----+ | Cerna | Camila | 3 | | | Tejada | Mario | 3 | | | Vividor | Liliana | 4 | | +-----------+------------+----+----+ >>> sel = 'a[title="02: Data Types, Statements, and Expressions"]' >>> link = teacher.query.css(sel) >>> # XXX: fix this, use clicks instead of open >>> teacher.open(link.get_attribute('href')) >>> teacher.ui.gradebook.worksheet.pprint() +------------------------+-----------------------------------------------+------------+-------------+ | 01: Python Environment | *02: Data Types, Statements, and Expressions* | 03: Errors | 04: Strings | +------------------------+-----------------------------------------------+------------+-------------+ +-----------+------------+----+----+----+----+----+----+ | Last Name | First Name | 03 | 04 | 05 | 06 | 07 | 08 | | | | 4 | 4 | 4 | 4 | 4 | 4 | +-----------+------------+----+----+----+----+----+----+ | Cerna | Camila | | | | | | | | Tejada | Mario | | | | | | | | Vividor | Liliana | | | | | | | +-----------+------------+----+----+----+----+----+----+ >>> sel = 'a[title="03: Errors"]' >>> link = teacher.query.css(sel) >>> # XXX: fix this, use clicks instead of open >>> teacher.open(link.get_attribute('href')) >>> teacher.ui.gradebook.worksheet.pprint() +------------------------+---------------------------------------------+--------------+-------------+ | 01: Python Environment | 02: Data Types, Statements, and Expressions | *03: Errors* | 04: Strings | +------------------------+---------------------------------------------+--------------+-------------+ +-----------+------------+----+----+ | Last Name | First Name | 09 | 10 | | | | 4 | 4 | +-----------+------------+----+----+ | Cerna | Camila | 2 | | | Tejada | Mario | | | | Vividor | Liliana | 1 | | +-----------+------------+----+----+ >>> sel = 'a[title="04: Strings"]' >>> link = teacher.query.css(sel) >>> # XXX: fix this, use clicks instead of open >>> teacher.open(link.get_attribute('href')) >>> teacher.ui.gradebook.worksheet.pprint() +------------------------+---------------------------------------------+------------+---------------+ | 01: Python Environment | 02: Data Types, Statements, and Expressions | 03: Errors | *04: Strings* | +------------------------+---------------------------------------------+------------+---------------+ +-----------+------------+----+----+----+----+ | Last Name | First Name | 11 | 12 | 13 | 14 | | | | 4 | 4 | 4 | 4 | +-----------+------------+----+----+----+----+ | Cerna | Camila | | | | 4 | | Tejada | Mario | | | | | | Vividor | Liliana | | | | | +-----------+------------+----+----+----+----+ schooltool.cando-2.6.2/src/schooltool/cando/browser/templates/0000755000175000017500000000000012322040274025636 5ustar menesismenesis00000000000000schooltool.cando-2.6.2/src/schooltool/cando/browser/templates/section_report_score_colors.pt0000644000175000017500000000270512270520445034027 0ustar menesismenesis00000000000000
    Score Colors
      % Passing Target
    Meets target
    schooltool.cando-2.6.2/src/schooltool/cando/browser/templates/edit_course_skills.pt0000644000175000017500000000351112270520445032076 0ustar menesismenesis00000000000000
    Skill Required Deprecated
    schooltool.cando-2.6.2/src/schooltool/cando/browser/templates/course_remove_skills.pt0000644000175000017500000000454112270520445032452 0ustar menesismenesis00000000000000
    Title Skills Remove

    :

    schooltool.cando-2.6.2/src/schooltool/cando/browser/templates/course_skills_edit_table_buttons.pt0000644000175000017500000000104112270520445035017 0ustar menesismenesis00000000000000
    schooltool.cando-2.6.2/src/schooltool/cando/browser/templates/section_report_script.pt0000644000175000017500000000215012270520445032631 0ustar menesismenesis00000000000000 schooltool.cando-2.6.2/src/schooltool/cando/browser/templates/iep_sections.pt0000644000175000017500000000263412270520445030701 0ustar menesismenesis00000000000000

    Sections attended

    This person has no sections.

    schooltool.cando-2.6.2/src/schooltool/cando/browser/templates/retire_nodes_script.pt0000644000175000017500000000070512270520445032260 0ustar menesismenesis00000000000000 schooltool.cando-2.6.2/src/schooltool/cando/browser/templates/gradebook_iep_students.pt0000644000175000017500000000060712270520445032736 0ustar menesismenesis00000000000000 schooltool.cando-2.6.2/src/schooltool/cando/browser/templates/document.pt0000644000175000017500000000207212270520445030027 0ustar menesismenesis00000000000000

    Edit

    There are none.

    schooltool.cando-2.6.2/src/schooltool/cando/browser/templates/aggregate_filter.pt0000644000175000017500000000606412270520445031511 0ustar menesismenesis00000000000000
    Showing of items
    Search
    Layers
    schooltool.cando-2.6.2/src/schooltool/cando/browser/templates/layer.pt0000644000175000017500000001124612270520445027330 0ustar menesismenesis00000000000000

    Edit

    Extra top
    Extra bottom
    Label

    Parent layers

    Title

    There are none.

    Child layers Edit

    Title

    There are none.

    schooltool.cando-2.6.2/src/schooltool/cando/browser/templates/document_add.pt0000644000175000017500000000424312270520445030641 0ustar menesismenesis00000000000000

    Layer Hierarchy

    Title
    schooltool.cando-2.6.2/src/schooltool/cando/browser/templates/retire_nodes_save_button.pt0000644000175000017500000000150012270520445033277 0ustar menesismenesis00000000000000
    schooltool.cando-2.6.2/src/schooltool/cando/browser/templates/scoresystem_help.pt0000644000175000017500000000054212270520445031601 0ustar menesismenesis00000000000000
    Score Rating
    schooltool.cando-2.6.2/src/schooltool/cando/browser/templates/cando_resources.pt0000644000175000017500000000010312270520445031360 0ustar menesismenesis00000000000000 schooltool.cando-2.6.2/src/schooltool/cando/browser/templates/nodes_table_filter.pt0000644000175000017500000000466712270520445032051 0ustar menesismenesis00000000000000
    Showing of items
    Search
    Layers
    schooltool.cando-2.6.2/src/schooltool/cando/browser/templates/section_report_score_colors_column.pt0000644000175000017500000000124612270520445035403 0ustar menesismenesis00000000000000
    schooltool.cando-2.6.2/src/schooltool/cando/browser/templates/dialog_button_column.pt0000644000175000017500000000147712270520445032430 0ustar menesismenesis00000000000000
    schooltool.cando-2.6.2/src/schooltool/cando/browser/templates/course_skills_overview.pt0000644000175000017500000000103612270520445033017 0ustar menesismenesis00000000000000

    Skills

    There are sets of skills assigned.

    There are no skills assigned.

    schooltool.cando-2.6.2/src/schooltool/cando/browser/templates/document_skillset.pt0000644000175000017500000000172512270520445031745 0ustar menesismenesis00000000000000

    Edit

    schooltool.cando-2.6.2/src/schooltool/cando/browser/templates/skill.pt0000644000175000017500000000601712270520445027332 0ustar menesismenesis00000000000000

    Edit

    Extra top
    Extra bottom
    Label
    schooltool.cando-2.6.2/src/schooltool/cando/browser/templates/project_skill_table_filter.pt0000644000175000017500000000577212270520445033603 0ustar menesismenesis00000000000000
    Showing of items
    Search
    schooltool.cando-2.6.2/src/schooltool/cando/browser/templates/cando_third_nav.pt0000644000175000017500000000101612270520445031330 0ustar menesismenesis00000000000000

    Scroll over a skill ID to see its description here

    schooltool.cando-2.6.2/src/schooltool/cando/browser/templates/gradebook_skills_dialog.pt0000644000175000017500000000273212270520445033051 0ustar menesismenesis00000000000000

    :

    There are no skills.

    There are no skills.

    schooltool.cando-2.6.2/src/schooltool/cando/browser/templates/form.pt0000644000175000017500000000066712270520445027164 0ustar menesismenesis00000000000000
    schooltool.cando-2.6.2/src/schooltool/cando/browser/templates/iep_details.pt0000644000175000017500000000137712270520445030502 0ustar menesismenesis00000000000000 schooltool.cando-2.6.2/src/schooltool/cando/browser/templates/projects.pt0000644000175000017500000000420112270520445030036 0ustar menesismenesis00000000000000

    Reorder or Hide Projects

    Order Title Visible
    Edit
    schooltool.cando-2.6.2/src/schooltool/cando/browser/templates/request_competency_certificate.pt0000644000175000017500000000223412270520445034471 0ustar menesismenesis00000000000000
    Description
    File Type

    Select a minimum display score for

    schooltool.cando-2.6.2/src/schooltool/cando/browser/templates/skillsets.pt0000644000175000017500000000447012270520445030232 0ustar menesismenesis00000000000000

    Reorder or Hide Skill Sets

    Order Title Visible
    Edit
    schooltool.cando-2.6.2/src/schooltool/cando/browser/templates/section_report_charts_column.pt0000644000175000017500000000270512270520445034174 0ustar menesismenesis00000000000000
    schooltool.cando-2.6.2/src/schooltool/cando/browser/templates/course_assign_skills_table_filter.pt0000644000175000017500000000515012270520445035152 0ustar menesismenesis00000000000000
    Showing of items
    Search
    Layers
    schooltool.cando-2.6.2/src/schooltool/cando/browser/templates/skillset.pt0000644000175000017500000000636412270520445030053 0ustar menesismenesis00000000000000

    Edit

    Extra top
    Extra bottom
    Label

    Skills

    schooltool.cando-2.6.2/src/schooltool/cando/browser/templates/document_skill.pt0000644000175000017500000000152112270520445031223 0ustar menesismenesis00000000000000

    Edit

    schooltool.cando-2.6.2/src/schooltool/cando/browser/templates/course_skills_edit.pt0000644000175000017500000000031112270520445032071 0ustar menesismenesis00000000000000

    schooltool.cando-2.6.2/src/schooltool/cando/browser/templates/f_import_related.pt0000644000175000017500000000150312270520445031526 0ustar menesismenesis00000000000000
    What is This?

    In addition to entering skill data through SchoolTool's web interface, you can also import skill data from a spreadsheet using this template: empty_skills_data.xls.

    Data included in the spreadsheet will be added to data in the system; importing will not cause data to be removed.

    You do not have to import all worksheets at the same time. You can import individual worksheets sequentially.

    schooltool.cando-2.6.2/src/schooltool/cando/browser/templates/course_skillset.pt0000644000175000017500000000136712270520445031431 0ustar menesismenesis00000000000000

    Edit

    schooltool.cando-2.6.2/src/schooltool/cando/browser/templates/node.pt0000644000175000017500000001575412270520445027151 0ustar menesismenesis00000000000000