jQuery: popolare una ComboBox tramite json

Piccolo snippet, mi è stato utile nello sviluppo di una applicazione PhoneGap realizzata con jQuery Mobile.

Per caricare i dati di una combobox partendo da un array json (jsonp, nel nostro caso) abbiamo bisogno di codice lato client:

function caricaCombo() {
	$.getJSON("http://www.tuosito.com/api/get.php?callback=?", function(result) {
		$.each(result, function() {
			$("#IDComboDaPopolare").append($("<option />").val(this.id).text(this.valore));
		});
   });
}

e di un semplice script lato server (get.php) che si occupi di ‘pescare’ dati dal database e serializzare i risultati in json:

<?php
$query = "SELECT id, descrizione from Dati";
$result = mysql_query($query);
$dati= array();
while ($row=mysql_fetch_array($result)) {
	if ($row[1] != $row[2]) {
	$tempAr = array("id" => $row[0], "valore"=>$row[1]);
	$dati[]= $tempAr;
	}
}
echo $_GET['callback'] . '(' . json_encode($dati) . ')';
?>

Contrassegnato da tag , , ,

Aggiornare PhoneGap in Adobe Dreamweaver CS 5.5

L’integrazione di PhoneGap all’interno del nuovo Dreamweaver CS5.5 è una gran comodità.

Tuttavia PhoneGap è un progetto sempre in movimento: la versione attualmente inclusa in dreamweaver è la 0.9.5.1, ma è già disponibile la 1.0.

Su MacOsX è possibile eseguire l’aggiornamento all’ultima versione semplicemente sostituendo alcuni file.
Ecco un come fare:
  1. Scaricare l’ultima versione di PhoneGap  da http://phonegap.com/
  2. Decomprimere il file scaricato
  3. Installare il pacchetto per IOS. Una cartella PhoneGapLib verrà creata in Documenti.
  4. Aprire una finestra del Finder e andare in /Applicazioni/Adobe Dreamweaver CS5.5/Configuration/NativeAppFramework/DWPhoneGap/: sono presenti le 2 cartelle, Android e iPhone
Per aggiornare la versione iPhone (e iPad):
  1. Entrare nella cartella iphone
  2. Copiare in  PhoneGabLib  il contenuto di ~ /Documenti/PhoneGapLib
L’aggiornamento di Android è leggermente più lungo:
  1. Entrare nella cartella android/PhoneGapApp
  2. Copiare nella cartella libs e il file PhoneGap-xxx.jar presente nei file di phonegap per android (xxx è il numero della versione).
  3. Rinominare PhoneGap-xxx.jar in phonegap.jar
  4. Spostare una cartella e ricerca di assets/www
  5. Sostituire il file phonegap.js con quello  scaricato per Android (anche qui rinominare il file scaricato in phonegap.js)
Finito! :-)

ASP.NET: esportare il contenuto di una Gridview in un file leggibile da Excel

Snippet VB.NET (ma adattabile rapidamente anche in C#) rapido-rapido: salviamo il contenuto del controllo GridView1in un file html (leggibile quindi con MS Excel), mantenendone le formattazioni:

Leggi l’articolo completo

Android: download di immagini e caricamento in ImageView con thread asincrono

Mi riaggancio al precedente post dove proponevo un frammento di codice che permetteva di creare un oggetto bitmap scaricando una immagine dal web, gestendo anche il caching.

Tuttavia, questa operazione porta via tempo e se la nostra applicazione ha necessità di caricare parecchie immagini in questo modo (penso ad esempio ad una ListView con un buon numero di elementi grafici) la reattività dell’interfaccia potrebbero risentirne pesantemente.

Come fare quindi? Semplicemente far eseguire la procedura di download, caching e caricamento su ImageView ad un thread separato, mentre l’interfaccia dell’applicazione continua a lavorare.

private class ImageLoader {

	    private  final WeakHashMap<ImageView, AsyncTask> assignments  = new WeakHashMap<ImageView, AsyncTask>();

	    public  void setImageAsync(final ImageView imageView, final String imageUrl) {
	        AsyncTask oldTask = assignments.get(imageView);
	        if (oldTask != null) {
	            oldTask.cancel(true);
	        }

	        // prepare to launch a new task to load this new image
	        AsyncTask<String, Integer, Bitmap> newTask = new AsyncTask<String, Integer, Bitmap>() {

	            protected void onPreExecute() {
	                // eventualmente creare una immagine di 'Loading...'
	            }

	            protected Bitmap doInBackground(String... urls) {
	                //il sorgente di downloadImage lo trovate nel post precedente
	                return Utils.downloadImage(imageUrl, null,getContext());
	            }

	            protected void onPostExecute(Bitmap bitmap) {
	                if (bitmap != null) {
	                    imageView.setImageBitmap(bitmap);
	                }
	            }
	        };
	        newTask.execute();
	        assignments.put(imageView, newTask);
	    }

	}

L’utilizzo è molto semplice:

new ImageLoader().setImageAsync(ImageView1, URL_IMMAGINE);

Android: scaricare immagini dal web (con gestione del caching)

Uno snippet per effettuare il download di una immagine da internet (da usare, ad esempio, come sorgente per una ImageView) con la gestione del caching dei file già scaricati e la possibilità di passare delle opzioni per la modifica della qualità delle immagini.


public static Bitmap downloadImage(String fileUrl, BitmapFactory.Options options, Context context){
Bitmap bmImg = null;
URL myFileUrl =null;
try {
myFileUrl= new URL(fileUrl);
} catch (MalformedURLException e) {
e.printStackTrace();
}

try {

String encodedfilename = Base64.encodeBytes(fileUrl.getBytes());

//Controllo presenza della cache
try {
InputStream check = context.openFileInput(encodedfilename);
} catch (FileNotFoundException e) {
// Se non presente, scarico il file

HttpURLConnection conn= (HttpURLConnection)myFileUrl.openConnection();
conn.setDoInput(true);
conn.connect();
InputStream is = conn.getInputStream();


//Salvataggio cache
FileOutputStream fos = context.openFileOutput(encodedfilename, Context.MODE_PRIVATE);
byte[] buffer = new byte[1024];
int len1 = 0;
while ( (len1 = is.read(buffer)) > 0 ) {
fos.write(buffer,0, len1);
}

fos.close();
}

 bmImg = BitmapFactory.decodeStream(context.openFileInput(encodedfilename),null,options);


 } catch (IOException e) {

e.printStackTrace();
 }
return bmImg;
 }


Un rapido esempio di utilizzo:

BitmapFactory.Options options=new BitmapFactory.Options();
//Setto la qualità dell'immagine        
options.inSampleSize = 8;

imageView1.setImageBitmap(downloadImage(URL_IMMAGINE, options,getContext()));

Decompilare una applicazione Asp.Net

Mi è capitato di recente di ricevere una richiesta particolare: realizzare una piccola modifica ad una applicazione web realizzata in asp.net. L’applicazione in questione era stata rilasciata compilata e senza i sorgenti acclusi.
Dopo una breve indagine, la cosa si riviera meno semplice del previsto: il collega che si occupò della realizzazione del progetto ha smarrito i sorgenti (argh!).

Che fare quindi? Riscrivere da capo l’applicazione? Nooooo! Decompiliamo la versione attualmente in produzione! :-)

Per prima cosa, diamo uno sguardo a cosa ci troviamo tra le mani: anziche’ avere, come in fase di sviluppo del progetto, ad ogni pagina .ascx un corrispondente file contenente il codebehind (.ascx.vb o .ascx.cs), in una applicazione compilata e’ presente solamente il file .ascx, che a sua volta ‘pesca’ codice da un assembly posizionato nel folder Bin, nella root dell’applicazione.

Nell’intestazione della nostra pagina troveremo quindi qualcosa del genere:

<%@ page language="vb" masterpagefile="~/MasterPage.master" autoeventwireup="false" inherits="applicazione._default, App_Web_js57z-yx" smartnavigation="False" stylesheettheme="MyTheme" %>

La proprieta’ Inherits ci fornisce il nome dell’assembly che contiene il codebehind della pagina (in questo caso App_Web_js57z-yx.dll).
A questo punto abbiamo tutte le informazioni che ci servono, iniziamo a decompilare.
Scarichiamo quindi un decompilatore per .net: personalmente uso Reflector, la versione base e’ gratuita e sembra fare il suo lavoro senza grossi problemi.

Una volta installato, diamo in pasto a reflector l’assembly identificato leggendo l’intestazione della pagina (App_Web_js57z-yx.dll), poi click di tasto destro sul nome apparso nell’elenco e selezionate ‘Export’:

Reflector a questo punto salvera’ un folder contenente il sorgente estratto dall’assembly: assieme ad alcune dipendenze che, troverete anche il file contenente il codebehind della pagina:

Ci rimane da effettuare una ultima, semplicissima operazione: copiamo il file generato da reflector nella stessa directory contenente il corrispondente .ascx, rinominiamo il nostro file con la sintassi standard (nel nostro esempio default.ascx.vb oppure default.ascx.cs) e modifichiamo in questo modo l’intestazione della pagina:

<%@ page language="vb" masterpagefile="~/MasterPage.master" autoeventwireup="false" inherits="_default" CodeFile="~/default.aspx.vb" smartnavigation="False" stylesheettheme="MyTheme" %>

Compiliamo il progetto e prendiamo nota delle dipendenze che non vengono soddisfatte: ripetiamo quindi questa procedura per i rimanenti file fino a risolvere tutte le dipendenze mancanti.

Infine, ricontrolliamo il codice verificando che tutti gli eventi dei controlli siano ‘collegati’ nel codebehind: in caso contrario sara’ necessario specificare l’handle dell’evento alla sub corrispondente.

HowTo: stampante per t-shirts

Bel tutorial pubblicato da hack-a-day che illustra la realizzazione di una stampante per t-shirts.

Inviare notifiche Prowl utilizzando CURL

Prowl e’ un progetto interessante: un sistema di notifiche push per iPhone che si interfaccia col piu’ famoso sistema di notifica Growl (per Mac e Windows).

Prowl fornisce anche una serie di API, utili per mandare notifiche Push agli iPhone registrati. Viene fornito anche uno script di esempio in Perl.

Io preferisco una soluzione piu’ ‘scarna’ ma immediata: utilizzando CURL e’ possibili inviare una notifica con una sola riga di codice:


curl -X POST -d"apikey=APIKEY" -d"application=Test" -d"event=Messaggio" -d"message=Test" https://prowl.weks.net/publicapi/add

sostituite naturalmente la parola APIKEY con la vostra chiave API, reperibile a Questo Indirizzo.

Contrassegnato da tag ,

Dreamhost: personalizzare php.ini

Suggerimento rapidorapido pescato dal forum di supporto di Dreamhost.

Nel caso si abbia la necessità di personalizzare il PHP.INI, ad esempio (come è servito a me) per aumentare il timeout di uno script, la procedura è questa:

  1. Se non presente, creare una directory ‘cgi-bin’ all’interno della directory che ospita il dominio (mkdir ~/domain.com/cgi-bin/)
  2. Nella home del proprio utente, creare un file (php_update.sh) contenente il seguente script:
    #/bin/sh
    
    CGIFILE="$HOME/dominio.com/cgi-bin/php.cgi"
    INIFILE="$HOME/dominio.com/cgi-bin/php.ini"
    
    cp /usr/local/bin/php "$CGIFILE"
    cp /etc/php/php.ini "$INIFILE"
    
    perl -p -i -e '
    s/.*post_max_size.*/post_max_size = 100M/;
    s/.*upload_max_filesize.*/upload_max_filesize = 100M/;
    s/.*max_execution_time.*/max_execution_time = 600/;
    s/.*memory_limit.*/memory_limit = 90M/;
    ' "$INIFILE"
    
  3. Renderlo eseguibile (chmod +x php_update.sh) ed eseguirlo (./php_update.sh).
  4. Aggiornare il file .htaccess nella root del sito (o crearlo se non presente) e aggiungere la riga seguente: “AddHandler php-cgi .php” (senza i “)
  5. Aggiungere lo script al crontab in modo da farlo eseguire a scadenza settimanale, in modo da mantenere la propria copia locale di php.ini aggiornata con quello principale.
Contrassegnato da tag ,

Gita al Genius Bar

genius-barIeri, improvvisamente e inaspettatamente dopo 7 mesi di servizio ineccepibile,  il mio iPhone ha deciso di trasformarsi in un iPod Touch: l’audio delle telefonate misteriosamente sparito (dallo speaker interno, dal vivavoce, dalle cuffie e dall’auticolare BT), presente invece in tutte le altre funzionalita’.

Dopo aver provato reset vari, ripristino e riti voodo desisto e chiamo il servizio clienti Apple (199 120 800).
Vengo accolto da una signorina che, senza nemmeno dirmi ‘buongiorno’ mi chiede numero di serie dell’iPhone, nome, cognome, indirizzo email, numero di cellulare e numero di scarpe: avuti i dati diventa improvvisamente gentile e mi chiede di illustarle il problema.

Le spiego il malfunzionamento e lei mi mette davanti a 2 scelte: prenotare il ritiro da parte di un corriere del telefono e riceverlo riparato entro 5 giorni oppure (essendo a Roma) prenotare un appuntamento al Genius Bar nell’AppleStore del centro commerciale Roma Est.

Scelgo la seconda e la sera, uscito dall’ufficio, mi sciroppo una ventina di chilometri per raggiungere il centro commerciale.

L’AppleStore come al solito e’ talmente pieno di gente da dover quasi sgomitare per raggiungere il GeniusBar, dietro le casse: gente che, oltre a osservare-toccare-provare i prodotti, inaspettatamente per il periodo economico non proprio felice COMPRA. :-)

Mi accoglie Paolo, ‘Apple Specialist’ al quale spiego nuovamente il problema: prende in consegna l’iphone, lo scruta con un un oggetto simile a un otoscopio (forse per verificare i famosi sensori di umidita’?), fa un paio di telefonate di prova e poi conclude con un laconico “Ok, non funziona, te lo cambio.“.

10 minuti dopo esco dall’apple store con un iPhone nuovo (leggi ‘rigenerato’), senza graffi e per di piu’ con la batteria sicuramente in uno stato migliore del precedente.

Che dire? Lode a Apple per l’ottima assistenza che, non smettero’ mai di dirlo, e’ fra le motivazioni che giustificano pienamente i prezzi nettamente piu’ alti rispetto alla concorrenza.

Contrassegnato da tag , , , ,

Google, finalmente il supporto nativo per la sincronizzazione di Contatti e Calendari su iPhone

Google ha finalmente  introdotto la possibilità di sincronizzare ‘OverTheAir’ contatti e calendari del proprio account su iPhone, senza utilizzare servizi come NuevaSync.

Su questa pagina tutti i dettagli sulla configurazione.

Contrassegnato da tag , ,

Migrare un DataBase da MySQL a MS SQLServer 2000

La domanda su come fare mi è stata posta oggi in ufficio, e la risposta non posso che prenderla dalla pagina dedicata su TechNet:

Di seguito viene riportata una procedura per configurare Microsoft SQL Server al fine di migrare il database MySQL.

1. Installare il supporto MyODBC, disponibile all’indirizzo http://www.mysql.com/

2. Durante l’installazione viene visualizzata la finestra di dialogo seguente:


      Configurare le impostazioni ODBC utilizzando le informazioni seguenti:
      Windows DSN name: test
      Description: Database di prova
      MySQL Database: test
      Server: seawolf.microsoft.com
      User: cgunn
      Password: my_password
      Port: 3306
      Nel caso delle impostazioni precedenti, il nome specificato nel campo “Windows DSN name” deve essere univoco nel computer che esegue la connessione, l’impostazione relativa al server può essere un nome di dominio completo (assicurarsi che sia disponibile un sistema di risoluzione dei nomi, per esempio tramite DNS) oppure un indirizzo IP.

    3. Quindi eseguire l’Importazione/Esportazione guidata DTS. Dal gruppo di programmi Microsoft SQL Server selezionare Importazione ed esportazione dati. Verrà visualizzata la finestra di dialogo seguente.

        Fare clic su Avanti, quindi proseguire con il passaggio successivo.

      4. Fornire le informazioni necessarie sull’origine dei dati: queste informazioni devono essere MySQL come origine dei dati ODBC e test come DSN del sistema. Quindi, fornire le credenziali di accesso, il nome utente e la password mostrati nella successiva finestra di dialogo, infine fare clic su Avanti.

        5. Fornire i dettagli della connessione di destinazione, come mostrato nella finestra di dialogo seguente, quindi fare clic su Avanti.

          6. La finestra di dialogo Copia tabella o query consente di selezionare gli oggetti del database dall’origine, in questo caso MySQL. Selezionare Copia tabelle e viste dal database di origine. È opportuno rammentare che MySQL non supporta le viste pertanto, selezionando questa opzione, verranno copiati solo gli oggetti tabella, come mostrato di seguito. Fare clic su Avanti per continuare.

            7. Verrà visualizzata la finestra di dialogo Seleziona tabelle e viste di origine, in cui è possibile selezionare le tabelle di origine e quelle di destinazione.

              8. Fare clic sul pulsante con i trattini per eseguire la trasformazione dei dati, come mostrato nella finestra di dialogo seguente Mapping e trasformazioni di colonna.

                  In questa finestra di dialogo vengono abbinati i tipi di dati di origine e di destinazione e vengono selezionati i campi di dati Null. Al termine, fare clic su OK.
                  Verrà visualizzata la finestra di dialogo Salva, pianifica e replica pacchetto, che consente di pianificare la migrazione fuori degli orari di punta e di salvare il pacchetto DTS in percorsi e formati diversi.

                9. La finestra di dialogo Salva pacchetto DTS fornisce due tipi di password per il pacchetto DTS. La prima password è quella del proprietario e consente di proteggere tutte le informazioni sugli utenti e sulle password incluse nel pacchetto, mentre la password dell’utente consente di eseguire il pacchetto e impedisce qualsiasi esecuzione non autorizzata, come mostrato di seguito. Fare clic su Avanti per continuare.

                  10. Infine, la finestra di dialogo Completamento della Importazione/Esportazione guidata DTS riepiloga le opzioni selezionate nella procedura guidata.

                      Fare clic su Fine per iniziare la migrazione dei dati.

                    11. La finestra di dialogo Esecuzione pacchetto visualizza lo stato di ogni attività mentre viene eseguita. Un segno di spunta verde indica il completamento di un’attività. Se l’esecuzione di un’attività non riesce e l’errore interrompe il processo, verrà visualizzata una finestra che riporta le informazioni sull’errore.

                      Contrassegnato da tag ,

                      .NET: effettuare query SQL su DataTable in memoria

                      Scenario: realizzazione di un sistema di ‘aggregazione dati’ in grado di caricare in memoria dati da fonti diverse (Db SQLServer/Oracle/MySQL, files Excel, Db Access) ed utilizzarli per realizzare semplici ‘reports’.

                      Riempire di dati le DataTables e’ cosa da poco, aggregarle all’interno di un DataSet e’ ancora piu’ semplice, comincia a saltar fuori qualche difficolta’ quando arriva il momento di permettere agli utenti di  ‘interrogare’ il DataSet utilizzando una sintassi ‘SQL-Like’: soluzione ottima per l’utente finale con una minima infarinatura di Structured Query Language, difficile da realizzare senza scomodare LINQ e il Framework 3.5.

                      Per fortuna ci viene incontro Emmet Gray, ottimo programmatore che ha realizzato una classe che implementa un engine SQL minimale utilizzabile sui DataSet: SQL_Engine.

                      L’utilizzo di tale classe e’ straordinariamente semplice: una volta riempito il nostro DataSet con le tabelle contenenti i dati da interrogare, basta instanziare l’oggetto passando al constructor il dataset

                      
                      Dim sc As New SQL_Engine.SelectCommand(ds)
                      
                      

                      e richiamare il metodo ‘Execute’ (passando come parametro la query da eseguire) , che si occupera di restituire una DataTable contenente i risultati

                      
                      Dim dt As DataTable = sc.Execute(query)
                      
                      

                      Contrassegnato da tag , ,

                      iUI, framework per interfacce web compatibili con iPhone

                      Leggo questa richiesta nei commenti di un post dedicato a BloggerSync:

                      [...] realizzare una pagine navigabile con iphone, è solo un probelma di dimensioni e css.. ??
                      Puoi indicarmi qualche risorsa in merito per imparare qualcosa ? [...]

                      Ultimamente sto realizzando delle semplici Web Applications per iPhone e sto utilizzando iUI, un framework che, con un uso intensivo di Javascript punta alla realizzazione di applicazioni web con look&feel assolutamente simile a quello delle applicazioni ‘stand-alone’.

                      L’utilizzo e’ estremamente semplice, la documentazione e gli esempi presenti aiutano non poco: buon divertimento!

                      http://code.google.com/p/iui/

                      Contrassegnato da tag ,

                      Leopard su iBook G4: Safari 3.2.1 e CPU al 100%?

                      Ho installato Leopard sul mio iBook G4 gia’ da qualche tempo, senza riscontrare nessun problema.

                      Tuttavia, dopo l’ultimo aggiornamento di Safari (che ha portato il browser alla versione 3.2.1) ho iniziato a notare un fastidioso comportamento: dopo qualche minuto di utilizzo, il browser di mamma Apple iniziava a impegnare il processore in maniera anomala, bloccando nel contempo anche la navigazione. L’unico modo per risolvere il blocco si riduceva a una ‘chiusura forzata’ e al restart del browser.

                      Dopo alcune prove, sono riuscito a restringere la ricerca del problema alle nuove funzionalita’ introdotte in questa ultima versione, e in particolare al ‘filtro anti-phishing’ (nella tab ‘Sicurezza’ delle preferenze di Safari):

                      immagine-1

                      Disabilitando questa utile funzionalita’ (che ho potuto verificare dare problemi anche su altre macchine con processore PowerPC, mentre funziona senza alcun intoppo sul mio MacMini Intel) Safari ricomincia a funzionare senza blocchi.

                      In attesa del prossimo aggiornamento di Safari…:-)

                      Contrassegnato da tag , ,
                      Follow

                      Get every new post delivered to your Inbox.