soz.sh

A server-side HTTP client for DICT protocol.
git clone git://efe.kim/soz.sh
Log | Files | Refs

commit 60fc3b75d78722eb8030fa300c20da33936b706c
Author: Sunur Efe Vural <efe@efe.kim>
Date:   Sat,  7 Sep 2019 10:56:56 -0400

initialize

Diffstat:
Asoz.sh | 265+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 265 insertions(+), 0 deletions(-)

diff --git a/soz.sh b/soz.sh @@ -0,0 +1,265 @@ +#!/bin/sh +# Dep: curl, sed, GNU xargs, uniq, sort, cat +# DICT Protocol: RFC 2229 + +# Fix: Percent Decode matched word href + +LANG=C +IFS=$(printf '\n\r') + +PercentDecode() { + sed ' + s/^+*// + s/+*$// + s/++*/ /g + s/%/\\x/g + ' | xargs -0 printf # Not POSIX +} + +EscapeChars() { + sed ' + s/&/\&amp;/g + s/</\&lt;/g + s/>/\&gt;/g + s/\"/\&quot;/g + s/'\''/\&#39;/g + s/\//\&#x2F;/g + s/`/\&#x60;/g + s/=/\&#x3D;/g + ' +} + +FormatField() { +# Example: FormatField "$line" '<a href="%s">%s</a>\n' \$3 \$1 + line="$1" + printeval=\'$2\' + shift 2 + for s + do + printeval="$printeval \"$s\"" + done + set -- + IFS=" " + for word in $line + do + if [ -z "$in_quote" ] + then + case "$word" in + \"*\") + field=${word#\"} + set -- "$@" "${field%\"}" + ;; + \"*) + in_quote=1 + field=${word#\"} + ;; + *) + field=$word + set -- "$@" "$field" + ;; + esac + else + case "$word" in + *\") + unset in_quote + field="${field} ${word%\"}" + set -- "$@" "$field" + ;; + *) + field="${field} ${word}" + ;; + esac + fi + done + unset IFS + eval "printf $printeval" +} + +QueryServer() { + command="$1" + set -- + for line in $(curl -s dict://127.0.0.1:2628/"${command}") + do + if [ -n "$text" ] + then + case "$line" in + ..) + printf '.<br/>' + ;; + .) + case "$text" in + match) + for s in $(printf "%s\n" "$@" | sort | uniq) + do + printf '<a href="/?q=%s%s%s" rel="nofollow">%s</a> ' \ + "$s" "${QUERY_DICT:+&d=}" "$dict" "$s" + done + printf '</p>' + ;; + definition) + printf '</p>' + ;; + esac + unset text + ;; + *) + case "$text" in + db) + case $(FormatField "$line" '%s' \$1) in + "$QUERY_DICT") + FormatField "$line" \ + '<option selected value="%s">%s</option>\n' \ + \$1 \$2 + ;; + *) + FormatField "$line" \ + '<option value="%s">%s</option>\n' \ + \$1 \$2 + ;; + esac + ;; + match) + set -- "$@" "$(FormatField "$line" '%s' \$2)" + ;; + info) + printf '%s\n' "$line" + ;; + header) + printf '<h4 class="word">%s</h4><p class="definition">\n' "$line" + text=definition + ;; + definition) + printf '%s<br/>' "$line" + ;; + esac + ;; + + esac + else + case "$line" in + 420*|421*|500*|501*|502*|503*|530*) + printf '<p>%s hatası. Devam ederse %s adresine bildiriniz.</p>' \ + "${line%% *}" "sungur@ariduruturkce.org" + break + ;; + 152*) + printf '<p>«%s» sözüyle eşleşen şu sözler var: ' "$query" + text=match + ;; + 110*) + text=db + ;; + 112*|114*) + text=info + ;; + 552*) + case "$command" in + m:*) + printf '<p>«%s» sözüyle eşleşen herhangi bir söz yok.</p>' "$query" + ;; + d:*) + printf '<p>«%s» sözünün aynısı yok.</p>' "$query" + QueryServer "m:${QUERY_WORD}:${QUERY_DICT:-*}" + ;; + esac + break + ;; + 151*) + FormatField "$line" '<h3 class="dict"><a href="/?i=dict&d=%s">%s</a></h3>' \$3 \$4 + text=header + ;; + esac + fi + done +} + +DisplayBlock() { + [ -n "$QUERY_WORD" ] || [ -n "$QUERY_INFO" ] && + printf '<div id="main"><h2 id=word>%s</h2>' "$query" + if [ -n "$QUERY_WORD" ] && [ -n "$QUERY_MATCH" ] + then + QueryServer "m:${QUERY_WORD}:${QUERY_DICT:-*}:${QUERY_MATCH}" + elif [ -n "$QUERY_WORD" ] + then + QueryServer "d:${QUERY_WORD}:${QUERY_DICT:-*}" + elif [ -n "$QUERY_INFO" ] + then + case "$QUERY_INFO" in + server) + printf '<pre>' + QueryServer 'show:server' + printf '\n</pre>' + ;; + dict) + printf '<pre>' + QueryServer "show:info:${QUERY_DICT}" + printf '\n</pre>' + ;; + esac + fi + [ -n "$QUERY_WORD" ] || [ -n "$QUERY_INFO" ] && + printf '</div>' +} + +printf "Content-type: text/html\r\n\r\n" + +# Use escaped values whenever the variable is inserted into HTML +query=$(printf '%s' "$QUERY_WORD" | PercentDecode | EscapeChars) +dict=$(printf '%s' "$QUERY_DICT" | PercentDecode | EscapeChars) + +cat << !__EOF__ +<!DOCTYPE html> +<html dir="ltr" lang="tr"> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Language" content="tr" /> + <meta content="width=device-width" name="viewport" /> + <meta content="sözlük, nedir, anlam, türkçe, türk, özbekçe, uygurca, + mana, anlam, anlamı, tatarca, türkmence, kırgızca" name="keywords" /> + <meta content="${query} ne demek, ${query} nedir, + ${query} anlamı, Türk Dilleri Sözlükleri" name="description" /> + <meta content="Arı Duru Türkçe" name="author" /> + <title>ADT - Türk Dilleri Sözlükleri</title> + <link rel="stylesheet" href="/style.css" type="text/css" media="screen" /> + <link rel="stylesheet" href="/print.css" type="text/css" media="print" /> + <link rel="icon" type="image/png" href="/favicon.png" /> +</head> +<body> +<div id="content"> +<div id="menuwrap"> + <a id="logo" href="/"> + <img height="57" src="/banner.svg" + alt="[Arı Duru Türkçe | Uydurukça değil Türkçe!]"> + </a> + <div id="menu"> + <ul id="links"> + <li><a href="/" title="Sözlük">Sözlük</a></li> + <li><a href="/?i=server" title="Yönünde">Hakkında</a></li> + <li><a href="http://ariduruturkce.org" + title="Arı Duru Türkçe">ADT</a></li> + </ul> + </div> + <form id="dict-form" action="/" method="get"> + <input type="text" required placeholder="${query}" + name="q" spellcheck="off" autocapitalize="off" + autocorrect="off" autocomplete="off" id="ara" /> + <input type="submit" value="Ara" /> + <select name="d"> + <option value="">Bütün Sözlükler</option> + $(QueryServer show:db) + </select> + <select name="m"> + <option value="">Birebir Eşleşme</option> + <option value="prefix">Baştan Eşleşme</option> + <option value="suffix">Sondan Eşleşme</option> + <option value="substring">İçten Eşleşme</option> + <option value="regexp">Kurallı Eşleşme (Regexp)</option> + <option value="lev">Levenshtein 1. Uzaklık Eşleşme</option> + </select> + </form> +</div> +$(DisplayBlock) +</div> +</body> +</html> +!__EOF__