Programmazione



Applicazioni multipiattaforma 100% GUI-Indipendent

|

Può capitare di dover realizzare programmi che siano utilizzabili con diverse interfacce grafiche, in Ruby ci sono diversi stratagemmi per farlo e al primo posto troviamo i blocchi, ecco un programmino d'esempio che funzione da gtk o console.

L'idea di base è che tutti i controlli dati vengono fatti dalla classe interna, mentre le interfacce si limitino solo a fare input/output; probabilmente questo approccio non va bene in tutti i casi, ma se si usano pochi semplici widget fa la sua bella figura.

Ho deciso di usare i metodi "error" e "notify", per semplicità, ma si sarebbero potute utilizzare anche le eccezioni; stesso discorso per l'alert. Gtk::Dialog sarebbe il widget giusto, ma rischierebbe di creare confusione.

Si esegue con:

ruby esempio.rb (Console) o ruby esempio.rb --gtk (Gtk)



#!/usr/bin/ruby
=begin
 == esempio.rb ==
 Una semplice implementazione di oggetti indipendenti dall'interfaccia grafica/console
 oOo. http://assente.altervista.org .oOo
=end

# Oggetto principale GUI-indipendent
class List
    def initialize()
        @a=[]
    end
    def add(value)
        # vari controlli sull'input
        if value==""
            error("Valore nullo")
        elsif value=~/[a-zA-Z]/
            error("Le lettere non sono ammesse")
        elsif value=~/[0-9]/
            @a << value
            notify("'#{value}' inserito")
        end
    end
    # yield viene sostituito con quello che passiamo a livello superiore,
    # puts oppure @display.text+=, fantastico, no?
    def show_all
        @a.each { |value| yield value}
    end
end

class ConsoleList < List
    def initialize
        super
        puts "Console mode"
        while true
            puts "1: Aggiungi 2: Visualizza 3: Esci"
            # toglie \n dall'input da terminale
            choice=gets.strip
            case (choice)
                when "1" then add
                when "2" then show_all
                when "3" then exit
            else
                error("Scelta non valida")                
            end        
        end
    end
    def add
        puts "Inserisci: "
        # manda al metodo List#add vedi su
        super(gets.strip)
    end
    # Richiamato da List
    def error(text)
        puts "!! #{text} !!"
    end
    def notify(text)
        puts ">> #{text}"    
    end
    def show_all
        super{|v| puts "|#{v}|"}
    end
end

class GtkList < List
    require 'gtk2'
    def initialize
        super
        puts "GUI mode"
        
        Gtk.init    
        
        #Inizializzo i widget
        @window=Gtk::Window.new
        @container=Gtk::VBox.new
        @entry=Gtk::Entry.new
        @display=Gtk::Label.new
        @button=Gtk::Button.new("Inserisci")
        
        #Assegno gli eventi
        @button.signal_connect("clicked"){add}
        @entry.signal_connect("activate"){add}
        @window.signal_connect("destroy"){exit}
        
        #impacchetto
        @container.add(@display).add(@entry).add(@display).add(@display).add(@button)
        @window.add(@container)
        
        @window.show_all
        
        Gtk.main
    end
    def add
        puts "Inserisci: "
        super(@entry.text)
        @entry.text=""
    end
    def error(text)
        # Con più spazio estendetevi Gtk::Alert :-)
        Gtk::Window.new.add(Gtk::Label.new("#{text}")).show_all
    end
    def notify(text)
        # Non necessario
        #Gtk::Window.new.add(Gtk::Label.new("#{text}")).show_all
        show_all
    end
    def show_all
        @display.text=""
        super{|v| @display.text+=v+" "}
    end
end

# Inizia qui
case(ARGV[0])
    when nil:     ConsoleList.new
    when "--gtk": GtkList.new
end



Gestire i pdf con pdftk e aggiungere un logo

|

Capita spesso di trovare dei pdf e non poterli modificare, se si avesse il file sorgente basterebbe aprirlo, fare le opportune modifiche e ristampare il pdf; purtroppo spesso non lo si ha e se si vogliono fare delle modifiche bisogna lavorare direttamente sui pdf.

Pdftk è un'utility multipiattaforma(Windows, Linux, Freebsd,..) molto comoda per scrivere, dividere, unire, crittare i pdf; i suoi usi possono essere sconfinati, visto che si tratta di un'applicazione da console con input e output.

Volendo esiste anche una gui, ma il suo utilizzo è molto semplice, ecco qualche esempio:

pdftk miopdf.pdf burst #separa miopdf.pdf in pdf da una pagina sola

pdftk miopdf.pdf background sfondo.pdf output pdf-con-sfondo.pdf # crea un nuovo file con lo sfondo aggiunto

 L'unico problema che ho riscontrato è che non si può aggiungere un pdf in foreground (primo piano), ma solo come sfondo; quindi se volete sbiancare una parte del pdf(per risparmiare toner) o aggiungerci un logo non potete farlo.. ecco allora che con qualche stratagemma si riesce ad ottere il risultato voluto con un semplice script in ruby:

- divide il pdf
- applica la pagina singola come background al logo
- ricompatta il tutto in un nuovo file

logo.pdf è il pdf che volete sovrapporre all'originale, potete farlo con Openffice.org

ecco qui:

 #!/usr/bin/ruby

### pdf-impaginator.rb - applica un logo e riordina le pagine di un pdf
### si usa così: ruby pdf-impaginator.rb original.pdf logo.pdf output.pdf

pdffile=ARGV[0]
p pdffile
markfile=ARGV[1]
p markfile
outfile=ARGV[2]

new_prefix="nuovo"

### Volendo potete cambiare l'ordine delle pagine per motivi di stampa ###

num1=0
num2=2
num3=0
num4=-2

#split OK
puts "Separo le pagine.."
system("pdftk "+ pdffile+" burst")

#mark
puts "Marchio e riordino"
cmd=IO.popen("ls pg_*.pdf")

page_counter=1
while pagefile=cmd.gets
pagefile=pagefile.gsub("\n","")

if (page_counter % 4) == 0
page=page_counter+num4
elsif (page_counter % 4) == 1
page=page_counter+num1
elsif (page_counter % 4) == 2
page=page_counter+num2
elsif (page_counter % 4) == 3
page=page_counter+num3
end

zeros="0"*(4 - page.to_s.length)
puts "pdftk "+markfile+" background "+ pagefile+" output "+new_prefix+"_"+ zeros+""+page.to_s+".pdf"
system("pdftk "+markfile+" background "+ pagefile+" output "+new_prefix+"_"+ zeros+""+page.to_s+".pdf")

page_counter+=1
end

#merge
puts "Ricostruisco il pdf"
system("pdftk "+new_prefix+"* cat output "+outfile)


#del
puts "Elimino i temporanei"
#system("rm "+new_prefix+"* pg_*")
cmd.close

csv2vcf: esportare i contatti da Pocket pc a Evolution senza activesync(synce)

|

E' un po' di tempo che cerco una via sostenibile per esportare i contatti dal mio [url=?q=node/view/109]pocket pc[/url] al mio computer; ho percorso tutte le strade conosciute, ma non ne sono rimasto entusiasta:

- [b]vcard[/b], è comodo per mandare contatti via Bluetooth, ma è ridicolo per esportare una rubrica intera perchè dal ppc si possono esportare/importare i contatti vcard solo singolarmente.

- [b]activesync[/b], funziona solo su Windows e comunque non direttamente con i contatti di Outlook Express, necessita di installare software aggiuntivo (server Exchange,..).

- [b]synce[/b], è l'implementazione del protocollo proprietario [url=http://synce.sf.net]activesync su Linux[/url], funziona per molti palmari, ma non con il mio (sia su USB, che su BT).

Ultima spiaggia, ho trovato un programma freeware ([url=http://www.bizon.org/bizorg/]Bizorg[/url]) che esporta i contatti in csv e un'altro che fa da csv a vcf(multiplo) (visto che Evolution non importa direttamente i csv).

Probabilmente lo [url=http://he4.phys.tohoku.ac.jp/~otsu/utility/csv2vcf.tar.gz]script csv2vcf[/url] è stato fatto per essere compatibile con Outlook e non con Evolution, quindi bisogna modificare qualcosina, per lo meno i campi.

Si usa così:
[code]
sh csv2vcf.sh file.csv file.vcf
[/code]

[b]Se non date il file.vcf restituisce l'output in console, controllate l'output prima di importarlo in Evolution![/b]

csv2vcf.awk
[code]
[ ... ]

##
# TARATEVI LA COLONNA GIUSTA DEL TELEFONO!!! Per me è $41

printf("TEL;VOICE;HOME:%s\n",$41);

[ ... ]
[/code]

Non che ne sia eccessivamente entusiasta, ma almeno non mi sento i dati intrappolati nel Pocket pc :-)
Buona fortuna!

PS: se invece volete esportare da Evolution a Gmail le cose sono molto più semplici e potete usare il mio script [url=?q=node/view/80]vcf2csv[/url]


l'equivalente di private static in Ruby

|

Se volete contare tutti gli oggetti creati con una certa classe avete bisogno di un campo private static; in Ruby questo non esiste, ma una via molto elegante per farlo è questa:
[code]
class Counter
def initialize
@count = 0
end
def next
value = @count
@count += 1
return value
end
end

module Countable
def self.included(mod)
mod.instance_eval do
@counter = Counter.new
end

class << mod;
attr_reader :counter
end
end
end

class Counted
include Countable
def initialize
@count = self.class.counter.next
end
end

p Counted.new
p Counted.new
p Counted.new
[/code]

Ringrazio il canale #ruby-lang su irc.freenode.net per questa dritta


Esportare i contatti di Evolution su GMail con vcf2csv

|

Finalmente uno script che mi funziona per esportare un file vcf di Evolution in uno csv pe GMail; ne avevo provati degli altri ma non mi funzionavano.. forse perchè Evolution cambia in ogni versione il modo in cui registra il campo email; attualmente sto utilizzando la 2.0.0 e ho quindi usato [b]EMAIL;TYPE=WORK;X-EVOLUTION-UI-SLOT=1:[/b], ma se usate versioni precedenti può darsi che sia [b]EMAIL:[/b] o altro, vi conviene fare prima un bel sostituisci :)

Lo script è in Ruby, sicuramente poteva essere più flessibile, compatto, ecc.. Ma per adesso dovete accontentarvi di questo visto che devo ancora imparalo ad usare bene.

Se avete idee migliori su come ottimizzarlo o per qualsiasi altra cosa, lasciatemi un commento.

Non vedo l'ora di poter sincronizzare i contatti/appuntamenti tra GMail-evolution-cellulare (Dai che per Natale arriva il [url=http://www.newsmobile.it/schedapalm/qteks100]qtek s100[/url], non vedo l'ora), speriamo che in futuro si possano gestire anche gli appuntamenti con [url=http://www.gmail.com]GMail[/url].
[code]
#! /usr/bin/ruby
=begin
vcf2csf - Export vcffile to csvfile
$Author: Assente $
Copyright (C) 2004 assente.altervista.org
This program is free software.
You can distribute/modify this program under
the terms of the GPL License.
=end
# CONFIG ME
vcfwords=["FN:","EMAIL;TYPE=WORK;X-EVOLUTION-UI-SLOT=1:","TEL;TYPE=CELL;X-EVOLUTION-UI-SLOT=3:"]
csvwords=["Full Name","Email Address","Mobile"]
#
if (ARGV[0]=="--help" || ARGV[0]==nil || ARGV[1]==nil)
puts "Usage: ./vcf2csf.rb [input-vcf] [output-csv]
Function: Convert a vcffile to csvfile, usefull to export contacts from Evolution to GMail"
else
vcffile=ARGV[0]
csvfile=ARGV[1]
csv=""
rows=open(vcffile).readlines
for i in 0..rows.length-1
if rows[i].slice(0,5)=='BEGIN'
csv << "\n"
end
for j in 0..vcfwords.length-1

if rows[i].slice(0,vcfwords[j].length)==vcfwords[j]
csv << rows[i].slice(vcfwords[j].length,30).chomp
csv << ","
end
end
end
c=open(csvfile,'w+');
c.write(csvwords.join(",")+csv)
c.close
end
[/code]


Syndicate content