コード例 #1
0
ファイル: makeabireports.py プロジェクト: gradgrind/Zeugs
def makeAbiReport (outpath, pdata):
    """Build an Abitur grade report for a pupil.
    The necessary information is supplied in the mapping <pdata>:
        {key: value}.
    The keys are user-fields in the document template (odt), the values
    are the strings to be inserted.
    The resulting file is placed at <outpath>, creating leading folders
    if necessary. <outpath> need not end in '.odt', if not present it
    will be added automatically.
    """
    NOTCHOSEN = CONF.FORMATTING.NOTCHOSEN

    ## Get template path
    template = Paths.getUserPath ('FILE_ABITUR_REPORT_TEMPLATE')
#    fieldnames = OdtUserFields.listUserFields (template)

    ## Convert the dates.
    for f in pdata:
        d = pdata [f]
        if f.endswith ('_D'):
#            print ("???", f, d)
            if d:
                pdata [f] = Dates.dateConv (d)
        # Substitute non-date empty cells
        elif not d:
            pdata [f] = NOTCHOSEN

    folder = os.path.dirname (outpath)
    if not os.path.isdir (folder):
        os.makedirs (folder)
    ofile, used, missing = OdtUserFields.fillUserFields (
            template, outpath, pdata)
    REPORT.Info (_ABIREPORTDONE, path=ofile)
    return ofile
コード例 #2
0
ファイル: coversheet.py プロジェクト: gradgrind/Zeugs
def test_02():
    pdfBytes = makeSheets(_year, _date, Klass(_klass))
    folder = Paths.getUserPath('DIR_TEXT_REPORT_TEMPLATES')
    fpath = os.path.join(folder, 'test.pdf')
    with open(fpath, 'wb') as fh:
        fh.write(pdfBytes)
    REPORT.Test(" --> %s" % fpath)
コード例 #3
0
def test_05():
    _klass_stream = Klass('11')
    pdfBytes = makeReports(_year, _term, _klass_stream, _date)
    folder = Paths.getUserPath('DIR_GRADE_REPORT_TEMPLATES')
    fpath = os.path.join(folder, 'test_%s_%s.pdf' % (_klass_stream, _date))
    with open(fpath, 'wb') as fh:
        fh.write(pdfBytes)
コード例 #4
0
ファイル: attendance.py プロジェクト: gradgrind/Zeugs
 def __init__ (self, schoolyear, klass):
     self._class = klass
     self._year = schoolyear
     self._month = Month (self._year)
     # Get the template
     self._tpath = Paths.getUserPath ('TEMPLATE_ATTENDANCE_TABLE')
     self._table = Table (self._tpath)
     self._wsInfo = self._table.getSheet (0)
     self._wsMonth = self._table.getSheet (1)
コード例 #5
0
def test_07():
    # Reports for second term
    _term = '2'
    _date = '2016-06-22'
    for _ks in '11', '12.RS-HS-_', '12.Gym':
        _klass_stream = Klass(_ks)
        pdfBytes = makeReports(_year, _term, _klass_stream, _date)
        folder = Paths.getUserPath('DIR_GRADE_REPORT_TEMPLATES')
        fpath = os.path.join(folder, 'test_%s_%s.pdf' % (_klass_stream, _date))
        with open(fpath, 'wb') as fh:
            fh.write(pdfBytes)
コード例 #6
0
ファイル: summary.py プロジェクト: gradgrind/Zeugs
def tSheets(schoolyear, manager, date):
    courses = CourseTables(schoolyear)
    tidmap = {}
    for k in courses.classes():
        klass = Klass(k)
        sid2tids = courses.filterText(klass)
        for sid, tids in sid2tids.items():
            if tids.TEXT:
                if not tids:
                    tids = [_nn]
                for tid in tids:
                    try:
                        tmap = tidmap[tid]
                    except:
                        tidmap[tid] = {klass.klass: {sid}}
                        continue
                    try:
                        tmap[klass.klass].add(sid)
                    except:
                        tmap[klass.klass] = {sid}

    noreports = []
    teachers = []
    for tid in courses.teacherData:
        lines = []
        tname = courses.teacherData.getTeacherName(tid)
        try:
            tmap = tidmap[tid]
        except:
            noreports.append(tname)
            continue
        for k in sorted(tmap):
            for sid in tmap[k]:
                sname = courses.subjectName(sid)
                lines.append((k, sname))
        teachers.append((tname, lines))

    tpdir = Paths.getUserPath('DIR_TEXT_REPORT_TEMPLATES')
    templateLoader = jinja2.FileSystemLoader(searchpath=tpdir)
    templateEnv = jinja2.Environment(loader=templateLoader, autoescape=True)
    tpfile = 'summary-teachers.html'
    try:
        template = templateEnv.get_template(tpfile)
    except:
        REPORT.Fail(_NOTEMPLATE, path=os.path.join(tpdir, tpfile))
    source = template.render(year=printSchoolYear(schoolyear),
                             manager=manager,
                             date=Dates.dateConv(date),
                             teachers=teachers,
                             noreports=noreports)
    html = HTML(string=source)
    pdfBytes = html.write_pdf()
    return pdfBytes
コード例 #7
0
def test_01():
    from wz_compat.template import openTemplate, getTemplateTags, pupilFields
    from glob import glob
    fbase = Paths.getUserPath('DIR_TEMPLATES')
    fx = 'Notenzeugnis/*.html'
    fmask = os.path.join(fbase, *fx.split('/'))
    for f in glob(fmask):
        fname = os.path.basename(f)
        fpath = fx.rsplit('/', 1)[0] + '/' + os.path.basename(f)
        REPORT.Test("TEMPLATE: %s" % fpath)
        t = openTemplate(fpath)
        tags = getTemplateTags(t)
        REPORT.Test("Pupil fields: %s" % repr(pupilFields(tags)))
コード例 #8
0
ファイル: coversheet.py プロジェクト: gradgrind/Zeugs
def test_03():
    _k = '12K'
    _k = '12'
    _klass = Klass(_k)
    pupils = Pupils(_year)
    plist = pupils.classPupils(_klass)
    pdata = plist[0]
    pdfBytes = makeOneSheet(_year, _date, _klass, pdata)
    folder = Paths.getUserPath('DIR_TEXT_REPORT_TEMPLATES')
    fpath = os.path.join(folder, 'test1.pdf')
    with open(fpath, 'wb') as fh:
        fh.write(pdfBytes)
    REPORT.Test(" --> %s" % fpath)
コード例 #9
0
def test_06():
    #TODO: Perhaps if _GS is set, the type should be overriden?
    _klass = Klass('12')
    _pid = '200407'
    pupils = Pupils(_year)
    pall = pupils.classPupils(_klass)  # list of data for all pupils
    pdata = pall.pidmap[_pid]
    pdfBytes = makeOneSheet(_year, '2016-02-03', pdata, _term, 'Abgang')
    folder = Paths.getUserPath('DIR_GRADE_REPORT_TEMPLATES')
    ptag = pdata['PSORT'].replace(' ', '_')
    fpath = os.path.join(folder, 'test_%s_Abgang.pdf' % ptag)
    with open(fpath, 'wb') as fh:
        fh.write(pdfBytes)
    REPORT.Test(" --> %s" % fpath)
コード例 #10
0
def choiceTable(schoolyear, klass):
    """Build a subject choice table for the given school-class.
    <klass> is a <Klass> instance.
     """
    template = Paths.getUserPath('FILE_SUBJECT_CHOICE_TEMPLATE')
    table = KlassMatrix(template)
    # Title already set in template:
    #table.setTitle("Kurswahl")

    # "Translation" of info items:
    kmap = CONF.TABLES.COURSE_PUPIL_FIELDNAMES
    info = (
        (kmap['SCHOOLYEAR'], str(schoolyear)),
        (kmap['CLASS'], klass.klass),
    )
    table.setInfo(info)

    ### Manage subjects
    courses = CourseTables(schoolyear)
    sid2tlist = courses.classSubjects(klass)
    # <table.headers> is a list of cell values in the header row.
    rsid = table.rowindex - 1       # row tag for sid
    rsname = table.rowindex         # row tag for subject name
    # Go through the template columns and check if they are needed:
    for sid in sid2tlist:
        if sid[0] != '_':
            sname = courses.subjectName(sid)
            # Add subject
            col = table.nextcol()
            table.write(rsid, col, sid)
            table.write(rsname, col, sname)
    # Delete excess columns
    table.delEndCols(col + 1)

    ### Add pupils
    pupils = Pupils(schoolyear)
    for pdata in pupils.classPupils(klass):
        row = table.nextrow()
        table.write(row, 0, pdata['PID'])
        table.write(row, 1, pdata.name())
        table.write(row, 2, pdata['STREAM'])
    # Delete excess rows
    table.delEndRows(row + 1)

    ### Save file
    table.protectSheet()
    return table.save()
コード例 #11
0
def openTemplate(tpath):
    """Return a jinja2 <Template> instance.
    <tpath> is the path (folder separator '/') to the template file,
    relative to the main templates folder.
    The filepath is available as attribute <filename>.
    """
    tpsplit = tpath.split('/')
    fname = tpsplit.pop()
    tpdir = Paths.getUserPath('DIR_TEMPLATES')
    if tpsplit:
        tpdir = os.path.join(tpdir, *tpsplit)
    templateLoader = jinja2.FileSystemLoader(searchpath=tpdir)
    templateEnv = jinja2.Environment(loader=templateLoader, autoescape=True)
    try:
        return templateEnv.get_template(fname)
    except:
        REPORT.Fail(_NO_TEMPLATE, fname=os.path.join(tpdir, fname))
コード例 #12
0
ファイル: summary.py プロジェクト: gradgrind/Zeugs
def ksSheets(schoolyear, manager, date):
    courses = CourseTables(schoolyear)
    tidmap = {
        tid: courses.teacherData.getTeacherName(tid)
        for tid in courses.teacherData
    }

    klasses = []
    for k in courses.classes():
        klass = Klass(k)
        sidmap = {}
        sid2tids = courses.filterText(klass)
        for sid, tids in sid2tids.items():
            if tids.TEXT:
                if not tids:
                    tids = [_nn]
                for tid in tids:
                    try:
                        sidmap[sid].add(tid)
                    except:
                        sidmap[sid] = {tid}
        lines = []
        for sid, tids in sidmap.items():
            sname = courses.subjectName(sid)
            for tid in tids:
                lines.append((sname, tidmap[tid]))
        klasses.append((klass.klass, lines))

    tpdir = Paths.getUserPath('DIR_TEXT_REPORT_TEMPLATES')
    templateLoader = jinja2.FileSystemLoader(searchpath=tpdir)
    templateEnv = jinja2.Environment(loader=templateLoader, autoescape=True)
    tpfile = 'summary-classes.html'
    try:
        template = templateEnv.get_template(tpfile)
    except:
        REPORT.Fail(_NOTEMPLATE, path=os.path.join(tpdir, tpfile))
    source = template.render(year=printSchoolYear(schoolyear),
                             manager=manager,
                             date=Dates.dateConv(date),
                             klasses=klasses)
    html = HTML(string=source)
    pdfBytes = html.write_pdf()
    return pdfBytes
コード例 #13
0
ファイル: makeabireports.py プロジェクト: gradgrind/Zeugs
def makeAbiTables (schoolyear, klass, date):
    """Build grade tables (one for each student) for the final Abitur
    grades.
    These tables are used to prepare the grades for (automatic) entry
    into the certificates.
    The new tables are placed in a subfolder of the normal folder (see
    configuration file PATHS: FILE_ABITABLE_NEW). This is to avoid
    accidentally overwriting existing tables which already contain data.
    Most of the necessary "cleverness" is built into the template file.
    """
    template = Paths.getUserPath ('FILE_ABITUR_GRADE_TEMPLATE')
    outpath = Paths.getYearPath (schoolyear, 'FILE_ABITABLE_NEW', klass=klass)
    for f in glob (os.path.join (os.path.dirname (outpath), '*')):
        os.remove (f)
    outpath += '.xlsx'

    sheetname = CONF.TABLES.ABITUR_RESULTS.GRADE_TABLE_SHEET
    FrHr = {}
    for v in CONF.TABLES.ABITUR_RESULTS.P_FrHr:
        k, v = v.split (':')
        FrHr [k] = v

    ncourses = CONF.TABLES.ABITUR_RESULTS.NCOURSES.nat ()

    courseTables = CourseTables (schoolyear)
    pupils = Pupils (schoolyear).classPupils (klass, date)
    sid2info = courseTables.filterGrades (klass, realonly=True)
    subjects = []
    for sid, sinfo in sid2info.items ():
        subjects.append ((sid, sinfo.COURSE_NAME))

    teacherMatrix = FormattedMatrix.readMatrix (schoolyear,
            'FILE_CLASS_SUBJECTS', klass)

    i = 0       # pid index for ordering files
    files = []  # list of created files (full paths)
    for pdata in pupils:
        pid = pdata ['PID']
        pname = pdata.name ()
        i += 1
        filepath = outpath.replace ('*', '{pnum:02d}-{pid}-{name}'.format (
                pnum=i, pid=pid,
                name=Paths.asciify (pname)))

        fields = {'YEAR': str (schoolyear),
                'LASTNAME': pdata ['LASTNAME'],
                'FIRSTNAMES': pdata ['FIRSTNAMES'],
                'DOB_D': pdata ['DOB_D'],
                'POB': pdata ['POB'],
                'HOME': pdata ['HOME']}
        try:
            fields ['FrHr'] = FrHr [pdata ['SEX']]
        except:
            REPORT.Error (_BADSEXFIELD, klass=klass, pname=pname,
                    sex=pdata ['SEX'])
            fields ['FrHr'] = ' '

        f = 0
        for sid, sname in subjects:
            if not teacherMatrix [pid][sid]:
                continue
            f += 1
            fields ['F' + str (f)] = sname.split ('|') [0].rstrip ()
        if ncourses and f != ncourses:
            REPORT.Error (_NOTNCOURSES, klass=klass, pname=pname, n=f,
                    nc0=ncourses)
            continue

        unused = XLS_template (filepath, template, fields,
                sheetname=sheetname)
        files.append (filepath)

    REPORT.Info (_MADENTABLES, klass=klass, n=len (files))
    return files
コード例 #14
0
ファイル: makeabireports.py プロジェクト: gradgrind/Zeugs
def test_02 ():
    ifile = Paths.getUserPath ('FILE_ABITUR_GRADE_EXAMPLE')
    outfile = os.path.join (os.path.dirname (ifile), 'tmp', 'AbiZeugnis.odt')
    pdata = readTableData (ifile, table='Daten')
    REPORT.Test ("??? Fields: %s" % repr(pdata))
    REPORT.Test ("\n --> %s" % makeAbiReport (outfile, pdata))
コード例 #15
0
def makeGradeTable(schoolyear, term, klass, title):
    """Make a grade table for the given school-class/group.
    <klass> is a <Klass> instance.
    <term> is a string.
    """
    # Info concerning grade tables:
    gtinfo = CONF.GRADES.GRADE_TABLE_INFO
    # Determine table template
    t = klass.match_map(gtinfo.GRADE_TABLE_TEMPLATE)
    if not t:
        REPORT.Fail(_NO_TEMPLATE, ks=klass)
    template = Paths.getUserPath('FILE_GRADE_TABLE_TEMPLATE').replace('*', t)
    table = KlassMatrix(template)

    ### Insert general info
    table.setTitle(title)
    # "Translation" of info items:
    kmap = CONF.TABLES.COURSE_PUPIL_FIELDNAMES
    info = (
        (kmap['SCHOOLYEAR'], str(schoolyear)),
        (kmap['CLASS'], klass.klass),
        (kmap['TERM'], term)
    )
    table.setInfo(info)

    ### Manage subjects
    courses = CourseTables(schoolyear)
    sid2tlist = courses.classSubjects(klass)
#    print ("???1", list(sid2tlist))
    # Go through the template columns and check if they are needed:
    colmap = {}
    col = _FIRSTSIDCOL
    for k in table.headers[_FIRSTSIDCOL:]:
        if k:
            if k in sid2tlist:
                colmap[k] = col
            elif k == _UNUSED:
                table.hideCol(col, True)
            else:
                # Handle extra _tags
                klassmap = gtinfo.get(k)
                if klassmap:
                    m = klass.match_map(klassmap)
                    if m and term in m.split():
                        colmap[k] = col
                    else:
                        table.hideCol(col, True)
                else:
                    table.hideCol(col, True)
        col += 1
#    print("???COLMAP:", colmap)

    ### Add pupils
    pupils = Pupils(schoolyear)
    for pdata in pupils.classPupils(klass):
        row = table.nextrow()
        pid = pdata['PID']
        table.write(row, 0, pid)
        table.write(row, 1, pdata.name())
        table.write(row, 2, pdata['STREAM'])
        # Add existing grades
        gd = getGradeData(schoolyear, pid, term)
#        print("\n???", pid, gd)
        if gd:
            grades = gd['GRADES']
            if grades:
                for k, v in grades.items():
                    try:
                        col = colmap[k]
                    except KeyError:
#                        print("!!! excess subject:", k)
                        continue
                    if k:
                        if k.startswith('__'):
                            # Calculated entry
                            continue
                        table.write(row, col, v)
    # Delete excess rows
    table.delEndRows(row + 1)

    ### Save file
    table.protectSheet()
    return table.save()
コード例 #16
0
def stripTable(schoolyear, term, klass, title):
    """Build a basic pupil/subject table for entering grades.
    <klass> is a <Klass> instance.
    <term> is a string.
     """
    # Info concerning grade tables:
    gtinfo = CONF.GRADES.GRADE_TABLE_INFO

    ### Determine table template (output)
    t = klass.match_map(gtinfo.GRADE_INPUT_TEMPLATE)
    if not t:
        REPORT.Fail(_NO_ITEMPLATE, ks=klass)
    template = Paths.getUserPath('FILE_GRADE_TABLE_TEMPLATE').replace('*', t)
    table = KlassMatrix(template)
    table.setTitle(title)
    table.setInfo([])

    ### Read input table template (for determining subjects and order)
    # Determine table template (input)
    t = klass.match_map(gtinfo.GRADE_TABLE_TEMPLATE)
    if not t:
        REPORT.Fail(_NO_TEMPLATE, ks=klass)
    template0 = Paths.getUserPath('FILE_GRADE_TABLE_TEMPLATE').replace('*', t)
    table0 = KlassMatrix(template0)
    i, x = 0, 0
    for row0 in table0.rows:
        i += 1
        if row0[0] and row0[0] != '#':
            # The subject key line
            break
    # <row0> is the title row.

    ### Manage subjects
    courses = CourseTables(schoolyear)
    sid2tlist = courses.classSubjects(klass)
#    print ("???1", list(sid2tlist))
    # Set klass cell
    rowix = table.rowindex - 1
    table.write(rowix, 0, table.headers[0].replace('*', klass.klass))
    # Go through the template columns and check if they are needed:
    col = 0
    for sid in row0:
        if sid and sid[0] != '_' and sid in sid2tlist:
            sname = courses.subjectName(sid)
            # Add subject
            col = table.nextcol()
            table.write(rowix, col, sname)
    # Delete excess columns
    table.delEndCols(col + 1)

    ### Add pupils
    pupils = Pupils(schoolyear)
    for pdata in pupils.classPupils(klass):
        row = table.nextrow()
        table.write(row, 0, pdata.name())
        table.write(row, 1, pdata['STREAM'])
    # Delete excess rows
    table.delEndRows(row + 1)

    ### Save file
    table.protectSheet()
    return table.save()