~azzar1/unity/add-show-desktop-key

« back to all changes in this revision

Viewing changes to ivle/webapp/admin/subject.py

  • Committer: Matt Giuca
  • Date: 2010-02-25 06:52:48 UTC
  • mto: This revision was merged to the branch mainline in revision 1731.
  • Revision ID: matt.giuca@gmail.com-20100225065248-p1t8oys3olxtwdlg
project-form no longer assumes the type of context; pass an extra projectset value.

Show diffs side-by-side

added added

removed removed

Lines of Context:
31
31
from storm.locals import Desc, Store
32
32
import genshi
33
33
from genshi.filters import HTMLFormFiller
34
 
from genshi.template import Context, TemplateLoader
 
34
from genshi.template import Context
35
35
import formencode
36
36
import formencode.validators
37
37
 
38
 
from ivle.webapp.base.forms import BaseFormView, URLNameValidator
 
38
from ivle.webapp.base.forms import (BaseFormView, URLNameValidator,
 
39
                                    DateTimeValidator)
39
40
from ivle.webapp.base.plugins import ViewPlugin, MediaPlugin
40
41
from ivle.webapp.base.xhtml import XHTMLView
41
42
from ivle.webapp.errors import BadRequest
46
47
from ivle import util
47
48
import ivle.date
48
49
 
49
 
from ivle.webapp.admin.projectservice import ProjectSetRESTView
50
 
from ivle.webapp.admin.offeringservice import OfferingRESTView
51
50
from ivle.webapp.admin.publishing import (root_to_subject, root_to_semester,
52
51
            subject_to_offering, offering_to_projectset, offering_to_project,
53
52
            offering_to_enrolment, subject_url, semester_url, offering_url,
54
53
            projectset_url, project_url, enrolment_url)
55
54
from ivle.webapp.admin.breadcrumbs import (SubjectBreadcrumb,
56
55
            OfferingBreadcrumb, UserBreadcrumb, ProjectBreadcrumb,
57
 
            EnrolmentBreadcrumb)
 
56
            ProjectsBreadcrumb, EnrolmentBreadcrumb)
58
57
from ivle.webapp.core import Plugin as CorePlugin
59
58
from ivle.webapp.groups import GroupsView
60
59
from ivle.webapp.media import media_url
308
307
 
309
308
        ctx['worksheets'], problems_total, problems_done = (
310
309
            ivle.worksheet.utils.create_list_of_fake_worksheets_and_stats(
311
 
                req.store, req.user, self.context))
 
310
                req.config, req.store, req.user, self.context))
312
311
 
313
312
        ctx['exercises_total'] = problems_total
314
313
        ctx['exercises_done'] = problems_done
385
384
    description = formencode.validators.UnicodeString(
386
385
        if_missing=None, not_empty=False)
387
386
    url = formencode.validators.URL(if_missing=None, not_empty=False)
 
387
    show_worksheet_marks = formencode.validators.StringBoolean(
 
388
        if_missing=False)
388
389
 
389
390
 
390
391
class OfferingAdminSchema(OfferingSchema):
425
426
                        self.context.semester.semester,
426
427
            'url': self.context.url,
427
428
            'description': self.context.description,
 
429
            'show_worksheet_marks': self.context.show_worksheet_marks,
428
430
            }
429
431
 
430
432
    def save_object(self, req, data):
433
435
            self.context.semester = data['semester']
434
436
        self.context.description = data['description']
435
437
        self.context.url = unicode(data['url']) if data['url'] else None
 
438
        self.context.show_worksheet_marks = data['show_worksheet_marks']
436
439
        return self.context
437
440
 
438
441
 
467
470
        new_offering.semester = data['semester']
468
471
        new_offering.description = data['description']
469
472
        new_offering.url = unicode(data['url']) if data['url'] else None
 
473
        new_offering.show_worksheet_marks = data['show_worksheet_marks']
470
474
 
471
475
        req.store.add(new_offering)
472
476
        return new_offering
615
619
        ctx['offering'] = self.context
616
620
        ctx['roles_auth'] = self.context.get_permissions(req.user, req.config)
617
621
        ctx['errors'] = errors
 
622
        # If all of the fields validated, set the global form error.
 
623
        if isinstance(errors, basestring):
 
624
            ctx['error_value'] = errors
618
625
 
619
626
 
620
627
class EnrolmentEditSchema(formencode.Schema):
679
686
 
680
687
    def populate(self, req, ctx):
681
688
        self.plugin_styles[Plugin] = ["project.css"]
682
 
        self.plugin_scripts[Plugin] = ["project.js"]
683
689
        ctx['req'] = req
684
690
        ctx['offering'] = self.context
685
691
        ctx['projectsets'] = []
686
 
        ctx['OfferingRESTView'] = OfferingRESTView
687
692
 
688
693
        #Open the projectset Fragment, and render it for inclusion
689
694
        #into the ProjectSets page
690
 
        #XXX: This could be a lot cleaner
691
 
        loader = genshi.template.TemplateLoader(".", auto_reload=True)
692
 
 
693
695
        set_fragment = os.path.join(os.path.dirname(__file__),
694
696
                "templates/projectset_fragment.html")
695
697
        project_fragment = os.path.join(os.path.dirname(__file__),
696
698
                "templates/project_fragment.html")
697
699
 
698
 
        for projectset in self.context.project_sets:
699
 
            settmpl = loader.load(set_fragment)
 
700
        for projectset in \
 
701
            self.context.project_sets.order_by(ivle.database.ProjectSet.id):
 
702
            settmpl = self._loader.load(set_fragment)
700
703
            setCtx = Context()
701
704
            setCtx['req'] = req
702
705
            setCtx['projectset'] = projectset
703
706
            setCtx['projects'] = []
704
707
            setCtx['GroupsView'] = GroupsView
705
 
            setCtx['ProjectSetRESTView'] = ProjectSetRESTView
 
708
            setCtx['ProjectSetEdit'] = ProjectSetEdit
 
709
            setCtx['ProjectNew'] = ProjectNew
706
710
 
707
 
            for project in projectset.projects:
708
 
                projecttmpl = loader.load(project_fragment)
 
711
            for project in \
 
712
                projectset.projects.order_by(ivle.database.Project.deadline):
 
713
                projecttmpl = self._loader.load(project_fragment)
709
714
                projectCtx = Context()
710
715
                projectCtx['req'] = req
711
716
                projectCtx['project'] = project
746
751
        ctx['req'] = req
747
752
        ctx['GroupsView'] = GroupsView
748
753
        ctx['EnrolView'] = EnrolView
 
754
        ctx['format_datetime'] = ivle.date.make_date_nice
749
755
        ctx['format_datetime_short'] = ivle.date.format_datetime_for_paragraph
750
756
        ctx['build_subversion_url'] = self.build_subversion_url
751
757
        ctx['svn_addr'] = req.config['urls']['svn_addr']
752
758
        ctx['project'] = self.context
753
759
        ctx['user'] = req.user
754
760
 
 
761
class ProjectUniquenessValidator(formencode.FancyValidator):
 
762
    """A FormEncode validator that checks that a project short_name is unique
 
763
    in a given offering.
 
764
 
 
765
    The project referenced by state.existing_project is permitted to
 
766
    hold that short_name. If any other project holds it, the input is rejected.
 
767
    """
 
768
    def _to_python(self, value, state):
 
769
        if (state.store.find(
 
770
            Project,
 
771
            Project.short_name == unicode(value),
 
772
            Project.project_set_id == ProjectSet.id,
 
773
            ProjectSet.offering == state.offering).one() not in
 
774
            (None, state.existing_project)):
 
775
            raise formencode.Invalid(
 
776
                "A project with that URL name already exists in this offering."
 
777
                , value, state)
 
778
        return value
 
779
 
 
780
class ProjectSchema(formencode.Schema):
 
781
    name = formencode.validators.UnicodeString(not_empty=True)
 
782
    short_name = formencode.All(
 
783
        URLNameValidator(not_empty=True),
 
784
        ProjectUniquenessValidator())
 
785
    deadline = DateTimeValidator(not_empty=True)
 
786
    url = formencode.validators.URL(if_missing=None, not_empty=False)
 
787
    synopsis = formencode.validators.UnicodeString(not_empty=True)
 
788
 
 
789
class ProjectNew(BaseFormView):
 
790
    """A form to create a new project."""
 
791
    template = 'templates/project-new.html'
 
792
    tab = 'subjects'
 
793
    permission = 'edit'
 
794
 
 
795
    @property
 
796
    def validator(self):
 
797
        return ProjectSchema()
 
798
 
 
799
    def populate(self, req, ctx):
 
800
        super(ProjectNew, self).populate(req, ctx)
 
801
        ctx['projectset'] = self.context
 
802
 
 
803
    def populate_state(self, state):
 
804
        state.offering = self.context.offering
 
805
        state.existing_project = None
 
806
 
 
807
    def get_default_data(self, req):
 
808
        return {}
 
809
 
 
810
    def save_object(self, req, data):
 
811
        new_project = Project()
 
812
        new_project.project_set = self.context
 
813
        new_project.name = data['name']
 
814
        new_project.short_name = data['short_name']
 
815
        new_project.deadline = data['deadline']
 
816
        new_project.url = unicode(data['url']) if data['url'] else None
 
817
        new_project.synopsis = data['synopsis']
 
818
        req.store.add(new_project)
 
819
        return new_project
 
820
 
 
821
class ProjectSetSchema(formencode.Schema):
 
822
    group_size = formencode.validators.Int(if_missing=None, not_empty=False)
 
823
 
 
824
class ProjectSetEdit(BaseFormView):
 
825
    """A form to edit a project set."""
 
826
    template = 'templates/projectset-edit.html'
 
827
    tab = 'subjects'
 
828
    permission = 'edit'
 
829
 
 
830
    @property
 
831
    def validator(self):
 
832
        return ProjectSetSchema()
 
833
 
 
834
    def populate(self, req, ctx):
 
835
        super(ProjectSetEdit, self).populate(req, ctx)
 
836
 
 
837
    def get_default_data(self, req):
 
838
        return {
 
839
            'group_size': self.context.max_students_per_group,
 
840
            }
 
841
 
 
842
    def save_object(self, req, data):
 
843
        self.context.max_students_per_group = data['group_size']
 
844
        return self.context
 
845
 
 
846
class ProjectSetNew(BaseFormView):
 
847
    """A form to create a new project set."""
 
848
    template = 'templates/projectset-new.html'
 
849
    tab = 'subjects'
 
850
    permission = 'edit'
 
851
    breadcrumb_text = "Projects"
 
852
 
 
853
    @property
 
854
    def validator(self):
 
855
        return ProjectSetSchema()
 
856
 
 
857
    def populate(self, req, ctx):
 
858
        super(ProjectSetNew, self).populate(req, ctx)
 
859
 
 
860
    def get_default_data(self, req):
 
861
        return {}
 
862
 
 
863
    def save_object(self, req, data):
 
864
        new_set = ProjectSet()
 
865
        new_set.offering = self.context
 
866
        new_set.max_students_per_group = data['group_size']
 
867
        req.store.add(new_set)
 
868
        return new_set
 
869
 
755
870
class Plugin(ViewPlugin, MediaPlugin):
756
871
    forward_routes = (root_to_subject, root_to_semester, subject_to_offering,
757
872
                      offering_to_project, offering_to_projectset,
777
892
             (Enrolment, '+edit', EnrolmentEdit),
778
893
             (Enrolment, '+delete', EnrolmentDelete),
779
894
             (Offering, ('+projects', '+index'), OfferingProjectsView),
 
895
             (Offering, ('+projects', '+new-set'), ProjectSetNew),
 
896
             (ProjectSet, '+edit', ProjectSetEdit),
 
897
             (ProjectSet, '+new', ProjectNew),
780
898
             (Project, '+index', ProjectView),
781
 
 
782
 
             (Offering, ('+projectsets', '+new'), OfferingRESTView, 'api'),
783
 
             (ProjectSet, ('+projects', '+new'), ProjectSetRESTView, 'api'),
784
899
             ]
785
900
 
786
901
    breadcrumbs = {Subject: SubjectBreadcrumb,