Intro

Classeviva.py contiene al suo interno i seguenti moduli:

  • classeviva: modulo principale, contiene tutti i metodi per la gestione della API

  • classeviva.collegamenti: URL dell’API

  • classeviva.eccezioni: eccezioni che possono essere sollevate da Classeviva.py

  • classeviva.variabili: costanti e classi per gestire i dati di Classeviva

classeviva

Classeviva è il modulo che contiene le classi per la comunicazione con il sito di Classeviva

Segue l’elenco delle classi pubbliche del modulo classeviva:

  • Utente: classe che rappresenta un utente

  • ListaUtenti: classe che rappresenta una lista di utenti

Utente

Rappresenta un utente di Classeviva, di tipo Studente 1

Classe

class Utente(object)

Costruttore

def __init__(
    self,
    id: str,
    password: str
) -> None:

Parametri:

  • id: username dell’utente

  • password: password dell’utente

Attributi

  • self.id: str: username dell’utente

  • password: str: password dell’utente

  • _sessione: requests.Session: sessione di comunicazione con l’API

  • _dati: dict: dati dell’utente

Proprietà

Semplici

  • biglietto_completo: dict[str, str] - Biglietto 2

  • biglietto: str - il biglietto, in forma di stringa e non in formato JSON [JSON]

  • secondi_rimasti: int - secondi rimasti alla sessione 3

  • stato: bool - comunica se la sessione è ancora attiva

  • connesso: bool - comunica se la sessione è attiva senza fare richieste all’API

  • token: str - token della sessione

Complesse

  • dati: dict[str, str] - dati dell’utente

@property
def dati(self) -> dict[str, str]:
    try:
        return {
            chiave: valore for chiave, valore in self._dati.items()
            if chiave in {"ident", "firstName", "lastName"}
        }
    except KeyError:
        raise e.SenzaDati(f"{self} non ha i dati sufficienti per questa proprietà")
  • pagelle: list[dict[str, str]] - pagelle dell’utente disponibili tra i documenti 4

@property
def pagelle(self) -> list[dict[str, str]]:
    documenti_ = asyncio.run(self.documenti())
    try:
        return [{
            chiave: valore for chiave, valore in documento_.items()
            if chiave in {"desc", "confirmLink", "viewLink"}
        } for documento_ in documenti_["schoolReports"]]
    except KeyError:
        raise e.SenzaDati(f"{self} non ha i dati sufficienti per questa proprietà")

Metodi

  • await self.accedi() - effettua l’accesso alla sessione 6

async def accedi(self) -> None:

Eccezioni

  • classeviva.eccezioni.PasswordNonValida - eccezione generata in caso di errore 422, dato da una password che non combacia con l’username

  • classeviva.eccezioni.ErroreHTTP - eccezione generata in caso di errore con altro codice HTTP

  • await self.documenti() - restituisce i documenti dell’utente 5

async def documenti(self) -> dict[str, list[dict[str, str]]]:

Ritorno

  • dict[str, list[dict[str, str]]] - i documenti dell’utente in formato JSON 5

Eccezioni

  • classeviva.eccezioni.ErroreHTTP - eccezione generata in caso di errore HTTP

  • await self.controlla_documento(documento: str) - controlla se il documento è presente

async def controlla_documento(self, documento: str) -> bool:

Parametri

  • documento: il codice hash del documento da controllare

Ritorno

  • bool - True se il documento è presente, False altrimenti

Eccezioni

  • classeviva.eccezioni.ErroreHTTP - eccezione generata in caso di errore HTTP

  • await self.assenze() - ottieni gli eventi in cui l’utente ha fatto assenza 7

async def assenze(self) -> list[dict[str, Any]]:

Ritorno

  • list[dict[str, Any]] - gli eventi in cui l’utente ha fatto assenza in formato JSON 7

Eccezioni

  • classeviva.eccezioni.ErroreHTTP - eccezione generata in caso di errore HTTP

  • await self.assenze_da(inizio: str=None) - ottieni gli eventi in cui l’utente ha fatto assenza a partire da una certa data

async def assenze_da(self, evento: str) -> list[dict[str, Any]]:

Parametri

  • inizio: str: data di inizio dell’evento da cui partire, in formato YYYY-MM-DD

Ritorno

  • list[dict[str, Any]] - gli eventi in cui l’utente ha fatto assenza in formato JSON

Eccezioni

  • classeviva.eccezioni.FormatoNonValido - il formato della data non è valido

  • classeviva.eccezioni.DataFuoriGamma - la data non appartiene all’anno scolastico corrente

  • classeviva.eccezioni.ErroreHTTP - eccezione generata in caso di errore HTTP

  • await self.assenze_da_a(inizio: str=None, fine: str=None) - ottieni gli eventi compresi tra due date in cui l’utente ha fatto assenza

async def assenze_da_a(self, inizio: str=None, fine: str=None) -> list[dict[str, Any]]:

Parametri

  • inizio: str: data di inizio degli eventi da cui partire, in formato YYYY-MM-DD

  • fine: str: data di fine degli eventi fino a cui partire, in formato YYYY-MM-DD

Ritorno

  • list[dict[str, Any]] - gli eventi in cui l’utente ha fatto assenza

Eccezioni

  • classeviva.eccezioni.FormatoNonValido - il formato della data non è valido

  • classeviva.eccezioni.DataFuoriGamma - la data non appartiene all’anno scolastico corrente, oppure la data di fine è precedente alla data di inizio

  • classeviva.eccezioni.ErroreHTTP - eccezione generata in caso di errore HTTP

  • await self.agenda_da_a(inizio: str, fine: str) - ottieni gli eventi che compongono l’agenda dell’utente

async def agenda_da_a(self, inizio: str=None, fine: str=None) -> list[dict[str, Any]]:

Parametri

  • inizio: str: data di inizio degli eventi da cui partire, in formato YYYY-MM-DD

  • fine: str: data di fine degli eventi fino a cui restituirli, in formato YYYY-MM-DD

Ritorno

  • list[dict[str, Any]] - gli eventi dell’argenda nel periodo di tempo specificato

Eccezioni

  • classeviva.eccezioni.FormatoNonValido - il formato della data non è valido

  • classeviva.eccezioni.DataFuoriGamma - la data non appartiene all’anno scolastico corrente, oppure la data di fine è precedente alla data di inizio

  • classeviva.eccezioni.ErroreHTTP404 - eccezione generata in caso di errore HTTP 404

  • classeviva.eccezioni.ErroreHTTP - eccezione generata in caso di errore HTTP di altro tipo

  • await self.agenda_codice_da_a(codice: str, inizio: str, fine: str) - ottieni gli eventi dell’utente con un determinato codice evento

async def agenda_codice_da_a(self, codice: str, inizio: str=None, fine: str=None) -> list[dict[str, Any]]:

Parametri

  • codice: str: codice evento sulla base del quale filtrare gli eventi

  • inizio: str: data di inizio degli eventi da cui partire, in formato YYYY-MM-DD

  • fine: str: data di fine degli eventi fino a cui restituirli, in formato YYYY-MM-DD

Ritorno

  • list[dict[str, Any]] - gli eventi dell’argenda nel periodo di tempo specificato che hanno il codice evento specificato

Eccezioni

  • classeviva.eccezioni.FormatoNonValido - il formato della data non è valido

  • classeviva.eccezioni.DataFuoriGamma - la data non appartiene all’anno scolastico corrente, oppure la data di fine è precedente alla data di inizio

  • classeviva.eccezioni.ErroreHTTP404 - eccezione generata in caso di errore HTTP 404

  • classeviva.eccezioni.ErroreHTTP - eccezione generata in caso di errore HTTP di altro tipo

  • await self.agenda() - ottieni gli eventi dell’utente nell’anno scolastico corrente

async def agenda(self) -> list[dict[str, Any]]:

Ritorno

  • list[dict[str, Any]] - gli eventi dell’agenda nell’anno scolastico corrente

Eccezioni

  • classeviva.eccezioni.FormatoNonValido - il formato della data non è valido

  • classeviva.eccezioni.DataFuoriGamma - la data non appartiene all’anno scolastico corrente, oppure la data di fine è precedente alla data di inizio

  • classeviva.eccezioni.ErroreHTTP404 - eccezione generata in caso di errore HTTP 404

  • classeviva.eccezioni.ErroreHTTP - eccezione generata in caso di errore HTTP di altro tipo

  • await self.didattica() - ottieni il materiale in didattica dell’anno scolastico corrente

async def didattica(self) -> list[dict[str, Any]]:

Ritorno

  • list[dict[str, Any]] - il materiale in didattica dell’anno scolastico corrente 19

Eccezioni

  • classeviva.eccezioni.ErroreHTTP - eccezione sollevata in caso di errore HTTP

  • await self.didattica_elemento(contenuto: int) - ottieni un contenuto dal materiale in didattica

async def didattica_elemento(self, contenuto: int) -> Any:

Parametri

  • contenuto: int: codice del contenuto da ottenere

Ritorno

  • Any - il contenuto richiesto

Avvertenze

  • L’endpoint restituisce lo stesso contenuto di didattica()

Eccezioni

  • classeviva.eccezioni.ErroreHTTP - eccezione sollevata in caso di errore HTTP

  • await self.bacheca() - ottieni il materiale in bacheca

async def bacheca(self) -> list[dict[str, str | bool | dict[str, str | int]]]:

Ritorno

  • list[dict[str, str | bool | dict[str, str | int]]] - il materiale in bacheca

Eccezioni

  • classeviva.eccezioni.ErroreHTTP - eccezione sollevata in caso di errore HTTP

  • await self.bacheca_leggi(contenuto: int) - ottieni un contenuto dal materiale in bacheca

async def bacheca_leggi(self, codice: int, id_: int) -> dict[str, dict[str, Any]]:

Parametri

  • codice: int: codice dell’evento (alla voce evtCode)

  • id_: int: id del contenuto da ottenere (alla voce pubId)

Ritorno

  • dict[str, dict[str, Any]] - il contenuto richiesto

Eccezioni

  • classeviva.eccezioni.ErroreHTTP - eccezione sollevata in caso di errore HTTP

  • await self.bacheca_allega(codice: int, id_: int) - ottieni un allegato

async def bacheca_allega(self, codice: int, id_: int) -> bytes:

Parametri

  • codice: int: codice dell’evento (alla voce evtCode)

  • id_: int: id del contenuto da ottenere (alla voce pubId)

Ritorno

  • bytes - il contenuto richiesto in formato binario

Eccezioni

  • classeviva.eccezioni.ErroreHTTP - eccezione sollevata in caso di errore HTTP

Alias

  • bacheca_allegato - alias per bacheca_allega

  • await self.lezioni() - ottieni tutte le lezioni dell’anno

async def lezioni(self) -> list[dict[str, Any]]:

Avvertenze

  • L’endpoint restituisce {"lessons": []} in ogni caso

  • await self.lezioni_giorno(giorno: str) - ottieni le lezioni del giorno

async def lezioni_giorno(self, giorno: str=None) -> Any:

Parametri

  • giorno: str: giorno di cui si richiede la lezione, in formato YYYY-MM-DD

Ritorno

  • list[dict[str, Any]] - le lezioni del giorno richiesto 20

Eccezioni

  • classeviva.eccezioni.FormatoNonValido - il formato della data non è valido

  • classeviva.eccezioni.DataFuoriGamma - la data non appartiene all’anno scolastico corrente, oppure la data di fine è precedente alla data di inizio

  • classeviva.eccezioni.ErroreHTTP - eccezione sollevata in caso di errore HTTP

  • await self.lezioni_da_a(inizio: str, fine: str) - ottieni le lezioni in un range di date

async def lezioni_da_a(self, inizio: str, fine: str) -> list[dict[str, Any]]:

Parametri

  • inizio: str: data di inizio, in formato YYYY-MM-DD

  • fine: str: data di fine, in formato YYYY-MM-DD

Ritorno

  • list[dict[str, Any]] - le lezioni del range richiesto 20

Eccezioni

  • classeviva.eccezioni.FormatoNonValido - il formato della data non è valido

  • classeviva.eccezioni.DataFuoriGamma - la data non appartiene all’anno scolastico corrente, oppure la data di fine è precedente alla data di inizio

  • classeviva.eccezioni.ErroreHTTP - eccezione sollevata in caso di errore HTTP

  • await self.calendario() - ottieni il calendario 21

async def calendario(self) -> list[dict[str, str | int]]:

Ritorno

  • list[dict[str, str | int]] - il calendario 21

Eccezioni

  • classeviva.eccezioni.ErroreHTTP - eccezione sollevata in caso di errore HTTP

  • await self.libri() - ottieni i libri di testo adottati per l’anno scolastico corrente 22

async def libri(self) -> dict[str, int | str | dict[str, Any]]:

Ritorno

  • dict[str, int | str | dict[str, Any]] - i libri di testo adottati per l’anno scolastico corrente 22

Eccezioni

  • classeviva.eccezioni.ErroreHTTP - eccezione sollevata in caso di errore HTTP

  • await self.carta() - ottieni la carta dello studente 23

async def carta(self) -> dict[str, str | int]:

Ritorno

  • dict[str, str | int] - la carta dello studente 23

Eccezioni

  • classeviva.eccezioni.ErroreHTTP - eccezione sollevata in caso di errore HTTP

  • await self.voti() - ottieni le valutazioni dello studente 24

async def voti(self) -> list[dict[str, str | int | NoneType]]:

Ritorno

  • list[dict[str, str | int | NoneType]] - le valutazioni dello studente 24

Eccezioni

  • classeviva.eccezioni.ErroreHTTP - eccezione sollevata in caso di errore HTTP

  • await self.periodi() - ottieni la suddivisione in periodi dell’anno 25

async def periodi(self) -> list[dict[str, str | int | bool | NoneType]]:

Ritorno

  • list[dict[str, str | int | bool | NoneType]] - la suddivisione in periodi dell’anno 25

Eccezioni

  • classeviva.eccezioni.ErroreHTTP - eccezione sollevata in caso di errore HTTP

  • await self.materie() - ottieni le materie e gli insegnanti 26

async def materie(self) -> list[dict[str, str | int | list[dict[str, str]]]]:

Ritorno

  • list[dict[str, str | int | list[dict[str, str]]]] - le materie e gli insegnanti 26

Eccezioni

  • classeviva.eccezioni.ErroreHTTP - eccezione sollevata in caso di errore HTTP

  • await self.note() - ottieni le note dell’anno scolastico corrente 27

async def note(self) -> dict[str, list[dict[str, str | int | bool]]]:

Ritorno

  • dict[str, list[dict[str, str | int | bool]]] - le note dell’anno scolastico corrente 27

Eccezioni

  • classeviva.eccezioni.ErroreHTTP - eccezione sollevata in caso di errore HTTP

  • await self.leggi_nota(tipo: str, id_: int) - leggi la nota data categoria e ID 28

async def leggi_nota(self, tipo: str, id_: int) -> str:

Parametri

  • tipo: str: categoria della nota 29

  • id_: int: ID della nota 30

Ritorno

  • str - il testo della nota

Eccezioni

  • classeviva.eccezioni.ParametroNonValido - se il campo id_ non combacia con nessuna nota

  • classeviva.eccezioni.CategoriaNonPresente - se il campo tipo non combacia con nessuna categoria

  • classeviva.eccezioni.ErroreHTTP - eccezione sollevata in caso di errore HTTP di diversa natura

Metodi magici 11

  • self.__call__() | self() - connette in modo sincrono l’utente

def __call__(self) -> None:
    asyncio.run(self.accedi())
  • self.__eq__() - gestisce le uguaglianze

def __eq__(self, other) -> bool:
    if (isinstance(other, Utente)):
        return (self.id == other.id and self.password == other.password)
    return False

Decoratori

  • @classeviva.Utente.connettente - passa l’utente alla funzione come primo parametro dopo aver chiamato il metodo accedi()

@utente_.connettente
def foo(x: classeviva.Utente) -> None:
    print(x.dati)

Avvertenze

  • Non funziona con le funzioni asincrone (async def) 8

ListaUtenti

Un’espansione di un set di classeviva.Utente, con metodi utili a eliminare duplicati e ad eseguire in modo asincrono i metodi iterando sugli utenti.

Classe

class ListaUtenti(set[Utente])

Costruttore

def __init__(
    self,
    utenti: Iterable[Utente]
) -> None:

Parametri:

  • utenti: Iterable[Utente] - iterabile contenente 9 oggetti di tipo classeviva.Utente

Proprietà

  • connessi: set[Utente] - elenco degli alunni connessi 10 della lista

@property
def connessi(self) -> set[Utente]:
    return {utente for utente in self if (utente.connesso)}
  • non_connessi: set[Utente] - elenco degli alunni non connessi 10 della lista

@property
def non_connessi(self) -> set[Utente]:
    return {utente for utente in self if (not utente.connesso)}

Metodi

  • await self.accedi() - effettua l’accesso alla sessione 6 per tutti gli utenti

async def accedi(self) -> None:
    await asyncio.gather(*[utente.accedi() for utente in self.non_connessi])
  • self.aggiungi(utente) - aggiunge un utente alla lista

def aggiungi(self, utente: Utente) -> bool:
    if (isinstance(utente, Utente) and utente not in self):
        self.add(utente)
        return True
    return False

Parametri

  • utente: Utente: l’utente da aggiungere

Ritorno

  • bool - True se l’utente è stato aggiunto, False altrimenti

Avvertenze

  • Utilizza il metodo add() della classe set da cui eredita, potrebbe sollevare delle eccezioni non gestite dal programma

Metodi magici 11

  • self.__call__() | self() - connette in modo sincrono tutti gli utenti

def __call__(self) -> None:
    asyncio.run(self.accedi())
  • self.__add__() - gestisce le addizioni (+, +=)

def __add__(self, oggetto) -> ListaUtenti:
    if (isinstance(oggetto, Utente)):
        self.aggiungi(oggetto)
    elif (isinstance(oggetto, IterableABC)):
        for oggetto_ in oggetto:
            self.aggiungi(oggetto_)
    else:
        raise TypeError(f"{oggetto} non è un oggetto valido")
  • self.__contains__() - stabilisce se un utente è presente nella lista

def __contains__(self, utente: Utente) -> bool:
    if (isinstance(utente, Utente)):
        for utentino in self:
            if (utente == utentino):
                return True
    return False

Decoratori

  • @classeviva.ListaUtenti.iterante - ripete le operazioni della funzione decorata su tutti i membri della lista quando viene chiamata

@lista_utenti.iterante
def foo(x: classeviva.ListaUtenti) -> None:
    print(x.connessi)

classeviva.collegamenti 13

classeviva.collegamenti è il modulo che contiene gli URL per le richieste all’API di ClasseViva. 14

Collegamenti

La classe classeviva.collegamenti.Collegamenti contiene gli URL per le richieste all’API di ClasseViva 15

L’intero codice del modulo è riportato qui, perché breve ed esemplificativo di sé stesso.

class Collegamenti:
    base: str = "https://web.spaggiari.eu/rest"
    accesso: str = f"{base}/v1/auth/login"
    stato: str = f"{base}/v1/auth/status"
    biglietto: str = f"{base}/v1/auth/ticket"
    documenti: str = f"{base}/v1/students/{{}}/documents"
    controllo_documento: str = f"{base}/v1/students/{{}}/documents/check/{{}}"
    leggi_documento: str = f"{base}/v1/students/{{}}/documents/read/{{}}"
    assenze: str = f"{base}/v1/students/{{}}/absences/details"

classeviva.eccezioni

classeviva.eccezioni è il modulo che contiene le eccezioni sollevate da funzioni e metodi contenuti in classeviva

TokenErrore

Rappresenta tutti gli errori legati al token di accesso all’API

class TokenErrore(Exception):
    ...

Sottoclassi

  • classeviva.eccezioni.TokenNonValido - il token non è riconosciuto come valido dall’API

class TokenNonValido(TokenErrore):
    ...
  • classeviva.eccezioni.TokenScaduto - il token è scaduto

class TokenScaduto(TokenErrore):
    ...
  • classeviva.eccezioni.TokenNonPresente - il token non è presente, ovvero non è stato effettuato l’accesso

class TokenNonPresente(TokenErrore):
    ...

UtenteErrore

Rappresenta tutti gli errori legati all’utente e in particolare alla compilazione dei suoi campi obbligatori

class UtenteErrore(Exception):
    """
    Errori legati alle utenze
    """

Sottoclassi

  • classeviva.eccezioni.PasswordNonValida - la password non combacia, l’API non ha potuto accettarla 16

class PasswordNonValida(UtenteErrore):
    ...

NonAccesso

Rappresenta tutti gli errori probabilmente dovuti ad un mancato accesso, e che non rientrano in un’altra categoria 17

class NonAccesso(Exception):
    """
    Errori dovuti a un mancato accesso
    """

Sottoclassi

  • classeviva.eccezioni.SenzaDati - l’utente non ha tra i suoi attributi privati quelli dati dall’accesso

class SenzaDati(NonAccesso):
    ...

ErroreHTTP

Rappresenta tutti gli errori HTTP provenienti dalle richieste fatte col modulo requests

class ErroreHTTP(Exception):
    ...

Fornisce tutte le informazioni date dalla risposta di requests 18

raise e.ErroreHTTP(f"""
        Richiesta non corretta, codice {response.status_code}
        {response.text}
        {response.json()}
    """)

Sottoclassi

  • classeviva.eccezioni.ErroreHTTP404 - la richiesta ha restituito un errore 404

class ErroreHTTP404(ErroreHTTP):
    ...

ValoreNonValido

Rappresenta tutti gli errori dovuti a valori forniti all’API non validi

class ValoreNonValido(Exception):
    """
    Errori legati ai valori
    """

Sottoclassi

  • classeviva.eccezioni.ParametroNonValido

class ParametroNonValido(ValoreNonValido):
    """
    Errori legati ai parametri
    Sollevati quando l'URI esiste ma i parametri forniti causano un errore
    """
  • classeviva.eccezioni.CategoriaNonPresente

class CategoriaNonPresente(ValoreNonValido):
    """
    Errori legati alle categorie
    Sollevati quando l'URI non esiste perché un sotto-endpoint non viene trovato
    """

Funzioni

Funzioni utilizzate per sollevare eccezioni mirate

  • sollevaErroreHTTP(response: Response)

Solleva un’eccezione di tipo classeviva.eccezioni.ErroreHTTP, e lo fa aggiungendo tutte le informazioni ottenute dalla risposta dell’API, e scegliendo il tipo di eccezione a seconda del tipo di errore

classeviva.variabili

classeviva.variabili è il modulo che contiene le costanti utili per evitare ridondanza nel codice

L’intero codice del modulo è riportato qui, perché breve ed esemplificativo di sé stesso.

# Constante che indica il tempo di connessione per una sessione
TEMPO_CONNESSIONE: int = 1800


# Constante che indica l'intestazione per le richieste
intestazione: dict[str, str] = {
    "content-type": "application/json",
    "Z-Dev-ApiKey": "+zorro+",
    "User-Agent": "zorro/1.0"
}

Note

JSON

Per «formato JSON» si intende il formato restituito dall”API, che non corrisponde con il valore di ritorno della funzione che, utilizzando il modulo json, converte i dati in oggetti di Python

1

Studente, in Classeviva, è un utente il cui identificatore inizia con il carattere “S”

2

Biglietto, in Classeviva, è una stringa di caratteri, ma non si è ancora capito a cosa serva

3

Richiesta di stato

4

Sezione «schoolReport» della risposta alla richiesta di documenti

5(1,2)

Sezione «documents» della risposta alla richiesta di documenti

6(1,2)

Richiesta di accesso

7(1,2)

Richiesta di assenze

8

Alla versione 0.1.0, ma è un miglioramento che verrà aggiunto in futuro

9

Non è necessario che contenga soltanto oggetti di quel tipo, grazie al metodo privato __riduci

10(1,2)

Vengono verificati tramite la loro proprietà Utente.connesso

11(1,2)

Sono riportati i metodi magici la cui sovrascrittura è rilevante ai fini dell’utilizzo del modulo, gli altri possno essere trovati nel codice sorgente

12

Il metodo __call__ è un metodo magico, che viene chiamato quando si fa utente()

13

Il modulo, alla versione 0.1.0, è comprensivo di un solo namespace contenente URL

14

Il suo utilizzo è volto alla fase di sviluppo, ma può essere adoperato anche in fase di produzione in caso di necessità

15

Per ogni versione sono disponibili soltanto gli URL per le richieste le cui rispettive funzioni sono già implementate

16

L’API lo comunica tramite una risposta HTTP con codice 422

17

Ne è un esempio TokenNonPresente, che pur rientrando nella descrizione di NonAccesso non ne è sottoclasse perché già parte di TokenErrore

18

Alla versione 0.1.0 va fatto manualmente sollevando l’eccezione come descritto sotto

19

La struttura dei dizionari contenuti nella lista è complessa, può essere trovata qui

20(1,2)

Si veda la documentazione

21(1,2)

Si veda la documentazione

22(1,2)

Si veda la documentazione

23(1,2)

Si veda la documentazione

24(1,2)

Si veda la documentazione

25(1,2)

Si veda la documentazione

26(1,2)

Si veda la documentazione

27(1,2)

Si veda la documentazione

28

Si veda la documentazione

29

Le categorie sono «NTTE», «NTCL», «NTWN» e «NTST». I significati delle sigle non sono ancora chiari

30

L’ID si trova alla voce «evtId» di ogni dizionario contenuto nella lista di dizionari restituita dalla richiesta di note