Ignore:
Timestamp:
8 Jan 2013, 11:38:14 (12 years ago)
Author:
Henrik Bettermann
Message:

Implement local student data exports in courses.

Location:
main/waeup.kofa/trunk/src/waeup/kofa/students
Files:
2 added
4 edited

Legend:

Unmodified
Added
Removed
  • main/waeup.kofa/trunk/src/waeup/kofa/students/browser.py

    r9842 r9843  
    5858from waeup.kofa.university.certificate import (
    5959    VirtualCertificateExportJobContainer,)
     60from waeup.kofa.university.course import (
     61    VirtualCourseExportJobContainer,)
    6062from waeup.kofa.university.vocabularies import course_levels
    6163from waeup.kofa.utils.batching import VirtualExportJobContainer
     
    27912793    """
    27922794    grok.context(VirtualCertificateExportJobContainer)
     2795    grok.template('exportconfig_certificate')
    27932796
    27942797    @property
    27952798    def certcode(self):
    27962799        return self.context.__parent__.code
     2800
     2801class CourseExportJobContainerJobConfig(ExportJobContainerJobConfig):
     2802    """Page that configures a students export job for courses.
     2803
     2804    In contrast to department or certificate student data exports the
     2805    coursetickets_catalog is searched here. Therefore the update
     2806    method from the base class is customized.
     2807    """
     2808    grok.context(VirtualCourseExportJobContainer)
     2809    grok.template('exportconfig_course')
     2810
     2811    def _set_exporter_values(self):
     2812        # We provide only the students exporter.
     2813        exporters = []
     2814        for name in ('students',):
     2815            util = getUtility(ICSVExporter, name=name)
     2816            exporters.append((util.title, name),)
     2817        self.exporters = exporters
     2818
     2819    def update(self, START=None, session=None, level=None, mode=None,
     2820               exporter=None):
     2821        self._set_session_values()
     2822        self._set_level_values()
     2823        self._set_mode_values()
     2824        self._set_exporter_values()
     2825        if START is None:
     2826            return
     2827        if session == 'all':
     2828            session=None
     2829        if level == 'all':
     2830            level = None
     2831        job_id = self.context.start_export_job(exporter,
     2832                                      self.request.principal.id,
     2833                                      # Use a different catalog and
     2834                                      # pass different keywords than
     2835                                      # for the (default) students_catalog
     2836                                      cat='coursetickets',
     2837                                      session=session,
     2838                                      level=level,
     2839                                      code=self.context.__parent__.code)
     2840        ob_class = self.__implemented__.__name__.replace('waeup.kofa.','')
     2841        self.context.logger.info(
     2842            '%s - exported: %s (%s, %s, %s), job_id=%s'
     2843            % (ob_class, exporter, session, level,
     2844            self.context.__parent__.code, job_id))
     2845        self.flash(_('Export started for course tickets with') +
     2846                   ' level_session=%s, level=%s' % (
     2847                   session, level))
     2848        self.redirect(self.url(self.redirect_target))
     2849        return
  • main/waeup.kofa/trunk/src/waeup/kofa/students/catalog.py

    r9795 r9843  
    140140    cat_name = 'students_catalog'
    141141    defaults = dict(student_id=None) # make sure we get all studs by default
     142
     143class CourseTicketsQuery(FilteredCatalogQueryBase):
     144    """Query students in a site. See waeup.kofa.catalog for more info.
     145    """
     146    cat_name = 'coursetickets_catalog'
     147    defaults = dict(code=None) # make sure we get all tickets by default
  • main/waeup.kofa/trunk/src/waeup/kofa/students/export.py

    r9834 r9843  
    2121from datetime import datetime
    2222from waeup.kofa.interfaces import MessageFactory as _
    23 from waeup.kofa.students.catalog import StudentsQuery
     23from waeup.kofa.students.catalog import StudentsQuery, CourseTicketsQuery
    2424from waeup.kofa.students.interfaces import (
    2525    IStudent, IStudentStudyCourse, IStudentStudyLevel, ICourseTicket,
     
    9696
    9797    def get_filtered(self, site, **kw):
    98         """Get students filtered by keywords.
    99 
    100         The keys must be valid students catalog index names. Returns a
    101         simple empty list or a catalog result set with `Student`
     98        """Get students from a catalog filtered by keywords.
     99
     100        students_catalog is the default catalog. The keys must be valid
     101        atalog index names.
     102        Returns a simple empty list, a list with `Student`
     103        objects or a catalog result set with `Student`
    102104        objects.
    103105
     
    105107
    106108        """
    107         # Pass only given keywords to StudentsQuery. This way we avoid
     109        # Pass only given keywords to create FilteredCatalogQuery objects.
     110        # This way we avoid
    108111        # trouble with `None` value ambivalences and queries are also
    109112        # faster (normally less indexes to ask). Drawback is, that
    110113        # developers must look into catalog to see what keywords are
    111114        # valid.
     115        if kw.get('cat', None) == 'coursetickets':
     116            coursetickets = CourseTicketsQuery(**kw).query()
     117            students = []
     118            for ticket in coursetickets:
     119                students.append(ticket.student)
     120            return list(set(students))
    112121        query = StudentsQuery(**kw)
    113122        return query.query()
  • main/waeup.kofa/trunk/src/waeup/kofa/students/tests/test_browser.py

    r9842 r9843  
    27982798        self.browser.getControl(name="session").value = ['2004']
    27992799        self.browser.getControl(name="level").value = ['100']
    2800         self.browser.getControl(name="mode").value = ['ug_ft']
    28012800        self.browser.getControl("Create CSV file").click()
    28022801
     
    28232822        self.assertTrue(
    28242823            'zope.mgr - students.browser.CertificateExportJobContainerJobConfig '
    2825             '- exported: students (2004, 100, ug_ft, None, CERT1), job_id=%s'
     2824            '- exported: students (2004, 100, None, None, CERT1), job_id=%s'
    28262825            % job_id in logcontent
    28272826            )
     
    28352834            '- discarded: job_id=%s' % job_id in logcontent
    28362835            )
     2836
     2837    def test_course_export(self):
     2838        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
     2839        course1_path = 'http://localhost/app/faculties/fac1/dep1/courses/COURSE1'
     2840        self.browser.open(course1_path)
     2841        self.browser.getLink("Export student data").click()
     2842        self.browser.getControl("Configure new export").click()
     2843        self.browser.getControl(name="exporter").value = ['students']
     2844        self.browser.getControl(name="session").value = ['2004']
     2845        self.browser.getControl(name="level").value = ['100']
     2846        self.browser.getControl("Create CSV file").click()
     2847
     2848        # When the job is finished and we reload the page...
     2849        job_id = self.wait_for_export_job_completed()
     2850        self.browser.open(course1_path + '/exports')
     2851        # ... the csv file can be downloaded ...
     2852        self.browser.getLink("Download").click()
     2853        self.assertEqual(self.browser.headers['content-type'],
     2854            'text/csv; charset=UTF-8')
     2855        self.assertTrue(
     2856            'filename="WAeUP.Kofa_students_%s.csv' % job_id in
     2857            self.browser.headers['content-disposition'])
     2858        self.assertEqual(len(self.app['datacenter'].running_exports), 1)
     2859        job_id = self.app['datacenter'].running_exports[0][0]
     2860        # ... and discarded
     2861        self.browser.open(course1_path + '/exports')
     2862        self.browser.getControl("Discard").click()
     2863        self.assertEqual(len(self.app['datacenter'].running_exports), 0)
     2864        # Creation, downloading and discarding is logged
     2865        logfile = os.path.join(
     2866            self.app['datacenter'].storage, 'logs', 'datacenter.log')
     2867        logcontent = open(logfile).read()
     2868        self.assertTrue(
     2869            'zope.mgr - students.browser.CourseExportJobContainerJobConfig '
     2870            '- exported: students (2004, 100, COURSE1), job_id=%s'
     2871            % job_id in logcontent
     2872            )
     2873        self.assertTrue(
     2874            'zope.mgr - students.browser.ExportJobContainerDownload '
     2875            '- downloaded: WAeUP.Kofa_students_%s.csv, job_id=%s'
     2876            % (job_id, job_id) in logcontent
     2877            )
     2878        self.assertTrue(
     2879            'zope.mgr - students.browser.ExportJobContainerOverview '
     2880            '- discarded: job_id=%s' % job_id in logcontent
     2881            )
Note: See TracChangeset for help on using the changeset viewer.