From 538ec80f6abeb3166dd97a4f9d7df921e1888af3 Mon Sep 17 00:00:00 2001 From: Alex Little Date: Thu, 21 Nov 2019 16:16:57 +0200 Subject: [PATCH] #476 fix line length issues --- activitylog/migrations/0001_initial.py | 19 ++++-- activitylog/views.py | 13 +++-- av/forms.py | 5 +- .../commands/generate_media_images.py | 8 +-- av/migrations/0001_initial.py | 6 +- gamification/views.py | 8 +-- helpers/templatetags/query_string.py | 23 +++++--- helpers/templatetags/settings_value.py | 6 +- integrations/dhis/views.py | 39 ++++++++----- oppia/permissions.py | 31 +++++----- profile/migrations/0001_initial.py | 26 +++++++-- profile/views.py | 58 +++++++++++++------ reports/migrations/0001_initial.py | 16 ++++- reports/views.py | 26 ++++++--- summary/cron.py | 4 +- summary/models/user_course_summary.py | 6 +- tests/api/test_media_upload.py | 22 +++++-- viz/management/commands/cartodb_update.py | 32 +++++----- viz/views.py | 40 ++++++++----- 19 files changed, 256 insertions(+), 132 deletions(-) diff --git a/activitylog/migrations/0001_initial.py b/activitylog/migrations/0001_initial.py index 88a13ae94..c3a3d58e2 100644 --- a/activitylog/migrations/0001_initial.py +++ b/activitylog/migrations/0001_initial.py @@ -20,11 +20,22 @@ class Migration(migrations.Migration): migrations.CreateModel( name='UploadedActivityLog', fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('created_date', models.DateTimeField(default=django.utils.timezone.now, verbose_name=b'date created')), - ('lastupdated_date', models.DateTimeField(default=django.utils.timezone.now, verbose_name=b'date updated')), + ('id', models.AutoField(auto_created=True, + primary_key=True, + serialize=False, + verbose_name='ID')), + ('created_date', + models.DateTimeField(default=django.utils.timezone.now, + verbose_name=b'date created')), + ('lastupdated_date', + models.DateTimeField(default=django.utils.timezone.now, + verbose_name=b'date updated')), ('file', models.FileField(upload_to=b'activitylog/%Y/%m/')), - ('create_user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='activitylog_create_user', to=settings.AUTH_USER_MODEL)), + ('create_user', + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name='activitylog_create_user', + to=settings.AUTH_USER_MODEL)), ], options={ 'verbose_name': 'Uploaded Activity Log', diff --git a/activitylog/views.py b/activitylog/views.py index 5ed6dea45..43fecd030 100644 --- a/activitylog/views.py +++ b/activitylog/views.py @@ -36,7 +36,7 @@ def process_uploaded_trackers(request, trackers, user, user_api_key): u"Already uploaded: tracker activity %(uuid)s for \ %(username)s added" % {'username': user.username, 'uuid': tracker.get('digest')}), - 'danger') + 'danger') def process_uploaded_quizresponses(request, @@ -94,7 +94,8 @@ def process_uploaded_file(request, json_data): req_user = User.objects.filter(username=username).first() try: - user_api_key, created = ApiKey.objects.get_or_create(user=req_user) + user_api_key, created = ApiKey.objects \ + .get_or_create(user=req_user) if (created): messages.warning(request, _( u"Generated new ApiKey for %(username)s : %(apikey)s" % { @@ -169,8 +170,9 @@ def upload_view(request): activity_log_file = request.FILES["activity_log_file"] # save activity_log_file - uploaded_activity_log = UploadedActivityLog(create_user=request.user, - file=activity_log_file) + uploaded_activity_log = \ + UploadedActivityLog(create_user=request.user, + file=activity_log_file) uploaded_activity_log.save() # open file and process @@ -178,7 +180,8 @@ def upload_view(request): file_data = file.read() success = process_activitylog(request, file_data) if success: - return HttpResponseRedirect(reverse('oppia_activitylog_upload_success')) + return HttpResponseRedirect( + reverse('oppia_activitylog_upload_success')) else: form = UploadActivityLogForm() return render(request, 'activitylog/upload.html', diff --git a/av/forms.py b/av/forms.py index ccf0f9af1..79e2c88c5 100644 --- a/av/forms.py +++ b/av/forms.py @@ -53,8 +53,9 @@ def clean(self): and media_file.content_type not in settings.OPPIA_MEDIA_FILE_TYPES: raise forms.ValidationError(_(u"You may only upload a media file \ which is one of the following types: \ - %s" - % ', '.join(settings.OPPIA_MEDIA_FILE_TYPES))) + %s" + % ', ' + .join(settings.OPPIA_MEDIA_FILE_TYPES))) ''' check this file hasn't already been uploaded diff --git a/av/management/commands/generate_media_images.py b/av/management/commands/generate_media_images.py index 551656e6d..ba2fb71c6 100644 --- a/av/management/commands/generate_media_images.py +++ b/av/management/commands/generate_media_images.py @@ -41,10 +41,10 @@ def handle(self, *args, **options): self.stdout.write(" > Generating miniatures... \r", ) image_generator_command = ("%s %s" % (settings.SCREENSHOT_GENERATOR_PROGRAM, settings.SCREENSHOT_GENERATOR_PROGRAM_PARAMS)) \ - % (m.file.path, - content.SCREENSHOT_IMAGE_WIDTH, - content.SCREENSHOT_IMAGE_HEIGHT, - cache_dir) + % (m.file.path, + content.SCREENSHOT_IMAGE_WIDTH, + content.SCREENSHOT_IMAGE_HEIGHT, + cache_dir) ffmpeg = subprocess.Popen(image_generator_command, shell=True, stdout=subprocess.PIPE, diff --git a/av/migrations/0001_initial.py b/av/migrations/0001_initial.py index 25b0ab698..aa50f4d14 100644 --- a/av/migrations/0001_initial.py +++ b/av/migrations/0001_initial.py @@ -22,11 +22,11 @@ class Migration(migrations.Migration): primary_key=True)), ('course_shortname', models.CharField(max_length=100)), ('created_date', - models.DateTimeField(default=django.utils.timezone.now, - verbose_name=b'date created')), + models.DateTimeField(default=django.utils.timezone.now, + verbose_name=b'date created')), ('lastupdated_date', models.DateTimeField(default=django.utils.timezone.now, - verbose_name=b'date updated')), + verbose_name=b'date updated')), ('file', models.FileField(upload_to=b'uploaded')), ('image', models.FileField(default=None, upload_to=b'uploaded', diff --git a/gamification/views.py b/gamification/views.py index a6ebcf249..0143f1c55 100644 --- a/gamification/views.py +++ b/gamification/views.py @@ -193,13 +193,13 @@ def edit_course_gamification(request, course_id): default_points = { 'course': DefaultGamificationEvent.objects - .exclude(level=DefaultGamificationEvent.GLOBAL), + .exclude(level=DefaultGamificationEvent.GLOBAL), 'activity': DefaultGamificationEvent.objects - .filter(level=DefaultGamificationEvent.ACTIVITY), + .filter(level=DefaultGamificationEvent.ACTIVITY), 'quiz': DefaultGamificationEvent.objects - .filter(level=DefaultGamificationEvent.QUIZ), + .filter(level=DefaultGamificationEvent.QUIZ), 'media': DefaultGamificationEvent.objects - .filter(level=DefaultGamificationEvent.MEDIA) + .filter(level=DefaultGamificationEvent.MEDIA) } course_events = CourseGamificationEvent.objects.filter(course=course) diff --git a/helpers/templatetags/query_string.py b/helpers/templatetags/query_string.py index f892b5c93..f3c185c97 100644 --- a/helpers/templatetags/query_string.py +++ b/helpers/templatetags/query_string.py @@ -14,16 +14,23 @@ def query_string(parser, token): If a given value is a context variable it will resolve it. Usage: - http://www.url.com/{% query_string "param_to_add=value, param_to_add=value" - "param_to_remove, params_to_remove" %} + http://www.url.com/{% query_string "param_to_add=value, + param_to_add=value" + "param_to_remove, + params_to_remove" %} """ try: tag_name, add_string, remove_string = token.split_contents() except ValueError: - raise(template.TemplateSyntaxError, "%r tag requires two arguments" % token.contents.split()[0]) - if not (add_string[0] == add_string[-1] and add_string[0] in ('"', "'")) or not (remove_string[0] == remove_string[-1] and remove_string[0] in ('"', "'")): - raise(template.TemplateSyntaxError, "%r tag's argument should be in quotes" % tag_name) + raise(template.TemplateSyntaxError, + "%r tag requires two arguments" % token.contents.split()[0]) + if not (add_string[0] == add_string[-1] + and add_string[0] in ('"', "'")) \ + or not (remove_string[0] == remove_string[-1] + and remove_string[0] in ('"', "'")): + raise(template.TemplateSyntaxError, + "%r tag's argument should be in quotes" % tag_name) add = string_to_dict(add_string[1:-1]) remove = string_to_list(remove_string[1:-1]) @@ -63,8 +70,10 @@ def get_query_string(p, new_params, remove, context): except: p[k] = v - return mark_safe('?' + '&'.join([u'%s=%s' % (urllib.parse.quote_plus(str(k)), - urllib.parse.quote_plus(str(v))) for k, v in p.items()])) + return mark_safe('?' + '&' + .join([u'%s=%s' % (urllib.parse.quote_plus(str(k)), + urllib.parse.quote_plus(str(v))) + for k, v in p.items()])) # Taken from lib/utils.py diff --git a/helpers/templatetags/settings_value.py b/helpers/templatetags/settings_value.py index cd8fb00cc..f011a652e 100644 --- a/helpers/templatetags/settings_value.py +++ b/helpers/templatetags/settings_value.py @@ -3,7 +3,11 @@ register = template.Library() -ALLOWABLE_VALUES = ("OPPIA_ANDROID_PACKAGEID", "OPPIA_ANDROID_ON_GOOGLE_PLAY", "OPPIA_ANDROID_DEFAULT_PACKAGEID", "BASESITE_URL", "OPPIA_MAX_UPLOAD_SIZE") +ALLOWABLE_VALUES = ("OPPIA_ANDROID_PACKAGEID", + "OPPIA_ANDROID_ON_GOOGLE_PLAY", + "OPPIA_ANDROID_DEFAULT_PACKAGEID", + "BASESITE_URL", + "OPPIA_MAX_UPLOAD_SIZE") # settings value (based on https://stackoverflow.com/a/21593607) @register.simple_tag diff --git a/integrations/dhis/views.py b/integrations/dhis/views.py index 580eedc35..5ce3379d1 100644 --- a/integrations/dhis/views.py +++ b/integrations/dhis/views.py @@ -27,10 +27,14 @@ def home(request): @staff_member_required def export_latest(request): - last_month = datetime.datetime.now() + dateutil.relativedelta.relativedelta(months=-1) + last_month = datetime.datetime.now() \ + + dateutil.relativedelta.relativedelta(months=-1) data = create_csv(last_month.year, last_month.month) - response = HttpResponse(data.csv, content_type='application/text;charset=utf-8') - response['Content-Disposition'] = "attachment; filename=dhis-export-{year}-{month}.csv".format(year=last_month.year, month=last_month.month) + response = HttpResponse(data.csv, + content_type='application/text;charset=utf-8') + response['Content-Disposition'] = \ + "attachment; filename=dhis-export-{year}-{month}.csv" \ + .format(year=last_month.year, month=last_month.month) return response @@ -38,8 +42,11 @@ def export_latest(request): @staff_member_required def export_month(request, year, month): data = create_csv(year, month) - response = HttpResponse(data.csv, content_type='application/text;charset=utf-8') - response['Content-Disposition'] = "attachment; filename=dhis-export-{year}-{month}.csv".format(year=year, month=month) + response = HttpResponse(data.csv, + content_type='application/text;charset=utf-8') + response['Content-Disposition'] = \ + "attachment; filename=dhis-export-{year}-{month}.csv" \ + .format(year=year, month=month) return response @@ -56,17 +63,21 @@ def create_csv(year, month): data = tablib.Dataset(*data, headers=headers) # get all the usernames for users who've had trackers or quizzes submitted - users = Tracker.objects.filter(submitted_date__month=month, - submitted_date__year=year).values('user').distinct() + users = Tracker.objects \ + .filter(submitted_date__month=month, + submitted_date__year=year).values('user').distinct() for user in users: - activities_completed = Tracker.objects.filter(submitted_date__month=month, - submitted_date__year=year, - user__id=user['user'], - completed=True).count() - points_earned = Tracker.objects.filter(submitted_date__month=month, - submitted_date__year=year, - user__id=user['user']).aggregate(Sum('points'))['points__sum'] + activities_completed = Tracker.objects \ + .filter(submitted_date__month=month, + submitted_date__year=year, + user__id=user['user'], + completed=True).count() + points_earned = Tracker.objects \ + .filter(submitted_date__month=month, + submitted_date__year=year, + user__id=user['user']) \ + .aggregate(Sum('points'))['points__sum'] quizzes_passed = Tracker.objects.filter(submitted_date__month=month, submitted_date__year=year, user__id=user['user'], diff --git a/oppia/permissions.py b/oppia/permissions.py index 042a17eaa..9dc5bf16f 100644 --- a/oppia/permissions.py +++ b/oppia/permissions.py @@ -67,24 +67,21 @@ def get_user(request, view_user_id): return view_user, None except User.DoesNotExist: raise Http404() - else: - try: - view_user = User.objects.get(pk=view_user_id) - courses = Course.objects.filter( - coursecohort__cohort__participant__user=view_user, - coursecohort__cohort__participant__role=Participant.STUDENT) \ - .filter( - coursecohort__cohort__participant__user= - request.user, - coursecohort__cohort__participant__role= - Participant.TEACHER) \ - .count() - if courses > 0: - return view_user, None - else: - raise exceptions.PermissionDenied - except User.DoesNotExist: + try: + view_user = User.objects.get(pk=view_user_id) + courses = Course.objects.filter( + coursecohort__cohort__participant__user=view_user, + coursecohort__cohort__participant__role=Participant.STUDENT) \ + .filter( + coursecohort__cohort__participant__user=request.user, + coursecohort__cohort__participant__role=Participant.TEACHER) \ + .count() + if courses > 0: + return view_user, None + else: raise exceptions.PermissionDenied + except User.DoesNotExist: + raise exceptions.PermissionDenied def get_user_courses(request, view_user): diff --git a/profile/migrations/0001_initial.py b/profile/migrations/0001_initial.py index e7e0ad0a3..0fd3d5614 100644 --- a/profile/migrations/0001_initial.py +++ b/profile/migrations/0001_initial.py @@ -20,13 +20,27 @@ class Migration(migrations.Migration): migrations.CreateModel( name='UserProfile', fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('about', models.TextField(blank=True, default=None, null=True)), + ('id', models.AutoField(auto_created=True, + primary_key=True, + serialize=False, + verbose_name='ID')), + ('about', models.TextField(blank=True, + default=None, + null=True)), ('can_upload', models.BooleanField(default=False)), - ('job_title', models.TextField(blank=True, default=None, null=True)), - ('organisation', models.TextField(blank=True, default=None, null=True)), - ('phone_number', models.TextField(blank=True, default=None, null=True)), - ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ('job_title', models.TextField(blank=True, + default=None, + null=True)), + ('organisation', models.TextField(blank=True, + default=None, + null=True)), + ('phone_number', models.TextField(blank=True, + default=None, + null=True)), + ('user', + models.OneToOneField( + on_delete=django.db.models.deletion.CASCADE, + to=settings.AUTH_USER_MODEL)), ], ), ] diff --git a/profile/views.py b/profile/views.py index 78997f226..329eff7c4 100644 --- a/profile/views.py +++ b/profile/views.py @@ -101,8 +101,9 @@ def login_view(request): def register(request): - self_register = SettingProperties.get_int(constants.OPPIA_ALLOW_SELF_REGISTRATION, - settings.OPPIA_ALLOW_SELF_REGISTRATION) + self_register = SettingProperties \ + .get_int(constants.OPPIA_ALLOW_SELF_REGISTRATION, + settings.OPPIA_ALLOW_SELF_REGISTRATION) if not self_register: raise Http404 @@ -195,7 +196,8 @@ def edit(request, user_id=0): view_user.last_name = last_name view_user.save() - user_profile, created = UserProfile.objects.get_or_create(user=view_user) + user_profile, created = UserProfile.objects \ + .get_or_create(user=view_user) user_profile.job_title = form.cleaned_data.get("job_title") user_profile.organisation = form.cleaned_data.get("organisation") user_profile.save() @@ -209,7 +211,8 @@ def edit(request, user_id=0): view_user.save() messages.success(request, _(u"Password updated")) else: - user_profile, created = UserProfile.objects.get_or_create(user=view_user) + user_profile, created = UserProfile.objects \ + .get_or_create(user=view_user) form = ProfileForm(initial={'username': view_user.username, 'email': view_user.email, @@ -217,7 +220,8 @@ def edit(request, user_id=0): 'last_name': view_user.last_name, 'api_key': key.key, 'job_title': user_profile.job_title, - 'organisation': user_profile.organisation}) + 'organisation': + user_profile.organisation}) return render(request, 'profile/profile.html', {'form': form}) @@ -233,7 +237,8 @@ def export_mydata_view(request, data_type): for mqa in my_quiz_attempts: data = {} data['quizattempt'] = mqa - data['quizattemptresponses'] = QuizAttemptResponse.objects.filter(quizattempt=mqa) + data['quizattemptresponses'] = QuizAttemptResponse.objects \ + .filter(quizattempt=mqa) my_quizzes.append(data) return render(request, 'profile/export/quiz_attempts.html', @@ -296,7 +301,8 @@ def user_activity(request, user_id): 'course_display': str(course), 'no_quizzes_completed': course_stats.quizzes_passed, 'pretest_score': course_stats.pretest_score, - 'no_activities_completed': course_stats.completed_activities, + 'no_activities_completed': + course_stats.completed_activities, 'no_media_viewed': course_stats.media_viewed, 'no_points': course_stats.points, 'no_badges': course_stats.badges_achieved, } @@ -335,7 +341,8 @@ def user_activity(request, user_id): start_date = timezone.now() - datetime.timedelta(days=31) end_date = timezone.now() - course_ids = list(chain(cohort_courses.values_list('id', flat=True), other_courses.values_list('id', flat=True))) + course_ids = list(chain(cohort_courses.values_list('id', flat=True), + other_courses.values_list('id', flat=True))) activity = get_tracker_activities(start_date, end_date, view_user, @@ -357,8 +364,9 @@ def user_course_activity_view(request, user_id, course_id): dashboard_accessed.send(sender=None, request=request, data=None) course = can_view_course(request, course_id) - act_quizzes = Activity.objects.filter(section__course=course, - type=Activity.QUIZ).order_by('section__order', 'order') + act_quizzes = Activity.objects \ + .filter(section__course=course, type=Activity.QUIZ) \ + .order_by('section__order', 'order') quizzes_attempted = 0 quizzes_passed = 0 @@ -383,14 +391,22 @@ def user_course_activity_view(request, user_id, course_id): if no_attempts > 0: quiz_maxscore = float(attempts[0].maxscore) - attemps_stats = attempts.aggregate(max=Max('score'), min=Min('score'), avg=Avg('score')) + attemps_stats = attempts.aggregate(max=Max('score'), + min=Min('score'), + avg=Avg('score')) max_score = 100 * float(attemps_stats['max']) / quiz_maxscore min_score = 100 * float(attemps_stats['min']) / quiz_maxscore avg_score = 100 * float(attemps_stats['avg']) / quiz_maxscore - first_date = attempts.aggregate(date=Min('attempt_date'))['date'] - recent_date = attempts.aggregate(date=Max('attempt_date'))['date'] - first_score = 100 * float(attempts.filter(attempt_date=first_date)[0].score) / quiz_maxscore - latest_score = 100 * float(attempts.filter(attempt_date=recent_date)[0].score) / quiz_maxscore + first_date = attempts \ + .aggregate(date=Min('attempt_date'))['date'] + recent_date = attempts \ + .aggregate(date=Max('attempt_date'))['date'] + first_score = 100 * float(attempts + .filter(attempt_date=first_date)[0] + .score) / quiz_maxscore + latest_score = 100 * float(attempts + .filter(attempt_date=recent_date)[0] + .score) / quiz_maxscore passed = max_score is not None and max_score > 75 if aq.section.order == 0: @@ -666,7 +682,8 @@ def delete_account_view(request): Tracker.objects.filter(user=user).delete() # delete quiz attempts - QuizAttemptResponse.objects.filter(quizattempt__user=user).delete() + QuizAttemptResponse.objects \ + .filter(quizattempt__user=user).delete() QuizAttempt.objects.filter(user=user).delete() # delete profile @@ -679,7 +696,8 @@ def delete_account_view(request): User.objects.get(pk=user.id).delete() # redirect - return HttpResponseRedirect(reverse('profile_delete_account_complete')) + return HttpResponseRedirect( + reverse('profile_delete_account_complete')) else: form = DeleteAccountForm(initial={'username': request.user.username}) @@ -693,7 +711,11 @@ def delete_account_complete_view(request): # helper functions -def get_tracker_activities(start_date, end_date, user, course_ids=[], course=None): +def get_tracker_activities(start_date, + end_date, + user, + course_ids=[], + course=None): activity = [] no_days = (end_date - start_date).days + 1 if course: diff --git a/reports/migrations/0001_initial.py b/reports/migrations/0001_initial.py index f96192e57..7ec65353d 100644 --- a/reports/migrations/0001_initial.py +++ b/reports/migrations/0001_initial.py @@ -17,13 +17,23 @@ class Migration(migrations.Migration): migrations.CreateModel( name='DashboardAccessLog', fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('access_date', models.DateTimeField(default=django.utils.timezone.now, verbose_name=b'date created')), + ('id', models.AutoField(verbose_name='ID', + serialize=False, + auto_created=True, + primary_key=True)), + ('access_date', + models.DateTimeField(default=django.utils.timezone.now, + verbose_name=b'date created')), ('ip', models.GenericIPAddressField()), ('agent', models.TextField(blank=True)), ('url', models.TextField(blank=True)), ('data', models.TextField(blank=True)), - ('user', models.ForeignKey(on_delete=django.db.models.deletion.SET_NULL, default=None, blank=True, to=settings.AUTH_USER_MODEL, null=True)), + ('user', + models.ForeignKey(on_delete=django.db.models.deletion.SET_NULL, + default=None, + blank=True, + to=settings.AUTH_USER_MODEL, + null=True)), ], ), ] diff --git a/reports/views.py b/reports/views.py index f68ad5099..e6069ea57 100644 --- a/reports/views.py +++ b/reports/views.py @@ -13,17 +13,26 @@ def menu_reports(request): # add in here any reports that need to appear in the menu - # return [{'name': 'test', 'url':'/reports/1/'},{'name': 'test2', 'url':'/reports/2/'}] - return [{'name': _('Completion Rates'), 'url': reverse('oppia_completion_rates')}] + # return [{'name': 'test', + # 'url':'/reports/1/'}, + # {'name': 'test2', + # 'url':'/reports/2/'}] + return [{'name': _('Completion Rates'), + 'url': reverse('oppia_completion_rates')}] @staff_member_required def completion_rates(request): - courses = Course.objects.filter(is_draft=False, is_archived=False).order_by('title') + courses = Course.objects.filter(is_draft=False, + is_archived=False).order_by('title') courses_list = [] - course_stats = list(UserCourseSummary.objects.filter(course__in=courses).values('course').annotate(users=Count('user'), completed=Sum('badges_achieved'))) + course_stats = list(UserCourseSummary.objects + .filter(course__in=courses) + .values('course') + .annotate(users=Count('user'), + completed=Sum('badges_achieved'))) for course in courses: obj = {} @@ -34,10 +43,12 @@ def completion_rates(request): no_users = stats['users'] obj['enroled'] = no_users if no_users > 0: - obj['completion'] = (float(stats['completed']) / float(no_users)) * 100 + obj['completion'] = (float(stats['completed']) + / float(no_users)) * 100 else: obj['completion'] = 0 - course_stats.remove(stats) # remove the element to optimize next searchs + # remove the element to optimize next searches + course_stats.remove(stats) continue courses_list.append(obj) @@ -58,7 +69,8 @@ def course_completion_rates(request, course_id): users_incompleted = [] course_activities = course.get_no_activities() - users_stats = UserCourseSummary.objects.filter(course=course_id).order_by('user') + users_stats = UserCourseSummary.objects \ + .filter(course=course_id).order_by('user') for user_stats in users_stats: user_activities = user_stats.completed_activities diff --git a/summary/cron.py b/summary/cron.py index 8b0ac506a..393a0ceeb 100644 --- a/summary/cron.py +++ b/summary/cron.py @@ -13,8 +13,8 @@ def update_summaries(last_tracker_pk=0, last_points_pk=0): from oppia.models import Tracker, Points, Course from settings.models import SettingProperties from summary.models import UserCourseSummary, \ - CourseDailyStats, \ - UserPointsSummary + CourseDailyStats, \ + UserPointsSummary # check if cron already running prop, created = SettingProperties.objects \ diff --git a/summary/models/user_course_summary.py b/summary/models/user_course_summary.py index 3400d1bac..70a3c95f6 100644 --- a/summary/models/user_course_summary.py +++ b/summary/models/user_course_summary.py @@ -51,8 +51,10 @@ def update_summary(self, pk__lte=newest_tracker_pk) # Add the values that are directly obtained from the last pks - self.total_activity = (0 if first_tracker else self.total_activity) + self_trackers.count() - self.total_downloads = (0 if first_tracker else self.total_downloads) + self_trackers.filter(type='download').count() + self.total_activity = (0 if first_tracker else self.total_activity) \ + + self_trackers.count() + self.total_downloads = (0 if first_tracker else self.total_downloads) \ + + self_trackers.filter(type='download').count() filters = { 'user': self.user, diff --git a/tests/api/test_media_upload.py b/tests/api/test_media_upload.py index 3330523bb..cec5e528d 100644 --- a/tests/api/test_media_upload.py +++ b/tests/api/test_media_upload.py @@ -16,8 +16,10 @@ class MediaPublishResourceTest(TestCase): def setUp(self): self.client = Client() self.url = '/api/media/' - self.course_file_path = './oppia/fixtures/reference_files/ncd1_test_course.zip' - self.video_file_path = './oppia/fixtures/reference_files/sample_video.m4v' + self.course_file_path = \ + './oppia/fixtures/reference_files/ncd1_test_course.zip' + self.video_file_path = \ + './oppia/fixtures/reference_files/sample_video.m4v' # test only POST is available def test_no_get(self): @@ -100,19 +102,27 @@ def test_upload(self): mime-type is found # normal user - response = self.client.post(self.url,{'username': 'demo', 'password': 'password', 'media_file': video_file }) + response = self.client.post(self.url,{'username': 'demo', + 'password': 'password', + 'media_file': video_file }) self.assertEqual(response.status_code, 201) # teacher - response = self.client.post(self.url, { 'username': 'teacher', 'password': 'password', 'media_file': video_file }) + response = self.client.post(self.url, {'username': 'teacher', + 'password': 'password', + 'media_file': video_file }) self.assertEqual(response.status_code, 201) # staff - response = self.client.post(self.url, { 'username': 'staff', 'password': 'password', 'media_file': video_file }) + response = self.client.post(self.url, {'username': 'staff', + 'password': 'password', + 'media_file': video_file }) self.assertEqual(response.status_code, 201) # admin - response = self.client.post(self.url, { 'username': 'admin', 'password': 'password', 'media_file': video_file }) + response = self.client.post(self.url, {'username': 'admin', + 'password': 'password', + 'media_file': video_file }) self.assertEqual(response.status_code, 201) ''' pass diff --git a/viz/management/commands/cartodb_update.py b/viz/management/commands/cartodb_update.py index f6f9c4187..07bea450d 100644 --- a/viz/management/commands/cartodb_update.py +++ b/viz/management/commands/cartodb_update.py @@ -31,7 +31,8 @@ def handle(self, *args, **options): # check can connect to cartodb API sql = "SELECT * FROM %s WHERE source_site='%s'" \ % (CARTODB_TABLE, source_site) - url = "http://%s.cartodb.com/api/v2/sql?q=%s" % (cartodb_account, sql) + url = "http://%s.cartodb.com/api/v2/sql?q=%s" % (cartodb_account, + sql) u = urllib.request.urlopen(url) data = u.read() carto_db_data = json.loads(data) @@ -42,16 +43,18 @@ def handle(self, *args, **options): .filter(lat=c['lat'], lng=c['lng']).aggregate(total=Sum('hits')) if location['total'] is not None \ - and c['total_hits'] != location['total']: + and c['total_hits'] != location['total']: self.stdout.write("found - will update") cartodb_id = c['cartodb_id'] - sql = "UPDATE %s SET total_hits=%d WHERE cartodb_id=%d AND source_site='%s'" % (CARTODB_TABLE, - location['total'], - cartodb_id, - source_site) - url = "http://%s.cartodb.com/api/v2/sql?q=%s&api_key=%s" % (cartodb_account, - sql, - cartodb_key) + sql = "UPDATE %s SET total_hits=%d WHERE cartodb_id=%d \ + AND source_site='%s'" % (CARTODB_TABLE, + location['total'], + cartodb_id, + source_site) + url = "http://%s.cartodb.com/api/v2/sql?q=%s&api_key=%s" \ + % (cartodb_account, + sql, + cartodb_key) u = urllib.request.urlopen(url) data = u.read() data_json = json.loads(data) @@ -59,10 +62,10 @@ def handle(self, *args, **options): time.sleep(1) # add any new points - locations = UserLocationVisualization.objects.exclude(lat=0, - lng=0).values('lat', - 'lng', - 'country_code').annotate(total_hits=Sum('hits')) + locations = UserLocationVisualization.objects \ + .exclude(lat=0, lng=0) \ + .values('lat', 'lng', 'country_code') \ + .annotate(total_hits=Sum('hits')) for l in locations: found = False # loop through and see if in carto_db_data @@ -74,7 +77,8 @@ def handle(self, *args, **options): self.stdout.write("not found - will insert") str = "INSERT INTO %s (the_geom, lat, lng, total_hits, \ country_code, source_site) VALUES \ - (ST_SetSRID(ST_Point(%f, %f),4326),%f,%f,%d ,'%s','%s')" + (ST_SetSRID(ST_Point(%f, %f),4326), \ + %f,%f,%d ,'%s','%s')" sql = str % \ (CARTODB_TABLE, l['lng'], diff --git a/viz/views.py b/viz/views.py index dd9f97718..53dfdde37 100644 --- a/viz/views.py +++ b/viz/views.py @@ -100,7 +100,9 @@ def summary_get_countries(start_date): other_country_activity = 0 for c in hits_by_country: if i < 20: - hits_percent = float(c['country_total_hits'] * 100.0 / total_hits['total_hits']) + hits_percent = float(c['country_total_hits'] + * 100.0 + / total_hits['total_hits']) country_activity.append({'country_code': c['country_code'], 'country_name': c['country_name'], 'hits_percent': hits_percent}) @@ -108,7 +110,9 @@ def summary_get_countries(start_date): other_country_activity += c['country_total_hits'] i += 1 if i > 20: - hits_percent = float(other_country_activity * 100.0 / total_hits['total_hits']) + hits_percent = float(other_country_activity + * 100.0 + / total_hits['total_hits']) country_activity.append({'country_code': None, 'country_name': _('Other'), 'hits_percent': hits_percent}) @@ -133,13 +137,18 @@ def summary_get_languages(start_date): other_languages = 0 for hbl in hit_by_language: if i < 10: - hits_percent = float(hbl['total_hits'] * 100.0 / total_hits['total_hits']) - languages.append({'lang': hbl['lang'], 'hits_percent': hits_percent}) + hits_percent = float(hbl['total_hits'] + * 100.0 + / total_hits['total_hits']) + languages.append({'lang': hbl['lang'], + 'hits_percent': hits_percent}) else: other_languages += hbl['total_hits'] i += 1 if i > 10: - hits_percent = float(other_languages * 100.0 / total_hits['total_hits']) + hits_percent = float(other_languages + * 100.0 + / total_hits['total_hits']) languages.append({'lang': _('Other'), 'hits_percent': hits_percent}) return languages @@ -152,8 +161,10 @@ def summary_get_downloads(start_date): .annotate(year=ExtractYear('day')) \ .annotate(count=Sum('total')) \ .order_by('year', 'month') - previous_course_downloads = CourseDailyStats.objects.filter(day__lt=start_date, - type='download').aggregate(total=Sum('total')).get('total', 0) + previous_course_downloads = CourseDailyStats.objects \ + .filter(day__lt=start_date, type='download') \ + .aggregate(total=Sum('total')) \ + .get('total', 0) if previous_course_downloads is None: previous_course_downloads = 0 @@ -167,17 +178,20 @@ def summary_get_course_activity(start_date): .annotate(count=Sum('total')) \ .order_by('year', 'month') - previous_course_activity = CourseDailyStats.objects.filter(day__lt=start_date).aggregate(total=Sum('total')).get('total', 0) + previous_course_activity = CourseDailyStats.objects \ + .filter(day__lt=start_date) \ + .aggregate(total=Sum('total')) \ + .get('total', 0) if previous_course_activity is None: previous_course_activity = 0 last_month = timezone.now() - datetime.timedelta(days=131) - hit_by_course = CourseDailyStats.objects.filter(day__gte=last_month, - course__isnull=False) \ - .values('course_id') \ - .annotate(total_hits=Sum('total')) \ - .order_by('-total_hits') + hit_by_course = CourseDailyStats.objects \ + .filter(day__gte=last_month, course__isnull=False) \ + .values('course_id') \ + .annotate(total_hits=Sum('total')) \ + .order_by('-total_hits') total_hits = sum(cstats['total_hits'] for cstats in hit_by_course) i = 0