forked from axiom-team/g1-stats
Compare commits
37 Commits
python-bac
...
master
Author | SHA1 | Date |
---|---|---|
Jean-Jacques Brucker | ef23a0a66d | |
poka | ba0f91404c | |
poka | f18a98f563 | |
poka | c7ebb9d2b4 | |
poka | 4418e2f11d | |
poka | 69bfe6cea7 | |
poka | db37ea2f51 | |
poka | a282d6a0c6 | |
poka | c4d7cea7ba | |
poka | 1600461097 | |
poka | bd973e6f39 | |
poka | 12bfb02345 | |
poka | 8f085e0e52 | |
poka | bb00097c93 | |
poka | 4da8bae7fa | |
poka | cb43ebf132 | |
poka | e9a203ac26 | |
poka | 3332403604 | |
poka | 8bf72a01b4 | |
poka | dadf846f90 | |
poka | 99af53841e | |
poka | 20d8df72e7 | |
poka | 27abf57a44 | |
poka | 41dc74a545 | |
poka | a3bdf1011e | |
poka | 2125a33bfa | |
poka | 7b32e5fa10 | |
poka | e513ae477a | |
poka | 26d42e19e0 | |
poka | 4f18443702 | |
poka | 8c4618378f | |
poka | e04767d59d | |
poka | e7686377d2 | |
poka | eb86ae17a9 | |
poka | 7d9b71fa54 | |
poka | b2404ead75 | |
poka | a74b28a6cb |
|
@ -1,3 +1,4 @@
|
|||
DUNITER="https://duniter-g1.p2p.legal" # Adresse du noeud Duniter qui sera scanné
|
||||
ESNODE="http://g1.data.duniter.fr" # Adresse du noeud ElasticSearch qui sera scanné (Si nécessaire)
|
||||
WEBPATH="/var/www/g1-stats" # Dossier qui sera créé si vous choisissez l'option web pour la mise en ligne des données (nécessite une configuration apache ou nginx)
|
||||
SILKAJ="" # Chemin vers Silkaj (Récupéré automatiquement si non renseigné)
|
||||
|
|
|
@ -5,3 +5,4 @@ cache
|
|||
debug.log
|
||||
bk-debug.log
|
||||
bk
|
||||
.gitPushToMaster.sh
|
||||
|
|
19
README.md
19
README.md
|
@ -2,7 +2,7 @@
|
|||
## Sous forme d'un fichier JSON journalisé et d'outils d'exploitation de ce JSON
|
||||
### Visible sur: [https://g1-stats.axiom-team.fr/](https://g1-stats.axiom-team.fr/)
|
||||
|
||||
Utilise l'[API BMA](https://github.com/duniter/duniter-bma/blob/master/doc/API.md) pour l'extraction et l'indexation des données de la [blockchain Duniter/Ḡ1](https://duniter.org).
|
||||
Utilise l'[API BMA](https://github.com/duniter/duniter-bma/blob/master/doc/API.md) pour l'extraction et l'indexation des données de la [blockchain Duniter/Ḡ1](https://duniter.org).<br>
|
||||
A exécuter dans un environnement Bash Debian/Ubuntu.
|
||||
|
||||
*Si vous souhaitez modifier les paramètres par defaut, copiez le fichier .env.example en .env et adaptez les variables selon votre usage.*
|
||||
|
@ -13,8 +13,8 @@ Lancer le scan ainsi que tout le processus d'indexation depuis le début de la b
|
|||
```
|
||||
./g1-stats.sh
|
||||
```
|
||||
*A la première execution, ce scan peut durer plusieurs heures!*
|
||||
Pour pourrez suivre la progression du scan en temps réel.
|
||||
*A la première execution, ce scan peut durer plusieurs heures!*<br>
|
||||
Pour pourrez suivre la progression du scan en temps réel.<br>
|
||||
Pour les exécutions ultérieures, un cache est géneré permettant de reprendre le scan là où il s'est arrêté, diminuant drastiquement le temps d'execution.
|
||||
|
||||
Le fichier JSON est alors généré: `db/daily.json`
|
||||
|
@ -27,12 +27,17 @@ Pour générer la page web static:
|
|||
|
||||
## Exploration
|
||||
|
||||
Une fois le fichier JSON correctement généré, vous pouvez l'exploiter via la commande:
|
||||
Une fois le fichier JSON correctement généré, vous pouvez utiliser `explorer.sh` pour l'exploiter.<br>
|
||||
Pour obtenir l'aide:
|
||||
```
|
||||
./explorer.sh
|
||||
./explorer.sh -h
|
||||
```
|
||||
**Ce script explorer.sh fonctionne de manière standalone, c'est à dire que vous pouvez l'utiliser en dehors de l'environnement Ḡ1Stats sans aucune dépendance:**
|
||||
|
||||
*TODO: Détailler cette partie ...*
|
||||
```
|
||||
wget https://git.p2p.legal/axiom-team/g1-stats/raw/master/explorer.sh
|
||||
chmod u+x explorer.sh
|
||||
```
|
||||
|
||||
## Sauvegarde/Restauration
|
||||
|
||||
|
@ -53,7 +58,7 @@ Pour restaurer un backup à partir d'un bloc précis, par exemple le bloc 4242 (
|
|||
|
||||
## Automatisation
|
||||
|
||||
Vous pouvez décider d'exécuter ce script régulièrement grâce à une tache cron.
|
||||
Vous pouvez décider d'exécuter ce script régulièrement grâce à une tache cron.<br>
|
||||
Par exemple pour l'exécuter toutes les 3 heures:
|
||||
|
||||
```
|
||||
|
|
165
explorer.sh
165
explorer.sh
|
@ -1,65 +1,140 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Récupération du chemin absolut du répertoir du script actuel
|
||||
################################################################################
|
||||
# Author: Poka (poka@p2p.legal)
|
||||
# Version: 0.0.3
|
||||
# License: AGPL-3.0 (https://choosealicense.com/licenses/agpl-3.0/)
|
||||
# Git: https://git.p2p.legal/axiom-team/g1-stats
|
||||
################################################################################
|
||||
|
||||
###
|
||||
# Please change this path if needed, in relative path from explorer.sh script
|
||||
# If no file found, then this script will download it from https://g1-stats.axiom-team.fr and prompt it
|
||||
jsonFile="db/daily.json"
|
||||
###
|
||||
|
||||
# Check if jq, jo and curl are installed, or install them
|
||||
[[ -z $(which jq) || -z $(which jo) || -z $(which curl) ]] && sudo apt update && sudo apt install jq jo bc curl -y
|
||||
|
||||
# Path of the current script
|
||||
GPATH="$( cd "$(dirname "$0")" ; pwd -P )"
|
||||
source $GPATH/.env
|
||||
jsonFile="$GPATH/$jsonFile"
|
||||
|
||||
jsonFile="$GPATH/db/daily.json"
|
||||
cmd=$1
|
||||
dateRange=$2
|
||||
[[ -z $dateRange ]] && dateRange=$(jq -r '.[].date' $jsonFile | tail -n1)
|
||||
lineNbr=$(grep -n "$dateRange" $jsonFile | cut -d : -f 1)
|
||||
[[ -z $lineNbr ]] && echo "La date $dateRange n'existe pas en cache G1Stats" && exit 1
|
||||
if [[ -f $jsonFile ]]; then
|
||||
jsonData=$(cat $jsonFile)
|
||||
else
|
||||
echo "Warning: No JSON file found, we download it from https://g1-stats.axiom-team.fr/data/daily.json" >&2
|
||||
jsonData="$(curl -s https://g1-stats.axiom-team.fr/data/daily.json)"
|
||||
fi
|
||||
|
||||
cumulate() {
|
||||
lineNbr=$(($lineNbr+7))
|
||||
# Help display
|
||||
helpOpt() {
|
||||
echo -e "Welcome to Ḡ1Stats Explorer V$(head $0 | awk '/# Version:/ { print $3 }')
|
||||
\rThis tool can be use in 2 differents mode:
|
||||
\r- Isolate mode (default): Display data of a selected day
|
||||
\r- Cumulative mode (option -c or --cumulate): Display cumulative data from begining of Ḡ1 Blockchain (08-03-17) until selected day
|
||||
|
||||
jsonDated=$(head -n$lineNbr $jsonFile)
|
||||
jsonDated=$(echo -e "$jsonDated\n }\n]")
|
||||
\rExamples:
|
||||
\r$0
|
||||
Default view show last day data in cumulative mode
|
||||
|
||||
sumRWBrut=$(jq -r '.[].rWallets' <<<$jsonDated | awk '{ SUM += $1} END { printf "%.2f", SUM }')
|
||||
sumRMBrut=$(jq -r '.[].rMembers' <<<$jsonDated | awk '{ SUM += $1} END { printf "%.2f", SUM }')
|
||||
sumRTBrut=$(jq -r '.[] | .rWallets, .rMembers' <<<$jsonDated | awk '{ SUM += $1} END { printf "%.2f", SUM }')
|
||||
sumSWBrut=$(jq -r '.[].sWallets' <<<$jsonDated | awk '{ SUM += $1} END { printf "%.2f", SUM }')
|
||||
sumSMBrut=$(jq -r '.[].sMembers' <<<$jsonDated | awk '{ SUM += $1} END { printf "%.2f", SUM }')
|
||||
sumSTBrut=$(jq -r '.[] | .sWallets, .sMembers' <<<$jsonDated | awk '{ SUM += $1} END { printf "%.2f", SUM }')
|
||||
\r$0 day 08-03-20
|
||||
Display 8th Mars 2020's data
|
||||
|
||||
nbrMembers=$(jq -r '.[].nbrMembers' <<<$jsonDated | awk '{ SUM += $1} END { printf "%.0f", SUM }')
|
||||
nbrWallets=$(jq -r '.[].nbrWallets' <<<$jsonDated | awk '{ SUM += $1} END { printf "%.0f", SUM }')
|
||||
\r$0 day 08-03-20 -c
|
||||
Display 8th Mars 2020's cumulative data from begining
|
||||
|
||||
soldeWBrut=$(echo "$sumRWBrut-$sumSWBrut" | bc)
|
||||
soldeMBrut=$(echo "$sumRMBrut-$sumSMBrut" | bc)
|
||||
\r$0 mass -c [day]
|
||||
Display monetary mass on current day, or selected day
|
||||
|
||||
UD=$(jq -r '.[].UD' <<<$jsonDated | tail -n1)
|
||||
\r$0 solde [day]
|
||||
Display solde (Received - Sent) for simple wallets and members wallets on a day
|
||||
|
||||
echo "{
|
||||
\"date\": "\"$dateRange\"",
|
||||
\"UD\": $UD,
|
||||
\"rWallets\": $sumRWBrut,
|
||||
\"sWallets\": $sumSWBrut,
|
||||
\"soldeWallets\": $soldeWBrut,
|
||||
\"rMembers\": $sumRMBrut,
|
||||
\"sMembers\": $sumSMBrut,
|
||||
\"soldeMembers\": $soldeMBrut,
|
||||
\"nbrMembers\": $nbrMembers,
|
||||
\"nbrWallets\": $nbrWallets
|
||||
}
|
||||
" | jq .
|
||||
\r$0 total [day]
|
||||
Display Sent and Received Ḡ1 in total on a day
|
||||
|
||||
\r$0 custom \".rMembers==0 and .sMembers==0\"
|
||||
Display custom filter. Here we get only days where members received and sent nothing
|
||||
|
||||
\r$0 anniversary -c
|
||||
Display UD reassessment days, the new UD value and the number of members this day"
|
||||
}
|
||||
|
||||
day() {
|
||||
lineNbr=$(($lineNbr+8))
|
||||
jqCumulate="def roundit: (.*100.0)+ 0.5|floor/100.0;
|
||||
[foreach .[] as \$row (null;
|
||||
.nbrMembers += \$row.nbrMembers |
|
||||
.nbrWallets += \$row.nbrWallets |
|
||||
.sMembers = (\$row.sMembers + .sMembers|roundit) |
|
||||
.rMembers = (\$row.rMembers + .rMembers|roundit) |
|
||||
.sWallets = (\$row.sWallets + .sWallets|roundit) |
|
||||
.rWallets = (\$row.rWallets + .rWallets|roundit);
|
||||
\$row + . )]"
|
||||
|
||||
jsonDated=$(head -n$lineNbr $jsonFile | tail -n10 | sed 's/},/}/g')
|
||||
jq . <<<"$jsonDated"
|
||||
# Parse options
|
||||
for i in $@; do
|
||||
case "$i" in
|
||||
-c|--cumulate) jsonData="$(jq "$jqCumulate" <<<$jsonData)";;
|
||||
-h|--help) helpOpt && exit 0;;
|
||||
*) isArg+="$i|";;
|
||||
esac
|
||||
done
|
||||
|
||||
# Load arguments in respective variables
|
||||
cmd=$(cut -d'|' -f1 <<<"$isArg")
|
||||
dateRange=$(cut -d'|' -f2 <<<"$isArg")
|
||||
args="$(cut -d'|' -f2- <<<"$isArg" | sed 's/.$//' | tr '|' ' ')"
|
||||
|
||||
# If no date, set last available
|
||||
[[ -z "$dateRange" ]] && dateRange=$(jq -r '.[].date' <<<$jsonData | tail -n1)
|
||||
# Check if date existe un JSON
|
||||
[[ ! $(grep -w "$dateRange" <<<$jsonData) && $cmd != "custom" ]] && echo "La date $dateRange n'existe pas en cache G1Stats" && exit 1
|
||||
|
||||
day() {
|
||||
jq '.[] | select(.date=="'$dateRange'")' <<<$jsonData
|
||||
}
|
||||
|
||||
mass() {
|
||||
lineNbr=$(($lineNbr+7))
|
||||
jsonDated="$(head -n$lineNbr $jsonFile)}]"
|
||||
jq -f $GPATH/lib/cumulate.jq <<<"$jsonDated" | jq '.[] | .UD*.nbrMembers' | awk '{ SUM += $1} END { printf "%.2f", SUM }'; echo
|
||||
local jsonDated=$(jq '.[0: map(.date) | index("'$dateRange'")+1]' <<<$jsonData)
|
||||
local mMass=$(jq '.[] | .UD*.nbrMembers' <<<"$jsonDated" | awk '{ SUM += $1} END { printf "%.2f", SUM }')
|
||||
jo -p date=$dateRange monetaryMass=$mMass | jq .
|
||||
}
|
||||
|
||||
[[ -z $cmd ]] && cmd=cumulate
|
||||
total() {
|
||||
local cumDay=$(day)
|
||||
local totalExchange=$(jq '(.rWallets+.rMembers)*100.0+ 0.5|floor/100.0' <<<$cumDay)
|
||||
local soldeWallets=$(jq '(.rWallets-.sWallets)*100.0+ 0.5|floor/100.0' <<<$cumDay)
|
||||
local soldeMembers=$(jq '(.rMembers-.sMembers)*100.0+ 0.5|floor/100.0' <<<$cumDay)
|
||||
jo -p date=$dateRange totalExchange=$totalExchange soldeWallets=$soldeWallets soldeMembers=$soldeMembers | jq .
|
||||
}
|
||||
|
||||
$cmd
|
||||
totall() {
|
||||
for i in $(jq -r .[].date <<<$jsonData); do
|
||||
dateRange=$i
|
||||
total
|
||||
done
|
||||
}
|
||||
|
||||
custom() {
|
||||
jq '.[] | select('"$args"')' <<<$jsonData
|
||||
}
|
||||
|
||||
anniversary() {
|
||||
local jqNewUD="reduce .[] as \$x (null;
|
||||
if . == null then [\$x]
|
||||
elif .[-1].UD == \$x.UD then .
|
||||
else . + [\$x] end) | .[] |=
|
||||
{date: .date, UD: .UD, nbrMembers: .nbrMembers}"
|
||||
|
||||
jq "$jqNewUD" <<<$jsonData
|
||||
}
|
||||
|
||||
print() {
|
||||
jq . <<<"$jsonData"
|
||||
}
|
||||
|
||||
# Load functions
|
||||
case $cmd in
|
||||
'') day;;
|
||||
solde) total;;
|
||||
*) [[ $(type -t $cmd) == "function" ]] && $cmd || (echo -e "$cmd: Commande inconnue\n" && helpOpt);;
|
||||
esac
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
# Exit script if error
|
||||
set -e
|
||||
|
||||
# Récupération du chemin absolut du répertoir du script actuel
|
||||
# Récupération du chemin absolu du répertoir du script actuel
|
||||
GPATH="$( cd "$(dirname "$0")" ; pwd -P )"
|
||||
[[ ! -f $GPATH/.env ]] && cp $GPATH/.env.example $GPATH/.env
|
||||
source $GPATH/.env
|
||||
|
@ -21,7 +21,7 @@ startTime=$(date +'%H:%M')
|
|||
day=$(date +'%y-%m-%d')
|
||||
dayP=$(date +'%d-%m-%y')
|
||||
echo -e "\n############# $day à $startTime #############\n"
|
||||
[[ -z $(which jq) || -z $(which bc) || -z $(which curl) ]] && sudo apt update && sudo apt install jq bc curl
|
||||
[[ -z $(which jq) || -z $(which jo) || -z $(which bc) || -z $(which curl) ]] && sudo apt update && sudo apt install jq jo bc curl -y
|
||||
echo "Initialisation ..."
|
||||
if $debug; then
|
||||
TXBLOCKS=$(cat $GPATH/db/debug/txblocs)
|
||||
|
@ -51,7 +51,6 @@ source $GPATH/lib/scanTxWallets.sh
|
|||
|
||||
### Extraction des adresses Ḡ1 actives
|
||||
scanTxWallets
|
||||
|
||||
### Calcul la somme des soldes portefeuilles et membres
|
||||
sumSoldes
|
||||
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
def roundit: .*100.0|round/100.0;
|
||||
[foreach .[] as $row ({nbrMembers: 0, nbrWallets: 0, sMembers: 0, rMembers: 0, sWallets: 0, rWallets: 0};
|
||||
{
|
||||
nbrMembers: ($row.nbrMembers + .nbrMembers),
|
||||
nbrWallets: ($row.nbrWallets + .nbrWallets),
|
||||
sMembers: ($row.sMembers + .sMembers|roundit),
|
||||
rMembers: ($row.rMembers + .rMembers|roundit),
|
||||
sWallets: ($row.sWallets + .sWallets|roundit),
|
||||
rWallets: ($row.rWallets + .rWallets|roundit)
|
||||
};
|
||||
$row * .
|
||||
)]
|
|
@ -61,12 +61,16 @@ web() {
|
|||
echo "$wallets" | grep . > $WEBPATH/data/wallets-g1.txt
|
||||
echo -e "$membresPubkeys" | sed 's/ /\n/g' > $WEBPATH/data/wallets-g1-membres.txt
|
||||
echo -e "$simpleWallets" > $WEBPATH/data/wallets-g1-simple.txt
|
||||
cp $GPATH/db/{daily.json,cum-daily.json} $WEBPATH/data/
|
||||
cp $GPATH/db/daily.json $WEBPATH/data/
|
||||
$GPATH/explorer.sh print -c > $WEBPATH/data/cum-daily.json
|
||||
|
||||
if [[ "$startTime" == "00:00" ]]; then
|
||||
cp $indexhtml $WEBPATH/history/index_$day.html
|
||||
sed -i "s/css\/style.css/..\/css\/style.css/g" $WEBPATH/history/index_$day.html
|
||||
sed -i "s/logo-axiom-team.svg/..\/logo-axiom-team.svg/g" $WEBPATH/history/index_$day.html
|
||||
sed -i 's/id="charts">/id="charts" style="display:none;">/g' $WEBPATH/history/index_$day.html
|
||||
sed -i '/href="css\/charts.css"/d' $WEBPATH/history/index_$day.html
|
||||
sed -i '/type="text\/javascript"/d' $WEBPATH/history/index_$day.html
|
||||
sed -i "s/_dateNext/$day/g" $WEBPATH/history/index_$datePrevious.html
|
||||
sed -i "s/style=\"display:none;\" class=\"next\"/class=\"next\"/g" $WEBPATH/history/index_$datePrevious.html
|
||||
fi
|
||||
|
@ -76,19 +80,20 @@ web() {
|
|||
}
|
||||
|
||||
sumSoldes() {
|
||||
source $GPATH/explorer.sh > /dev/null
|
||||
|
||||
sumRW=$(echo $sumRWBrut | sed ':a;s/\B[0-9]\{3\}\>/ &/;ta')
|
||||
sumRM=$(echo $sumRMBrut | sed ':a;s/\B[0-9]\{3\}\>/ &/;ta')
|
||||
sumRT=$(echo $sumRTBrut | sed ':a;s/\B[0-9]\{3\}\>/ &/;ta')
|
||||
sumSW=$(echo $sumSWBrut | sed ':a;s/\B[0-9]\{3\}\>/ &/;ta')
|
||||
sumSM=$(echo $sumSMBrut | sed ':a;s/\B[0-9]\{3\}\>/ &/;ta')
|
||||
sumST=$(echo $sumSTBrut | sed ':a;s/\B[0-9]\{3\}\>/ &/;ta')
|
||||
soldeW=$(echo $soldeWBrut | sed ':a;s/\B[0-9]\{3\}\>/ &/;ta')
|
||||
soldeM=$(echo $soldeMBrut | sed ':a;s/\B[0-9]\{3\}\>/ &/;ta')
|
||||
source $GPATH/explorer.sh -c > /dev/null
|
||||
sumRW=$(day | jq '.rWallets' | sed ':a;s/\B[0-9]\{3\}\>/ &/;ta')
|
||||
sumRM=$(day | jq '.rMembers' | sed ':a;s/\B[0-9]\{3\}\>/ &/;ta')
|
||||
sumRT=$(total | jq '.totalExchange' | sed ':a;s/\B[0-9]\{3\}\>/ &/;ta')
|
||||
sumSW=$(day | jq '.sWallets' | sed ':a;s/\B[0-9]\{3\}\>/ &/;ta')
|
||||
sumSM=$(day | jq '.sMembers' | sed ':a;s/\B[0-9]\{3\}\>/ &/;ta')
|
||||
sumSTBrut=$(total | jq '.totalExchange')
|
||||
sumST=$(sed ':a;s/\B[0-9]\{3\}\>/ &/;ta' <<<"$sumSTBrut")
|
||||
soldeWBrut=$(total | jq '.soldeWallets')
|
||||
soldeW=$(sed ':a;s/\B[0-9]\{3\}\>/ &/;ta' <<<"$soldeWBrut")
|
||||
soldeM=$(total | jq '.soldeMembers' | sed ':a;s/\B[0-9]\{3\}\>/ &/;ta')
|
||||
|
||||
### Calcul de la masse monétaire et du pourcentage de Ḡ1 sur les simples portefeuilles
|
||||
monetaryMassBrut=$($GPATH/explorer.sh mass)
|
||||
monetaryMassBrut=$(mass | jq .monetaryMass)
|
||||
monetaryMass=$(echo "$monetaryMassBrut" | sed ':a;s/\B[0-9]\{3\}\>/ &/;ta')
|
||||
|
||||
pourcentSimpleWallet=$(echo "$soldeWBrut*100/$monetaryMassBrut/1" | bc -l | xargs printf %.1f)
|
||||
|
|
|
@ -40,6 +40,9 @@ scanTxWallets() {
|
|||
|
||||
# Récupération de la date du block
|
||||
local blockDate=$(jq '.medianTime' <<<"$blocBrut")
|
||||
#kopa echo "$blocBrut"
|
||||
# echo "---"
|
||||
# echo "$blockDate"
|
||||
blockDate=$(date -d"@$blockDate" +%d-%m-%y -u)
|
||||
local walletsReceivedBloc=$(jq '.transactions[]' <<<"$blocBrut")
|
||||
|
||||
|
@ -240,9 +243,6 @@ scanTxWallets() {
|
|||
sed -i '$ s/,//g' $jsonFile
|
||||
echo "]" >> $jsonFile
|
||||
|
||||
# On génère le JSON équivalent avec données cumulatives
|
||||
jq -f $GPATH/lib/cumulate.jq $jsonFile > $GPATH/db/cum-daily.json
|
||||
|
||||
# On supprime les doublons et les lignes vides
|
||||
wallets=$(echo -e "$wallets" | sort -u | awk 'NF')
|
||||
# On écrit les pubkeys avec transaction dans un fichier de cache pour la prochaine itération
|
||||
|
|
|
@ -14,9 +14,9 @@ chainMbr=$(head -n1 <<<"$chainData")
|
|||
|
||||
((day--))
|
||||
Date=$(date -d "17-03-08+${day}day" '+%d-%m-%y')
|
||||
jsonMass=$($GPATH/explorer.sh mass $Date)
|
||||
jsonMass=$($GPATH/explorer.sh mass $Date -c | jq .monetaryMass)
|
||||
|
||||
jsonMbr=$($GPATH/explorer.sh cumulate $Date | jq .nbrMembers)
|
||||
jsonMbr=$($GPATH/explorer.sh day $Date -c | jq .nbrMembers)
|
||||
|
||||
#if [[ $jsonMbr != $chainMbr ]]; then
|
||||
echo "$Date - $bloc - $day
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Récupération du chemin absolu du répertoire du script actuel
|
||||
GPATH="$( cd "$(dirname "$0")" ; pwd -P )/.."
|
||||
[[ ! -f $GPATH/.env ]] && cp $GPATH/.env.example $GPATH/.env
|
||||
source $GPATH/.env
|
||||
node=$(cut -d '/' -f3 <<<"$DUNITER")
|
||||
|
||||
#Check if ed is installed
|
||||
which ed || { echo "$0: Error: please install ed" >&2 ; exit 1 ; }
|
||||
|
||||
#Check if Jaklis or silkaj is installed
|
||||
if [[ "$JAKLIS" ]] ; then
|
||||
exec() {
|
||||
jsonResult=$($JAKLIS idBalance -p $i) || return $?
|
||||
balance=$(echo "$jsonResult" | jq -r '.balance')
|
||||
username=$(echo "$jsonResult" | jq -r '.username')
|
||||
}
|
||||
elif which silkaj ; then
|
||||
exec() {
|
||||
balance=$(silkaj -p "$node" balance "$i") || return $?
|
||||
balance=$(sed -n 's,.* \([\.0-9]\+\) Ğ1.*,\1,p' <<<$balance)
|
||||
username=$(silkaj -p "$node" id "$i") || return $?
|
||||
username=$(sed -n 's,.*: \(.*\)$,\1,p' <<<$username)
|
||||
}
|
||||
else
|
||||
echo "$0: Error: you should use Jaklis or install silkaj." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
work() {
|
||||
for i in $wallets; do
|
||||
((j++))
|
||||
# For tests only
|
||||
#(( j > 42 )) && break
|
||||
|
||||
unset k
|
||||
while ! exec ; do echo "Erreur $?: retry=$((k)) wallet=$i"; ((k++ > 9999)) && break ; sleep $((RANDOM%8)) ; done
|
||||
|
||||
formatedBalance=$(printf "%-10s | %-45s | %-1s" $balance $i $username)
|
||||
|
||||
[[ $1 == "members" ]] && username="<b>$username</b>"
|
||||
htmlBloc="$htmlBloc<td>$balance</td><td><a id=\"k$i\" href=\"payto://g1/$i\">$i</a></td><td><b>$username</b></td>"$'\n'
|
||||
|
||||
echo "$formatedBalance" | tee -a /tmp/balance-g1.txt | sed "s,^,$j | ,"
|
||||
|
||||
totalBalance="$totalBalance$formatedBalance"$'\n'
|
||||
done
|
||||
}
|
||||
|
||||
wallets=$(cat $WEBPATH/data/wallets-g1-membres.txt 2>/dev/null)
|
||||
[[ -z $wallets ]] && wallets=$(curl -s https://g1-stats.axiom-team.fr/data/wallets-g1-membres.txt)
|
||||
work members && unset wallets
|
||||
wallets=$(cat $WEBPATH/data/wallets-g1-simple.txt 2>/dev/null)
|
||||
[[ -z $wallets ]] && wallets=$(curl -s https://g1-stats.axiom-team.fr/data/wallets-g1-simple.txt)
|
||||
work && unset wallets
|
||||
|
||||
totalBalance=$(sort -nr <<<$totalBalance)
|
||||
[[ ! -d $GPATH/db ]] && mkdir $GPATH/db
|
||||
grep . <<<"$totalBalance" > $GPATH/db/wallets_balance.txt && rm /tmp/balance-g1.txt
|
||||
|
||||
# Construct HTML
|
||||
cp $GPATH/tpl/css/wallets_balance.css $WEBPATH/css/
|
||||
cp $GPATH/tpl/js/wallets_balance.js $WEBPATH/js/
|
||||
cp $GPATH/tpl/wallets_balance.html $WEBPATH/data/wallets_balance.html
|
||||
|
||||
sort -Vr <<<"$htmlBloc" | awk '{ print "<tr id=\"p"NR"\"><td>"NR"</td>"$0"</tr>" ; }' > /tmp/solde_g1_html.txt
|
||||
printf '%s\n' '/_LINE/r /tmp/solde_g1_html.txt' 1 '/_LINE/d' w | ed $WEBPATH/data/wallets_balance.html > /dev/null
|
||||
sed -i "0,/_DATE/s//$(date '+%d-%m-%Y')/" $WEBPATH/data/wallets_balance.html
|
||||
rm /tmp/solde_g1_html.txt
|
|
@ -2,12 +2,40 @@
|
|||
width: 98%;
|
||||
margin-left: 0px;
|
||||
overflow-x: scroll;
|
||||
/* display: none; */
|
||||
}
|
||||
|
||||
|
||||
.chartWrapper {
|
||||
position: relative;
|
||||
background-color: #DFCFBE;
|
||||
border-radius: 30px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.chartWrapper > canvas {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
pointer-events:none;
|
||||
}
|
||||
.chartAreaWrapper {
|
||||
overflow-x: scroll;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 400px;
|
||||
}
|
||||
.chartAreaWrapper2 {
|
||||
|
||||
position: relative;
|
||||
height: 300px;
|
||||
width: 3000px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@media only screen and (max-width: 1100px) {
|
||||
|
||||
#charts {
|
||||
width: 95%;
|
||||
}
|
||||
|
||||
#charts {
|
||||
width: 95%;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
body {
|
||||
background-color: #c4a787;
|
||||
margin-top: 10px;
|
||||
margin-left: 20px;
|
||||
font-family: "Gill Sans", sans-serif;
|
||||
}
|
||||
|
||||
.date {
|
||||
margin-left: 2px;
|
||||
}
|
||||
|
||||
#pseudo, #key {
|
||||
background-position: 10px 12px; /* Position the search icon */
|
||||
background-repeat: no-repeat; /* Do not repeat the icon image */
|
||||
width: 300px; /* Full-width */
|
||||
font-size: 16px; /* Increase font-size */
|
||||
padding: 12px 20px 12px 20px; /* Add some padding */
|
||||
border: 1px solid #ddd; /* Add a grey border */
|
||||
margin-bottom: 12px; /* Add some space below the input */
|
||||
margin-top: 7px;
|
||||
}
|
||||
|
||||
#soldes {
|
||||
border-collapse: collapse; /* Collapse borders */
|
||||
width: 50%; /* Full-width */
|
||||
border: 1px solid #ddd; /* Add a grey border */
|
||||
font-size: 16px; /* Increase font-size */
|
||||
background-color: #DFCFBE;
|
||||
}
|
||||
|
||||
#soldes th, #soldes td {
|
||||
text-align: left; /* Left-align text */
|
||||
padding: 8px; /* Add padding */
|
||||
}
|
||||
|
||||
#soldes tr {
|
||||
/* Add a bottom border to all table rows */
|
||||
border-bottom: 1px solid #ddd;
|
||||
}
|
||||
|
||||
#soldes tr:hover {
|
||||
/* Add a grey background color to the table header and on hover */
|
||||
background-color: #f1f1f1;
|
||||
}
|
||||
|
||||
#soldes th {
|
||||
/* Add a grey background color to the table header and on hover */
|
||||
background-color: #B69776;
|
||||
cursor: pointer;
|
||||
top: 0px;
|
||||
}
|
||||
|
||||
#splw {
|
||||
margin-left: 20px;
|
||||
}
|
134
tpl/graph.js
134
tpl/graph.js
|
@ -1,134 +0,0 @@
|
|||
var jsonfileRW = $.getJSON( "daily.json", function(data) {
|
||||
var date = jsonfileRW.responseJSON.map(function(e) {
|
||||
return e.date;
|
||||
});
|
||||
var rwallets = jsonfileRW.responseJSON.map(function(e) {
|
||||
return e.rWallets;
|
||||
});
|
||||
var rmembers = jsonfileRW.responseJSON.map(function(e) {
|
||||
return e.rMembers;
|
||||
});
|
||||
var nbrwallets = jsonfileRW.responseJSON.map(function(e) {
|
||||
return e.nbrWallets;
|
||||
});
|
||||
var nbrmembers = jsonfileRW.responseJSON.map(function(e) {
|
||||
return e.nbrMembers;
|
||||
});
|
||||
|
||||
//ReceivedGraph
|
||||
var ctx = document.getElementById("chartRW");
|
||||
var config = {
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: date,
|
||||
datasets: [{
|
||||
label: 'Ḡ1 reçus sur les simples portefeuilles',
|
||||
data: rwallets,
|
||||
backgroundColor: 'rgba(0, 119, 204, 0.3)',
|
||||
pointBorderWidth: 1,
|
||||
pointHoverRadius: 8,
|
||||
pointHoverBackgroundColor: "beige",
|
||||
pointHoverBorderColor: "brown",
|
||||
pointHoverBorderWidth: 2,
|
||||
pointRadius: 3,
|
||||
pointHitRadius: 8
|
||||
}, {
|
||||
label: 'Ḡ1 reçus sur les portefeuilles membres',
|
||||
data: rmembers,
|
||||
backgroundColor: 'rgba(0, 178, 0, 0.3)',
|
||||
pointBorderWidth: 1,
|
||||
pointHoverRadius: 8,
|
||||
pointHoverBackgroundColor: "beige",
|
||||
pointHoverBorderColor: "brown",
|
||||
pointHoverBorderWidth: 2,
|
||||
pointRadius: 3,
|
||||
pointHitRadius: 8
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
maintainAspectRatio: true,
|
||||
responsive: true
|
||||
}
|
||||
};
|
||||
var myChartRW = new Chart(ctx, config);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// NbrWallets Graph
|
||||
var ctx = document.getElementById("chartNBRW");
|
||||
var config = {
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: date,
|
||||
datasets: [{
|
||||
label: 'Nombre de simple portefeuilles',
|
||||
data: nbrwallets,
|
||||
backgroundColor: 'rgba(0, 119, 204, 0.3)',
|
||||
pointBorderWidth: 1,
|
||||
pointHoverRadius: 8,
|
||||
pointHoverBackgroundColor: "beige",
|
||||
pointHoverBorderColor: "brown",
|
||||
pointHoverBorderWidth: 2,
|
||||
pointRadius: 3,
|
||||
pointHitRadius: 8
|
||||
}, {
|
||||
label: 'Nombre de portefeuilles membres',
|
||||
data: nbrmembers,
|
||||
backgroundColor: 'rgba(0, 178, 0, 0.3)',
|
||||
pointBorderWidth: 1,
|
||||
pointHoverRadius: 8,
|
||||
pointHoverBackgroundColor: "beige",
|
||||
pointHoverBorderColor: "brown",
|
||||
pointHoverBorderWidth: 2,
|
||||
pointRadius: 3,
|
||||
pointHitRadius: 8
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
maintainAspectRatio: true,
|
||||
responsive: true
|
||||
}
|
||||
};
|
||||
|
||||
var myChartNBRW = new Chart(ctx, config);
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*var jqxhr = $.getJSON( "example.json", function() {
|
||||
console.log( "success" );
|
||||
})
|
||||
.done(function() {
|
||||
console.log( "second success" );
|
||||
})
|
||||
.fail(function() {
|
||||
console.log( "error" );
|
||||
})
|
||||
.always(function() {
|
||||
console.log( "complete" );
|
||||
});*/
|
|
@ -16,7 +16,8 @@
|
|||
| <a href="/data/daily.json">Voir le fichier JSON</a>
|
||||
| <a href="/data/wallets-g1.txt">Liste de tous les wallets</a>
|
||||
| <a href="/data/wallets-g1-membres.txt">Liste des wallets membres</a>
|
||||
| <a href="/data/wallets-g1-simple.txt">Liste des simples portefeuilles</a> |
|
||||
| <a href="/data/wallets-g1-simple.txt">Liste des simples portefeuilles</a>
|
||||
| <a href="/data/wallets_balance.html">Classement FORBES</a> |
|
||||
</center>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
var jsonfileRW = $.getJSON( "../data/cum-daily.json", function(data) {
|
||||
var date = jsonfileRW.responseJSON.map(function(e) {
|
||||
return e.date;
|
||||
});
|
||||
var rwallets = jsonfileRW.responseJSON.map(function(e) {
|
||||
return e.rWallets;
|
||||
});
|
||||
var rmembers = jsonfileRW.responseJSON.map(function(e) {
|
||||
return e.rMembers;
|
||||
});
|
||||
var nbrwallets = jsonfileRW.responseJSON.map(function(e) {
|
||||
return e.nbrWallets;
|
||||
});
|
||||
var nbrmembers = jsonfileRW.responseJSON.map(function(e) {
|
||||
return e.nbrMembers;
|
||||
});
|
||||
|
||||
//var optionsGen = 'pointBorderWidth: 1, pointHoverRadius: 6, pointHoverBackgroundColor: "beige", pointHoverBorderColor: "brown", pointHoverBorderWidth: 2, pointRadius: 1, pointHitRadius: 4';
|
||||
|
||||
//Received Graph
|
||||
var ctx = document.getElementById("chartRW");
|
||||
var config = {
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: date,
|
||||
datasets: [{
|
||||
label: 'Ḡ1 reçus sur les simples portefeuilles',
|
||||
data: rwallets,
|
||||
backgroundColor: 'rgba(0, 119, 204, 0.3)',
|
||||
pointBorderWidth: 1,
|
||||
pointHoverRadius: 6,
|
||||
pointHoverBackgroundColor: "beige",
|
||||
pointHoverBorderColor: "brown",
|
||||
pointHoverBorderWidth: 2,
|
||||
pointRadius: 1,
|
||||
pointHitRadius: 4
|
||||
}, {
|
||||
label: 'Ḡ1 reçus sur les portefeuilles membres',
|
||||
data: rmembers,
|
||||
backgroundColor: 'rgba(0, 178, 0, 0.3)',
|
||||
pointBorderWidth: 1,
|
||||
pointHoverRadius: 6,
|
||||
pointHoverBackgroundColor: "beige",
|
||||
pointHoverBorderColor: "brown",
|
||||
pointHoverBorderWidth: 2,
|
||||
pointRadius: 1,
|
||||
pointHitRadius: 4
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
maintainAspectRatio: false,
|
||||
responsive: true
|
||||
}
|
||||
};
|
||||
var myChartRW = new Chart(ctx, config);
|
||||
|
||||
|
||||
// NbrWallets Graph
|
||||
var ctx = document.getElementById("chartNBRW");
|
||||
var config = {
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: date,
|
||||
datasets: [{
|
||||
label: 'Nombre de simple portefeuilles',
|
||||
data: nbrwallets,
|
||||
backgroundColor: 'rgba(0, 119, 204, 0.3)',
|
||||
pointBorderWidth: 1,
|
||||
pointHoverRadius: 6,
|
||||
pointHoverBackgroundColor: "beige",
|
||||
pointHoverBorderColor: "brown",
|
||||
pointHoverBorderWidth: 2,
|
||||
pointRadius: 1,
|
||||
pointHitRadius: 4
|
||||
}, {
|
||||
label: 'Nombre de portefeuilles membres',
|
||||
data: nbrmembers,
|
||||
backgroundColor: 'rgba(0, 178, 0, 0.3)',
|
||||
pointBorderWidth: 1,
|
||||
pointHoverRadius: 6,
|
||||
pointHoverBackgroundColor: "beige",
|
||||
pointHoverBorderColor: "brown",
|
||||
pointHoverBorderWidth: 2,
|
||||
pointRadius: 1,
|
||||
pointHitRadius: 4
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
maintainAspectRatio: true,
|
||||
responsive: true
|
||||
}
|
||||
};
|
||||
|
||||
var myChartNBRW = new Chart(ctx, config);
|
||||
|
||||
});
|
|
@ -0,0 +1,72 @@
|
|||
|
||||
const getCellValue = (tr, idx) => tr.children[idx].innerText || tr.children[idx].textContent;
|
||||
|
||||
const comparer = (idx, asc) => (a, b) => ((v1, v2) =>
|
||||
v1 !== '' && v2 !== '' && !isNaN(v1) && !isNaN(v2) ? v1 - v2 : v1.toString().localeCompare(v2)
|
||||
)(getCellValue(asc ? a : b, idx), getCellValue(asc ? b : a, idx));
|
||||
|
||||
// Sort work
|
||||
document.querySelectorAll('th').forEach(th => th.addEventListener('click', (() => {
|
||||
const table = th.closest('table');
|
||||
Array.from(table.querySelectorAll('tr:nth-child(n+2)'))
|
||||
.sort(comparer(Array.from(th.parentNode.children).indexOf(th), this.asc = !this.asc))
|
||||
.forEach(tr => table.appendChild(tr) );
|
||||
})));
|
||||
|
||||
// Search
|
||||
function recherche(select) {
|
||||
// Declare variables
|
||||
var input, filter, table, tr, td, i, txtValue;
|
||||
input = document.getElementById(select);
|
||||
filter = input.value.toUpperCase();
|
||||
table = document.getElementById("soldes");
|
||||
tr = table.getElementsByTagName("tr");
|
||||
|
||||
// Loop through all table rows, and hide those who don't match the search query
|
||||
for (i = 0; i < tr.length; i++) {
|
||||
if (select == "pseudo") { td = tr[i].getElementsByTagName("td")[2]; }
|
||||
else if (select == "key") { td = tr[i].getElementsByTagName("td")[1]; }
|
||||
|
||||
if (td) {
|
||||
txtValue = td.textContent || td.innerText;
|
||||
if (txtValue.toUpperCase().indexOf(filter) > -1) {
|
||||
tr[i].style.display = "";
|
||||
} else {
|
||||
tr[i].style.display = "none";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Affichage des simples portefeuilles
|
||||
|
||||
var checkWallets = document.querySelector('input[value="splw"]');
|
||||
|
||||
checkWallets.onchange = function() {
|
||||
var table, tr, td, i, txtValue;
|
||||
table = document.getElementById("soldes");
|
||||
tr = table.getElementsByTagName("tr");
|
||||
|
||||
if(checkWallets.checked) {
|
||||
for (i = 0; i < tr.length; i++) {
|
||||
td = tr[i].getElementsByTagName("td")[2];
|
||||
if (td) {
|
||||
txtValue = td.textContent || td.innerText;
|
||||
if (txtValue == " ") {
|
||||
tr[i].style.display = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < tr.length; i++) {
|
||||
td = tr[i].getElementsByTagName("td")[2];
|
||||
if (td) {
|
||||
txtValue = td.textContent || td.innerText;
|
||||
if (txtValue == " ") {
|
||||
tr[i].style.display = "none";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
|
@ -0,0 +1,20 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<link rel="stylesheet" href="../css/wallets_balance.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="date"> Données générées le _DATE<br></div>
|
||||
<input type="text" id="pseudo" onkeyup="recherche('pseudo')" placeholder="Rechercher un pseudo...">
|
||||
<input type="text" id="key" onkeyup="recherche('key')" placeholder="Rechercher une clé publique...">
|
||||
<input type="checkbox" id="splw" value="splw" checked><label for="splw">Afficher les simples portefeuilles</label>
|
||||
|
||||
<table id="soldes">
|
||||
<tr><th>Position</th><th>Solde (Ḡ1)</th><th>Clé publique</th><th>Identifiant utilisateur</th></tr>
|
||||
_LINE
|
||||
</table>
|
||||
|
||||
<script type="text/javascript" src="../js/wallets_balance.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue