edoardoColi / PONG-1972

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Pong in Django container

Here are some general Pong 1972 references

Series of link to justify implementation choises

List:

Initial setup Django + PostgreSQL

Link di riferimento

Sicurity purpose

Dati i file docker-compose.yml, .env, django/requirements.txt, django/Dockerfile

# The command that will be executed inside the "web" service container. It's a  Django command (django-admin startproject) used to create a new Django project.
# The argument djangodockertest is the name of the project being created, and the . specifies the current directory as the location where the project files will be created.
$ docker-compose run web django-admin startproject djangodocker .

# Adapt django/djangodocker/settings.py and django/manage.py as needed for postgreSQL and network access
$ docker-compose run backend python manage.py makemigrations
$ docker-compose run backend python manage.py migrate

$ docker-compose up
$ docker-compose down

Per entrare nel container possiamo usare

docker exec -it <container_id_or_name> bash

e per entrare nel database del container psql -U username -d your_database_name se non trovasse il database cancellare la cartella relativa ai dati e ri-buildare, poi ri-usare makemigrations e migrate(avendo controllato che i valori in django/djangodocker/settings.py e .env sono presi e usati correttamente)

Per aggungere un superuser con cui fare il login in /admin usiamo

$ docker-compose run backend python manage.py createsuperuser
$ docker-compose run backend python manage.py changepassword <username>

File permission

Quanto si fa push meglio usare sudo chown -R <user>:<group> /path/to/directory perche' le cartelle condivise ai container possono prendere owner diversi(root) e non venire pushate (tipo quelle del DB)

Django apps

I progetti Django sono organizzati in più app, ognuna delle quali gestisce un aspetto particolare dell'applicazione web complessiva.
(Encapsulation of Functionality) Ogni app Django di solito si concentra su un aspetto specifico della funzionalità dell'applicazione, come l'autenticazione degli utenti, la gestione dei contenuti o l'analisi dei dati.
(Loose Coupling) Le app Django sono debolmente accoppiate, il che significa che possono interagire tra loro attraverso interfacce ben definite senza dipendenze strette. Si possono estendere o modificare la funzionalità di un'app senza influenzare altre parti dell'applicazione

Andremo a creare le seguenti app all'interno per la gestione dei vari componenti

$ docker-compose run web django-admin startapp <nome app>

poi dobbiamo aggiungerle l'app al progetto mettendo in settings.py, nel parametro INSTALLED_APPS <name>.apps.<name class in apps.py>

Models in app

Vogliamo avere views piccole e la maggior parte della logica in models.py. I modelli sono astrazioni/regole dentro django per tabelle nel database. Nel momento in cui modifichiamo il database aggiungendo un nuovo modello dobbiamo fare

$ docker-compose run backend python manage.py makemigrations
# Sara' mostrato che e' stato aggiunto un modello con il nome che abbiamo dato

$ docker-compose run backend python manage.py migrate

Form

Il form principale/primario e' quello per la registrazione utenti. Django ha gia qualcosa di pronto, che contiene nome_utente e password. Se vogliamo estenderlo con altri campi dobbiamo creare il file forms.py con all'interno una classe che estende il predefinito user di Django.
Anche qui facciamo

$ docker-compose run backend python manage.py makemigrations
$ docker-compose run backend python manage.py migrate

se cambiamo dei dati, tipo aggiungere nuovi campi agli utenti. Di conseguenza con il form deve essere presenta anche il model per contenere i dati.
After defining this custom user model, you'll need to update your Django settings (settings.py) to use this model as the default user model:
AUTH_USER_MODEL = 'your_app_name.CustomUser'
Replace 'your_app_name' with the name of the Django app where you define your CustomUser model.

Admin.py

Dopo aver creato un Form e il relativo Model per salvare i valori nel database possiamo creare il superutente. Dalla pagina di gjango di amministratore possiamo vedere i diversi utenti solo se modifichiamo il file admin.py dicendo di registrere il contro CustomUser.
Sempre nello stesso file possiamo gestire cosa mostrare nell'interfaccia degli utenti della schernata amministratore.

Database access

Per vedere i dati si dovrebbe poter utilizzare l'interfaccia di admin gia' presente, altrimenti possiamo usare

docker exec -it nome_db bash

# Internamente usiamo:  (nomi in .env file)
psql -U user_name -d db_name
\dt     # Per avere le tabelle disponibili nel database
SELECT * FROM nome_tabella;      # Importante il ';' alla fine

come parametri base dell'utente in postgress database abbiamo:

  • id (by Database- int(automatically inserted))
  • password (by User- required string hash)
  • last_login (by User- time(automatically inserted))
  • is_superuser (by User- bool(false by default))
  • username (by User- required string)
  • first_name (by User- optional string)
  • last_name (by User- optional string)
  • email (by User- optional email)
  • is_staff (by User- bool(false by default))
  • is_active (by User- bool(true by default))
  • date_joined (by User- time(automatically inserted))

Templates

Per avere delle pagine html da personalizzare possiamo creare dei template che poi vengono estesi. Possiamo anche usare template di un applicazione estendendoli in un altra applicazione, e' importante rispettare i nomi delle directory e specificare il come dell'app quando si estendono.

Per aggiungere Bootstrap possiamo seguire le istruzioni sul loro sito link. Da li possiamo poi prendere lo style e i vari componenti da inserire all'interno del nostro. Se inseriamo Bootstrap nel template possiamo poi usarlo dell'expander direttamente, che fa comodo.

OAuth authentication

Quando vogliamo usare un autenticatore esterno a django dobbiamo specificare il relativo backend in AUTHERNTICATION_BECKENDS in settings.py, aggiornre TEMPLATES in settings.py e aggiungere a urls.py.
Ogni volta che viene eseguito il rendering di un modello con una richiesta, viene restituito anche un context. Immagina di creare un'app in cui dobbiamo includere gli stessi dati in ogni visualizzazione che creiamo. È difficile e soggetto a errori, giusto. Qui che entrano in gioco i context_processors.
Sulla pagine della piattaforma ci verranno date key e secret key. probabilmente avremo specificato anche un 'Authorization callback URL' importante perche dopo una autenticazione l'autenticator returns him/her to that callback URL.

Signals in Django

Notice that we have to go to the admin page to create a profile whenever a user is created, but we don't wanna do that every now and then. It would be great if we can create the profiles automatically when a new user is created. To do this we use signals.
But what are signals??
Signals are used to perform some action on modification/creation of a particular entry in database.
In a signal, we have the following basic concepts.

  • Sender: is usually a model that notifies the receiver when an event occurs.
  • Receiver: The receiver is usually a function that works on the data once it is notified of some action that has taken place for instance when a user instance is just about to be saved inside the database.
    The connection between the senders and the receivers is done through “signal dispatchers”.

Use Case:- using signals we can create a profile instance right when a new user instance is created inside the database.
Django recommends us to put signals in the app's directory as a single module. Therefore, create a signals.py file inside the users app.

Supporting Multiple Languages

From https://testdriven.io/blog/multiple-languages-in-django/

  • Internationalization, represented by i18n (18 is the number of letters between i and n), is the processing of developing your application so that it can be used by different locales. This process is generally handled by developers.
  • Localization, represented by l10n (10 is the number of letters between l and n), on the other hand, is the process of translating your application to a particular language and locale. This is generally handled by translators.

For the LANGUAGE_CODE to take effect, USE_I18N must be True, which enables Django’s translation system.
Let's add some additional settings to complement the existing ones:
from django.utils.translation import gettext_lazy as _ (trattino basso importante altrimenti non funziona)

  • We specified the languages we want our project to be available in. If this is not specified, Django will assume our project should be available in all of its supported languages.
  • This LANGUAGE setting consists of the language code and the language name. Recall that the language codes can be locale-specific, such as 'en-gb' or generic such as 'en'.
  • Also, gettext_lazy is used to translate the language names instead of gettext to prevent circular imports. You should almost always use gettext_lazy when you're in the global scope.

Open the shell and run the following command from your project directory to create a .po message file for each language:
$ django-admin makemessages --all --ignore=env
Take note of one of the .po message files:
msgid: represents the translation string as it appears in the source code.
msgstr: represents the language translation, which is empty by default. You'll have to supply the actual translation for any given string.
Currently, only the LANGUAGES from our settings.py file have been marked for translation.
Next, let's compile the messages by running the following command:
$ django-admin compilemessages --ignore=env
A .mo compiled message file has been generated for each language.
You can translate model field names and forms by marking them for translation using either the gettext or gettext_lazy function.

  • We can do this for forms by adding a label.
    from django import forms
    from django.utils.translation import gettext_lazy as _
    
    class ExampleForm(forms.Form):
        first_name = forms.CharField(label=_('first name'))
    
  • To translate our templates, Django offers the {% trans %} and {% blocktrans %} template tags to translate strings. You have to add {% load i18n %} at the top of the HTML file to use the translation templates tags.
    The {% trans %} template tag allows you to mark a literal for translation. Django simply executes the gettext function on the given text internally.
    The {% trans %} tag is useful for simple translation strings, but it can't handle content for translation that includes variables.
    The {% blocktrans %} template tag, on the other hand, allows you to mark content that includes literals and variables.
    Update the following element in the course/templates/index.html file to see this in action:
    <h1>{% trans "TestDriven.io Courses" %}</h1>

We'll be using a third-party library called Rosetta to edit translations using the same interface as the Django administration site. It makes it easy to edit .po files and it updates compiled translation files automatically for us.

SSL Certificate or use Certbot

https://medium.com/@akshatgadodia/deploying-a-django-application-with-docker-nginx-and-certbot-eaf576463f19
After commenting out the HTTPS section in nginx.conf, you can obtain SSL certificates with the following command

docker-compose run --rm certbot certonly --webroot --webroot-path=/var/www/certbot --email your_email@example.com --agree-tos --no-eff-email -d your_domain.com

Il dominio deve essere davvero pubblico ed esistere pero'
Creating self-signed certificates for HTTPS involves a few steps. Here's a general outline:

  1. Generate a Private Key: First, generate a private key. This key will be used to sign the certificate request.
openssl genrsa -out key.pem 2048

This command generates a 2048-bit RSA private key and saves it to key.pem.

  1. Generate a Certificate Signing Request (CSR): Next, generate a CSR using the private key. The CSR contains information about the entity the certificate is being issued to.
openssl req -new -key key.pem -out csr.pem

Follow the prompts to enter information like country, state, locality, organization, etc. You can leave some fields blank if you want.

  1. Generate the Self-Signed Certificate: Use the CSR and the private key to generate the self-signed certificate.
openssl x509 -req -days 365 -in csr.pem -signkey key.pem -out cert.pem

This command generates a self-signed certificate that is valid for 365 days (-days 365) and saves it to cert.pem.

  1. Configure your HTTPS Server: Finally, configure your server (e.g., Apache, Nginx) to use the generated private key and certificate.

Here's a very basic example of an Nginx configuration:

server {
    listen 443 ssl;
    server_name your_domain.com;

    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;

    # Other SSL configurations...
}

Replace /path/to/cert.pem and /path/to/key.pem with the paths to your generated certificate and private key respectively.

Workflow

Per gestire il database mettiamo modelli in app app_name/models.py
Per le risposte in base agli endpoint facciamo delle classi in app app_name/views.py
Che utilizzeranno dei serializer per validare e gestire i dati in ingresso e uscita, facciamo delle classi in app app_name/serializers.py

Nel frontend andremo ad usare Bootstrap, quindi inizializziamo il progetto con npm init -y nella cartella del progetto e poi installiamo npm install bootstrap@5. npm andra' a gestire tutti i mobuli e ci permettera anche di installarne altri.
(Babel utile per rendere il codice compatibile con piu' browsers.)
Avremo una struttura del genere:

project_name/
│
├── manage.py
├── static/
│   └── ...
│
├── project_name/
│   ├── __init__.py
│   ├── asgi.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
│
└── app_name/
    ├── migrations/
    │   └── ...
    ├── node_modules/                   (cartella generata da npm, contiene le dipendenze)
    │   └── ...
    ├── static/
    │   └── ...
    ├── templates/
    │   └── app_name/
    │       ├── base.html
    │       └── extension_page.html     (per sfruttare la template inheritance con base.html)
    ├── __init__.py
    ├── admin.py
    ├── apps.py
    ├── models.py
    ├── forms.py                        (file per personalizzare i form, come quello utente)
    ├── package.json                    (file di configurazione npm)
    ├── package-lock.json               (file di blocco delle versioni npm)
    ├── tests.py
    ├── urls.py
    └── views.py

Implementation Choises

Mandatory

Chosen modules

  • Web
    • 1 Framework backend ---> Django
    • 0.5 Framework frontend ---> Django
    • 0.5 Database for Beckend ---> PostgreSQL
  • User Management
  • Gameplay e UE
  • AI algo
    • 0.5 User and Game Stats
  • Cybersecurity
  • DevOps
    • 0.5 Monitoring System
  • Gaming
  • Graphics
  • Accessibility
    • 0.5 Browser compatibility
    • 0.5 Multi-languages
  • Server Side Pong

About

License:GNU General Public License v3.0


Languages

Language:JavaScript 41.4%Language:CSS 40.7%Language:HTML 9.2%Language:Python 7.9%Language:Makefile 0.6%Language:Dockerfile 0.2%