-
Notifications
You must be signed in to change notification settings - Fork 306
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
212 changed files
with
13,410 additions
and
9,628 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -44,4 +44,5 @@ writeup/ | |
/TAGS | ||
.tags | ||
/kalite/i18n/static/ | ||
ghostdriver.log | ||
/.vagrant/ | ||
ghostdriver.log |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
# -*- mode: ruby -*- | ||
# vi: set ft=ruby : | ||
|
||
# Vagrantfile API/syntax version. Don't touch unless you know what you're doing! | ||
VAGRANTFILE_API_VERSION = "2" | ||
|
||
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| | ||
|
||
# Every Vagrant virtual environment requires a box to build off of. | ||
config.vm.box = "trusty64" | ||
|
||
# Create a forwarded port mapping which allows access to a specific port | ||
# within the machine from a port on the host machine. In the example below, | ||
# accessing "localhost:8080" will access port 80 on the guest machine. | ||
config.vm.network "forwarded_port", guest: 8008, host: 38008 | ||
|
||
# Create a private network, which allows host-only access to the machine | ||
# using a specific IP. | ||
config.vm.network "private_network", ip: "192.168.33.10" | ||
|
||
# Create a public network, which generally matched to bridged network. | ||
# Bridged networks make the machine appear as another physical device on | ||
# your network. | ||
# config.vm.network "public_network" | ||
|
||
# Share an additional folder to the guest VM. The first argument is | ||
# the path on the host to the actual folder. The second argument is | ||
# the path on the guest to mount the folder. And the optional third | ||
# argument is a set of non-required options. | ||
config.vm.synced_folder ".", "/vagrant", type: "nfs" | ||
|
||
end |
Empty file.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
CONDITION_SETTINGS = { | ||
"nalanda_control": { | ||
"distributed.turn_off_motivational_features": True, | ||
"distributed.turn_off_points_for_videos": True, | ||
"distributed.turn_off_points_for_exercises": True, | ||
"student_testing.turn_on_points_for_practice_exams": False, | ||
"store.show_store_link_once_points_earned": False, | ||
"distributed.front_page_welcome_message": "Try as hard as you can on each question in your practicing and and on the exams!", | ||
}, | ||
"nalanda_input": { | ||
"distributed.turn_off_motivational_features": False, | ||
"distributed.turn_off_points_for_videos": True, | ||
"distributed.turn_off_points_for_noncurrent_unit": True, | ||
"student_testing.turn_on_points_for_practice_exams": False, | ||
"store.show_store_link_once_points_earned": True, | ||
"distributed.front_page_welcome_message": "This month you will earn points for the questions you answer correctly <b>in your practice exercises and quizzes</b>, and you will be able to exchange your points for rewards. For example Y points will earn you X stickers. Try as hard as you can on each question to earn rewards!", | ||
}, | ||
"nalanda_output": { | ||
"distributed.turn_off_motivational_features": True, | ||
"distributed.turn_off_points_for_videos": True, | ||
"distributed.turn_off_points_for_exercises": True, | ||
"student_testing.turn_on_points_for_practice_exams": True, | ||
"store.show_store_link_once_points_earned": True, | ||
"distributed.front_page_welcome_message": "This month you will earn points for the questions you answer correctly <b>on your first unit test</b>. You will also be able to exchange your points for rewards. For example Y points will earn you X stickers. Try as hard as you can on the exam at the end of the month to earn rewards!", | ||
}, | ||
"testing": { | ||
"distributed.turn_off_motivational_features": False, | ||
"distributed.turn_off_points_for_videos": False, | ||
"distributed.turn_off_points_for_exercises": False, | ||
"store.show_store_link_once_points_earned": True, | ||
"distributed.front_page_welcome_message": "This month you will earn points for the questions you answer correctly <b>in your practice exercises and quizzes</b>, and you will be able to exchange your points for rewards. For example Y points will earn you X stickers. Try as hard as you can on each question to earn rewards!", | ||
}, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
CONDITION_BY_FACILITY_AND_UNIT = { | ||
"facility1": { | ||
"1": "nalanda_control", | ||
"2": "nalanda_input", | ||
"3": "nalanda_output", | ||
}, | ||
"facility2": { | ||
"1": "nalanda_output", | ||
"2": "nalanda_control", | ||
"3": "nalanda_input", | ||
}, | ||
"facility3": { | ||
"1": "nalanda_input", | ||
"2": "nalanda_output", | ||
"3": "nalanda_control", | ||
}, | ||
"Test": { | ||
"1": "testing", | ||
"2": "testing", | ||
"3": "testing", | ||
"4": "testing", | ||
"5": "testing", | ||
"6": "testing", | ||
"7": "testing", | ||
"8": "testing", | ||
}, | ||
} | ||
|
||
GRADE_BY_FACILITY = { | ||
"facility1": 4, | ||
"facility2": 5, | ||
"facility3": 6, | ||
"Test": 1, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
from .data.groups import CONDITION_BY_FACILITY_AND_UNIT as CONDITION, GRADE_BY_FACILITY as GRADE | ||
from .data.conditions import CONDITION_SETTINGS | ||
|
||
from kalite.student_testing.utils import get_current_unit_settings_value | ||
|
||
from kalite.dynamic_assets import DynamicSettingsBase, fields | ||
|
||
class DynamicSettings(DynamicSettingsBase): | ||
student_grade_level = fields.IntegerField(default=0) | ||
|
||
# modify ds in-place. Use when you're modifying ds rather than defining new dynamic settings | ||
def modify_dynamic_settings(ds, request=None, user=None): | ||
|
||
user = user or request.session.get('facility_user') | ||
|
||
if user and not user.is_teacher: | ||
|
||
# determine the facility and unit for the current user | ||
facility = user.facility | ||
unit = get_current_unit_settings_value(facility.id) | ||
|
||
# look up what condition the user is currently assigned to | ||
condition = CONDITION.get(facility.id, CONDITION.get(facility.name, CONDITION.get(facility.id[0:8], {}))).get(str(unit), "") | ||
|
||
# Set grade level on students to enable dynamic checking of student playlists within a unit. | ||
# TODO (richard): (doge) Much hardcode. Such hack. So get rid. Wow. | ||
ds["ab_testing"].student_grade_level = GRADE.get(facility.id, GRADE.get(facility.name, GRADE.get(facility.id[0:8], 0))) | ||
ds["ab_testing"].unit = unit | ||
|
||
# load the settings associated with the user's current condition | ||
new_settings = CONDITION_SETTINGS.get(condition, {}) | ||
|
||
# merge the settings into the distributed settings (ds) object | ||
for key, value in new_settings.items(): | ||
namespace, setting = key.split(".") | ||
if namespace not in ds: | ||
raise Exception("Could not modify setting '%s': the '%s' app has not defined a dynamic_assets.py file containing DynamicSettings." % (key, namespace)) | ||
if not hasattr(ds[namespace], setting): | ||
raise Exception("Could not modify setting '%s': no such setting defined in the '%s' app's DynamicSettings." % (key, namespace)) | ||
setattr(ds[namespace], setting, value) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
try: | ||
import local_settings | ||
except ImportError: | ||
local_settings = object() | ||
|
||
INSTALLED_APPS = tuple() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
""" | ||
This file demonstrates writing tests using the unittest module. These will pass | ||
when you run "manage.py test". | ||
Replace this with more appropriate tests for your application. | ||
""" | ||
|
||
from django.test import TestCase | ||
|
||
|
||
class SimpleTest(TestCase): | ||
def test_basic_addition(self): | ||
""" | ||
Tests that 1 + 1 always equals 2. | ||
""" | ||
self.assertEqual(1 + 1, 2) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
from tastypie import fields | ||
from tastypie.exceptions import NotFound, Unauthorized | ||
from tastypie.resources import ModelResource, Resource | ||
|
||
from django.utils.translation import ugettext as _ | ||
|
||
from kalite.shared.decorators import get_user_from_request | ||
from .models import PlaylistProgress, PlaylistProgressDetail | ||
|
||
|
||
class PlaylistParentResource(Resource): | ||
""" | ||
A parent resource that houses shared code between the two resources we actually use | ||
in the API | ||
""" | ||
|
||
@classmethod | ||
def permission_check(self, request): | ||
""" | ||
Require that the users are logged in, and that the user is the same student | ||
whose data is being requested, an admin, or a teacher in that facility | ||
""" | ||
if getattr(request, "is_logged_in", False): | ||
pass | ||
else: | ||
raise Unauthorized(_("You must be logged in to access this page.")) | ||
|
||
if getattr(request, "is_admin", False): | ||
pass | ||
else: | ||
user = get_user_from_request(request=request) | ||
if request.GET.get("user_id") == user.id: | ||
pass | ||
else: | ||
raise Unauthorized(_("You requested information for a user that you are not authorized to view.")) | ||
|
||
|
||
class PlaylistProgressResource(PlaylistParentResource): | ||
|
||
title = fields.CharField(attribute='title') | ||
id = fields.CharField(attribute='id') | ||
tag = fields.CharField(attribute='tag', null=True) | ||
url = fields.CharField(attribute='url') | ||
vid_pct_complete = fields.IntegerField(attribute='vid_pct_complete') | ||
vid_pct_started = fields.IntegerField(attribute='vid_pct_started') | ||
vid_status = fields.CharField(attribute='vid_status') | ||
ex_pct_mastered = fields.IntegerField(attribute='ex_pct_mastered') | ||
ex_pct_struggling = fields.IntegerField(attribute='ex_pct_struggling') | ||
ex_pct_incomplete = fields.IntegerField(attribute='ex_pct_incomplete') | ||
ex_status = fields.CharField(attribute='ex_status') | ||
quiz_exists = fields.BooleanField(attribute='quiz_exists') | ||
quiz_status = fields.CharField(attribute='quiz_status') | ||
quiz_pct_score = fields.IntegerField(attribute='quiz_pct_score') | ||
n_pl_videos = fields.IntegerField(attribute='n_pl_videos') | ||
n_pl_exercises = fields.IntegerField(attribute='n_pl_exercises') | ||
|
||
class Meta: | ||
resource_name = "playlist_progress" | ||
object_class = PlaylistProgress | ||
|
||
def detail_uri_kwargs(self, bundle_or_obj): | ||
kwargs = {} | ||
if isinstance(bundle_or_obj, PlaylistProgress): | ||
kwargs['pk'] = bundle_or_obj.id | ||
else: | ||
kwargs['pk'] = bundle_or_obj.obj.id | ||
|
||
return kwargs | ||
|
||
def get_object_list(self, request): | ||
user_id = request.GET.get('user_id') | ||
result = PlaylistProgress.user_progress(user_id=user_id) | ||
return result | ||
|
||
def obj_get_list(self, bundle, **kwargs): | ||
self.permission_check(bundle.request) | ||
return self.get_object_list(bundle.request) | ||
|
||
|
||
class PlaylistProgressDetailResource(PlaylistParentResource): | ||
|
||
kind = fields.CharField(attribute='kind') | ||
status = fields.CharField(attribute='status') | ||
title = fields.CharField(attribute='title') | ||
score = fields.IntegerField(attribute='score') | ||
path = fields.CharField(attribute='path') | ||
|
||
class Meta: | ||
resource_name = "playlist_progress_detail" | ||
object_class = PlaylistProgressDetail | ||
|
||
def detail_uri_kwargs(self, bundle_or_obj): | ||
kwargs = {} | ||
if isinstance(bundle_or_obj, PlaylistProgressDetail): | ||
kwargs['pk'] = bundle_or_obj.id | ||
else: | ||
kwargs['pk'] = bundle_or_obj.obj.id | ||
|
||
return kwargs | ||
|
||
def get_object_list(self, request): | ||
user_id = request.GET.get("user_id") | ||
playlist_id = request.GET.get("playlist_id") | ||
result = PlaylistProgressDetail.user_progress_detail(user_id=user_id, playlist_id=playlist_id) | ||
if not result: | ||
raise NotFound("User playlist progress details with user ID '%s' and playlist ID '%s' were not found." % (user_id, playlist_id)) | ||
return result | ||
|
||
def obj_get_list(self, bundle, **kwargs): | ||
self.permission_check(bundle.request) | ||
return self.get_object_list(bundle.request) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,16 @@ | ||
from django.conf.urls import patterns, url, include | ||
|
||
from .api_resources import PlaylistProgressResource, PlaylistProgressDetailResource | ||
|
||
|
||
urlpatterns = patterns(__package__ + '.api_views', | ||
# Non tasty API | ||
url(r'data/$', 'api_data', {}, 'api_data'), | ||
url(r'^data/(?P<xaxis>\w+)/(?P<yaxis>\w+)/$', 'api_data', {}, 'api_data_2'), | ||
# url(r'friendly/$', 'api_friendly_names', {}, 'api_friendly_names'), | ||
url(r'^get_topic_tree(?P<topic_path>.*)$', 'get_topic_tree_by_kinds', {}, 'get_topic_tree_by_kinds') | ||
) | ||
# url(r'friendly/$', 'api_friendly_names', {}, 'api_friendly_names'), | ||
url(r'^get_topic_tree(?P<topic_path>.*)$', 'get_topic_tree_by_kinds', {}, 'get_topic_tree_by_kinds'), | ||
|
||
# TastyPie API Urls | ||
url(r'^', include(PlaylistProgressResource().urls)), | ||
url(r'^', include(PlaylistProgressDetailResource().urls)), | ||
) |
Oops, something went wrong.