Lint fix v1

This commit is contained in:
2025-02-04 15:49:25 -03:00
parent ff010739c4
commit e6c3896918
35 changed files with 392 additions and 432 deletions

View File

@@ -2,4 +2,4 @@ from django.apps import AppConfig
class ApiConfig(AppConfig):
name = "api"
name = 'api'

View File

@@ -3,12 +3,13 @@ from rest_framework.response import Response
from rest_framework.views import APIView
from game.models import Game, GameEvent, GameStatuses
from ..serializers import GameSerializer, GameEventSerializer
from ..serializers import GameEventSerializer, GameSerializer
class GameResource(APIView):
def post(self, request):
""" Creates a new game """
"""Creates a new game"""
serializer = GameSerializer(data=request.data)
if serializer.is_valid():
@@ -19,7 +20,7 @@ class GameResource(APIView):
class GameSingleResource(APIView):
def get(self, request, game_id):
""" Returns a game serialized or not found """
"""Returns a game serialized or not found"""
try:
game = Game.objects.get(pk=game_id)
@@ -32,7 +33,7 @@ class GameSingleResource(APIView):
class GameEventResource(APIView):
def get(self, request, game_id):
""" Returns a list of all game events """
"""Returns a list of all game events"""
try:
game = Game.objects.get(pk=game_id)
@@ -44,7 +45,7 @@ class GameEventResource(APIView):
return Response(serializer.data)
def post(self, request, game_id):
""" Creates a new event """
"""Creates a new event"""
try:
game = Game.objects.get(pk=game_id)
@@ -53,20 +54,20 @@ class GameEventResource(APIView):
if game.status == GameStatuses.FINISHED:
return Response(
{"message": "Game is already finished"},
{'message': 'Game is already finished'},
status=status.HTTP_412_PRECONDITION_FAILED,
)
row = request.data.get("row")
col = request.data.get("col")
row = request.data.get('row')
col = request.data.get('col')
game_event = GameEvent.objects.filter(game=game, row=row, col=col).first()
if game_event:
return Response(
{"message": "This event was already registered"},
{'message': 'This event was already registered'},
status=status.HTTP_409_CONFLICT,
)
data = dict(request.data)
data["game"] = game.pk
data['game'] = game.pk
serializer = GameEventSerializer(data=data)
if serializer.is_valid():

View File

@@ -5,4 +5,4 @@ from rest_framework.views import APIView
class MainResource(APIView):
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)

View File

@@ -1,4 +1,3 @@
from .game import GameSerializer, GameEventSerializer
from .game import GameEventSerializer, GameSerializer
__all__ = ["GameSerializer", "GameEventSerializer"]
__all__ = ['GameEventSerializer', 'GameSerializer']

View File

@@ -6,22 +6,22 @@ from game.models import Game, GameEvent, GameStatuses
class GameSerializer(serializers.ModelSerializer):
def to_representation(self, instance):
response = super().to_representation(instance)
if not response["status"] == GameStatuses.FINISHED:
del response["board"]
if not response['status'] == GameStatuses.FINISHED:
del response['board']
return response
class Meta:
model = Game
fields = "__all__"
fields = '__all__'
class GameEventSerializer(serializers.ModelSerializer):
def to_representation(self, instance):
response = super().to_representation(instance)
response["active_game"] = GameSerializer(instance.game).data
response['active_game'] = GameSerializer(instance.game).data
return response
class Meta:
model = GameEvent
fields = "__all__"
fields = '__all__'

View File

@@ -1,14 +1,13 @@
from django.urls import path
from .resources.game import GameEventResource, GameResource, GameSingleResource
from .resources.main import MainResource
from .resources.game import GameResource, GameSingleResource, GameEventResource
app_name = "api"
app_name = 'api'
urlpatterns = [
path("games/<game_id>/events", GameEventResource.as_view(), name="games_events"),
path("games/<game_id>", GameSingleResource.as_view(), name="games_single"),
path("games", GameResource.as_view(), name="games"),
path("", MainResource.as_view(), name="main"),
path('games/<game_id>/events', GameEventResource.as_view(), name='games_events'),
path('games/<game_id>', GameSingleResource.as_view(), name='games_single'),
path('games', GameResource.as_view(), name='games'),
path('', MainResource.as_view(), name='main'),
]

View File

@@ -11,6 +11,6 @@ import os
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()

View File

@@ -1,8 +1,8 @@
import os
from pathlib import Path
import sentry_sdk
from sentry_sdk.integrations.django import DjangoIntegration
from .utils import 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']
# 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
INSTALLED_APPS = [
"rest_framework",
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"corsheaders",
"core",
"api",
"game",
'rest_framework',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'corsheaders',
'core',
'api',
'game',
]
MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"corsheaders.middleware.CorsMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = "app.urls"
ROOT_URLCONF = 'app.urls'
TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [],
"APP_DIRS": True,
"OPTIONS": {
"context_processors": [
"django.template.context_processors.debug",
"django.template.context_processors.request",
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'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
# https://docs.djangoproject.com/en/3.1/ref/settings/#databases
DATABASES = {
"default": {
"ENGINE": "django.db.backends.mysql",
"NAME": op_config['database.name'],
"USER": op_config['database.user'],
"PASSWORD": op_config['database.password'],
"HOST": op_config['database.host'],
"PORT": op_config['database.port'],
"OPTIONS": {"charset": "utf8mb4"},
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': op_config['database.name'],
'USER': op_config['database.user'],
'PASSWORD': op_config['database.password'],
'HOST': op_config['database.host'],
'PORT': op_config['database.port'],
'OPTIONS': {'charset': 'utf8mb4'},
}
}
@@ -98,21 +98,19 @@ DATABASES = {
# https://docs.djangoproject.com/en/3.1/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
"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.NumericPasswordValidator"},
{'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.NumericPasswordValidator'},
]
# Internationalization
# 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
@@ -124,15 +122,13 @@ USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.1/howto/static-files/
STATIC_URL = "/static/"
STATIC_URL = '/static/'
# Some Django Rest Framework parameters
REST_FRAMEWORK = {
"DEFAULT_PERMISSION_CLASSES": ["rest_framework.permissions.AllowAny"],
"DEFAULT_AUTHENTICATION_CLASSES": [
"rest_framework.authentication.TokenAuthentication"
],
"DEFAULT_RENDERER_CLASSES": ("rest_framework.renderers.JSONRenderer",),
'DEFAULT_PERMISSION_CLASSES': ['rest_framework.permissions.AllowAny'],
'DEFAULT_AUTHENTICATION_CLASSES': ['rest_framework.authentication.TokenAuthentication'],
'DEFAULT_RENDERER_CLASSES': ('rest_framework.renderers.JSONRenderer',),
}
if DEBUG is True:

View File

@@ -1,14 +1,13 @@
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path("", include("api.urls")),
path('', include('api.urls')),
]
# We need this only for development purpose
if settings.DEBUG is True:
urlpatterns += [
path("admin/", admin.site.urls),
path('admin/', admin.site.urls),
]

View File

@@ -1,5 +1,3 @@
import os
import onepasswordconnectsdk
from onepasswordconnectsdk.client import Client, new_client_from_environment
@@ -22,6 +20,6 @@ def get_op_config():
op_config_get = {}
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)

View File

@@ -11,6 +11,6 @@ import os
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()

View File

@@ -5,12 +5,12 @@ from .models import User
@admin.register(User)
class UserAdmin(admin.ModelAdmin):
search_fields = ("id", "email", "first_name", "last_name")
search_fields = ('id', 'email', 'first_name', 'last_name')
list_display = (
"id",
"first_name",
"last_name",
"is_active",
"email",
"date_joined",
'id',
'first_name',
'last_name',
'is_active',
'email',
'date_joined',
)

View File

@@ -2,4 +2,4 @@ from django.apps import AppConfig
class CoreConfig(AppConfig):
name = "core"
name = 'core'

View File

@@ -9,7 +9,7 @@ class UserManager(BaseUserManager):
Creates and saves a User with the given email and password.
"""
if not email:
raise ValueError("The given email must be set")
raise ValueError('The given email must be set')
email = self.normalize_email(email)
user = self.model(email=email, **extra_fields)
user.set_password(password)
@@ -17,13 +17,13 @@ class UserManager(BaseUserManager):
return user
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)
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:
raise ValueError("Superuser must have is_superuser=True.")
if extra_fields.get('is_superuser') is not True:
raise ValueError('Superuser must have is_superuser=True.')
return self._create_user(email, password, **extra_fields)

View File

@@ -1,98 +1,89 @@
# Generated by Django 3.1.3 on 2020-11-05 00:51
import core.managers
from django.db import migrations, models
import core.managers
class Migration(migrations.Migration):
initial = True
dependencies = [
("auth", "0012_alter_user_first_name_max_length"),
('auth', '0012_alter_user_first_name_max_length'),
]
operations = [
migrations.CreateModel(
name="User",
name='User',
fields=[
(
"id",
'id',
models.AutoField(
auto_created=True,
primary_key=True,
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",
models.DateTimeField(
blank=True, null=True, verbose_name="last login"
),
'last_login',
models.DateTimeField(blank=True, null=True, verbose_name='last login'),
),
(
"email",
models.EmailField(
max_length=254, unique=True, verbose_name="E-mail"
),
'email',
models.EmailField(max_length=254, unique=True, verbose_name='E-mail'),
),
(
"first_name",
models.CharField(
blank=True, max_length=30, verbose_name="First name"
),
'first_name',
models.CharField(blank=True, max_length=30, verbose_name='First name'),
),
(
"last_name",
models.CharField(
blank=True, max_length=30, verbose_name="Last name"
),
'last_name',
models.CharField(blank=True, max_length=30, verbose_name='Last name'),
),
(
"date_joined",
models.DateTimeField(auto_now_add=True, verbose_name="date joined"),
'date_joined',
models.DateTimeField(auto_now_add=True, verbose_name='date joined'),
),
(
"is_active",
models.BooleanField(default=True, verbose_name="User active?"),
'is_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",
models.BooleanField(default=False, verbose_name="Superuser?"),
'is_superuser',
models.BooleanField(default=False, verbose_name='Superuser?'),
),
(
"groups",
'groups',
models.ManyToManyField(
blank=True,
help_text="The groups this user belongs to. A"
"user will get all permissions granted to each of their groups.",
related_name="user_set",
related_query_name="user",
to="auth.Group",
verbose_name="groups",
help_text='The groups this user belongs to. Auser will get all permissions granted to each of their groups.',
related_name='user_set',
related_query_name='user',
to='auth.Group',
verbose_name='groups',
),
),
(
"user_permissions",
'user_permissions',
models.ManyToManyField(
blank=True,
help_text="Specific permissions for this user.",
related_name="user_set",
related_query_name="user",
to="auth.Permission",
verbose_name="user permissions",
help_text='Specific permissions for this user.',
related_name='user_set',
related_query_name='user',
to='auth.Permission',
verbose_name='user permissions',
),
),
],
options={
"verbose_name": "User",
"verbose_name_plural": "Users",
"db_table": "users",
"ordering": ["first_name", "last_name"],
'verbose_name': 'User',
'verbose_name_plural': 'Users',
'db_table': 'users',
'ordering': ['first_name', 'last_name'],
},
managers=[("objects", core.managers.UserManager())],
managers=[('objects', core.managers.UserManager())],
),
]

View File

@@ -4,24 +4,22 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("auth", "0012_alter_user_first_name_max_length"),
("core", "0001_initial"),
('auth', '0012_alter_user_first_name_max_length'),
('core', '0001_initial'),
]
operations = [
migrations.AlterField(
model_name="user",
name="groups",
model_name='user',
name='groups',
field=models.ManyToManyField(
blank=True,
help_text="The groups this user belongs to. "
"A user will get all permissions granted to each of their groups.",
related_name="user_set",
related_query_name="user",
to="auth.Group",
verbose_name="groups",
help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.',
related_name='user_set',
related_query_name='user',
to='auth.Group',
verbose_name='groups',
),
),
]

View File

@@ -4,15 +4,14 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("core", "0002_auto_20201105_0303"),
('core', '0002_auto_20201105_0303'),
]
operations = [
migrations.AlterField(
model_name="user",
name="is_staff",
field=models.BooleanField(default=True, verbose_name="Staff?"),
model_name='user',
name='is_staff',
field=models.BooleanField(default=True, verbose_name='Staff?'),
),
]

View File

@@ -4,17 +4,14 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("core", "0003_auto_20201106_0152"),
('core', '0003_auto_20201106_0152'),
]
operations = [
migrations.AlterField(
model_name="user",
name="id",
field=models.BigAutoField(
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
),
model_name='user',
name='id',
field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
),
]

View File

@@ -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.models import PermissionsMixin
from django.db import models
from .managers import UserManager
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)
last_name = models.CharField("Last 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)
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_staff = models.BooleanField("Staff?", default=True)
is_superuser = models.BooleanField("Superuser?", default=False)
is_active = models.BooleanField('User active?', default=True)
is_staff = models.BooleanField('Staff?', default=True)
is_superuser = models.BooleanField('Superuser?', default=False)
objects = UserManager()
USERNAME_FIELD = "email"
USERNAME_FIELD = 'email'
class Meta:
ordering = ["first_name", "last_name"]
verbose_name = "User"
verbose_name_plural = "Users"
db_table = "users"
ordering = ['first_name', 'last_name']
verbose_name = 'User'
verbose_name_plural = 'Users'
db_table = 'users'
def get_full_name(self):
"""
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()
def get_short_name(self):
"""
Returns the short name for the user.
"""
return self.first_name or "Unamed"
return self.first_name or 'Unamed'

View File

@@ -1 +1 @@
default_app_config = "game.apps.GameConfig"
default_app_config = 'game.apps.GameConfig'

View File

@@ -6,24 +6,24 @@ from .models import Game, GameEvent
@admin.register(Game)
class GameAdmin(admin.ModelAdmin):
list_display = (
"id",
"created_at",
"modified_at",
"rows",
"cols",
"mines",
"win",
"status",
'id',
'created_at',
'modified_at',
'rows',
'cols',
'mines',
'win',
'status',
)
list_filter = (
"win",
"status",
'win',
'status',
)
@admin.register(GameEvent)
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',)

View File

@@ -2,9 +2,9 @@ from django.apps import AppConfig
class GameConfig(AppConfig):
name = "game"
verbose_name = "Game"
verbose_name_plural = "Games"
name = 'game'
verbose_name = 'Game'
verbose_name_plural = 'Games'
def ready(self):
import game.signals # noqa

View File

@@ -16,11 +16,9 @@ class Minesweeper:
self.board_progress = board_progress
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_progress = [
["-" for col in range(self.cols)] for row in range(self.rows)
]
self.board_progress = [['-' for col in range(self.cols)] for row in range(self.rows)]
def put_mine(self):
"""Put a single mine on the board.
@@ -36,7 +34,7 @@ class Minesweeper:
return row, col
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):
row, col = self.put_mine()
@@ -71,31 +69,31 @@ class Minesweeper:
self.increment_safe_point(row - 1, col - 1)
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):
return False
return self.board[row][col] == -1
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):
return False
return self.board[row][col] == 0
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):
return False
return self.board[row][col] > 0
def is_point_in_board(self, row, col):
""" Checks whether the location is inside board """
if row in range(0, self.rows) and col in range(0, self.cols):
"""Checks whether the location is inside board"""
if row in range(self.rows) and col in range(self.cols):
return True
return False
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
if not self.is_point_in_board(row, col):
@@ -129,7 +127,7 @@ class Minesweeper:
while r < max_row:
c = min_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]
if self.board[r][c] == 0:
@@ -138,7 +136,7 @@ class Minesweeper:
r += 1
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]
# We will show adjacents only if the cell clicked is zero
@@ -146,14 +144,14 @@ class Minesweeper:
self.reveal_adjacents(row, col)
def win(self):
""" Identify if the player won the game """
"""Identify if the player won the game"""
unrevealed = 0
for row in self.board_progress:
for cell in row:
if cell == -1:
return False
if cell == "-":
if cell == '-':
unrevealed += 1
if (unrevealed - self.mines) == 0:
return True

View File

@@ -1,65 +1,61 @@
# Generated by Django 3.1.3 on 2020-11-05 03:03
from django.db import migrations, models
import django_mysql.models
from django.db import migrations, models
import internal.utils
class Migration(migrations.Migration):
initial = True
dependencies = []
operations = [
migrations.CreateModel(
name="Game",
name='Game',
fields=[
(
"id",
'id',
models.AutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
verbose_name='ID',
),
),
(
"created_at",
models.DateTimeField(
auto_now_add=True, verbose_name="Creation date"
),
'created_at',
models.DateTimeField(auto_now_add=True, verbose_name='Creation date'),
),
(
"modified_at",
models.DateTimeField(auto_now=True, verbose_name="Last update"),
'modified_at',
models.DateTimeField(auto_now=True, verbose_name='Last update'),
),
(
"rows",
models.PositiveIntegerField(default=10, verbose_name="Board rows"),
'rows',
models.PositiveIntegerField(default=10, verbose_name='Board rows'),
),
(
"cols",
models.PositiveIntegerField(default=10, verbose_name="Board cols"),
'cols',
models.PositiveIntegerField(default=10, verbose_name='Board cols'),
),
(
"mines",
models.PositiveIntegerField(
default=5, verbose_name="Mines on board"
),
'mines',
models.PositiveIntegerField(default=5, verbose_name='Mines on board'),
),
(
"board",
'board',
django_mysql.models.JSONField(
default=internal.utils.empty_list,
verbose_name="Generated board",
verbose_name='Generated board',
),
),
],
options={
"verbose_name": "Game",
"verbose_name_plural": "Games",
"db_table": "games",
'verbose_name': 'Game',
'verbose_name_plural': 'Games',
'db_table': 'games',
},
),
]

View File

@@ -1,68 +1,64 @@
# Generated by Django 3.1.3 on 2020-11-06 02:25
from django.db import migrations, models
import django_mysql.models
from django.db import migrations, models
import game.models
import internal.utils
class Migration(migrations.Migration):
dependencies = [
("game", "0001_initial"),
('game', '0001_initial'),
]
operations = [
migrations.AddField(
model_name="game",
name="status",
model_name='game',
name='status',
field=models.IntegerField(
choices=[(0, "NOT_PLAYED"), (1, "PLAYING"), (2, "FINISHED")],
default=game.models.GameStatuses["NOT_PLAYED"],
help_text="Actual game status",
choices=[(0, 'NOT_PLAYED'), (1, 'PLAYING'), (2, 'FINISHED')],
default=game.models.GameStatuses['NOT_PLAYED'],
help_text='Actual game status',
),
),
migrations.AddField(
model_name="game",
name="win",
model_name='game',
name='win',
field=models.BooleanField(
blank=True,
default=None,
help_text="Did the user win the game?",
help_text='Did the user win the game?',
null=True,
verbose_name="Win?",
verbose_name='Win?',
),
),
migrations.AlterField(
model_name="game",
name="board",
model_name='game',
name='board',
field=django_mysql.models.JSONField(
default=internal.utils.empty_list,
help_text="Whe generated board game",
verbose_name="Generated board",
help_text='Whe generated board game',
verbose_name='Generated board',
),
),
migrations.AlterField(
model_name="game",
name="cols",
field=models.PositiveIntegerField(
default=10, help_text="Board's total columns", verbose_name="Board cols"
),
model_name='game',
name='cols',
field=models.PositiveIntegerField(default=10, help_text="Board's total columns", verbose_name='Board cols'),
),
migrations.AlterField(
model_name="game",
name="mines",
model_name='game',
name='mines',
field=models.PositiveIntegerField(
default=5,
help_text="Board's total placed mines",
verbose_name="Mines on board",
verbose_name='Mines on board',
),
),
migrations.AlterField(
model_name="game",
name="rows",
field=models.PositiveIntegerField(
default=10, help_text="Board's total rows", verbose_name="Board rows"
),
model_name='game',
name='rows',
field=models.PositiveIntegerField(default=10, help_text="Board's total rows", verbose_name='Board rows'),
),
]

View File

@@ -1,73 +1,69 @@
# 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_mysql.models
from django.db import migrations, models
import game.models
import internal.utils
class Migration(migrations.Migration):
dependencies = [
("game", "0002_auto_20201106_0225"),
('game', '0002_auto_20201106_0225'),
]
operations = [
migrations.CreateModel(
name="GameEvent",
name='GameEvent',
fields=[
(
"id",
'id',
models.AutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
verbose_name='ID',
),
),
(
"created_at",
models.DateTimeField(
auto_now_add=True, verbose_name="Creation date"
),
'created_at',
models.DateTimeField(auto_now_add=True, verbose_name='Creation date'),
),
(
"type",
'type',
models.IntegerField(
choices=[
(0, "START_GAME"),
(1, "PAUSE"),
(2, "RESUME"),
(3, "CLICK_MINE"),
(4, "CLICK_POINT"),
(5, "CLICK_EMPTY"),
(6, "CLICK_FLAG"),
(7, "GAME_OVER"),
(0, 'START_GAME'),
(1, 'PAUSE'),
(2, 'RESUME'),
(3, 'CLICK_MINE'),
(4, 'CLICK_POINT'),
(5, 'CLICK_EMPTY'),
(6, 'CLICK_FLAG'),
(7, 'GAME_OVER'),
],
default=game.models.EventTypes["START_GAME"],
help_text="The game event",
default=game.models.EventTypes['START_GAME'],
help_text='The game event',
),
),
(
"metadata",
'metadata',
django_mysql.models.JSONField(
default=internal.utils.empty_object,
help_text="Some usefull event metadata",
verbose_name="Event metadata",
help_text='Some usefull event metadata',
verbose_name='Event metadata',
),
),
(
"game",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE, to="game.game"
),
'game',
models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='game.game'),
),
],
options={
"verbose_name": "Game event",
"verbose_name_plural": "Game events",
"db_table": "game_events",
'verbose_name': 'Game event',
'verbose_name_plural': 'Game events',
'db_table': 'game_events',
},
),
]

View File

@@ -1,41 +1,41 @@
# Generated by Django 3.1.3 on 2020-11-06 04:53
from django.db import migrations, models
import game.models
class Migration(migrations.Migration):
dependencies = [
("game", "0003_gameevent"),
('game', '0003_gameevent'),
]
operations = [
migrations.AlterModelOptions(
name="gameevent",
name='gameevent',
options={
"ordering": ["created_at"],
"verbose_name": "Game event",
"verbose_name_plural": "Game events",
'ordering': ['created_at'],
'verbose_name': 'Game event',
'verbose_name_plural': 'Game events',
},
),
migrations.AlterField(
model_name="gameevent",
name="type",
model_name='gameevent',
name='type',
field=models.IntegerField(
choices=[
(0, "START_GAME"),
(1, "PAUSE"),
(2, "RESUME"),
(3, "CLICK_MINE"),
(4, "CLICK_POINT"),
(5, "CLICK_EMPTY"),
(6, "CLICK_FLAG"),
(7, "GAME_OVER"),
(8, "CLICK_NAIVE"),
(0, 'START_GAME'),
(1, 'PAUSE'),
(2, 'RESUME'),
(3, 'CLICK_MINE'),
(4, 'CLICK_POINT'),
(5, 'CLICK_EMPTY'),
(6, 'CLICK_FLAG'),
(7, 'GAME_OVER'),
(8, 'CLICK_NAIVE'),
],
default=game.models.EventTypes["START_GAME"],
help_text="The game event",
default=game.models.EventTypes['START_GAME'],
help_text='The game event',
),
),
]

View File

@@ -1,51 +1,54 @@
# Generated by Django 3.1.3 on 2020-11-06 23:57
from django.db import migrations, models
import game.models
class Migration(migrations.Migration):
dependencies = [
("game", "0004_auto_20201106_0453"),
('game', '0004_auto_20201106_0453'),
]
operations = [
migrations.RemoveField(model_name="gameevent", name="metadata",),
migrations.RemoveField(
model_name='gameevent',
name='metadata',
),
migrations.AddField(
model_name="gameevent",
name="event_col",
model_name='gameevent',
name='event_col',
field=models.PositiveIntegerField(
blank=True,
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,
verbose_name="The column clicked",
verbose_name='The column clicked',
),
),
migrations.AddField(
model_name="gameevent",
name="event_row",
model_name='gameevent',
name='event_row',
field=models.PositiveIntegerField(
blank=True,
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,
verbose_name="The row clicked",
verbose_name='The row clicked',
),
),
migrations.AlterField(
model_name="game",
name="status",
model_name='game',
name='status',
field=models.IntegerField(
choices=[
(0, "NOT_PLAYED"),
(1, "PLAYING"),
(2, "PAUSED"),
(3, "FINISHED"),
(0, 'NOT_PLAYED'),
(1, 'PLAYING'),
(2, 'PAUSED'),
(3, 'FINISHED'),
],
default=game.models.GameStatuses["NOT_PLAYED"],
help_text="Actual game status",
default=game.models.GameStatuses['NOT_PLAYED'],
help_text='Actual game status',
),
),
]

View File

@@ -4,16 +4,19 @@ from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
("game", "0005_auto_20201106_2357"),
('game', '0005_auto_20201106_2357'),
]
operations = [
migrations.RenameField(
model_name="gameevent", old_name="event_col", new_name="col",
model_name='gameevent',
old_name='event_col',
new_name='col',
),
migrations.RenameField(
model_name="gameevent", old_name="event_row", new_name="row",
model_name='gameevent',
old_name='event_row',
new_name='row',
),
]

View File

@@ -1,33 +1,33 @@
# Generated by Django 3.1.3 on 2020-11-07 01:30
from django.db import migrations
import django_mysql.models
from django.db import migrations
import internal.utils
class Migration(migrations.Migration):
dependencies = [
("game", "0006_auto_20201107_0010"),
('game', '0006_auto_20201107_0010'),
]
operations = [
migrations.AddField(
model_name="game",
name="board_progress",
model_name='game',
name='board_progress',
field=django_mysql.models.JSONField(
default=internal.utils.empty_list,
help_text="This board is updated at each GameEvent recorded",
verbose_name="Progress board",
help_text='This board is updated at each GameEvent recorded',
verbose_name='Progress board',
),
),
migrations.AlterField(
model_name="game",
name="board",
model_name='game',
name='board',
field=django_mysql.models.JSONField(
default=internal.utils.empty_list,
help_text="The generated board game",
verbose_name="Generated board",
help_text='The generated board game',
verbose_name='Generated board',
),
),
]

View File

@@ -1,47 +1,43 @@
# Generated by Django 4.1 on 2022-08-30 23:20
from django.db import migrations, models
import game.models
class Migration(migrations.Migration):
dependencies = [
("game", "0007_auto_20201107_0130"),
('game', '0007_auto_20201107_0130'),
]
operations = [
migrations.AlterField(
model_name="game",
name="id",
field=models.BigAutoField(
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
),
model_name='game',
name='id',
field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
),
migrations.AlterField(
model_name="gameevent",
name="id",
field=models.BigAutoField(
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
),
model_name='gameevent',
name='id',
field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
),
migrations.AlterField(
model_name="gameevent",
name="type",
model_name='gameevent',
name='type',
field=models.IntegerField(
choices=[
(0, "START_GAME"),
(1, "PAUSE"),
(2, "RESUME"),
(3, "CLICK_MINE"),
(4, "CLICK_POINT"),
(5, "CLICK_EMPTY"),
(6, "CLICK_FLAG"),
(7, "GAME_OVER"),
(8, "CLICK_NAIVE"),
(0, 'START_GAME'),
(1, 'PAUSE'),
(2, 'RESUME'),
(3, 'CLICK_MINE'),
(4, 'CLICK_POINT'),
(5, 'CLICK_EMPTY'),
(6, 'CLICK_FLAG'),
(7, 'GAME_OVER'),
(8, 'CLICK_NAIVE'),
],
default=game.models.EventTypes["CLICK_NAIVE"],
help_text="The game event",
default=game.models.EventTypes['CLICK_NAIVE'],
help_text='The game event',
),
),
]

View File

@@ -1,13 +1,15 @@
from enum import IntEnum
from django.db import models
from django_mysql.models import JSONField
from internal.utils import empty_list
from .game import Minesweeper
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
def choices(cls):
@@ -15,7 +17,7 @@ class EnumChoicesBase(IntEnum):
class GameStatuses(EnumChoicesBase):
""" Statuses used by the player and system on game """
"""Statuses used by the player and system on game"""
NOT_PLAYED = 0
PLAYING = 1
@@ -24,43 +26,35 @@ class GameStatuses(EnumChoicesBase):
class Game(models.Model):
created_at = models.DateTimeField("Creation date", auto_now_add=True)
modified_at = models.DateTimeField("Last update", auto_now=True)
created_at = models.DateTimeField('Creation date', auto_now_add=True)
modified_at = models.DateTimeField('Last update', auto_now=True)
rows = models.PositiveIntegerField(
"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"
)
rows = models.PositiveIntegerField('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")
board = JSONField(
"Generated board", default=empty_list, help_text="The generated board game"
)
board = JSONField('Generated board', default=empty_list, help_text='The generated board game')
board_progress = JSONField(
"Progress board",
'Progress board',
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?",
'Win?',
default=None,
null=True,
blank=True,
help_text="Did the user win the game?",
help_text='Did the user win the game?',
)
status = models.IntegerField(
choices=GameStatuses.choices(),
default=GameStatuses.NOT_PLAYED,
help_text="Actual game status",
help_text='Actual game status',
)
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:
ms = Minesweeper(self.rows, self.cols, self.mines)
@@ -72,13 +66,13 @@ class Game(models.Model):
super(Game, self).save(*args, **kwargs)
class Meta:
verbose_name = "Game"
verbose_name_plural = "Games"
db_table = "games"
verbose_name = 'Game'
verbose_name_plural = 'Games'
db_table = 'games'
class EventTypes(EnumChoicesBase):
""" Event types to generate a game timeline """
"""Event types to generate a game timeline"""
START_GAME = 0
PAUSE = 1
@@ -92,32 +86,32 @@ class EventTypes(EnumChoicesBase):
class GameEvent(models.Model):
created_at = models.DateTimeField("Creation date", auto_now_add=True)
game = models.ForeignKey("game.Game", on_delete=models.CASCADE)
created_at = models.DateTimeField('Creation date', auto_now_add=True)
game = models.ForeignKey('game.Game', on_delete=models.CASCADE)
type = models.IntegerField(
choices=EventTypes.choices(),
default=EventTypes.CLICK_NAIVE,
help_text="The game event",
help_text='The game event',
)
row = models.PositiveIntegerField(
"The row clicked",
'The row clicked',
default=None,
null=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(
"The column clicked",
'The column clicked',
default=None,
null=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:
ordering = ["created_at"]
verbose_name = "Game event"
verbose_name_plural = "Game events"
db_table = "game_events"
ordering = ['created_at']
verbose_name = 'Game event'
verbose_name_plural = 'Game events'
db_table = 'game_events'

View File

@@ -1,13 +1,13 @@
from django.db.models.signals import post_save, pre_save
from django.dispatch import receiver
from .models import Game, GameEvent, EventTypes, GameStatuses
from .game import Minesweeper
from .models import EventTypes, Game, GameEvent, GameStatuses
@receiver(post_save, sender=Game)
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:
return
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)
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:
return

View File

@@ -1,3 +1,3 @@
from .utils import empty_list, empty_object
__all__ = ["empty_list", "empty_object"]
__all__ = ['empty_list', 'empty_object']

View File

@@ -1,22 +1,23 @@
#!/usr/bin/env python
"""Django's command-line utility for administrative tasks."""
import os
import sys
def main():
"""Run administrative tasks."""
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "app.settings")
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'app.settings')
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
'available on your PYTHONPATH environment variable? Did you '
'forget to activate a virtual environment?'
) from exc
execute_from_command_line(sys.argv)
if __name__ == "__main__":
if __name__ == '__main__':
main()