Пример #1
0
    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)
Пример #2
0
    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)
Пример #3
0
    def attributes2key(self, group_kind, attributes):
        """Construct a Cerebrum group_name/CF group id, given a bunch of
        attributes.

        This function is useful to map various information tidbits on groups,
        roles, etc to a unique ID in Cerebrum for that particular kind of
        attributes. Each L{group_kind} results in a group in Cerebrum and this
        function calculates that group's id (not entity_id, but the id used in
        CF).

        @type group_kind: basestring
        @param group_kind:
          A tag that describes what kind of information is to be expected in
          L{attributes}. The ONLY legal values are:

            - 'stprog', 'kull', 'kullklasse', 'undenh', 'undakt'
            - 'student-undenh', 'student-undakt', 'student-kullklasse',
              'student-kull'

          Each kind has a different set of keys in attributes that MUST be
          present.

        @type attributes: dict (of basestring -> basestring)
        @param attributes:
          A collection of attributes. This collection may contain more than what
          is required by L{group_kind}.

        @rtype: basestring or None
        @return:
          None if an id could not be constructed. The id itself otherwise.
        """

        # easiest way to copy, since we modify these destructively
        attrs = lower(attributes)

        if group_kind not in self.group_kind2required_keys:
            logger.warn("Don't know how to process attributes "
                        "belonging to '%s' (%s)",
                        group_kind, repr(attrs))
            return None

        keys = self.group_kind2required_keys[group_kind]
        if not all(x in attrs for x in keys):
            logger.warn("Missing essential keys for kind=%s. "
                        "Required=%s, available=%s",
                        group_kind, sorted(keys), sorted(attrs))
            return None

        # Now, those that have "terminnr" > 1 MUST be remapped.
        if "terminnr" in keys:
            attrs = count_back_semesters(attrs)

        result_id = self.group_kind2name_template[group_kind]
        result_id = result_id % attrs
        return result_id
Пример #4
0
    def attributes2key(self, group_kind, attributes):
        """Construct a Cerebrum group_name/CF group id, given a bunch of
        attributes.

        This function is useful to map various information tidbits on groups,
        roles, etc to a unique ID in Cerebrum for that particular kind of
        attributes. Each L{group_kind} results in a group in Cerebrum and this
        function calculates that group's id (not entity_id, but the id used in
        CF).

        @type group_kind: basestring
        @param group_kind:
          A tag that describes what kind of information is to be expected in
          L{attributes}. The ONLY legal values are:

            - 'stprog', 'kull', 'kullklasse', 'undenh', 'undakt'
            - 'student-undenh', 'student-undakt', 'student-kullklasse',
              'student-kull'

          Each kind has a different set of keys in attributes that MUST be
          present.

        @type attributes: dict (of basestring -> basestring)
        @param attributes:
          A collection of attributes. This collection may contain more than what
          is required by L{group_kind}.

        @rtype: basestring or None
        @return:
          None if an id could not be constructed. The id itself otherwise.
        """

        # easiest way to copy, since we modify these destructively
        attrs = lower(attributes)

        if group_kind not in self.group_kind2required_keys:
            logger.warn("Don't know how to process attributes "
                        "belonging to '%s' (%s)",
                        group_kind, repr(attrs))
            return None

        keys = self.group_kind2required_keys[group_kind]
        if not all(x in attrs for x in keys):
            logger.warn("Missing essential keys for kind=%s. "
                        "Required=%s, available=%s",
                        group_kind, sorted(keys), sorted(attrs))
            return None

        # Now, those that have "terminnr" > 1 MUST be remapped.
        if "terminnr" in keys:
            attrs = count_back_semesters(attrs)

        result_id = self.group_kind2name_template[group_kind]
        result_id = result_id % attrs
        return result_id
Пример #5
0
    def fixup_attributes(self, attributes):
        """Convert attributes to standard form and amend with extra keys.

        This is a convenience/external method.
        """

        # Force lowercase, so we won't have to bother about this later.
        attrs = lower(attributes)
        # Force-insert a few required attributes
        attrs = self._extend_attributes(attrs)
        return attrs
Пример #6
0
    def fixup_attributes(self, attributes):
        """Convert attributes to standard form and amend with extra keys.

        This is a convenience/external method.
        """

        # Force lowercase, so we won't have to bother about this later.
        attrs = lower(attributes)
        # Force-insert a few required attributes
        attrs = self._extend_attributes(attrs)
        return attrs
Пример #7
0
    def _stprog2avdeling(self, stprog_file):
        """Create a dictionary mapping stprog to avdeling (department).

        fs.studieprogram.faknr_studieansv is the value we want.
        """

        result = dict()
        for entry in EduDataGetter(stprog_file, logger).iter_stprog():
            attrs = lower(entry)
            stprog = attrs["studieprogramkode"]
            result[stprog] = "%02d0000" % int(attrs["faknr_studieansv"])

        logger.debug("Collected %d stprog->avdeling mappings from %s",
                     len(result), stprog_file)
        return result
Пример #8
0
    def _stprog2avdeling(self, stprog_file):
        """Create a dictionary mapping stprog to avdeling (department).

        fs.studieprogram.faknr_studieansv is the value we want.
        """

        result = dict()
        for entry in EduDataGetter(stprog_file, logger).iter_stprog():
            attrs = lower(entry)
            stprog = attrs["studieprogramkode"]
            result[stprog] = "%02d0000" % int(attrs["faknr_studieansv"])

        logger.debug("Collected %d stprog->avdeling mappings from %s",
                     len(result), stprog_file)
        return result
Пример #9
0
    def _load_emne_names(self, undenh_file):
        """Slurp in the human-friendly names from undenh_file.
        """

        result = dict()
        for entry in EduDataGetter(undenh_file,
                                   logger).iter_undenh("undenhet"):
            if "emnenavn_bokmal" in entry:
                name = entry["emnenavn_bokmal"]
            elif "emnenavnfork" in entry:
                name = entry["emnenavnfork"]
            else:
                name = ""

            result[lower(entry["emnekode"])] = name
        return result
Пример #10
0
    def _load_emne_names(self, undenh_file):
        """Slurp in the human-friendly names from undenh_file.
        """

        result = dict()
        for entry in EduDataGetter(undenh_file,
                                   logger).iter_undenh("undenhet"):
            if "emnenavn_bokmal" in entry:
                name = entry["emnenavn_bokmal"]
            elif "emnenavnfork" in entry:
                name = entry["emnenavnfork"]
            else:
                name = ""

            result[lower(entry["emnekode"])] = name
        return result
Пример #11
0
    def _load_exportable_keys(self, stprog_file, undenh_file, undakt_file):
        """Build a set of FS 'entity' keys that are exportable to LMS.

        There is a constraint placed by hiof on stprog, undenh and undakt. If
        status_eksport_lms = 'J', then the entity in question is exportable to
        CF. If it is NOT, then it should be interpreted as if the entity did
        not exist.

        This means that any group related to, say, a non-exportable
        stprog is skipped as well (*ALL* kull/kullklasse/roles associated with
        that stprog).

        @param stprog_file: See L{__init__}.

        @param undenh_file: See L{__init__}.

        @param undakt_file: See L{__init_-}

        @rtype: set (of str)
        @return:
           A dict containing the keys for all exportable stprog/undenh/undakt
           and the corresponding names. The latter is useful for group naming.
        """

        result = set()
        for (source,
             entry_kind) in ((EduDataGetter(stprog_file, logger).iter_stprog,
                              "stprog",),
                             (lambda:
                              EduDataGetter(undenh_file,
                                            logger).iter_undenh("undenhet"),
                              "undenh",),
                             (EduDataGetter(undakt_file, logger).iter_undakt,
                              "undakt",)):
            logger.debug("Loading exportable %s", entry_kind)
            for entry in source():
                attrs = lower(entry)
                key = self._attributes2exportable_key(entry_kind, attrs)
                if attrs["status_eksport_lms"] == 'j':
                    result.add(key)

                logger.debug("%s=%s is%sexportable",
                             entry_kind, key,
                             key in result and " " or " not ")
        return result
Пример #12
0
    def _load_exportable_keys(self, stprog_file, undenh_file, undakt_file):
        """Build a set of FS 'entity' keys that are exportable to LMS.

        There is a constraint placed by hiof on stprog, undenh and undakt. If
        status_eksport_lms = 'J', then the entity in question is exportable to
        CF. If it is NOT, then it should be interpreted as if the entity did
        not exist.

        This means that any group related to, say, a non-exportable
        stprog is skipped as well (*ALL* kull/kullklasse/roles associated with
        that stprog).

        @param stprog_file: See L{__init__}.

        @param undenh_file: See L{__init__}.

        @param undakt_file: See L{__init_-}

        @rtype: set (of str)
        @return:
           A dict containing the keys for all exportable stprog/undenh/undakt
           and the corresponding names. The latter is useful for group naming.
        """

        result = set()
        for (source, 
             entry_kind) in ((EduDataGetter(stprog_file, logger).iter_stprog,
                              "stprog",),
                             (lambda :
                                EduDataGetter(undenh_file,
                                              logger).iter_undenh("undenhet"),
                              "undenh",),
                             (EduDataGetter(undakt_file, logger).iter_undakt,
                              "undakt",)):
            logger.debug("Loading exportable %s", entry_kind)
            for entry in source():
                attrs = lower(entry)
                key = self._attributes2exportable_key(entry_kind, attrs)
                if attrs["status_eksport_lms"] == 'j':
                    result.add(key)

                logger.debug("%s=%s is%sexportable",
                             entry_kind, key,
                             key in result and " " or " not ")
        return result
Пример #13
0
    def _attributes2exportable_key(self, attr_kind, attributes):
        """A help method to create an internal lookup key.

        This is for internal usage only. The key is similar to
        group.group_name for the groups we create (but not quite the same).

        @type attr_kind: basestring
        @param attr_kind:
           String tagging the attributes.

        @type attributes: dict (basestring -> basestring)
        @param attributes:
           Attributes from which a key is derived

        @rtype: basestring
        @return:
           Key calculated from L{attributes}.
        """
        key = None

        attrs = lower(attributes)

        if attr_kind == "undenh":
            attrs = count_back_semesters(attrs)
            key = ":".join((attrs[x] for x in
                            ("arstall", "terminkode",
                             "emnekode", "versjonskode", "terminnr")))
        elif attr_kind == "undakt":
            attrs = count_back_semesters(attrs)
            key = ":".join((attrs[x] for x in
                            ("arstall", "terminkode",
                             "emnekode", "versjonskode", "terminnr",
                             "aktivitetkode")))
        elif attr_kind in ("stprog", "kull", "kullklasse"):
            key = attributes["studieprogramkode"]
        else:
            assert False, "NOTREACHED"

        return key
Пример #14
0
    def _attributes2exportable_key(self, attr_kind, attributes):
        """A help method to create an internal lookup key.

        This is for internal usage only. The key is similar to
        group.group_name for the groups we create (but not quite the same).

        @type attr_kind: basestring
        @param attr_kind:
           String tagging the attributes.

        @type attributes: dict (basestring -> basestring)
        @param attributes:
           Attributes from which a key is derived

        @rtype: basestring
        @return:
           Key calculated from L{attributes}.
        """
        key = None

        attrs = lower(attributes)

        if attr_kind == "undenh":
            attrs = count_back_semesters(attrs)
            key = ":".join((attrs[x] for x in
                            ("arstall", "terminkode",
                             "emnekode", "versjonskode", "terminnr")))
        elif attr_kind == "undakt":
            attrs = count_back_semesters(attrs)
            key = ":".join((attrs[x] for x in
                            ("arstall", "terminkode",
                             "emnekode", "versjonskode", "terminnr",
                             "aktivitetkode")))
        elif attr_kind in ("stprog", "kull", "kullklasse"):
            key = attributes["studieprogramkode"]
        else:
            assert False, "NOTREACHED"

        return key
Пример #15
0
 def slurp_emne(element, attributes):
     if element == "emne":
         emne = lower(attributes["emnekode"])
         result[emne] = "%02d0000" % int(attributes["faknr_reglement"])
Пример #16
0
 def slurp_emne(element, attributes):
     if element == "emne":
         emne = lower(attributes["emnekode"])
         result[emne] = "%02d0000" % int(attributes["faknr_reglement"])