Sylvain303 / freeboxos-bash-api

Access FreeboxOS API from bash
0 stars 0 forks source link

Moving this 'issue' within the project to which it relates #1

Open nbanb opened 1 year ago

nbanb commented 1 year ago

Dear Sylvain303

Sorry to open it here, but as it's a fork, I didn't find the way to open an issue it at your fork of freeboxos-bash-api ...

I didn't see your work before I became the main contributor of the original project freeboxos-bash-api

Developping frontend functions in the library (you can see the project I maintien here fbx-delta-nba_bash_api.sh even if it's had been recently merged with the original project), I also encountering troubles with functions from JSON.SH when freebox API reply a json object that is bigger than 80kb or 100kb

As I need to make the code running in old UNIX systems, I'm not using 'jq' for parsing but I'm dumping all key pairs from the JSON, caching those results and printing the output from cache (see ls_fs and nearly all list_* functions) and I also develop a function which is printing json in "pretty json" format: colorize_output_pretty_json

In many situations it can be acceptable but sometimes (for ex: when retrieving a large collection of lanHost objects), it's still too slow. From my experiments, jq-1.5.1 is really faster than jq-1.6 ... Which 'jq' are you using ? Is the performance gap really interresting?

Second point, reading your code, I've seen :

# ==== ### NOTE ### ====
# The script will WRITE file in its own dir:
# - auth.sh   : [DOESN'T WORK YET] after the authorize process, store SAVED_APP_ID and SAVED_APP_TOKEN

You may be interrested by the rewrite of login_freebox which publish encrypted credentials to subshell and my relogin_freebox function which made the job automatically for exemple when monitoring a long filesystem task which is longer than the session timeout

Kind regards nbanba


Hello @nbanb,

I didn't used this script since ages. Thanks contacting me.

I moved to jq since this script. And I will never switch back to parsed json again.

I didn't notice any performance drawback on jq 1.6. 1.6 is the default version on my ubuntu variant.

make the code running in old UNIX systems

Is it safe to keep them?

If you absolutely needed to keep "old UNIX systems", well, I suppose you don't have python as well on such OS.

You could:

What is the benefit for you to keep the old OS?

Hope that helps.

I will open issue on the forked project. We may be able to chat in French too, as I suppose for using freebox OS you should speak French too.

nbanb commented 1 year ago

Hello @Sylvain303

Switching in french...


Déjà merci pour votre retour sur ce projet et d'avoir activer les 'issues'

Effectivement, ce n'est pas très 'safe' de maintenir le code sur de vieux UNIX. Et ce maintien ne pourras pas être éternel, j'ai déjà eu un mal fou pour faire fonctionner le TLS1.2.

Après, c'est dans le cadre d'un projet particulier avec un haut niveau d'isolation et de sécurité ou certaines machines ayant 6000 days d'uptime ne peuvent pas être migrés pour le moment ni arrêtées d'ailleurs. Pour faire court, suite à des contraintes empêchant la migration des applications hébergés par ces mainframes sur des systèmes plus modernes et pour des contraintes budgétaires, une freebox à été installée dans une DMZ et les mainframes peuvent piloter l'API de la freebox pour lancer des downloads https/ftp (qui sont récupérés par des crawlers) et ces mainframes peuvent pop 1 vm sur la freebox delta et ouvrir des ports dynamiquement et à la demande pour créer un NAT temporaire vers cette VM créé à la volée et pour l'occasion, mettant ainsi de la donnée enrichiee à disposition d'une autre application déportée avant de détruire la VM à la volée une fois la donnée récupérée par l'autre application. Les seuls accès de ces vieux systeme UNIX vers l'extérieur se cantonnent à piloter l'API d'une freebox dans une DMZ dédiée. Les limites des versions TLS sont atteintes et celles de bash également (pas plus de bash 4.2) et bien sûre, je n'ai pas python... Après, les CPU présent sur ces machines sont incomparables avec des x86, les performances de parsing des json en bash sont plusieurs fois meilleurs que sur mon XPS15 sous debian disposant d'un i7-9750H 12 core, donc le parsing manuel des json est acceptable, là ou il est souvent limite sur x86_64 et catastrophique sur arm64.

Mais bon, il faudrait que ça puisse encore tenir jusqu'en 2025...

Après, j'avoue qu'en parallèle faire une version comme vous avez faite n'utilisant que jq serait intéressante pour tous les ordinateurs modernes de petite puissance (comme les rapsberri ou équivalent) utilisant des processeurs arm64 qui eux sont très pénalisés par le parsing manuel du json. Avec la sortie du pack domotique et des VM dans la freebox delta dans les 5 dernières années, il y a un véritable intérêt à pouvoir manager les VM de la freebox delta depuis une autre VM présente dans le freebox et ayant une ligne de commande bash ou depuis n'importe quelle ligne de commande bash (de plus en plus de personnes non informaticienne faisant de la domotique se mettent à faire tourner des VM linux dans leur freebox delta et ont besoin d'utiliser l'API de la freebox simplement depuis la ligne de commande bash pour automatiser des process domotiques)

C'est d'ailleurs pour cela que j'ai repris le projet initiale qui dormait depuis plus de 5 ans et ajouté +3000 lignes dans la library originelle de 220 lignes et que j'ai réécrit le README avec le détail de chaque fonction (plus de 100 pages de doc). C'est pour que 'monsieur tout le monde' un peu curieux et démarrant une VM linux dans sa freebox puisse tout de suite gérer les VM de la freebox depuis l'API sans connaissances particulières si ce n'est savoir lire un README ou l'help de chaque commande (cf mon autre projet utilisant la library et permettant la gestion des VM par l'API : fbxvm-ctrl que je suis en train d'intégrer dans la library avec le même 'mindset' que les fonctions frontend développées dans cette dernière)

C'est aussi pour ça que je trouve bien que cette library utilise le moins 'd'external tools' possible, aujourd'hui openssl, curl et pour les websocket API: websocat que j'aimerai bien remplacer par du pure bash car websocat pour AIX6 et solaris8 c'est utopic (EOL 2012) Et aussi parce que c'est un truc de plus à compiler / installer pour 'monsieur tout le monde pas informaticien' (disposer nativement d'openssl et curl dans des linux moderne permet l'utilisation de la lib par 'monsieur tout le monde' sans ne rien installer d'autre si ce n'est websocat pour accéder aux consoles des VM)

Bref, des choix délicats pour répondre aux plus grand nombre de use cases possibles, uses cases qui seront mis en place par des personnes ayant une maitrise différente d'UNIX / Linux, et certaines fois même inexistante ...

Cordialement nbanba

Sylvain303 commented 1 year ago

Salut @nbanb

Tout un programme :smile:

Oui, je vois... Pas simple. Lorsque j'ai cherché un projet équivalent pour piloter ma freebox de l'époque (révolution) j'ai en effet été limité vraiment très vite sur la durée du parsing json sur amd64. Spécialement en interactif.

D'où la mise en place de jq dès que j'ai trouvé ce parser.

Depuis je n'utilise plus ce script, j'ai une autre freebox et plus de disque pour l'instant. Donc plus de navigation dans les fichiers mais je comprends l'utilité de ce que vous mentionnez.

les CPU présent sur ces machines sont incomparables avec des x86, les performances de parsing des json en bash J'en déduis que vous avez atteint toutefois un volume de json important.

Alors on peut bidouiller biensûr. Du genre utiliser une regexp juste pour le case d'usage le plus lent. Et extraire sans parser le JSON l’élément le plus probable...

Si vous voyez le genre ?

sylvain@lap43: ~$ echo '{"json de ouf" : { "blablo" : "vma valeur ici" } }' | grep -E -o '"blablo" : "([^"]+)"' | awk -F: '{print $2}'
 "vma valeur ici"

Après vous mentionnez colorize_output_pretty_json c'est ce que fait jq aussi, ce serait dommage de s'en privé. En golang ça fait facilement des binaires linké statique et en cross compil, c'est peut être une autre piste.

En suite le système source où se déclenche l'action le "mainframes peuvent piloter l'API de la freebox pour lancer des downloads https/ftp" Il est capable de faire un ssh?

ssh vm_de_pliotage_api_freebox "ma commande ici"

Et vous installer une debian moderne (ou la saveur que vous affectionnez) dans une VM de la box, puisqu'elle semble savoir faire ça. Et hop, une passerelle du moderne dans du vieux. :smile:

Cette dernière VM reste évidemment il ne faut pas la décommissionner, c'est un outil... Ou un container docker.

nbanb commented 1 year ago

Bonjour

Merci pour votre retour et désolé pour le lag... Oui, je vois le genre, d'ailleurs dès que j'ai besoin d'un peu d'efficacité, j'utilise des trucs bien dégueulasses comme

[[ "${result}" =~ ^"{\"success\":true" ]] \
        && echo -e "
${WHITE}$(print_vm_detail ${new_vm_id}|sed -e ':a' -e 'N' -e '$!ba' -e 's/\n/\\n/g')${norm}
${WHITE}VM creation status:${norm} ${GREEN} $(echo -e  "${result}" |grep success |cut -d',' -f-1 |sed 's/true/true\}/')${norm}
${norm}" \
        || echo -e "
${WHITE}VM creation status:${norm} ${RED} ${result}

Pour le pas utiliser la fonctions _check_success qui fait appel 3 fois à la fonction get_json_value_for_key qui parse le json

Ou encore pour print les json en mode pretty-json

echo -e "$(echo ${result[@]} \
        |sed -e 's/true,/true}\\\n/' -e  's/"result":/\\\nresult:\\\n/' -e 's/\\//g' -e 's/}}$/}/g'\
        |grep -Eo '"([^"\]*(\\")*(\\[^"])*)*" *(: *([0-9]*|"([^"\]*(\\")*(\\[^"])*)*")[^{}\["]*|,)?|[^"\]\[\}\{]*|\{|\},?|\[|\],?|[0-9]+ *,?|,' \
        | awk '{if ($0 ~ /^[]}]/ ) offset-=4; c=0; while (c++<offset) printf " "; printf "%s\n",$0; if ($0 ~ /^[[{]/) offset+=4}' \
        |xargs -0I @ echo "${GREEN}@${norm}" \
        )\n" 

Et j'arrive à des vitesses acceptables très proches de jq voir meilleur que jq quand le json dépasse les 100kb

$ call_freebox_api /vm/ |wc -c
124045

Avec la fonction colorize_output_pretty_json

time colorize_output_pretty_json $(call_freebox_api /vm/) 2>&1 >/dev/null

real    0m39,325s
user    0m39,017s
sys 0m0,176s

Avec jq

$ time call_freebox_api /vm/ |jq 2>&1 >/dev/null

real    0m39,357s
user    0m39,027s
sys 0m0,208s

Surprenant mais vrai sur un Xeon E5-2698 v4

Idem sur ARM64, les performances d'un snapdragon (celui de la freebox delta) :

$ time colorize_output_pretty_json $(call_freebox_api /vm/) 2>&1 >/dev/null

real    3m14,119s
user    3m12,412s
sys 0m0,863s

avec jq c'est un peu meilleur, de 1,5% :

$ time call_freebox_api /vm/ |jq 2>&1 >/dev/null

real    3m11,655s
user    3m10,227s
sys 0m0,775s

Et sur un mainframe avec des SPARC64 Fujitsu (je n'ai pas jq) mais le pasring grep est sans appel et de très loin bien plus performant que tout ce que j'ai pu tester, 10 fois plus rapide qu'un Xeon haut de gamme des années 2020 et ~55 fois plus rapide que sur les CPU des freebox Delta :

time colorize_output_pretty_json $(call_freebox_api /vm/) 2>&1 >/dev/null

real    0m3,689s
user    0m3,612s
sys 0m0,075s

Bon je vais tester sur une machine de guerre: un AIX power8 (sur lequel je pourrais avoir jq ) pour voir ce que ça donne

PS: l'idée d'attaquer une VM en ssh est bonne mais elle fait modifier l'application pour qu'elle soit capable de faire du SSH 2 et c'est compliqué de recompiler ssh sur la machine. Et vous immaginez bien que si le système a 20 ans et qu'on arrive pas à le migrer pour se séparer des machines qui n'ont pas reboot depuis + de 6000 jours, c'est bien parce qu'il n'y a plus de compétences (les devs ont pris leur retraite depuis 10 ans) ni de library ni de framework, ni rien pour compiler du code de l'an 2000 et encore moins de budget pour le faire... C'était pourtant une bonne piste

Cordialement nbanba

Sylvain303 commented 1 year ago

D'habitude j'ai bien plus de lag, ça se compte en mois pour certains. Vous avez juste passé dans un moment de calme. :smile:

Vous indiquez ce code. Mais ça fait quoi d'autre ce call ?

> $ time call_freebox_api /vm/ |jq 2>&1 >/dev/null 
real 0m39,357s
user 0m39,027s
sys 0m0,208s

Comptez juste le temps de la colorization sans le call d'API, ça donne quoi ? remplacez par :

call_freebox_api /vm/ > t.json
# attention y a un . de root de parsing json avant le nom du fichier.
time jq . t.json  2>&1 >/dev/null 

attaquer une VM en ssh est bonne mais elle fait modifier l'application pour qu'elle soit capable de faire du SSH 2

Alors on doit pouvoir downgrader la config du sshd si c'est pour continuer d’accepter ssh1 ? Ou en http et le sécuriser avec un token, c'est juste qu'il faut écrire un peu de code. Ou en telnet ? Ou en TCP sur un câble RJ45 dédié ?

Vous pouvez demander à chatGPT ? :wink:

donne moi un code qui fait un serveur web en python qui accepte un appel d'API /callfreebox/ avec une authentification par token

sa réponse (qui est un peu merdique)

from flask import Flask, request
from flask_restful import Api, Resource

app = Flask(__name__)
api = Api(app)

TOKEN = "votre_token_ici"

class CallFreebox(Resource):
    def get(self, url_API):
        if request.headers.get("Authorization") != f"Bearer {TOKEN}":
            return {"error": "Invalid token"}, 401
        # Votre code pour appeler l'API Freebox ici
        return {"message": f"Appel de l'API Freebox à l'URL: {url_API}"}

api.add_resource(CallFreebox, "/callfreebox/<string:url_API>")

if __name__ == "__main__":
    app.run(debug=True)

Remplacez python par ce qui compile encore sur la machine ?

J'ai aussi conscience de la problématique de chatGPT et des millions de lignes de code Libre qui ont été déroutées/volées, certes. Et qu'il donne aussi de la merde parfois, et qu'il est souvent saturé.

Si non, à part du interactive rubber duck debugging, comment puis-je vous aider ? :wink:

nbanb commented 1 year ago

Bonjour

Alors je n'avais pas suivi chatGPT (relativement récent), mais j'avoue que ça à l'air terrible ! Sur la machine il y a GCC 4.2 donc du bon vieux C ça compile, mais faut pas trop pousser les librairies et il n'y a pas de LLVM donc faut pas trop se rapprocher du système.

D'autre part, en terme de sécurité (un bien grand mot ici au vu de l'age des systèmes concernés), malheureusement je n'ai pas les mains complètement libres et l'utilisation de flux non cryptés ou de SSH1 ne seront jamais acceptés (même sur 1 câble point-à-point unique)

Suite à un ensemble d'échanges avec ceux qui décident, aujourd'hui ma position est plus de chercher à optimiser le code peu performant que de contourner les soucis de perfs en utilisant des systèmes tiers et n'étant pas développeur, je suis rapidement limité.

d'autre part, vous aviez raison, les tests remontés avec la fonction call_freebox_api ne sont en réalité pas pertinent , car cette fonction appelle une fonction _check_success qui elle même appelle 1 à 3 fois la fonction get_json_value_for_key, cette dernière parsant le json en directe, sans cache au travers de la fonction _parse_and_cache_json qui elle même fait appel aux fonctions de JSON.sh à savoir _parse_json < <(echo $answer | _tokenize_json)

Les temps de comparaisons entre jq et le parsing manuel étaient en fait uniquement ceux du parsing manuel déjà présent dans la fonction call_frebox_api. Le curl manuel seul de la fonction call_frebox_api met au plus une fraction de seconde à afficher 100kb de résultats la ou la fonction complète call_frebox_api met ~40 secondes

Si non, à part du interactive rubber duck debugging, comment puis-je vous aider ?

Si vous êtes développeur et que vous avez une idée pour réécrire de manière complète, rapide et performante le code suivant (j'ai déjà commencé avec la fonction _check_success notament ):

######## FUNCTIONS FROM JSON.SH ########
# This is from https://github.com/dominictarr/JSON.sh

_throw () {
# NBA 20230123: 
# modif to avoid terminal exit when sourcing lib and using function directly in cmdline
   # echo "$*" >&2
    #exit 1
    bash -c "echo -e \"${RED}$*${norm}\" >&2 && exit 1"
    return 1
}

_throw_orig () {
    echo "$*" >&2
    exit 1
}

_tokenize_json () {
    local ESCAPE='(\\[^u[:cntrl:]]|\\u[0-9a-fA-F]{4})'
    local CHAR='[^[:cntrl:]"\\]'
    local STRING="\"$CHAR*($ESCAPE$CHAR*)*\""
    # The Freebox api don't put quote between string values
    # STRING2 solve this problem
    local STRING2="[^:,][a-zA-Z][a-zA-Z0-9_-]*[^],}]"
    local NUMBER='-?(0|[1-9][0-9]*)([.][0-9]*)?([eE][+-]?[0-9]*)?'
    local KEYWORD='null|false|true'
    local SPACE='[[:space:]]+'

    $GREP "$STRING|$STRING2|$NUMBER|$KEYWORD|$SPACE|." | egrep -v "^$SPACE$"
    # " Fix xemacs fontification
}

_parse_array () {
    local index=0
    local ary=''
    read -r token
    case "$token" in
        ']') ;;
        *)
           while : ; do
               _parse_value "${1%*.}" "[$index]."
               index=$((index+1))
               ary="$ary""$value"
               read -r token
               case "$token" in
                   ']') break ;;
                   ',') ary="$ary," ;;
                   *) _throw "EXPECTED , or ] GOT ${token:-EOF}" ;;
               esac
               read -r token
           done
           ;;
    esac
    value=$(printf '[%s]' "$ary")
}

_parse_object () {
    local key
    local obj=''
    read -r token
    case "$token" in
        '}') ;;
        *)
           while : ; do
               case "$token" in
                   '"'*'"') key=$token;;
                   *) _throw "EXPECTED string GOT ${token:-EOF}" ;;
               esac
               read -r token
               case "$token" in
                   ':') ;;
                   *) _throw "EXPECTED : GOT ${token:-EOF}" ;;
               esac
               read -r token
               _parse_value "$1" "$key"
               obj="$obj$key:$value"
               read -r token
               case "$token" in
                   '}') break ;;
                   ',') obj="$obj," ;;
                   *) _throw "EXPECTED , or } GOT ${token:-EOF}" ;;
               esac
               read -r token
           done
           ;;
    esac
    value=$(printf '{%s}' "$obj")
}

_parse_value () {
    local jpath="${1:-}${2:-}"
    case "$token" in
        '{') _parse_object "$jpath" ;;
        '[') _parse_array  "$jpath";;
        # At this point, the only valid single-character tokens are digits.
        ''|[!0-9]) _throw "EXPECTED value GOT ${token:-EOF}" ;;
        *) value=$token ;;
    esac
    [ "${value:-}" = '' ] && return
    jpath=${jpath//\"\"/.}
    jpath=${jpath//\"/}
    local key="${jpath%*.}"
    [[ "$key" = '' ]] && return
    _JSON_DECODE_DATA_KEYS+=("$key")
    value=${value#\"}  # Remove leading "
    value=${value%*\"} # Remove trailing "
    value=${value//\\\///} # convert \/ to /
    _JSON_DECODE_DATA_VALUES+=("$value")
    # NBA       
    #_JSON_NBA+=("${key}=${value}\n")
}

_parse_json () {
    read -r token
    _parse_value
    read -r token
    case "$token" in
        '') ;;
        *) _throw "EXPECTED EOF GOT $token" ;;
    esac
}

######## END OF FUNCTIONS FROM JSON.SH ########

########  LIBRARY API CORE FUNCTIONS  #########

_parse_and_cache_json () {
    if [[ "$_JSON_DATA" != "$1" ]]; then
        _JSON_DATA="$1"
        _JSON_DECODE_DATA_KEYS=("")
        _JSON_DECODE_DATA_VALUES=("")
        _parse_json < <(echo "$_JSON_DATA" | _tokenize_json)
    fi
}

get_json_value_for_key2 () {
    _parse_and_cache_json "$1"
    local key i=1 max_index=${#_JSON_DECODE_DATA_KEYS[@]};
   # local _JSON_NBA=("\"${_JSON_DECODE_DATA_KEYS[@]}\" = \"${_JSON_DECODE_DATA_VALUES[@]}\"")
    #echo -e "${_JSON_NBA[@]}"
    local chk="${2//\[/\\\[}"
    chk="${chk//\]/\\\]}"
    #echo $chk
    echo -e "${_JSON_NBA[@]}"  |egrep ${chk}|cut -d= -f2-
}

get_json_value_for_key () {
    _parse_and_cache_json "$1"
    local key i=1 max_index=${#_JSON_DECODE_DATA_KEYS[@]};
    while [[ $i -lt $max_index ]]; do
        if [[ "${_JSON_DECODE_DATA_KEYS[$i]}" = "$2" ]]; then
            echo ${_JSON_DECODE_DATA_VALUES[$i]}
            return 0
        fi
        ((i++))
    done
    return 1
}

dump_json_keys_values () {
    _parse_and_cache_json "$1"
    local key i=1 max_index=${#_JSON_DECODE_DATA_KEYS[@]};
    while [[ $i -lt $max_index ]]; do
        printf "%s = %s\n" "${_JSON_DECODE_DATA_KEYS[$i]}" "${_JSON_DECODE_DATA_VALUES[$i]}"
        ((i++))
    done
}

# NBA: Original _check_success function: too slow
_check_success_old () {
    local value=$(get_json_value_for_key "$1" success)
    if [[ "$value" != true ]]; then
        #echo "$(get_json_value_for_key "$1" msg): $(get_json_value_for_key "$1" error_code)" >&2
        echo -e "${RED}$(get_json_value_for_key "$1" msg): $(get_json_value_for_key "$1" error_code)${norm}" >&2
        return 1
    fi
    return 0
}

_check_success () {
    #  NBA  
    local val="${1}"
    local value=$(echo ${val} \
                        |tr "," "\n" \
                        |egrep success \
                        |cut -d':' -f2 \
                        |sed -e 's/,//g' -e 's/}\+//g'  
                )
    #echo "$val" >&2 
    #echo $value  >&2 
    if [[ "$value" != true ]]
    then 
            #echo "$val" >&2 
            echo  -e "${RED}$(echo ${val} |tr "," "\n" |egrep msg |cut -d'"' -f4): $(echo ${val} |tr "," "\n" |egrep error_code |cut -d'"' -f4)${norm}" >&2
            return 1
    fi
    return 0
}

_check_freebox_api () {
    local options=("")
    mk_bundle_cert_file fbx-cacert                # create CACERT BUNDLE FILE
    [[ -n "$FREEBOX_CACERT" ]] && [[ -f "$FREEBOX_CACERT" ]] \
            && options+=(--cacert "$FREEBOX_CACERT") \
            || options+=("-k")
    local answer=$(curl -s "${options[@]}" "$FREEBOX_URL/api_version")
    _API_VERSION=$(get_json_value_for_key "$answer" api_version | sed 's/\..*//')
    _API_BASE_URL=$(get_json_value_for_key "$answer" api_base_url)
    del_bundle_cert_file fbx-cacert               # remove CACERT BUNDLE FILE
}

# simple API call using curl automatic GET or POST detection (simple POST)  
call_freebox_api () {
    local api_url="$1"
    local data="${2-}"
    local options=("")
    local url="$FREEBOX_URL"$( echo "/$_API_BASE_URL/v$_API_VERSION/$api_url" | sed 's@//@/@g')
    [[ -n "$_SESSION_TOKEN" ]] && options+=(-H "X-Fbx-App-Auth: $_SESSION_TOKEN")
    [[ -n "$data" ]] && options+=(-d "$data")
    mk_bundle_cert_file fbx-cacert                # create CACERT BUNDLE FILE
    [[ -n "$FREEBOX_CACERT" ]] && [[ -f "$FREEBOX_CACERT" ]] \
            && options+=(--cacert "$FREEBOX_CACERT") \
            || options+=("-k")
    answer=$(curl -s "$url" "${options[@]}")
    _check_success "$answer" || return 1
    echo "$answer"
    del_bundle_cert_file fbx-cacert               # remove CACERT BUNDLE FILE
}

Si vous voulez voir la totalité du code ajouté depuis que j'ai repris le projet (~ +3500 lignes, la library d'origine ne faisait que 220 lignes) le projet est dispo ici : fbx-delta-nba_bash_api.sh

Et n'étant pas développeur, j'avoue avoir du mal à optimiser le code existant, fonctionnel mais trop lent (quelques exemples au dessus comme get_json_value_for_key2 () , _check_success () ...

En vous remerciant encore pour votre aide, Cordialement nbanba

Sylvain303 commented 1 year ago

du bon vieux C ça compile, mais faut pas trop pousser les librairies et il n'y a pas de LLVM donc faut pas trop se rapprocher du système.

Alors y a https://github.com/DaveGamble/cJSON par exemple ça compilerait ?

https://github.com/sheredom/json.h

https://github.com/search?q=c+json+parser

Bon après si vous n'êtes pas développer C, c'est assez limité pour vous voir plus bas...

(même sur 1 câble point-à-point unique)

Ah dommage. c'est pourtant difficile à pirater. :wink:

d'autre part, vous aviez raison, les tests remontés avec la fonction call_freebox_api ne sont en réalité pas pertinent , car cette fonction appelle une fonction _check_success qui elle même appelle 1 à 3 fois la fonction get_json_value_for_key,

ah, donc jq il dépote bien (il est rapide) comme prévu. Ouf.

Si non, à part du interactive rubber duck debugging, comment puis-je vous aider ?

Si vous êtes développeur et que vous avez une idée pour réécrire de manière complète, rapide et performante le code suivant (j'ai déjà commencé avec la fonction _check_success notament ):

Bon, j'ai vu votre issue dans le projet source, c'est effectivement d'eux que ça dépend. https://github.com/dominictarr/JSON.sh/issues (pas de modif depuis 6 ans sur le code, y a assez peu de chance que ça bouge, :man_shrugging: )

Engagez un développeur C free lance pour vous compiler une lib vanilla C qui passe ?

Je n'ai pas d'intérêt à utiliser JSON.sh de mon côté. Bien que j'ai les compétences pour optimiser le code, sous certaines conditions d'usage, je n'encouragerais pas cette pratique. J'ai bien conscience de votre problématique, qui demeure un défit fort intéressant, mais à part les work-around que j'ai mentionné, je suis bientôt à cours d'idées.

perl ?

À suivre, Sylvain.

nbanb commented 1 year ago

Bonjour

Merci beaucoup pour vos retours et toutes les idées...!

Suite à de nouveaux échanges avec les décideurs, je vais devoir faire 2 choses :

  1. écrire une version en remplaçant le parsing manuel par 'jq'
  2. optimiser et accélérer les fonctions de parsing manuel

Partout ou l'on peut, on utilisera 'jq', mais on utilisera également le parsing manuel pour parser les retours de certaines API et pas uniquement de l'API de la freebox mais par exemple les retours de l'API des firewalls Fortigate depuis des appliances sur lesquelles on ne peut rien installer (appliances sécu, apliances systèmes, Access Point WIFI qui poll l'API du contrôleur WIFI pour de l'autoenrollement, déploiement automatisés sur et depuis des switchs ONIE ...) ou sur certains systèmes embarqués ne disposant que de BusyBox. Malheureusement, plus je creuse, plus je recense de cas ou le parsing manuel des retours d'API en json est inévitable sans déployer des usines à gaz dans des environnements déjà complexes avec architecture figée ou complètement isolés. D'autre part, ces systèmes sont généralement peu puissant d'où la nécessité d'utiliser du code performant.

Je reviendrai peut-être vers vous concernant l'un ou l'autre des 2 points notamment si je me retrouve bloqué ou limité. Après, vous n'êtes pas obligé de m'aider le cas échéant, ça restera bien évidemment à votre convenance.

En vous remerciant encore pour votre aide, avec un + tout spécial pour ChatGPT que je n'avais pas testé et que je trouve terrible !

Cordialement nbanba

Sylvain303 commented 1 year ago

Salut @nbanb

Ravi d'avoir pu vous aidé. Si j'ai des dispos je vous ferai signe. :wink: (j'en doute mais on verra)

Concernant ChatGPT, il faut aussi s’instruire de la controverse si on s'intéresse au Libre:

Sur le site de la FSF, ils ont mis un lien vers un site : https://libreplanet.org/wiki/Group:Copilot_Watch_Group

Mais il est évident que 2023 verra un grand bouleversement dans la façon d'écrire du code. Et de qui peut écrire du code. Et dans la présence de IA au quotidien.

Je vous recommande aussi Coded Bias : Algorithmes et discrimination un documentaire sur netflix.

Vous écrivez:

écrire une version en remplaçant le parsing manuel par 'jq'

Il me semble que c'est ce que j'avais fait dans ce fork concernant la lib freeboxos-bash-api. J'avoue n'avoir pas relu le code, et encore moins re-tester.

Ah je n'ai pas mis de license dans le dépôt, je peux ajouter GPLv3 on MIT qui est moins contraignante/engageante :wink: .

Le code d'origine a désormais une licence GPLv3: https://github.com/JrCs/freeboxos-bash-api/blob/master/LICENSE

Ce qui règle le problème du choix !

Bonne aventure dans le legacy code. :smile: Cordialement, Sylvain.