Sblocco Smart Modem TIM Technicolor TG789 vac (AGTOT)

Interessante articolo per la gestione del router fibra tim 1.04

Nel passaggio del firmware dalla versione 1.0.2 alla versione 1.0.4 è stata modificata la chiave di criptazione del file di configurazione rendendo non modificabile la stessa ed è inoltre stato rimosso il menù segreto originale di Technicolor.

Chi possiede il modem alla versione AGTOT_1.0.2 può utilizzare la seguente guida:

Per poter utilizzare questi comandi mi rifaccio alla guida di  AlezzioZ_

  1. Se non lo avete già, scaricatevi OpenSSL
    io utilizzo ( https://indy.fulgan.com/SSL/openssl-1.0.2k-x64_86-win64.zip );
  2. Estraete lo zip;
  3. Nella cartella appena creata inserite il file di backup generato dal modem chiamato user_config.ini;
  4. Aprite una finestra Dos (cmd) e date:
    openssl aes-128-cbc -K a0dd1da4242d32424fdffaa0ed0e0f12 -nosalt -iv 0 -d -in user_config.ini -out user.ini
  5. Avete appena generato il file user.ini in chiaro dove potete leggere ed apportare modifiche alla attuale configurazione.
  6. Per caricarlo nuovamente sul modem dovrete trasformarlo nuovamente in file cryptato. Per cui, a modifiche terminate e salvate date:
    openssl aes-128-cbc -K a0dd1da4242d32424fdffaa0ed0e0f12 -nosalt -iv 0 -e -in user.ini -out newuser_config.ini

Per la versione AGTOT_1.0.4 la chiave è stata cambiata nella seguente:

openssl aes-128-cbc -K a875e62aa6f1d430dac45fcd0e3bb246 -nosalt -iv 0 -d -in user_config.ini -out user.ini (Per decriptare)
openssl aes-128-cbc -K a875e62aa6f1d430dac45fcd0e3bb246 -nosalt -iv 0 -e -in user.ini -out user_config.ini (Per criptare)

Attenzione!
Se a seguito dell’uso di questi comandi, vi ritroverete davanti con questo errore:
digital envelope routines:EVP_DecryptFinal_ex:bad decrypt:evp_enc.c:529:
Il file user_config.ini decriptato presenterà alle ultime righe questi caratteri
Per risolvere basterà eliminare tutto ciò che è sottostante [ endofarch ]
Non contiene nulla è solo sporcizia creatosi da qualche errore di criptazione del programma sul modem

Una volta decriptato il file di configurazione vi troverete davanti a un file di testo strutturato per sezioni, che contiene tutti comandi che il modem utilizza all’avvio per configurare l’hardware, i servizi, le periferiche e i permessi.

Per attivare un utente con ruolo root e quindi avere accesso alla shell interna, la cosa più semplice è copiare la riga dell’utente Administrator, che è quello di cui conosciamo la password (di default admin), dare un nuovo nome all’utente copiato (ad esempio r00t) e modificare il ruolo da Administrator a root nel file user.ini.

Ricordiamo a tal proposito che  il nome utente root vero e proprio, essendo l’amministratore del sistema linux sottostante, resta ovviamente riservato e non può essere utilizzato.

Purtroppo però dalla versione 1.0.4, il firmware non accetta più valori di user con ruolo root. Eventuali utenti di questo tipo vengono eliminati. Per aggirare questa ulteriore protezione aggiungiamo manualmente un ruolo che abbia gli stessi diritti del ruolo root:

Guida passo passo allo sblocco

  1. Una volta decriptato il file aggiungete questi due user nella sezione mlpuser.ini:
    add
    name=Unlock
    password=_CYP2_53e2ac63e7b839c0708ec54912d3a36c87d6655ade7089b8
    role=BHSAdmin hash2=d77b2bd8ab60bf664ac7d6151215b9f4 crypt=GiD5FRyGAVFGI


    add name=R00t
    password=_CYP2_53e2ac63e7b839c0708ec54912d3a36c87d6655ade7089b8 role=ALL
    hash2=d77b2bd8ab60bf664ac7d6151215b9f4 crypt=GiD5FRyGAVFGI

     
  2. Cercate questo testo e modificate da disabled ad enabled
    modify name=TELNET state=disabled natpmweight=10
    modify name=FTP state=disabled natpmweight=10

  3. Cercate questo testo nella sezione cwmp.ini e modificate da full a read-only
    config state=enabled mode=full periodicInform=disabled periodicInfInt=43200 sessionTimeout=60 noIpTimeout=180 maxEnvelopes=1 connectionRequest=enabled connectionReqAuth=digest bootdelayrange=0 persistentSubscription=enabled connectionReqThrotNumber=1 connectionReqThrotTime=0 activeNotifThrotTime=0 maxWriteBufferSize=4096 showPasswords=enabled

Terminate queste operazioni avrete il vostro nuovo file di configurazione  è pronto per essere caricato nuovamente nel modem.

Spiegazione estensiva modifica n.3
Settando il cwmp in read-only renderete il modem ugualmente accessibile dal gestore, ma con la particolarità che esso non potrà effettuare alcun comando (reset configurazione, aggiornamenti firmware). Così facendo, saranno tranquillamente visualizzabili i propri dati dalla app MyTimFisso in remoto senza alcun problema, esclusa la non possibilità di eseguire comandi in remoto quali per esempio il riavvio o lo spegnimento del wifi. 

La procedura è la seguente

  1. Criptate il file user.ini con il comando SSL sopra indicato, otterrete il nuovo user_config.ini;
  2. Caricare il file config_user.ini da interfaccia TIM dal menù Manutenzione;
  3. Il modem si riavvierà;
  4. Accedete in FTP al modem (con un qualsiasi client FTP come FileZilla o WinSCP)
    IP: quello che usate per accedere all’interfaccia, di norma 192.168.1.1
    User: Unlock
    Password: root
  5. Sovrascrivete il file security.cfg con il mio file presente nel repository;
  6. Ricaricate nuovamente lo stesso file config_user.ini precedentemente criptato da interfaccia TIM dal menù Manutenzione;
  7. Il modem si riavvierà.

A termine della procedura avrete accesso con privilegi root al modem

Nome utente: R00t

Password: root

Da questo momento avete accesso alla shell interna, e avendo disattivando la telegestione, siete finalmente “possessori” del vostro modem e potete usarlo al massimo delle sue potenzialità.
Si specifica che questa procedura non arreca cambiamenti all’interfaccia del modem, è normale che nella pagina del login rimanga come unico utente di accesso l’Administrator, quello è un limite della pagina e non può essere modificato!

Seguiranno nuove guide per spiegarvi come effettuare modifiche specifiche alla configurazione, quali il routing, i server DNS, il fuso orario, le modalità only bridge, le sessioni PPP, il WiFi, e altro ancora !

Vi invitiamo a partecipare al topic ufficiale dell’articolo sul forum, in cui potete scrivere anche in caso di dubbi o domande.

Comandi per telecamera wanscam HW0045

VIDEO

rtsp://admin:instar@IP-Address:RTSP-Port/11 :: VLC Stream

http://admin:instar@IP-Address:Port/iphone/11 :: Quicktime Stream

http://IP-Address:Port/tmpfs/snap.jpg?usr=admin&pwd=instar :: Snapshot (720p / 1280×720 Pixel)

http://IP-Address:Port/tmpfs/auto.jpg?usr=admin&pwd=instar :: Snapshot (352p or 176p)

http://IP-Address:Port/cgi-bin/hi3510/mjpegstream.cgi?-chn=11&-usr=admin&-pwd=instar :: MJPEG Stream
also note the additional SDK documentation for accessing video / audio

PTZ

http://IP-Address:Port/cgi-bin/hi3510/ptzctrl.cgi?-step=0&-act=right :: Moves continuously right

http://IP-Address:Port/cgi-bin/hi3510/ptzctrl.cgi?-step=0&-act=left :: Moves continuously left

http://IP-Address:Port/cgi-bin/hi3510/ptzctrl.cgi?-step=0&-act=up :: Moves continuously up

http://IP-Address:Port/cgi-bin/hi3510/ptzctrl.cgi?-step=0&-act=down :: Moves continuously down

http://IP-Address:Port/cgi-bin/hi3510/ptzctrl.cgi?-step=0&-act=stop :: Stops moving camera-head

http://IP-Address:Port/cgi-bin/hi3510/ptzctrl.cgi?-step=1&-act=right :: Moves one step right

http://IP-Address:Port/cgi-bin/hi3510/ptzctrl.cgi?-step=1&-act=left :: Moves one step left

http://IP-Address:Port/cgi-bin/hi3510/ptzctrl.cgi?-step=1&-act=up :: Moves one step up

http://IP-Address:Port/cgi-bin/hi3510/ptzctrl.cgi?-step=1&-act=down :: Moves one step down

http://IP-Address:Port/cgi-bin/hi3510/ptzctrl.cgi?-step=0&-act=home :: Go to Center Position

http://IP-Address:Port/cgi-bin/hi3510/ptzctrl.cgi?-step=0&-act=hscan :: Scan horizontal

http://IP-Address:Port/cgi-bin/hi3510/ptzctrl.cgi?-step=0&-act=vscan :: Scan vertical

http://IP-Address:Port/cgi-bin/hi3510/preset.cgi?-act=set&-status=1&-number=[0-7] :: set a position

http://IP-Address:Port/cgi-bin/hi3510/preset.cgi?-act=set&-status=0&-number=[0-7] :: unset a position

http://IP-Address:Port/cgi-bin/hi3510/preset.cgi?-act=goto&-status=1&-number=[0-7] :: goto to a set position

IMAGE

http://IP-Address:Port/cgi-bin/hi3510/param.cgi?cmd=setimageattr :: Sets the Image Parameter
You can set the following parameters:

brightness :: [0 – 255] the bigger the value the brighter the image

saturation :: [0 – 255] the bigger the value the more saturation the image has

contrast :: [0 – 255] the bigger the value the more contrast the image has

hue :: [0 – 127] the bigger the value the more hue the image has

flip :: (on , off) flips the image

mirror :: (on , off) flips the image

scene :: (auto , indoor , outdoor) sets the white balance mode
http://IP-Address:Port/cgi-bin/hi3510/param.cgi?cmd=setimageattr&-brightness=0&-saturation=0&-contrast=0&-hue=0&-flip=off&-mirror=off&-scene=auto

WLAN

reset the parameter values

http://192.168.xxx.xxx./cgi-bin/hi3510/param.cgi?cmd=setwirelessattr&-wf_ssid=SSID&-wf_enable=0&-wf_auth=2&-wf_key=1234&-wf_enc=1&-wf_mode=0

IR-LED

http://192.168.178.87/cgi-bin/hi3510/param.cgi?cmd=setinfrared&-infraredstat=auto :: Sets IR LED’s to auto mode

http://192.168.178.87/cgi-bin/hi3510/param.cgi?cmd=setinfrared&-infraredstat=open :: Sets IR LED’s always active :: only IN-6011

http://192.168.178.87/cgi-bin/hi3510/param.cgi?cmd=setinfrared&-infraredstat=close :: Sets IR LED’s always inactive

ALARM

http://admin:instar@192.168.xxx.xxx/cgi-bin/hi3510/param.cgi?cmd=setmdattr&-enable=1&-name=1 :: enables the md area 1

http://admin:instar@192.168.xxx.xxx/cgi-bin/hi3510/param.cgi?cmd=setmdattr&-enable=0&-name=1 :: disables the md area 1

http://192.168.x.x/cgi-bin/hi3510/param.cgi?cmd=setioattr&-io_enable=1&-io_flag=1 :: enable / disable external alarm in to trigger recording
http://admin:instar@192.168.xxx.xxx/cgi-bin/hi3510/param.cgi?cmd=setmdattr&-enable=0&-name=1&cmd=setmdattr&-enable=0&-name=2&cmd=setmdattr&-enable=0&-name=3&cmd=setmdattr&-enable=0&-name=4

Download INSTAR_CGI_H264_Chipset_English Guide

Download FI9821W-CGI-Commands

http://community.ispyconnect.com/ispybb2/viewtopic.php?t=1442

/cgi-bin/hi3510/ptzgotopoint.cgi?&-chn=0&-point=0

      /cgi-bin/hi3510/ptzctrl.cgi?&-chn=0&-act=left&-speed=10
      /cgi-bin/hi3510/ptzctrl.cgi?&-chn=0&-act=upleft&-speed=10
      /cgi-bin/hi3510/ptzctrl.cgi?&-chn=0&-act=right&-speed=10
      /cgi-bin/hi3510/ptzctrl.cgi?&-chn=0&-act=upright&-speed=10
      /cgi-bin/hi3510/ptzctrl.cgi?&-chn=0?&-act=up&-speed=10
      /cgi-bin/hi3510/ptzctrl.cgi?&-chn=0&-act=down&-speed=10
      /cgi-bin/hi3510/ptzctrl.cgi?&-chn=0&-act=downleft&-speed=10
      /cgi-bin/hi3510/ptzctrl.cgi?&-chn=0&-act=downright&-speed=10
      /cgi-bin/hi3510/ptzstop.cgi?&-chn=0&-speed=0
 
 
 
 
      <command />/cgi-bin/hi3510/ptzgotopoint.cgi?&amp;-chn=0&amp;-point=0
      <command />/cgi-bin/hi3510/ptzgotopoint.cgi?&amp;-chn=0&amp;-point=1
      <command />/cgi-bin/hi3510/ptzgotopoint.cgi?&amp;-chn=0&amp;-point=2
      <command />/cgi-bin/hi3510/ptzgotopoint.cgi?&amp;-chn=0&amp;-point=3
      <command />/cgi-bin/hi3510/ptzgotopoint.cgi?&amp;-chn=0&amp;-point=4
      <command />/cgi-bin/hi3510/ptzgotopoint.cgi?&amp;-chn=0&amp;-point=5
      <command />/cgi-bin/hi3510/ptzgotopoint.cgi?&amp;-chn=0&amp;-point=6
      <command />/cgi-bin/hi3510/ptzgotopoint.cgi?&amp;-chn=0&amp;-point=7
      <command />/cgi-bin/hi3510/ptzgotopoint.cgi?&amp;-chn=0&amp;-point=8
      <command />/cgi-bin/hi3510/ptzsetpoint.cgi?&amp;-chn=0&amp;-point=1
      <command />/cgi-bin/hi3510/ptzsetpoint.cgi?&amp;-chn=0&amp;-point=2
      <command />/cgi-bin/hi3510/ptzsetpoint.cgi?&amp;-chn=0&amp;-point=3
      <command />/cgi-bin/hi3510/ptzsetpoint.cgi?&amp;-chn=0&amp;-point=4
      <command />/cgi-bin/hi3510/ptzsetpoint.cgi?&amp;-chn=0&amp;-point=5
      <command />/cgi-bin/hi3510/ptzsetpoint.cgi?&amp;-chn=0&amp;-point=6
      <command />/cgi-bin/hi3510/ptzsetpoint.cgi?&amp;-chn=0&amp;-point=7
      <command />/cgi-bin/hi3510/ptzsetpoint.cgi?&amp;-chn=0&amp;-point=8
      <command />/cgi-bin/hi3510/ptzstarttour.cgi?&amp;-tour=0
      <command />/cgi-bin/hi3510/ptzstarttour.cgi?&amp;-tour=1
      <command />/cgi-bin/hi3510/ptzstarttour.cgi?&amp;-tour=2
      <command />/cgi-bin/hi3510/ptzstarttour.cgi?&amp;-tour=3
      <command />/cgi-bin/hi3510/ptzctrl.cgi?&amp;-step=0&amp;-speed=10&amp;-act=hscan
      <command />/cgi-bin/hi3510/ptzctrl.cgi?&amp;-step=0&amp;-speed=10&amp;-a

Installare su domoticz Aeotec ZW090 Z-Stick Gen5 EU

Ho comprato questa chiavetta Aeotec ZW090 Z-Stick Gen5 EU per il mercato europeo circa 60 euro importata dalla Cina. L’installazione è stata molto semplice ho su una raspberry installato domoticz e ho ricompilato la versione disponibile su Git di openzwave qui trovate le informazioni necessarie per la gestione: https://www.domoticz.com/wiki/Installing_and_running_Domoticz_on_a_Raspberry_PI Molto semplice basta entrare in /home/pi e dare il comando

git clone https://github.com/OpenZWave/open-zwave open-zwave-read-only

poi compilare con

cd open-zwave-read-only
git pull
make -j 3

Il controller si sincronizza con un device z-wave (io ho preso quelli prodotti dalla WIDOM, UME304 Energy Driven Switch) premendo il bottone della chiavetta ed aspettare che diventi blu lampeggiante e contemporaneamente  cliccare sul bottone del dispositivo una volta. Sul menu dei dispositivi troverete tutte le risorse informative che mette a disposizione il device delle WIDOM. Se la sincronizzazione non avviene il colore è giallo altrimenti è blu fisso.

Inviare dati da un form usando php bash ed Aruba

Per eseguire uno script php su hosting aruba che richiama uno script bash devi inserire lo script nella dir

/web/htdocs/www.recapriata.gov.it/home/cgi-bin/ciao.sh

Il codice dello script bash è (esegue la somma degli argomenti passati tramite form):

#!/bin/bash
a=$1
b=$2
echo ‘somma = ‘$((a+b))

exit 1

Il codice del pagine php che contiene il form è (pagina.php):

<html>
<head>
<meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″ />
<title>Add new customer </title>
</head>

<body>

<h1>Inserimento dati</h1>

<form method=”post” action=”web-add_new_customer.php”>

Primo numero: <br />
<input type=”text” name=”NUMERO_UNO” size=”35″ />
<br />

Secondo numero: <br />
<input type=”text” name=”NUMERO_DUE” size=”35″ />
<br /> <br />

<input type=”submit” value=”Invia” />
<br />
</form>

</body>
</html>

Il codice della script richiamato è (calcola_con_script_bash.php):

<?php
$NUMERO_UNO = $_POST[‘NUMERO_UNO’];
$NUMERO_DUE = $_POST[‘NUMERO_DUE’];

if(empty($NUMERO_UNO ) || empty($NUMERO_DUE )) {
echo “<h2>Compila tutti i campi</h2>\n” ;
die (“Torna indietro per compilare.”);
}

echo “<h2>Inserisci le informazioni necessarie:</h2>”;
echo “<b>Il primo numero inserito è:</b><br><br>”;
echo $NUMERO_UNO;
echo “<br><br><b>Il secondo numero inserito è:</b><br><br>”;
echo $NUMERO_DUE;
echo “<br><br/>”;
echo “<b>Comando:</b><br><br/>”;

$cmd = “/web/htdocs/www.dominiosito.it/home/cgi-bin/ciao.sh escapeshellarg($NUMERO_UNO) escapeshellarg($NUMERO_DUE)”;

echo(“Commando testuale = ” . $cmd . “<br/>\n”);
echo(“<b>Dump della variabile con var_dump</b><br/>\n”);
var_dump($cmd);

echo(“<br/>\n”);

exec(“/web/htdocs/www.dominiosito.it/home/cgi-bin/ciao.sh $NUMERO_UNO $NUMERO_DUE”, $output, $output2);

echo(“<br/>\n”);
echo(“Uscita array = ” . print_r($output) . “<br/>\n”);
echo(“Uscita = ” . $output2 . “<br/>\n”);
?>

Uscita array stampa l’array che contiene il risultato contenuta in $output

output2 contiene un valore numerico che segan se lo script è stato eseguito correttamente in questo caso restituisce 1 (vedi script bash)

 

 

 

 

Eseguire script bash su hosting linux Aruba

Ho avuto questa necessità…. come faccio?

Segue script bash hello.sh

#!/bin/bash
echo “Hello World!”

Segue script prova.php messo dentro la dir cgi-bin

<?php
$result=exec(“/web/htdocs/www.dominio.ext/home/cgi-bin/hello.sh”);
echo($result);
?>

I files vanno messi nella cartella cgi-bin con i permessi 0755 eseguire il tutto richizmando dal browser il file

https://www.dominio.ext/cgi-bin/prova.php

Vi faccio notare che lo script bash può essere richiamato anche passando dei parametri

<?php
$result=exec(“/web/htdocs/www.dominio.ext/home/cgi-bin/hello.sh abc bng”);
echo($result);
?>

Rendere PDF che contiene del testo inserito in una immagine ricercabile con Tesseract e script bash

A volte ci sono dei pdf che non sono ricercabili. Per permettere la ricerca di una parola o di una frase (anche con l’uso del mio script pubblicato in una altro link) ho trovato questo script chiamato pdfocr.sh

#! /bin/bash

INPUT=
declare -a INPUT_FILES
ARGUMENTS=( “$@” )
OUTPUT=
OUT_FINAL=
TESS_CONFIG=pdf
TESS_LANG=ita
RES=300
IMG_FMT=
MODE=full
TESS_PARAMS=
KEEP_TMP=false
MODE=full
PARALLEL=false
JOBS=1
GSDEV=jpeg
INPUT_BASENAME=
TMPDIR_PATH=~/tmp
VERBOSE=false

RESET=”\e[0m”
PENDING=”\e[1;91m”
ERROR=”\e[1;31m”
DONE=”\e[1;36m”
MSG=”\e[1;36m”

#regexes
shopt -s extglob

#kill child processes on error
trap ‘end_jobs’ EXIT

function pdfocr {

if [ ${#ARGUMENTS[@]} -eq 0 ]; then
print_usage
exit
fi

parse_args

check_req

for input_file in “${INPUT_FILES[@]}”; do
echo -e “${MSG}Input file:$RESET” `basename “$input_file”`

if [[ $MODE = clean ]]; then
echo Cleaning temp files…
fi

check_file “$input_file”

init “$input_file”

pdfocr_proc “$input_file”

echo

done

echo -e “${DONE}Finished$RESET”

}

function pdfocr_proc {

local input_file=$1

split “$input_file”

local IN_P=”$TMPDIR_PATH/$INPUT_BASENAME”

if [[ -n $PREPROCESSOR ]]; then
preprocess “$IN_P” “$IMG_FMT”
fi

ocr “$IN_P” “$IMG_FMT”

merge “$IN_P”

clean_tmp “$IN_P” “$IMG_FMT”
}

function split {

if ! [[ $MODE = @(full|split) ]];then
return
fi

echo -e ${PENDING}Running$RESET ghostscript

local IN_F=$1

local GS_OUT=”$TMPDIR_PATH/$INPUT_BASENAME%04d_gs.$IMG_FMT”
gs -dSAFER -dBATCH -dNOPAUSE -sDEVICE=$GSDEV -r$RES -dTextAlphaBits=4 \
-o “$GS_OUT” -f “$IN_F” > /dev/null

try “Error while converting $IN_F”
}

function preprocess {

if [ $PARALLEL = true ]; then
echo -e ${PENDING}Running$RESET preprocessor in parallel
export -f run_preproc
export -f try
local PRE4PARA=`parallel –shellquote ::: “$PREPROCESSOR”`
parallel -n 1 -d ::: -j $JOBS -m run_preproc “$PRE4PARA” {} ::: “$1″*_gs.”$2”
try “Error during parallel preprocessing!”
else
echo -e ${PENDING}Running$RESET preprocessor
for f in “$1″*_gs.”$2”;do
run_preproc “$PREPROCESSOR” “$f”
done
fi

}

function ocr {

if ! [[ $MODE = @(full|ocr) ]]; then
return
fi

local IN_P=”$TMPDIR_PATH/$INPUT_BASENAME”
if [ $PARALLEL = true ]; then
echo -e ${PENDING}Running$RESET tesseract in parallel
if [ “$VERBOSE” = false ];then
run_wait
fi

export -f run_tess
export -f try
export -f print_errors

if [ -z “$TESS_PARAMS” ]; then
TESS_PARAMS=” ”
fi

local ESC=`echo $TESS_PARAMS| sed ‘s/-/__-/’`
ESC=`parallel –shellquote ::: “$ESC”`
parallel -n1 -j $JOBS -m run_tess {} “$TESS_LANG” “$ESC” “$TESS_CONFIG” “$VERBOSE” ::: “$1″*_gs.”$2”
try “Error while running parallel tesseract jobs!”

if [ “$VERBOSE” = false ]; then
kill -INT $!
fi

else
echo -e ${PENDING}Running$RESET tesseract
if [ “$VERBOSE” = false ];then
run_wait
fi

for f in “$1″*_gs.”$2”; do
run_tess “$f” “$TESS_LANG” “$TESS_PARAMS” “$TESS_CONFIG” “$VERBOSE”
done

if [ “$VERBOSE” = false ]; then
kill -INT $!
fi
fi
}

function merge {

if ! [[ $MODE = @(full|merge) ]]; then
return
fi

# local IN_P=”$TMPDIR_PATH/$INPUT_BASENAME”
local file_count=`ls -1 “$1″*_gs_tess.pdf | wc -l`
echo -e ${PENDING}Merging$RESET into $OUT_FINAL
if [[ $file_count -gt 1 ]]; then
pdfunite “$1″*_gs_tess.pdf “$OUT_FINAL”
else
cp “$1″*_gs_tess.pdf “$OUT_FINAL”
fi
try “Error while merging $1″*”$2 into $OUT_FINAL”
}

function clean_tmp {
if [ $KEEP_TMP = true ]; then
return
fi

if [[ $MODE != split ]]; then
rm “$1″*_gs.”$2”
fi
if [[ $MODE != ocr ]]; then
rm “$1″*_gs_tess.pdf
fi
}
function run_wait {

export -f wait_anim
wait_anim &

}

function run_tess {
local IN=$1
local TESS_LANG=$2
local TESS_PARAMS=$3
TESS_PARAMS=`echo $TESS_PARAMS | sed ‘s/__-/-/’`
local TESS_CONFIG=$4
local VERBOSE=$5
local tess_o=
if [ “$VERBOSE” = true ]; then
echo tesseract “$IN” “${IN%.*}_tess” -l $TESS_LANG -psm 3 $TESS_PARAMS $TESS_CONFIG
fi

tess_o=$(tesseract “$IN” “${IN%.*}_tess” -l $TESS_LANG -psm 3 $TESS_PARAMS $TESS_CONFIG 2>&1)
try “Error while performing ocr!” “$tess_o”

if [ “$VERBOSE” = true ]; then
echo $tess_o
echo Tesseract input $1
echo Tesseract output ${1%.*}_tess.pdf
fi
}

function run_preproc {
local PAGE_NUM=`echo $2|gawk ‘match($0,/.+([0-9]{4})_gs.*/,arr) { print arr[1]}’`
$1 “$2” $PAGE_NUM
try “Error while preprocessing!” “Preprocessor: $1” “Input file: $2”
}

function init {

local INPUT=$1

INPUT_BASENAME=$(basename “$INPUT”)
INPUT_BASENAME=${INPUT_BASENAME%.*}

if [ -z “$OUTPUT” ]; then

local INPUT_DIR=$(dirname “$INPUT”)
OUT_FINAL=”$INPUT_DIR/$INPUT_BASENAME”_ocr.pdf

else

if [[ “$OUTPUT” =~ INPUT_BASENAME ]]; then
OUT_FINAL=”${OUTPUT/INPUT_BASENAME/$INPUT_BASENAME}”
elif [[ “${OUTPUT: -1}” == “/” ]]; then
OUT_FINAL=”$OUTPUT$INPUT_BASENAME”_ocr.pdf
OUTPUT_DIR=$OUTPUT
else
OUT_FINAL=$OUTPUT
fi

if [ -z $OUTPUT_DIR ]; then
local OUTPUT_DIR=$(dirname $OUTPUT)
fi

if [ ! -d “$OUTPUT_DIR” ]; then
mkdir -p “$OUTPUT_DIR”
try “Failed creating the output directory: $OUTPUT_DIR”
fi

fi

if [ ! -d “TMPDIR_PATH” ]; then
mkdir -p “$TMPDIR_PATH”
try “Failed creating the temporary directory: $TMPDIR_PATH”
fi

case $GSDEV in
jpeg)
IMG_FMT=jpg
;;
ppm)
;;
png*)
IMG_FMT=png
;;
tiff*)
IMG_FMT=tiff
;;
*)
throw “$IMG_FMT not supported”
;;
esac
}

function parse_args {

local let in_c=0
local let v_c=0

local LANGS_ARR=()
local IN_ARG=

while [[ $v_c -lt ${#ARGUMENTS[@]} ]]; do

key=${ARGUMENTS[$v_c]}

if (( v_c < ${#ARGUMENTS[@]} ));then
local val=”${ARGUMENTS[$((v_c+1))]}”
if [[ $val == -* ]]; then
val=
fi

fi
case $key in
-*)
IN_ARG=
let in_c=0
;;&
-i|–input)
IN_ARG=INPUT
;;
-o|–output)
OUTPUT=”$val”
;;
-t|–tempdir)
TMPDIR_PATH=”$val”
;;
–tess-config)
TESS_CONFIG=”$val”
;;
-l|–language)
IN_ARG=TESS_LANG
;;
-r|–resolution)
RES=”$val”
;;
-f|–img-format)
GSDEV=”$val”
;;
-c|–tess-param)
TESS_PARAMS=”$TESS_PARAMS -c $val”
;;
–keep-tmp)
KEEP_TMP=true
;;
-m|–mode)
MODE=”$val”
;;
-p|–parallel)
if hash parallel 2>/dev/null; then
PARALLEL=true
if [[ -n $val ]]; then
JOBS=$val
else
JOBS=`parallel –number-of-cores`
fi
fi
;;
-s|–preprocessor)
PREPROCESSOR=$val
;;
-v|–verbose)
VERBOSE=true
;;
-h|–help)
print_help
exit
;;
*)
case $IN_ARG in
INPUT)
INPUT_FILES[$in_c]=$key
let in_c++
;;
TESS_LANG)
LANGS_ARR[$in_c]=$key
let in_c++
esac
;;
esac
let v_c++
done

if [[ ${#LANGS_ARR} -gt 0 ]]; then
TESS_LANG=”${LANGS_ARR[@]}”
TESS_LANG=`echo “$TESS_LANG”|sed ‘s/ /+/’`
fi

if ! [[ $MODE = @(split|full|ocr|merge|clean) ]];then
echo “Invalid mode: $MODE”
print_usage
exit
fi

}

function check_req {

if ! hash pdfunite 2> /dev/null; then
throw “pdfunite missing!”
fi

if ! hash tesseract 2> /dev/null; then
throw “tesseract missing!”
fi

if ! hash gs 2> /dev/null; then
throw “ghostscript missing!”
fi

if [ ${#INPUT_FILES[@]} -eq 0 ]; then
throw “pdf input path is missing!”
fi
}

function check_file {
if ! [ -f “$1” ]; then
throw “No such file: $1”
fi
}

function try {
if [[ $? -ne 0 ]] ; then
throw “$@”
fi
return 0
}

function throw {
print_errors “$@”
exit 1
}

function print_errors {
for msg; do
echo -e “$ERROR$msg$RESET”
done
}

function print_help {

cat << END
pdfocr script

Description:

A convenience script that implements a pipeline for creating a searchable
pdf file. The pipeline involves three parts:
-pdf splitting and conversion to images
-character recognition
-merging into the final pdf
Each step can be performed separately of others. You can split pdf, preprocess
images (e.g. with ImageMagick) and then perform ocr and merging.

Requirements:

The following software applications are required:
gs (Ghostscript)
tesseract
pdfunite

Optional:
parallel (speeds up ocr on multiple cores)

Usage:

pdfocr -i|–input input.pdf [options…]

Options:

-l, –lang LANGS set the language(s) for tesseract; check available
languages with:
tesseract –list-langs

-o, –output OUTPUT_PATH set the output path; it can be explicit or use the
INPUT_BASENAME variable to construct it dynamically
e.g. , -o INPUT_BASENAME_ocr.pdf
Default: INPUT_BASENAME_ocr.pdf

-t, –tempdir TMPDIR_PATH set the path to directory with intermediate
files; Default: ~/tmp

-s, –preprocessor PROC_PATH set the path to an image preprocessor;
the preprocessor shall be executed for the image of
each page like this:
preprocessor img_path page_num
the preprocessor should overwrite the original image

-m, –mode MODE set the mode to perform only the part of processing;
MODE can be one of:
split
ocr
merge
full
Default: full
note: it is assumed that required files are in the
TMPDIR_PATH; modes ‘split’ and ‘ocr’ don’t delete
their output intermediate files

–tess-config CONFIG set the tesseract configuration; default: pdf

-p, –parallel [JOBS] use GNU parallel if available; limit the number
of jobs to JOBS

-v, –verbose allow verbose output

–keep-tmp keep the intermediate files; deleted by default

-f, –img-format the format of the intermediate images;
possible values:
jpeg png* ppm tiff*
any format supported by Ghostscript that matches
the above values is valid;
note: the image format makes a difference for
tesseract, so experiment with different values
Default: jpeg

-r, –resolution RES set the resolution of intermediate images to RES;
default: 300

-c, –tess-param key=val set a tesseract parameter
e.g., -c textord_min_linesize=2.5

-h, –help print this
END
}

function print_usage {
cat << END
pdfocr script

Usage:

pdfocr -i|–input input.pdf [options…]

Options:

-h, –help print help
-l, –lang LANGS set the language(s) for tesseract
-o, –output OUTPUT_PATH set the output path
-t, –tempdir TMPDIR_PATH set the path to tempdir (def: ~/tmp)
-m, –mode MODE set the mode (split,ocr,merge,full)
–tess-config CONFIG set the tesseract configuration; default: pdf
-f, –img-format FMT the format of the intermediate images;
jpeg png* ppm tiff*
-r, –resolution NUM set the resolution of the intermediate images
-c, –tess-param key=val set a tesseract parameter
–keep-tmp keep the intermediate files; deleted by default
-p, –parallel [JOBS] use GNU parallel if available
-v, –verbose allow verbose output
-s, –preprocessor PROC_PATH set the path to images preprocessor

END

}

function wait_anim {

trap “__STOP_PRINT=true” SIGINT
local move=r
local let length=5
local let pos=0
while [[ $__STOP_PRINT != true ]]; do

echo -en ” |”

for ((i=0;i<pos;i++));do
echo -n ” ”
done

echo -en “$PENDING*$RESET”

for ((i=0;i<length-pos;i++));do
echo -n ” ”
done

echo -en “|”
echo -ne \\r
if [[ $move == r ]]; then
let pos++
if ((pos>=length)); then
move=l
fi
else
let pos–
if ((pos<=0)); then
move=r
fi
fi

sleep 0.07
done
}

function end_jobs {

local job_n=`jobs -p | wc -l`
if ((job_n>0)); then
jobs -p | xargs kill
fi

}

pdfocr
trap ” EXIT SIGINT

# vim: ts=2 sw=2

Cambiare versione PHP Aruba.it

Da qualche mese Aruba ha aggiornato il look del Pannello di Controllo. Sicuramente più compatto rispetto al precedente paginone, questo cambio ha causato diversi disagi a determinati utenti, che non riuscirebbero più a trovare delle funzioni. Più che di difficoltà però, si tratta di disabitudine: abbandonare un’interfaccia usata per anni e anni (magari quotidianamente) non è certo facile.

Il dilemma di oggi è: dove posso modificare la versione di PHP in uso? Riferito al servizio Hosting, quindi siti web. Aruba offre un semplice tool per farlo, ma sembra essersi perso. In realtà, raggiungerlo è semplice!

Ci basta effettuare il Login, e cliccare poi su Pannello di Controllo. Sulla colonna dei menù a sinistra, clicchiamo su Hosting Linux, e poi sulla sottovoce Gestione Hosting Linux. Verremo reindirizzati ad un’altra pagina, dove ci basterà cliccare sul tab Strumenti e Impostazioni (in alto), e da li cliccare su Scelta della versione PHP. Aperto il pop-up, scegliamo la versione desiderata e confermiamo. Nel giro di qualche minuto, saremo in grado di verificare la nuova versione di PHP.

Problemi di compatibilità sconfitti in meno di un minuto 😎

PDF Estrattore di testo e di pagine script bash

Lo script estrae del testo da alcuni file pdf inseriti in una dir passata come argomento e li copia in una cartella deposito di un percorso specificato. Vengono creati dei file pdf con le pagine che contengono le stringe ricercate oltre a copiare il file originale. Se il nome del file contiene degli spazi questi vengono sostituiti con il carattere undescore “_”.

pdfestrattore.sh “Text” “./target/*” “./destination/”

#!/bin/bash
# Ricerca Testo e copia file presso la directory di destinazione
# bash pdfestrattore.sh “Text” “./target/*” “./destination/”
#  Vers. 1.1 del 06/02/2017
# Uso del pdfgrep versione 1.4.x e 2.0.x

controllapdfgrep=(`which pdfgrep`)
controllapdftk=(`which pdftk`)

if [ “$controllapdfgrep” = “” ];
then
echo “PdfGrep non è installato! Il comando su Ubuntu è apt-get install pdfgrep”
exit
fi

if [ “$controllapdftk” = “” ];
then
echo “Pdftk non è installato! Il comando su Ubuntu è  apt-get install pdftk”
exit
fi

function pausa()
{
read -p “$*”
}

#funzione usata per rinominare i file
RINOMINAFILE() {
#$FILE non è necessario definirla come locale
local BASENAME=$1 #$1 è la 1° variabile passata alla funzione al momento della sua invocazione
#se non ho spazi nel nome file non lo devo rinominare
if echo $BASENAME | grep ” ” ; then
NUOVONOMEFILE=`echo $BASENAME | tr ‘A-Z ‘ ‘A-Z_’`
#rinomino il file $NUOVONOMEFILE contiene il nome del file
#con gli spazi traformati in _
mv “$BASENAME” $NUOVONOMEFILE
fi
}

#questa è una funzione ricorsiva
RINOMINADIR() {
#$DIR è necessario definirla come locale
local DIR=$1
if echo $DIR | grep ” ” ; then
NUOVONOMEDIR=`echo $DIR | tr ‘A-Z ‘ ‘A-Z_’`
mv “$DIR” $NUOVONOMEDIR
else
#se non ci sono spazi assegno a $NUOVONOMEDIR il valor di $DIR
NUOVONOMEDIR=$DIR
fi
#Entro nella dir per verificare se ho altre dir o file
cd $NUOVONOMEDIR
find -maxdepth 1 | while read d; do
#il comando find mi restituisce tra i risultati anche la dir corrente ./
#che non và considerata
if [ “$d” != “.” ]; then
#verifico se $d è una directory
if [ -d “$d” ]; then
#se $d è una directory richiamo la funzione ricorsivamente
RINOMINADIR “$d”
else
#se $d non è una directory richiamo la funzione RINOMINAFILE
RINOMINAFILE “$d”
fi
fi
done
#Visto che prima sono entrato in $NUOVONOMEDIR adesso devo uscirne per poter continuare
cd ..
}

#MAIN
find -maxdepth 1 | while read l; do
#il comando find mi restituisce tra i risultati anche la dir corrente ./
#che non và considerata
if [ “$l” != “.” ]; then
#verifico se ho una directory
if [ -d “$l” ]; then
#ricchiamo la funzione RINOMINADIR
RINOMINADIR “$l”
else
#ricchiamo la funzione RINOMINAFILE
RINOMINAFILE “$l”
fi
fi
done

# Controlla se il comando viene eseguito con le opzioni corrette

if [ $# -eq 0 ]; then
echo -e ” ”
echo -e “pdfestrattore.sh Script v. 1.0 del 31-01-2017″
echo -e ” ”
echo -e “SINTASSI: ./pdfestrattore.sh “Text da cercare” sorgente destinazione”
echo -e ” ”
echo -e “Errore: devi specificare degli argomenti!”
echo -e ” ”
exit 1;
fi

PERCORSO=”$3″
ARCHIVIO=”deposito”

# Controlla l’esistenza della dir e cancella il contenuto, se non presente crea sotto $DESTINAZIONE la cartella deposito
if [ ! -d $PERCORSO/$ARCHIVIO ]; then
echo -e “Verra’ creata la dir $PERCORSO/$ARCHIVIO!”
#  chiamata di funzione pausa
pausa ‘Premere [Enter] per continuare, puoi premere CTRL+C per interrompere!’
mkdir -p $PERCORSO/$ARCHIVIO;
else
echo -e “Attenzione i file della dir $PERCORSO/$ARCHIVIO verranno cancellati!”
# controlla il numero di file nella directori di origine e di destinazione
NUMERO1=`ls -l “$2” | wc -l`
echo -e “Il numbero di files nella cartella di origine è $NUMERO1”
NUMERO2=`ls -l “$3” | wc -l`
echo -e “Il numbero di files nella catella di destinazione è $NUMERO2″
#  chiamata di funzione pausa
pausa ‘Premere [Enter] per continuare, puoi premere CTRL+C per interrompere!’
rm -rf $PERCORSO/$ARCHIVIO/*;
fi;

while read line; do
file=$(echo $line|awk -F: ‘{print $1}’)
STRING=”$1″
FILENAME=”${file##*/}”
BASENAME=”${FILENAME%.*}”
DIRNAME=”${file%/*}”
printf “$file: ”
echo “$line”|grep -q :0$ && echo Stringa non trovata! && continue
echo Stringa trovata!
cp -fi “$file” $PERCORSO/$ARCHIVIO;
RINOMINAFILE “${PERCORSO}/${ARCHIVIO}/${BASENAME}.pdf”
echo “Salvataggio nella dir: $PERCORSO/$ARCHIVIO del file completo: ${FILENAME}”
echo “Processo il file: $FILENAME…”
echo “Sto controllando per la stringa: $STRING…”
echo “Salvataggio nella dir: $PERCORSO/$ARCHIVIO del file ${BASENAME}_pagina_con_${STRING}.pdf”
## Ricerca il testo nei file passati
PAGES=”$(pdfgrep -in “$STRING” “$file” | cut -f1 -d “:” | uniq | tr ‘\n’ ‘ ‘)”
echo “Trovata stringa nella/e pagina/e numero: $PAGES”
## extract pages to new file in original directory
echo “Sto estraendo le pagine…”
pdftk “$file” cat $PAGES output “${PERCORSO}/${ARCHIVIO}/${BASENAME}_pagina_con_${STRING}.pdf”
RINOMINAFILE “${PERCORSO}/${ARCHIVIO}/${BASENAME}_pagina_con_${STRING}.pdf”
echo “Ciclo terminato per il file ${FILENAME}”
done < <(find $2 -type f -iname ‘*.pdf’ -exec pdfgrep -ircnHF “${STRING}” {} \;)
echo “Programma terminato!”