def handle(self, *args, **options): # Check by arguments. if len(args) > 0: if "/" in args[0]: course_key, exercise_key = args[0].split("/", 1) else: course_key = args[0] exercise_key = None course = config.course_entry(course_key) if course is None: raise CommandError("Course not found for key: %s" % (course_key)) self.stdout.write("Configuration syntax ok for: %s" % (course_key)) if exercise_key: (_course, exercise) = config.exercise_entry(course_key, exercise_key) if exercise is None: raise CommandError("Exercise not found for key: %s/%s" % (course_key, exercise_key)) self.stdout.write("Configuration syntax ok for: %s/%s" % (course_key, exercise_key)) else: (_course, exercises) = config.exercises(course_key) for exercise in exercises: self.stdout.write("Configuration syntax ok for: %s/%s" % (course_key, exercise["key"])) # Check all. else: for course in config.courses(): self.stdout.write("Configuration syntax ok for: %s" % (course["key"])) (_course, exercises) = config.exercises(course["key"]) for exercise in exercises: self.stdout.write("Configuration syntax ok for: %s/%s" % (course["key"], exercise["key"]))
def handle(self, *args, **options): view_types = {} for course in config.courses(): course_name = course['key'] (_, exercises) = config.exercises(course_name) for exercise in exercises: view_type = exercise.get('view_type', None) if view_type == 'access.types.stdsync.createForm' and ( 'container' in exercise or 'actions' in exercise): view_type += " [async]" view_types.setdefault(view_type, []).append( (course_name, exercise['key'])) for view_list in view_types.values(): view_list.sort() summary = [(key, len(courses)) for key, courses in view_types.items()] summary.sort(key=lambda x: (x[1], x[0]), reverse=True) print("\n ALL:") for key, count in summary: courses = view_types[key] print("%s (%d)" % (key, count)) for course, exercise in courses: print(" - %s/%s" % (course, exercise)) print("\n SUMMARY:") for key, count in summary: print("%s (%d)" % (key, count))
def handle(self, *args, **options): course_key = options["course_key"] exercise_key = options["exercise_key"] course = config.course_entry(course_key) if course is None: raise CommandError("Course not found for key: %s" % (course_key)) if exercise_key: (_course, exercise) = config.exercise_entry(course_key, exercise_key) if exercise is None: raise CommandError("Exercise not found for key: %s/%s" % (course_key, exercise_key)) if not ("personalized" in exercise and exercise["personalized"]): raise CommandError('Exercise %s/%s is not personalized (check setting "personalized") ' \ 'and hence generating is impossible' % (course_key, exercise_key)) exercises = [exercise] else: (_course, exercises) = config.exercises(course_key) # take only personalized exercises exercises = list( filter(lambda ex: "personalized" in ex and ex["personalized"], exercises)) if not exercises: self.stdout.write( self.style.WARNING( "The course %s has no personalized exercises so no instances are generated." % (course_key))) return # course and exercises have been parsed if options["instances"] < 1: raise CommandError("--instances value must be at least 1") try: for ex in exercises: if options[ "gen_if_none_exist"] and pregenerated_exercise_instances( course, ex): # some instances already exist so do not delete them and do not generate any new instances continue if not options["keep_old"]: delete_pregenerated_exercise_instances(course, ex) # check if there are any users that had accessed any of the old, deleted instances for _ in glob.iglob( os.path.join(settings.PERSONALIZED_CONTENT_PATH, course_key, "users", "*", ex["key"])): self.stderr.write("Warning: previous exercise instances for %s/%s " \ "were deleted but there are users that had accessed those instances" % (course_key, ex["key"])) break # ensure that base directory exists prepare_pregenerated_exercises_directory(course, ex) generate_exercise_instances(course, ex, options["instances"]) except Exception as e: raise CommandError(str(e))
def handle(self, *args, **options): images = {} for course in config.courses(): course_name = course['key'] (_, exercises) = config.exercises(course_name) for exercise in exercises: container = exercise.get('container', {}) image = container.get("image") if image: base, has_tag, tag = image.rpartition(':') if not has_tag: base, tag = tag, 'latest' course_counts = images.setdefault(base, {}).setdefault(tag, {}) if course_name in course_counts: course_counts[course_name] += 1 else: course_counts[course_name] = 1 image_counts = [] for image, tags in images.items(): image_count = 0 tag_counts = [] for tag, courses in tags.items(): course_counts = [(count, course) for course, count in courses.items()] course_counts.sort(reverse=True) tag_count = sum((x for x, _ in course_counts)) tag_counts.append((tag_count, tag, course_counts)) image_count += tag_count tag_counts.sort(reverse=True) image_counts.append((image_count, image, tag_counts)) image_counts.sort(reverse=True) for image_count, image, tag_counts in image_counts: for tag_count, tag, course_counts in tag_counts: print("%s:%s %d:" % (image, tag, tag_count)) for count, course in course_counts: print(" - %s: %d" % (course, count))
def handle(self, *args, **options): course_key = options["course_key"] exercise_key = options["exercise_key"] course = config.course_entry(course_key) if course is None: raise CommandError("Course not found for key: %s" % (course_key)) if exercise_key: (_course, exercise) = config.exercise_entry(course_key, exercise_key) if exercise is None: raise CommandError("Exercise not found for key: %s/%s" % (course_key, exercise_key)) if not ("personalized" in exercise and exercise["personalized"]): raise CommandError('Exercise %s/%s is not personalized (check setting "personalized") ' \ 'and hence generating is impossible' % (course_key, exercise_key)) exercises = [exercise] else: (_course, exercises) = config.exercises(course_key) # take only personalized exercises exercises = list(filter(lambda ex: "personalized" in ex and ex["personalized"], exercises)) if not exercises: self.stdout.write(self.style.WARNING("The course %s has no personalized exercises so no instances are generated." % (course_key))) return # course and exercises have been parsed if options["instances"] < 1: raise CommandError("--instances value must be at least 1") try: for ex in exercises: if options["gen_if_none_exist"] and pregenerated_exercise_instances(course, ex): # some instances already exist so do not delete them and do not generate any new instances continue if not options["keep_old"]: delete_pregenerated_exercise_instances(course, ex) # check if there are any users that had accessed any of the old, deleted instances for _ in glob.iglob(os.path.join(settings.PERSONALIZED_CONTENT_PATH, course_key, "users", "*", ex["key"])): self.stderr.write("Warning: previous exercise instances for %s/%s " \ "were deleted but there are users that had accessed those instances" % (course_key, ex["key"])) break # ensure that base directory exists prepare_pregenerated_exercises_directory(course, ex) generate_exercise_instances(course, ex, options["instances"]) except Exception as e: raise CommandError(str(e))