Script bash pour prendre soin de ses contacts

Salut,

Je me suis dit aujourd’hui que l’idée de mon script pourrait être intégrée à wot-wizard. Une catégorie là-dessus, un peu comme la section « explorateur de toile de confiance ». Ou ça pourrait être intégré à cette section.

Ce que j’apprécie beaucoup avec wot-wizard est que c’est léger, on consomme très peu de données pour le consulter (et avec mon petit forfait free à 2€ c’est bien pratique, termux + w3m!)

J’ai testé le calculateur de distance et de qualité, j’ai pas tout compris (notamment la partie « nouveaux certificateurs » comment s’en servir).
Très intéressant, et utile. J’avais pensé aussi qu’il pouvait servir pour simuler la certification d’un nouveau membre (est-ce qu’il passera la règle de distance ou pas).

Pour le reste de wot-wizard, j’imagine qu’il est prévu pour être utilisé par des logiciels qui mettent en forme les données?
Je ne comprends pas toutes les sections, il faudrait que quelqu’un m’explique vraiment tout ça!

L’équivalent de g1monit ( Fichier ) est bien pratique.

Est-ce que tu pourrais résumer ce que fait ton script ? J’ai essayé sur ma clé publique et j’obtiens une liste de gens que je connais bien, et d’autres que je ne connais pas.
Sinon, je suis tout à fait d’accord pour intégrer ce genre de recherche.

C’est exactement ça. En mettant des pseudos de membres dans le champ “Nouveaux certificateurs”, tu obtiens (après clic sur OK) l’effet qu’auraient les certifications de ces membres sur la distance ou la qualité de l’identité considérée, ainsi qu’une liste de certificateurs supplémentaires avec l’effet qu’ils auraient, effets classés par ordre décroissant. Dans le cas où l’identité considérée est un nouveau venu, on peut laisser son champ vide.

Ce que tu vois à l’écran n’est que l’affichage du client WotWizard (WW), qui fait déjà un peu de mise en forme. Si tu veux améliorer celle-ci, il vaut mieux partir directement du serveur WotWizard. Celui-ci a une interface graphQL en entrée et une sortie en JSON. Tu peux lire le manuel de WotWizard (pour la dernière version officielle) ici. Pour des raisons de sécurité, cgeek n’autorise pas l’accès au serveur WW de wot-wizard.duniter.org. Il faudrait regarder si tu peux y avoir accès, au moins en privé sur le site wotwizard.coinduf.eu (voir avec @HugoTrentesaux).

@gerard94 Alors mon script va récupérer les infos sur wot-wizard.duniter.org (il pourrait en récupérer d’autres et les mettre en forme, mais j’ai pas tout compris dans wot-wizard!), celles qui sont nécessaires pour prévenir nos contacts (certifiés et certificateurs) et en prendre soin:

  • la « qualité » de membre de nos contacts; comme ça si parmi eux on a des gens qui veulent développer la Ğ1 et approchent des 80% on peut les prévenir ou les conseiller
  • les certifications en cours des contacts, comme ça on peut prévenir nos contacts si ils certifient trop de nouveaux en avance (là dans mon script c’est pas très lisible)
  • les dates limites des adhésions non-renouvelées, pour « repêcher »
  • les dates limites des adhésions, pour les prévenir avant DeathReaper
  • les dates limites des certifications, aussi pour les prévenir avant DeathReaper

On pourrait rajouter d’autres choses, comme la disponibilité de la prochaine certif, ou d’autres.

Je viens de comprendre comment faire avec « Nouveaux certificateurs ». Super!

Je ne maîtrise pas bien JSON, mais je vais lire le manuel!

Un fichier JSON contient un objet javascript (des datas sous forme de clé/valeur) facilement utilisable par tous les langages de programmation (PHP, Python, Java, javascript, etc.) car y’a toujours une fonction pour importer un JSON dans tableau ou un objet par ex. La valeur de chaque clé peut être un number, une string, un booléen, un tableau ou même un autre objet JSON (ou éventuellement NULL).

{ "nom": "Dupont",
  "prenom": "Jean",
  "isEmployed": true,
  "adresse": NULL,
  "age": 32,
  "telephone": [ { "mobile": "0612345678" },
                 { "fax": "0312345678" } ]
}

Tu peux aussi avoir la syntaxe sous forme de tableau d’objets :

[{ "prenom":"prenom1", "nom":"nom1" },
 { "prenom":"prenom2" , "nom":"nom2" },
 { "prenom":"prenom3" , "nom":"nom3" }]

Tu trouveras une description graphique simple et complète de la grammaire JSON ici.

OK, mais qui considères-tu être tes contacts ? Ceux que tu as certifiés, ceux qui t’ont certifié, d’autres personnes ?
Ton script semble filtrer les données de WotWizard autour d’un groupe particulier. C’est un peu ce que fait déjà WotWizard dans sa dernière version (à part le deuxième point que tu cites). Ces cas d’usage m’intéressent. Est-ce que tu en as d’autres en vue ?
En tous cas, belle initiative.

En fait WotWizard (partie wwServer) expose une API GraphQL qui permettrait de construire un client alternatif à l’existant (partie wwClient) avec une interface axée sur l’aspect intuitif et pratique.

J’avais tenté de mettre en place un playground GraphQL (en ce moment sur https://ww2.coinduf.eu/) ce qui pourrait faciliter le développement (de manière analogue à https://g1.librelois.fr/gva/playground) mais je ne m’y connais pas assez et WotWizard, bien que parfaitement conforme aux spécifications GraphQL était à côté des conventions implicites, ce qui rendait plus difficile de brancher des outils reposant sur ces conventions implicites.

Je suis près à te former et t’accompagner pour faire une interface graphique, et à te fournir un serveur de test et de production. J’ai déjà fait quelques mini prototypes dont je parle sur le sujet Mes contributions à la Ğ1 (HugoTrentesaux 2021-2022). Quand serais-tu dispo pour des sessions de formation de ~2h (en soirée ou le weekend par exemple) ?

Je considérai comme contacts juste ceux que j’ai certifié et qui m’ont certifié.
Il est vrai que j’ai aussi prévenu parfois d’autres connaissances de la Ğ1.

Mon script filtre les données de WotWizard autour d’une clé publique (je fais la liste des contacts de cette identité avec silkaj).

En fait je voulais quelque chose qui me donne automatiquement la situation de mes contacts.

Une autre idée que j’avais est de faire quelque chose de récursif, donner (sous la forme d’un tableau par exemple) les résultats de mon script aussi pour les contacts de nos contacts. (en s’arrêtant peut-être à 2 pas!)

1 Like

Oui pourquoi pas, je pars de peu de connaissances (j’ai surtout fait des install linux, archlinux, et du coup un peu de bash mais pas beaucoup plus!).

Je suis dispo surtout les week-end, lundis, mardis, mercredis (je bosse à mi-temps, boulot physique et peu de dépenses dans mon orga).

1 Like

je prends la discussion en cours… @hypericum je cherche à monter une interface pour visualiser mon « metavers », c’est à dire le réseau d’amis que j’ai dans la June.
Je me rends compte que certains sont membres, d’autres pas… @Gullande par exemple.

Serait il possible d’étendre ce script pour extraire des données de gchange également?

Hier soir avec hypericum, nous avons :

Je devrais réussir à publier la vidéo avant noël et ça pourra servir de base pour créer une petite visualisation du « metavers », comme tu dis.

4 Likes

Justement ça m’aurait intéressé de participer :slight_smile: Avec @gerard94 on est en train de voir pour refaire l’UI de WotWizard. Et je me demandais si y’avais pas moyen de tout faire en VueJS avec des requêtes graphQL. Je vais faire une visio mardi matin avec @ManUtopiK . On pourra en parler. Pour l’instant, je fais des maquettes from scratch, au marteau et au burin (HTML/CSS/vanillaJS) :stuck_out_tongue: qu’on essaiera d’intégrer à l’application en Go dans des fichiers de template.

2 Likes

Euh ben je suis pas contre, mais je dois apprendre!

Là ce que je vais commencer à faire, c’est modifier le script existant « au minimum », en changeant toutes les requêtes wget par des requêtes GraphQL comme me l’a expliqué @HugoTrentesaux

Ça me prendra un peu de temps, je pourrai tester des trucs.
Puis je pourrais continuer à améliorer, en vue de pouvoir l’utiliser sur un site web.
Mon rythme va être lent, mais je me suis dit que ça vaut le coup d’apprendre à me servir de tout ça.

1 Like

Je te rassure : moi aussi :stuck_out_tongue:
J’ai plutôt l’habitude des vieilles technos. Alors GraphQL, NodeJS et tout ça, j’ai jamais bossé avec. Je commence juste à apprendre la théorie :slight_smile:

Si, carrément, j’ai d’ailleurs fait une preuve de concept ici : https://wwtmp.coinduf.eu/app.html

C’est une app minimale en VueJS qui fait des requêtes GraphQL à WotWizard.

J’ai d’ailleurs repris cette poc pour ajouter des requêtes Cesium+ http://datajune.coinduf.eu/wotexplorer/

C’est quasiment la même app VueJS, mais ré-écrite un peu différemment.

On se fait une visio quand tu veux (je suis libre ce WE normalement) si tu as besoin d’aide pour prendre les choses en main.

1 Like

On vient de faire une visio avec @Paidge pour regarder comment intégrer des requêtes GraphQL WotWizard à une appli VueJS. Avec @ManUtopiK ils vont voir comment intégrer d3js ou chartsjs pour les graphiques. @gerard94, il faudrait qu’on fasse un fil sur le forum avec des exemples de requêtes WotWizard pour aider à le prendre en main.

2 Likes

Je peux déjà vous mettre toutes les requêtes qu’utilise le client WotWizard actuel.

1 Like
# Dont forget to RTFM (Help/manual.en.pdf) !!! and, above all, page 3.

# All certifications sorted by receivers ($to = true) or by senders ($to = false). Very big. Use with care.
query Certifications ($to: Boolean!, $start: String, $end: String) {
	now {
		number
		bct
	}
	identities(status_list: MEMBER, start: $start, end: $end) {
		uid
		sent_certifications @skip(if: $to) {
			other: to {
				uid
			}
			registration: block {
				bct
			}
			limit: expires_on
		}
		received_certifications @include(if: $to) {
			certifications {
				other: from {
					uid
				}
				registration: block {
					bct
				}
				limit: expires_on
			}
		}
	}
}

# What time is it?
query Now {
	now {
		number
		bct
	}
}

# Calculation of 'uid's distance when she is certified by the extra certifiers 'certs' and list of next best certifiers, chosen in 'group' and limited to 'ansNb' results.
query CalculateDist ($group: [String!], $uid: String, $certs: [String!], $ansNb: Int) {
	now {
		number
		bct
	}
	valD: calcDist(uid: $uid, certifiers: $certs) {
		value {
			ratio
		}
		ok: dist_ok
	}
	list: bestDist(group: $group, uid:$uid, certifiers: $certs, answerNb: $ansNb) {
		id {
			uid
		}
		valD: dist {
			value {
				ratio
			}
		}
	}
}

# Idem for quality instead of distance.
query CalculateQual ($group: [String!], $uid: String, $certs: [String!], $ansNb: Int) {
	now {
		number
		bct
	}
	val: calcQual(uid: $uid, certifiers: $certs) {
		ratio
	}
	list: bestQual(group: $group, uid:$uid, certifiers: $certs, answerNb: $ansNb) {
		id {
			uid
		}
		val: qual {
			ratio
		}
	}
}
 
# Limit dates of availability of memberships.
query LimitsMem ($group: [String!]) {
	now {
		number
		bct
	}
	identities: memEnds(group: $group) {
		uid
		limitDate
	}
}

# Limit dates before revocation.
query LimitsMissing ($group: [String!]) {
	now {
		number
		bct
	}
	identities: missEnds(group: $group) {
		uid
		limitDate
	}
}

# Limit dates of availability of the last five certifications.
query LimitsCerts ($group: [String!]) {
	now {
		number
		bct
	}
	datedIdentities: certEnds(group: $group) {
		id {
			uid
			status
		}
		limitDate: date
	}
}

# All identities sorted by uid. Very big. Use with care.
query Identities ($status: Identity_Status!) {
	now {
		number
		bct
	}
	identities(status_list: [$status]) {
		uid
		pubkey
		hash
		block: id_written_block {
			bct
		}
		limitDate
	}
}

# Find the hashes all identities with their uid or public key beginning by 'hint' and whose status is in 'statuses'.
query IdSearchFind ($hint: String, $statuses:  [Identity_Status!]) {
	now {
		number
		bct
	}
	idSearch (with: {hint: $hint, status_list: $statuses}) {
		revokedNb
		missingNb
		memberNb
		newcomerNb
		ids {
			uid
			status
			hash
		}
	}
}

# Find all informations about the identity whose hash is 'hash'.
query IdSearchFix ($hash: Hash!, $dispDist: Boolean = false, $dispQual: Boolean = false, $dispCentr: Boolean = false) {
	now {
		number
		bct
	}
	idFromHash (hash: $hash) {
		hash
		uid
		pubkey
		id_written_block {
			number
			bct
		}
		lastApplication {
			number
			bct
		}
		limitDate
		status
		sentry
		membership_pending
		membership_pending_limitDate
		minDate
		minDatePassed
		history {
			in
			block {
				number
				bct
			}
		}
		received_certifications {
			certifications {
				from {
					uid
				}
				expires_on
				pending
			}
			limit
		}
		sent_certifications {
			to {
				uid
			}
			expires_on
			pending
		}
		all_certifiers {
			uid
		}
		all_certified {
			uid
		}
		all_certifiersIO {
			id {
				uid
			}
			hist {
				in
				block {
					number
					bct
				}
			}
		}
		all_certifiedIO {
			id {
				uid
			}
			hist {
				in
				block {
					number
					bct
				}
			}
		}
		distance @include(if: $dispDist) {
			value {
				num
				denom
				ratio
			}
			dist_ok
		}
		distanceE @include(if: $dispDist) {
			value {
				num
				denom
				ratio
			}
			dist_ok
		}
		quality @include(if: $dispQual) {
			num
			denom
			ratio
		}
		qualityE @include(if: $dispQual) {
			num
			denom
			ratio
		}
		centrality @include(if: $dispCentr)
	}
}

# Real time of the last block.
query CountMax {
	countMax {
		utc0
	}
}

# History of members entering or exiting the wot.
query MembersCount ($start: Int64, $end: Int64, $text: Boolean! = true) {
	now {
		number
		bct
	}
	events: membersCount(start: $start, end: $end) {
		block {
			number @include(if: $text)
			utc0
			bct @include(if: $text)
		}
		idList @include(if: $text) {
			in: inOut
			id {
				uid
			}
		}
		number
	}
}

# Parameters of the money.
query AllParameters {
	allParameters {
		name
		par_type
		comment
		value
	}
}

# Dispatch 'group' between 'selected' (members), 'others', 'unknown' and 'duplicate'.
query Group ($group: [String!]!) {
	filterGroup (group: $group, status_list: MEMBER) {
		selected
		others {
			... dispPath
		}
		unknown {
			... dispPath
		}
		duplicate {
			... dispPath
		}
	}
}
fragment dispPath on Error {
	uid: mes
	path {
		... on Field {
			name
		}
		... on Rank {
			index
		}
	}
}

# List all distances in 'group', or in wot if 'group' is absent or null.
query Distances ($group: [String!]) {
	now {
		number
		bct
	}
	identities(group: $group, status_list: MEMBER) {
		uid
		distance {
			value {
				num
				denom
				ratio
			}
		}
	}
}

# List all qualities in 'group', or in wot if 'group' is absent or null.
query Qualities ($group: [String!]) {
	now {
		number
		bct
	}
	identities(group: $group, status_list: MEMBER) {
		uid
		quality {
			num
			denom
			ratio
		}
	}
}

# List all degrees of centrality in 'group', or in wot if 'group' is absent or null.
query Centralities ($group: [String!]) {
	now {
		number
		bct
	}
	identities(group: $group, status_list: MEMBER) {
		uid
		centrality
	}
}

# List all sentries
query Sentries {
	now {
		number
		bct
	}
	sentryThreshold
	sentries {
		uid
	}
}

# Display of the Preparatory File.
query WWFile {
	now {
		number
		bct
	}
	parameter(name: sigQty) {
		sigQty:value
	}
	wwFile(full: true) {
		certifs_dossiers {
			... on MarkedDatedCertification {
				datedCertification {
					date
					certification {
						from {
							uid
						}
						to {
							uid
						}
						expires_on
					}
				}
			}
			... on MarkedDossier {
				dossier {
					main_certifs
					newcomer {
						uid
						lastApplication {
							lastAppDate: bct
						}
						distance: distanceE {
							value {
								ratio
							}
							dist_ok
						}
					}
					date
					minDate
					expires_on:limit
					certifications {
						date
						certification {
							from {
								uid
								quality {
									ratio
								}
							}
							expires_on
						}
					}
				}
			}
		}
	}
}

# Display of Permutations.
query WWPerms {
	now {
		number
		bct
	}
	wwResult {
		permutations {
			proba
			permutation {
				id {
					uid
				}
				date
				after
			}
		}
	}
}

# Subscription to the forecasts of the WW window.
subscription By {
	wwResult {
		now {
			number
			bct
		}
		computation_duration
		permutations_nb
		dossiers_nb
		certifs_nb
		forecastsByNames {
			id {
				uid
			}
			date
			after
			proba
		}
		forecastsByDates {
			id {
				uid
			}
			date
			after
			proba
		}
	}
}

# Subscription to the metadata of the WW window.
subscription Meta {
	wwFile(full: false) {
		now {
			number
			bct
		}
		certifs_dossiers {
			...on MarkedDatedCertification {
				datedCertification {
					date
					certification {
						from {
							uid
						}
						to {
							uid
						}
						expires_on
					}
				}
			}
			...on MarkedDossier {
				dossier {
					main_certifs
					newcomer {
						uid
						lastApplication {
							lastAppDate: bct
						}
						distance: distanceE {
							value {
								ratio
							}
						}
					}
					date
					minDate
					expires_on:limit
					certifications {
						date
						certification {
							from {
								uid
								quality {
									ratio
								}
							}
							expires_on
						}
					}
				}
			}
		}
	}
}
2 Likes

J’adore le nouvel utilitaire :

https://wot-wizard.duniter.org/23calculator

Vous pourriez peut-être l’expliquer un peu mieux dans l’aide pour qu’il n’y ait pas de confusion, je n’ai pas non plus compris comment cela fonctionnait au début.

Une question… comment appliquer ce paramètre ?
“Nombre maximal de propositions de certificateurs :”

Merci.

2 Likes

Oui ça me sera utile quand je vais la redévelopper pour wotwizard.netlify.app
J’ai compris qu’il fallait saisir les noms de son groupe local (ou pas) ainsi qu’une identité qui va devenir membre (ou pas) pour obtenir une liste de certificateurs potentiels et déterminer le taux de respect de la règle de distance ou la qualité obtenue. Mais tout n’est pas clair (en tous cas le champ « Nouveaux certificateurs »). Qu’est-ce que ça veut dire ça par exemple ?


https://wotwizard.netlify.app/ est superbe… pourriez-vous mettre i10n dessus pour le traduire en anglais/espagnol ?

Dans mon cas, cela m’a aidé à prévoir dans quelle mesure la qualité des liens d’une DÉJÀ membre (carmela dans ce cas) (vous devez écrire ce membre dans le champ que vous mentionnez, « Pseudo de l’identité considerée ») augmenterait s’il recevait de nouvelles certifications (que vous pouvez mettre dans le champ « Nouveaux Certificateurs »).

La qualité actuelle de « carmela » est de 76% et avec ces 4 nouvelles certifications, elle passerait à 79,39%, presque 80%