Gambas France BETA


Pas de compte ? Incription

Présentation de la classe Config, configuration de logiciels avec JSON

Ce sujet est résolu.

1
AuteurMessages
tincho#1 Posté le 28/2/2022 à 10:03:07
Bonjour les amis.
Je voudrais vous présenter une méthode pour gérer la configuration d'un logiciel, que je trouve intéressante.
En collaboration avec TercoIDE (gambas-es), nous avons préparé cet exemple dans lequel une classe contient tous les paramètres d'un logiciel et où il est possible d'en ajouter d'autres avec une grande flexibilité. Ensuite, dans n'importe quelle autre partie du programme, vous pouvez lire et écrire ces variables.
Enfin, il existe une méthode (Save) qui parcourt les symboles de la classe et les enregistre dans un fichier texte au format json pour une utilisation ultérieure en récupérant ces données avec la méthode "Load".
N'hésitez pas à donner votre avis, à faire des commentaires ou à améliorer ce programme.

Note : Il est nécessaire d'activer le composant gb.util.web

A bientôt.

Config.class
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
' Gambas class file

CREATE STATIC
EXPORT
PUBLIC AppDir AS STRING
PUBLIC Depot AS STRING
'Private Const ConfigFile As String = ".app/config.json"
''Configuration variables to be saved, add as needed below
PUBLIC CurrentColor AS INTEGER
PUBLIC OtherParameter1 AS STRING = "gambas-es.org"
PUBLIC OtherParameter2 AS STRING = "gambas.one"
PUBLIC OtherParameter3 AS STRING = "gambas-club.de"
PUBLIC OtherParameter4 AS STRING = "gambas-it.org"
PUBLIC OtherParameter5 AS STRING = "gambas-fr.org"

PUBLIC SUB Load(sFile AS STRING)

DIM cConfig AS Collection
DIM sSymbol AS STRING
DIM obj AS OBJECT = ME
DIM MyClass AS Class = Object.Class(obj)

IF Exist(sFile) THEN
cConfig = JSON.FromString(File.Load(sFile))
FOR EACH sSymbol IN myClass.Symbols
IF cConfig.Exist(sSymbol) THEN
Object.SetProperty(obj, sSymbol, cConfig[sSymbol])
ENDIF
NEXT
ENDIF

END

STATIC PUBLIC SUB Save(sFile AS STRING)

DIM cConfig AS NEW Collection
DIM obj AS OBJECT = ME
DIM MyClass AS Class = Object.Class(obj)
DIM Var AS STRING
DIM Valor AS VARIANT

FOR EACH Var IN myClass.Symbols
'' Verifying that it is a property or a variable.
IF (MyClass[var].kind = Class.Variable) OR (MyClass[var].kind = Class.Property) THEN
valor = Object.GetProperty(obj, var)
cConfig.Add(Valor, var)
END IF

NEXT

IF NOT Exist(File.Dir(sFile)) THEN
SHELL "mkdir -p " & File.Dir(sFile) WAIT
ENDIF
File.Save(sFile, JSON.Encode2(cConfig))

END

STATIC PUBLIC SUB Update(sTag AS STRING, vSet AS VARIANT)

DIM sSymbol AS STRING
DIM obj AS OBJECT = ME
DIM MyClass AS Class = Object.Class(obj)

FOR EACH sSymbol IN myClass.Symbols
IF sSymbol = sTag THEN
Object.SetProperty(obj, sSymbol, vSet)
BREAK
ENDIF
NEXT

END


Par exemple dans un formulaire...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
' Gambas class file

PUBLIC SUB Form_Open()

Config.AppDir = User.Home &/ ".config/jconfig"
Config.Depot = Config.AppDir &/ "config.json"
Config.Load(Config.Depot)
ColorButton1.Color = Config.CurrentColor

END

PUBLIC SUB bsave_Click()

Config.CurrentColor = ColorButton1.Color
Config.Save(Config.Depot)

END


Cette méthode étend la classe JSON et permet d'encoder le texte Json dans une forme plus lisible pour les humains. Pour l'utiliser vous devez créer une classe dans votre projet appelée JSON (avec des lettres majuscules) et ensuite mettre ce code (Encode2) prêt alors au lieu d'utiliser JSON.Encode dans vos projets utilisez JSON.Encode2 et vous avez terminé.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
' Gambas class file

EXPORT

'' Encode in JSON format in a human readable way. Based on a Laurent tool

STATIC PUBLIC FUNCTION Encode2(vData AS VARIANT) AS STRING

DIM sInput AS STRING
DIM sOutput AS STRING
DIM iStream AS Stream

DIM $sReadChar AS STRING
DIM $iTab AS INTEGER
DIM $bQuote, $bBracket AS BOOLEAN

sInput = JSON.Encode(vData)

iStream = OPEN STRING sInput FOR READ

WHILE (NOT Eof(iStream))
$sReadChar = READ #iStream, 1
IF ($sReadChar = "{" AND NOT $bQuote) THEN
$iTab += 1
$sReadChar &= "\n" & Space$($iTab * 2)
ELSE IF ($sReadChar = "}" AND NOT $bQuote) THEN
$iTab -= 1
$sReadChar = "\n" & Space$($iTab * 2) & $sReadChar
ELSE IF ($sReadChar = "\"") THEN
$bQuote = NOT $bQuote
ELSE IF ($sReadChar = "[") THEN
$bBracket = TRUE
ELSE IF ($sReadChar = "]") THEN
$bBracket = FALSE
ELSE IF ($sReadChar = ":" AND NOT $bQuote) THEN
$sReadChar &= " "
ELSE IF ($sReadChar = "," AND NOT $bQuote) THEN
IF (NOT $bBracket) THEN
$sReadChar &= "\n" & Space$($iTab * 2)
ELSE
$sReadChar &= " "
ENDIF
ENDIF
sOutput &= $sReadChar
WEND

CLOSE iStream
' replace null with ""
sOutput = Replace(sOutput, " null", " \"\"")

RETURN sOutput

END

spheris#2 Posté le 1/3/2022 à 07:19:28
tincho,
buenos dias,
le code ne fonctionne pas car dans la classe Config, dans la methode Save, la variable jconfig n'est pas reconnue car 'JSONCollection' n'est pas déclaré.
Peux-tu nous expliquer ce qu'est JSONCollection?

voici les sources du projet que tu as posté.


Tincho,
JSONCollection is not declared.
Here source code you posted
tincho#3 Posté le 1/3/2022 à 10:29:10

buenos dias

hehe, bonjour. :D


le code ne fonctionne pas car dans la classe Config, dans la methode Save, la variable jconfig n'est pas reconnue car 'JSONCollection' n'est pas déclaré.
Peux-tu nous expliquer ce qu'est JSONCollection?

JSONCOllection est une collection mais elle permet de conserver les éléments qui ont une valeur nulle ou zéro. Elle est plus lente que la collecte normale, et pour qu'elle fonctionne, le composant gb.util.web doit être chargé.

J'ai modifié le premier message pour le rendre plus clair.
Au fait, comment puis-je joindre un projet gambas au fil de discussion ?

tincho#4 Posté le 1/3/2022 à 12:39:43
ok, je me réponds moi-même hehe.
J'ai ajouté un projet d'exemple de l'utilisation de la claase, en utilisant l'exemple que vous avez proposé et j'y ai apporté quelques modifications.
Les variables "Single" n'ont pas fonctionné et je ne comprends pas pourquoi.
J'espère que vous le trouverez utile et que vous pourrez y jeter un coup d'œil.

https://gambas-fr.org/code-186-config.html
spheris#5 Posté le 1/3/2022 à 19:46:29
gracias,
Ton exemple fonctionne très bien.
il faut bien utiliser le composant gb.util.web.
Merci pour ces informations.
;)
valaquarus#6 Posté le 4/3/2022 à 14:02:19
-- Unus Ex Altera --Bonjour tincho, spheris et je n'oublie pas tous les autres,
juste une petite, toute petite modification à proposer :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
PUBLIC SUB Parameters_change()

DIM obj AS OBJECT = Config
DIM MyClass AS Class = Object.Class(obj)
DIM sTag AS STRING
DIM vSet AS VARIANT
DIM sProp AS STRING

IF bLoaded THEN
sTag = LAST.Tag
SELECT Object.Type(LAST)
CASE "ValueBox"
vSet = LAST.Value
CASE "TextBox"
vSet = LAST.Text
FOR EACH sProp IN MyClass.Symbols
IF sProp = sTag THEN
Config.Update(sTag, vSet)
ENDIF
NEXT

END SELECT

ENDIF

END

la valeur last.value ne prend pas en compte le texte donc pour pouvoir modifier la textbox j'ai ajouté cette ligne :
1
2
CASE "TextBox"
vSet = LAST.Text

ah que salut todos!
Système d'exploitation : KDE neon 6.0 ~ Version Gambas : 3.19.5
spheris#7 Posté le 5/3/2022 à 09:55:28
Exact !
Par contre entre nous, je préfère utiliser les fichiers markdown plutôt que du json.
Il semble que cela ne soit pas fait au début pour la même utilisation.
valaquarus#8 Posté le 5/3/2022 à 16:24:43
-- Unus Ex Altera --Bonjour à todos,
une question bête car j'ai utilisé tout type de variable avec l'exemple de Tincho et seul les single plantent.
Quelqu'un a une idée du pourquoi et du comment, c'est par besoin de culture car de toute façon je ne maîtrise en rien, json.
Philippe
Système d'exploitation : KDE neon 6.0 ~ Version Gambas : 3.19.5
jeanyvon#9 Posté le 6/3/2022 à 08:54:22
Gambas? Ma! Et gustoSalut tous
Je vais sans doute passer pour un nullard, mais, il me semble que le composant setting fait exactement la même chose en plus simple
Vieillir? On peut retarder mais pas y échapper!
tincho#10 Posté le 6/3/2022 à 18:26:02

juste une petite, toute petite modification à proposer :

Super, j'ai modifié le code, merci pour le commentaire
Martín.
tincho#11 Posté le 6/3/2022 à 18:40:28

Par contre entre nous, je préfère utiliser les fichiers markdown plutôt que du json. Il semble que cela ne soit pas fait au début pour la même utilisation.

Oui, json est un format d'échange de données alors que markdown est un langage de balisage.
Par conséquent, pour stocker et récupérer des données, il est pratique d'utiliser JSON et de créer un document Markdown.
Mais, comme toujours en programmation, il existe plusieurs façons d'obtenir des résultats similaires.
Martín.
tincho#12 Posté le 6/3/2022 à 19:15:35
Je vais sans doute passer pour un nullard, mais, il me semble que le composant setting fait exactement la même chose en plus simple

Oui, en effet, il fait la même chose et plus encore.
Pour ne citer que quelques exemples, si vous utilisez Settings, vous devez vous souvenir des noms de variables lorsque vous écrivez votre code, et si votre programme comporte plus de 10 variables, vous les oublierez probablement au bout d'un moment, alors qu'avec la classe Config, il vous suffit d'appuyer sur "."
Ensuite, Settings supprime complètement du fichier toutes les variables nulles, à valeur nulle, ainsi que les chaînes vides, ce qui n'est pas pratique lorsqu'il s'agit de programmes complexes où les variables doivent parfois avoir une valeur nulle ou des chaînes vides, ou encore gérer des listes ou des collections.
Un autre point en faveur de Config est qu'avec une petite routine, vous pouvez créer un formulaire pour modifier la configuration d'un programme de façon dynamique, et que vous n'avez pas besoin de toucher à autre chose si dans le futur vous ajoutez deux ou trois (ou 64) variables supplémentaires.
Hehe, désolé pour le fanatisme que j'ai pour cette classe.
Martín.
1