1
Fork 0
mirror of https://github.com/Steffo99/sophon.git synced 2024-12-22 06:44:21 +00:00

🎓 More progress

This commit is contained in:
Steffo 2021-11-25 03:47:06 +01:00
parent e789bfd158
commit 7476a74e2e
Signed by: steffo
GPG key ID: 6965406171929D01
2 changed files with 132 additions and 72 deletions

View file

@ -417,23 +417,23 @@ Fa ampio uso delle `CSS Custom Properties <https://developer.mozilla.org/en-US/d
.. figure:: bluelib_royalblue.png .. figure:: bluelib_royalblue.png
Il tema "Royal Blue" di Bluelib, da cui ha origine il nome. Il tema "Royal Blue" (``royalblue``) di Bluelib, da cui ha origine il nome.
.. figure:: bluelib_paper.png .. figure:: bluelib_paper.png
Il tema "Sheet of Paper" di Bluelib, pensato per la stampa su carta. Il tema "Sheet of Paper" (``paper``) di Bluelib, pensato per la stampa su carta.
.. figure:: bluelib_sophon.png .. figure:: bluelib_sophon.png
Il tema "Sophon" di Bluelib, creato appositamente per questo progetto. Il tema "The Sophonity" (``sophon``) di Bluelib, creato appositamente per questo progetto.
.. figure:: bluelib_hacker.png .. figure:: bluelib_hacker.png
Il tema "Hacker Terminal" di Bluelib, creato per testare la visualizzazione di caratteri monospace. Il tema "Hacker Terminal" (``hacker``) di Bluelib, creato per testare la visualizzazione di caratteri monospace.
.. figure:: bluelib_amber.png .. figure:: bluelib_amber.png
Il tema "Gestione Amber" di Bluelib, realizzato da Lorenzo Balugani. Il tema "Gestione Amber" (``amber``) di Bluelib, realizzato da Lorenzo Balugani.
.. index:: .. index::
@ -659,7 +659,7 @@ Controllo versione
Per assistere nello sviluppo del software si è deciso di utilizzare il sistema di controllo versione `Git` in ogni fase dello sviluppo del progetto. Per assistere nello sviluppo del software si è deciso di utilizzare il sistema di controllo versione `Git` in ogni fase dello sviluppo del progetto.
Inoltre, per favorire lo sviluppo di una community `open source <Open source>` attorno a Sophon, si è deciso di pubblicare il progetto su `GitHub`, sotto la licenza `AGPL 3.0+`. Inoltre, per favorire lo sviluppo di una community `open source <Open source>` attorno a Sophon, si è deciso di pubblicare il progetto su `GitHub`, sotto la `Affero General Public License 3.0+`.
.. index:: .. index::
@ -688,6 +688,21 @@ GitHub
Per ciascun repository sono messe a disposizione gratuitamente numerose funzionalità, quali un issue tracker, strumenti di code review e sistemi di automazione per lo sviluppo :cite:`github:features`. Per ciascun repository sono messe a disposizione gratuitamente numerose funzionalità, quali un issue tracker, strumenti di code review e sistemi di automazione per lo sviluppo :cite:`github:features`.
Affero General Public License 3.0+
----------------------------------
Sophon è rilasciato sotto la `GNU Affero General Public License 3`_ (o successiva).
Il testo completo della licenza è disponibile all'interno del file `LICENSE.txt`_ allegato al codice sorgente del software.
In breve, la licenza permette a chiunque di utilizzare, distribuire e modificare il software, a condizione che qualsiasi modifica venga ri-distribuita agli utenti del software modificato.
Si specifica che la licenza copre tutti i file all'interno del repository ``Steffo99/sophon``, anche se essi non contengono un header che indica che sono protetti da copyright.
.. _GNU Affero General Public License 3: https://www.gnu.org/licenses/agpl-3.0.html
.. _LICENSE.txt: https://github.com/Steffo99/sophon/blob/main/LICENSE.txt
.. index:: .. index::
pair: Sophon; entità pair: Sophon; entità
@ -778,7 +793,7 @@ Un *gruppo di ricerca* rappresenta un insieme di utenti che collaborano su uno o
Membri e modalità di accesso Membri e modalità di accesso
^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Gli utenti dell'`istanza <Istanza di Sophon>` possono diventare *membri* dei gruppi di ricerca, con una delle seguenti modalità selezionate nelle impostazioni del gruppo: Gli utenti dell'`istanza <Istanza in Sophon>` possono diventare *membri* dei gruppi di ricerca, con una delle seguenti modalità selezionate nelle impostazioni del gruppo:
- se il gruppo è *aperto*, allora qualsiasi utente potrà diventarne membro semplicemente **facendo richiesta** attraverso l'interfaccia web; - se il gruppo è *aperto*, allora qualsiasi utente potrà diventarne membro semplicemente **facendo richiesta** attraverso l'interfaccia web;
- se il gruppo è in *modalità manuale*, allora nessun utente potrà richiedere di unirsi, e i membri saranno **selezionati manualmente** dal creatore del gruppo. - se il gruppo è in *modalità manuale*, allora nessun utente potrà richiedere di unirsi, e i membri saranno **selezionati manualmente** dal creatore del gruppo.

View file

@ -59,7 +59,7 @@ Inoltre, il template predefinito viene sovrascritto da quello all'interno del fi
.. attribute:: default_site = "sophon.admin.SophonAdminSite" .. attribute:: default_site = "sophon.admin.SophonAdminSite"
`.SophonAdminSite` è selezionata come classe predefinita per il sito di amministrazione. :class:`.SophonAdminSite` è selezionata come classe predefinita per il sito di amministrazione.
Caricamento dinamico delle impostazioni Caricamento dinamico delle impostazioni
@ -122,18 +122,18 @@ Aggiunta di un nuovo comando di gestione
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. module:: sophon.core.management.commands.initsuperuser .. module:: sophon.core.management.commands.initsuperuser
Per permettere l'integrazione la creazione automatica del primo :ref:`superutente` quando Sophon viene eseguito da Docker, viene introdotto dall'app il comando di gestione ``initsuperuser``. Per permettere l'integrazione la creazione automatica del primo superutente quando Sophon viene eseguito da Docker, viene introdotto dall'app il comando di gestione ``initsuperuser``.
.. class:: Command .. class:: Command
Questo comando crea automaticamente un :ref:`superutente` con le credenziali specificate in :ref:`\`\`DJANGO_SU_USERNAME\`\``, :ref:`\`\`DJANGO_SU_EMAIL\`\`` e :ref:`\`\`DJANGO_SU_PASSWORD\`\``. Questo comando crea automaticamente un superutente con le credenziali specificate in :env:`DJANGO_SU_USERNAME`, :env:`DJANGO_SU_EMAIL` e :env:`DJANGO_SU_PASSWORD`.
Modello base astratto Modello base astratto
^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^
.. module:: sophon.core.models .. module:: sophon.core.models
Viene estesa la classe astratta `django.db.models.Model` con funzioni per stabilire il `livello di accesso` di un `utente <Utenti in Sophon>` all'oggetto e per generare automaticamente i `rest_framework.serializers.ModelSerializer` in base ad esso. Viene estesa la classe astratta `django.db.models.Model` con funzioni per stabilire il `livello di accesso <Livelli di accesso>` di un `utente <Utenti in Sophon>` all'oggetto e per generare automaticamente i `rest_framework.serializers.ModelSerializer` in base ad esso.
.. class:: SophonModel(django.db.models.Model) .. class:: SophonModel(django.db.models.Model)
@ -143,7 +143,7 @@ Viene estesa la classe astratta `django.db.models.Model` con funzioni per stabil
Controlla se un utente può modificare l'oggetto attuale. Controlla se un utente può modificare l'oggetto attuale.
:param user: L'utente da controllare. :param user: L'utente da controllare.
:returns: `True` se l'utente deve poter modificare l'oggetto, altrimenti `False`. :returns: :data:`True` se l'utente deve poter modificare l'oggetto, altrimenti :data:`False`.
.. method:: can_admin(self, user: django.contrib.auth.models.User) -> bool .. method:: can_admin(self, user: django.contrib.auth.models.User) -> bool
:abstractmethod: :abstractmethod:
@ -151,23 +151,23 @@ Viene estesa la classe astratta `django.db.models.Model` con funzioni per stabil
Controlla se un utente può amministrare l'oggetto attuale. Controlla se un utente può amministrare l'oggetto attuale.
:param user: L'utente da controllare. :param user: L'utente da controllare.
:returns: `True` se l'utente deve poter amministrare l'oggetto, altrimenti `False`. :returns: :data:`True` se l'utente deve poter amministrare l'oggetto, altrimenti :data:`False`.
.. classmethod:: get_fields(cls) -> set[str] .. classmethod:: get_fields(cls) -> set[str]
:returns: il `set` di nomi di campi che devono essere mostrati quando viene richiesto l'oggetto attraverso l'API. :returns: il :class:`set` di nomi di campi che devono essere mostrati quando viene richiesto l'oggetto attraverso l'API.
.. classmethod:: get_editable_fields(cls) -> set[str] .. classmethod:: get_editable_fields(cls) -> set[str]
:returns: il `set` di nomi di campi di cui deve essere permessa la modifica se l'utente può modificare (`.can_edit`) l'oggetto. :returns: il :class:`set` di nomi di campi di cui deve essere permessa la modifica se l'utente può modificare (:meth:`.can_edit`) l'oggetto.
.. classmethod:: get_administrable_fields(cls) -> set[str] .. classmethod:: get_administrable_fields(cls) -> set[str]
:returns: il `set` di nomi di campi di cui deve essere permessa la modifica se l'utente può amministrare (`.can_admin`) l'oggetto. :returns: il :class:`set` di nomi di campi di cui deve essere permessa la modifica se l'utente può amministrare (:meth:`.can_admin`) l'oggetto.
.. classmethod:: get_creation_fields(cls) -> set[str] .. classmethod:: get_creation_fields(cls) -> set[str]
:returns: il `set` di nomi di campi che possono essere specificati dall'utente al momento della creazione dell'oggetto. :returns: il :class:`set` di nomi di campi che possono essere specificati dall'utente al momento della creazione dell'oggetto.
Modello di autorizzazione astratto Modello di autorizzazione astratto
@ -223,7 +223,7 @@ Viene definito un nuovo modello astratto, basato su `SophonModel`, che permette
Modello dei dettagli dell'istanza Modello dei dettagli dell'istanza
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Viene creato il modello che rappresenta i dettagli dell'`istanza di Sophon <Istanza di Sophon>`. Viene creato il modello che rappresenta i dettagli dell'`istanza di Sophon <Istanza in Sophon>`.
.. class:: SophonInstanceDetails(SophonModel) .. class:: SophonInstanceDetails(SophonModel)
@ -254,7 +254,7 @@ Viene creato il modello che rappresenta i dettagli dell'`istanza di Sophon <Ista
Modello del gruppo di ricerca Modello del gruppo di ricerca
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Viene creato il modello che rappresenta un :ref:`gruppo di ricerca <Gruppi di ricerca>`. Viene creato il modello che rappresenta un `gruppo di ricerca <Gruppi di ricerca in Sophon>`.
.. class:: ResearchGroup(SophonGroupModel) .. class:: ResearchGroup(SophonGroupModel)
@ -937,8 +937,11 @@ public
Contiene i file statici da servire assieme all'app. Contiene i file statici da servire assieme all'app.
Comunicazione con il server Comunicazione con il backend
--------------------------- ----------------------------
Sono state sviluppate alcune funzioni di utilità per facilitare la comunicazione con il `modulo backend <Realizzazione del modulo backend>`.
Axios Axios
^^^^^ ^^^^^
@ -971,25 +974,53 @@ Utilizzo di viewset
Viene implementato un hook che si integra con i viewset di Django, fornendo un API semplificato per effettuare azioni su di essi. Viene implementato un hook che si integra con i viewset di Django, fornendo un API semplificato per effettuare azioni su di essi.
.. function:: useViewSet(baseRoute) .. function:: useViewSet(baseRoute) → viewset
Questo hook implementa tutte le azioni :py:mod:`rest_framework` di un viewset in lettura e scrittura. Questo hook implementa tutte le azioni :py:mod:`rest_framework` di un viewset in lettura e scrittura.
Richiede di essere chiamato all'interno di un :data:`AuthorizationContext`. Richiede di essere chiamato all'interno di un :data:`AuthorizationContext`.
.. function:: async list(config = {}) .. function:: viewset.list(config = {})
.. function:: async retrieve(pk, config = {})
.. function:: async create(config) Funzione **asincrona**, che restituisce una :class:`Promise`.
.. function:: async update(pk, config)
.. function:: async destroy(pk, config) Richiede la lista di tutte le risorse del viewset.
.. function:: viewset.retrieve(pk, config = {})
Funzione **asincrona**, che restituisce una :class:`Promise`.
Richiede i dettagli di una specifica risorsa del viewset.
.. function:: viewset.create(config)
Funzione **asincrona**, che restituisce una :class:`Promise`.
Crea una nuova risorsa nel viewset.
.. function:: viewset.update(pk, config)
Funzione **asincrona**, che restituisce una :class:`Promise`.
Aggiorna una specifica risorsa nel viewset.
.. function:: viewset.destroy(pk, config)
Funzione **asincrona**, che restituisce una :class:`Promise`.
Elimina una specifica risorsa dal viewset.
Viene inoltre fornito supporto per le azioni personalizzate. Viene inoltre fornito supporto per le azioni personalizzate.
.. function:: async command(config) .. function:: viewset.command(config)
Funzione **asincrona**, che restituisce una :class:`Promise`.
Permette azioni personalizzate su tutto il viewset. Permette azioni personalizzate su tutto il viewset.
.. function:: async action(config) .. function:: viewset.action(config)
Funzione **asincrona**, che restituisce una :class:`Promise`.
Permette azioni personalizzate su uno specifico oggetto del viewset. Permette azioni personalizzate su uno specifico oggetto del viewset.
@ -999,51 +1030,63 @@ Emulazione di viewset
Viene creato un hook che tiene traccia degli oggetti restituiti da un determinato viewset, ed emula i risultati delle azioni effettuate, minimizzando i rerender e ottenendo una ottima user experience. Viene creato un hook che tiene traccia degli oggetti restituiti da un determinato viewset, ed emula i risultati delle azioni effettuate, minimizzando i rerender e ottenendo una ottima user experience.
.. function:: useManagedViewSet(baseRoute, pkKey, refreshOnMount) .. function:: useManagedViewSet(baseRoute, pkKey, refreshOnMount) → managed
.. attribute:: viewset .. attribute:: managed.viewset
Il viewset restituito da :func:`useViewSet`, utilizzato come interfaccia di basso livello per effettuare azioni. Il viewset restituito da :func:`useViewSet`, utilizzato come interfaccia di basso livello per effettuare azioni.
.. attribute:: state .. attribute:: managed.state
Lo stato del viewset, che tiene traccia degli oggetti e delle azioni in corso su di essi. Lo stato del viewset, che tiene traccia degli oggetti e delle azioni in corso su di essi.
Gli oggetti all'interno di esso sono istanze di :class:`ManagedResource`, create usando wrapper di :func:`.update`, :func:`.destroy` e :func:`.action`, che permettono di modificare direttamente l'oggetto senza preoccuparsi dell'indice a cui si trova nell'array. Gli oggetti all'interno di esso sono istanze di :class:`ManagedResource`, create usando wrapper di :func:`.update`, :func:`.destroy` e :func:`.action`, che permettono di modificare direttamente l'oggetto senza preoccuparsi dell'indice a cui si trova nell'array.
.. attribute:: dispatch .. attribute:: managed.dispatch
Riduttore che permette di alterare lo :attr:`.state`. Riduttore che permette di alterare lo :attr:`.state`.
.. function:: async refresh() .. function:: managed.refresh()
Funzione **asincrona**, che restituisce una :class:`Promise`.
Ricarica gli oggetti del viewset. Ricarica gli oggetti del viewset.
Viene chiamata automaticamente al primo render se ``refreshOnMount`` è :data:`True`. Viene chiamata automaticamente al primo render se ``refreshOnMount`` è :data:`True`.
.. function:: async create(data) .. function:: managed.create(data)
Funzione **asincrona**, che restituisce una :class:`Promise`.
Crea un nuovo oggetto nel viewset con i dati specificati come argomento, e lo aggiunge allo stato se la richiesta va a buon fine. Crea un nuovo oggetto nel viewset con i dati specificati come argomento, e lo aggiunge allo stato se la richiesta va a buon fine.
.. function:: async command(method, cmd, data) .. function:: managed.command(method, cmd, data)
Funzione **asincrona**, che restituisce una :class:`Promise`.
Esegue l'azione personalizzata ``cmd`` su tutto il viewset, utilizzando il metodo ``method`` e con i dati specificati in ``data``. Esegue l'azione personalizzata ``cmd`` su tutto il viewset, utilizzando il metodo ``method`` e con i dati specificati in ``data``.
Se la richiesta va a buon fine, il valore restituito dal backend sostituisce nello stato le risorse dell'intero viewset. Se la richiesta va a buon fine, il valore restituito dal backend sostituisce nello stato le risorse dell'intero viewset.
.. function:: async update(index, data) .. function:: managed.update(index, data)
Funzione **asincrona**, che restituisce una :class:`Promise`.
Modifica l'oggetto alla posizione ``index`` dell'array :attr:`.state` con i dati specificati in ``data``. Modifica l'oggetto alla posizione ``index`` dell'array :attr:`.state` con i dati specificati in ``data``.
Se la richiesta va a buon fine, la modifica viene anche applicata all'interno di :attr:`.state` Se la richiesta va a buon fine, la modifica viene anche applicata all'interno di :attr:`.state`
.. function:: async destroy(index) .. function:: managed.destroy(index)
Funzione **asincrona**, che restituisce una :class:`Promise`.
Elimina l'oggetto alla posizione ``index`` dell'array :attr:`.state`. Elimina l'oggetto alla posizione ``index`` dell'array :attr:`.state`.
Se la richiesta va a buon fine, l'oggetto viene eliminato anche da :attr:`.state`. Se la richiesta va a buon fine, l'oggetto viene eliminato anche da :attr:`.state`.
.. function:: async action(index, method, act, data) .. function:: managed.action(index, method, act, data)
Funzione **asincrona**, che restituisce una :class:`Promise`.
Esegue l'azione personalizzata ``act`` sull'oggetto alla posizione ``index`` dell'array :attr:`.state`, utilizzando il metodo ``method`` e con i dati specificati in ``data``. Esegue l'azione personalizzata ``act`` sull'oggetto alla posizione ``index`` dell'array :attr:`.state`, utilizzando il metodo ``method`` e con i dati specificati in ``data``.
@ -1064,11 +1107,11 @@ Viene definito un contesto per ogni tipo di risorsa selezionabile nell'interfacc
Essi sono, in ordine dal più esterno al più interno: Essi sono, in ordine dal più esterno al più interno:
#. :data:`InstanceContext` (:ref:`Istanza`) #. :data:`InstanceContext` (`Istanza <Istanza in Sophon>`)
#. :data:`AuthorizationContext` (:ref:`Utente`) #. :data:`AuthorizationContext` (`Utente <Utenti in Sophon>`)
#. :data:`GroupContext` (:ref:`Gruppo di ricerca`) #. :data:`GroupContext` (`Gruppo di ricerca <Gruppi di ricerca in Sophon>`)
#. :data:`ProjectContext` (:ref:`Progetto di ricerca`) #. :data:`ProjectContext` (`Progetto di ricerca <Progetti di ricerca in Sophon>`)
#. :data:`NotebookContext` (:ref:`Notebook`) #. :data:`NotebookContext` (`Notebook <Notebook in Sophon>`)
Contenuto dei contesti Contenuto dei contesti
@ -1113,10 +1156,10 @@ Viene definita una funzione in grado di comprendere gli URL contestuali:
Un oggetto con le seguenti chiavi, dette "segmenti di percorso", le quali possono essere :data:`undefined` per indicare che non è stato selezionato un oggetto di quel tipo: Un oggetto con le seguenti chiavi, dette "segmenti di percorso", le quali possono essere :data:`undefined` per indicare che non è stato selezionato un oggetto di quel tipo:
- ``instance``: l'URL dell'istanza da utilizzare, con caratteri speciali sostituiti da ``:`` - ``instance``: l'URL dell'istanza da utilizzare, con caratteri speciali sostituiti da ``:``
- ``loggedIn``: :class:`Boolean`, se :data:`True` l'utente ha effettuato il login (come :ref:`Ospite` o :ref:`Utente`) - ``loggedIn``: :class:`Boolean`, se :data:`True` l'utente ha effettuato il login (anche come ospite)
- ``researchGroup``: lo slug del :ref:`gruppo di ricerca` selezionato - ``researchGroup``: lo slug del `gruppo di ricerca <Gruppi di ricerca in Sophon>` selezionato
- ``researchProject``: lo slug del :ref:`progetto di ricerca` selezionato - ``researchProject``: lo slug del `progetto di ricerca <Progetti di ricerca in Sophon>` selezionato
- ``notebook``: lo slug del :ref:`notebook` selezionato - ``notebook``: lo slug del `notebook <Notebook in Sophon>` selezionato
Ad esempio, l'URL precedente restituirebbe il seguente oggetto se processato: Ad esempio, l'URL precedente restituirebbe il seguente oggetto se processato:
@ -1181,7 +1224,7 @@ Esempio di utilizzo di ViewSetRouter
Implementato come: Implementato come:
.. code-block:: tsx .. code-block:: jsx
<ViewSetRouter <ViewSetRouter
{...props} {...props}
@ -1240,7 +1283,7 @@ Il tema dell'istanza è implementato come uno speciale contesto globale :data:`T
Cache Cache
""""" """""
Viene salvato l'elenco di tutti i membri dell':ref:`istanza` in uno speciale contesto :data:`CacheContext` in modo da poter risolvere gli id degli utenti al loro username senza dover effettuare ulteriori richieste. Viene salvato l'elenco di tutti i membri dell'`istanza <Istanza in Sophon>` in uno speciale contesto :data:`CacheContext` in modo da poter risolvere gli id degli utenti al loro username senza dover effettuare ulteriori richieste.
Containerizzazione del modulo frontend Containerizzazione del modulo frontend
@ -1251,8 +1294,8 @@ Il modulo frontend è incapsulato in un'immagine `Docker` basata sull'immagine u
L'immagine installa le dipendenze del modulo con `Yarn`, per poi eseguire il comando ``yarn run serve``, che avvia la procedura di preparazione della pagina e la rende disponibile su un webserver locale alla porta 3000. L'immagine installa le dipendenze del modulo con `Yarn`, per poi eseguire il comando ``yarn run serve``, che avvia la procedura di preparazione della pagina e la rende disponibile su un webserver locale alla porta 3000.
Modulo proxy Realizzazione del modulo proxy
============ ==============================
Il modulo proxy consiste in un file di configurazione di `Apache HTTP Server`. Il modulo proxy consiste in un file di configurazione di `Apache HTTP Server`.
@ -1266,7 +1309,7 @@ Il file di configurazione abilita i moduli httpd `rewrite`_, `proxy`_, `proxy_ws
Inoltre, nel file di configurazione viene abilitato il ``RewriteEngine``, che viene utilizzato per effettuare reverse proxying secondo le seguenti regole: Inoltre, nel file di configurazione viene abilitato il ``RewriteEngine``, che viene utilizzato per effettuare reverse proxying secondo le seguenti regole:
#. Tutte le richieste verso ``static.`` prefisso ad :ref:`\`\`APACHE_PROXY_BASE_DOMAIN\`\`` vengono processate direttamente dal webserver, utilizzando i file disponibili nella cartella ``/var/www/html/django-static`` che gli vengono forniti dal volume ``django-static`` del :ref:`modulo backend`. #. Tutte le richieste verso ``static.`` prefisso ad :env:`APACHE_PROXY_BASE_DOMAIN` vengono processate direttamente dal webserver, utilizzando i file disponibili nella cartella ``/var/www/html/django-static`` che gli vengono forniti dal volume ``django-static`` del :ref:`modulo backend`.
.. code-block:: apacheconf .. code-block:: apacheconf
@ -1275,7 +1318,7 @@ Inoltre, nel file di configurazione viene abilitato il ``RewriteEngine``, che vi
# Process the request yourself # Process the request yourself
RewriteRule ".?" - [L] RewriteRule ".?" - [L]
#. Tutte le richieste verso :ref:`\`\`APACHE_PROXY_BASE_DOMAIN\`\`` senza nessun sottodominio vengono inoltrate al container Docker del :ref:`modulo frontend` utilizzando la risoluzione dei nomi di dominio di Docker Compose. #. Tutte le richieste verso :env:`APACHE_PROXY_BASE_DOMAIN` senza nessun sottodominio vengono inoltrate al container Docker del :ref:`modulo frontend` utilizzando la risoluzione dei nomi di dominio di Docker Compose.
.. code-block:: apacheconf .. code-block:: apacheconf
@ -1286,7 +1329,7 @@ Inoltre, nel file di configurazione viene abilitato il ``RewriteEngine``, che vi
# Forward to the frontend # Forward to the frontend
RewriteRule "/(.*)" "http://%1/$1" [P,L] RewriteRule "/(.*)" "http://%1/$1" [P,L]
#. Tutte le richieste verso ``api.`` prefisso ad :ref:`\`\`APACHE_PROXY_BASE_DOMAIN\`\`` vengono inoltrate al container Docker del :ref:`modulo backend` utilizzando la risoluzione dei nomi di dominio di Docker Compose. #. Tutte le richieste verso ``api.`` prefisso ad :env:`APACHE_PROXY_BASE_DOMAIN` vengono inoltrate al container Docker del :ref:`modulo backend` utilizzando la risoluzione dei nomi di dominio di Docker Compose.
.. code-block:: apacheconf .. code-block:: apacheconf
@ -1334,8 +1377,8 @@ Dockerizzazione del modulo proxy
Il modulo proxy è incapsulato in un'immagine `Docker` basata sull'immagine ufficiale `httpd:2.4 <https://hub.docker.com/_/httpd>`_, che si limita ad applicare la configurazione personalizzata. Il modulo proxy è incapsulato in un'immagine `Docker` basata sull'immagine ufficiale `httpd:2.4 <https://hub.docker.com/_/httpd>`_, che si limita ad applicare la configurazione personalizzata.
Modulo Jupyter Realizzazione del modulo Jupyter
============== ================================
Il *modulo Jupyter* consiste in un ambiente `Jupyter <https://jupyter.org/>`_ e `JupyterLab <https://jupyterlab.readthedocs.io/en/stable/>`_ modificato per una migliore integrazione con Sophon, in particolare con il :ref:`modulo frontend` e il :ref:`modulo backend`. Il *modulo Jupyter* consiste in un ambiente `Jupyter <https://jupyter.org/>`_ e `JupyterLab <https://jupyterlab.readthedocs.io/en/stable/>`_ modificato per una migliore integrazione con Sophon, in particolare con il :ref:`modulo frontend` e il :ref:`modulo backend`.
@ -1343,17 +1386,25 @@ Il *modulo Jupyter* consiste in un ambiente `Jupyter <https://jupyter.org/>`_ e
Sviluppo del tema per Jupyter Sviluppo del tema per Jupyter
============================= -----------------------------
.. todo:: Tema personalizzato di Jupyter Per rendere l'interfaccia grafica più consistente ed user-friendly, è stato sviluppato un tema colori personalizzato per `JupyterLab`.
È stato creato partendo dal template `jupyterlab/theme-cookiecutter <https://github.com/jupyterlab/theme-cookiecutter>`_, e in esso sono state modificati le variabili di stile (contenute nel file ``style/variables.css``) usando i colori del tema "The Sophonity" di `Bluelib`.
È stato poi pubblicato sull':abbr:`PyPI (Python Package Index)` e su `npm`, permettendone l'uso a tutti gli utenti di JupyterLab.
.. note::
Per facilitarne la distribuzione e il riutilizzo anche esternamente a Sophon, il tema è stato creato in un repository `Git` esterno a quello del progetto.
Funzionamento del modulo Estensione del container Docker di Jupyter
------------------------ ------------------------------------------
Il modulo è composto da un singolo ``Dockerfile`` che crea un immagine Docker in quattro fasi: Il ``Dockerfile`` del modulo ne crea un immagine Docker in quattro fasi:
#. **Base**: Parte dall'immagine base ``jupyter/scipy-notebook`` ed altera i label dell'immagine; #. **Base**: Parte dall'immagine base ``jupyter/scipy-notebook`` e ne altera i label.
.. code-block:: docker .. code-block:: docker
@ -1361,7 +1412,7 @@ Il modulo è composto da un singolo ``Dockerfile`` che crea un immagine Docker i
# Set the maintainer label # Set the maintainer label
LABEL maintainer="Stefano Pigozzi <me@steffo.eu>" LABEL maintainer="Stefano Pigozzi <me@steffo.eu>"
#. **Env**: Configura le variabili di ambiente dell'immagine, attivando JupyterLab, configurando il riavvio automatico di Jupyter e permettendo all'utente non-privilegiato di acquisire i privilegi di root attraverso il comando ``sudo``; #. **Env**: Configura le variabili di ambiente dell'immagine, attivando JupyterLab, configurando il riavvio automatico di Jupyter e permettendo all'utente non-privilegiato di acquisire i privilegi di root attraverso il comando ``sudo``.
.. code-block:: docker .. code-block:: docker
@ -1371,7 +1422,7 @@ Il modulo è composto da un singolo ``Dockerfile`` che crea un immagine Docker i
ENV RESTARTABLE=yes ENV RESTARTABLE=yes
ENV GRANT_SUDO=yes ENV GRANT_SUDO=yes
#. **Extensions**: Installa, abilita e configura le estensioni necessarie all'integrazione con Sophon (attualmente, soltanto il tema JupyterLab Sophon); #. **Extensions**: Installa, abilita e configura le estensioni necessarie all'integrazione con Sophon (attualmente, soltanto il tema JupyterLab Sophon).
.. code-block:: docker .. code-block:: docker
@ -1387,7 +1438,7 @@ Il modulo è composto da un singolo ``Dockerfile`` che crea un immagine Docker i
RUN mkdir -p '.jupyter/lab/user-settings/@jupyterlab/apputils-extension/' RUN mkdir -p '.jupyter/lab/user-settings/@jupyterlab/apputils-extension/'
RUN echo '{"theme": "JupyterLab Sophon"}' > ".jupyter/lab/user-settings/@jupyterlab/apputils-extension/themes.jupyterlab-settings" RUN echo '{"theme": "JupyterLab Sophon"}' > ".jupyter/lab/user-settings/@jupyterlab/apputils-extension/themes.jupyterlab-settings"
#. **Healthcheck**: Installa ``curl``, e aggiunge all'immagine un controllo per verificarne lo stato di avvio, permettendo al :ref:`modulo backend` di comunicare una richiesta di avvio riuscita solo quando l'intera immagine è avviata #. **Healthcheck**: Installa `curl`, uno strumento in grado di effettuare richieste :abbr:`HTTP (HyperText Transfer Protocol` da linea di comando, e configura la verifica dello `stato di salute <Controllo dello stato di salute>` dell'immagine, al fine di comunicare al `modulo backend <Modulo backend>` il risultato di una richiesta di avvio.
.. code-block:: docker .. code-block:: docker
@ -1403,12 +1454,6 @@ Il modulo è composto da un singolo ``Dockerfile`` che crea un immagine Docker i
# We probably should go back to the default user # We probably should go back to the default user
USER ${NB_UID} USER ${NB_UID}
.. note::
I blocchi di codice all'interno di questa sezione sono stati inseriti manualmente e potrebbero non essere interamente aggiornati alla versione più recente del file.
Si consiglia di consultare il ``Dockerfile`` in caso si necessiti di informazioni aggiornate.
Strumenti di sviluppo Strumenti di sviluppo
===================== =====================