This huge function generates a hierarchy with hopefully more
    clear structure of modules/sections/lectures.

def _iter_modules(modules, class_name, path, ignored_formats, args):
    """
    This huge function generates a hierarchy with hopefully more
    clear structure of modules/sections/lectures.
    """
    file_formats = args.file_formats
    lecture_filter = args.lecture_filter
    resource_filter = args.resource_filter
    section_filter = args.section_filter
    verbose_dirs = args.verbose_dirs
    combined_section_lectures_nums = args.combined_section_lectures_nums

    class IterModule(object):
        def __init__(self, index, module):
            self.index = index
            self.name = '%02d_%s' % (index + 1, module[0])
            self._module = module

        @property
        def sections(self):
            sections = self._module[1]
            for (secnum, (section, lectures)) in enumerate(sections):
                if section_filter and not re.search(section_filter, section):
                    logging.debug('Skipping b/c of sf: %s %s',
                                  section_filter, section)
                    continue

                yield IterSection(self, secnum, section, lectures)

    class IterSection(object):
        def __init__(self, module_iter, secnum, section, lectures):
            self.index = secnum
            self.name = '%02d_%s' % (secnum, section)
            self.dir = os.path.join(
                path, class_name, module_iter.name,
                format_section(secnum + 1, section,
                               class_name, verbose_dirs))
            self._lectures = lectures

        @property
        def lectures(self):
            for (lecnum, (lecname, lecture)) in enumerate(self._lectures):
                if lecture_filter and not re.search(lecture_filter, lecname):
                    logging.debug('Skipping b/c of lf: %s %s',
                                  lecture_filter, lecname)
                    continue

                yield IterLecture(self, lecnum, lecname, lecture)

    class IterLecture(object):
        def __init__(self, section_iter, lecnum, lecname, lecture):
            self.index = lecnum
            self.name = lecname
            self._lecture = lecture
            self._section_iter = section_iter

        def filename(self, fmt, title):
            lecture_filename = get_lecture_filename(
                combined_section_lectures_nums,
                self._section_iter.dir, self._section_iter.index,
                self.index, self.name, title, fmt)
            return lecture_filename

        @property
        def resources(self):
            resources_to_get = find_resources_to_get(
                self._lecture, file_formats, resource_filter,
                ignored_formats)

            for fmt, url, title in resources_to_get:
                yield IterResource(fmt, url, title)

    class IterResource(object):
        def __init__(self, fmt, url, title):
            self.fmt = fmt
            self.url = url
            self.title = title

    for index, module in enumerate(modules):
        yield IterModule(index, module)