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): class ApiConfig(AppConfig):
name = "api" name = 'api'

View File

@@ -3,7 +3,8 @@ 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):
@@ -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():

View File

@@ -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)

View File

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

View File

@@ -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__'

View File

@@ -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'),
] ]

View File

@@ -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()

View File

@@ -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:

View File

@@ -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),
] ]

View File

@@ -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)

View File

@@ -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()

View File

@@ -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',
) )

View File

@@ -2,4 +2,4 @@ from django.apps import AppConfig
class CoreConfig(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. 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)

View File

@@ -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())],
), ),
] ]

View File

@@ -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",
), ),
), ),
] ]

View File

@@ -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?'),
), ),
] ]

View File

@@ -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"
),
), ),
] ]

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.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'

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) @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',)

View File

@@ -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

View File

@@ -18,9 +18,7 @@ class Minesweeper:
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.
@@ -90,7 +88,7 @@ class Minesweeper:
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
@@ -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:
@@ -153,7 +151,7 @@ class Minesweeper:
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

View File

@@ -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',
}, },
), ),
] ]

View File

@@ -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"
),
), ),
] ]

View File

@@ -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',
}, },
), ),
] ]

View File

@@ -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',
), ),
), ),
] ]

View File

@@ -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',
), ),
), ),
] ]

View File

@@ -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',
), ),
] ]

View File

@@ -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',
), ),
), ),
] ]

View File

@@ -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',
), ),
), ),
] ]

View File

@@ -1,8 +1,10 @@
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
@@ -24,39 +26,31 @@ 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):
@@ -72,9 +66,9 @@ 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):
@@ -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'

View File

@@ -1,8 +1,8 @@
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)

View File

@@ -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']

View File

@@ -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()