martedì 11 settembre 2018

Java Telegram Bot


Breve appunto di come si ho fatto per fare un bot in java per telegram e di come l'ho fatto funzionare su tomcat8 e su jboss 10 + configurazione proxy.

Prima di tutto perche' un bot? Beh un bot che ti risponde su un'app di messaggistica istantanea ha delle potenzialita' notevoli, per esempio ti permette di interagire con l'applicativo senza essere loggato sull'applicativo stesso direttamente dal cellulare ovunque tu sia, e' una bella comodita'. Mi incuriosivano le potenzialita' del bot quindi mi sono detto: perche' no?

Primo passo:
le dipendenze. Se usate maven

<dependency> <groupId>org.telegram</groupId> <artifactId>telegrambots</artifactId> <version>3.6.1</version> </dependency>
(perche' proprio la 6 e non che ne so la 3? Per via del proxy...)

Secondo passo:
registrarsi usando BotFather
aprite telegram cercate BotFather
/start - per iniziare
BotFather vi dara' tutta una lista di comandi che puo' eseguire manteniamoci sul semplice:
/newbot - vi permette di creare un nuovo bot
vi chiedera' il nome del bot, il nome utente e vi dara' un token segnatevi tutto

Secondo passo:
creare il vostro bot ed estendere TelegramLongPollingBot il nome della classe dev'essere il nome del bot
dovrete estendere due metodi
getBotUsername() che deve restituire l'username scelto
getBotToken() che deve restituire il token che vi ha dato il botdrino
io per comodita' mi creo un metodo statico per registrare il bot in modo da avere tutto il codice relativo al bot in un punto solo

public static void registerBot(){ ApiContextInitializer.init(); TelegramBotsApi papi = new TelegramBotsApi(); //questo serve se la macchina che fa girare il bot e' proxata DefaultBotOptions botOptions = ApiContext.getInstance(DefaultBotOptions.class); HttpHost httpHost = new HttpHost("proxy_address", proxyPortAsInt); botOptions.setHttpProxy(httpHost); //ovviamente devi avere un costruttore con DefaultBotOptions come parametro IlTuoBot bobi = new IlTuoBot(botOptions); try{ papi.registerBot(bobi); }catch(TelegramApiException e){ //TODO faqquacos } }

Terzo passo:
implementare onUpdateReceived
che e' il metodo che vi permette di rispondere a chi vi scrive

bene ragassuoli, questo e' il metodo piu' importante di tutti perche' vi permette di interagire con l'utente
(se lui scrive per primo)

@Override public void onUpdateReceived(Update arg0) { if(arg0.hasMessage() && arg0.getMessage().hasText()){ //qui ho un nuovo messaggio //il chat id serve per poter rispondere ad un client specifico //se avete bisogno di inviare un messaggio automaticamente //salvatevelo da qualche parte (db?) Long chatId = arg0.getMessage().getChatId(); //il messaggio che il bot inviera' come risposta String text = "bot non ancora implementato"; SendMessage sm = new SendMessage(chatId, text); try{ execute(sm); }catch(TelegramApiException e){ //TODO faqcs } } }

Se volete che il bot scriva "suo sponte" a qualcuno dovete salvarvi il chat id da qualche parte
(io per sicurezza me lo faccio comunicare dall'utente che vuole interagire con il bot a mano, il bot su richiesta lo fornisce, l'utente se lo salva me lo da' a me io so chi e' etc)
non e' un metodo "obbligatorio" quindi la signature e' quella che vi pare a voi, basta che poi usiate la classe SendMessage e il metodo execute

Il bot puo' fare molto altro, puo' anche ricevere ed inviare contenuti multimediali tipo file immagini video etc. Quindi sbizzarritevi...

$NON_RICORDO_IL-NUMERO passo:
eseguire il bot.
- tramite main:
registrate il bot se deve solo rispondere non c'e' bisogno di fare altro. Finche' il main gira il bot sta su. - tramite server:
in tomcat8 avevo un filtro dichiarato nel web.xml e il bot lo inizializzo li'
su jboss 10 ho creato un singleton da eseguire allo startup (quindi una sola volta mentre si avvia il server) tramite le annotation

@Startup @Singleton annoti un metodo con @PostConstruct e li' dentro registri il bot

Penso (spero) sia tutto...

lunedì 10 settembre 2018

Perl e ZIP


Non so se puo' servirvi - spero di si. Oggi parliamo di perl come comprimere/decomprimere files.

Comprimere:
io ho usato use IO::Compress::Zip qw(zip $ZipError);
(perche' con Archive::Zip non c'e' stato verso - allora l'ho mandato affangrulo)
in secundis io ho avuto necessita' di mettere i files in un array (per poterli cancellare una volta fatto)
ter avevo bisogno di avere tutti i file sciolti nello zip (quindi senza preservare il path)
quindi ho letto la directory, ho ficcato tutto in un'array scansando tutto cio' che non e' file e non e' pdf
voi ovviamente fate quello che cazzo vi pare, ovviamente con questo metodo non potete zippare direttamente una directory



- apro la directory
- la scansiono
- butto nell'array solo i pdf
- passo l'array allo zip
- elimino i file (uno per uno)

Decomprimere:
ho una pletora di file pdf che devono essere buttati su db. Li decomprimo, mi salvo in un array i nomi delle directory e poi butto tutto su db...



- scansiono la directory dove risiedono gli zip
- salto se directory
- salto se non e' uno zip
- cosa interessante: salvo ogni zip in una directory che ha lo stesso nome del file zip (tranne l'estensione).
per farlo devo fare un substring (substr $zipname 0, -4)
- creo un nuovo zip (my $zip = Archive::Zip -> new($zipname))
- prendo ogni singolo membro dello zip e lo estraggo nella directory che gli corrisponde
( foreach my $member ($zip->members){
next if $member->isDirectory;
(my $extractName = $member->fileName) =~ s{.*/}{};
$member->extractToFileNamed(
"$destinationDirectory/$extractName");
})
- salvo il nome della dir nell'array (push(@unzipped_to_scan, $destinationDirectory);)
- elimino il file zip una volta estratto (unlink $file;)

mercoledì 5 settembre 2018

Giornalismo un po' cosi' - Il Telegrafo Livorno

Il link alla notizia originale e' qui.

In soldoni: un bimbetto di 15 anni prende la pistola del nonno e la punta contro la ruota della bicicletta di un amico.

Primo appunto: la beretta 70 come riporta wikipedia ha 8/10 colpi su caricatore monofilare. Non ventotto come riportato dall'articolista (per farvi capire il bm59 fal ha un caricatore da 20 colpi)

Secondo appunto: la pistola era carica? Perche' per legge armi e munizioni devono essere custoditi in due luoghi diversi.

Terzo appunto: Aveva il colpo in canna? Non basta procurarsi le munzioni bisogna anche scarrellare...

Quarto appunto: evito di menzionare la sicura ma anche fossero verificate tutte le condizioni precedenti, se ha puntato alla ruota della bicicletta il massimo danno che poteva causare era un cerchione sforacchiato.

Piu' che di "tragedia sfiorata" io parlerei di "cazzata mostruosa" - poi si sa che i giornalisti devono sempre drammatizzare, ma insomma qui si esagera!

giovedì 14 giugno 2018

venerdì 11 maggio 2018

lunedì 9 aprile 2018

Altro esempio di "buona" programmazione


Oggi mi sono imbattuto in questo: frontend che deve visualizzare dati da una tabella A e permette di ricercare per vari parametri tra cui x. X che pero' non e' su A ma su B. Poco male, basta una join... Pero' se fosse stato cosi' non sarei qui a scrivere.

Il tizio: prima va su B e si tira su tutte le righe che corrispondono a x (e sono una valanga di colonne). Poi fa un ciclo e aggiunge l'id di A ad un Set (poi vi spiego anche perche'). Prende un interator dal set e va per id su A (finalmente).

Perche' proprio un Set? Perche' non ammette duplicati, e la relazione tra A e B e' uno a molti. Quindi una riga di A ha piu' corrispondenze su B. Bastava una distinct... in sql select distinct(id) su hibernate addiruttura e' possibile a) tirare su l'entity (select pippo from A pippo) passando alla select l'alias e farlo con distinct (select distinct pippo) e poi schioccarci la join... select distinct a from A a, B b where a.id = b.id and eccetera...

UNA query. UNA!

sabato 30 dicembre 2017

Negazionismo


Giovedi' alla radio stavano intervistando un negazionista. Oddio "intervistare" e' un parolone visto che i conduttori l'hanno (giustamente) ricoperto di insulti. Pero' a me invece sarebbe sembrato piu' opportuno fargli qualche domandina, giusto cosi' per vedere cosa si sarebbe inventato...

Tipo come mai tutti i sopravvissuti (quindi quelli che in Lager ci sono stati veramente) sono concordi nell'affermare che le camere a gas sono esistite?
Se davvero e' stata una montatura come dicono i negazionisti come mai non ne e' mai saltato fuori uno che sia uno a dire oh ma che cazzo dite? Le camere a gas non c'erano! - nemmeno in punto di morte?

Come mai gli appartenenti al Sonderkommando che hanno avuto il culo di sopravvivere (visto che non era assolutamente nei piani tedeschi che succedesse visto il compito) hanno tutti testimoniato riguardo l'esistenza delle suddette - visto che erano loro a prelevare i cadaveri dalle camere a gas ed infilarli nei crematori?
Come mai non hanno mai detto oh guardate che e' un'invenzione degli alleati!
Chi meglio di loro?

C'erano i contratti di fornitura dei crematori (le ditte che le producevano facevano crematori "civili") - invenzione pure quelli?
...e i resti trovati fatti frettolosamente saltare dai tedeschi in ritirata?
...e le macerie dei crematori che i Sonderkommando hanno dovuto spalare?

e le fotografie (come quella di Brasse che accompagna questo articolo)? Ci sono foto di donne e bambini che viaggiano verso il crematorio - un falso anche quello?

E se davvero le camere a gas (e i crematori) non sono mai esistiti dove sono finiti quei milioni di persone che a tutt'oggi risultano scomparsi?

- ragazzi il negazionismo non si regge in piedi, non e' nemmeno lontanamente plausibile, ed e' un'offesa per tutte quelle persone che sono state uccise o hanno patito solo perche' erano considerati "inferiori". Piu' che il tempo passa e piu' che questi fatti si affievoliscono, i testimoni diretti sono sempre meno. Cerchiamo di non dimenticare, perche' questo e' stato. -

11/05/2018 ADDENDUM: Il libro Comandante ad Auschwitz di Rudolf Hoss (si proprio lui) descrive dettagliatamente l'uso delle camere a gas, del sonderkommando, e come sono arrivati ad usare lo Zyklon B (addirittura se ne vanta come metodo "piu' umano" (per i carnefici) di uccisione). Hoss era l'ultimo che avrebbe avuto interesse ad affermare una falsita' (ha una personalita' complessa, il libro ve lo consiglio non tanto per quello che scrive ma per quello che e' possibile capire da quello che scrive della sua personalita'). Quindi i dettagli che abbiamo, da diverse fonti e diversi testimoni sono tutti straordinariamente coerenti...