Lint fix v1
This commit is contained in:
@@ -2,4 +2,4 @@ from django.apps import AppConfig
|
|||||||
|
|
||||||
|
|
||||||
class ApiConfig(AppConfig):
|
class ApiConfig(AppConfig):
|
||||||
name = "api"
|
name = 'api'
|
||||||
|
|||||||
@@ -3,12 +3,13 @@ from rest_framework.response import Response
|
|||||||
from rest_framework.views import APIView
|
from rest_framework.views import APIView
|
||||||
|
|
||||||
from game.models import Game, GameEvent, GameStatuses
|
from game.models import Game, GameEvent, GameStatuses
|
||||||
from ..serializers import GameSerializer, GameEventSerializer
|
|
||||||
|
from ..serializers import GameEventSerializer, GameSerializer
|
||||||
|
|
||||||
|
|
||||||
class GameResource(APIView):
|
class GameResource(APIView):
|
||||||
def post(self, request):
|
def post(self, request):
|
||||||
""" Creates a new game """
|
"""Creates a new game"""
|
||||||
|
|
||||||
serializer = GameSerializer(data=request.data)
|
serializer = GameSerializer(data=request.data)
|
||||||
if serializer.is_valid():
|
if serializer.is_valid():
|
||||||
@@ -19,7 +20,7 @@ class GameResource(APIView):
|
|||||||
|
|
||||||
class GameSingleResource(APIView):
|
class GameSingleResource(APIView):
|
||||||
def get(self, request, game_id):
|
def get(self, request, game_id):
|
||||||
""" Returns a game serialized or not found """
|
"""Returns a game serialized or not found"""
|
||||||
|
|
||||||
try:
|
try:
|
||||||
game = Game.objects.get(pk=game_id)
|
game = Game.objects.get(pk=game_id)
|
||||||
@@ -32,7 +33,7 @@ class GameSingleResource(APIView):
|
|||||||
|
|
||||||
class GameEventResource(APIView):
|
class GameEventResource(APIView):
|
||||||
def get(self, request, game_id):
|
def get(self, request, game_id):
|
||||||
""" Returns a list of all game events """
|
"""Returns a list of all game events"""
|
||||||
|
|
||||||
try:
|
try:
|
||||||
game = Game.objects.get(pk=game_id)
|
game = Game.objects.get(pk=game_id)
|
||||||
@@ -44,7 +45,7 @@ class GameEventResource(APIView):
|
|||||||
return Response(serializer.data)
|
return Response(serializer.data)
|
||||||
|
|
||||||
def post(self, request, game_id):
|
def post(self, request, game_id):
|
||||||
""" Creates a new event """
|
"""Creates a new event"""
|
||||||
|
|
||||||
try:
|
try:
|
||||||
game = Game.objects.get(pk=game_id)
|
game = Game.objects.get(pk=game_id)
|
||||||
@@ -53,20 +54,20 @@ class GameEventResource(APIView):
|
|||||||
|
|
||||||
if game.status == GameStatuses.FINISHED:
|
if game.status == GameStatuses.FINISHED:
|
||||||
return Response(
|
return Response(
|
||||||
{"message": "Game is already finished"},
|
{'message': 'Game is already finished'},
|
||||||
status=status.HTTP_412_PRECONDITION_FAILED,
|
status=status.HTTP_412_PRECONDITION_FAILED,
|
||||||
)
|
)
|
||||||
|
|
||||||
row = request.data.get("row")
|
row = request.data.get('row')
|
||||||
col = request.data.get("col")
|
col = request.data.get('col')
|
||||||
game_event = GameEvent.objects.filter(game=game, row=row, col=col).first()
|
game_event = GameEvent.objects.filter(game=game, row=row, col=col).first()
|
||||||
if game_event:
|
if game_event:
|
||||||
return Response(
|
return Response(
|
||||||
{"message": "This event was already registered"},
|
{'message': 'This event was already registered'},
|
||||||
status=status.HTTP_409_CONFLICT,
|
status=status.HTTP_409_CONFLICT,
|
||||||
)
|
)
|
||||||
data = dict(request.data)
|
data = dict(request.data)
|
||||||
data["game"] = game.pk
|
data['game'] = game.pk
|
||||||
|
|
||||||
serializer = GameEventSerializer(data=data)
|
serializer = GameEventSerializer(data=data)
|
||||||
if serializer.is_valid():
|
if serializer.is_valid():
|
||||||
|
|||||||
@@ -5,4 +5,4 @@ from rest_framework.views import APIView
|
|||||||
|
|
||||||
class MainResource(APIView):
|
class MainResource(APIView):
|
||||||
def get(self, request):
|
def get(self, request):
|
||||||
return Response({"message": "Welcome to the game!"}, status=status.HTTP_200_OK)
|
return Response({'message': 'Welcome to the game!'}, status=status.HTTP_200_OK)
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
from .game import GameSerializer, GameEventSerializer
|
from .game import GameEventSerializer, GameSerializer
|
||||||
|
|
||||||
|
__all__ = ['GameEventSerializer', 'GameSerializer']
|
||||||
__all__ = ["GameSerializer", "GameEventSerializer"]
|
|
||||||
|
|||||||
@@ -6,22 +6,22 @@ from game.models import Game, GameEvent, GameStatuses
|
|||||||
class GameSerializer(serializers.ModelSerializer):
|
class GameSerializer(serializers.ModelSerializer):
|
||||||
def to_representation(self, instance):
|
def to_representation(self, instance):
|
||||||
response = super().to_representation(instance)
|
response = super().to_representation(instance)
|
||||||
if not response["status"] == GameStatuses.FINISHED:
|
if not response['status'] == GameStatuses.FINISHED:
|
||||||
del response["board"]
|
del response['board']
|
||||||
|
|
||||||
return response
|
return response
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Game
|
model = Game
|
||||||
fields = "__all__"
|
fields = '__all__'
|
||||||
|
|
||||||
|
|
||||||
class GameEventSerializer(serializers.ModelSerializer):
|
class GameEventSerializer(serializers.ModelSerializer):
|
||||||
def to_representation(self, instance):
|
def to_representation(self, instance):
|
||||||
response = super().to_representation(instance)
|
response = super().to_representation(instance)
|
||||||
response["active_game"] = GameSerializer(instance.game).data
|
response['active_game'] = GameSerializer(instance.game).data
|
||||||
return response
|
return response
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = GameEvent
|
model = GameEvent
|
||||||
fields = "__all__"
|
fields = '__all__'
|
||||||
|
|||||||
13
api/urls.py
13
api/urls.py
@@ -1,14 +1,13 @@
|
|||||||
from django.urls import path
|
from django.urls import path
|
||||||
|
|
||||||
|
from .resources.game import GameEventResource, GameResource, GameSingleResource
|
||||||
from .resources.main import MainResource
|
from .resources.main import MainResource
|
||||||
from .resources.game import GameResource, GameSingleResource, GameEventResource
|
|
||||||
|
|
||||||
|
app_name = 'api'
|
||||||
app_name = "api"
|
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path("games/<game_id>/events", GameEventResource.as_view(), name="games_events"),
|
path('games/<game_id>/events', GameEventResource.as_view(), name='games_events'),
|
||||||
path("games/<game_id>", GameSingleResource.as_view(), name="games_single"),
|
path('games/<game_id>', GameSingleResource.as_view(), name='games_single'),
|
||||||
path("games", GameResource.as_view(), name="games"),
|
path('games', GameResource.as_view(), name='games'),
|
||||||
path("", MainResource.as_view(), name="main"),
|
path('', MainResource.as_view(), name='main'),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -11,6 +11,6 @@ import os
|
|||||||
|
|
||||||
from django.core.asgi import get_asgi_application
|
from django.core.asgi import get_asgi_application
|
||||||
|
|
||||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "app.settings")
|
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'app.settings')
|
||||||
|
|
||||||
application = get_asgi_application()
|
application = get_asgi_application()
|
||||||
|
|||||||
110
app/settings.py
110
app/settings.py
@@ -1,8 +1,8 @@
|
|||||||
import os
|
|
||||||
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
import sentry_sdk
|
import sentry_sdk
|
||||||
from sentry_sdk.integrations.django import DjangoIntegration
|
from sentry_sdk.integrations.django import DjangoIntegration
|
||||||
|
|
||||||
from .utils import get_op_config
|
from .utils import get_op_config
|
||||||
|
|
||||||
op_config = get_op_config()
|
op_config = get_op_config()
|
||||||
@@ -26,70 +26,70 @@ BASE_DIR = Path(__file__).resolve().parent.parent
|
|||||||
SECRET_KEY = op_config['settings.SECRET_KEY']
|
SECRET_KEY = op_config['settings.SECRET_KEY']
|
||||||
|
|
||||||
# SECURITY WARNING: don't run with debug turned on in production!
|
# SECURITY WARNING: don't run with debug turned on in production!
|
||||||
DEBUG = op_config.get("settings.DEBUG", "0") in ["1", "true"]
|
DEBUG = op_config.get('settings.DEBUG', '0') in ['1', 'true']
|
||||||
|
|
||||||
ALLOWED_HOSTS = op_config.get("settings.ALLOWED_HOSTS", "127.0.0.1,localhost").split(",")
|
ALLOWED_HOSTS = op_config.get('settings.ALLOWED_HOSTS', '127.0.0.1,localhost').split(',')
|
||||||
|
|
||||||
# Application definition
|
# Application definition
|
||||||
INSTALLED_APPS = [
|
INSTALLED_APPS = [
|
||||||
"rest_framework",
|
'rest_framework',
|
||||||
"django.contrib.admin",
|
'django.contrib.admin',
|
||||||
"django.contrib.auth",
|
'django.contrib.auth',
|
||||||
"django.contrib.contenttypes",
|
'django.contrib.contenttypes',
|
||||||
"django.contrib.sessions",
|
'django.contrib.sessions',
|
||||||
"django.contrib.messages",
|
'django.contrib.messages',
|
||||||
"django.contrib.staticfiles",
|
'django.contrib.staticfiles',
|
||||||
"corsheaders",
|
'corsheaders',
|
||||||
"core",
|
'core',
|
||||||
"api",
|
'api',
|
||||||
"game",
|
'game',
|
||||||
]
|
]
|
||||||
|
|
||||||
MIDDLEWARE = [
|
MIDDLEWARE = [
|
||||||
"django.middleware.security.SecurityMiddleware",
|
'django.middleware.security.SecurityMiddleware',
|
||||||
"django.contrib.sessions.middleware.SessionMiddleware",
|
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||||
"corsheaders.middleware.CorsMiddleware",
|
'corsheaders.middleware.CorsMiddleware',
|
||||||
"django.middleware.common.CommonMiddleware",
|
'django.middleware.common.CommonMiddleware',
|
||||||
"django.middleware.csrf.CsrfViewMiddleware",
|
'django.middleware.csrf.CsrfViewMiddleware',
|
||||||
"django.contrib.auth.middleware.AuthenticationMiddleware",
|
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||||
"django.contrib.messages.middleware.MessageMiddleware",
|
'django.contrib.messages.middleware.MessageMiddleware',
|
||||||
"django.middleware.clickjacking.XFrameOptionsMiddleware",
|
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||||
]
|
]
|
||||||
|
|
||||||
ROOT_URLCONF = "app.urls"
|
ROOT_URLCONF = 'app.urls'
|
||||||
|
|
||||||
TEMPLATES = [
|
TEMPLATES = [
|
||||||
{
|
{
|
||||||
"BACKEND": "django.template.backends.django.DjangoTemplates",
|
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||||
"DIRS": [],
|
'DIRS': [],
|
||||||
"APP_DIRS": True,
|
'APP_DIRS': True,
|
||||||
"OPTIONS": {
|
'OPTIONS': {
|
||||||
"context_processors": [
|
'context_processors': [
|
||||||
"django.template.context_processors.debug",
|
'django.template.context_processors.debug',
|
||||||
"django.template.context_processors.request",
|
'django.template.context_processors.request',
|
||||||
"django.contrib.auth.context_processors.auth",
|
'django.contrib.auth.context_processors.auth',
|
||||||
"django.contrib.messages.context_processors.messages",
|
'django.contrib.messages.context_processors.messages',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
WSGI_APPLICATION = "app.wsgi.application"
|
WSGI_APPLICATION = 'app.wsgi.application'
|
||||||
|
|
||||||
AUTH_USER_MODEL = "core.User"
|
AUTH_USER_MODEL = 'core.User'
|
||||||
|
|
||||||
|
|
||||||
# Database
|
# Database
|
||||||
# https://docs.djangoproject.com/en/3.1/ref/settings/#databases
|
# https://docs.djangoproject.com/en/3.1/ref/settings/#databases
|
||||||
DATABASES = {
|
DATABASES = {
|
||||||
"default": {
|
'default': {
|
||||||
"ENGINE": "django.db.backends.mysql",
|
'ENGINE': 'django.db.backends.mysql',
|
||||||
"NAME": op_config['database.name'],
|
'NAME': op_config['database.name'],
|
||||||
"USER": op_config['database.user'],
|
'USER': op_config['database.user'],
|
||||||
"PASSWORD": op_config['database.password'],
|
'PASSWORD': op_config['database.password'],
|
||||||
"HOST": op_config['database.host'],
|
'HOST': op_config['database.host'],
|
||||||
"PORT": op_config['database.port'],
|
'PORT': op_config['database.port'],
|
||||||
"OPTIONS": {"charset": "utf8mb4"},
|
'OPTIONS': {'charset': 'utf8mb4'},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,21 +98,19 @@ DATABASES = {
|
|||||||
# https://docs.djangoproject.com/en/3.1/ref/settings/#auth-password-validators
|
# https://docs.djangoproject.com/en/3.1/ref/settings/#auth-password-validators
|
||||||
|
|
||||||
AUTH_PASSWORD_VALIDATORS = [
|
AUTH_PASSWORD_VALIDATORS = [
|
||||||
{
|
{'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator'},
|
||||||
"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator"
|
{'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator'},
|
||||||
},
|
{'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator'},
|
||||||
{"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator"},
|
{'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator'},
|
||||||
{"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator"},
|
|
||||||
{"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator"},
|
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
# Internationalization
|
# Internationalization
|
||||||
# https://docs.djangoproject.com/en/3.1/topics/i18n/
|
# https://docs.djangoproject.com/en/3.1/topics/i18n/
|
||||||
|
|
||||||
LANGUAGE_CODE = "en-us"
|
LANGUAGE_CODE = 'en-us'
|
||||||
|
|
||||||
TIME_ZONE = "UTC"
|
TIME_ZONE = 'UTC'
|
||||||
|
|
||||||
USE_I18N = True
|
USE_I18N = True
|
||||||
|
|
||||||
@@ -124,15 +122,13 @@ USE_TZ = True
|
|||||||
# Static files (CSS, JavaScript, Images)
|
# Static files (CSS, JavaScript, Images)
|
||||||
# https://docs.djangoproject.com/en/3.1/howto/static-files/
|
# https://docs.djangoproject.com/en/3.1/howto/static-files/
|
||||||
|
|
||||||
STATIC_URL = "/static/"
|
STATIC_URL = '/static/'
|
||||||
|
|
||||||
# Some Django Rest Framework parameters
|
# Some Django Rest Framework parameters
|
||||||
REST_FRAMEWORK = {
|
REST_FRAMEWORK = {
|
||||||
"DEFAULT_PERMISSION_CLASSES": ["rest_framework.permissions.AllowAny"],
|
'DEFAULT_PERMISSION_CLASSES': ['rest_framework.permissions.AllowAny'],
|
||||||
"DEFAULT_AUTHENTICATION_CLASSES": [
|
'DEFAULT_AUTHENTICATION_CLASSES': ['rest_framework.authentication.TokenAuthentication'],
|
||||||
"rest_framework.authentication.TokenAuthentication"
|
'DEFAULT_RENDERER_CLASSES': ('rest_framework.renderers.JSONRenderer',),
|
||||||
],
|
|
||||||
"DEFAULT_RENDERER_CLASSES": ("rest_framework.renderers.JSONRenderer",),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if DEBUG is True:
|
if DEBUG is True:
|
||||||
|
|||||||
@@ -1,14 +1,13 @@
|
|||||||
from django.contrib import admin
|
|
||||||
from django.urls import path, include
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
from django.contrib import admin
|
||||||
|
from django.urls import include, path
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path("", include("api.urls")),
|
path('', include('api.urls')),
|
||||||
]
|
]
|
||||||
|
|
||||||
# We need this only for development purpose
|
# We need this only for development purpose
|
||||||
if settings.DEBUG is True:
|
if settings.DEBUG is True:
|
||||||
urlpatterns += [
|
urlpatterns += [
|
||||||
path("admin/", admin.site.urls),
|
path('admin/', admin.site.urls),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
import os
|
|
||||||
|
|
||||||
import onepasswordconnectsdk
|
import onepasswordconnectsdk
|
||||||
from onepasswordconnectsdk.client import Client, new_client_from_environment
|
from onepasswordconnectsdk.client import Client, new_client_from_environment
|
||||||
|
|
||||||
@@ -22,6 +20,6 @@ def get_op_config():
|
|||||||
|
|
||||||
op_config_get = {}
|
op_config_get = {}
|
||||||
for var in OP_DJANGO_SETTINGS_VARS:
|
for var in OP_DJANGO_SETTINGS_VARS:
|
||||||
op_config_get[var] = {"opitem": "mines", "opfield": var}
|
op_config_get[var] = {'opitem': 'mines', 'opfield': var}
|
||||||
|
|
||||||
return onepasswordconnectsdk.load_dict(op_client, op_config_get)
|
return onepasswordconnectsdk.load_dict(op_client, op_config_get)
|
||||||
|
|||||||
@@ -11,6 +11,6 @@ import os
|
|||||||
|
|
||||||
from django.core.wsgi import get_wsgi_application
|
from django.core.wsgi import get_wsgi_application
|
||||||
|
|
||||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "app.settings")
|
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'app.settings')
|
||||||
|
|
||||||
application = get_wsgi_application()
|
application = get_wsgi_application()
|
||||||
|
|||||||
@@ -5,12 +5,12 @@ from .models import User
|
|||||||
|
|
||||||
@admin.register(User)
|
@admin.register(User)
|
||||||
class UserAdmin(admin.ModelAdmin):
|
class UserAdmin(admin.ModelAdmin):
|
||||||
search_fields = ("id", "email", "first_name", "last_name")
|
search_fields = ('id', 'email', 'first_name', 'last_name')
|
||||||
list_display = (
|
list_display = (
|
||||||
"id",
|
'id',
|
||||||
"first_name",
|
'first_name',
|
||||||
"last_name",
|
'last_name',
|
||||||
"is_active",
|
'is_active',
|
||||||
"email",
|
'email',
|
||||||
"date_joined",
|
'date_joined',
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -2,4 +2,4 @@ from django.apps import AppConfig
|
|||||||
|
|
||||||
|
|
||||||
class CoreConfig(AppConfig):
|
class CoreConfig(AppConfig):
|
||||||
name = "core"
|
name = 'core'
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ class UserManager(BaseUserManager):
|
|||||||
Creates and saves a User with the given email and password.
|
Creates and saves a User with the given email and password.
|
||||||
"""
|
"""
|
||||||
if not email:
|
if not email:
|
||||||
raise ValueError("The given email must be set")
|
raise ValueError('The given email must be set')
|
||||||
email = self.normalize_email(email)
|
email = self.normalize_email(email)
|
||||||
user = self.model(email=email, **extra_fields)
|
user = self.model(email=email, **extra_fields)
|
||||||
user.set_password(password)
|
user.set_password(password)
|
||||||
@@ -17,13 +17,13 @@ class UserManager(BaseUserManager):
|
|||||||
return user
|
return user
|
||||||
|
|
||||||
def create_user(self, email, password=None, **extra_fields):
|
def create_user(self, email, password=None, **extra_fields):
|
||||||
extra_fields.setdefault("is_superuser", False)
|
extra_fields.setdefault('is_superuser', False)
|
||||||
return self._create_user(email, password, **extra_fields)
|
return self._create_user(email, password, **extra_fields)
|
||||||
|
|
||||||
def create_superuser(self, email, password, **extra_fields):
|
def create_superuser(self, email, password, **extra_fields):
|
||||||
extra_fields.setdefault("is_superuser", True)
|
extra_fields.setdefault('is_superuser', True)
|
||||||
|
|
||||||
if extra_fields.get("is_superuser") is not True:
|
if extra_fields.get('is_superuser') is not True:
|
||||||
raise ValueError("Superuser must have is_superuser=True.")
|
raise ValueError('Superuser must have is_superuser=True.')
|
||||||
|
|
||||||
return self._create_user(email, password, **extra_fields)
|
return self._create_user(email, password, **extra_fields)
|
||||||
|
|||||||
@@ -1,98 +1,89 @@
|
|||||||
# Generated by Django 3.1.3 on 2020-11-05 00:51
|
# Generated by Django 3.1.3 on 2020-11-05 00:51
|
||||||
|
|
||||||
import core.managers
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
import core.managers
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
initial = True
|
initial = True
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
("auth", "0012_alter_user_first_name_max_length"),
|
('auth', '0012_alter_user_first_name_max_length'),
|
||||||
]
|
]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name="User",
|
name='User',
|
||||||
fields=[
|
fields=[
|
||||||
(
|
(
|
||||||
"id",
|
'id',
|
||||||
models.AutoField(
|
models.AutoField(
|
||||||
auto_created=True,
|
auto_created=True,
|
||||||
primary_key=True,
|
primary_key=True,
|
||||||
serialize=False,
|
serialize=False,
|
||||||
verbose_name="ID",
|
verbose_name='ID',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
("password", models.CharField(max_length=128, verbose_name="password")),
|
('password', models.CharField(max_length=128, verbose_name='password')),
|
||||||
(
|
(
|
||||||
"last_login",
|
'last_login',
|
||||||
models.DateTimeField(
|
models.DateTimeField(blank=True, null=True, verbose_name='last login'),
|
||||||
blank=True, null=True, verbose_name="last login"
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"email",
|
'email',
|
||||||
models.EmailField(
|
models.EmailField(max_length=254, unique=True, verbose_name='E-mail'),
|
||||||
max_length=254, unique=True, verbose_name="E-mail"
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"first_name",
|
'first_name',
|
||||||
models.CharField(
|
models.CharField(blank=True, max_length=30, verbose_name='First name'),
|
||||||
blank=True, max_length=30, verbose_name="First name"
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"last_name",
|
'last_name',
|
||||||
models.CharField(
|
models.CharField(blank=True, max_length=30, verbose_name='Last name'),
|
||||||
blank=True, max_length=30, verbose_name="Last name"
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"date_joined",
|
'date_joined',
|
||||||
models.DateTimeField(auto_now_add=True, verbose_name="date joined"),
|
models.DateTimeField(auto_now_add=True, verbose_name='date joined'),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"is_active",
|
'is_active',
|
||||||
models.BooleanField(default=True, verbose_name="User active?"),
|
models.BooleanField(default=True, verbose_name='User active?'),
|
||||||
),
|
),
|
||||||
("is_staff", models.BooleanField(default=False, verbose_name="Staff?")),
|
('is_staff', models.BooleanField(default=False, verbose_name='Staff?')),
|
||||||
(
|
(
|
||||||
"is_superuser",
|
'is_superuser',
|
||||||
models.BooleanField(default=False, verbose_name="Superuser?"),
|
models.BooleanField(default=False, verbose_name='Superuser?'),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"groups",
|
'groups',
|
||||||
models.ManyToManyField(
|
models.ManyToManyField(
|
||||||
blank=True,
|
blank=True,
|
||||||
help_text="The groups this user belongs to. A"
|
help_text='The groups this user belongs to. Auser will get all permissions granted to each of their groups.',
|
||||||
"user will get all permissions granted to each of their groups.",
|
related_name='user_set',
|
||||||
related_name="user_set",
|
related_query_name='user',
|
||||||
related_query_name="user",
|
to='auth.Group',
|
||||||
to="auth.Group",
|
verbose_name='groups',
|
||||||
verbose_name="groups",
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"user_permissions",
|
'user_permissions',
|
||||||
models.ManyToManyField(
|
models.ManyToManyField(
|
||||||
blank=True,
|
blank=True,
|
||||||
help_text="Specific permissions for this user.",
|
help_text='Specific permissions for this user.',
|
||||||
related_name="user_set",
|
related_name='user_set',
|
||||||
related_query_name="user",
|
related_query_name='user',
|
||||||
to="auth.Permission",
|
to='auth.Permission',
|
||||||
verbose_name="user permissions",
|
verbose_name='user permissions',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
options={
|
options={
|
||||||
"verbose_name": "User",
|
'verbose_name': 'User',
|
||||||
"verbose_name_plural": "Users",
|
'verbose_name_plural': 'Users',
|
||||||
"db_table": "users",
|
'db_table': 'users',
|
||||||
"ordering": ["first_name", "last_name"],
|
'ordering': ['first_name', 'last_name'],
|
||||||
},
|
},
|
||||||
managers=[("objects", core.managers.UserManager())],
|
managers=[('objects', core.managers.UserManager())],
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -4,24 +4,22 @@ from django.db import migrations, models
|
|||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
("auth", "0012_alter_user_first_name_max_length"),
|
('auth', '0012_alter_user_first_name_max_length'),
|
||||||
("core", "0001_initial"),
|
('core', '0001_initial'),
|
||||||
]
|
]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name="user",
|
model_name='user',
|
||||||
name="groups",
|
name='groups',
|
||||||
field=models.ManyToManyField(
|
field=models.ManyToManyField(
|
||||||
blank=True,
|
blank=True,
|
||||||
help_text="The groups this user belongs to. "
|
help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.',
|
||||||
"A user will get all permissions granted to each of their groups.",
|
related_name='user_set',
|
||||||
related_name="user_set",
|
related_query_name='user',
|
||||||
related_query_name="user",
|
to='auth.Group',
|
||||||
to="auth.Group",
|
verbose_name='groups',
|
||||||
verbose_name="groups",
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -4,15 +4,14 @@ from django.db import migrations, models
|
|||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
("core", "0002_auto_20201105_0303"),
|
('core', '0002_auto_20201105_0303'),
|
||||||
]
|
]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name="user",
|
model_name='user',
|
||||||
name="is_staff",
|
name='is_staff',
|
||||||
field=models.BooleanField(default=True, verbose_name="Staff?"),
|
field=models.BooleanField(default=True, verbose_name='Staff?'),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -4,17 +4,14 @@ from django.db import migrations, models
|
|||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
("core", "0003_auto_20201106_0152"),
|
('core', '0003_auto_20201106_0152'),
|
||||||
]
|
]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name="user",
|
model_name='user',
|
||||||
name="id",
|
name='id',
|
||||||
field=models.BigAutoField(
|
field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
|
||||||
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,41 +1,41 @@
|
|||||||
from django.db import models
|
|
||||||
from django.contrib.auth.models import PermissionsMixin
|
|
||||||
from django.contrib.auth.base_user import AbstractBaseUser
|
from django.contrib.auth.base_user import AbstractBaseUser
|
||||||
|
from django.contrib.auth.models import PermissionsMixin
|
||||||
|
from django.db import models
|
||||||
|
|
||||||
from .managers import UserManager
|
from .managers import UserManager
|
||||||
|
|
||||||
|
|
||||||
class User(AbstractBaseUser, PermissionsMixin):
|
class User(AbstractBaseUser, PermissionsMixin):
|
||||||
email = models.EmailField("E-mail", unique=True)
|
email = models.EmailField('E-mail', unique=True)
|
||||||
|
|
||||||
first_name = models.CharField("First name", max_length=30, blank=True)
|
first_name = models.CharField('First name', max_length=30, blank=True)
|
||||||
last_name = models.CharField("Last name", max_length=30, blank=True)
|
last_name = models.CharField('Last name', max_length=30, blank=True)
|
||||||
|
|
||||||
date_joined = models.DateTimeField("date joined", auto_now_add=True)
|
date_joined = models.DateTimeField('date joined', auto_now_add=True)
|
||||||
|
|
||||||
is_active = models.BooleanField("User active?", default=True)
|
is_active = models.BooleanField('User active?', default=True)
|
||||||
is_staff = models.BooleanField("Staff?", default=True)
|
is_staff = models.BooleanField('Staff?', default=True)
|
||||||
is_superuser = models.BooleanField("Superuser?", default=False)
|
is_superuser = models.BooleanField('Superuser?', default=False)
|
||||||
|
|
||||||
objects = UserManager()
|
objects = UserManager()
|
||||||
|
|
||||||
USERNAME_FIELD = "email"
|
USERNAME_FIELD = 'email'
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
ordering = ["first_name", "last_name"]
|
ordering = ['first_name', 'last_name']
|
||||||
verbose_name = "User"
|
verbose_name = 'User'
|
||||||
verbose_name_plural = "Users"
|
verbose_name_plural = 'Users'
|
||||||
db_table = "users"
|
db_table = 'users'
|
||||||
|
|
||||||
def get_full_name(self):
|
def get_full_name(self):
|
||||||
"""
|
"""
|
||||||
Returns the first_name plus the last_name, with a space in between.
|
Returns the first_name plus the last_name, with a space in between.
|
||||||
"""
|
"""
|
||||||
full_name = f"{self.first_name} {self.last_name}"
|
full_name = f'{self.first_name} {self.last_name}'
|
||||||
return full_name.strip()
|
return full_name.strip()
|
||||||
|
|
||||||
def get_short_name(self):
|
def get_short_name(self):
|
||||||
"""
|
"""
|
||||||
Returns the short name for the user.
|
Returns the short name for the user.
|
||||||
"""
|
"""
|
||||||
return self.first_name or "Unamed"
|
return self.first_name or 'Unamed'
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
default_app_config = "game.apps.GameConfig"
|
default_app_config = 'game.apps.GameConfig'
|
||||||
|
|||||||
@@ -6,24 +6,24 @@ from .models import Game, GameEvent
|
|||||||
@admin.register(Game)
|
@admin.register(Game)
|
||||||
class GameAdmin(admin.ModelAdmin):
|
class GameAdmin(admin.ModelAdmin):
|
||||||
list_display = (
|
list_display = (
|
||||||
"id",
|
'id',
|
||||||
"created_at",
|
'created_at',
|
||||||
"modified_at",
|
'modified_at',
|
||||||
"rows",
|
'rows',
|
||||||
"cols",
|
'cols',
|
||||||
"mines",
|
'mines',
|
||||||
"win",
|
'win',
|
||||||
"status",
|
'status',
|
||||||
)
|
)
|
||||||
|
|
||||||
list_filter = (
|
list_filter = (
|
||||||
"win",
|
'win',
|
||||||
"status",
|
'status',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@admin.register(GameEvent)
|
@admin.register(GameEvent)
|
||||||
class GameEventAdmin(admin.ModelAdmin):
|
class GameEventAdmin(admin.ModelAdmin):
|
||||||
list_display = ("id", "created_at", "game", "type", "row", "col")
|
list_display = ('id', 'created_at', 'game', 'type', 'row', 'col')
|
||||||
|
|
||||||
list_filter = ("type",)
|
list_filter = ('type',)
|
||||||
|
|||||||
@@ -2,9 +2,9 @@ from django.apps import AppConfig
|
|||||||
|
|
||||||
|
|
||||||
class GameConfig(AppConfig):
|
class GameConfig(AppConfig):
|
||||||
name = "game"
|
name = 'game'
|
||||||
verbose_name = "Game"
|
verbose_name = 'Game'
|
||||||
verbose_name_plural = "Games"
|
verbose_name_plural = 'Games'
|
||||||
|
|
||||||
def ready(self):
|
def ready(self):
|
||||||
import game.signals # noqa
|
import game.signals # noqa
|
||||||
|
|||||||
28
game/game.py
28
game/game.py
@@ -16,11 +16,9 @@ class Minesweeper:
|
|||||||
self.board_progress = board_progress
|
self.board_progress = board_progress
|
||||||
|
|
||||||
def create_board(self):
|
def create_board(self):
|
||||||
""" Creating the board cells with 0 as default value """
|
"""Creating the board cells with 0 as default value"""
|
||||||
self.board = [[0 for col in range(self.cols)] for row in range(self.rows)]
|
self.board = [[0 for col in range(self.cols)] for row in range(self.rows)]
|
||||||
self.board_progress = [
|
self.board_progress = [['-' for col in range(self.cols)] for row in range(self.rows)]
|
||||||
["-" for col in range(self.cols)] for row in range(self.rows)
|
|
||||||
]
|
|
||||||
|
|
||||||
def put_mine(self):
|
def put_mine(self):
|
||||||
"""Put a single mine on the board.
|
"""Put a single mine on the board.
|
||||||
@@ -36,7 +34,7 @@ class Minesweeper:
|
|||||||
return row, col
|
return row, col
|
||||||
|
|
||||||
def put_mines(self):
|
def put_mines(self):
|
||||||
""" Put the desired amount of mines on the board """
|
"""Put the desired amount of mines on the board"""
|
||||||
for mine in range(1, self.mines + 1):
|
for mine in range(1, self.mines + 1):
|
||||||
row, col = self.put_mine()
|
row, col = self.put_mine()
|
||||||
|
|
||||||
@@ -71,31 +69,31 @@ class Minesweeper:
|
|||||||
self.increment_safe_point(row - 1, col - 1)
|
self.increment_safe_point(row - 1, col - 1)
|
||||||
|
|
||||||
def is_mine(self, row, col):
|
def is_mine(self, row, col):
|
||||||
""" Checks whether the given location have a mine """
|
"""Checks whether the given location have a mine"""
|
||||||
if not self.is_point_in_board(row, col):
|
if not self.is_point_in_board(row, col):
|
||||||
return False
|
return False
|
||||||
return self.board[row][col] == -1
|
return self.board[row][col] == -1
|
||||||
|
|
||||||
def is_empty(self, row, col):
|
def is_empty(self, row, col):
|
||||||
""" Checks whether the given location is empty """
|
"""Checks whether the given location is empty"""
|
||||||
if not self.is_point_in_board(row, col):
|
if not self.is_point_in_board(row, col):
|
||||||
return False
|
return False
|
||||||
return self.board[row][col] == 0
|
return self.board[row][col] == 0
|
||||||
|
|
||||||
def is_point(self, row, col):
|
def is_point(self, row, col):
|
||||||
""" Checks whether the given location have pontuation """
|
"""Checks whether the given location have pontuation"""
|
||||||
if not self.is_point_in_board(row, col):
|
if not self.is_point_in_board(row, col):
|
||||||
return False
|
return False
|
||||||
return self.board[row][col] > 0
|
return self.board[row][col] > 0
|
||||||
|
|
||||||
def is_point_in_board(self, row, col):
|
def is_point_in_board(self, row, col):
|
||||||
""" Checks whether the location is inside board """
|
"""Checks whether the location is inside board"""
|
||||||
if row in range(0, self.rows) and col in range(0, self.cols):
|
if row in range(self.rows) and col in range(self.cols):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def increment_safe_point(self, row, col):
|
def increment_safe_point(self, row, col):
|
||||||
""" Creates the mine's pontuation frame """
|
"""Creates the mine's pontuation frame"""
|
||||||
|
|
||||||
# Ignores if the point whether not in the board
|
# Ignores if the point whether not in the board
|
||||||
if not self.is_point_in_board(row, col):
|
if not self.is_point_in_board(row, col):
|
||||||
@@ -129,7 +127,7 @@ class Minesweeper:
|
|||||||
while r < max_row:
|
while r < max_row:
|
||||||
c = min_col
|
c = min_col
|
||||||
while c < max_col:
|
while c < max_col:
|
||||||
if not self.board[r][c] == -1 and self.board_progress[r][c] == "-":
|
if not self.board[r][c] == -1 and self.board_progress[r][c] == '-':
|
||||||
self.board_progress[r][c] = self.board[r][c]
|
self.board_progress[r][c] = self.board[r][c]
|
||||||
|
|
||||||
if self.board[r][c] == 0:
|
if self.board[r][c] == 0:
|
||||||
@@ -138,7 +136,7 @@ class Minesweeper:
|
|||||||
r += 1
|
r += 1
|
||||||
|
|
||||||
def reveal(self, row, col):
|
def reveal(self, row, col):
|
||||||
""" Reveals the cell's content and yours adjacents cells """
|
"""Reveals the cell's content and yours adjacents cells"""
|
||||||
self.board_progress[row][col] = self.board[row][col]
|
self.board_progress[row][col] = self.board[row][col]
|
||||||
|
|
||||||
# We will show adjacents only if the cell clicked is zero
|
# We will show adjacents only if the cell clicked is zero
|
||||||
@@ -146,14 +144,14 @@ class Minesweeper:
|
|||||||
self.reveal_adjacents(row, col)
|
self.reveal_adjacents(row, col)
|
||||||
|
|
||||||
def win(self):
|
def win(self):
|
||||||
""" Identify if the player won the game """
|
"""Identify if the player won the game"""
|
||||||
unrevealed = 0
|
unrevealed = 0
|
||||||
for row in self.board_progress:
|
for row in self.board_progress:
|
||||||
for cell in row:
|
for cell in row:
|
||||||
if cell == -1:
|
if cell == -1:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if cell == "-":
|
if cell == '-':
|
||||||
unrevealed += 1
|
unrevealed += 1
|
||||||
if (unrevealed - self.mines) == 0:
|
if (unrevealed - self.mines) == 0:
|
||||||
return True
|
return True
|
||||||
|
|||||||
@@ -1,65 +1,61 @@
|
|||||||
# Generated by Django 3.1.3 on 2020-11-05 03:03
|
# Generated by Django 3.1.3 on 2020-11-05 03:03
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
import django_mysql.models
|
import django_mysql.models
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
import internal.utils
|
import internal.utils
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
initial = True
|
initial = True
|
||||||
|
|
||||||
dependencies = []
|
dependencies = []
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name="Game",
|
name='Game',
|
||||||
fields=[
|
fields=[
|
||||||
(
|
(
|
||||||
"id",
|
'id',
|
||||||
models.AutoField(
|
models.AutoField(
|
||||||
auto_created=True,
|
auto_created=True,
|
||||||
primary_key=True,
|
primary_key=True,
|
||||||
serialize=False,
|
serialize=False,
|
||||||
verbose_name="ID",
|
verbose_name='ID',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"created_at",
|
'created_at',
|
||||||
models.DateTimeField(
|
models.DateTimeField(auto_now_add=True, verbose_name='Creation date'),
|
||||||
auto_now_add=True, verbose_name="Creation date"
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"modified_at",
|
'modified_at',
|
||||||
models.DateTimeField(auto_now=True, verbose_name="Last update"),
|
models.DateTimeField(auto_now=True, verbose_name='Last update'),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"rows",
|
'rows',
|
||||||
models.PositiveIntegerField(default=10, verbose_name="Board rows"),
|
models.PositiveIntegerField(default=10, verbose_name='Board rows'),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"cols",
|
'cols',
|
||||||
models.PositiveIntegerField(default=10, verbose_name="Board cols"),
|
models.PositiveIntegerField(default=10, verbose_name='Board cols'),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"mines",
|
'mines',
|
||||||
models.PositiveIntegerField(
|
models.PositiveIntegerField(default=5, verbose_name='Mines on board'),
|
||||||
default=5, verbose_name="Mines on board"
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"board",
|
'board',
|
||||||
django_mysql.models.JSONField(
|
django_mysql.models.JSONField(
|
||||||
default=internal.utils.empty_list,
|
default=internal.utils.empty_list,
|
||||||
verbose_name="Generated board",
|
verbose_name='Generated board',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
options={
|
options={
|
||||||
"verbose_name": "Game",
|
'verbose_name': 'Game',
|
||||||
"verbose_name_plural": "Games",
|
'verbose_name_plural': 'Games',
|
||||||
"db_table": "games",
|
'db_table': 'games',
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,68 +1,64 @@
|
|||||||
# Generated by Django 3.1.3 on 2020-11-06 02:25
|
# Generated by Django 3.1.3 on 2020-11-06 02:25
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
import django_mysql.models
|
import django_mysql.models
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
import game.models
|
import game.models
|
||||||
import internal.utils
|
import internal.utils
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
("game", "0001_initial"),
|
('game', '0001_initial'),
|
||||||
]
|
]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name="game",
|
model_name='game',
|
||||||
name="status",
|
name='status',
|
||||||
field=models.IntegerField(
|
field=models.IntegerField(
|
||||||
choices=[(0, "NOT_PLAYED"), (1, "PLAYING"), (2, "FINISHED")],
|
choices=[(0, 'NOT_PLAYED'), (1, 'PLAYING'), (2, 'FINISHED')],
|
||||||
default=game.models.GameStatuses["NOT_PLAYED"],
|
default=game.models.GameStatuses['NOT_PLAYED'],
|
||||||
help_text="Actual game status",
|
help_text='Actual game status',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name="game",
|
model_name='game',
|
||||||
name="win",
|
name='win',
|
||||||
field=models.BooleanField(
|
field=models.BooleanField(
|
||||||
blank=True,
|
blank=True,
|
||||||
default=None,
|
default=None,
|
||||||
help_text="Did the user win the game?",
|
help_text='Did the user win the game?',
|
||||||
null=True,
|
null=True,
|
||||||
verbose_name="Win?",
|
verbose_name='Win?',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name="game",
|
model_name='game',
|
||||||
name="board",
|
name='board',
|
||||||
field=django_mysql.models.JSONField(
|
field=django_mysql.models.JSONField(
|
||||||
default=internal.utils.empty_list,
|
default=internal.utils.empty_list,
|
||||||
help_text="Whe generated board game",
|
help_text='Whe generated board game',
|
||||||
verbose_name="Generated board",
|
verbose_name='Generated board',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name="game",
|
model_name='game',
|
||||||
name="cols",
|
name='cols',
|
||||||
field=models.PositiveIntegerField(
|
field=models.PositiveIntegerField(default=10, help_text="Board's total columns", verbose_name='Board cols'),
|
||||||
default=10, help_text="Board's total columns", verbose_name="Board cols"
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name="game",
|
model_name='game',
|
||||||
name="mines",
|
name='mines',
|
||||||
field=models.PositiveIntegerField(
|
field=models.PositiveIntegerField(
|
||||||
default=5,
|
default=5,
|
||||||
help_text="Board's total placed mines",
|
help_text="Board's total placed mines",
|
||||||
verbose_name="Mines on board",
|
verbose_name='Mines on board',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name="game",
|
model_name='game',
|
||||||
name="rows",
|
name='rows',
|
||||||
field=models.PositiveIntegerField(
|
field=models.PositiveIntegerField(default=10, help_text="Board's total rows", verbose_name='Board rows'),
|
||||||
default=10, help_text="Board's total rows", verbose_name="Board rows"
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,73 +1,69 @@
|
|||||||
# Generated by Django 3.1.3 on 2020-11-06 03:54
|
# Generated by Django 3.1.3 on 2020-11-06 03:54
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
import django.db.models.deletion
|
import django.db.models.deletion
|
||||||
import django_mysql.models
|
import django_mysql.models
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
import game.models
|
import game.models
|
||||||
import internal.utils
|
import internal.utils
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
("game", "0002_auto_20201106_0225"),
|
('game', '0002_auto_20201106_0225'),
|
||||||
]
|
]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name="GameEvent",
|
name='GameEvent',
|
||||||
fields=[
|
fields=[
|
||||||
(
|
(
|
||||||
"id",
|
'id',
|
||||||
models.AutoField(
|
models.AutoField(
|
||||||
auto_created=True,
|
auto_created=True,
|
||||||
primary_key=True,
|
primary_key=True,
|
||||||
serialize=False,
|
serialize=False,
|
||||||
verbose_name="ID",
|
verbose_name='ID',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"created_at",
|
'created_at',
|
||||||
models.DateTimeField(
|
models.DateTimeField(auto_now_add=True, verbose_name='Creation date'),
|
||||||
auto_now_add=True, verbose_name="Creation date"
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"type",
|
'type',
|
||||||
models.IntegerField(
|
models.IntegerField(
|
||||||
choices=[
|
choices=[
|
||||||
(0, "START_GAME"),
|
(0, 'START_GAME'),
|
||||||
(1, "PAUSE"),
|
(1, 'PAUSE'),
|
||||||
(2, "RESUME"),
|
(2, 'RESUME'),
|
||||||
(3, "CLICK_MINE"),
|
(3, 'CLICK_MINE'),
|
||||||
(4, "CLICK_POINT"),
|
(4, 'CLICK_POINT'),
|
||||||
(5, "CLICK_EMPTY"),
|
(5, 'CLICK_EMPTY'),
|
||||||
(6, "CLICK_FLAG"),
|
(6, 'CLICK_FLAG'),
|
||||||
(7, "GAME_OVER"),
|
(7, 'GAME_OVER'),
|
||||||
],
|
],
|
||||||
default=game.models.EventTypes["START_GAME"],
|
default=game.models.EventTypes['START_GAME'],
|
||||||
help_text="The game event",
|
help_text='The game event',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"metadata",
|
'metadata',
|
||||||
django_mysql.models.JSONField(
|
django_mysql.models.JSONField(
|
||||||
default=internal.utils.empty_object,
|
default=internal.utils.empty_object,
|
||||||
help_text="Some usefull event metadata",
|
help_text='Some usefull event metadata',
|
||||||
verbose_name="Event metadata",
|
verbose_name='Event metadata',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"game",
|
'game',
|
||||||
models.ForeignKey(
|
models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='game.game'),
|
||||||
on_delete=django.db.models.deletion.CASCADE, to="game.game"
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
options={
|
options={
|
||||||
"verbose_name": "Game event",
|
'verbose_name': 'Game event',
|
||||||
"verbose_name_plural": "Game events",
|
'verbose_name_plural': 'Game events',
|
||||||
"db_table": "game_events",
|
'db_table': 'game_events',
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,41 +1,41 @@
|
|||||||
# Generated by Django 3.1.3 on 2020-11-06 04:53
|
# Generated by Django 3.1.3 on 2020-11-06 04:53
|
||||||
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
||||||
import game.models
|
import game.models
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
("game", "0003_gameevent"),
|
('game', '0003_gameevent'),
|
||||||
]
|
]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterModelOptions(
|
migrations.AlterModelOptions(
|
||||||
name="gameevent",
|
name='gameevent',
|
||||||
options={
|
options={
|
||||||
"ordering": ["created_at"],
|
'ordering': ['created_at'],
|
||||||
"verbose_name": "Game event",
|
'verbose_name': 'Game event',
|
||||||
"verbose_name_plural": "Game events",
|
'verbose_name_plural': 'Game events',
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name="gameevent",
|
model_name='gameevent',
|
||||||
name="type",
|
name='type',
|
||||||
field=models.IntegerField(
|
field=models.IntegerField(
|
||||||
choices=[
|
choices=[
|
||||||
(0, "START_GAME"),
|
(0, 'START_GAME'),
|
||||||
(1, "PAUSE"),
|
(1, 'PAUSE'),
|
||||||
(2, "RESUME"),
|
(2, 'RESUME'),
|
||||||
(3, "CLICK_MINE"),
|
(3, 'CLICK_MINE'),
|
||||||
(4, "CLICK_POINT"),
|
(4, 'CLICK_POINT'),
|
||||||
(5, "CLICK_EMPTY"),
|
(5, 'CLICK_EMPTY'),
|
||||||
(6, "CLICK_FLAG"),
|
(6, 'CLICK_FLAG'),
|
||||||
(7, "GAME_OVER"),
|
(7, 'GAME_OVER'),
|
||||||
(8, "CLICK_NAIVE"),
|
(8, 'CLICK_NAIVE'),
|
||||||
],
|
],
|
||||||
default=game.models.EventTypes["START_GAME"],
|
default=game.models.EventTypes['START_GAME'],
|
||||||
help_text="The game event",
|
help_text='The game event',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,51 +1,54 @@
|
|||||||
# Generated by Django 3.1.3 on 2020-11-06 23:57
|
# Generated by Django 3.1.3 on 2020-11-06 23:57
|
||||||
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
||||||
import game.models
|
import game.models
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
("game", "0004_auto_20201106_0453"),
|
('game', '0004_auto_20201106_0453'),
|
||||||
]
|
]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.RemoveField(model_name="gameevent", name="metadata",),
|
migrations.RemoveField(
|
||||||
|
model_name='gameevent',
|
||||||
|
name='metadata',
|
||||||
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name="gameevent",
|
model_name='gameevent',
|
||||||
name="event_col",
|
name='event_col',
|
||||||
field=models.PositiveIntegerField(
|
field=models.PositiveIntegerField(
|
||||||
blank=True,
|
blank=True,
|
||||||
default=None,
|
default=None,
|
||||||
help_text="Column on the board where the event occurred, if applicable",
|
help_text='Column on the board where the event occurred, if applicable',
|
||||||
null=True,
|
null=True,
|
||||||
verbose_name="The column clicked",
|
verbose_name='The column clicked',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name="gameevent",
|
model_name='gameevent',
|
||||||
name="event_row",
|
name='event_row',
|
||||||
field=models.PositiveIntegerField(
|
field=models.PositiveIntegerField(
|
||||||
blank=True,
|
blank=True,
|
||||||
default=None,
|
default=None,
|
||||||
help_text="Row on the board where the event occurred, if applicable",
|
help_text='Row on the board where the event occurred, if applicable',
|
||||||
null=True,
|
null=True,
|
||||||
verbose_name="The row clicked",
|
verbose_name='The row clicked',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name="game",
|
model_name='game',
|
||||||
name="status",
|
name='status',
|
||||||
field=models.IntegerField(
|
field=models.IntegerField(
|
||||||
choices=[
|
choices=[
|
||||||
(0, "NOT_PLAYED"),
|
(0, 'NOT_PLAYED'),
|
||||||
(1, "PLAYING"),
|
(1, 'PLAYING'),
|
||||||
(2, "PAUSED"),
|
(2, 'PAUSED'),
|
||||||
(3, "FINISHED"),
|
(3, 'FINISHED'),
|
||||||
],
|
],
|
||||||
default=game.models.GameStatuses["NOT_PLAYED"],
|
default=game.models.GameStatuses['NOT_PLAYED'],
|
||||||
help_text="Actual game status",
|
help_text='Actual game status',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -4,16 +4,19 @@ from django.db import migrations
|
|||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
("game", "0005_auto_20201106_2357"),
|
('game', '0005_auto_20201106_2357'),
|
||||||
]
|
]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.RenameField(
|
migrations.RenameField(
|
||||||
model_name="gameevent", old_name="event_col", new_name="col",
|
model_name='gameevent',
|
||||||
|
old_name='event_col',
|
||||||
|
new_name='col',
|
||||||
),
|
),
|
||||||
migrations.RenameField(
|
migrations.RenameField(
|
||||||
model_name="gameevent", old_name="event_row", new_name="row",
|
model_name='gameevent',
|
||||||
|
old_name='event_row',
|
||||||
|
new_name='row',
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,33 +1,33 @@
|
|||||||
# Generated by Django 3.1.3 on 2020-11-07 01:30
|
# Generated by Django 3.1.3 on 2020-11-07 01:30
|
||||||
|
|
||||||
from django.db import migrations
|
|
||||||
import django_mysql.models
|
import django_mysql.models
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
import internal.utils
|
import internal.utils
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
("game", "0006_auto_20201107_0010"),
|
('game', '0006_auto_20201107_0010'),
|
||||||
]
|
]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name="game",
|
model_name='game',
|
||||||
name="board_progress",
|
name='board_progress',
|
||||||
field=django_mysql.models.JSONField(
|
field=django_mysql.models.JSONField(
|
||||||
default=internal.utils.empty_list,
|
default=internal.utils.empty_list,
|
||||||
help_text="This board is updated at each GameEvent recorded",
|
help_text='This board is updated at each GameEvent recorded',
|
||||||
verbose_name="Progress board",
|
verbose_name='Progress board',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name="game",
|
model_name='game',
|
||||||
name="board",
|
name='board',
|
||||||
field=django_mysql.models.JSONField(
|
field=django_mysql.models.JSONField(
|
||||||
default=internal.utils.empty_list,
|
default=internal.utils.empty_list,
|
||||||
help_text="The generated board game",
|
help_text='The generated board game',
|
||||||
verbose_name="Generated board",
|
verbose_name='Generated board',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,47 +1,43 @@
|
|||||||
# Generated by Django 4.1 on 2022-08-30 23:20
|
# Generated by Django 4.1 on 2022-08-30 23:20
|
||||||
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
||||||
import game.models
|
import game.models
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
("game", "0007_auto_20201107_0130"),
|
('game', '0007_auto_20201107_0130'),
|
||||||
]
|
]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name="game",
|
model_name='game',
|
||||||
name="id",
|
name='id',
|
||||||
field=models.BigAutoField(
|
field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
|
||||||
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name="gameevent",
|
model_name='gameevent',
|
||||||
name="id",
|
name='id',
|
||||||
field=models.BigAutoField(
|
field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
|
||||||
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name="gameevent",
|
model_name='gameevent',
|
||||||
name="type",
|
name='type',
|
||||||
field=models.IntegerField(
|
field=models.IntegerField(
|
||||||
choices=[
|
choices=[
|
||||||
(0, "START_GAME"),
|
(0, 'START_GAME'),
|
||||||
(1, "PAUSE"),
|
(1, 'PAUSE'),
|
||||||
(2, "RESUME"),
|
(2, 'RESUME'),
|
||||||
(3, "CLICK_MINE"),
|
(3, 'CLICK_MINE'),
|
||||||
(4, "CLICK_POINT"),
|
(4, 'CLICK_POINT'),
|
||||||
(5, "CLICK_EMPTY"),
|
(5, 'CLICK_EMPTY'),
|
||||||
(6, "CLICK_FLAG"),
|
(6, 'CLICK_FLAG'),
|
||||||
(7, "GAME_OVER"),
|
(7, 'GAME_OVER'),
|
||||||
(8, "CLICK_NAIVE"),
|
(8, 'CLICK_NAIVE'),
|
||||||
],
|
],
|
||||||
default=game.models.EventTypes["CLICK_NAIVE"],
|
default=game.models.EventTypes['CLICK_NAIVE'],
|
||||||
help_text="The game event",
|
help_text='The game event',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,13 +1,15 @@
|
|||||||
from enum import IntEnum
|
from enum import IntEnum
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django_mysql.models import JSONField
|
from django_mysql.models import JSONField
|
||||||
|
|
||||||
from internal.utils import empty_list
|
from internal.utils import empty_list
|
||||||
|
|
||||||
from .game import Minesweeper
|
from .game import Minesweeper
|
||||||
|
|
||||||
|
|
||||||
class EnumChoicesBase(IntEnum):
|
class EnumChoicesBase(IntEnum):
|
||||||
""" Enum was used as choices of Game.status because explicit is better than implicit """
|
"""Enum was used as choices of Game.status because explicit is better than implicit"""
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def choices(cls):
|
def choices(cls):
|
||||||
@@ -15,7 +17,7 @@ class EnumChoicesBase(IntEnum):
|
|||||||
|
|
||||||
|
|
||||||
class GameStatuses(EnumChoicesBase):
|
class GameStatuses(EnumChoicesBase):
|
||||||
""" Statuses used by the player and system on game """
|
"""Statuses used by the player and system on game"""
|
||||||
|
|
||||||
NOT_PLAYED = 0
|
NOT_PLAYED = 0
|
||||||
PLAYING = 1
|
PLAYING = 1
|
||||||
@@ -24,43 +26,35 @@ class GameStatuses(EnumChoicesBase):
|
|||||||
|
|
||||||
|
|
||||||
class Game(models.Model):
|
class Game(models.Model):
|
||||||
created_at = models.DateTimeField("Creation date", auto_now_add=True)
|
created_at = models.DateTimeField('Creation date', auto_now_add=True)
|
||||||
modified_at = models.DateTimeField("Last update", auto_now=True)
|
modified_at = models.DateTimeField('Last update', auto_now=True)
|
||||||
|
|
||||||
rows = models.PositiveIntegerField(
|
rows = models.PositiveIntegerField('Board rows', default=10, help_text="Board's total rows")
|
||||||
"Board rows", default=10, help_text="Board's total rows"
|
cols = models.PositiveIntegerField('Board cols', default=10, help_text="Board's total columns")
|
||||||
)
|
mines = models.PositiveIntegerField('Mines on board', default=5, help_text="Board's total placed mines")
|
||||||
cols = models.PositiveIntegerField(
|
|
||||||
"Board cols", default=10, help_text="Board's total columns"
|
|
||||||
)
|
|
||||||
mines = models.PositiveIntegerField(
|
|
||||||
"Mines on board", default=5, help_text="Board's total placed mines"
|
|
||||||
)
|
|
||||||
|
|
||||||
board = JSONField(
|
board = JSONField('Generated board', default=empty_list, help_text='The generated board game')
|
||||||
"Generated board", default=empty_list, help_text="The generated board game"
|
|
||||||
)
|
|
||||||
board_progress = JSONField(
|
board_progress = JSONField(
|
||||||
"Progress board",
|
'Progress board',
|
||||||
default=empty_list,
|
default=empty_list,
|
||||||
help_text="This board is updated at each GameEvent recorded",
|
help_text='This board is updated at each GameEvent recorded',
|
||||||
)
|
)
|
||||||
|
|
||||||
win = models.BooleanField(
|
win = models.BooleanField(
|
||||||
"Win?",
|
'Win?',
|
||||||
default=None,
|
default=None,
|
||||||
null=True,
|
null=True,
|
||||||
blank=True,
|
blank=True,
|
||||||
help_text="Did the user win the game?",
|
help_text='Did the user win the game?',
|
||||||
)
|
)
|
||||||
status = models.IntegerField(
|
status = models.IntegerField(
|
||||||
choices=GameStatuses.choices(),
|
choices=GameStatuses.choices(),
|
||||||
default=GameStatuses.NOT_PLAYED,
|
default=GameStatuses.NOT_PLAYED,
|
||||||
help_text="Actual game status",
|
help_text='Actual game status',
|
||||||
)
|
)
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
""" If the board was not defined, we create a new as default """
|
"""If the board was not defined, we create a new as default"""
|
||||||
|
|
||||||
if not self.board:
|
if not self.board:
|
||||||
ms = Minesweeper(self.rows, self.cols, self.mines)
|
ms = Minesweeper(self.rows, self.cols, self.mines)
|
||||||
@@ -72,13 +66,13 @@ class Game(models.Model):
|
|||||||
super(Game, self).save(*args, **kwargs)
|
super(Game, self).save(*args, **kwargs)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = "Game"
|
verbose_name = 'Game'
|
||||||
verbose_name_plural = "Games"
|
verbose_name_plural = 'Games'
|
||||||
db_table = "games"
|
db_table = 'games'
|
||||||
|
|
||||||
|
|
||||||
class EventTypes(EnumChoicesBase):
|
class EventTypes(EnumChoicesBase):
|
||||||
""" Event types to generate a game timeline """
|
"""Event types to generate a game timeline"""
|
||||||
|
|
||||||
START_GAME = 0
|
START_GAME = 0
|
||||||
PAUSE = 1
|
PAUSE = 1
|
||||||
@@ -92,32 +86,32 @@ class EventTypes(EnumChoicesBase):
|
|||||||
|
|
||||||
|
|
||||||
class GameEvent(models.Model):
|
class GameEvent(models.Model):
|
||||||
created_at = models.DateTimeField("Creation date", auto_now_add=True)
|
created_at = models.DateTimeField('Creation date', auto_now_add=True)
|
||||||
game = models.ForeignKey("game.Game", on_delete=models.CASCADE)
|
game = models.ForeignKey('game.Game', on_delete=models.CASCADE)
|
||||||
|
|
||||||
type = models.IntegerField(
|
type = models.IntegerField(
|
||||||
choices=EventTypes.choices(),
|
choices=EventTypes.choices(),
|
||||||
default=EventTypes.CLICK_NAIVE,
|
default=EventTypes.CLICK_NAIVE,
|
||||||
help_text="The game event",
|
help_text='The game event',
|
||||||
)
|
)
|
||||||
|
|
||||||
row = models.PositiveIntegerField(
|
row = models.PositiveIntegerField(
|
||||||
"The row clicked",
|
'The row clicked',
|
||||||
default=None,
|
default=None,
|
||||||
null=True,
|
null=True,
|
||||||
blank=True,
|
blank=True,
|
||||||
help_text="Row on the board where the event occurred, if applicable",
|
help_text='Row on the board where the event occurred, if applicable',
|
||||||
)
|
)
|
||||||
col = models.PositiveIntegerField(
|
col = models.PositiveIntegerField(
|
||||||
"The column clicked",
|
'The column clicked',
|
||||||
default=None,
|
default=None,
|
||||||
null=True,
|
null=True,
|
||||||
blank=True,
|
blank=True,
|
||||||
help_text="Column on the board where the event occurred, if applicable",
|
help_text='Column on the board where the event occurred, if applicable',
|
||||||
)
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
ordering = ["created_at"]
|
ordering = ['created_at']
|
||||||
verbose_name = "Game event"
|
verbose_name = 'Game event'
|
||||||
verbose_name_plural = "Game events"
|
verbose_name_plural = 'Game events'
|
||||||
db_table = "game_events"
|
db_table = 'game_events'
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
from django.db.models.signals import post_save, pre_save
|
from django.db.models.signals import post_save, pre_save
|
||||||
from django.dispatch import receiver
|
from django.dispatch import receiver
|
||||||
|
|
||||||
from .models import Game, GameEvent, EventTypes, GameStatuses
|
|
||||||
from .game import Minesweeper
|
from .game import Minesweeper
|
||||||
|
from .models import EventTypes, Game, GameEvent, GameStatuses
|
||||||
|
|
||||||
|
|
||||||
@receiver(post_save, sender=Game)
|
@receiver(post_save, sender=Game)
|
||||||
def game_start(sender, signal, instance, **kwargs):
|
def game_start(sender, signal, instance, **kwargs):
|
||||||
""" If the game was just created, insert the first event START_GAME """
|
"""If the game was just created, insert the first event START_GAME"""
|
||||||
if not instance.status == GameStatuses.NOT_PLAYED:
|
if not instance.status == GameStatuses.NOT_PLAYED:
|
||||||
return
|
return
|
||||||
GameEvent.objects.get_or_create(game=instance, type=EventTypes.START_GAME)
|
GameEvent.objects.get_or_create(game=instance, type=EventTypes.START_GAME)
|
||||||
@@ -15,7 +15,7 @@ def game_start(sender, signal, instance, **kwargs):
|
|||||||
|
|
||||||
@receiver(pre_save, sender=GameEvent)
|
@receiver(pre_save, sender=GameEvent)
|
||||||
def identify_click_event(sender, signal, instance, **kwargs):
|
def identify_click_event(sender, signal, instance, **kwargs):
|
||||||
""" Verify what is on the naive click: mine, point or empty """
|
"""Verify what is on the naive click: mine, point or empty"""
|
||||||
if not instance.type == EventTypes.CLICK_NAIVE:
|
if not instance.type == EventTypes.CLICK_NAIVE:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
from .utils import empty_list, empty_object
|
from .utils import empty_list, empty_object
|
||||||
|
|
||||||
__all__ = ["empty_list", "empty_object"]
|
__all__ = ['empty_list', 'empty_object']
|
||||||
|
|||||||
@@ -1,22 +1,23 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
"""Django's command-line utility for administrative tasks."""
|
"""Django's command-line utility for administrative tasks."""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
"""Run administrative tasks."""
|
"""Run administrative tasks."""
|
||||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "app.settings")
|
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'app.settings')
|
||||||
try:
|
try:
|
||||||
from django.core.management import execute_from_command_line
|
from django.core.management import execute_from_command_line
|
||||||
except ImportError as exc:
|
except ImportError as exc:
|
||||||
raise ImportError(
|
raise ImportError(
|
||||||
"Couldn't import Django. Are you sure it's installed and "
|
"Couldn't import Django. Are you sure it's installed and "
|
||||||
"available on your PYTHONPATH environment variable? Did you "
|
'available on your PYTHONPATH environment variable? Did you '
|
||||||
"forget to activate a virtual environment?"
|
'forget to activate a virtual environment?'
|
||||||
) from exc
|
) from exc
|
||||||
execute_from_command_line(sys.argv)
|
execute_from_command_line(sys.argv)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
|||||||
Reference in New Issue
Block a user