We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Fix aimmo view tests 
The new PR on branch `fix_staging` is breaking some tests.

--- 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.core.urlresolvers import reverse
8 from django.http import HttpResponse, Http404
9 from django.http import JsonResponse
10 from django.shortcuts import redirect, render, get_object_or_404
11 from django.views.decorators.csrf import csrf_exempt
12 from django.views.decorators.http import require_http_methods
13 from django.views.generic import TemplateView
14 
15 from models import Avatar, Game, LevelAttempt
16 from players import forms
17 from . import app_settings
18 
19 LOGGER = logging.getLogger(__name__)
20 
21 
22 def _post_code_success_response(message):
23     return _create_response("SUCCESS", message)
24 
25 
26 def _create_response(status, message):
27     response = {
28         "status": status,
29         "message": message
30     }
31     return JsonResponse(response)
32 
33 
34 @login_required
35 def code(request, id):
36     game = get_object_or_404(Game, id=id)
37     if not game.can_user_play(request.user):
38         raise Http404
39     try:
40         avatar = game.avatar_set.get(owner=request.user)
41     except Avatar.DoesNotExist:
42         initial_code_file_name = os.path.join(
43             os.path.abspath(os.path.dirname(__file__)),
44             'avatar_examples/dumb_avatar.py',
45         )
46         with open(initial_code_file_name) as initial_code_file:
47             initial_code = initial_code_file.read()
48         avatar = Avatar.objects.create(owner=request.user, code=initial_code,
49                                        game_id=id)
50     if request.method == 'POST':
51         avatar.code = request.POST['code']
52         avatar.save()
53         return _post_code_success_response('Your code was saved!<br><br><a href="%s">Watch</a>' % reverse('aimmo/watch', kwargs={'id': game.id}))
54     else:
55         return HttpResponse(avatar.code)
56 
57 
58 def list_games(request):
59     response = {
60         game.pk:
61             {
62                 'name': game.name,
63                 'settings': pickle.dumps(game.settings_as_dict()),
64             } for game in Game.objects.exclude_inactive()
65     }
66     return JsonResponse(response)
67 
68 
69 def get_game(request, id):
70     game = get_object_or_404(Game, id=id)
71     response = {
72         'main': {
73             'parameters': [],
74             'main_avatar': None,
75             'users': [],
76         }
77     }
78     for avatar in game.avatar_set.all():
79         if avatar.owner_id == game.main_user_id:
80             response['main']['main_avatar'] = avatar.owner_id
81         response['main']['users'].append({
82             'id': avatar.owner_id,
83             'code': avatar.code,
84         })
85     return JsonResponse(response)
86 
87 
88 @csrf_exempt
89 @require_http_methods(['POST'])
90 def mark_game_complete(request, id):
91     game = get_object_or_404(Game, id=id)
92     game.completed = True
93     game.static_data = request.body
94     game.save()
95     return HttpResponse('Done!')
96 
97 
98 class ProgramView(TemplateView):
99     template_name = 'players/program.html'
100 
101     def get_context_data(self, **kwargs):
102         context = super(ProgramView, self).get_context_data(**kwargs)
103         game = get_object_or_404(Game, id=self.kwargs['id'])
104         if not game.can_user_play(self.request.user):
105             raise Http404
106         context['game_id'] = int(self.kwargs['id'])
107         return context
108 
109 
110 def program_level(request, num):
111     try:
112         game = Game.objects.get(levelattempt__user=request.user, levelattempt__level_number=num)
113     except Game.DoesNotExist:
114         LOGGER.debug('Adding level')
115         game = _add_and_return_level(num, request.user)
116     LOGGER.debug('Programming game with id %s', game.id)
117     return render(request, 'players/program.html', {'game_id': game.id})
118 
119 
120 def _render_game(request, game):
121     context = {
122         'current_user_player_key': request.user.pk,
123         'active': game.is_active,
124         'static_data': game.static_data or '{}',
125     }
126     context['game_url_base'], context['game_url_path'] = app_settings.GAME_SERVER_LOCATION_FUNCTION(game.id)
127     context['game_id'] = game.id
128     return render(request, 'players/viewer.html', context)
129 
130 
131 def watch_game(request, id):
132     game = get_object_or_404(Game, id=id)
133     if not game.can_user_play(request.user):
134         raise Http404
135     return _render_game(request, game)
136 
137 
138 def watch_level(request, num):
139     try:
140         game = Game.objects.get(levelattempt__user=request.user, levelattempt__level_number=num)
141     except Game.DoesNotExist:
142         LOGGER.debug('Adding level')
143         game = _add_and_return_level(num, request.user)
144     LOGGER.debug('Displaying game with id %s', game.id)
145     return _render_game(request, game)
146 
147 
148 def _add_and_return_level(num, user):
149     game = Game(generator='Level'+num, name='Level '+num, public=False, main_user=user)
150     try:
151         game.save()
152     except ValidationError as e:
153         LOGGER.warn(e)
154         raise Http404
155     game.can_play = [user]
156     game.save()
157     level_attempt = LevelAttempt(game=game, user=user, level_number=num)
158     level_attempt.save()
159     return game
160 
161 
162 @login_required
163 def add_game(request):
164     if request.method == 'POST':
165         form = forms.AddGameForm(request.POST)
166         if form.is_valid():
167             game = form.save(commit=False)
168             game.generator = 'Main'
169             game.owner = request.user
170             game.save()
171             return redirect('aimmo/program', id=game.id)
172     else:
173         form = forms.AddGameForm()
174     return render(request, 'players/add_game.html', {'form': form})
175
```

Path: `players/app_settings.py`
Content:
```
1 from django.conf import settings
2 
3 #: URL function for locating the game server, takes one parameter `game`
4 GAME_SERVER_LOCATION_FUNCTION = getattr(settings, 'AIMMO_GAME_SERVER_LOCATION_FUNCTION', None)
5 
6 MAX_LEVEL = 1
7
```

Path: `example_project/example_project/settings.py`
Content:
```
1 # -*- coding: utf-8 -*-
2 # Code for Life
3 #
4 # Copyright (C) 2015, Ocado Innovation Limited
5 #
6 # This program is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU Affero General Public License as
8 # published by the Free Software Foundation, either version 3 of the
9 # License, or (at your option) any later version.
10 #
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 # GNU Affero General Public License for more details.
15 #
16 # You should have received a copy of the GNU Affero General Public License
17 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 #
19 # ADDITIONAL TERMS – Section 7 GNU General Public Licence
20 #
21 # This licence does not grant any right, title or interest in any “Ocado” logos,
22 # trade names or the trademark “Ocado” or any other trademarks or domain names
23 # owned by Ocado Innovation Limited or the Ocado group of companies or any other
24 # distinctive brand features of “Ocado” as may be secured from time to time. You
25 # must not distribute any modification of this program using the trademark
26 # “Ocado” or claim any affiliation or association with Ocado or its employees.
27 #
28 # You are not authorised to use the name Ocado (or any of its trade names) or
29 # the names of any author or contributor in advertising or for publicity purposes
30 # pertaining to the distribution of this program, without the prior written
31 # authorisation of Ocado.
32 #
33 # Any propagation, distribution or conveyance of this program must include this
34 # copyright notice and these terms. You must not misrepresent the origins of this
35 # program; modified versions of the program must be marked as such and not
36 # identified as the original program.
37 """Django settings for example_project project."""
38 import subprocess
39 
40 import os
41 
42 ALLOWED_HOSTS = ['*']
43 
44 DEBUG = True
45 
46 DATABASES = {
47     'default': {
48         'ENGINE': 'django.db.backends.sqlite3',  # Add 'postgresql_psycopg2', 'mysql',
49                                                  # 'sqlite3' or 'oracle'.
50         'NAME': os.path.join(os.path.abspath(os.path.dirname(__file__)), 'db.sqlite3'),
51         # Or path to database file if using sqlite3.
52     }
53 }
54 
55 USE_I18N = True
56 USE_L10N = True
57 
58 TIME_ZONE = 'Europe/London'
59 LANGUAGE_CODE = 'en-gb'
60 STATIC_ROOT = os.path.join(os.path.dirname(__file__), 'static')
61 STATIC_URL = '/static/'
62 SECRET_KEY = 'not-a-secret'
63 
64 ROOT_URLCONF = 'django_autoconfig.autourlconf'
65 
66 WSGI_APPLICATION = 'example_project.wsgi.application'
67 
68 INSTALLED_APPS = (
69     'django.contrib.admin',
70     'django.contrib.auth',
71     'django.contrib.contenttypes',
72     'players',
73     'django_forms_bootstrap',
74 )
75 
76 LOGGING = {
77     'version': 1,
78     'disable_existing_loggers': False,
79     'filters': {
80         'require_debug_false': {
81             '()': 'django.utils.log.RequireDebugFalse'
82         }
83     },
84     'handlers': {
85         'console': {
86             'level': 'DEBUG',
87             'class': 'logging.StreamHandler'
88         },
89     },
90     'loggers': {
91         'views': {
92             'handlers': ['console'],
93             'level': 'DEBUG'
94         },
95     }
96 }
97 
98 LOGIN_URL = '/players/accounts/login/'
99 
100 LOGIN_REDIRECT_URL = '/players/'
101 
102 MIDDLEWARE_CLASSES = [
103    'django.contrib.sessions.middleware.SessionMiddleware',
104    'django.middleware.locale.LocaleMiddleware',
105    'django.middleware.common.CommonMiddleware',
106    'django.middleware.csrf.CsrfViewMiddleware',
107    'django.contrib.auth.middleware.AuthenticationMiddleware',
108    'django.contrib.messages.middleware.MessageMiddleware',
109 ]
110 
111 
112 def get_url(game):
113     if os.environ.get('AIMMO_MODE', '') == 'minikube':
114         output = subprocess.check_output([os.environ['MINIKUBE_PATH'], 'service',
115                                           'game-%s' % game, '--url'])
116         return 'http://dev.aimmo.codeforlife.education', '/game-%s' % game
117     else:
118         return 'http://localhost:%d' % (6001 + int(game) * 1000), ''
119 
120 
121 AIMMO_GAME_SERVER_LOCATION_FUNCTION = get_url
122 
123 try:
124     from example_project.local_settings import *  # pylint: disable=E0611
125 except ImportError:
126     pass
127 
128 from django_autoconfig import autoconfig
129 autoconfig.configure_settings(globals())
130
```
--- 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/example_project/example_project/settings.py b/example_project/example_project/settings.py
--- a/example_project/example_project/settings.py
+++ b/example_project/example_project/settings.py
@@ -109,16 +109,25 @@
 ]
 
 
-def get_url(game):
+def get_game_url_base_and_path(game):
     if os.environ.get('AIMMO_MODE', '') == 'minikube':
         output = subprocess.check_output([os.environ['MINIKUBE_PATH'], 'service',
                                           'game-%s' % game, '--url'])
-        return 'http://dev.aimmo.codeforlife.education', '/game-%s' % game
+        return 'local.aimmo.codeforlife.education', '/game-%s' % game
     else:
-        return 'http://localhost:%d' % (6001 + int(game) * 1000), ''
+        return 'localhost', ''
 
 
-AIMMO_GAME_SERVER_LOCATION_FUNCTION = get_url
+def get_game_port(game):
+    if os.environ.get('AIMMO_MODE', '') == 'minikube':
+        return 0
+
+    return 6001 + int(game) * 1000
+
+
+AIMMO_GAME_SERVER_URL_FUNCTION = get_game_url_base_and_path
+AIMMO_GAME_SERVER_PORT_FUNCTION = get_game_port
+AIMMO_GAME_SERVER_SSL_FLAG = False
 
 try:
     from example_project.local_settings import *  # pylint: disable=E0611
diff --git a/players/app_settings.py b/players/app_settings.py
--- a/players/app_settings.py
+++ b/players/app_settings.py
@@ -1,6 +1,8 @@
 from django.conf import settings
 
 #: URL function for locating the game server, takes one parameter `game`
-GAME_SERVER_LOCATION_FUNCTION = getattr(settings, 'AIMMO_GAME_SERVER_LOCATION_FUNCTION', None)
+GAME_SERVER_URL_FUNCTION = getattr(settings, 'AIMMO_GAME_SERVER_URL_FUNCTION', None)
+GAME_SERVER_PORT_FUNCTION = getattr(settings, 'AIMMO_GAME_SERVER_PORT_FUNCTION', None)
+GAME_SERVER_SSL_FLAG = getattr(settings, 'AIMMO_GAME_SERVER_SSL_FLAG', False)
 
 MAX_LEVEL = 1
diff --git a/players/views.py b/players/views.py
--- a/players/views.py
+++ b/players/views.py
@@ -123,7 +123,9 @@
         'active': game.is_active,
         'static_data': game.static_data or '{}',
     }
-    context['game_url_base'], context['game_url_path'] = app_settings.GAME_SERVER_LOCATION_FUNCTION(game.id)
+    context['game_url_base'], context['game_url_path'] = app_settings.GAME_SERVER_URL_FUNCTION(game.id)
+    context['game_url_port'] = app_settings.GAME_SERVER_PORT_FUNCTION(game.id)
+    context['game_ssl_flag'] = app_settings.GAME_SERVER_SSL_FLAG
     context['game_id'] = game.id
     return render(request, 'players/viewer.html', context)

{"golden_diff": "diff --git a/example_project/example_project/settings.py b/example_project/example_project/settings.py\n--- a/example_project/example_project/settings.py\n+++ b/example_project/example_project/settings.py\n@@ -109,16 +109,25 @@\n ]\n \n \n-def get_url(game):\n+def get_game_url_base_and_path(game):\n     if os.environ.get('AIMMO_MODE', '') == 'minikube':\n         output = subprocess.check_output([os.environ['MINIKUBE_PATH'], 'service',\n                                           'game-%s' % game, '--url'])\n-        return 'http://dev.aimmo.codeforlife.education', '/game-%s' % game\n+        return 'local.aimmo.codeforlife.education', '/game-%s' % game\n     else:\n-        return 'http://localhost:%d' % (6001 + int(game) * 1000), ''\n+        return 'localhost', ''\n \n \n-AIMMO_GAME_SERVER_LOCATION_FUNCTION = get_url\n+def get_game_port(game):\n+    if os.environ.get('AIMMO_MODE', '') == 'minikube':\n+        return 0\n+\n+    return 6001 + int(game) * 1000\n+\n+\n+AIMMO_GAME_SERVER_URL_FUNCTION = get_game_url_base_and_path\n+AIMMO_GAME_SERVER_PORT_FUNCTION = get_game_port\n+AIMMO_GAME_SERVER_SSL_FLAG = False\n \n try:\n     from example_project.local_settings import *  # pylint: disable=E0611\ndiff --git a/players/app_settings.py b/players/app_settings.py\n--- a/players/app_settings.py\n+++ b/players/app_settings.py\n@@ -1,6 +1,8 @@\n from django.conf import settings\n \n #: URL function for locating the game server, takes one parameter `game`\n-GAME_SERVER_LOCATION_FUNCTION = getattr(settings, 'AIMMO_GAME_SERVER_LOCATION_FUNCTION', None)\n+GAME_SERVER_URL_FUNCTION = getattr(settings, 'AIMMO_GAME_SERVER_URL_FUNCTION', None)\n+GAME_SERVER_PORT_FUNCTION = getattr(settings, 'AIMMO_GAME_SERVER_PORT_FUNCTION', None)\n+GAME_SERVER_SSL_FLAG = getattr(settings, 'AIMMO_GAME_SERVER_SSL_FLAG', False)\n \n MAX_LEVEL = 1\ndiff --git a/players/views.py b/players/views.py\n--- a/players/views.py\n+++ b/players/views.py\n@@ -123,7 +123,9 @@\n         'active': game.is_active,\n         'static_data': game.static_data or '{}',\n     }\n-    context['game_url_base'], context['game_url_path'] = app_settings.GAME_SERVER_LOCATION_FUNCTION(game.id)\n+    context['game_url_base'], context['game_url_path'] = app_settings.GAME_SERVER_URL_FUNCTION(game.id)\n+    context['game_url_port'] = app_settings.GAME_SERVER_PORT_FUNCTION(game.id)\n+    context['game_ssl_flag'] = app_settings.GAME_SERVER_SSL_FLAG\n     context['game_id'] = game.id\n     return render(request, 'players/viewer.html', context)\n", "issue": "Fix aimmo view tests \nThe new PR on branch `fix_staging` is breaking some tests.\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.core.urlresolvers import reverse\nfrom django.http import HttpResponse, Http404\nfrom django.http import JsonResponse\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\n\nfrom models import Avatar, Game, LevelAttempt\nfrom players import forms\nfrom . import app_settings\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\ndef code(request, id):\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 _post_code_success_response('Your code was saved!<br><br><a href=\"%s\">Watch</a>' % reverse('aimmo/watch', kwargs={'id': game.id}))\n    else:\n        return HttpResponse(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.owner_id\n        response['main']['users'].append({\n            'id': avatar.owner_id,\n            'code': avatar.code,\n        })\n    return JsonResponse(response)\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 _render_game(request, game):\n    context = {\n        'current_user_player_key': request.user.pk,\n        'active': game.is_active,\n        'static_data': game.static_data or '{}',\n    }\n    context['game_url_base'], context['game_url_path'] = app_settings.GAME_SERVER_LOCATION_FUNCTION(game.id)\n    context['game_id'] = game.id\n    return render(request, 'players/viewer.html', 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 _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 _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\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.save()\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", "path": "players/views.py"}, {"content": "from django.conf import settings\n\n#: URL function for locating the game server, takes one parameter `game`\nGAME_SERVER_LOCATION_FUNCTION = getattr(settings, 'AIMMO_GAME_SERVER_LOCATION_FUNCTION', None)\n\nMAX_LEVEL = 1\n", "path": "players/app_settings.py"}, {"content": "# -*- coding: utf-8 -*-\n# Code for Life\n#\n# Copyright (C) 2015, Ocado Innovation Limited\n#\n# This program is free software: you can redistribute it and/or modify\n# it under the terms of the GNU Affero General Public License as\n# published by the Free Software Foundation, either version 3 of the\n# License, or (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU Affero General Public License for more details.\n#\n# You should have received a copy of the GNU Affero General Public License\n# along with this program.  If not, see <http://www.gnu.org/licenses/>.\n#\n# ADDITIONAL TERMS \u2013 Section 7 GNU General Public Licence\n#\n# This licence does not grant any right, title or interest in any \u201cOcado\u201d logos,\n# trade names or the trademark \u201cOcado\u201d or any other trademarks or domain names\n# owned by Ocado Innovation Limited or the Ocado group of companies or any other\n# distinctive brand features of \u201cOcado\u201d as may be secured from time to time. You\n# must not distribute any modification of this program using the trademark\n# \u201cOcado\u201d or claim any affiliation or association with Ocado or its employees.\n#\n# You are not authorised to use the name Ocado (or any of its trade names) or\n# the names of any author or contributor in advertising or for publicity purposes\n# pertaining to the distribution of this program, without the prior written\n# authorisation of Ocado.\n#\n# Any propagation, distribution or conveyance of this program must include this\n# copyright notice and these terms. You must not misrepresent the origins of this\n# program; modified versions of the program must be marked as such and not\n# identified as the original program.\n\"\"\"Django settings for example_project project.\"\"\"\nimport subprocess\n\nimport os\n\nALLOWED_HOSTS = ['*']\n\nDEBUG = True\n\nDATABASES = {\n    'default': {\n        'ENGINE': 'django.db.backends.sqlite3',  # Add 'postgresql_psycopg2', 'mysql',\n                                                 # 'sqlite3' or 'oracle'.\n        'NAME': os.path.join(os.path.abspath(os.path.dirname(__file__)), 'db.sqlite3'),\n        # Or path to database file if using sqlite3.\n    }\n}\n\nUSE_I18N = True\nUSE_L10N = True\n\nTIME_ZONE = 'Europe/London'\nLANGUAGE_CODE = 'en-gb'\nSTATIC_ROOT = os.path.join(os.path.dirname(__file__), 'static')\nSTATIC_URL = '/static/'\nSECRET_KEY = 'not-a-secret'\n\nROOT_URLCONF = 'django_autoconfig.autourlconf'\n\nWSGI_APPLICATION = 'example_project.wsgi.application'\n\nINSTALLED_APPS = (\n    'django.contrib.admin',\n    'django.contrib.auth',\n    'django.contrib.contenttypes',\n    'players',\n    'django_forms_bootstrap',\n)\n\nLOGGING = {\n    'version': 1,\n    'disable_existing_loggers': False,\n    'filters': {\n        'require_debug_false': {\n            '()': 'django.utils.log.RequireDebugFalse'\n        }\n    },\n    'handlers': {\n        'console': {\n            'level': 'DEBUG',\n            'class': 'logging.StreamHandler'\n        },\n    },\n    'loggers': {\n        'views': {\n            'handlers': ['console'],\n            'level': 'DEBUG'\n        },\n    }\n}\n\nLOGIN_URL = '/players/accounts/login/'\n\nLOGIN_REDIRECT_URL = '/players/'\n\nMIDDLEWARE_CLASSES = [\n   'django.contrib.sessions.middleware.SessionMiddleware',\n   'django.middleware.locale.LocaleMiddleware',\n   'django.middleware.common.CommonMiddleware',\n   'django.middleware.csrf.CsrfViewMiddleware',\n   'django.contrib.auth.middleware.AuthenticationMiddleware',\n   'django.contrib.messages.middleware.MessageMiddleware',\n]\n\n\ndef get_url(game):\n    if os.environ.get('AIMMO_MODE', '') == 'minikube':\n        output = subprocess.check_output([os.environ['MINIKUBE_PATH'], 'service',\n                                          'game-%s' % game, '--url'])\n        return 'http://dev.aimmo.codeforlife.education', '/game-%s' % game\n    else:\n        return 'http://localhost:%d' % (6001 + int(game) * 1000), ''\n\n\nAIMMO_GAME_SERVER_LOCATION_FUNCTION = get_url\n\ntry:\n    from example_project.local_settings import *  # pylint: disable=E0611\nexcept ImportError:\n    pass\n\nfrom django_autoconfig import autoconfig\nautoconfig.configure_settings(globals())\n", "path": "example_project/example_project/settings.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.core.urlresolvers import reverse\nfrom django.http import HttpResponse, Http404\nfrom django.http import JsonResponse\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\n\nfrom models import Avatar, Game, LevelAttempt\nfrom players import forms\nfrom . import app_settings\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\ndef code(request, id):\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 _post_code_success_response('Your code was saved!<br><br><a href=\"%s\">Watch</a>' % reverse('aimmo/watch', kwargs={'id': game.id}))\n    else:\n        return HttpResponse(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.owner_id\n        response['main']['users'].append({\n            'id': avatar.owner_id,\n            'code': avatar.code,\n        })\n    return JsonResponse(response)\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 _render_game(request, game):\n    context = {\n        'current_user_player_key': request.user.pk,\n        'active': game.is_active,\n        'static_data': game.static_data or '{}',\n    }\n    context['game_url_base'], context['game_url_path'] = app_settings.GAME_SERVER_URL_FUNCTION(game.id)\n    context['game_url_port'] = app_settings.GAME_SERVER_PORT_FUNCTION(game.id)\n    context['game_ssl_flag'] = app_settings.GAME_SERVER_SSL_FLAG\n    context['game_id'] = game.id\n    return render(request, 'players/viewer.html', 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 _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 _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\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.save()\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", "path": "players/views.py"}, {"content": "from django.conf import settings\n\n#: URL function for locating the game server, takes one parameter `game`\nGAME_SERVER_URL_FUNCTION = getattr(settings, 'AIMMO_GAME_SERVER_URL_FUNCTION', None)\nGAME_SERVER_PORT_FUNCTION = getattr(settings, 'AIMMO_GAME_SERVER_PORT_FUNCTION', None)\nGAME_SERVER_SSL_FLAG = getattr(settings, 'AIMMO_GAME_SERVER_SSL_FLAG', False)\n\nMAX_LEVEL = 1\n", "path": "players/app_settings.py"}, {"content": "# -*- coding: utf-8 -*-\n# Code for Life\n#\n# Copyright (C) 2015, Ocado Innovation Limited\n#\n# This program is free software: you can redistribute it and/or modify\n# it under the terms of the GNU Affero General Public License as\n# published by the Free Software Foundation, either version 3 of the\n# License, or (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU Affero General Public License for more details.\n#\n# You should have received a copy of the GNU Affero General Public License\n# along with this program.  If not, see <http://www.gnu.org/licenses/>.\n#\n# ADDITIONAL TERMS \u2013 Section 7 GNU General Public Licence\n#\n# This licence does not grant any right, title or interest in any \u201cOcado\u201d logos,\n# trade names or the trademark \u201cOcado\u201d or any other trademarks or domain names\n# owned by Ocado Innovation Limited or the Ocado group of companies or any other\n# distinctive brand features of \u201cOcado\u201d as may be secured from time to time. You\n# must not distribute any modification of this program using the trademark\n# \u201cOcado\u201d or claim any affiliation or association with Ocado or its employees.\n#\n# You are not authorised to use the name Ocado (or any of its trade names) or\n# the names of any author or contributor in advertising or for publicity purposes\n# pertaining to the distribution of this program, without the prior written\n# authorisation of Ocado.\n#\n# Any propagation, distribution or conveyance of this program must include this\n# copyright notice and these terms. You must not misrepresent the origins of this\n# program; modified versions of the program must be marked as such and not\n# identified as the original program.\n\"\"\"Django settings for example_project project.\"\"\"\nimport subprocess\n\nimport os\n\nALLOWED_HOSTS = ['*']\n\nDEBUG = True\n\nDATABASES = {\n    'default': {\n        'ENGINE': 'django.db.backends.sqlite3',  # Add 'postgresql_psycopg2', 'mysql',\n                                                 # 'sqlite3' or 'oracle'.\n        'NAME': os.path.join(os.path.abspath(os.path.dirname(__file__)), 'db.sqlite3'),\n        # Or path to database file if using sqlite3.\n    }\n}\n\nUSE_I18N = True\nUSE_L10N = True\n\nTIME_ZONE = 'Europe/London'\nLANGUAGE_CODE = 'en-gb'\nSTATIC_ROOT = os.path.join(os.path.dirname(__file__), 'static')\nSTATIC_URL = '/static/'\nSECRET_KEY = 'not-a-secret'\n\nROOT_URLCONF = 'django_autoconfig.autourlconf'\n\nWSGI_APPLICATION = 'example_project.wsgi.application'\n\nINSTALLED_APPS = (\n    'django.contrib.admin',\n    'django.contrib.auth',\n    'django.contrib.contenttypes',\n    'players',\n    'django_forms_bootstrap',\n)\n\nLOGGING = {\n    'version': 1,\n    'disable_existing_loggers': False,\n    'filters': {\n        'require_debug_false': {\n            '()': 'django.utils.log.RequireDebugFalse'\n        }\n    },\n    'handlers': {\n        'console': {\n            'level': 'DEBUG',\n            'class': 'logging.StreamHandler'\n        },\n    },\n    'loggers': {\n        'views': {\n            'handlers': ['console'],\n            'level': 'DEBUG'\n        },\n    }\n}\n\nLOGIN_URL = '/players/accounts/login/'\n\nLOGIN_REDIRECT_URL = '/players/'\n\nMIDDLEWARE_CLASSES = [\n   'django.contrib.sessions.middleware.SessionMiddleware',\n   'django.middleware.locale.LocaleMiddleware',\n   'django.middleware.common.CommonMiddleware',\n   'django.middleware.csrf.CsrfViewMiddleware',\n   'django.contrib.auth.middleware.AuthenticationMiddleware',\n   'django.contrib.messages.middleware.MessageMiddleware',\n]\n\n\ndef get_game_url_base_and_path(game):\n    if os.environ.get('AIMMO_MODE', '') == 'minikube':\n        output = subprocess.check_output([os.environ['MINIKUBE_PATH'], 'service',\n                                          'game-%s' % game, '--url'])\n        return 'local.aimmo.codeforlife.education', '/game-%s' % game\n    else:\n        return 'localhost', ''\n\n\ndef get_game_port(game):\n    if os.environ.get('AIMMO_MODE', '') == 'minikube':\n        return 0\n\n    return 6001 + int(game) * 1000\n\n\nAIMMO_GAME_SERVER_URL_FUNCTION = get_game_url_base_and_path\nAIMMO_GAME_SERVER_PORT_FUNCTION = get_game_port\nAIMMO_GAME_SERVER_SSL_FLAG = False\n\ntry:\n    from example_project.local_settings import *  # pylint: disable=E0611\nexcept ImportError:\n    pass\n\nfrom django_autoconfig import autoconfig\nautoconfig.configure_settings(globals())\n", "path": "example_project/example_project/settings.py"}]}