Informatica
Prova eReader Sony PRS-T1
0Per motivi di lavoro mi è capitato tra le mani l’ultimo modello di eReader prodotto dalla Sony, PRS-T1. Dal sito del produttore:
Il Reader di e-book più leggero al mondo*
Lettore ultra sottile e leggero con schermo tattile simile alla carta e Wi-Fi®
- Accesso immediato ai siti Web e capacità Wi-Fi®
- Piccolo, sottile e leggero con un peso di appena 168 grammi
- Doppio display tattile nitido
- Schermo E Ink simile alla carta per semplificare la lettura
- Non rimanere mai senza parole con i 12 dizionari integrati
La prima impressione è di un dispositivo molto pratico nell’uso, con dimensioni non eccessive e veramente leggero (non affatica il polso durante l’uso). La scatola contiene l’eReader Sony PRS-T1, il cavo USB per la connessione al PC, manuale cartaceo di istruzioni in varie lingue, pennino di plastica per un più agevole uso dello schermo tattile (che comunque risponde bene anche alla semplice pressione delle dita). Degno di nota: lo schermo supporta lo scrolling ed il multitouch per lo zoom.
I dettagli sono ben curati ed anche il materiale costruttivo sembra essere di ottima qualità, come per la maggioranza dei prodotti Sony.
Accendiamo il dispositivo premendo il relativo pulsante posto nella parte inferiore, attendendo qualche manciata di secondi per l’inizializzazione.
Lo schermo, in tecnologia E Ink® Pearl, ha un buon contrasto anche se i relativamente lunghi tempi di refresh (vero punto debole di questa tecnologia) sono un pò fastidiosi.
Questo eReader è molto reattivo, anche se le prestazioni non sono certo paragonabili ad un qualsiasi tablet (iPad e simili) che, ricodiamo, hanno altre destinazioni d’uso.
La risoluzione del display, 800×600 pixel con una scala di grigi a 16 livelli, è veramente ottima e capace di rendere bene anche i dettagli delle immagini.
Certo, bisogna tenere bene a mente che si tratta di un dispositivo per leggere testi e non per guardare foto (a meno di non essere appassionati di Ansel Adams) o materiale multimediale.
La grande sorpresa la riserva il pulsante Reader Store, il quale afferma -candidamente- che non sarà disponibile prima di primavera. Epic fail.
Non rimane altro, per poter leggere qualcosa oltre ai 2 eBook ed il manuale d’uso inclusi, di utilizzare la rete WiFi (802.11b/g/n) oppure una scheda di memoria MicroSD da inserire nell’apposito slot sul retro del dispositivo.
Da sottolineare che il dispositivo ha una memoria interna di 2GByte, capace di contenere oltre 1000 eBooks.
Per concludere, considerando il costo non proprio basso del dispositivo (intorno ai 200€ ivati), devo dire che non mia particolarmente entusiasmato. Certo, come prima dicevo, bisogna tenere bene a mente che si tratta di uno strumento creato per sostituire le edizioni cartacee dei libri ed assolve sicuramente bene a questo compito. Tuttavia, anche se decisamente pratico e leggero in confronto alle edizioni cartacee, il dispositivo trasmette una sensazione di freddezza (parole testuali di mia moglie) che ne ostacola l’empatia.
Per concludere vi propongo un video riepilogativo e dimostrativo del Sony PRS-T1 che ho tra le mani.
Postfix: black e white list per i mittenti
0Può sembrare banale ma in questi giorni ho avuto qualche difficoltà a capire come bloccare i mittenti non unisi.it. Ho avuto così nuovamente a che fare con la configurazione di Postfix da vicino. Senza troppo tergiversare, visto che lo scopo di questo post è avere un quick reminder per il futuro, ecco come fare:
in main.cf (/etc/postfix/main.cf):
smtpd_sender_restrictions = check_sender_access hash:/etc/postfix/sender_access, reject
I dettagli e le possibili opzioni sono spiegate nel manuale di Postfix. Adesso creo il file sender_access e scrivo:
unisi.it OK
che significa, per farla breve, che tutti gli indirizzi e-mail che hanno come dominio @unisi.it sono accettati.
A questo punto creo l’hash map con postmap:
postmap sender_access
il quale crea il file sender_access.db. Per finire, riavviamo postfix.
Il risultato lo possiamo verificare dai log (/var/log/mail.log):
postfix/smtpd[19994]: connect from xxx.unisi.it[193.205.x.x] postfix/smtpd[19994]: NOQUEUE: reject: RCPT from xxx.unisi.it[193.205.x.x]: 554 5.7.1 <o-zone@zerozone.it>: Sender address rejected: Access denied; from=<o-zone@zerozone.it> to=<xxxx@unisi.it> proto=ESMTP helo=<XXX.UNISI.IT>
Giocare con Latitude e Google Maps
0In merito al progetto iDem ho lavorato con le API v.3 di Google Maps ed il sistema di localizzazione del visitatore. Sfruttando alcune funzionalità dei browser moderni, inclusi molti di quelli installati nei nostri dispositivi mobili (soprattutto Android), è possibile identificare con discreta precisione da quale zona arriva il nostro visitatore, presentando le risorse a lui più vicine.
Utilizzando poi chiamate asincrone (Ajax) è possibile aggiornare una Maps (…e non solo…) in maniera dinamica.
Passiamo subito alla parte del codice, in PHP e Javascript. E’ necessario definire un DIV con id=”map” dove visualizzare la mappa:
<div id='map' style='width:520px; height: 300px; margin-top: 10px;'> Loading Google Maps... </div>
e poi incorporiamo il necessario codice Javascript nella nostra pagina:
<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">
<html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' lang='en'>
<head>
<meta http-equiv='content-type' content='text-html; charset=UTF-8'></meta>
<link rel='stylesheet' type='text/css' href='http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.1/themes/base/jquery-ui.css'>
<script type='text/javascript' src='http://maps.google.com/maps/api/js?sensor=true'></script>
<script type='text/javascript' src='https://ajax.googleapis.com/ajax/libs/jquery/1.6.0/jquery.min.js'></script>
<script src='http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.9/jquery-ui.min.js'></script>
<link href='http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.9/themes/base/jquery-ui.css' rel='stylesheet' type='text/css'/>
<script type='text/javascript' src='http://code.google.com/apis/gears/gears_init.js'></script>
...
P.S. Google Gears è consigliato nel caso non sia possibile utilizzare i metodi nativi W3C nella localizzazione dell’utente.
Nelle pagine dove vogliamo utilizzare il sistema descritto è poi necessario inserire questo javascript:
<script type='text/javascript'>
$(document).ready(function() {
var initialLocation;
var defaultLoc = new google.maps.LatLng(41.87194,12.56738); // Visualizza tutta l'Italia
var browserSupportFlag = new Boolean();
var mapOptions = {
zoom: 5,
mapTypeId: google.maps.MapTypeId.ROADMAP,
center: defaultLoc
};
var map = new google.maps.Map(document.getElementById('map'),mapOptions);
// Try W3C Geolocation (Preferred)
if(navigator.geolocation) {
browserSupportFlag = true;
navigator.geolocation.getCurrentPosition(function(position) {
initialLocation = new google.maps.LatLng(position.coords.latitude,position.coords.longitude);
map.setCenter(initialLocation);
map.setZoom(10);
}, function() {
map.setCenter(initialLocation);
});
// Try Google Gears Geolocation
} else if (google.gears) {
browserSupportFlag = true;
var geo = google.gears.factory.create('beta.geolocation');
geo.getCurrentPosition(function(position) {
initialLocation = new google.maps.LatLng(position.latitude,position.longitude);
map.setCenter(initialLocation);
map.setZoom(10);
}, function() {
map.setCenter(initialLocation);
});
// Browser doesn't support Geolocation
} else {
map.setCenter(initialLocation);
}
var geocoder = new google.maps.Geocoder();
google.maps.event.addListener(map, 'idle', showMarkers);
function showMarkers() {
// get viewport bounds
var southWestLat = map.getBounds().getSouthWest().lat();
var southWestLng = map.getBounds().getSouthWest().lng();
var northEastLat = map.getBounds().getNorthEast().lat();
var northEastLng = map.getBounds().getNorthEast().lng();
$.ajax({
type: 'POST',
url: 'ajaxCb.php',
dataType: 'json',
data: ({'action':'getGroupMarkers', 'southWestLat' : southWestLat , 'southWestLng' : southWestLng , 'northEastLat' : northEastLat , 'northEastLng' : northEastLng}),
success: function(groups) {
groupsMap = groups.data;
var markers=new Array();
var infowindow = new google.maps.InfoWindow({
content: "Loading..."
});
for (var group in groupsMap){
if(typeof(groupsMap[group]) == 'object') {
var center = new google.maps.LatLng(groupsMap[group].lat, groupsMap[group].lng);
var groupOptions = {
strokeColor: '#FF0000',
strokeOpacity: 0.6,
strokeWeight: 2,
fillColor: '#FF0000',
fillOpacity: 0.25,
map: map,
center: center,
radius: groupsMap[group].radius
};
var groupCircle = new google.maps.Circle(groupOptions);
markers[group] = new google.maps.Marker({
position: center,
map: map,
title: groupsMap[group].name,
html: "<h3><img src='/avatar/"+groupsMap[group].avatar+"' class='icon'> <a href='/group/"+groupsMap[group].id+"'>"+groupsMap[group].name+"</a></h3><p>"+groupsMap[group].description+"</p>"
});
google.maps.event.addListener(markers[group], 'click', function () {
infowindow.setContent(this.html);
infowindow.open(map, this);
});
}
}
});
}
});
});</script>
Come potete vedere, ogni qualvolta l’utente si muove nella mappa viene generato un evento che effettua una chiamata ajax ad ajaxCb.php con 5 parametri POST:
'action':'getGroupMarkers', 'southWestLat' : southWestLat, 'southWestLng' : southWestLng, 'northEastLat' : northEastLat, 'northEastLng' : northEastLng
Nel file ajaxCb.php ci prepariamo a soddisfare adeguatamente la richiesta:
$ajaxAction = $_POST["action"];
function isBetween($numToCheck, $high, $low) {
if($numToCheck <= $low) return false;
if($numToCheck >= $high) return false;
return true;
}
if($ajaxAction == 'getGroupMarkers') {
$SW_Lat = $_POST['southWestLat'];
$SW_Lng = $_POST['southWestLng'];
$NE_Lat = $_POST['northEastLat'];
$NE_Lng = $_POST['northEastLng'];
$data = array();
$result = DB_Query("SELECT ID,Name,Avatar,Description,Place FROM Groups AS t1 WHERE LENGTH(Place) > 0;");
if(mysql_num_rows($result) > 0) {
while($row = mysql_fetch_array($result, MYSQL_ASSOC)) {
$groupId = $row["ID"];
$groupName = stripslashes($row["Name"]);
$groupAvatar = stripslashes($row["Avatar"]);
$groupDescription = stripslashes($row["Description"]);
$groupPlace = unserialize(stripslashes($row["Place"]));
$groupPlaceLat = $groupPlace["Latitude"];
$groupPlaceLng = $groupPlace["Longitude"];
if(isBetween($groupPlaceLat, $NE_Lat, $SW_Lat) && isBetween($groupPlaceLng, $NE_Lng, $SW_Lng)) {
array_push($data,array('id'=>$groupId, 'name'=>$groupName, 'avatar'=>$groupAvatar, 'description'=>$groupDescription, 'lat'=>$groupPlaceLat, 'lng'=>$groupPlaceLng, 'radius'=>500);
}
}
}
echo json_encode(array('status'=>'success', 'data'=>$data));
}
Provo a spiegare in poche parole come funziona il sistema. L’evento generato quando l’utente si muove nella mappa invia le coordinate Nord-Est e Sud-Ovest dell’area visualizzata.
Da queste due coordinate posso fare una ricerca di tutti gli elementi che sono in quella zona semplicemente verificando se la Latitudine e la Longitudine di X è tra NE e SW:
if(isBetween($groupPlaceLat, $NE_Lat, $SW_Lat) && isBetween($groupPlaceLng, $NE_Lng, $SW_Lng)) {
A questo punto, se l’oggetto è nella zona, aggiungo i valori che voglio riportare sulla mappa ad una struttura di array pronta per essere condificata in JSON ed inviata al browser per la visualizzazione. Nell’esempio creo un marker per ogni gruppo a cui assegno una infoWindow per visualizzare, al click dell’utente, alcune informazioni formattate in HTML.
Per far capire meglio il funzionamento, ecco il tracciato delle chiamate tra il browser utente ed il server:
UTENTE: muove la mappa
AJAX: POST 200 text/xml http://www.i-dem.eu/ajaxCb.php
action getGroupMarkers
southWestLat 43.25568276691273
southWestLng 10.757850646484371
northEastLat 43.5549949798281
northEastLng 11.471961974609371
SERVER LAMP: risposta in formato JSON
{“status”:”success”,”data”:[{"id":"1","name":"xxxx","avatar":"xxxx.jpg","description":"Gruppo xxxx","lat":43.3186614,"lng":11.3305135,"radius":11500},{"id":"30","name":"yyyy","avatar":"yyyyy.jpg","description":"Gruppo yyyy","lat":43.3186614,"lng":11.3305135,"radius":2500}]}
BROWSER: interpreta la stringa ed aggiorna la mappa
L’unico “neo”, se così vogliamo definirlo, è che ogni volta che l’utente visualizza la nostra pagina riceve un alert tipo:
che lo avverte della richiesta di conoscere la propria posizione. E’ comunque una garanzia da un punto di vista della privacy che non dobbiamo trascurare.
La mia VPS su NordicVPS è down
0
Visto che il supporto tecnico di NordicVPS non rispondono ai miei tickets, alle mie mail ed ai miei post su twitter @nordicvps, scrivo qua un bel post di denuncia su quanto sta accadendo alla mia VPS. Il grafico sotto è esplicativo:
praticamente sono 4 giorni, da venerdì 9 Dicembre, che la mia VPS è down. Il loro Twitter segnala che il
problema è causato da alcuni “Abusive customer” e che è necessario un rebbot della macchina. Beh, sono passati ormai 4 giorni ed ancora nulla.
La cosa più antipatica, tra le altre, è che non rispondono nè alle e-mail nè ai tickets di assistenza, lasciandomi in uno stato di totale frustrazione.
A questo punto ho chiesto di avere un rimborso, almeno parziale, ed un dump delle tabelle MySQL, così da poter migrare verso un nuovo lido. Fortunatamente, dopo alcune infelici esperienze passate, è già da alcuni anni che per i miei siti web importanti opto per un provider DNS diverso dall’Hosting, permettendomi così una rapida migrazione (basta cambiare il DNS e fare l’upload dei dati !).
Sono amareggiato, lo ammetto, perchè NordicVPS non era nuova a guasti (e capisco che possono succedere) ma non era mai capitato che non rispondessero, per così tanti giorni, ai tickets di assistenza. Posso capire che per 59.50$ annuali non posso pretendere un uptime del 99.9% ma neppure down prolungati ed una totale assenza di customer care. Oltretutto, cercando sul web, non sono l’unico ad aver avuto gli stessi problemi. A questo punto non solo me ne andrò al più presto dai loro servers ma non lo consiglierò neppure.
Aggiornamento di Venerdì 23/12/2011: la VPS è ancora giù, senza alcuna risposta agli oltre 14 tickets aperti.
Aggiornamento di Giovedì 09/02/2012:
Dear Michele Pinassi (Openitaly.net)
Please backup all important data!
Final call before termination of your VPS.
All operations are being terminated and all node servers will go offline on Friday the 10th of February!
/NordicVPs.com
Autenticazione ‘social’ con Janrain !
0Non è una novità: ogni volta che scopriamo un servizio interessante, eccoci a dover nuovamente cliccare sul bottone “Crea nuovo account“, per poi compilare lunghi form, verificare l’indirizzo email, ricordarsi la password.
Quanto è più comodo poter usare, per l’autenticazione, alcuni dei più famosi social network mondiali ? Beh, se non si tratta di servizi critici, poter chiedere la garanzia di un account ad un attore di terze parti come Google o Facebook è molto comodo: basta password da memorizzare, procedure di recupero da inventare, captcha…
C’è però un problemino: quale terza parte scegliamo di usare ? Beh, non è banale ma prendendo anche solo i 3 maggiori social network:
vediamo che ognuno ha la sua libreria ed i suoi metodi per l’autenticazione attraverso il protocollo OAuth.
A tal proposito ci viene in aiuto Janrain, un comodo servizio -gratuito per i piccoli siti- che funge da meta-autenticatore: sarà Janrain a presentare all’utente il servizio social con cui intende autenticarsi, dopodichè provvederà lui ad inviare al nostro server il token ed altre informazioni utili sull’utente.
Come si implementa sul proprio sito web ?
Innanzitutto si crea un account su Janrain.com e poi si crea una nuova “Applicazione”. A questo punto si decide se si preferisce il widget modale (apre un popup) oppure embedded (si tratta di un <div> da inserire nelle proprie pagine).
Il secondo passaggio, un pò più oneroso in termini di tempo, è la scelta dei providers di autenticazione e la creazione, per ognuno di essi, di una applicazione. Il percorso è guidato ed è comunque molto semplice da realizzare.
Dal lato client, è sufficente inserire il loro snipet javascript nelle pagine web dove l’utente può accedere all’autenticazione. Personalmente ho preferito copiare il codice in un nuovo file:
<script type='text/javascript' src='[path_to_js]/janrain.js'></script>
Importante ricordarsi di cambiare l’URL della pagina per il callback dell’autenticazione:
janrain.settings.tokenUrl = 'http://www.openitaly.net/janrain.php';
A questo punto passiamo alla parte più interessante del processo di single sign-on: la pagina di callback. Sul loro sito ci sono esempi i tutti i linguaggi di programmazione più comuni, compreso il PHP. Io ho preferito fare alcune prove e posso dare qualche informazione in più, con il var_dump di quanto restituiscono i tre provider succitati:
<?php
$rpx_api_key = '[API KEY DELL'APPLICAZIONE SU JANRAIN]'; $engage_pro = false; /* STEP 1: Extract token POST parameter */ $token = $_POST['token']; if(strlen($token) == 40) {//test the length of the token; it should be 40 characters /* STEP 2: Use the token to make the auth_info API call */ $post_data = array('token' => $token, 'apiKey' => $rpx_api_key, 'format' => 'json', 'extended' => 'true'); //Extended is not available to Basic. $curl = curl_init(); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_URL, 'https://rpxnow.com/api/v2/auth_info'); curl_setopt($curl, CURLOPT_POST, true); curl_setopt($curl, CURLOPT_POSTFIELDS, $post_data); curl_setopt($curl, CURLOPT_HEADER, false); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($curl, CURLOPT_FAILONERROR, true); $result = curl_exec($curl); if ($result == false) { $mySession->sendMessage("cURL error: ".curl_error($curl)."(".curl_errno($curl).")",T_ERROR); } curl_close($curl); $authInfoArray = json_decode($result, true); if($authInfoArray['stat'] == 'ok') { $profileArray = $authInfoArray["profile"]; // var_dump($profileArray); $identifier = CleanInput($profileArray["identifier"]); $result = dbQuery("SELECT Username FROM Users WHERE providerId='$identifier';"); if(mysql_num_rows($result) == 1) { $row = mysql_fetch_array($result, MYSQL_ASSOC); $userName = stripslashes($row["Username"]); if($userName) { // Ok, questo utente e' registrato. Autentica la sessione e vai alla sua pagina principale .... } } // Se l'utente non e' presente nel DB, richiedi autenticazione oppure l'iscrizione if($profileArray["providerName"] == "Facebook") { /* FACEBOOK array(10) { ["name"]=> array(3) { ["givenName"]=> string(9) "Openitaly" ["familyName"]=> string(3) "Net" ["formatted"]=> string(13) "Openitaly Net" } ["photo"]=> string(60) "http://graph.facebook.com/100000185893913/picture?type=large" ["address"]=> array(1) { ["formatted"]=> string(12) "Siena, Italy" } ["displayName"]=> string(13) "Openitaly Net" ["preferredUsername"]=> string(12) "OpenitalyNet" ["url"]=> string(33) "http://www.facebook.com/openitaly" ["gender"]=> string(4) "" ["utcOffset"]=> string(5) "01:00" ["providerName"]=> string(8) "Facebook" ["identifier"]=> string(54) "http://www.facebook.com/profile.php?id=[ID]" } */ .... } else if($profileArray["providerName"] == "Twitter") { /* TWITTER array(7) { ["photo"]=> string(74) "http://a3.twimg.com/profile_images/1665796327/logoSquare128x128_normal.png" ["name"]=> array(1) { ["formatted"]=> string(9) "OpenItaly" } ["displayName"]=> string(9) "OpenItaly" ["preferredUsername"]=> string(9) "OpenItaly" ["url"]=> string(28) "http://twitter.com/OpenItaly" ["providerName"]=> string(7) "Twitter" ["identifier"]=> string(51) "http://twitter.com/account/profile?user_id=[ID]" } */ .... } else if($profileArray["providerName"] == "Google") { /* GOOGLE array(9) { ["googleUserId"]=> string(21) "[userId]" ["name"]=> array(3) { ["givenName"]=> string(7) "Michele" ["familyName"]=> string(7) "Pinassi" ["formatted"]=> string(15) "Michele Pinassi" } ["verifiedEmail"]=> string(25) "michele.pinassi@gmail.com" ["displayName"]=> string(15) "michele.pinassi" ["preferredUsername"]=> string(15) "michele.pinassi" ["url"]=> string(53) "https://www.google.com/profiles/[ID]" ["providerName"]=> string(6) "Google" ["identifier"]=> string(53) "https://www.google.com/profiles/[ID]" ["email"]=> string(25) "michele.pinassi@gmail.com" } */ .... } else { // Provider non riconosciuto. Che faccio ? } } else { // Gracefully handle auth_info error. Hook this into your native error handling system. $mySession->sendMessage("Error while signing on: ".$authInfoArray['err']['msg'],T_ERROR); } } else { // Gracefully handle the missing or malformed token. Hook this into your native error handling system. $mySession->sendMessage("Abort received while signing on. Wanna try again ?",T_ERROR); }
Come potete vedere, non tutti i provider restituiscono gli stessi dati. Tuttavia Janrain suggerisce di utilizzare identifier come identificatore univoco dell’utente.
Spero di esservi stato di aiuto e …buona autenticazione !
DRM e eBooks
5L’ateneo di Siena, dove lavoro, ha sottoscritto un contratto con l’editore Casalini per l’accesso alla sua piattaforma di eBooks “Torrossa“:
Benvenuto su Torrossa.it! La piattaforma full text di Casalini libri mette a disposizione 190.000 contenuti digitali, 9600 e-book e 480 periodici di 135 case editrici italiane e spagnole.
Entusiasta, sono subito andato a vedere il materiale disponibile ed ho trovato numerosi testi interessanti, consultabili anche in formato PDF Full Text. Ingenuamente, ho scaricato alcuni PDF che ho poi trasferito sul mio tablet, per leggermeli comodamente da casa: invano, ho scoperto che tutti i PDF sono apribili solamente con Adobe Reader perchè i contenuti sono protetti. Deluso e frustrato, ho approfondito la questione del DRM di Torrossa scoprendo che:
- i PDF sono scaricabili ma accessibili solamente se si è connessi ad internet da un range IP abilitato (come quello dell’Università di Siena)

- i PDF hanno una data di scadenza, circa 10-15 minuti dal download, rendendo velocemente inutilizzabile il file dopo lo scaricamento
Insomma, ipotizzando la necessità di dover studiare (ma anche semplicemente leggere) uno di questi testi, le procedure di sicurezza introdotte rendono il tutto molto scomodo e frustrante. Personalmente ho proprio abbandonato l’idea di usufruire di questo eBooks, anche perchè non posso pensare di dover essere collegato alla rete informatica dell’Ateneo per potermi leggere uno di questi testi.
Approfittiamone per approfondire la questione dei DRM, Digital Rights Managements. Direttamente sul sito di Adobe troviamo una descrizione abbastanza esaustiva del processo (http://www.adobe.com/it/epaper/features/drm/howdrmworks.html):
Le tecnologie DRM funzionano permettendo ai distributori di prodotti elettronici di controllare l’accesso alle visualizzazioni dei prodotti, siano essi pubblicati sotto forma di stampati, musica o di immagini con una sorta di codifica personalizzata. Agli utenti finali che hanno acquistato i diritti vengono fornite “chiavi” personali per la visualizzazione o l’ascolto dei prodotti, generalmente con la limitazione della copia, stampa e ridistribuzione.
Praticamente, sfruttando sistemi di crittazione, è possibile introdurre all’interno dei PDF dei “metadati” che vengono interpretati dal software (in questo caso Adobe Reader), che “imparerà” come decodificare i dati, chiedendo ad un server remoto la chiave. Il server effettuerà le verifiche del caso e consentirà o meno l’apertura del documento.
Concludendo, penso che la tutela dei diritti -commerciali e di copyright- sia importante ma questo non dovrebbe influire in maniera così pesante sulle possibilità di utilizzo di tali documenti. Deve essere trovato un giusto connubio tra tutela e fruizione, raggiungibile solamente con l’implementazione di migliori tecnologie ed anche la volontà degli editori di aprire il proprio mercato anche ai materiali digitali.
Primi passi con il VoIP – Debian, Asterisk e FreePBX
0Il titolo di questo post riassume perfettamente quello di cui parliamo oggi, ovvero come gettare le basi per un centralino VoIP full-featured con software libero ed, eventualmente, hardware Digium (TDM410 e 4 FXO).
Si inizia installando una linux box con Debian 6.0.3. Il mio consiglio è di tenerla il più leggera e pulita possibile: niente X, niente programmi inutili etc etc… il sistema base è perfetto !
Il passo successivo è l’installazione di Asterisk e di FreePBX, una GUI che ne permette un facile utilizzo e configurazione. Fortunatamente per tutti voi (la mia prima installazione di un sistema simile, 5 anni addietro, è stata un macello !), c’è chi ha creato dei comodi scripts che automatizzano gran parte del processo. In particolare, per la Debian, abbiamo questi:
http://www.freepbx.org/support/documentation/installation/install-process-for-debian / http://www.corenetworks.com.au/wiki/doku.php
Sono necessarie comunque alcune piccolissime modifiche, in particolare l’aggiornamento del numero di versione di Asterisk (serie 1.4.x), ad oggi alla 1.4.42 (lo script, se non modificato, scaricherà ed installerà la 1.4.39).
Lo script installa automaticamente anche Dahdi, la LibPRI e gli Asterisk AddOns (CDR su MySQL, MoH ed altro…), velocizzando tantissimo il nostro lavoro di installazione.
Interfacciarsi alla rete telefonica tradizionale
Per chi ha intenzione di interfacciare il centralino Asterisk alla rete telefonica tradizionale (PSTN) sarà necessario acquistare dell’hardware dedicato. Personalmente mi son sempre trovato bene con le schede Digium, supportate al 100% da Asterisk (il produttore è lo stesso…) e di veloce installazione e configurazione.
In particolare ho utilizzato 2 schede TMD410 per interfacciare 8 linee PSTN ad un sistema telefonico VoIP, acquistando anche 8 moduli FXO. I moduli FXO servono per collegare linee telefoniche ATTIVE ad un centralino Asterisk. I moduli FXS, invece, servono se vogliamo collegare a questo centralino anche dei telefoni/fax PSTN.
Il modulo Dahdi, e relativi tools, è il driver per queste schede (ed altre della Digium) e richiede un pò di tempo per capire come configurarlo, anche perchè questo modulo si occupa dell’echo cancellation, riconosce i fax, i toni di linea…
Insomma, questi tools dovranno diventare vostri amici, anche perchè questa è la fase più delicata di tutto il setup: dahdi_cfg, dahdi_genconf, dahdi_hardware, dahdi_monitor, dahdi_scan, dahdi_test, dahdi_tool.
P.S. Mentre lo script succitato provvede a scaricare e compilare, leggetevi comodamente il manuale
Due parole sul funzionamento di Asterisk…
Come avevo già parlato in alcune mie slides in occasione del Linux Day (www.zerozone.it/Documenti/Presentazioni/VoIP/ e www.zerozone.it/Documenti/Presentazioni/Asterisk/Asterisk.pdf), Asterisk è un PBX (Private Branch eXchange) VoIP che offre, oltre alle funzionalità di routing e di grouping proprie di un qualsiasi centralino, anche funzioni di IVR, Conference, Fax, Queues, etc etc etc
La configurazione di Asterisk avviene attraverso dei files, generalmente presenti nella directory /etc/asterisk, dove si definisce quali sono i moduli da disattivare, le configurazioni, i flussi di routing, l’autenticazione etc etc etc
In rete trovate centinaia di pagine su come funziona Asterisk pertanto vi rimando al buon vecchio Google. Tuttavia quello che dovete aver ben chiaro sono i contesti (context), ovvero i “punti di accesso” delle telefonate. E’ importante perchè Asterisk (file /etc/asterisk/extensions.conf) si aspetta che le chiamate in ingresso arrivino dal contesto [from-pstn] :
;------------------------------------------------------------------------------- ; from-pstn: ; ; Entry context for calls from the outside world to hit FreePBX [from-pstn] include => from-pstn-custom ; create this context in extensions_custom.conf to include customizations include => ext-did include => ext-did-post-custom include => from-did-direct include => ext-did-catchall ; THIS MUST COME AFTER ext-did
pertanto dobbiamo assicurarci che il file di configurazione di Dahdi (/etc/asterisk/dahdi-channels.conf) contenga il context giusto:
; Span 1: WCTDM/0 "Wildcard TDM410P Board 1" (MASTER) ;;; line="1 WCTDM/0/0 FXSKS" signalling=fxs_ks callerid=asreceived group=0 context=from-pstn channel => 1 callerid= group= context=default
Possiamo adesso tralasciate tutto il resto della configurazione che faremo attraverso l’interfaccia web di FreePBX. Quello che dobbiamo sapere è:
Extensions (Extensioni) = sono gli “interni” telefonici
Trunks = sono i canali di ingresso/uscita delle chiamate dal nostro PBX. Ad esempio, se vogliamo connetterci con un’altro Asterisk, possiamo creare un trunk IAX !
Outbound routes = Le rotte in uscita, ovvero quelle che utilizzeranno i nostri interni per chiamare all’esterno (per capirsi, qui definiamo lo “0″ per uscire).
Inbound routes = Rotte in ingresso, ovvero indicheremo quali sono i canali da cui riceviamo le chiamate.
CID = Caller ID, possiamo utilizzare questo valore per creare regole diverse a seconda della linea da cui proviene la chiamata. Ad esempio, se ho 8 linee esterne che rispondono ai numeri 555-1001, 555-1002….555-1008 ed il 1001 è il direttore, il 1002 la segretaria… dobbiamo creare regole diverse per ognuna di queste linee ed utilizzeremo proprio il CID come variabile discriminante.
Ok, nel frattempo che scrivevo, l’installazione di Asterisk e FreepBX si è conclusa con successo.
+----------------------------------------------------------------+ | Asterisk with FreePBX installation is finished. | | For running asterisk+freepbx you must use this command : | | # /etc/init.d/freepbx start | | | | # you can also use amportal start stop restart etc | | !! NEVER LOAD ASTERISK DIRECTLY !! | +----------------------------------------------------------------+ +----------------------------------------------------------------+ | Asterisk has been started goto http://[your ip] | | Done, enjoy | +----------------------------------------------------------------+
Apro il browser e vado su http://[your ip], dove trovo il buon server http Apache2 a rispondermi come dovrebbe. Da questa interfaccia si accede:
ARI = Pannello di gestione delle caselle vocali degli utenti abilitati
FOP (Flash Operatori Panel) = Strumento in Adobe Flash che visualizza lo stato degli interni, dei trunk, delle conferenze…
FreePBX Administration = Interfaccia di amministrazione FreePBX di Asterisk, che rappresenta la parte più importante del nostro centralino.
Cliccando sul FreePBX Administration si accede alla schermata riepilogativa, con il menu delle funzioni a sinistra.
La prima cosa da fare è aggiornare FreePBX all’ultima versione. Clicchiamo su Module Admin, sotto la voce Tools, per accedere alle funzioni di aggiornamento ed installazione dei vari moduli a disposizione.
N.B. Dopo ogni cambiamento ricordatevi di cliccare sempre su Apply configuration changes per rendere effettive le modifiche.
A questo punto dobbiamo solo decidere come il nostro centralino dovrà funzionare. Per iniziare, possiamo anche scaricare uno dei tanti softphone SIP (XLite, SJPhone…) ed utilizzarlo per fare alcune prove.
Per creare un nuovo interno andiamo su Setup->Extensions, scegliamo quale tipo di interno vogliamo creare (che sarà Generic SIP devices…) e poi compiliamo i vari campi che si presenteranno a schermo.
In particolare:
User Extension = il numero di interno che vogliamo creare (200, 101, 302…)
Display name = nome dell’utente (“Pinco Pallino”), che verrà utilizzato anche per altre funzioni
secret = la password dell’interno, che dovremmo inserire nella configurazione del softphone
importante anche specificare se l’interno si può trovare dietro un NAT oppure no: questo è importante perchè tutti i messaggi SIP transitano via UDP !
Ok, per il momento credo di avervi aiutato a configurare almeno la base di un centralino Asterisk. Consideratelo come aver varcato la soglia di un albergo di 90 piani: avere lo sguardo sulla reception non è certo sufficiente ma può andar bene come inizio !
Alcuni lettori si chiederanno come mai ho già scritto dei posti sul VoIP parlando però di OpenSIPS: bene, OpenSIPS è essenzialmente un SIP router che svolge funzioni di autenticazione e gestione dei flussi SIP, adatto alle grandi realtà (10000 ed oltre dispositivi) mentre Asterisk è molto più adatto, e completo, per le piccole realtà di 10-20-50 interni. Tuttavia OpenSIPS si integra perfettamente con Asterisk, soprattutto per l’interfacciamento con la rete PSTN e come Media gateway. Una comparazione tra i due strumenti è disponibile a questo link: http://advantia.ca/weblog/opensips-and-asterisk-compared
Se ci sono domande o segnalazioni, i commenti sono a vostra disposizione.
La “Ricostruzione” del PD
0
“Ricostruzione in nome del popolo italiano“, recita l’opuscolo che è arrivato giovedì scorso nella cassetta della pubblicità condominiale, per pubblicizzare una grande manifestazione nazionale (ancora !?!?) in programma il 5 Novembre 2011 a Roma. Un opuscolo inviato direttamente dal PD nazionale, sfruttando il servizio postaZONE contact di Poste Italiane.
Dentro questo opuscolo, dove campeggia ben visibile il simbolo del Partito Democratico, oltre ad una serie di frasi fuffose ad effetto tra cui:
PER ritrovare fiducia e credere nel cambiamento
PER sentirci sicuri e liberi
e, la chicca: PER l’Italia
c’è allegato un bel bollettino postale, con causale “EROGAZIONE LIBERALE“, intestato al Partito Democratico. Una postilla in fondo alla pagina: “…Se lo desideri puoi partecipare anche sostenendo il PD, utilizzando il bollettino postale allegato. Sarai informato sull’impiego dei fondi raccolti…”.
Ah si ? Beh, allora potrebbero iniziare a raccontarci come sono stati spesi i 180 milioni di EURO dei rimborsi elettorali, erogati nel 2009, a fronte di una spesa accertata di circa 18 milioni di EURO (10 volte tanto: alla faccia della crisi !).
E questi signorotti, tanto bravi a fare la morale, come si permettono di chiedere pure il contributo ai cittadini ? Oltre al danno, pure la beffa: le EROGAZIONI LIBERALI sono pure detraibili, dai 51,65€ fino a 103.291,38€ (si, non avete mai pensato di donare 100.000€ al vostro Partito ?), per il 19% sul lordo !
Insomma, già un fiume di denaro pubblico finisce nelle loro casse. In più c’è anche la possibilità di fare le erogazioni liberali (deducibili del 19%, pertanto lo Stato ci perde pure i soldi !), anche fino a somme importanti (chiedetevi quale può essere il motivo di tanta generosità !).
SInceramente sono disgustato. E voi ?
MID Tablet Ekoore “Pascal”
0Finalmente, dopo settimane impiegate a studiare e cercare, ho trovato una occasione per il tablet “Pascal” della Ekoore, una azienda italiana con sede ad Orta di Atella (CE).
Avendo già un Netbook per le funzioni classiche da computer, la mia necessità era di avere un dispositivo per leggere PDF, con qualche possibilità multimediale in più. Soprattutto, considerando che l’avrei utilizzato nelle situazioni di relax, avevo subito scartato gli ingombranti e pesanti tablet da 10.1″, orientando la scelta verso dimensioni tra i 7 e gli 8 pollici. Tuttavia ero alla ricerca di prestazioni accettabili e, soprattutto, di un touchscreen capacitivo multitouch: i touch resistivi sono poco sensibili al tocco e possono risultare, con il tempo, piuttosto frustanti !
Da non sottovalutare il fattore costo: essendo essenzialmente uno sfizio (lo ammetto candidamente !), non volevo spenderci più di 200€.
La pulce per questo Tablet mi era stata messa da una risposta sul mio stream Google+ ed avevo subito così scartato le varie cinesate di 1000 brand diversi ma del solito capanno a Guangzhou

La risposta è avvenuta da Google Annunci, in cui un ragazzo di Napoli (dimostratosi estremamente serio e puntuale !) vendeva il Tablet in oggetto perchè non corrispondeva alle sue esigenze. Prendo i contatti, mi accordo sul prezzo ed in 4 giorni eccolo tra le mie mani !
L’aspetto è robusto e compatto, con un unico pulsante ben visibile per il “Back” ed il pin hole della fotocamera da 2mpixel. Sul retro, di plastica rubber (gommata antiscivolo), campeggia il logo della ekoore.
Sul lato in basso ci sono il connettore HDMI, mini-USB (Host e slave), slot per mini-SD, jack per le cuffie audio, connettore per l’alimentatore (5V 3000mah).
Il display, 7″ capacitivo multitouch, è reattivo e discretamente sensibile. Le applicazioni sono fluide, grazie anche alla CPU da 1.2GHz e alla RAM DDR3 da 512MByte, ed anche giochi più cpu-bound e video vengono eseguiti fluidi e senza scatti.
Il sistema operativo Android 2.3 è completo e solido. Il Pascal ha accesso al Market di Android, che permette di installare migliaia di applicazioni attraverso la connessione Wi-Fi di cui è dotato.
Peso di circa 200gr e durata della batteria di oltre 3 ore (dipende molto dall’uso e dalla luminosità del display).
Uno dei piccoli “nei” è che il tablet non si ricarica via USB e non sono ancora riuscito a trovare alimentatori per l’auto (5V e 3000ma non sono facili da trovare).
Si tiene comodamente in mano, anche se con qualche difficoltà, ma il peso ridotto ne permettono tranquillamente l’uso anche per lungo tempo. Anche con l’uso prolungato il dispositivo non si surriscalda molto (nei periodi invernali è anche piacevole un certo teporino alle mani
).
Come ho già detto, uno degli usi a cui è predestinato è la lettura di Internazionale in formato PDF così installo subito l’Acrobat Reader e lo sperimento nella lettura di PDF pesanti (oltre 10MByte): ottimo !
La risoluzione ed il contrasto del display sono discrete, con un buon angolo di visualizzazione (circa 110-120°). L’audio è un pò scarso, a
causa del forse troppo piccolo speaker che si trova sul retro, visibile attraverso una piccola asola.
Per finire, anche se forse è da troppo poco che ho tra le mani questo tablet, sono pienamente soddisfatto delle prestazioni e dell’usabilità di questo Pascal.
Debian: VSFTPD ed Apache
0Scrivo questo veloce post più per utilità personale che altro, visto che in rete esistono già decine di tutorial su come configurare VSFTPD su Debian. Ho notato però che per poterlo utilizzare con Apache HTTP servono alcune piccole accortezze. Ovviamente la configurazione che vado a spiegare è con gli utenti virtuali con PAM.
Procediamo dunque per gradi:
# apt-get install vsftpd libpam-pwdfile
per avere il VSFTPD ed il modulo PAM di autenticazione installati. La configurazione del server FTP è in /etc/vsftpd.conf. Creiamo adesso la directory /etc/vsftp/ che conterrà il file con le credenziali degli utenti virtuali:
# mkdir /etc/vsftp/
e nel file /etc/vsftpd.conf scriviamo:
listen=YES anonymous_enable=NO local_enable=YES virtual_use_local_privs=YES write_enable=YES connect_from_port_20=YES secure_chroot_dir=/var/run/vsftpd pam_service_name=vsftpd guest_enable=YES local_umask=022 anon_umask=0666 guest_username=www-data # per uso con utenti multipli scommentate le righe seguenti # user_sub_token=$USER # local_root=/var/www/$USER local_root=/var/www/ chroot_local_user=YES hide_ids=YES
e poi configuriamo il relativo file di PAM (/etc/pam.d/vsftpd) sostituendo all’originale le righe seguenti:
# Customized login using htpasswd file auth required pam_pwdfile.so pwdfile /etc/vsftpd/passwd account required pam_permit.so
A questo punto utilizziamo l’utility htpasswd per creare e gestire gli utenti (nel mio caso solamente uno):
# htpasswd -c /etc/vsftpd/passwd wwwuser
ed al relativo prompt inseriamo la password prescelta. Riavviamo VSFTPD:
# /etc/init.d/vsftpd restart
e…buon divertimento !












Commenti recenti