예제 #1
0
def parse_xml_roles(fname):
    """
    Parse XML dump of FS roles (roller) and return a mapping structured thus:

    map = { K1 : [ S_1, S_2, ... S_k ],
            ...
            Kn : [ S_1, ..., S_kn ], }

    ... where each K_i is a key falling into one of these four categories:
    undakt, undenh, kursakt, evu; and each S_i is a mapping structured thus:

    map2 = { 'fodselsdato' : ...,
             'personnr'    : ..., }

    S_i are an attempt to mimic db_rows (output from this function is used
    elsewhere where such keys are required).
    """

    result = dict()
    def gimme_lambda(element, data):
        kind = data[roles_xml_parser.target_key]
        if len(kind) > 1:
            logger.warn("Cannot decide on role kind for: %s", kind)
            return
        kind = kind[0]

        if kind in ("undakt", "undenh"):
            key = (data["institusjonsnr"],
                   data["emnekode"],
                   data["versjonskode"],
                   data["terminkode"],
                   data["arstall"],
                   data["terminnr"])
            if kind == "undakt":
                key = key + (data["aktivitetkode"],)

        elif kind in ("evu", ):
            logger.info("Ignoring roles pertaining to EVU-courses for now")
            return
        
        else:
            logger.warn("%s%s: Wrong role entry kind: %s; '%s'",
                        data["fodselsdato"], data["personnr"], kind, data)
            return

        
        result.setdefault(key, list()).append(
            { "fodselsdato" : int(data["fodselsdato"]),
              "personnr"    : int(data["personnr"]), })

    roles_xml_parser(fname, gimme_lambda)
    for entry in result.keys():
        logger.debug("Role-mapping: '%s' => '%s'" % (entry, result[entry]))
    return result
예제 #2
0
def parse_xml_roles(fname):
    """
    Parse XML dump of FS roles (roller) and return a mapping structured thus:

    map = { K1 : [ S_1, S_2, ... S_k ],
            ...
            Kn : [ S_1, ..., S_kn ], }

    ... where each K_i is a key falling into one of these four categories:
    undakt, undenh, kursakt, evu; and each S_i is a mapping structured thus:

    map2 = { 'fodselsdato' : ...,
             'personnr'    : ..., }

    S_i are an attempt to mimic db_rows (output from this function is used
    elsewhere where such keys are required).
    """

    result = dict()

    def gimme_lambda(element, data):
        kind = data[roles_xml_parser.target_key]
        if len(kind) > 1:
            logger.warn("Cannot decide on role kind for: %s", kind)
            return
        kind = kind[0]

        if kind in ("undakt", "undenh"):
            key = (data["institusjonsnr"], data["emnekode"],
                   data["versjonskode"], data["terminkode"], data["arstall"],
                   data["terminnr"])
            if kind == "undakt":
                key = key + (data["aktivitetkode"], )

        elif kind in ("evu", ):
            logger.info("Ignoring roles pertaining to EVU-courses for now")
            return

        else:
            logger.warn("%s%s: Wrong role entry kind: %s; '%s'",
                        data["fodselsdato"], data["personnr"], kind, data)
            return

        result.setdefault(key, list()).append({
            "fodselsdato":
            int(data["fodselsdato"]),
            "personnr":
            int(data["personnr"]),
        })

    roles_xml_parser(fname, gimme_lambda)
    for entry in result.keys():
        logger.debug("Role-mapping: '%s' => '%s'" % (entry, result[entry]))
    return result
예제 #3
0
def main():
    init_globals()

    # Opprett objekt for "internal:hia.no:fs:{supergroup}"
    fs_super = fs_supergroup()

    # Gå igjennom alle kjente undervisningsenheter; opprett
    # gruppe-objekter for disse.
    #
    # La fs-supergruppe-objektet ta seg av all logikk rundt hvor mange
    # nivåer gruppestrukturen skal ha for undervisningsenhet-grupper,
    # etc.
    def create_UE_helper(el_name, attrs):
        if el_name == 'undenhet':
            fs_super.add('undenh', attrs)

    logger.info("Leser XML-fil: underv_enhet.xml")
    access_FS.underv_enhet_xml_parser(
        os.path.join(dump_dir, 'underv_enhet.xml'), create_UE_helper)

    # Gå igjennom alle kjente EVU-kurs; opprett gruppeobjekter for disse.
    def create_evukurs_helper(el_name, attrs):
        if (el_name == "evukurs" and attrs.get("status_aktiv") == 'J'
                and attrs.get("status_nettbasert_und") == 'J'):

            if (immediate_evu_expire and mx.DateTime.strptime(
                    attrs.get("dato_til"), "%Y-%m-%d") < mx.DateTime.now()):
                logger.debug("Kurs %s-%s ekspirerte",
                             attrs["etterutdkurskode"],
                             attrs["kurstidsangivelsekode"])
            else:
                fs_super.add("evu", attrs)
            # fi
        # fi

    # end create_evukurs_helper
    xmlfile = "evu_kursinfo.xml"
    logger.info("Leser XML-fil: %s", xmlfile)
    access_FS.evukurs_xml_parser(os.path.join(dump_dir, xmlfile),
                                 create_evukurs_helper)
    logger.info("Ferdig med %s", xmlfile)

    # Meld studenter inn i undervisningsenhet-gruppene
    def student_UE_helper(el_name, attrs):
        if el_name == 'student':
            for undenh in fs_super.list_matches_1('undenh', attrs, 'student'):
                undenh.add(attrs)

    logger.info("Leser XML-fil: student_undenh.xml")
    access_FS.student_undenh_xml_parser(
        os.path.join(dump_dir, 'student_undenh.xml'), student_UE_helper)

    # Meld EVU-kursdeltakere i de respektive EVU-kursgruppene.
    def EVU_deltaker_helper(el_name, attrs):
        if el_name == "person" and len(attrs.get("evu")) > 0:
            # Dette blir ikke fult så pent -- i merged_persons plasserer man
            # informasjonen om EVU-tilknytning i form av underelementer av
            # <person>. Dermed må ethvert EVU-underelement (de er samlet i en
            # liste av dict'er under nøkkelen "evu" under) "suppleres" med
            # fdato/pnr på eieren til det EVU-underelementet.
            tmp = {
                "fodselsdato": attrs["fodselsdato"],
                "personnr": attrs["personnr"],
            }
            for evuattrs in attrs["evu"]:
                evuattrs.update(tmp)
                for evukurs in fs_super.list_matches_1("evu", evuattrs,
                                                       "kursdeltaker"):
                    evukurs.add(evuattrs)
                # od
            # od
        # fi

    # end create_EVU_participant_helper
    xmlfile = "merged_persons.xml"
    logger.info("Leser XML-fil: %s", xmlfile)
    access_FS.deltaker_xml_parser(os.path.join(dump_dir, xmlfile),
                                  EVU_deltaker_helper)
    logger.info("Ferdig med %s", xmlfile)

    # Gå igjennom alle kjente studieprogrammer; opprett gruppeobjekter
    # for disse.
    def create_studieprog_helper(el_name, attrs):
        if el_name == 'studprog' and attrs.get('status_utgatt') != 'J':
            fs_super.add('studieprogram', attrs)

    logger.info("Leser XML-fil: studieprog.xml")
    access_FS.studieprog_xml_parser(os.path.join(dump_dir, 'studieprog.xml'),
                                    create_studieprog_helper)

    # Meld forelesere og studieledere inn i passende
    # undervisningsenhet/EVU-kurs -gruppene
    def rolle_helper(el_name, attrs):
        if el_name != 'rolle':
            return
        rolle = attrs['rollekode']
        target = attrs[access_FS.roles_xml_parser.target_key]
        if len(target) != 1:
            return
        target = target[0]
        if target in ('undenh', 'stprog'):
            if rolle == 'FORELESER':
                for ue_foreleser in fs_super.list_matches(
                        'undenh', attrs, 'foreleser'):
                    ue_foreleser.add(attrs)
            elif rolle in ('STUDILEDER', 'STUDKOORD'):
                for ue_studieleder in fs_super.list_matches(
                        'undenh', attrs, 'studieleder'):
                    ue_studieleder.add(attrs)
                for stpr_studieleder in fs_super.list_matches(
                        'studieprogram', attrs, 'studieleder'):
                    stpr_studieleder.add(attrs)
            # fi
        elif target in ('evu', ):
            if rolle == 'FORELESER':
                # Kan ett element tilhøre flere evukurs?
                for evu_foreleser in fs_super.list_matches(
                        'evu', attrs, "foreleser"):
                    evu_foreleser.add(attrs)
                # od
            # fi
        # fi

    # end rolle_helper

    xmlfile = "roles.xml"
    logger.info("Leser XML-fil: %s", xmlfile)
    access_FS.roles_xml_parser(os.path.join(dump_dir, xmlfile), rolle_helper)
    logger.info("Ferdig med %s", xmlfile)

    # Finn alle studenter
    def student_studieprog_helper(el_name, attrs):
        if el_name == 'aktiv':
            for stpr in fs_super.list_matches_1('studieprogram', attrs,
                                                'student'):
                stpr.add(attrs)

    logger.info("Leser XML-fil: person.xml")
    access_FS.person_xml_parser(os.path.join(dump_dir, 'person.xml'),
                                student_studieprog_helper)
    logger.info("Ferdig med XML-fil: person.xml")

    # Write back all changes to the database
    fs_super.sync()

    if dryrun:
        logger.info("rolling back all changes")
        db.rollback()
    else:
        logger.info("committing all changes")
        db.commit()
예제 #4
0
def main():
    init_globals()

    # Opprett objekt for "internal:hia.no:fs:{supergroup}"
    fs_super = fs_supergroup()

    # Gå igjennom alle kjente undervisningsenheter; opprett
    # gruppe-objekter for disse.
    #
    # La fs-supergruppe-objektet ta seg av all logikk rundt hvor mange
    # nivåer gruppestrukturen skal ha for undervisningsenhet-grupper,
    # etc.
    def create_UE_helper(el_name, attrs):
        if el_name == 'undenhet':
            fs_super.add('undenh', attrs)

    logger.info("Leser XML-fil: underv_enhet.xml")
    access_FS.underv_enhet_xml_parser(
        os.path.join(dump_dir, 'underv_enhet.xml'),
        create_UE_helper)

    # Gå igjennom alle kjente EVU-kurs; opprett gruppeobjekter for disse.
    def create_evukurs_helper(el_name, attrs):
        if (el_name == "evukurs" and
            attrs.get("status_aktiv") == 'J' and
            attrs.get("status_nettbasert_und") == 'J'):
            
            if (immediate_evu_expire and
                mx.DateTime.strptime(attrs.get("dato_til"), "%Y-%m-%d") <
                mx.DateTime.now()):
                logger.debug("Kurs %s-%s ekspirerte",
                             attrs["etterutdkurskode"],
                             attrs["kurstidsangivelsekode"])
            else:
                fs_super.add("evu", attrs)
            # fi
        # fi
    # end create_evukurs_helper
    xmlfile = "evu_kursinfo.xml"
    logger.info("Leser XML-fil: %s", xmlfile)
    access_FS.evukurs_xml_parser(os.path.join(dump_dir, xmlfile),
                                 create_evukurs_helper)
    logger.info("Ferdig med %s", xmlfile)

    # Meld studenter inn i undervisningsenhet-gruppene
    def student_UE_helper(el_name, attrs):
        if el_name == 'student':
            for undenh in fs_super.list_matches_1('undenh', attrs,
                                                  'student'):
                undenh.add(attrs)

    logger.info("Leser XML-fil: student_undenh.xml")
    access_FS.student_undenh_xml_parser(
        os.path.join(dump_dir, 'student_undenh.xml'),
        student_UE_helper)

    # Meld EVU-kursdeltakere i de respektive EVU-kursgruppene.
    def EVU_deltaker_helper(el_name, attrs):
        if el_name == "person" and len(attrs.get("evu")) > 0:
            # Dette blir ikke fult så pent -- i merged_persons plasserer man
            # informasjonen om EVU-tilknytning i form av underelementer av
            # <person>. Dermed må ethvert EVU-underelement (de er samlet i en
            # liste av dict'er under nøkkelen "evu" under) "suppleres" med
            # fdato/pnr på eieren til det EVU-underelementet.
            tmp = { "fodselsdato" : attrs["fodselsdato"],
                    "personnr"  : attrs["personnr"], }
            for evuattrs in attrs["evu"]:
                evuattrs.update(tmp)
                for evukurs in fs_super.list_matches_1("evu", evuattrs,
                                                       "kursdeltaker"):
                    evukurs.add(evuattrs)
                # od
            # od
        # fi
    # end create_EVU_participant_helper
    xmlfile = "merged_persons.xml"
    logger.info("Leser XML-fil: %s", xmlfile)
    access_FS.deltaker_xml_parser(os.path.join(dump_dir, xmlfile),
                                  EVU_deltaker_helper)
    logger.info("Ferdig med %s", xmlfile)

    # Gå igjennom alle kjente studieprogrammer; opprett gruppeobjekter
    # for disse.
    def create_studieprog_helper(el_name, attrs):
        if el_name == 'studprog' and attrs.get('status_utgatt') != 'J':
            fs_super.add('studieprogram', attrs)
    logger.info("Leser XML-fil: studieprog.xml")
    access_FS.studieprog_xml_parser(
        os.path.join(dump_dir, 'studieprog.xml'),
        create_studieprog_helper)

    # Meld forelesere og studieledere inn i passende
    # undervisningsenhet/EVU-kurs -gruppene
    def rolle_helper(el_name, attrs):
        if el_name != 'rolle':
            return
        rolle = attrs['rollekode']
        target = attrs[access_FS.roles_xml_parser.target_key]
        if len(target) != 1:
            return
        target = target[0]
        if target in ('undenh', 'stprog'):
            if rolle == 'FORELESER':
                for ue_foreleser in fs_super.list_matches('undenh', attrs,
                                                          'foreleser'):
                    ue_foreleser.add(attrs)
            elif rolle in ('STUDILEDER', 'STUDKOORD'):
                for ue_studieleder in fs_super.list_matches('undenh', attrs,
                                                            'studieleder'):
                    ue_studieleder.add(attrs)
                for stpr_studieleder in fs_super.list_matches('studieprogram',
                                                              attrs,
                                                              'studieleder'):
                    stpr_studieleder.add(attrs)
            # fi
        elif target in ('evu',):
            if rolle == 'FORELESER':
                # Kan ett element tilhøre flere evukurs?
                for evu_foreleser in fs_super.list_matches('evu', attrs,
                                                           "foreleser"):
                    evu_foreleser.add(attrs)
                # od
            # fi
        # fi
    # end rolle_helper
            

    xmlfile = "roles.xml"
    logger.info("Leser XML-fil: %s", xmlfile)
    access_FS.roles_xml_parser(os.path.join(dump_dir, xmlfile),
                               rolle_helper)
    logger.info("Ferdig med %s", xmlfile)

    # Finn alle studenter 
    def student_studieprog_helper(el_name, attrs):
        if el_name == 'aktiv':
            for stpr in fs_super.list_matches_1('studieprogram', attrs,
                                                'student'):
                stpr.add(attrs)

    logger.info("Leser XML-fil: person.xml")
    access_FS.person_xml_parser(
        os.path.join(dump_dir, 'person.xml'),
        student_studieprog_helper)
    logger.info("Ferdig med XML-fil: person.xml")

    # Write back all changes to the database
    fs_super.sync()

    if dryrun:
        logger.info("rolling back all changes")
        db.rollback()
    else:
        logger.info("committing all changes")
        db.commit()
예제 #5
0
def collect_roles(role_file, fs_handler):
    """Read role data and build a suitable data structure.

    Extract all the interesting roles from role_file, and return a suitable
    representation of the roles for group building.

    @type role_file: basestring
    @param role_file:
      File with FS role data. Not all roles are of interest!
    """

    logger.debug("Extracting roles from %s", role_file)
    role_parser = access_FS.roles_xml_parser

    result = dict()

    def slurp_role(element_name, attributes):
        """Look at a specific <role>-element"""

        if element_name != "rolle":
            return

        # what *kind* of role is this?
        role_kind = attributes[role_parser.target_key]
        if len(role_kind) != 1:
            # A warning about this has has already been issued
            return
        role_kind = role_kind[0]

        if role_kind not in fs_handler.valid_roles:
            logger.debug("Ignoring '%s' role for: %s",
                         role_kind, repr(attributes))
            return

        if not timeslot_is_valid(lower(attributes)):
            logger.debug("Ignoring '%s' - data too old/in the future: "
                         "attrs=%s", role_kind, lower(attributes))
            return

        attrs = fs_handler.fixup_attributes(attributes)
        if attrs["rollekode"] not in fs_handler.valid_role_codes:
            logger.debug("Ignoring '%s' role, role code %s: attrs=%s",
                         role_kind, attrs["rollekode"], attrs)
            return

        logger.debug("Collecting role '%s' with %s",
                     role_kind, repr(attributes))

        group_key = fs_handler.attributes2key(role_kind, attrs)
        if group_key is None:
            return
        fs_handler.register_description(group_key, attrs)
        if group_key is None:
            logger.warn("Failed to create group key for role=%s/attrs=%s",
                        role_kind, attrs)
            return

        if not fs_handler.role_is_exportable(role_kind, attrs):
            logger.debug("Ignoring role=%s/attrs=%s (not exportable to LMS)",
                         role_kind, attrs)
            return

        fnr = "%06d%05d" % (int(attrs["fodselsdato"]),
                            int(attrs["personnr"]))
        result.setdefault(group_key, set()).add(fnr)
    # end slurp_role

    access_FS.roles_xml_parser(role_file, slurp_role)
    logger.debug("Roles from %s result in %d groups", role_file, len(result))
    return result
예제 #6
0
def collect_roles(role_file, fs_handler):
    """Read role data and build a suitable data structure.

    Extract all the interesting roles from role_file, and return a suitable
    representation of the roles for group building.

    @type role_file: basestring
    @param role_file:
      File with FS role data. Not all roles are of interest!
    """

    logger.debug("Extracting roles from %s", role_file)
    role_parser = access_FS.roles_xml_parser

    result = dict()

    def slurp_role(element_name, attributes):
        """Look at a specific <role>-element"""

        if element_name != "rolle":
            return

        # what *kind* of role is this?
        role_kind = attributes[role_parser.target_key]
        if len(role_kind) != 1:
            # A warning about this has has already been issued
            return 
        role_kind = role_kind[0]

        if role_kind not in fs_handler.valid_roles:
            logger.debug("Ignoring '%s' role for: %s",
                         role_kind, repr(attributes))
            return

        if not timeslot_is_valid(lower(attributes)):
            logger.debug("Ignoring '%s' - data too old/in the future: "
                         "attrs=%s", role_kind, lower(attributes))
            return

        attrs = fs_handler.fixup_attributes(attributes)
        if attrs["rollekode"] not in fs_handler.valid_role_codes:
            logger.debug("Ignoring '%s' role, role code %s: attrs=%s",
                         role_kind, attrs["rollekode"], attrs)
            return 

        logger.debug("Collecting role '%s' with %s",
                     role_kind, repr(attributes))

        group_key = fs_handler.attributes2key(role_kind, attrs)
        if group_key is None:
            return
        fs_handler.register_description(group_key, attrs)
        if group_key is None:
            logger.warn("Failed to create group key for role=%s/attrs=%s",
                        role_kind, attrs)
            return

        if not fs_handler.role_is_exportable(role_kind, attrs):
            logger.debug("Ignoring role=%s/attrs=%s (not exportable to LMS)",
                         role_kind, attrs)
            return

        fnr = "%06d%05d" % (int(attrs["fodselsdato"]),
                            int(attrs["personnr"]))
        result.setdefault(group_key, set()).add(fnr)
    # end slurp_role

    access_FS.roles_xml_parser(role_file, slurp_role)
    logger.debug("Roles from %s result in %d groups", role_file, len(result))
    return result