def test_get_prop_string_doesnotexist(self): key = "testkey" value = "mystring" SettingProperties.set_string(key, value) retreived_value = SettingProperties.get_property("some non key", "not here") self.assertEqual("not here", retreived_value)
def test_delete_string(self): key = "testkey1" value = "testval" SettingProperties.set_string(key, value) SettingProperties.delete_key(key) retreived_value = SettingProperties.get_string(key, "default") self.assertEqual("default", retreived_value)
def handle(self, *args, **options): if options['hours']: hours=options['hours'] else: hours=0 #check if cron already running prop, created = SettingProperties.objects.get_or_create(key='oppia_cron_lock',int_value=1) if not created: print("Oppia cron is already running") return now = time.time() path = os.path.join(settings.COURSE_UPLOAD_DIR, "temp") if os.path.exists(path): print('Cleaning up: ' + path) for f in os.listdir(path): f = os.path.join(path, f) if os.stat(f).st_mtime < now - 3600 * 6: print("deleting: {file}".format(file=f)) if os.path.isfile(f): os.remove(f) else: print('{path} does not exist. Don\'t need to clean it'.format(path=path)) from oppia.awards import courses_completed courses_completed(int(hours)) # create and new media images call_command('generate_media_images') SettingProperties.set_string('oppia_cron_last_run', timezone.now()) SettingProperties.delete_key('oppia_cron_lock')
def test_delete_int(self): key = "testkey1" value = 123 SettingProperties.set_int(key, value) SettingProperties.delete_key(key) retreived_value = SettingProperties.get_int(key, 0) self.assertEqual(0, retreived_value)
def test_self_registration_disabled_cant_view(self): # turn off self registration SettingProperties.set_int(constants.OPPIA_ALLOW_SELF_REGISTRATION,0) response = self.client.get(self.url) self.assertEqual(response.status_code, 404) # turn back on SettingProperties.set_int(constants.OPPIA_ALLOW_SELF_REGISTRATION,1)
def handle(self, *args, **options): if options['fromstart']: update_summaries(0, 0) else: # get last tracker and points PKs processed last_tracker_pk = SettingProperties.get_property('last_tracker_pk', 0) last_points_pk = SettingProperties.get_property('last_points_pk', 0) update_summaries(last_tracker_pk, last_points_pk)
def test_summary_cron(self): # check lock not set lock = SettingProperties.get_int('oppia_summary_cron_lock', 999) self.assertEqual(lock, 999) update_summaries() # check new details on pks tracker_id = SettingProperties.get_int('last_tracker_pk', 0) self.assertEqual(tracker_id, 1472216) # this id is from the test_tracker data #check unlocked again lock = SettingProperties.get_int('oppia_summary_cron_lock', 999)
def run(): print('Starting Oppia Summary cron...') start = time.time() from settings.models import SettingProperties # get last tracker and points PKs processed last_tracker_pk = SettingProperties.get_property('last_tracker_pk', 0) last_points_pk = SettingProperties.get_property('last_points_pk', 0) update_summaries(last_tracker_pk, last_points_pk) elapsed_time = time.time() - start print('cron completed, took %.2f seconds' % elapsed_time)
def test_self_registration_disabled_cant_post(self): # turn off self registration SettingProperties.set_int(constants.OPPIA_ALLOW_SELF_REGISTRATION,0) filled_form = { 'username': '******', 'email': '*****@*****.**', 'password': '******', 'password_again': 'password', 'first_name': 'Test name', 'last_name': 'Last name' } response = self.client.post(self.url, data=filled_form) self.assertEqual(response.status_code, 404) # turn back on SettingProperties.set_int(constants.OPPIA_ALLOW_SELF_REGISTRATION,1)
def register(request): self_register = SettingProperties.get_int(constants.OPPIA_ALLOW_SELF_REGISTRATION, settings.OPPIA_ALLOW_SELF_REGISTRATION) if not self_register: raise Http404 if request.method == 'POST': # if form submitted... form = RegisterForm(request.POST) if form.is_valid(): # All validation rules pass # Create new user username = form.cleaned_data.get("username") email = form.cleaned_data.get("email") password = form.cleaned_data.get("password") first_name = form.cleaned_data.get("first_name") last_name = form.cleaned_data.get("last_name") user = User.objects.create_user(username, email, password) user.first_name = first_name user.last_name = last_name user.save() user_profile = UserProfile() user_profile.user = user user_profile.job_title = form.cleaned_data.get("job_title") user_profile.organisation = form.cleaned_data.get("organisation") user_profile.save() u = authenticate(username=username, password=password) if u is not None and u.is_active: login(request, u) return HttpResponseRedirect('thanks/') return HttpResponseRedirect('thanks/') # Redirect after POST else: form = RegisterForm(initial={'next': filter_redirect(request.GET), }) return render(request, 'oppia/form.html', {'form': form, 'title': _(u'Register'), })
def test_self_registration_disabled_cant_view(self): # turn off self registration SettingProperties.set_int(constants.OPPIA_ALLOW_SELF_REGISTRATION,0) data = { 'username': '******', 'password': '******', 'passwordagain': 'secret', 'email': '*****@*****.**', 'firstname': 'demo', 'lastname': 'user', } response = self.api_client.post(self.url, format='json', data=data) self.assertHttpBadRequest(response) self.assertValidJSON(response.content) # turn back on SettingProperties.set_int(constants.OPPIA_ALLOW_SELF_REGISTRATION,1)
def handle(self, *args, **options): cartodb_account = SettingProperties.get_string(constants.OPPIA_CARBODB_ACCOUNT, None) cartodb_key = SettingProperties.get_string(constants.OPPIA_CARBODB_KEY, None) source_site = SettingProperties.get_string(constants.OPPIA_HOSTNAME, None) # 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) u = urllib.urlopen(url) data = u.read() carto_db_data = json.loads(data) # update any existing points for c in carto_db_data['rows']: location = UserLocationVisualization.objects.filter(lat=c['lat'], lng=c['lng']).aggregate(total=Sum('hits')) if location['total'] != None 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) u = urllib.urlopen(url) data = u.read() data_json = json.loads(data) self.stdout.write(data_json) 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')) for l in locations: found = False # loop through and see if in carto_db_data for c in carto_db_data['rows']: if l['lat'] == c['lat'] and l['lng'] == c['lng']: found = True if not found: self.stdout.write("not found - will insert") sql = "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')" % (CARTODB_TABLE, l['lng'], l['lat'], l['lat'], l['lng'], l['total_hits'], l['country_code'], source_site) url = "http://%s.cartodb.com/api/v2/sql?q=%s&api_key=%s" % (cartodb_account, sql, cartodb_key) u = urllib.urlopen(url) data = u.read() data_json = json.loads(data) self.stdout.write(data) time.sleep(1)
def get_settings(request): self_register = SettingProperties.get_int(constants.OPPIA_ALLOW_SELF_REGISTRATION, settings.OPPIA_ALLOW_SELF_REGISTRATION) return {'OPPIA_ALLOW_SELF_REGISTRATION': self_register, 'OPPIA_GOOGLE_ANALYTICS_ENABLED': settings.OPPIA_GOOGLE_ANALYTICS_ENABLED, 'OPPIA_GOOGLE_ANALYTICS_CODE': settings.OPPIA_GOOGLE_ANALYTICS_CODE, 'OPPIA_GOOGLE_ANALYTICS_DOMAIN': settings.OPPIA_GOOGLE_ANALYTICS_DOMAIN, 'OPPIA_SHOW_GRAVATARS': settings.OPPIA_SHOW_GRAVATARS, 'OPPIA_DEVICEADMIN_ENABLED': settings.DEVICE_ADMIN_ENABLED, 'OPPIA_REPORTS': menu_reports(request), 'DEBUG': settings.DEBUG, }
def insert_self_registration(apps, schema_editor): current = SettingProperties.get_int(constants.OPPIA_ALLOW_SELF_REGISTRATION, None) if current is None and hasattr(settings, 'OPPIA_ALLOW_SELF_REGISTRATION'): settings_prop = SettingProperties() settings_prop.key = constants.OPPIA_ALLOW_SELF_REGISTRATION settings_prop.int_value = settings.OPPIA_ALLOW_SELF_REGISTRATION settings_prop.save()
def insert_maxuploadsize(apps, schema_editor): current = SettingProperties.get_int(constants.MAX_UPLOAD_SIZE, None) if current is None and hasattr(settings, 'OPPIA_MAX_UPLOAD_SIZE'): settings_prop = SettingProperties() settings_prop.key = constants.MAX_UPLOAD_SIZE settings_prop.int_value = settings.OPPIA_MAX_UPLOAD_SIZE settings_prop.save()
def clean(self): cleaned_data = super(UploadCourseStep1Form, self).clean() file = cleaned_data.get("course_file") max_upload = SettingProperties.get_int(constants.MAX_UPLOAD_SIZE, settings.OPPIA_MAX_UPLOAD_SIZE) if file is not None and file._size > max_upload: size = int(math.floor(max_upload / 1024 / 1024)) raise forms.ValidationError(_("Your file is larger than the maximum allowed (%(size)d Mb). You may want to check your course for large includes, such as images etc.") % {'size': size, }) if file is not None and file.content_type != 'application/zip' and file.content_type != 'application/x-zip-compressed': raise forms.ValidationError(_("You may only upload a zip file")) return cleaned_data
def __init__(self, *args, **kwargs): super(UploadCourseStep1Form, self).__init__( * args, ** kwargs) max_upload = SettingProperties.get_int(constants.MAX_UPLOAD_SIZE, settings.OPPIA_MAX_UPLOAD_SIZE) self.fields['course_file'].help_text = _('Max size %(size)d Mb') % {'size': int(math.floor(max_upload / 1024 / 1024))} self.helper = FormHelper() self.helper.form_action = reverse('oppia_upload') self.helper.form_class = 'form-horizontal' self.helper.label_class = 'col-lg-2' self.helper.field_class = 'col-lg-4' self.helper.layout = Layout( 'course_file', Div( Submit('submit', _(u'Upload'), css_class='btn btn-default'), css_class='col-lg-offset-2 col-lg-4', ), )
def test_summary_cron_locked(self): # set lock not SettingProperties.set_int('oppia_summary_cron_lock', 1) lock = SettingProperties.get_int('oppia_summary_cron_lock', 0) self.assertEqual(lock, 1) update_summaries() # check new details on pks # cron is locked so nothing should happen tracker_id = SettingProperties.get_int('last_tracker_pk', 0) self.assertEqual(tracker_id, 0) #unlock SettingProperties.delete_key('oppia_summary_cron_lock') #check unlocked again lock = SettingProperties.get_int('oppia_summary_cron_lock', 999) self.assertEqual(lock, 999)
def __init__(self, *args, **kwargs): super(ProfileForm, self).__init__(* args, ** kwargs) if len(args) == 1: email = args[0]['email'] username = args[0]['username'] else: kw = kwargs.pop('initial') email = kw['email'] username = kw['username'] helpers.custom_fields(self) self.helper = FormHelper() self.helper.form_class = 'form-horizontal' self.helper.label_class = 'col-lg-2 col-md-3 col-sm-4' self.helper.field_class = 'col-lg-5 col-md-7 col-sm-8' self.helper.layout = Layout() if SettingProperties.get_bool( constants.OPPIA_SHOW_GRAVATARS, settings.OPPIA_SHOW_GRAVATARS): gravatar_url = "https://www.gravatar.com/avatar.php?" gravatar_id = hashlib.md5(str(email).encode('utf-8')).hexdigest() gravatar_url += urllib.parse.urlencode({ 'gravatar_id': gravatar_id, 'size': 64 }) self.helper.layout.append( Div( HTML("""<label class="control-label col-lg-2">""" + _(u'Photo') + """</label>"""), Div( HTML(mark_safe( '<img src="{0}" alt="gravatar for {1}" \ class="gravatar" width="{2}" height="{2}"/>' .format(gravatar_url, username, 64))), HTML("""<br/>"""), HTML("""<a href="https://www.gravatar.com">""" + _(u'Update gravatar') + """</a>"""), css_class="col-lg-4", ), css_class="form-group", ) ) self.helper.layout.extend( ['api_key', 'username', 'email', 'first_name', 'last_name', 'job_title', 'organisation']) custom_fields = CustomField.objects.all().order_by('order') for custom_field in custom_fields: self.helper.layout.append(custom_field.id) self.helper.layout.extend([ Div( HTML("""<h4 class='mt-5 mb-3'>""" + _(u'Change password') + """</h4>"""), ), Div(HTML("""<div style='clear:both'></div>""")), 'password', 'password_again', Div( Submit('submit', _(u'Save Profile'), css_class='btn btn-default mt-3'), css_class='text-center col-lg-offset-2 col-lg-6', )])
def __init__(self, allow_edit=True, *args, **kwargs): super(ProfileForm, self).__init__(* args, ** kwargs) userdata = kwargs.get('initial') \ if 'initial' in kwargs else kwargs.get('data') email = userdata.get('email', None) username = userdata.get('username', None) helpers.custom_fields(self) self.helper = FormHelper() self.helper.form_class = 'form-horizontal' self.helper.form_tag = False self.helper.label_class = 'col-lg-2 col-md-3 col-sm-4' self.helper.field_class = 'col-lg-5 col-md-8 col-sm-8' self.helper.layout = Layout() if SettingProperties.get_bool( constants.OPPIA_SHOW_GRAVATARS, settings.OPPIA_SHOW_GRAVATARS): gravatar_url = "https://www.gravatar.com/avatar.php?" gravatar_id = hashlib.md5(str(email).encode('utf-8')).hexdigest() gravatar_url += urllib.parse.urlencode({ 'gravatar_id': gravatar_id, 'size': 64 }) self.gravatar = FormHelper() self.gravatar.form_tag = False self.gravatar.layout = Layout( Div( HTML("""<label class="control-label col-lg-2">""" + _(u'Photo') + """</label>"""), Div( HTML(mark_safe( '<img src="{0}" alt="gravatar for {1}" \ class="gravatar" width="{2}" height="{2}"/>' .format(gravatar_url, username, 64))), HTML("""<br/>"""), HTML("""<a href="https://www.gravatar.com">""" + _(u'Update gravatar') + """</a>"""), css_class="col-lg-4", ), css_class="form-group", ) ) if not allow_edit: # Set fields as read-only if the user is not allow to edit their # profile for key, field in self.fields.items(): if not key.startswith('password'): field.widget.attrs.update({'readonly': 'readonly'}) self.helper.layout.extend( ['job_title', 'organisation', 'phone_number']) custom_fields = CustomField.objects.all().order_by('order') for custom_field in custom_fields: self.helper.layout.append(custom_field.id) self.helper.layout.extend([ Div( HTML("""<h4 class='mt-5 mb-3'>""" + _(u'Change password') + """</h4>"""), ), Div(HTML("""<div style='clear:both'></div>""")), 'password', 'password_again', Div( Submit('submit', _(u'Save Profile'), css_class='btn btn-default mt-3'), css_class='text-center col-lg-offset-2 col-lg-6', )])
def obj_create(self, bundle, **kwargs): self_register = SettingProperties.get_int( constants.OPPIA_ALLOW_SELF_REGISTRATION, settings.OPPIA_ALLOW_SELF_REGISTRATION) if not self_register: raise BadRequest(_(u'Registration is disabled on this server.')) required = [ 'username', 'password', 'passwordagain', 'email', 'firstname', 'lastname' ] check_required_params(bundle, required) data = { 'username': bundle.data['username'], 'password': bundle.data['password'], 'password_again': bundle.data['passwordagain'], 'email': bundle.data['email'], 'first_name': bundle.data['firstname'], 'last_name': bundle.data['lastname'], } rf = RegisterForm(data) if not rf.is_valid(): str = "" for key, value in rf.errors.items(): for error in value: str += error + "\n" raise BadRequest(str) else: username = bundle.data['username'] password = bundle.data['password'] email = bundle.data['email'] first_name = bundle.data['firstname'] last_name = bundle.data['lastname'] try: bundle.obj = User.objects.create_user(username, email, password) bundle.obj.first_name = first_name bundle.obj.last_name = last_name bundle.obj.save() user_profile = UserProfile() user_profile.user = bundle.obj if 'jobtitle' in bundle.data: user_profile.job_title = bundle.data['jobtitle'] if 'organisation' in bundle.data: user_profile.organisation = bundle.data['organisation'] if 'phoneno' in bundle.data: user_profile.phone_number = bundle.data['phoneno'] user_profile.save() u = authenticate(username=username, password=password) if u is not None and u.is_active: login(bundle.request, u) # Add to tracker tracker = Tracker() tracker.user = u tracker.type = 'register' tracker.ip = bundle.request.META.get('REMOTE_ADDR', api.DEFAULT_IP_ADDRESS) tracker.agent = bundle.request.META.get( 'HTTP_USER_AGENT', 'unknown') tracker.save() key = ApiKey.objects.get(user=u) bundle.data['api_key'] = key.key except IntegrityError: raise BadRequest( _(u'Username "%s" already in use, please select another' % username)) del bundle.data['passwordagain'] del bundle.data['password'] del bundle.data['firstname'] del bundle.data['lastname'] return bundle
def insert_hostname(apps, schema_editor): current = SettingProperties.get_string(constants.OPPIA_HOSTNAME, None) if current is None: SettingProperties.set_string(constants.OPPIA_HOSTNAME, None)
def test_emailing_on_email_address_field_shows(self): SettingProperties.set_bool(constants.OPPIA_EMAIL_CERTIFICATES, True) url = reverse(self.STR_URL, args=[self.normal_user.id]) self.client.force_login(self.admin_user) self.client.get(url)
def get_settings(request): self_register = SettingProperties.get_bool( constants.OPPIA_ALLOW_SELF_REGISTRATION, settings.OPPIA_ALLOW_SELF_REGISTRATION) show_gravatars = SettingProperties.get_bool( constants.OPPIA_SHOW_GRAVATARS, settings.OPPIA_SHOW_GRAVATARS) ga_enabled = SettingProperties.get_bool( constants.OPPIA_GOOGLE_ANALYTICS_ENABLED, settings.OPPIA_GOOGLE_ANALYTICS_ENABLED) ga_code = SettingProperties.get_string( constants.OPPIA_GOOGLE_ANALYTICS_CODE, settings.OPPIA_GOOGLE_ANALYTICS_CODE) ga_domain = SettingProperties.get_string( constants.OPPIA_GOOGLE_ANALYTICS_DOMAIN, settings.OPPIA_GOOGLE_ANALYTICS_DOMAIN) map_viz_enabled = SettingProperties.get_bool( constants.OPPIA_MAP_VISUALISATION_ENABLED, False) cron_warning = False last_cron = SettingProperties.get_string( constants.OPPIA_CRON_LAST_RUN, None) last_summary_cron = SettingProperties.get_string( constants.OPPIA_SUMMARY_CRON_LAST_RUN, None) TIME_ZONE_FIX = '+00:00' # fix for bad timezone dates if last_cron and TIME_ZONE_FIX not in last_cron: last_cron += TIME_ZONE_FIX if last_summary_cron and TIME_ZONE_FIX not in last_summary_cron: last_summary_cron += TIME_ZONE_FIX if last_cron is None or last_summary_cron is None: cron_warning = True else: start_date = datetime.datetime.now() - datetime.timedelta(days=7) last_cron_date = datetime.datetime.strptime( last_cron, constants.CRON_DATETIME_FORMAT) if last_cron_date < start_date: cron_warning = True last_summary_cron_date = datetime.datetime.strptime( last_summary_cron, constants.CRON_DATETIME_FORMAT) if last_summary_cron_date < start_date: cron_warning = True return { 'OPPIA_ALLOW_SELF_REGISTRATION': self_register, 'OPPIA_GOOGLE_ANALYTICS_ENABLED': ga_enabled, 'OPPIA_GOOGLE_ANALYTICS_CODE': ga_code, 'OPPIA_GOOGLE_ANALYTICS_DOMAIN': ga_domain, 'OPPIA_SHOW_GRAVATARS': show_gravatars, 'OPPIA_REPORTS': menu_reports(request), 'DEBUG': settings.DEBUG, 'CRON_WARNING': cron_warning, 'OPPIA_MAP_VISUALISATION_ENABLED': map_viz_enabled}
def test_set_string(self): key = "testkey" value = "testval" SettingProperties.set_string(key, value) retreived_value = SettingProperties.get_string(key, "default") self.assertEqual(value, retreived_value)
def test_self_name_int(self): sp = SettingProperties() sp.key = u"testintkey" sp.int_value = 123 sp.save() self.assertEqual(sp.__unicode__(), u"testintkey")
def test_get_prop_string_none(self): key = "testkey" value = None SettingProperties.set_string(key, value) retreived_value = SettingProperties.get_property(key, "default") self.assertEqual("default", retreived_value)
def test_regenerate_own_get(self): SettingProperties.set_bool(constants.OPPIA_EMAIL_CERTIFICATES, True) url = reverse(self.STR_URL) self.client.force_login(self.normal_user) response = self.client.get(url) self.assertEqual(response.status_code, 200)
def test_string_is_null(self): key = "intkey" value = 123 SettingProperties.set_int(key, value) retreived_value = SettingProperties.get_string(key, "default") self.assertEqual("default", retreived_value)
def dehydrate_badging(self, bundle): return SettingProperties.get_bool(constants.OPPIA_BADGES_ENABLED, settings.OPPIA_BADGES_ENABLED)
def test_get_prop_int_doesnotexist(self): key = "testkey" value = 123 SettingProperties.set_int(key, value) retreived_value = SettingProperties.get_property("some non key", 100) self.assertEqual(100, retreived_value)
def form_valid(self, form): response = super().form_valid(form) SettingProperties.set_bool( constants.OPPIA_SERVER_REGISTERED, True, constants.SETTING_CATEGORY_SERVER_REGISTRATION) server_url = form.cleaned_data.get("server_url") SettingProperties.set_string(constants.OPPIA_HOSTNAME, server_url, constants.SETTING_CATEGORY_SYSTEM_CONFIG) include_no_courses = form.cleaned_data.get("include_no_courses") SettingProperties.set_bool( constants.OPPIA_SERVER_REGISTER_NO_COURSES, include_no_courses, constants.SETTING_CATEGORY_SERVER_REGISTRATION) include_no_users = form.cleaned_data.get("include_no_users") SettingProperties.set_bool( constants.OPPIA_SERVER_REGISTER_NO_USERS, include_no_users, constants.SETTING_CATEGORY_SERVER_REGISTRATION) email_notifications = form.cleaned_data.get("email_notifications") SettingProperties.set_bool( constants.OPPIA_SERVER_REGISTER_EMAIL_NOTIF, email_notifications, constants.SETTING_CATEGORY_SERVER_REGISTRATION) notif_email_address = form.cleaned_data.get("notif_email_address") SettingProperties.set_string( constants.OPPIA_SERVER_REGISTER_NOTIF_EMAIL_ADDRESS, notif_email_address, constants.SETTING_CATEGORY_SERVER_REGISTRATION) return response
def generate_certificate_pdf(display_name, certificate_template_id, date, validation_uuid): cert_template = CertificateTemplate.objects.get(pk=certificate_template_id) buffer = io.BytesIO() with Image.open(cert_template.image_file.path) as img: w, h = img.size # Create the PDF object if w > h: cert = canvas.Canvas(buffer, pagesize=landscape(A4)) else: cert = canvas.Canvas(buffer, pagesize=portrait(A4)) cert.setTitle(cert_template.course.get_title()) # add background cert.drawImage(cert_template.image_file.path, 0, 0) # add name if cert_template.include_name: cert.setFont('Helvetica-Bold', 24) cert.drawCentredString(cert_template.name_x, cert_template.name_y, display_name) # add course if cert_template.include_course_title: cert.setFont('Helvetica-Bold', 24) cert.drawCentredString(cert_template.course_title_x, cert_template.course_title_y, cert_template.course.get_title()) # add date if cert_template.include_date: cert.setFont('Helvetica-Bold', 16) cert.drawCentredString(cert_template.date_x, cert_template.date_y, date) host = SettingProperties.get_string(constants.OPPIA_HOSTNAME, '') url_path = reverse('oppia:certificate_validate', args=[validation_uuid]) validation_link = host + url_path # add url if cert_template.validation == CertificateTemplate.VALIDATION_OPTION_URL: cert.setFont('Helvetica', 10) cert.drawCentredString(cert_template.validation_x, cert_template.validation_y, "Verify certificate: " + validation_link) # add QR Code if cert_template.validation == \ CertificateTemplate.VALIDATION_OPTION_QRCODE: qr_img = qrcode.make(validation_link) maxsize = (60, 60) qr_img.thumbnail(maxsize, Image.ANTIALIAS) bytes_in = io.BytesIO() qr_img.save(bytes_in, format='png') bytes_in.seek(0) qr = ImageReader(bytes_in) cert.drawImage(qr, cert_template.validation_x, cert_template.validation_y) cert.setFont('Helvetica', 10) cert.drawCentredString(cert_template.validation_x + 28, cert_template.validation_y - 5, (u"Verify Certificate")) cert.showPage() cert.save() return buffer
def obj_create(self, bundle, **kwargs): self_register = SettingProperties.get_int(constants.OPPIA_ALLOW_SELF_REGISTRATION, settings.OPPIA_ALLOW_SELF_REGISTRATION) if not self_register: raise BadRequest(_(u'Registration is disabled on this server.')) required = ['username', 'password', 'passwordagain', 'email', 'firstname', 'lastname'] check_required_params(bundle, required) data = {'username': bundle.data['username'], 'password': bundle.data['password'], 'password_again': bundle.data['passwordagain'], 'email': bundle.data['email'], 'first_name': bundle.data['firstname'], 'last_name': bundle.data['lastname'], } rf = RegisterForm(data) if not rf.is_valid(): str = "" for key, value in rf.errors.items(): for error in value: str += error + "\n" raise BadRequest(str) else: username = bundle.data['username'] password = bundle.data['password'] email = bundle.data['email'] first_name = bundle.data['firstname'] last_name = bundle.data['lastname'] try: bundle.obj = User.objects.create_user(username, email, password) bundle.obj.first_name = first_name bundle.obj.last_name = last_name bundle.obj.save() user_profile = UserProfile() user_profile.user = bundle.obj if 'jobtitle' in bundle.data: user_profile.job_title = bundle.data['jobtitle'] if 'organisation' in bundle.data: user_profile.organisation = bundle.data['organisation'] if 'phoneno' in bundle.data: user_profile.phone_number = bundle.data['phoneno'] user_profile.save() u = authenticate(username=username, password=password) if u is not None and u.is_active: login(bundle.request, u) # Add to tracker tracker = Tracker() tracker.user = u tracker.type = 'register' tracker.ip = bundle.request.META.get('REMOTE_ADDR', api.DEFAULT_IP_ADDRESS) tracker.agent = bundle.request.META.get('HTTP_USER_AGENT', 'unknown') tracker.save() key = ApiKey.objects.get(user=u) bundle.data['api_key'] = key.key except IntegrityError: raise BadRequest(_(u'Username "%s" already in use, please select another' % username)) del bundle.data['passwordagain'] del bundle.data['password'] del bundle.data['firstname'] del bundle.data['lastname'] return bundle
def update_summaries(last_tracker_pk=0, last_points_pk=0): from django.contrib.auth.models import User from django.db.models import Count from oppia.models import Tracker, Points, Course from settings.models import SettingProperties from summary.models import UserCourseSummary, CourseDailyStats, UserPointsSummary # check if cron already running prop, created = SettingProperties.objects.get_or_create( key='oppia_summary_cron_lock', int_value=1) if not created: print("Oppia summary cron is already running") return SettingProperties.set_string('oppia_summary_cron_last_run', timezone.now()) # get last tracker and points PKs to be processed # (to avoid leaving some out if new trackers arrive while processing) try: newest_tracker_pk = Tracker.objects.latest('id').id newest_points_pk = Points.objects.latest('id').id except Tracker.DoesNotExist: print("Tracker table is empty. Aborting cron...") SettingProperties.delete_key('oppia_summary_cron_lock') return except Points.DoesNotExist: newest_points_pk = last_points_pk print('Last tracker processed: %d\nNewest tracker: %d\n' % (last_tracker_pk, newest_tracker_pk)) if last_tracker_pk >= newest_tracker_pk: print('No new trackers to process. Aborting cron...') SettingProperties.delete_key('oppia_summary_cron_lock') return first_tracker = (last_tracker_pk == 0) first_points = (last_points_pk == 0) # If we are calculating from the start, delete previous summary calculations if first_tracker: UserCourseSummary.objects.all().delete() CourseDailyStats.objects.all().delete() if first_points: UserPointsSummary.objects.all().delete() # get different (distinct) user/courses involved user_courses = Tracker.objects \ .filter(pk__gt=last_tracker_pk, pk__lte=newest_tracker_pk) \ .exclude(course__isnull=True) \ .values('course', 'user').distinct() total_users = user_courses.count() print('%d different user/courses to process.' % total_users) count = 1 for uc_tracker in user_courses: print('processing user/course trackers... (%d/%d)' % (count, total_users)) user = User.objects.get(pk=uc_tracker['user']) course = Course.objects.get(pk=uc_tracker['course']) user_course, created = UserCourseSummary.objects.get_or_create( course=course, user=user) user_course.update_summary(last_tracker_pk=last_tracker_pk, last_points_pk=last_points_pk, newest_tracker_pk=newest_tracker_pk, newest_points_pk=newest_points_pk) count += 1 # get different (distinct) courses/dates involved course_daily_type_logs = Tracker.objects \ .filter(pk__gt=last_tracker_pk, pk__lte=newest_tracker_pk) \ .exclude(course__isnull=True) \ .extra({'day': "day(tracker_date)", 'month': "month(tracker_date)", 'year': "year(tracker_date)"}) \ .values('course', 'day', 'month', 'year', 'type') \ .annotate(total=Count('type')) \ .order_by('day') total_logs = course_daily_type_logs.count() print('%d different courses/dates/types to process.' % total_logs) count = 0 for type_log in course_daily_type_logs: day = date(type_log['year'], type_log['month'], type_log['day']) course = Course.objects.get(pk=type_log['course']) stats, created = CourseDailyStats.objects.get_or_create( course=course, day=day, type=type_log['type']) stats.total = (0 if first_tracker else stats.total) + type_log['total'] stats.save() count += 1 print(count) # get different (distinct) search logs involved search_daily_logs = Tracker.objects \ .filter(pk__gt=last_tracker_pk, pk__lte=newest_tracker_pk, user__is_staff=False, type='search') \ .extra({'day': "day(tracker_date)", 'month': "month(tracker_date)", 'year': "year(tracker_date)"}) \ .values('day', 'month', 'year') \ .annotate(total=Count('id')) \ .order_by('day') print('%d different search/dates to process.' % search_daily_logs.count()) for search_log in search_daily_logs: day = date(search_log['year'], search_log['month'], search_log['day']) stats, created = CourseDailyStats.objects.get_or_create(course=None, day=day, type='search') stats.total = (0 if first_tracker else stats.total) + search_log['total'] stats.save() # get different (distinct) user/points involved users_points = Points.objects \ .filter(pk__gt=last_points_pk, pk__lte=newest_points_pk) \ .values('user').distinct() total_users = users_points.count() print('%d different user/points to process.' % total_users) for user_points in users_points: user = User.objects.get(pk=user_points['user']) points, created = UserPointsSummary.objects.get_or_create(user=user) points.update_points(last_points_pk=last_points_pk, newest_points_pk=newest_points_pk) # update last tracker and points PKs with the last one processed SettingProperties.objects.update_or_create( key='last_tracker_pk', defaults={"int_value": newest_tracker_pk}) SettingProperties.objects.update_or_create( key='last_points_pk', defaults={"int_value": newest_points_pk}) SettingProperties.delete_key('oppia_summary_cron_lock')
def test_set_string_default(self): key = "testkey1" retreived_value = SettingProperties.get_string(key, "default") self.assertEqual("default", retreived_value)
def test_self_name_string(self): sp = SettingProperties() sp.key = u"teststrkey" sp.str_value = u"test string" sp.save() self.assertEqual(sp.__str__(), u"teststrkey")
def test_self_name_string(self): sp = SettingProperties() sp.key = u"teststrkey" sp.str_value = u"test string" sp.save() self.assertEqual(sp.__unicode__(), u"teststrkey")
def test_set_int_default(self): key = "testkey1" retreived_value = SettingProperties.get_int(key, 0) self.assertEqual(0, retreived_value)
def dehydrate_scoring(self, bundle): return SettingProperties.get_bool(constants.OPPIA_POINTS_ENABLED, settings.OPPIA_POINTS_ENABLED)
def test_set_string(self): key = "testkey" value = "testval" SettingProperties.set_string(key, value) retreived_value = SettingProperties.get_string(key, "default") self.assertEqual(value,retreived_value)
def test_self_name_int(self): sp = SettingProperties() sp.key = u"testintkey" sp.int_value = 123 sp.save() self.assertEqual(sp.__str__(), u"testintkey")
def test_int_is_null(self): key = "testkey" value = "testval" SettingProperties.set_string(key, value) retreived_value = SettingProperties.get_int(key, 123) self.assertEqual(123, retreived_value)
def test_get_prop_int(self): key = "testkey" value = 123 SettingProperties.set_int(key, value) retreived_value = SettingProperties.get_property(key, 0) self.assertEqual(value, retreived_value)
def test_get_prop_int_none(self): key = "testkey" value = None SettingProperties.set_int(key, value) retreived_value = SettingProperties.get_property(key, 100) self.assertEqual(100, retreived_value)
def test_email_certificates(self): SettingProperties.set_bool(constants.OPPIA_EMAIL_CERTIFICATES, True) call_command('generate_certificates', '--allcerts', stdout=StringIO()) self.assertEqual(len(mail.outbox), 0)