From 5eb8ef63f636e1db70cc580b767c9efab9abed69 Mon Sep 17 00:00:00 2001 From: Vitaly Lipatov <lav@etersoft.ru> Date: Wed, 7 Dec 2016 22:04:26 +0300 Subject: [PATCH] epm-site: fix json parsing --- bin/epm-site | 25 ++++-- bin/tools_json | 211 +++++++++++++++++++++++++++++++++++++++++++++ pack_in_onefile.sh | 2 + 3 files changed, 232 insertions(+), 6 deletions(-) create mode 100755 bin/tools_json diff --git a/bin/epm-site b/bin/epm-site index c48ccb48..0789ec86 100644 --- a/bin/epm-site +++ b/bin/epm-site @@ -22,6 +22,24 @@ load_helper epm-print PAOURL="https://packages.altlinux.org" +paoapi() +{ + # http://petstore.swagger.io/?url=http://packages.altlinux.org/api/docs + epm assure curl || return 1 + showcmd curl "$PAOURL/api/$1" + a= curl -s --header "Accept: application/json" "$PAOURL/api/$1" +} + +# TODO: use /home/lav/Projects/git/JSON.sh +get_pao_var() +{ + local FIELD="$1" + #grep '"$FIELD"' | sed -e 's|.*"$FIELD":"||g' | sed -e 's|".*||g' + $SHAREDIR/tools_json -b | egrep "\[.*\"$FIELD\"\]" | sed -e 's|.*[[:space:]]"\(.*\)"|\1|g' + return 0 +} + + run_command_if_exists() { local CMD="$1" @@ -43,14 +61,9 @@ open_browser() __query_package_hl_url() { - local PAOAPI="$PAOURL/api" case $DISTRNAME in ALTLinux) - # http://petstore.swagger.io/?url=http://packages.altlinux.org/api/docs - epm assure curl || return 1 - showcmd curl "$PAOAPI/srpms/$1" - a= curl -s --header "Accept: application/json" "$PAOAPI/srpms/$1" | grep '"url"' | sed -e 's|.*"url":"||g' | sed -e 's|".*||g' - return 0 + paoapi srpms/$1 | get_pao_var url ;; esac return 1 diff --git a/bin/tools_json b/bin/tools_json new file mode 100755 index 00000000..c4452f9b --- /dev/null +++ b/bin/tools_json @@ -0,0 +1,211 @@ +#!/bin/sh + +# License: MIT or Apache +# Homepage: http://github.com/dominictarr/JSON.sh + +throw() { + echo "$*" >&2 + exit 1 +} + +BRIEF=0 +LEAFONLY=0 +PRUNE=0 +NO_HEAD=0 +NORMALIZE_SOLIDUS=0 + +usage() { + echo + echo "Usage: JSON.sh [-b] [-l] [-p] [-s] [-h]" + echo + echo "-p - Prune empty. Exclude fields with empty values." + echo "-l - Leaf only. Only show leaf nodes, which stops data duplication." + echo "-b - Brief. Combines 'Leaf only' and 'Prune empty' options." + echo "-n - No-head. Do not show nodes that have no path (lines that start with [])." + echo "-s - Remove escaping of the solidus symbol (straight slash)." + echo "-h - This help text." + echo +} + +parse_options() { + set -- "$@" + local ARGN=$# + while [ "$ARGN" -ne 0 ] + do + case $1 in + -h) usage + exit 0 + ;; + -b) BRIEF=1 + LEAFONLY=1 + PRUNE=1 + ;; + -l) LEAFONLY=1 + ;; + -p) PRUNE=1 + ;; + -n) NO_HEAD=1 + ;; + -s) NORMALIZE_SOLIDUS=1 + ;; + ?*) echo "ERROR: Unknown option." + usage + exit 0 + ;; + esac + shift 1 + ARGN=$((ARGN-1)) + done +} + +awk_egrep () { + local pattern_string=$1 + + gawk '{ + while ($0) { + start=match($0, pattern); + token=substr($0, start, RLENGTH); + print token; + $0=substr($0, start+RLENGTH); + } + }' pattern="$pattern_string" +} + +tokenize () { + local GREP + local ESCAPE + local CHAR + + if echo "test string" | egrep -ao --color=never "test" >/dev/null 2>&1 + then + GREP='egrep -ao --color=never' + else + GREP='egrep -ao' + fi + + if echo "test string" | egrep -o "test" >/dev/null 2>&1 + then + ESCAPE='(\\[^u[:cntrl:]]|\\u[0-9a-fA-F]{4})' + CHAR='[^[:cntrl:]"\\]' + else + GREP=awk_egrep + ESCAPE='(\\\\[^u[:cntrl:]]|\\u[0-9a-fA-F]{4})' + CHAR='[^[:cntrl:]"\\\\]' + fi + + local STRING="\"$CHAR*($ESCAPE$CHAR*)*\"" + local NUMBER='-?(0|[1-9][0-9]*)([.][0-9]*)?([eE][+-]?[0-9]*)?' + local KEYWORD='null|false|true' + local SPACE='[[:space:]]+' + + # Force zsh to expand $A into multiple words + local is_wordsplit_disabled=$(unsetopt 2>/dev/null | grep -c '^shwordsplit$') + if [ $is_wordsplit_disabled != 0 ]; then setopt shwordsplit; fi + $GREP "$STRING|$NUMBER|$KEYWORD|$SPACE|." | egrep -v "^$SPACE$" + if [ $is_wordsplit_disabled != 0 ]; then unsetopt shwordsplit; fi +} + +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 + [ "$BRIEF" -eq 0 ] && value=$(printf '[%s]' "$ary") || value= + : +} + +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 + [ "$BRIEF" -eq 0 ] && value=$(printf '{%s}' "$obj") || value= + : +} + +parse_value () { + local jpath="${1:+$1,}$2" isleaf=0 isempty=0 print=0 + 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 + # if asked, replace solidus ("\/") in json strings with normalized value: "/" + [ "$NORMALIZE_SOLIDUS" -eq 1 ] && value=$(echo "$value" | sed 's#\\/#/#g') + isleaf=1 + [ "$value" = '""' ] && isempty=1 + ;; + esac + [ "$value" = '' ] && return + [ "$NO_HEAD" -eq 1 ] && [ -z "$jpath" ] && return + + [ "$LEAFONLY" -eq 0 ] && [ "$PRUNE" -eq 0 ] && print=1 + [ "$LEAFONLY" -eq 1 ] && [ "$isleaf" -eq 1 ] && [ $PRUNE -eq 0 ] && print=1 + [ "$LEAFONLY" -eq 0 ] && [ "$PRUNE" -eq 1 ] && [ "$isempty" -eq 0 ] && print=1 + [ "$LEAFONLY" -eq 1 ] && [ "$isleaf" -eq 1 ] && \ + [ $PRUNE -eq 1 ] && [ $isempty -eq 0 ] && print=1 + [ "$print" -eq 1 ] && printf "[%s]\t%s\n" "$jpath" "$value" + : +} + +parse () { + read -r token + parse_value + read -r token + case "$token" in + '') ;; + *) throw "EXPECTED EOF GOT $token" ;; + esac +} + +if ([ "$0" = "$BASH_SOURCE" ] || ! [ -n "$BASH_SOURCE" ]); +then + parse_options "$@" + tokenize | parse +fi + +# vi: expandtab sw=2 ts=2 diff --git a/pack_in_onefile.sh b/pack_in_onefile.sh index 68182e24..ec5a51b6 100755 --- a/pack_in_onefile.sh +++ b/pack_in_onefile.sh @@ -44,6 +44,7 @@ filter_out() { grep -v "^[ ]*load_helper " | \ sed -e 's|$SHAREDIR/tools_eget|internal_tools_eget|g' | \ + sed -e 's|$SHAREDIR/tools_json|internal_tools_json|g' | \ sed -e 's|DISTRVENDOR=$PROGDIR/distr_info|DISTRVENDOR=internal_distr_info|g' | \ sed -e "s|@VERSION@|$(get_version)|g" @@ -64,6 +65,7 @@ done | filter_out >>$OUTPUT incorporate_subfile distr_info incorporate_subfile tools_eget +incorporate_subfile tools_json awk 'BEGIN{desk=0}{if(desk>0) {print} ; if(/^load_helper epm-sh-functions/){desk++}}' <bin/$PACKCOMMAND | filter_out >>$OUTPUT chmod 0755 $OUTPUT -- 2.24.1