We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[New UI] Introduce different reducers aside from editor
## New UI - Fix on `UI_new_design` branch

We currently only have one reducer that we use, editor. This should be splitted per feature into different reducers.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `players/views.py`
Content:
```
1 import cPickle as pickle
2 import logging
3 import os
4 
5 from django.contrib.auth.decorators import login_required
6 from django.core.exceptions import ValidationError
7 from django.http import HttpResponse, JsonResponse, Http404, HttpResponseForbidden
8 from django.shortcuts import redirect, render, get_object_or_404
9 from django.views.decorators.csrf import csrf_exempt
10 from django.views.decorators.http import require_http_methods
11 from django.views.generic import TemplateView
12 from django.middleware.csrf import get_token
13 
14 from models import Avatar, Game, LevelAttempt
15 from players import forms, game_renderer
16 from app_settings import get_users_for_new_game, preview_user_required
17 
18 LOGGER = logging.getLogger(__name__)
19 
20 
21 def _post_code_success_response(message):
22     return _create_response("SUCCESS", message)
23 
24 
25 def _create_response(status, message):
26     response = {
27         "status": status,
28         "message": message
29     }
30     return JsonResponse(response)
31 
32 
33 @login_required
34 @preview_user_required
35 def code(request, id):
36     if not request.user:
37         return HttpResponseForbidden()
38     game = get_object_or_404(Game, id=id)
39     if not game.can_user_play(request.user):
40         raise Http404
41     try:
42         avatar = game.avatar_set.get(owner=request.user)
43     except Avatar.DoesNotExist:
44         initial_code_file_name = os.path.join(
45             os.path.abspath(os.path.dirname(__file__)),
46             'avatar_examples/dumb_avatar.py',
47         )
48         with open(initial_code_file_name) as initial_code_file:
49             initial_code = initial_code_file.read()
50         avatar = Avatar.objects.create(owner=request.user, code=initial_code,
51                                        game_id=id)
52     if request.method == 'POST':
53         avatar.code = request.POST['code']
54         avatar.save()
55         return HttpResponse(status=200)
56     else:
57         return JsonResponse({'code': avatar.code})
58 
59 
60 def list_games(request):
61     response = {
62         game.pk:
63             {
64                 'name': game.name,
65                 'settings': pickle.dumps(game.settings_as_dict()),
66             } for game in Game.objects.exclude_inactive()
67     }
68     return JsonResponse(response)
69 
70 
71 def get_game(request, id):
72     game = get_object_or_404(Game, id=id)
73     response = {
74         'main': {
75             'parameters': [],
76             'main_avatar': None,
77             'users': [],
78         }
79     }
80     for avatar in game.avatar_set.all():
81         if avatar.owner_id == game.main_user_id:
82             response['main']['main_avatar'] = avatar.id
83         response['main']['users'].append({
84             'id': avatar.id,
85             'code': avatar.code,
86         })
87     return JsonResponse(response)
88 
89 
90 def connection_parameters(request, id):
91     """
92     An API view which returns the correct connection settings required
93     to run the game in different environments. These values will change
94     depending on where the project is started (ie. local, etc).
95     :param id: Integer with the ID of the game.
96     :return: JsonResponse object with the contents.
97     """
98     return JsonResponse(
99         game_renderer.get_environment_connection_settings(id)
100     )
101 
102 
103 @csrf_exempt
104 @require_http_methods(['POST'])
105 def mark_game_complete(request, id):
106     game = get_object_or_404(Game, id=id)
107     game.completed = True
108     game.static_data = request.body
109     game.save()
110     return HttpResponse('Done!')
111 
112 
113 class ProgramView(TemplateView):
114     template_name = 'players/program.html'
115 
116     def get_context_data(self, **kwargs):
117         context = super(ProgramView, self).get_context_data(**kwargs)
118         game = get_object_or_404(Game, id=self.kwargs['id'])
119         if not game.can_user_play(self.request.user):
120             raise Http404
121         context['game_id'] = int(self.kwargs['id'])
122         return context
123 
124 
125 def program_level(request, num):
126     try:
127         game = Game.objects.get(levelattempt__user=request.user, levelattempt__level_number=num)
128     except Game.DoesNotExist:
129         LOGGER.debug('Adding level')
130         game = _add_and_return_level(num, request.user)
131     LOGGER.debug('Programming game with id %s', game.id)
132     return render(request, 'players/program.html', {'game_id': game.id})
133 
134 
135 def watch_game(request, id):
136     game = get_object_or_404(Game, id=id)
137     if not game.can_user_play(request.user):
138         raise Http404
139     return game_renderer.render_game(request, game)
140 
141 
142 def watch_level(request, num):
143     try:
144         game = Game.objects.get(levelattempt__user=request.user, levelattempt__level_number=num)
145     except Game.DoesNotExist:
146         LOGGER.debug('Adding level')
147         game = _add_and_return_level(num, request.user)
148     LOGGER.debug('Displaying game with id %s', game.id)
149     return game_renderer.render_game(request, game)
150 
151 
152 def _add_and_return_level(num, user):
153     game = Game(generator='Level' + num, name='Level ' + num, public=False, main_user=user)
154     try:
155         game.save()
156     except ValidationError as e:
157         LOGGER.warn(e)
158         raise Http404
159     game.can_play = [user]
160     game.save()
161     level_attempt = LevelAttempt(game=game, user=user, level_number=num)
162     level_attempt.save()
163     return game
164 
165 
166 @login_required
167 @preview_user_required
168 def add_game(request):
169     if request.method == 'POST':
170         form = forms.AddGameForm(request.POST)
171         if form.is_valid():
172             game = form.save(commit=False)
173             game.generator = 'Main'
174             game.owner = request.user
175             game.main_user = request.user
176             game.save()
177             users = get_users_for_new_game(request)
178             if users is not None:
179                 game.can_play.add(*users)
180             return redirect('aimmo/program', id=game.id)
181     else:
182         form = forms.AddGameForm()
183     return render(request, 'players/add_game.html', {'form': form})
184 
185 
186 def current_avatar_in_game(request, game_id):
187     game = get_object_or_404(Game, id=game_id)
188 
189     if not game.can_user_play(request.user.id):
190         return HttpResponse('User unauthorized to play', status=401)
191 
192     try:
193         avatar = game.avatar_set.get(owner=request.user.id)
194     except Avatar.DoesNotExist:
195         return HttpResponse('Avatar does not exist for this user', status=404)
196 
197     return JsonResponse({'current_avatar_id': avatar.id})
198 
199 
200 def csrfToken(request):
201     if request.method == 'GET':
202         token = get_token(request)
203         return JsonResponse({'csrfToken': token})
204     else:
205         return HttpResponse(status=405)
206
```

Path: `players/urls.py`
Content:
```
1 from django.conf.urls import url
2 from django.contrib.auth import views as auth_views
3 from django.contrib.auth.decorators import login_required
4 from django.views.generic import TemplateView
5 from django.views.generic import RedirectView
6 
7 from players import views
8 from app_settings import preview_user_required
9 
10 urlpatterns = [
11     url(r'^$', login_required(preview_user_required(TemplateView.as_view(template_name='players/home.html'))), name='aimmo/home'),
12 
13     url(r'^accounts/login/$', auth_views.login, name='aimmo/login'),
14     url(r'^accounts/logout/$', auth_views.logout, {'next_page' : 'aimmo/logout_success'}, name='aimmo/logout'),
15     url(r'^accounts/logout_success/$', TemplateView.as_view(template_name='registration/success_logout.html'), name='aimmo/logout_success'),
16 
17     url(r'^program/(?P<id>[0-9]+)/$', login_required(preview_user_required(views.ProgramView.as_view())), name='aimmo/program'),
18     url(r'^program_level/(?P<num>[0-9]+)/$', login_required(preview_user_required(views.program_level)), name='aimmo/program_level'),
19     url(r'^watch/(?P<id>[0-9]+)/$', login_required(preview_user_required(views.watch_game)), name='aimmo/watch'),
20     url(r'^watch_level/(?P<num>[0-9]+)/$', login_required(preview_user_required(views.watch_level)), name='aimmo/watch_level'),
21     url(r'^statistics/$', TemplateView.as_view(template_name='players/statistics.html'), name='aimmo/statistics'),
22     url(r'^game_ide/$', TemplateView.as_view(template_name='players/game_ide.html'), name='aimmo/game_ide'),
23 
24     url(r'^api/csrf_token', views.csrfToken, name='aimmo/csrf_token'),
25     url(r'^api/code/(?P<id>[0-9]+)/$', views.code, name='aimmo/code'),
26     url(r'^api/games/$', views.list_games, name='aimmo/games'),
27     url(r'^api/games/(?P<id>[0-9]+)/$', views.get_game, name='aimmo/game_details'),
28     url(r'^api/games/(?P<id>[0-9]+)/connection_parameters/$', views.connection_parameters, name='aimmo/connection_parameters'),
29     url(r'^api/games/(?P<id>[0-9]+)/complete/$', views.mark_game_complete, name='aimmo/complete_game'),
30     url(r'^api/games/(?P<game_id>[0-9]+)/current_avatar/$', views.current_avatar_in_game, name='aimmo/current_avatar_in_game'),
31 
32     url(r'^jsreverse/$', 'django_js_reverse.views.urls_js', name='aimmo/js_reverse'),  # TODO: Pull request to make django_js_reverse.urls
33     url(r'^games/new/$', views.add_game, name='aimmo/new_game'),
34 
35     # TODO: this is a quickfix for redirecting for the Unity resources
36     url(r'^watch/(?P<id>[0-9]+)/(?P<resource>.[0-9A-Za-z/.]+)$',
37         RedirectView.as_view(url='/static/unity/%(resource)s', permanent=False)),
38 
39     url(r'^socket.io/socket.io.js',
40         RedirectView.as_view(url='https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.7.4/socket.io.min.js', permanent=False)),
41 ]
42
```

Path: `players/game_renderer.py`
Content:
```
1 """
2 Any helper functions used for the unity game.
3 """
4 
5 from django.shortcuts import render
6 from players import app_settings
7 
8 
9 def render_game(request, game):
10     """
11     :param request: Request object used to generate this response.
12     :param game: Game object.
13     :return: HttpResponse object with a given context dictionary and a template.
14     """
15     context = {'current_user_player_key': request.user.pk, 'active': game.is_active,
16                'static_data': game.static_data or '{}'
17                }
18 
19     connection_settings = get_environment_connection_settings(game.id)
20 
21     context.update(connection_settings)
22 
23     return render(request, 'players/viewer.html', context)
24 
25 
26 def get_environment_connection_settings(game_id):
27     """
28     This function will return the correct URL parts and a SSL flag
29     based on the environment of which it exists in.
30 
31     :param request: Request object used to generate this response.
32     :param game_id: Integer with the ID of the game.
33     :return: A dict object with all relevant settings.
34     """
35 
36     return {
37         'game_url_base': app_settings.GAME_SERVER_URL_FUNCTION(game_id)[0],
38         'game_url_path': app_settings.GAME_SERVER_URL_FUNCTION(game_id)[1],
39         'game_url_port': app_settings.GAME_SERVER_PORT_FUNCTION(game_id),
40         'game_ssl_flag': app_settings.GAME_SERVER_SSL_FLAG, 'game_id': game_id
41     }
42
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/players/game_renderer.py b/players/game_renderer.py
--- a/players/game_renderer.py
+++ b/players/game_renderer.py
@@ -20,7 +20,7 @@
 
     context.update(connection_settings)
 
-    return render(request, 'players/viewer.html', context)
+    return render(request, 'players/game_ide.html', context)
 
 
 def get_environment_connection_settings(game_id):
diff --git a/players/urls.py b/players/urls.py
--- a/players/urls.py
+++ b/players/urls.py
@@ -14,12 +14,8 @@
     url(r'^accounts/logout/$', auth_views.logout, {'next_page' : 'aimmo/logout_success'}, name='aimmo/logout'),
     url(r'^accounts/logout_success/$', TemplateView.as_view(template_name='registration/success_logout.html'), name='aimmo/logout_success'),
 
-    url(r'^program/(?P<id>[0-9]+)/$', login_required(preview_user_required(views.ProgramView.as_view())), name='aimmo/program'),
-    url(r'^program_level/(?P<num>[0-9]+)/$', login_required(preview_user_required(views.program_level)), name='aimmo/program_level'),
-    url(r'^watch/(?P<id>[0-9]+)/$', login_required(preview_user_required(views.watch_game)), name='aimmo/watch'),
-    url(r'^watch_level/(?P<num>[0-9]+)/$', login_required(preview_user_required(views.watch_level)), name='aimmo/watch_level'),
+    url(r'^play/(?P<id>[0-9]+)/$', login_required(preview_user_required(views.watch_game)), name='aimmo/play'),
     url(r'^statistics/$', TemplateView.as_view(template_name='players/statistics.html'), name='aimmo/statistics'),
-    url(r'^game_ide/$', TemplateView.as_view(template_name='players/game_ide.html'), name='aimmo/game_ide'),
 
     url(r'^api/csrf_token', views.csrfToken, name='aimmo/csrf_token'),
     url(r'^api/code/(?P<id>[0-9]+)/$', views.code, name='aimmo/code'),
diff --git a/players/views.py b/players/views.py
--- a/players/views.py
+++ b/players/views.py
@@ -122,16 +122,6 @@
         return context
 
 
-def program_level(request, num):
-    try:
-        game = Game.objects.get(levelattempt__user=request.user, levelattempt__level_number=num)
-    except Game.DoesNotExist:
-        LOGGER.debug('Adding level')
-        game = _add_and_return_level(num, request.user)
-    LOGGER.debug('Programming game with id %s', game.id)
-    return render(request, 'players/program.html', {'game_id': game.id})
-
-
 def watch_game(request, id):
     game = get_object_or_404(Game, id=id)
     if not game.can_user_play(request.user):
@@ -177,7 +167,7 @@
             users = get_users_for_new_game(request)
             if users is not None:
                 game.can_play.add(*users)
-            return redirect('aimmo/program', id=game.id)
+            return redirect('aimmo/play', id=game.id)
     else:
         form = forms.AddGameForm()
     return render(request, 'players/add_game.html', {'form': form})

{"golden_diff": "diff --git a/players/game_renderer.py b/players/game_renderer.py\n--- a/players/game_renderer.py\n+++ b/players/game_renderer.py\n@@ -20,7 +20,7 @@\n \n     context.update(connection_settings)\n \n-    return render(request, 'players/viewer.html', context)\n+    return render(request, 'players/game_ide.html', context)\n \n \n def get_environment_connection_settings(game_id):\ndiff --git a/players/urls.py b/players/urls.py\n--- a/players/urls.py\n+++ b/players/urls.py\n@@ -14,12 +14,8 @@\n     url(r'^accounts/logout/$', auth_views.logout, {'next_page' : 'aimmo/logout_success'}, name='aimmo/logout'),\n     url(r'^accounts/logout_success/$', TemplateView.as_view(template_name='registration/success_logout.html'), name='aimmo/logout_success'),\n \n-    url(r'^program/(?P<id>[0-9]+)/$', login_required(preview_user_required(views.ProgramView.as_view())), name='aimmo/program'),\n-    url(r'^program_level/(?P<num>[0-9]+)/$', login_required(preview_user_required(views.program_level)), name='aimmo/program_level'),\n-    url(r'^watch/(?P<id>[0-9]+)/$', login_required(preview_user_required(views.watch_game)), name='aimmo/watch'),\n-    url(r'^watch_level/(?P<num>[0-9]+)/$', login_required(preview_user_required(views.watch_level)), name='aimmo/watch_level'),\n+    url(r'^play/(?P<id>[0-9]+)/$', login_required(preview_user_required(views.watch_game)), name='aimmo/play'),\n     url(r'^statistics/$', TemplateView.as_view(template_name='players/statistics.html'), name='aimmo/statistics'),\n-    url(r'^game_ide/$', TemplateView.as_view(template_name='players/game_ide.html'), name='aimmo/game_ide'),\n \n     url(r'^api/csrf_token', views.csrfToken, name='aimmo/csrf_token'),\n     url(r'^api/code/(?P<id>[0-9]+)/$', views.code, name='aimmo/code'),\ndiff --git a/players/views.py b/players/views.py\n--- a/players/views.py\n+++ b/players/views.py\n@@ -122,16 +122,6 @@\n         return context\n \n \n-def program_level(request, num):\n-    try:\n-        game = Game.objects.get(levelattempt__user=request.user, levelattempt__level_number=num)\n-    except Game.DoesNotExist:\n-        LOGGER.debug('Adding level')\n-        game = _add_and_return_level(num, request.user)\n-    LOGGER.debug('Programming game with id %s', game.id)\n-    return render(request, 'players/program.html', {'game_id': game.id})\n-\n-\n def watch_game(request, id):\n     game = get_object_or_404(Game, id=id)\n     if not game.can_user_play(request.user):\n@@ -177,7 +167,7 @@\n             users = get_users_for_new_game(request)\n             if users is not None:\n                 game.can_play.add(*users)\n-            return redirect('aimmo/program', id=game.id)\n+            return redirect('aimmo/play', id=game.id)\n     else:\n         form = forms.AddGameForm()\n     return render(request, 'players/add_game.html', {'form': form})\n", "issue": "[New UI] Introduce different reducers aside from editor\n## New UI - Fix on `UI_new_design` branch\r\n\r\nWe currently only have one reducer that we use, editor. This should be splitted per feature into different reducers.\n", "before_files": [{"content": "import cPickle as pickle\nimport logging\nimport os\n\nfrom django.contrib.auth.decorators import login_required\nfrom django.core.exceptions import ValidationError\nfrom django.http import HttpResponse, JsonResponse, Http404, HttpResponseForbidden\nfrom django.shortcuts import redirect, render, get_object_or_404\nfrom django.views.decorators.csrf import csrf_exempt\nfrom django.views.decorators.http import require_http_methods\nfrom django.views.generic import TemplateView\nfrom django.middleware.csrf import get_token\n\nfrom models import Avatar, Game, LevelAttempt\nfrom players import forms, game_renderer\nfrom app_settings import get_users_for_new_game, preview_user_required\n\nLOGGER = logging.getLogger(__name__)\n\n\ndef _post_code_success_response(message):\n    return _create_response(\"SUCCESS\", message)\n\n\ndef _create_response(status, message):\n    response = {\n        \"status\": status,\n        \"message\": message\n    }\n    return JsonResponse(response)\n\n\n@login_required\n@preview_user_required\ndef code(request, id):\n    if not request.user:\n        return HttpResponseForbidden()\n    game = get_object_or_404(Game, id=id)\n    if not game.can_user_play(request.user):\n        raise Http404\n    try:\n        avatar = game.avatar_set.get(owner=request.user)\n    except Avatar.DoesNotExist:\n        initial_code_file_name = os.path.join(\n            os.path.abspath(os.path.dirname(__file__)),\n            'avatar_examples/dumb_avatar.py',\n        )\n        with open(initial_code_file_name) as initial_code_file:\n            initial_code = initial_code_file.read()\n        avatar = Avatar.objects.create(owner=request.user, code=initial_code,\n                                       game_id=id)\n    if request.method == 'POST':\n        avatar.code = request.POST['code']\n        avatar.save()\n        return HttpResponse(status=200)\n    else:\n        return JsonResponse({'code': avatar.code})\n\n\ndef list_games(request):\n    response = {\n        game.pk:\n            {\n                'name': game.name,\n                'settings': pickle.dumps(game.settings_as_dict()),\n            } for game in Game.objects.exclude_inactive()\n    }\n    return JsonResponse(response)\n\n\ndef get_game(request, id):\n    game = get_object_or_404(Game, id=id)\n    response = {\n        'main': {\n            'parameters': [],\n            'main_avatar': None,\n            'users': [],\n        }\n    }\n    for avatar in game.avatar_set.all():\n        if avatar.owner_id == game.main_user_id:\n            response['main']['main_avatar'] = avatar.id\n        response['main']['users'].append({\n            'id': avatar.id,\n            'code': avatar.code,\n        })\n    return JsonResponse(response)\n\n\ndef connection_parameters(request, id):\n    \"\"\"\n    An API view which returns the correct connection settings required\n    to run the game in different environments. These values will change\n    depending on where the project is started (ie. local, etc).\n    :param id: Integer with the ID of the game.\n    :return: JsonResponse object with the contents.\n    \"\"\"\n    return JsonResponse(\n        game_renderer.get_environment_connection_settings(id)\n    )\n\n\n@csrf_exempt\n@require_http_methods(['POST'])\ndef mark_game_complete(request, id):\n    game = get_object_or_404(Game, id=id)\n    game.completed = True\n    game.static_data = request.body\n    game.save()\n    return HttpResponse('Done!')\n\n\nclass ProgramView(TemplateView):\n    template_name = 'players/program.html'\n\n    def get_context_data(self, **kwargs):\n        context = super(ProgramView, self).get_context_data(**kwargs)\n        game = get_object_or_404(Game, id=self.kwargs['id'])\n        if not game.can_user_play(self.request.user):\n            raise Http404\n        context['game_id'] = int(self.kwargs['id'])\n        return context\n\n\ndef program_level(request, num):\n    try:\n        game = Game.objects.get(levelattempt__user=request.user, levelattempt__level_number=num)\n    except Game.DoesNotExist:\n        LOGGER.debug('Adding level')\n        game = _add_and_return_level(num, request.user)\n    LOGGER.debug('Programming game with id %s', game.id)\n    return render(request, 'players/program.html', {'game_id': game.id})\n\n\ndef watch_game(request, id):\n    game = get_object_or_404(Game, id=id)\n    if not game.can_user_play(request.user):\n        raise Http404\n    return game_renderer.render_game(request, game)\n\n\ndef watch_level(request, num):\n    try:\n        game = Game.objects.get(levelattempt__user=request.user, levelattempt__level_number=num)\n    except Game.DoesNotExist:\n        LOGGER.debug('Adding level')\n        game = _add_and_return_level(num, request.user)\n    LOGGER.debug('Displaying game with id %s', game.id)\n    return game_renderer.render_game(request, game)\n\n\ndef _add_and_return_level(num, user):\n    game = Game(generator='Level' + num, name='Level ' + num, public=False, main_user=user)\n    try:\n        game.save()\n    except ValidationError as e:\n        LOGGER.warn(e)\n        raise Http404\n    game.can_play = [user]\n    game.save()\n    level_attempt = LevelAttempt(game=game, user=user, level_number=num)\n    level_attempt.save()\n    return game\n\n\n@login_required\n@preview_user_required\ndef add_game(request):\n    if request.method == 'POST':\n        form = forms.AddGameForm(request.POST)\n        if form.is_valid():\n            game = form.save(commit=False)\n            game.generator = 'Main'\n            game.owner = request.user\n            game.main_user = request.user\n            game.save()\n            users = get_users_for_new_game(request)\n            if users is not None:\n                game.can_play.add(*users)\n            return redirect('aimmo/program', id=game.id)\n    else:\n        form = forms.AddGameForm()\n    return render(request, 'players/add_game.html', {'form': form})\n\n\ndef current_avatar_in_game(request, game_id):\n    game = get_object_or_404(Game, id=game_id)\n\n    if not game.can_user_play(request.user.id):\n        return HttpResponse('User unauthorized to play', status=401)\n\n    try:\n        avatar = game.avatar_set.get(owner=request.user.id)\n    except Avatar.DoesNotExist:\n        return HttpResponse('Avatar does not exist for this user', status=404)\n\n    return JsonResponse({'current_avatar_id': avatar.id})\n\n\ndef csrfToken(request):\n    if request.method == 'GET':\n        token = get_token(request)\n        return JsonResponse({'csrfToken': token})\n    else:\n        return HttpResponse(status=405)\n", "path": "players/views.py"}, {"content": "from django.conf.urls import url\nfrom django.contrib.auth import views as auth_views\nfrom django.contrib.auth.decorators import login_required\nfrom django.views.generic import TemplateView\nfrom django.views.generic import RedirectView\n\nfrom players import views\nfrom app_settings import preview_user_required\n\nurlpatterns = [\n    url(r'^$', login_required(preview_user_required(TemplateView.as_view(template_name='players/home.html'))), name='aimmo/home'),\n\n    url(r'^accounts/login/$', auth_views.login, name='aimmo/login'),\n    url(r'^accounts/logout/$', auth_views.logout, {'next_page' : 'aimmo/logout_success'}, name='aimmo/logout'),\n    url(r'^accounts/logout_success/$', TemplateView.as_view(template_name='registration/success_logout.html'), name='aimmo/logout_success'),\n\n    url(r'^program/(?P<id>[0-9]+)/$', login_required(preview_user_required(views.ProgramView.as_view())), name='aimmo/program'),\n    url(r'^program_level/(?P<num>[0-9]+)/$', login_required(preview_user_required(views.program_level)), name='aimmo/program_level'),\n    url(r'^watch/(?P<id>[0-9]+)/$', login_required(preview_user_required(views.watch_game)), name='aimmo/watch'),\n    url(r'^watch_level/(?P<num>[0-9]+)/$', login_required(preview_user_required(views.watch_level)), name='aimmo/watch_level'),\n    url(r'^statistics/$', TemplateView.as_view(template_name='players/statistics.html'), name='aimmo/statistics'),\n    url(r'^game_ide/$', TemplateView.as_view(template_name='players/game_ide.html'), name='aimmo/game_ide'),\n\n    url(r'^api/csrf_token', views.csrfToken, name='aimmo/csrf_token'),\n    url(r'^api/code/(?P<id>[0-9]+)/$', views.code, name='aimmo/code'),\n    url(r'^api/games/$', views.list_games, name='aimmo/games'),\n    url(r'^api/games/(?P<id>[0-9]+)/$', views.get_game, name='aimmo/game_details'),\n    url(r'^api/games/(?P<id>[0-9]+)/connection_parameters/$', views.connection_parameters, name='aimmo/connection_parameters'),\n    url(r'^api/games/(?P<id>[0-9]+)/complete/$', views.mark_game_complete, name='aimmo/complete_game'),\n    url(r'^api/games/(?P<game_id>[0-9]+)/current_avatar/$', views.current_avatar_in_game, name='aimmo/current_avatar_in_game'),\n\n    url(r'^jsreverse/$', 'django_js_reverse.views.urls_js', name='aimmo/js_reverse'),  # TODO: Pull request to make django_js_reverse.urls\n    url(r'^games/new/$', views.add_game, name='aimmo/new_game'),\n\n    # TODO: this is a quickfix for redirecting for the Unity resources\n    url(r'^watch/(?P<id>[0-9]+)/(?P<resource>.[0-9A-Za-z/.]+)$',\n        RedirectView.as_view(url='/static/unity/%(resource)s', permanent=False)),\n\n    url(r'^socket.io/socket.io.js',\n        RedirectView.as_view(url='https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.7.4/socket.io.min.js', permanent=False)),\n]\n", "path": "players/urls.py"}, {"content": "\"\"\"\nAny helper functions used for the unity game.\n\"\"\"\n\nfrom django.shortcuts import render\nfrom players import app_settings\n\n\ndef render_game(request, game):\n    \"\"\"\n    :param request: Request object used to generate this response.\n    :param game: Game object.\n    :return: HttpResponse object with a given context dictionary and a template.\n    \"\"\"\n    context = {'current_user_player_key': request.user.pk, 'active': game.is_active,\n               'static_data': game.static_data or '{}'\n               }\n\n    connection_settings = get_environment_connection_settings(game.id)\n\n    context.update(connection_settings)\n\n    return render(request, 'players/viewer.html', context)\n\n\ndef get_environment_connection_settings(game_id):\n    \"\"\"\n    This function will return the correct URL parts and a SSL flag\n    based on the environment of which it exists in.\n\n    :param request: Request object used to generate this response.\n    :param game_id: Integer with the ID of the game.\n    :return: A dict object with all relevant settings.\n    \"\"\"\n\n    return {\n        'game_url_base': app_settings.GAME_SERVER_URL_FUNCTION(game_id)[0],\n        'game_url_path': app_settings.GAME_SERVER_URL_FUNCTION(game_id)[1],\n        'game_url_port': app_settings.GAME_SERVER_PORT_FUNCTION(game_id),\n        'game_ssl_flag': app_settings.GAME_SERVER_SSL_FLAG, 'game_id': game_id\n    }\n", "path": "players/game_renderer.py"}], "after_files": [{"content": "import cPickle as pickle\nimport logging\nimport os\n\nfrom django.contrib.auth.decorators import login_required\nfrom django.core.exceptions import ValidationError\nfrom django.http import HttpResponse, JsonResponse, Http404, HttpResponseForbidden\nfrom django.shortcuts import redirect, render, get_object_or_404\nfrom django.views.decorators.csrf import csrf_exempt\nfrom django.views.decorators.http import require_http_methods\nfrom django.views.generic import TemplateView\nfrom django.middleware.csrf import get_token\n\nfrom models import Avatar, Game, LevelAttempt\nfrom players import forms, game_renderer\nfrom app_settings import get_users_for_new_game, preview_user_required\n\nLOGGER = logging.getLogger(__name__)\n\n\ndef _post_code_success_response(message):\n    return _create_response(\"SUCCESS\", message)\n\n\ndef _create_response(status, message):\n    response = {\n        \"status\": status,\n        \"message\": message\n    }\n    return JsonResponse(response)\n\n\n@login_required\n@preview_user_required\ndef code(request, id):\n    if not request.user:\n        return HttpResponseForbidden()\n    game = get_object_or_404(Game, id=id)\n    if not game.can_user_play(request.user):\n        raise Http404\n    try:\n        avatar = game.avatar_set.get(owner=request.user)\n    except Avatar.DoesNotExist:\n        initial_code_file_name = os.path.join(\n            os.path.abspath(os.path.dirname(__file__)),\n            'avatar_examples/dumb_avatar.py',\n        )\n        with open(initial_code_file_name) as initial_code_file:\n            initial_code = initial_code_file.read()\n        avatar = Avatar.objects.create(owner=request.user, code=initial_code,\n                                       game_id=id)\n    if request.method == 'POST':\n        avatar.code = request.POST['code']\n        avatar.save()\n        return HttpResponse(status=200)\n    else:\n        return JsonResponse({'code': avatar.code})\n\n\ndef list_games(request):\n    response = {\n        game.pk:\n            {\n                'name': game.name,\n                'settings': pickle.dumps(game.settings_as_dict()),\n            } for game in Game.objects.exclude_inactive()\n    }\n    return JsonResponse(response)\n\n\ndef get_game(request, id):\n    game = get_object_or_404(Game, id=id)\n    response = {\n        'main': {\n            'parameters': [],\n            'main_avatar': None,\n            'users': [],\n        }\n    }\n    for avatar in game.avatar_set.all():\n        if avatar.owner_id == game.main_user_id:\n            response['main']['main_avatar'] = avatar.id\n        response['main']['users'].append({\n            'id': avatar.id,\n            'code': avatar.code,\n        })\n    return JsonResponse(response)\n\n\ndef connection_parameters(request, id):\n    \"\"\"\n    An API view which returns the correct connection settings required\n    to run the game in different environments. These values will change\n    depending on where the project is started (ie. local, etc).\n    :param id: Integer with the ID of the game.\n    :return: JsonResponse object with the contents.\n    \"\"\"\n    return JsonResponse(\n        game_renderer.get_environment_connection_settings(id)\n    )\n\n\n@csrf_exempt\n@require_http_methods(['POST'])\ndef mark_game_complete(request, id):\n    game = get_object_or_404(Game, id=id)\n    game.completed = True\n    game.static_data = request.body\n    game.save()\n    return HttpResponse('Done!')\n\n\nclass ProgramView(TemplateView):\n    template_name = 'players/program.html'\n\n    def get_context_data(self, **kwargs):\n        context = super(ProgramView, self).get_context_data(**kwargs)\n        game = get_object_or_404(Game, id=self.kwargs['id'])\n        if not game.can_user_play(self.request.user):\n            raise Http404\n        context['game_id'] = int(self.kwargs['id'])\n        return context\n\n\ndef watch_game(request, id):\n    game = get_object_or_404(Game, id=id)\n    if not game.can_user_play(request.user):\n        raise Http404\n    return game_renderer.render_game(request, game)\n\n\ndef watch_level(request, num):\n    try:\n        game = Game.objects.get(levelattempt__user=request.user, levelattempt__level_number=num)\n    except Game.DoesNotExist:\n        LOGGER.debug('Adding level')\n        game = _add_and_return_level(num, request.user)\n    LOGGER.debug('Displaying game with id %s', game.id)\n    return game_renderer.render_game(request, game)\n\n\ndef _add_and_return_level(num, user):\n    game = Game(generator='Level' + num, name='Level ' + num, public=False, main_user=user)\n    try:\n        game.save()\n    except ValidationError as e:\n        LOGGER.warn(e)\n        raise Http404\n    game.can_play = [user]\n    game.save()\n    level_attempt = LevelAttempt(game=game, user=user, level_number=num)\n    level_attempt.save()\n    return game\n\n\n@login_required\n@preview_user_required\ndef add_game(request):\n    if request.method == 'POST':\n        form = forms.AddGameForm(request.POST)\n        if form.is_valid():\n            game = form.save(commit=False)\n            game.generator = 'Main'\n            game.owner = request.user\n            game.main_user = request.user\n            game.save()\n            users = get_users_for_new_game(request)\n            if users is not None:\n                game.can_play.add(*users)\n            return redirect('aimmo/play', id=game.id)\n    else:\n        form = forms.AddGameForm()\n    return render(request, 'players/add_game.html', {'form': form})\n\n\ndef current_avatar_in_game(request, game_id):\n    game = get_object_or_404(Game, id=game_id)\n\n    if not game.can_user_play(request.user.id):\n        return HttpResponse('User unauthorized to play', status=401)\n\n    try:\n        avatar = game.avatar_set.get(owner=request.user.id)\n    except Avatar.DoesNotExist:\n        return HttpResponse('Avatar does not exist for this user', status=404)\n\n    return JsonResponse({'current_avatar_id': avatar.id})\n\n\ndef csrfToken(request):\n    if request.method == 'GET':\n        token = get_token(request)\n        return JsonResponse({'csrfToken': token})\n    else:\n        return HttpResponse(status=405)\n", "path": "players/views.py"}, {"content": "from django.conf.urls import url\nfrom django.contrib.auth import views as auth_views\nfrom django.contrib.auth.decorators import login_required\nfrom django.views.generic import TemplateView\nfrom django.views.generic import RedirectView\n\nfrom players import views\nfrom app_settings import preview_user_required\n\nurlpatterns = [\n    url(r'^$', login_required(preview_user_required(TemplateView.as_view(template_name='players/home.html'))), name='aimmo/home'),\n\n    url(r'^accounts/login/$', auth_views.login, name='aimmo/login'),\n    url(r'^accounts/logout/$', auth_views.logout, {'next_page' : 'aimmo/logout_success'}, name='aimmo/logout'),\n    url(r'^accounts/logout_success/$', TemplateView.as_view(template_name='registration/success_logout.html'), name='aimmo/logout_success'),\n\n    url(r'^play/(?P<id>[0-9]+)/$', login_required(preview_user_required(views.watch_game)), name='aimmo/play'),\n    url(r'^statistics/$', TemplateView.as_view(template_name='players/statistics.html'), name='aimmo/statistics'),\n\n    url(r'^api/csrf_token', views.csrfToken, name='aimmo/csrf_token'),\n    url(r'^api/code/(?P<id>[0-9]+)/$', views.code, name='aimmo/code'),\n    url(r'^api/games/$', views.list_games, name='aimmo/games'),\n    url(r'^api/games/(?P<id>[0-9]+)/$', views.get_game, name='aimmo/game_details'),\n    url(r'^api/games/(?P<id>[0-9]+)/connection_parameters/$', views.connection_parameters, name='aimmo/connection_parameters'),\n    url(r'^api/games/(?P<id>[0-9]+)/complete/$', views.mark_game_complete, name='aimmo/complete_game'),\n    url(r'^api/games/(?P<game_id>[0-9]+)/current_avatar/$', views.current_avatar_in_game, name='aimmo/current_avatar_in_game'),\n\n    url(r'^jsreverse/$', 'django_js_reverse.views.urls_js', name='aimmo/js_reverse'),  # TODO: Pull request to make django_js_reverse.urls\n    url(r'^games/new/$', views.add_game, name='aimmo/new_game'),\n\n    # TODO: this is a quickfix for redirecting for the Unity resources\n    url(r'^watch/(?P<id>[0-9]+)/(?P<resource>.[0-9A-Za-z/.]+)$',\n        RedirectView.as_view(url='/static/unity/%(resource)s', permanent=False)),\n\n    url(r'^socket.io/socket.io.js',\n        RedirectView.as_view(url='https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.7.4/socket.io.min.js', permanent=False)),\n]\n", "path": "players/urls.py"}, {"content": "\"\"\"\nAny helper functions used for the unity game.\n\"\"\"\n\nfrom django.shortcuts import render\nfrom players import app_settings\n\n\ndef render_game(request, game):\n    \"\"\"\n    :param request: Request object used to generate this response.\n    :param game: Game object.\n    :return: HttpResponse object with a given context dictionary and a template.\n    \"\"\"\n    context = {'current_user_player_key': request.user.pk, 'active': game.is_active,\n               'static_data': game.static_data or '{}'\n               }\n\n    connection_settings = get_environment_connection_settings(game.id)\n\n    context.update(connection_settings)\n\n    return render(request, 'players/game_ide.html', context)\n\n\ndef get_environment_connection_settings(game_id):\n    \"\"\"\n    This function will return the correct URL parts and a SSL flag\n    based on the environment of which it exists in.\n\n    :param request: Request object used to generate this response.\n    :param game_id: Integer with the ID of the game.\n    :return: A dict object with all relevant settings.\n    \"\"\"\n\n    return {\n        'game_url_base': app_settings.GAME_SERVER_URL_FUNCTION(game_id)[0],\n        'game_url_path': app_settings.GAME_SERVER_URL_FUNCTION(game_id)[1],\n        'game_url_port': app_settings.GAME_SERVER_PORT_FUNCTION(game_id),\n        'game_ssl_flag': app_settings.GAME_SERVER_SSL_FLAG, 'game_id': game_id\n    }\n", "path": "players/game_renderer.py"}]}