<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><title>Mirko Pagliai</title><link>http://www.mirkopagliai.it</link><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/mirkopagliai" /><description>La morale della domenica ed altre elucubrazioni</description><language>en</language><lastBuildDate>Sat, 11 Feb 2012 09:32:01 PST</lastBuildDate><generator>http://wordpress.org/?v=3.3.1</generator><sy:updatePeriod xmlns:sy="http://purl.org/rss/1.0/modules/syndication/">hourly</sy:updatePeriod><sy:updateFrequency xmlns:sy="http://purl.org/rss/1.0/modules/syndication/">1</sy:updateFrequency><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/mirkopagliai" /><feedburner:info uri="mirkopagliai" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:feedFlare href="http://www.plusmo.com/add?url=http%3A%2F%2Ffeeds.feedburner.com%2Fmirkopagliai" src="http://plusmo.com/res/graphics/fbplusmo.gif">Subscribe with Plusmo</feedburner:feedFlare><feedburner:feedFlare href="http://www.thefreedictionary.com/_/hp/AddRSS.aspx?http%3A%2F%2Ffeeds.feedburner.com%2Fmirkopagliai" src="http://img.tfd.com/hp/addToTheFreeDictionary.gif">Subscribe with The Free Dictionary</feedburner:feedFlare><feedburner:feedFlare href="http://www.bitty.com/manual/?contenttype=rssfeed&amp;contentvalue=http%3A%2F%2Ffeeds.feedburner.com%2Fmirkopagliai" src="http://www.bitty.com/img/bittychicklet_91x17.gif">Subscribe with Bitty Browser</feedburner:feedFlare><feedburner:feedFlare href="http://www.live.com/?add=http%3A%2F%2Ffeeds.feedburner.com%2Fmirkopagliai" src="http://tkfiles.storage.msn.com/x1piYkpqHC_35nIp1gLE68-wvzLZO8iXl_JMledmJQXP-XTBOLfmQv4zhj4MhcWEJh_GtoBIiAl1Mjh-ndp9k47If7hTaFno0mxW9_i3p_5qQw">Subscribe with Live.com</feedburner:feedFlare><feedburner:feedFlare href="http://mix.excite.eu/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2Fmirkopagliai" src="http://image.excite.co.uk/mix/addtomix.gif">Subscribe with Excite MIX</feedburner:feedFlare><feedburner:feedFlare href="http://www.webwag.com/wwgthis.php?url=http%3A%2F%2Ffeeds.feedburner.com%2Fmirkopagliai" src="http://www.webwag.com/images/wwgthis.gif">Subscribe with Webwag</feedburner:feedFlare><feedburner:feedFlare href="http://www.podcastready.com/oneclick_bookmark.php?url=http%3A%2F%2Ffeeds.feedburner.com%2Fmirkopagliai" src="http://www.podcastready.com/images/podcastready_button.gif">Subscribe with Podcast Ready</feedburner:feedFlare><feedburner:feedFlare href="http://www.wikio.com/subscribe?url=http%3A%2F%2Ffeeds.feedburner.com%2Fmirkopagliai" src="http://www.wikio.com/shared/img/add2wikio.gif">Subscribe with Wikio</feedburner:feedFlare><feedburner:feedFlare href="http://www.dailyrotation.com/index.php?feed=http%3A%2F%2Ffeeds.feedburner.com%2Fmirkopagliai" src="http://www.dailyrotation.com/rss-dr2.gif">Subscribe with Daily Rotation</feedburner:feedFlare><item><title>Debian: i mirror più veloci</title><link>http://feedproxy.google.com/~r/mirkopagliai/~3/wmcmCADDkaY/</link><category>Unix</category><category>/etc/apt/sources.list</category><category>Debian</category><category>individuare il mirror italiano più veloce</category><category>lista dei mirror da testare</category><category>lista mirror</category><category>mirror debian</category><category>mirror italiano</category><category>mirror più veloce</category><category>mirror veloce</category><category>netselect</category><category>testare mirror</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Mirko Pagliai</dc:creator><pubDate>Sat, 11 Feb 2012 08:19:06 PST</pubDate><guid isPermaLink="false">http://www.mirkopagliai.it/?p=2202</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p>Riporto qui sul blog l&#8217;ottimo suggerimento¹ di xtow sul forum <a href="http://forum.debianizzati.org/viewtopic.php?p=146572#p146572" target="_blank">debianizzati.org</a> su come <strong>individuare il mirror italiano più veloce</strong>.</p>
<p>Innanzitutto è necessario installare <em>netselect</em> e quindi:</p>
<pre class="brush: bash; light: true; title: ; notranslate">apt-get install netselect</pre>
<p>Va quindi lanciato col l&#8217;opzione <em>-vv</em> (&#8220;very verbose mode&#8221;), seguito dalla <strong>lista dei mirror da testare</strong>. Ad esempio:</p>
<pre class="brush: bash; light: true; title: ; notranslate">netselect -vv debian.bononia.it debian.fastweb.it ftp.it.debian.org debian.dynamica.it debian.fastbull.org freedom.dicea.unifi.it giano.com.dist.unige.it mi.mirror.garr.it mirror.units.it</pre>
<p>Nel mio caso:</p>
<pre class="brush: bash; light: true; title: ; notranslate">root@mirko-laptop:/home/mirko# netselect -vv debian.bononia.it debian.fastweb.it ftp.it.debian.org debian.dynamica.it debian.fastbull.org freedom.dicea.unifi.it giano.com.dist.unige.it mi.mirror.garr.it mirror.units.it
Running netselect to choose 1 out of 9 addresses.
...............................................................................
freedom.dicea.unifi.it                  82 ms  22 hops   90% ok ( 9/10) [  291]
debian.fastbull.org                     39 ms  16 hops  100% ok (10/10) [  101]
giano.com.dist.unige.it               9999 ms  30 hops    0% ok
debian.fastweb.it                       28 ms  12 hops   90% ok ( 9/10) [   68]
ftp.it.debian.org                       40 ms  17 hops   90% ok ( 9/10) [  121]
mi.mirror.garr.it                       29 ms  16 hops   75% ok ( 6/ 8) [  101]
debian.dynamica.it                      33 ms  14 hops   90% ok ( 9/10) [   88]
debian.bononia.it                     9999 ms  30 hops    0% ok
mirror.units.it                         40 ms  19 hops   90% ok ( 9/10) [  127]
   68 debian.fastweb.it</pre>
<p>Modificate il vostro <em>/etc/apt/sources.list</em> di conseguenza.</p>
<p>Per qualsiasi altra cosa, fate sempre riferimento al manuale:</p>
<pre class="brush: bash; light: true; title: ; notranslate">man netselect</pre>
<p><em>netselect</em></p>
<img src="http://feeds.feedburner.com/~r/mirkopagliai/~4/wmcmCADDkaY" height="1" width="1"/>]]></content:encoded><description>Riporto qui sul blog l&amp;#8217;ottimo suggerimento¹ di xtow sul forum debianizzati.org su come individuare il mirror italiano più veloce. Innanzitutto è necessario installare netselect e quindi: Va quindi lanciato col l&amp;#8217;opzione -vv (&amp;#8220;very verbose mode&amp;#8221;), seguito dalla lista dei mirror da testare. Ad esempio: Nel mio caso: Modificate il vostro /etc/apt/sources.list di conseguenza. Per qualsiasi [...]</description><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.mirkopagliai.it/debian-i-mirror-piu-veloci/feed/</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">2</slash:comments><feedburner:origLink>http://www.mirkopagliai.it/debian-i-mirror-piu-veloci/</feedburner:origLink></item><item><title>Silverlight su qualsiasi versione di Firefox/Iceweasel</title><link>http://feedproxy.google.com/~r/mirkopagliai/~3/gwCSE2FzVlg/</link><category>Unix</category><category>Debian</category><category>Firefox</category><category>Firefox 9</category><category>GNU/Linux</category><category>Iceweasel</category><category>Iceweasel 9</category><category>Moonlight</category><category>Silverlight</category><category>siti Rai</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Mirko Pagliai</dc:creator><pubDate>Sat, 28 Jan 2012 11:45:31 PST</pubDate><guid isPermaLink="false">http://www.mirkopagliai.it/?p=2197</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p><img class="alignleft size-full wp-image-2198" title="Firefox" src="http://www.mirkopagliai.it/wp-content/uploads/2012/01/firefox.png" alt="Firefox" width="71" height="74" />Come probabilmente già saprete (soprattutto se giungete a questo post da una ricerca) le ultime versioni di <strong>Firefox</strong>/<strong>Iceweasel</strong> non supportano l&#8217;ultima versione dell&#8217;estensione <strong>Silverlight</strong> (la 3.99.0.3 del 12 aprile 2011); estensione ahimè necessaria (anche se in rete si possono trovare varie alternative, più o meno funzionanti) per fruire di diversi contenuti multimediali, come quelli sui <strong>siti Rai</strong>.</p>
<p>Taccio a proposito di:</p>
<ol>
<li>motivi che portano alla scelta di adottare software proprietario o che si appoggia a software proprietario, software non libero, software non-multipiattaforma o con problemi/scarse prestazioni su alcune piattaforme, software non flessibile e via dicendo. Soprattutto quando (vedi caso della Rai) sono tenuto anche a pagare. Ma è già assodato come ci siano in giro troppi ingegneri, esperti di informatica o sviluppatori che, anche se con laurea alla mano, dovrebbe andare a fare un altro lavoro causa pochezza mentale;</li>
<li>motivi che portano a sviluppare un software, farlo adottare da tanti e in contesti così cruciali da fare in modo che diventi un software essenziale e poi non aggiornarlo regolarmente (l&#8217;ultima release stabile risale &#8211; lo ripeto &#8211; ad aprile 2011).</li>
</ol>
<p>Vengo a spiegarvi come ho risolto sulla <strong>Debian</strong>, procedura che dovrebbe essere valida anche su altre distribuzioni <strong>GNU/Linux</strong>.  Anzitutto dovete sapere che l&#8217;estensione funziona benissimo (almeno io la sto usando su <strong>Firefox 9</strong>), è solo che per ogni estensione viene indicata una versione massima e una minima dei vari browser e presumibilmente la prima sarà l&#8217;ultima versione disponibile al momento della versione dell&#8217;estensione.</p>
<p>Dunque:</p>
<ol>
<li>scaricate (non installandola, ma scaricandola effettivamente sul vostro hard disk) l&#8217;estensione da <a href="http://www.go-mono.com/moonlight/download.aspx" target="_blank">qui</a>. Con lo stesso Firefox/Iceweasel dovrebbe essere sufficiente fare click destro sul link e quindi scegliere l&#8217;opzione &#8220;Salva destinazione con nome&#8230;&#8221;. Altrimenti, c&#8217;è sempre il divino <em>wget</em>:
<pre class="brush: bash; light: true; title: ; notranslate">wget http://www.go-mono.com/moonlight/downloads/3.99.0.3/novell-moonlight-3.99.0.3-x86_64.xpi</pre>
</li>
<li>il file scaricato è un archivio, quindi decomprimetelo (assumo sappiate già come fare). In caso di problemi, rinominatelo come un <em>.zip</em>;</li>
<li>entrate nella directory estratta e aprite il file <em>install.rdf</em>, con un qualsiasi editor di testo. Quindi cercate le seguenti righe:
<pre class="brush: plain; light: true; title: ; notranslate">&lt;em:targetApplication&gt; &lt;!-- Firefox --&gt;
   &lt;Description&gt;
   &lt;em:id&gt;{ec8030f7-c20a-464f-9b0e-13a3a9e97384}&lt;/em:id&gt;
   &lt;em:minVersion&gt;1.5&lt;/em:minVersion&gt;
   &lt;em:maxVersion&gt;4.0.*&lt;/em:maxVersion&gt;
   &lt;/Description&gt;
&lt;/em:targetApplication&gt;</pre>
<p>Modificate la versione massima, ad esempio così:</p>
<pre class="brush: plain; light: true; title: ; notranslate">&lt;em:maxVersion&gt;10.*&lt;/em:maxVersion&gt;</pre>
<p>Non dovete rimuoverla, deve essere presente, volutamente potete indicare qualsiasi numero (anche 100).<br />
Quindi salvate il file;</li>
<li>cancellate la directory META-INF;</li>
<li>ricreate l&#8217;archivio come file <em>.zip</em>. <span style="text-decoration: underline;">Fate attenzione a creare un archivio non della directory estratta</span> (altrimenti, al momento dell&#8217;installazione, vi dirà che l&#8217;estensione risulta danneggiata), ma dei file contenuti nella directory. Il file risultante dovrebbe chiamarsi <em>novell-moonlight-3.99.0.3-x86_64.xpi_FILES.zip</em>, modificatelo affinché abbia il nome come quello originale;</li>
<li>in Firefox andate su &#8220;Strumenti&#8221;, &#8220;Componenti aggiuntivi&#8221;, fate click sul pulsante alla sinistra della barra di ricerca e scegliete l&#8217;opzione &#8220;Installa componente aggiuntivo da file&#8230;&#8221;. Selezionate il file, attendete il termine dell&#8217;installazione e riavviate il browser.</li>
</ol>
<p>Fatto.</p>
<p>Fonte: <a href="http://bit.ly/tM4rS2" target="_blank">http://bit.ly/tM4rS2</a></p>
<img src="http://feeds.feedburner.com/~r/mirkopagliai/~4/gwCSE2FzVlg" height="1" width="1"/>]]></content:encoded><description>Come probabilmente già saprete (soprattutto se giungete a questo post da una ricerca) le ultime versioni di Firefox/Iceweasel non supportano l&amp;#8217;ultima versione dell&amp;#8217;estensione Silverlight (la 3.99.0.3 del 12 aprile 2011); estensione ahimè necessaria (anche se in rete si possono trovare varie alternative, più o meno funzionanti) per fruire di diversi contenuti multimediali, come quelli sui [...]</description><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.mirkopagliai.it/silverlight-su-qualsiasi-versione-di-firefoxiceweasel/feed/</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">4</slash:comments><feedburner:origLink>http://www.mirkopagliai.it/silverlight-su-qualsiasi-versione-di-firefoxiceweasel/</feedburner:origLink></item><item><title>Amarok 1.4.10</title><link>http://feedproxy.google.com/~r/mirkopagliai/~3/1a0dQ5cynpE/</link><category>Unix</category><category>Amarok</category><category>Amarok 1.4</category><category>Amarok 1.4.10</category><category>amarok-common</category><category>Debian</category><category>Debian Lenny</category><category>dpkg. installare Amarok</category><category>repository Debian Lenny</category><category>sources.list</category><category>Synaptic</category><category>vecchia versione di Amarok</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Mirko Pagliai</dc:creator><pubDate>Tue, 10 Jan 2012 03:44:16 PST</pubDate><guid isPermaLink="false">http://www.mirkopagliai.it/?p=2189</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p><img class="alignleft size-thumbnail wp-image-2191" title="Amarok logo" src="http://www.mirkopagliai.it/wp-content/uploads/2012/01/amarok-logo-180x180.jpg" alt="Amarok logo" width="120" height="120" />Mettiamo che, come il sottoscritto, reputate la <strong>vecchia versione di Amarok</strong> (<strong>Amarok 1.4</strong>) come la migliore. Mettiamo che, come il sottoscritto, volete ancora utilizzarla sulla vostra <strong>Debian</strong> (qualsiasi versione).</p>
<p>Bene, Amarok 1.4 è ancora presente &#8211; al momento in cui scrivo &#8211; su <strong>Debian Lenny</strong>, l&#8217;attuale old-stable: vediamo come reperirlo, come conservarlo (prima o poi i <strong>repository di Debian Lenny</strong> andranno off, anche se con un po&#8217; di impegno si può accedere ancora a repository molto più vecchi, che qualcuno conserva qua e là) e come installarlo.</p>
<p>Innanzitutto, se i repository di Debian Lenny sono ancora disponibili, configuriamo il pinning (se non lo abbiamo ancora fatto) come spiegato <a href="http://www.mirkopagliai.it/debian-repository-e-pinning/" target="_blank">qui</a> e poi aggiungiamo al nostro<em> sources.list</em> il repository:</p>
<pre class="brush: plain; light: true; title: ; notranslate">deb http://ftp.it.debian.org/debian/ lenny main contrib non-free</pre>
<p>Fatto questo, aggiorniamo e poi scarichiamo i pacchetti che ci servono (li scarichiamo proprio per conservarli per il futuro):</p>
<pre class="brush: bash; light: true; title: ; notranslate">aptitude update
aptitude -t lenny download amarok amarok-common amarok-engine-xine libgpod3-nogtk libmtp7 libmysqlclient15off</pre>
<p>I pacchetti verranno scaricati nell&#8217;attuale directory e dovrebbero essere (può cambiare l&#8217;architettura):</p>
<pre class="brush: bash; light: true; title: ; notranslate">amarok_1.4.10-2lenny1_i386.deb
amarok-common_1.4.10-2lenny1_all.deb
amarok-engine-xine_1.4.10-2lenny1_i386.deb
libgpod3-nogtk_0.6.0-6_i386.deb
libmtp7_0.2.6.1-3_i386.deb
libmysqlclient15off_5.0.51a-24+lenny5_i386.deb</pre>
<p>Semmai i repository di Lenny non dovessero essere più presenti, ho preparato un archivio con questi pacchetti per <a href="http://docs.mirkopagliai.it/packages/amarok_32bit.tar.gz" target="_blank">32bit</a> e <a href="http://docs.mirkopagliai.it/packages/amarok_64bit.tar.gz" target="_blank">64bit</a>. Scaricate e decomprimete.</p>
<p>Fatto questo, è necessario procedere con l&#8217;installazione di alcune dipendenze necessarie:</p>
<pre class="brush: bash; light: true; title: ; notranslate">aptitude install kdelibs4c2a libqt3-mt libifp4 libkarma0 libnjb5 libpq5 libtunepimp5</pre>
<p>Notate che queste dipendenze dovrebbero essere presenti anche nella vostra versione di Debian, quindi in questo caso non si necessita di pinning. Le dipendenze non più presenti (cioè obsolete) le abbiamo già reperite. Bisogna prima installare queste perché il resto verrà installato tramite <em>dpkg</em>, che non si preoccupa di installare eventuali dipendenze mancanti.</p>
<p>Infatti, a questo punto non resta che <strong>installare Amarok</strong> e le dipendenze ormai obsolete. Nella cartella in cui abbiamo precedentemente scaricato:</p>
<pre class="brush: bash; light: true; title: ; notranslate">dpkg -i amarok*.deb libgpod3-nogtk*.deb libmtp*.deb libmysqlclient15off*.deb</pre>
<p>Ed è fatta. Due accorgimenti:</p>
<ol>
<li>il lanciatore nel menù è nascosto di default, quindi (in Gnome 2) click destro del mouse sul menù, &#8220;Modifica menù&#8221;, andate sotto &#8220;Audio e video&#8221; e mettete la spunta alla relativa opzione;</li>
<li>il nostro gestore dei pacchetti, rilevata una versione più recente di Amarok, insisterà nel farci aggiornare. Per risolvere è sufficiente bloccare i pacchetti <em>amarok</em> e <em>amarok-common</em>. In <em>aptitude</em>:
<pre class="brush: bash; light: true; title: ; notranslate">aptitude hold amarok amarok-common</pre>
<p>In <em>synaptic</em> cercate (guardate sotto &#8220;Installato (aggiornabile)&#8221;) i due pacchetti, selezionatene uno alla volta, poi andate sul menù &#8220;Pacchetto&#8221; e mettete la spunta a &#8220;Blocca versione&#8221;.<br />
Notate che dovete seguire entrambe le procedure.</li>
</ol>
<p>Et voilà:</p>
<p><a href="http://www.mirkopagliai.it/wp-content/uploads/2012/01/amarok.jpg"><img class="aligncenter size-full wp-image-2190" title="Amarok" src="http://www.mirkopagliai.it/wp-content/uploads/2012/01/amarok.jpg" alt="Amarok" width="600" height="340" /></a></p>
<img src="http://feeds.feedburner.com/~r/mirkopagliai/~4/1a0dQ5cynpE" height="1" width="1"/>]]></content:encoded><description>Mettiamo che, come il sottoscritto, reputate la vecchia versione di Amarok (Amarok 1.4) come la migliore. Mettiamo che, come il sottoscritto, volete ancora utilizzarla sulla vostra Debian (qualsiasi versione). Bene, Amarok 1.4 è ancora presente &amp;#8211; al momento in cui scrivo &amp;#8211; su Debian Lenny, l&amp;#8217;attuale old-stable: vediamo come reperirlo, come conservarlo (prima o poi [...]</description><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.mirkopagliai.it/amarok-1-4-10/feed/</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">0</slash:comments><feedburner:origLink>http://www.mirkopagliai.it/amarok-1-4-10/</feedburner:origLink></item><item><title>Bash scripting: check for and install missing dependencies</title><link>http://feedproxy.google.com/~r/mirkopagliai/~3/Jq-UymZCldg/</link><category>Programmazione</category><category>Unix</category><category>apt-get</category><category>ArchLinux</category><category>bash</category><category>bash scripting</category><category>CentOS</category><category>Debian</category><category>dpkg</category><category>Fedora</category><category>install missing dependencies</category><category>list of required dependencies</category><category>logiche di mercato</category><category>Mandriva</category><category>Mint</category><category>missing dependencies</category><category>need some dependencies</category><category>openSUSE</category><category>pacman</category><category>rpm</category><category>rpm-based</category><category>run a bash script</category><category>Ubuntu</category><category>urpmi</category><category>what dependencies are missing</category><category>yum</category><category>zypper</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Mirko Pagliai</dc:creator><pubDate>Tue, 03 Jan 2012 07:49:10 PST</pubDate><guid isPermaLink="false">http://www.mirkopagliai.it/?p=2181</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p><img class="alignleft size-thumbnail wp-image-2145" title="Bash script" src="http://www.mirkopagliai.it/wp-content/uploads/2011/10/bash-script-180x180.png" alt="" width="116" height="116" />Sometimes we <strong>need some dependencies</strong> are installed on the operating system to <strong>run a bash script</strong>. So you can create a script that installs the missing dependencies.</p>
<p>After making <strong>a list of required dependencies</strong>, there are two ways to do this:</p>
<ol>
<li>pass the entire list to the package manager. Then the package manager will check which packages are already installed and will proceed with the installation of those that are missing;</li>
<li>check what dependencies are already installed, make a list of dependencies that are missing, then pass to the package manager only missing dependencies list.</li>
</ol>
<p>The second choice is the best choice, besides being more elegant. First, because it has a better chance of success (by hypothesis, some package managers may not work, if we ask it to install a package that&#8217;s already installed); second, &#8217;cause if we were having some problems with the installation (for whatever reason), we can say exactly to the user what are the packages that he has to install manually.</p>
<p>Now let&#8217;s see what we have to do. As I have already said, we should:</p>
<ol>
<li>make a list of required dependencies (it&#8217;ll be the <em>DEPENDENCIES</em> array);</li>
<li>check <strong>what dependencies are missing</strong> and save them in a new list (it&#8217;ll be the <em>PKGSTOINSTALL</em> string);</li>
<li>install missing dependencies (from the <em>PKGSTOINSTALL</em> string).</li>
</ol>
<p>Well, let&#8217;s go to the code. We need to create a list of required dependencies, for example <em>foo</em> and <em>bar</em> packages:</p>
<pre class="brush: bash; light: true; title: ; notranslate">DEPENDENCIES=(foo bar)</pre>
<p>Now we need to check which of those packages are already installed. The missing packages will be added to the <em>PKGSTOINSTALL</em> string, separated by a space:</p>
<pre class="brush: bash; title: ; notranslate"># What dependencies are missing?
PKGSTOINSTALL=&quot;&quot;
for (( i=0; i /dev/null; then
		if [[ ! `dpkg -l | grep -w &quot;ii  ${DEPENDENCIES[$i]} &quot;` ]]; then
			PKGSTOINSTALL=$PKGSTOINSTALL&quot; &quot;${DEPENDENCIES[$i]}
		fi
	# OpenSuse, Mandriva, Fedora, CentOs, ecc. (with rpm)
	elif which rpm &amp;&gt; /dev/null; then
		if [[ ! `rpm -q ${DEPENDENCIES[$i]}` ]]; then
			PKGSTOINSTALL=$PKGSTOINSTALL&quot; &quot;${DEPENDENCIES[$i]}
		fi
	# ArchLinux (with pacman)
	elif which pacman &amp;&gt; /dev/null; then
		if [[ ! `pacman -Qqe | grep &quot;${DEPENDENCIES[$i]}&quot;` ]]; then
			PKGSTOINSTALL=$PKGSTOINSTALL&quot; &quot;${DEPENDENCIES[$i]}
		fi
	# If it's impossible to determine if there are missing dependencies, mark all as missing
	else
		PKGSTOINSTALL=$PKGSTOINSTALL&quot; &quot;${DEPENDENCIES[$i]}
	fi
done</pre>
<p>With a loop we will be checked every necessary dependency. <em>Dpkg</em> will be used for the <strong>deb-based distros</strong> (Debian, Ubuntu and derivatives, as Mint), <em>rpm</em> for the <strong>rpm-based</strong> (OpenSuse, Mandriva, Fedora, CentOs, etc.) and <em>pacman</em> for ArchLinux. If none of these is available on the system (for whatever reason), all the required dependencies will be marked as missing.</p>
<p>At this point, as I said before, the <em>PKGSTOINSTALL</em> string contains the list of required dependencies that are missing. We can proceed to install them:</p>
<pre class="brush: bash; title: ; notranslate"># If some dependencies are missing, asks if user wants to install
if [ &quot;$PKGSTOINSTALL&quot; != &quot;&quot; ]; then
	echo -n &quot;Some dependencies are missing. Want to install them? (Y/n): &quot;
	read SURE
	# If user want to install missing dependencies
	if [[ $SURE = &quot;Y&quot; || $SURE = &quot;y&quot; || $SURE = &quot;&quot; ]]; then
		# Debian, Ubuntu and derivatives (with apt-get)
		if which apt-get &amp;&gt; /dev/null; then
			apt-get install $PKGSTOINSTALL
		# OpenSuse (with zypper)
		elif which zypper &amp;&gt; /dev/null; then
			zypper in $PKGSTOINSTALL
		# Mandriva (with urpmi)
		elif which urpmi &amp;&gt; /dev/null; then
			urpmi $PKGSTOINSTALL
		# Fedora and CentOS (with yum)
		elif which yum &amp;&gt; /dev/null; then
			yum install $PKGSTOINSTALL
		# ArchLinux (with pacman)
		elif which pacman &amp;&gt; /dev/null; then
			pacman -Sy $PKGSTOINSTALL
		# Else, if no package manager has been founded
		else
			# Set $NOPKGMANAGER
			NOPKGMANAGER=TRUE
			echo &quot;ERROR: impossible to found a package manager in your sistem. Please, install manually ${DEPENDENCIES[*]}.&quot;
		fi
		# Check if installation is successful
		if [[ $? -eq 0 &amp;&amp; ! -z $NOPKGMANAGER ]] ; then
			echo &quot;All dependencies are satisfied.&quot;
		# Else, if installation isn't successful
		else
			echo &quot;ERROR: impossible to install some missing dependencies. Please, install manually ${DEPENDENCIES[*]}.&quot;
		fi
	# Else, if user don't want to install missing dependencies
	else
		echo &quot;WARNING: Some dependencies may be missing. So, please, install manually ${DEPENDENCIES[*]}.&quot;
	fi
fi</pre>
<p>Now I&#8217;ll explain this portion of code. First of all, the script asks the user if he wanna proceed with the installation (else, it will tell the user which packages have to install manually). Then it proceeds by using the package manager avaible on the system: <em>apt-get</em> for Debian, Ubuntu and derivateves, <em>zypper</em> for OpenSuse, <em>urpmi</em> for Mandriva, <em>yum</em> for Fedora and CentOS and <em>pacman</em> for Archlinux.</p>
<p>If none is available, the user indicates which packages have to install manually. Finally it verifies if the installation was successful and in case of problems, again, alerts the user.</p>
<p>Good luck.</p>
<p>(in italiano: <a href="http://www.mirkopagliai.it/bash-scripting-verificare-e-installare-dipendenze-mancanti/">Bash scripting: verificare e installare dipendenze mancanti</a>)</p>
<img src="http://feeds.feedburner.com/~r/mirkopagliai/~4/Jq-UymZCldg" height="1" width="1"/>]]></content:encoded><description>Sometimes we need some dependencies are installed on the operating system to run a bash script. So you can create a script that installs the missing dependencies. After making a list of required dependencies, there are two ways to do this: pass the entire list to the package manager. Then the package manager will check [...]</description><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.mirkopagliai.it/bash-scripting-check-for-and-install-missing-dependencies/feed/</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">0</slash:comments><feedburner:origLink>http://www.mirkopagliai.it/bash-scripting-check-for-and-install-missing-dependencies/</feedburner:origLink></item><item><title>CakePHP: custom flash messages</title><link>http://feedproxy.google.com/~r/mirkopagliai/~3/a8w8JHLkWLU/</link><category>Programmazione</category><category>Cake's core</category><category>CakePHP</category><category>CakePHP documentation</category><category>different types of messages</category><category>flash</category><category>flash message</category><category>flash method</category><category>manage directly the session</category><category>MVC</category><category>one-time notification message</category><category>override the classes of Cake's core</category><category>php</category><category>rewrite component</category><category>rewrite helper</category><category>SessionComponent</category><category>SessionHelper</category><category>setFlash</category><category>setFlash method</category><category>show a message inside a view</category><category>store more messages in a single action</category><category>store multiple messages</category><category>style for flash messages</category><category>style sheet</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Mirko Pagliai</dc:creator><pubDate>Tue, 03 Jan 2012 05:02:39 PST</pubDate><guid isPermaLink="false">http://www.mirkopagliai.it/?p=2166</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p><a href="http://www.mirkopagliai.it/wp-content/uploads/2012/01/cake-logo.png"><img class="alignleft  wp-image-2168" title="CakePHP" src="http://www.mirkopagliai.it/wp-content/uploads/2012/01/cake-logo.png" alt="CakePHP" width="138" height="138" /></a>As you know, <strong>CakePHP</strong> can manage <strong>flash messages</strong>, information messages for the user that are stored by and in session. They are particularly used to notify some operations (result of authentication operations, operations on the database, etc..).</p>
<p>Essentially, flash messages are used whenever you want to say to an user: &#8220;hey man, everything is fine, or something went wrong&#8221;.</p>
<p>As the <a href="http://book.cakephp.org/2.0/en/core-libraries/components/sessions.html?highlight=setflash#creating-notification-messages" target="_blank">CakePHP documentation</a> explains:</p>
<blockquote><p>Often in web applications, you will need to display a one-time notification message to the user after processing a form or acknowledging data. In CakePHP, these are referred to as “flash messages”. You can set flash messages with the SessionComponent and display them with the SessionHelper::flash(). To set a message, use setFlash.</p></blockquote>
<p>To store a message inside a controller, you can use the <em>setFlash()</em> method (<a href="http://book.cakephp.org/2.0/en/core-libraries/components/sessions.html#SessionComponent::setFlash" target="_blank">API</a>) provided by <em>SessionComponent</em>; to <strong>show a message inside a view</strong>, you can instead use the <em>flash()</em> method (<a href="http://book.cakephp.org/2.0/en/core-libraries/helpers/session.html#SessionHelper::flash" target="_blank">API</a>) provided by <em>SessionHelper</em>. </p>
<p>For example, inside a controller like this:</p>
<pre class="brush: php; title: ; notranslate">public function myAction() {
   // do something...
   $this-&gt;Session-&gt;setFlash(&quot;it works!&quot;);
   // do something...
}</pre>
<p>Inside a view:</p>
<pre class="brush: php; light: true; title: ; notranslate">Session-&gt;flash(); ?&gt;</pre>
<p>As my example says, this will work correctly and will produce this html:</p>
<pre class="brush: xml; light: true; title: ; notranslate">&lt;div id=&quot;flashMessage&quot; class=&quot;message&quot;&gt;it works!&lt;/div&gt;</pre>
<p>This is really nice, especially because flash messages are &#8220;one-time messages&#8221; and the developer doesn&#8217;t have to worry about <strong>manage directly the session</strong> (<strong>Cake&#8217;s core</strong> will take care of this, not you). But there are problems when you wanna <strong>store more messages in a single action</strong> of a controller. Indeed this one:</p>
<pre class="brush: php; title: ; notranslate">public function myAction() {
   // do something...
   $this-&gt;Session-&gt;setFlash(&quot;does it work?&quot;);
   $this-&gt;Session-&gt;setFlash(&quot;it works!&quot;);
   // do something...
}</pre>
<p>will remember only the second flash message. And the first one? Another problem is: and if I wanted to differentiate between <strong>different types of messages</strong> (for example: warnings, errors, confirmations, etc..)?<br />
As the documentation explains, &#8220;using the <em>$key</em> parameter you can <strong>store multiple messages</strong>, which can be output separately&#8221; (quoting the documentation example):</p>
<pre class="brush: php; title: ; notranslate">// set a bad message.
$this-&gt;Session-&gt;setFlash('Something bad.', 'default', array(), 'bad');
// set a good message.
$this-&gt;Session-&gt;setFlash('Something good.', 'default', array(), 'good');</pre>
<p>These flash messages will be output as html and styled differently:</p>
<pre class="brush: php; title: ; notranslate">// in a view.
echo $this-&gt;Session-&gt;flash('good');
echo $this-&gt;Session-&gt;flash('bad');</pre>
<p>You can also pass a class in <em>$params</em> array using again <em>$this->Session->setFlash</em>:</p>
<pre class="brush: php; light: true; title: ; notranslate">$this-&gt;Session-&gt;setFlash('Example message text', 'default', array('class' =&gt; 'example_class'));</pre>
<p>Using <em>$this->Session->flash()</em>, the output will be:</p>
<pre class="brush: xml; light: true; title: ; notranslate">&lt;div id=&quot;flashMessage&quot; class=&quot;example_class&quot;&gt;Example message text&lt;/div&gt;</pre>
<p>But all this is very uncomfortable to use and is very difficult to develop using the proposal syntax.<br />
So, how to solve? It&#8217;s simple: <strong>rewrite component and helper</strong>.<br />
First, you need to copy</p>
<pre class="brush: plain; light: true; title: ; notranslate">lib/Cake/Controller/Component/SessionComponent.php</pre>
<p>in</p>
<pre class="brush: plain; light: true; title: ; notranslate">app/Controller/Component/</pre>
<p>and</p>
<pre class="brush: plain; light: true; title: ; notranslate">lib/Cake/View/Helper/SessionHelper.php</pre>
<p>in</p>
<pre class="brush: plain; light: true; title: ; notranslate">app/View/Helper/</pre>
<p>This allows you to <strong>override the classes of Cake&#8217;s core</strong> with yours, that will be used first (<span style="text-decoration: underline;">note</span>: you must not edit directly Cake&#8217;s core, never! Just rewrite components, helpers, views, etc.).</p>
<p>Then, in <em>app/Controller/Component/SessionComponent.php</em> replace the <em>setFlash()</em> function with this one:</p>
<pre class="brush: php; title: ; notranslate">public function setFlash($message, $type=&quot;message&quot;) {
	//If flash messages are already stored in session, fetch array
	if(CakeSession::check('flashMessages'))
		$messages = CakeSession::read('flashMessages');
	//Else, create a new empty array
	else
		$messages = array();
	//If the flash message type is not supported (only &quot;error&quot;, &quot;notice&quot;, &quot;success&quot; and &quot;warning&quot;), set it to &quot;notice&quot;
	if(!in_array($type = strtolower($type), array(&quot;error&quot;, &quot;notice&quot;, &quot;success&quot;, &quot;warning&quot;)))
		$type = &quot;notice&quot;;
	//Add the passed flash message to the array
	$messages[$type][] = $message;
	//Store in sessione
	CakeSession::write('flashMessages', $messages);
}</pre>
<p>With this, now you can store flash messages like this (it will store an error):</p>
<pre class="brush: php; light: true; title: ; notranslate">echo $this-&gt;Session-&gt;flash('something has gone wrong', 'error');</pre>
<p>Again, in <em>app/View/Helper/SessionHelper.php</em> replace the <em>flash()</em> function with this one:</p>
<pre class="brush: php; title: ; notranslate">public function flash() {
	//Check if flash messages are stored in session
	if(CakeSession::check('flashMessages')) {
		//Retrieve saved flash messages and deletes them from the session
		$messages = CakeSession::read('flashMessages');
		CakeSession::delete('flashMessages');
		//Prepare the $out variable that will contain the final output
		$out = &quot;&quot;;
		//Loop every flash message that is stored in session, appending to the variable $out
		foreach ($messages as $type =&gt; $message) {
			foreach ($message as $text)
				$out .= '&lt;div class=&quot;'.$type.'&quot;&gt;'.$text.'&lt;/div&gt;';
		}
		//Return flash messages in html
		return $out;
	}
}</pre>
<p>It will return flash messages as:</p>
<pre class="brush: php; light: true; title: ; notranslate">&lt;div class=&quot;$type&quot;&gt;$text&lt;/div&gt;</pre>
<p>Now a new example. Inside your controller:</p>
<pre class="brush: php; title: ; notranslate">$this-&gt;Session-&gt;setFlash(&quot;This is just a warning&quot;, &quot;warning&quot;);
$this-&gt;Session-&gt;setFlash(&quot;It's ok!&quot;, &quot;success&quot;);
$this-&gt;Session-&gt;setFlash(&quot;Something seems to have gone wrong&quot;, &quot;error&quot;);
$this-&gt;Session-&gt;setFlash(&quot;A simple, innocent news.&quot;, &quot;notice&quot;);</pre>
<p>It will be displayed like this:</p>
<pre class="brush: xml; title: ; notranslate">&lt;div class=&quot;warning&quot;&gt;This is just a warning&lt;/div&gt;
&lt;div class=&quot;success&quot;&gt;It's ok!&lt;/div&gt;
&lt;div class=&quot;error&quot;&gt;Something seems to have gone wrong&lt;/div&gt;
&lt;div class=&quot;notice&quot;&gt;A simple, innocent news.&lt;/div&gt;
</pre>
<p>Wonderful, is not it?</p>
<p>Since we are here, just add a little <strong>style for flash messages</strong>. In the view, you have to display messages like this:</p>
<pre class="brush: php; title: ; notranslate">&lt;div id=&quot;flashMessages&quot;&gt;
	&lt;?php echo $this-&gt;Session-&gt;flash(); ?&gt;
&lt;/div&gt;</pre>
<p>Download <a href="http://docs.mirkopagliai.it/documents/dialogs-pics.tar.gz" target="_blank">these files</a> and move them to <em>app/webroot/img/</em>, then add to your <strong>style sheet</strong>:</p>
<pre class="brush: css; title: ; notranslate">#flashMessages div {
	background: no-repeat 5px 5px;
	border-radius: 5px;
	border-style: solid;
	border-width: 2px;
	box-shadow: 0 5px 5px -5px #555;
	margin-bottom: .5em;
	min-height: 24px;
	padding: 5px 10px 5px 35px;
}

#flashMessages .error {
	background-color: #FFCCCC;
    background-image: url(&quot;/img/error.png&quot;);
    border-color: #8F0000;
    color: #8F0000;
}

#flashMessages .notice {
	background-color: #e6ecf2;
	background-image: url(&quot;/img/notice.png&quot;);
	border-color: #314e6c;
	color: #314e6c;
}

#flashMessages .success {
    background-color: #DEFADE;
    background-image: url(&quot;/img/success.png&quot;);
    border-color: #267726;
    color: #267726;
}

#flashMessages .warning {
    background-color: #FFEEBF;
    background-image: url(&quot;/img/warning.png&quot;);
    border-color: #B87D00;
    color: #B87D00;
}</pre>
<p>This is the result:</p>
<p><a href="http://www.mirkopagliai.it/wp-content/uploads/2012/01/flashMessages.png"><img class="aligncenter size-full wp-image-2167" title="flash messages" src="http://www.mirkopagliai.it/wp-content/uploads/2012/01/flashMessages.png" alt="flash messages" width="611" height="182" /></a></p>
<p>A great work guys! ;-)</p>
<img src="http://feeds.feedburner.com/~r/mirkopagliai/~4/a8w8JHLkWLU" height="1" width="1"/>]]></content:encoded><description>As you know, CakePHP can manage flash messages, information messages for the user that are stored by and in session. They are particularly used to notify some operations (result of authentication operations, operations on the database, etc..). Essentially, flash messages are used whenever you want to say to an user: &amp;#8220;hey man, everything is fine, or [...]</description><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.mirkopagliai.it/cakephp-custom-flash-messages/feed/</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">0</slash:comments><feedburner:origLink>http://www.mirkopagliai.it/cakephp-custom-flash-messages/</feedburner:origLink></item><item><title>Abortisce con la pillola del giorno dopo</title><link>http://feedproxy.google.com/~r/mirkopagliai/~3/8PXD9qS1OGc/</link><category>Costume e società</category><category>abortire</category><category>alimentare la disinformazione</category><category>Cinzia Sasso</category><category>disinformazione</category><category>pillola del giorno dopo</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Mirko Pagliai</dc:creator><pubDate>Fri, 09 Dec 2011 05:42:53 PST</pubDate><guid isPermaLink="false">http://www.mirkopagliai.it/?p=2159</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p><a href="http://www.mirkopagliai.it/wp-content/uploads/2011/12/Schermata-del-2011-12-09-134059.jpg"><img class="aligncenter size-full wp-image-2160" title="Pillola del giorno dopo" src="http://www.mirkopagliai.it/wp-content/uploads/2011/12/Schermata-del-2011-12-09-134059.jpg" alt="Pillola del giorno dopo" width="693" height="158" /></a>L&#8217;articolo è <a href="http://www.repubblica.it/cronaca/2011/12/09/news/ragazzina_aborto-26317910/" target="_blank">qui</a>, a firma di <strong>Cinzia Sasso</strong>. Si legge chiaramente come una ragazza, per <strong>abortire</strong>, abbia fatto ricorso alla <strong>pillola del giorno dopo</strong>. Le ipotesi plausibili (o meglio: che mi vengono in mente) sono due:</p>
<ol>
<li>la giornalista è venuta a sapere che la ragazza aveva fatto uso della pillola del giorno dopo e ha dedotto (erroneamente) che ha abortito e che quindi fosse rimasta incinta;</li>
<li>viceversa, che la ragazza era rimasta incinta e ha abortito e ha dedotto (sempre erroneamente) che l&#8217;abbia fatto tramite l&#8217;uso della pillola del giorno dopo.</li>
</ol>
<p>In ogni caso &#8211; diciamo per sintesi &#8211; la giornalista ha lavorato di fantasia per arricchire l&#8217;articolo. E il risultato è quello che si vede.</p>
<p>Il problema è che la discussione su aborto da una parte e contraccettivi dall&#8217;altra, ad oggi, nel nostro Paese, è basata quasi esclusivamente sulla <strong>disinformazione</strong>, sia di chi è contrario ai due (soprattutto), sia (anche e non di meno) di chi è favore delle due o di una delle due.<br />
In questo contesto, un giornalista può permettersi, senza troppe responsabilità, di <strong>alimentare la disinformazione</strong>? Non si sente la necessità di aderire a un codice deontologico oppure, quanto meno, di informarsi come requisito per informare (&#8220;informarsi per informare&#8230;&#8221;), assumendo che si sia in buona fede?</p>
<img src="http://feeds.feedburner.com/~r/mirkopagliai/~4/8PXD9qS1OGc" height="1" width="1"/>]]></content:encoded><description>L&amp;#8217;articolo è qui, a firma di Cinzia Sasso. Si legge chiaramente come una ragazza, per abortire, abbia fatto ricorso alla pillola del giorno dopo. Le ipotesi plausibili (o meglio: che mi vengono in mente) sono due: la giornalista è venuta a sapere che la ragazza aveva fatto uso della pillola del giorno dopo e ha [...]</description><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.mirkopagliai.it/abortisce-con-la-pillola-del-giorno-dopo/feed/</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">0</slash:comments><feedburner:origLink>http://www.mirkopagliai.it/abortisce-con-la-pillola-del-giorno-dopo/</feedburner:origLink></item><item><title>Tutorial Jquery: menù a tendina</title><link>http://feedproxy.google.com/~r/mirkopagliai/~3/81gjYI_Z_Ok/</link><category>Programmazione</category><category>append</category><category>codice html pulito e conforme</category><category>costrutto if</category><category>each</category><category>effetti menù</category><category>effetto al passaggio del mouse</category><category>fadeToggle</category><category>foglio di stile</category><category>hover</category><category>jQuery</category><category>length</category><category>menù a tendina</category><category>menù a tendina completo</category><category>menù Jquery</category><category>passaggio del mouse</category><category>proprietà css di base</category><category>quali menù contengono un sotto-menù</category><category>slideToggle</category><category>sotto-menù con Jquery</category><category>struttura html</category><category>toggle</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Mirko Pagliai</dc:creator><pubDate>Mon, 31 Oct 2011 09:48:47 PDT</pubDate><guid isPermaLink="false">http://www.mirkopagliai.it/?p=2150</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p><img class="size-thumbnail wp-image-2054 alignleft" title="Jquery" src="http://www.mirkopagliai.it/wp-content/uploads/2011/07/Jquery-180x44.gif" alt="" width="180" height="44" />Avevo già scritto <a href="http://www.mirkopagliai.it/how-to-menu-a-tendina/" target="_blank">qualcosa</a> sui <strong>menù a tendina</strong>, arrivando a consigliare di utilizzare <a href="http://users.tpg.com.au/j_birch/plugins/superfish/" target="_blank">SuperFish</a>, che a tutt&#8217;ora considero un ottimo plugin. Vediamo però come realizzare da zero un <strong>menù a tendina completo</strong>, utilizzando solo e semplicemente <a href="http://jquery.com/" target="_blank">Jquery</a> e limitandoci (per questo articolo, più in là semmai approfondirò) a un solo livello di profondità (in altri termini: i sotto-menù, a loro volta, non si espanderanno).</p>
<p>Due piccole premesse:</p>
<ol>
<li>dovete conoscere bene html e css, in quanto qui ci limiteremo (per questi due) allo stretto indispensabile;</li>
<li>qui utilizzeremo un menù principale orizzontale (quindi le voci del menù affiancate) con sotto-menù in verticale (quindi voci elencate). Nulla toglie che poi, in base alle proprie esigenze e con le giuste modifiche, si possa operare diversamente (esempio: entrambi verticali).</li>
</ol>
<p>Innanzitutto è necessario e doveroso scrivere del <strong>codice html pulito e conforme</strong>. Potete tenere a riferimento le considerazioni già espresse nel <a href="http://www.mirkopagliai.it/how-to-menu-a-tendina/" target="_blank">precedente articolo</a>, e quindi scrivere un codice di questo genere:</p>
<pre class="brush: xml; title: ; notranslate">&lt;ul&gt;
	&lt;li&gt;&lt;a href=&quot;pagina1.html&quot;&gt;Pagina 1&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;
            &lt;a href=&quot;#&quot;&gt;Pagina 2&lt;/a&gt;
            &lt;ul&gt;
               &lt;li&gt;&lt;a href=&quot;paginaA.html&quot;&gt;Pagina A&lt;/a&gt;&lt;/li&gt;
               &lt;li&gt;&lt;a href=&quot;paginaB.html&quot;&gt;Pagina B&lt;/a&gt;&lt;/li&gt;
               &lt;li&gt;&lt;a href=&quot;paginaC.html&quot;&gt;Pagina C&lt;/a&gt;&lt;/li&gt;
            &lt;/ul&gt;
        &lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;pagina3.html&quot;&gt;Pagina 3&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</pre>
<p>È fondamentale notare come sia corretto organizzare il sotto-menù: il tag <em>&lt;ul&gt;</em> del sotto-menù (riga 5) è all&#8217;interno del tag <em>&lt;li&gt;</em> (riga 3) da cui si estende, che include anche il tag <em>&lt;a&gt;</em> (riga 4) che funge da finto-collegamento (in questo caso, perché deve essere funzionale solo all&#8217;estensione del sotto-menù) e da testo di riferimento per il sotto-menù. Potete vedere un primo esempio (solo html) <a href="http://docs.mirkopagliai.it/html/menu-tendina/esempio1.html" target="_blank">qui</a>.</p>
<p><a href="http://www.mirkopagliai.it/wp-content/uploads/2011/10/submenu1.jpg"><img class="aligncenter size-full wp-image-2152" title="submenu1" src="http://www.mirkopagliai.it/wp-content/uploads/2011/10/submenu1.jpg" alt="" width="168" height="133" /></a>Passiamo al <strong>foglio di stile</strong>. Innanzitutto aggiungiamo un id al menù principale (nell&#8217;esempio sarà <em>navbar</em> e quindi <em>&lt;ul id=&#8221;navbar&#8221;&gt;</em>), così da facilitarne la selezione (sia nel foglio di stile, sia con Jquery; e ricordo che in entrambi bisogna anteporre il cancelletto (#) davanti al nome), poi aggiungiamo delle <strong>proprietà css di base</strong> affinché il menù diventi <a href="http://docs.mirkopagliai.it/html/menu-tendina/esempio2.html" target="_blank">così</a>. Non le riporto per intero in questo articolo, potete trovare il foglio di stile <a href="http://docs.mirkopagliai.it/html/menu-tendina/style1.css" target="_blank">qui</a>.</p>
<p><a href="http://www.mirkopagliai.it/wp-content/uploads/2011/10/submenu22.jpg"><img class="aligncenter size-full wp-image-2153" title="submenu2" src="http://www.mirkopagliai.it/wp-content/uploads/2011/10/submenu22.jpg" alt="" width="259" height="107" /></a>Alcuni commenti:</p>
<ol>
<li>si seleziona il menù principale con <em>#navbar</em> (avendo l&#8217;<em>&lt;ul&gt;</em> principale id <em>navbar</em>, come già detto), i sotto-menù con <em>#navbar ul</em> (non solo quelli di primo livello, semmai ce ne fossero di inferiori!), entrambi (menù principale e sotto-menù) unendo le due con una virgola (quindi: <em>#navbar, #navbar ul</em> su un&#8217;unica riga);</li>
<li>il menù principale si estende orizzontalmente, i sotto-menù (anche qui, non solo quelli di primo livello, ma tutti) verticalmente. Ciò significa che che una regola generale potrebbe (e spesso ha bisogno di) essere riscritta o perfezionata per essere applicata a uno stesso elemento contenuto in un sotto-menù di livello inferiore (il punto 4 di questo elenco ne è un esempio);</li>
<li>dare una posizione assoluta ai sotto-menù (riga 13) è utile affinché siano indipendenti per quanto riguarda le misure (che saranno automatiche e calcolate in base al contenuto). Per eventuali altri sotto-livelli, ho notato dei problemi (sempre con le misure) credo imputabili ai limiti di Css 2. In questi casi, è bene specificare delle larghezze minime assolute per i sotto-menù, che potrebbe comunque essere &#8211; a prescindere &#8211; una buona pratica, anche per motivi estetici;</li>
<li>i <em>&lt;li&gt;</em> del menù principale devono essere &#8220;flottanti&#8221; a sinistra per essere mostrati uno affianco all&#8217;altro (riga 23), visto che di default un elenco (<em>&lt;ul&gt;</em>) si estende in verticale. Questa regola viene annullata per i <em>&lt;li&gt;</em> dei sotto-menù (riga 30), visto che l&#8217;ordinamento di default va bene (anche i sotto-menù si estendono in verticale);</li>
<li>bisogna annullare lo stile dei menù (riga 24);</li>
<li>le <em>&lt;a&gt;</em> hanno bisogno della proprietà <em>display</em> impostata a <em>block</em> (riga 36), altrimenti non avranno le stesse dimensioni dei <em>&lt;li&gt;</em> che le contengono;</li>
<li>le modifiche di stile al passaggio del mouse (righe 45-47) vengono &#8220;attivate&#8221; al passaggio del mouse su un <em>&lt;li&gt;</em> (infatti troviamo <em>li:hover</em>), ma vengono applicate alla <em>&lt;a&gt;</em> contenuta in quel <em>&lt;li&gt;</em>, visto che è alla <em>&lt;a&gt;</em> che viene definito un stile (righe 34-40). Le modifiche vengono applicate solo alla <em>&lt;a&gt;</em> &#8220;primo figlio&#8221; (meglio in inglese: <em>first child</em>) tramite il <em>&gt;</em> (riga 45), per evitare comportamenti non voluti (se togliete il &gt; e passate sul <em>&lt;li&gt;</em> che contiene un sotto-menù, noterete che le modifiche vengono applicate anche a tutte le <em>&lt;a&gt;</em> del sotto-menù e non solo a quella che apre il sotto-menù &#8211; è normale, visto che anche quelle sono &#8220;figlie&#8221; del <em>&lt;li&gt;</em> principale, proprio per la <strong>struttura html</strong> che abbiamo (correttamente) definito).</li>
</ol>
<p>In questo esempio &#8211; come sicuramente avrete già notato &#8211; il sotto-menù è mostrato sempre, diremmo &#8220;fisso&#8221;: ho scelto così per permettere di visualizzare nel complesso l&#8217;applicazione del foglio di stile. Normalmente, però, non dovrebbe essere così, quindi dobbiamo nasconderlo. Per farlo utilizzeremo la proprietà <em>display</em> settata su <em>none</em>, da applicare a tutti i sotto-menù. Quindi, a questo punto, dobbiamo aggiungere <span style="text-decoration: underline;">sotto</span> la riga 12 quanto segue:</p>
<pre class="brush: css; light: true; title: ; notranslate">display: none;</pre>
<p>Notare che si potrebbe usare anche la <a href="http://www.w3schools.com/cssref/pr_class_visibility.asp" target="_blank">regola visibility</a> (settata su <em>hidden</em>), che porta allo stesso risultato ed è anche migliore da un punto di vista strettamente semantico; ma dobbiamo necessariamente ricorrere a <em>display</em>, perché Jquery lavora su questa proprietà per modificare la visibilità di un elemento.<br />
Fatto questo, l&#8217;esempio aggiornato è <a href="http://docs.mirkopagliai.it/html/menu-tendina/esempio3.html" target="_blank">questo</a> e il relativo foglio di stile <a href="http://docs.mirkopagliai.it/html/menu-tendina/style2.css" target="_blank">questo qui</a>.</p>
<p>Non resta che aggiungere Jquery. L&#8217;operazione da eseguire è: al <strong>passaggio del mouse</strong> su un <em>&lt;li&gt;</em>, mostra l&#8217;<em>&lt;ul&gt;</em> <em>first child</em> (anche qui, altrimenti se usiamo più livelli di sotto-menù, li estenderebbe subito tutti). Va da sé che se un <em>&lt;li&gt;</em> non ha nessun <em>&lt;ul&gt;</em> figlio, non accade nulla. Quindi innanzitutto includiamo Jquery (all&#8217;interno dei tag <em>&lt;head&gt;</em>):</p>
<pre class="brush: xml; title: ; notranslate">&lt;script src=&quot;http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js&quot;&gt;&lt;/script&gt;
&lt;script&gt;
	$(document).ready(function(){
	 	//Il nostro codice andrà qui...
	});
&lt;/script&gt;</pre>
<p>Per attivare un <strong>effetto al passaggio del mouse</strong> su un <em>&lt;li&gt;</em>, possiamo usare l&#8217;evento <em>hover()</em> (<a href="http://api.jquery.com/hover/" target="_blank">documentazione</a>). Il nostro codice diventa quindi (ometto l&#8217;inclusione del <em>.js</em> di Jquery e i vari tag <em>&lt;script&gt;</em>):</p>
<pre class="brush: jscript; title: ; notranslate">$(document).ready(function(){
	$(&quot;#navbar li&quot;).hover(function (){
		//L'effetto da applicare va qui...
	});
});</pre>
<p>Che semplicemente corrisponde a: al passaggio del mouse (evento<em> hover()</em>) su un (qualsiasi) <em>&lt;li&gt;</em> contenuto nell&#8217;<em>&lt;ul&gt;</em> <em>#navbar</em> (quindi <em>#navbar li</em>), applica la funzione alla riga 3 (che qui dobbiamo implementare).</p>
<p>Di effetti disponibili ce ne sono parecchi (<a href="http://api.jquery.com/category/effects/" target="_blank">lista completa</a>): noi utilizzeremo <em>slideToggle()</em> (<a href="http://api.jquery.com/slideToggle/" target="_blank">documentazione</a>), ma si valutino anche il classico <em>toggle()</em> (<a href="http://api.jquery.com/toggle/" target="_blank">documentazione</a>) e <em>fadeToggle()</em> (<a href="http://api.jquery.com/fadeToggle/" target="_blank">documentazione</a>), che differiscono per lo più per il tipo di animazione (si fa prima a provare che a descrivere in questo articolo). Il codice diventa quindi:</p>
<pre class="brush: jscript; title: ; notranslate">$(document).ready(function(){
	$(&quot;#navbar li&quot;).hover(function (){
		$(this).children(&quot;ul&quot;).slideToggle();
	});
});</pre>
<p>Che sta a significare: applica l&#8217;effetto <em>slideToggle()</em> al figlio <em>&lt;ul&gt;</em> (grazie a <em>children()</em> (<a href="http://api.jquery.com/children/" target="_blank">documentazione</a>)) dell&#8217;attuale <em>&lt;li&gt;</em> (<em>this</em>) su cui si è passato il mouse. Ecco quindi il <a href="http://docs.mirkopagliai.it/html/menu-tendina/esempio4.html" target="_blank">nuovo esempio</a> (il foglio di stile è sempre lo stesso, non lo abbiamo toccato), che soddisfa le necessità iniziali.</p>
<p>Manca giusto una (ultima) cosa, per lo più un &#8220;orpello&#8221;: come fare a capire (ad occhio, per il visitatore) <strong>quali menù contengono un sotto-menù</strong>. È diffusa l&#8217;abitudine di aggiungere il carattere &#8220;»&#8221; (ascii &amp;#187;) ai menù che contengono un sotto-menù, pratica chiara e immediata. Potremmo occuparci di questa &#8220;aggiunta&#8221; manualmente, ma perché farlo (e faticare e rischiare di commettere errori o di non aggiornare in là col tempo), quando Jquery può occuparsi anche di questo e al posto nostro?<br />
D&#8217;altronde la cosa è semplice: ciclare tutti i <em>&lt;li&gt;</em> del menù (<em>&lt;li&gt;</em> a qualsiasi profondità, ovviamente), verificare se hanno un <em>&lt;ul&gt;</em> figlio (con un <strong>costrutto if</strong>) e in caso positivo aggiungere il carattere (preceduto da uno spazio!) alla fine del link.</p>
<p>Bene, passiamo al codice. Per ciclare possiamo utilizzare <em>each()</em> (<a href="http://api.jquery.com/each/" target="_blank">documentazione</a>):</p>
<pre class="brush: jscript; title: ; notranslate">$(&quot;#navbar li&quot;).each(function() {
	//Fa qualcosa ad ogni &lt;li&gt; all'interno di #navbar...
});</pre>
<p>che, in questo caso, eseguire la funzione qui dichiarata su ogni elemento <em>&lt;li&gt;</em> all&#8217;interno di <em>#navbar</em>. Quindi la verifica, per la quale possiamo affidarci a <em>length</em> (<a href="http://api.jquery.com/length/" target="_blank">documentazione</a>):</p>
<pre class="brush: jscript; title: ; notranslate">$(&quot;#navbar li&quot;).each(function() {
	if ($(this).children(&quot;ul&quot;).length) //Fa qualcosa ad ogni &lt;li&gt; all'interno di #navbar che contiene un &lt;ul&gt;...
});</pre>
<p>In sostanza, in questo esempio <em>lenght</em> è pari al numero degli <em>&lt;ul&gt;</em> figli del <em>&lt;li&gt;</em> per il quale stiamo eseguendo il ciclo (sempre il famoso selettore this), e quindi l&#8217;if avrà esito negativo se non ci sono <em>&lt;ul&gt;</em> figli, viceversa positivi se c&#8217;è almeno un <em>&lt;ul&gt;</em> figlio &#8211; nota: questo if può essere generalmente utilizzato per verificare se un tag ne contiene un altro ed eventualmente in quale quantità.<br />
Quindi l&#8217;aggiunta:</p>
<pre class="brush: jscript; title: ; notranslate">$(&quot;#navbar li&quot;).each(function() {
	//Se un &lt;li&gt; contiene un sotto-menù, aggiunge al collegamento &quot; »&quot;
	if ($(this).children(&quot;ul&quot;).length) $(this).children(&quot;a&quot;).append(&quot; &amp;#187;&quot;);
});</pre>
<p>Utilizziamo il manipolatore <em>append()</em> (<a href="http://api.jquery.com/append/" target="_blank">documentazione</a>) per aggiungere uno spazio e un carattere alla<em> &lt;a&gt;</em> figlia di ogni <em>&lt;li&gt;</em> che ha come figlio un <em>&lt;ul&gt;</em> &#8211; sembra un ragionamento contorto, sì, lo so; ma riflettete un po&#8217; sul codice e ci arriverete: l&#8217;aggiunta va fatta alla <em>&lt;a&gt;</em> contenuta nel <em>&lt;li&gt;</em> e non al <em>&lt;li&gt;</em> sul quale abbiamo eseguito il controllo.</p>
<p>Ecco quindi il codice Jquery finale e completo:</p>
<pre class="brush: jscript; title: ; notranslate">$(document).ready(function(){
	$(&quot;#navbar li&quot;).hover(function (){
		$(this).children(&quot;ul&quot;).slideToggle();
	});
	$(&quot;#navbar li&quot;).each(function() {
		//Se un &lt;li&gt; contiene un sotto-menù, aggiunge al collegamento &quot; »&quot;
		if ($(this).children(&quot;ul&quot;).length) $(this).children(&quot;a&quot;).append(&quot; &amp;#187;&quot;);
	});
});</pre>
<p>Nonché, l&#8217;<a href="http://docs.mirkopagliai.it/html/menu-tendina/esempio5.html" target="_blank">ultimo esempio</a>.</p>
<p><a href="http://www.mirkopagliai.it/wp-content/uploads/2011/10/submenu3.jpg"><img class="aligncenter size-full wp-image-2154" title="submenu3" src="http://www.mirkopagliai.it/wp-content/uploads/2011/10/submenu3.jpg" alt="" width="248" height="104" /></a></p>
<img src="http://feeds.feedburner.com/~r/mirkopagliai/~4/81gjYI_Z_Ok" height="1" width="1"/>]]></content:encoded><description>Avevo già scritto qualcosa sui menù a tendina, arrivando a consigliare di utilizzare SuperFish, che a tutt&amp;#8217;ora considero un ottimo plugin. Vediamo però come realizzare da zero un menù a tendina completo, utilizzando solo e semplicemente Jquery e limitandoci (per questo articolo, più in là semmai approfondirò) a un solo livello di profondità (in altri [...]</description><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.mirkopagliai.it/tutorial-jquery-menu-a-tendina/feed/</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">1</slash:comments><feedburner:origLink>http://www.mirkopagliai.it/tutorial-jquery-menu-a-tendina/</feedburner:origLink></item><item><title>Bash scripting: verificare e installare dipendenze mancanti</title><link>http://feedproxy.google.com/~r/mirkopagliai/~3/53uJ_xO4FgU/</link><category>Programmazione</category><category>Unix</category><category>apt-get</category><category>ArchLinux</category><category>CentOS</category><category>costrutto if</category><category>costrutto if-elif-else</category><category>Debian</category><category>dipendenze da verificare</category><category>dpkg</category><category>esito dell'installazione</category><category>Fedora</category><category>install.sh</category><category>installate determinate dipendenze</category><category>installazione dello script</category><category>Mandriva</category><category>Mint</category><category>openSUSE</category><category>pacman</category><category>pacmangestore di pacchetti</category><category>provvedere a installare manualmente</category><category>rpm</category><category>script bash</category><category>Ubuntu</category><category>urpmi</category><category>verificare quali dipendenze sono mancanti</category><category>yum</category><category>zypper</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Mirko Pagliai</dc:creator><pubDate>Mon, 24 Oct 2011 06:58:15 PDT</pubDate><guid isPermaLink="false">http://www.mirkopagliai.it/?p=2141</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p><img class="size-thumbnail wp-image-2145 alignleft" title="Bash script" src="http://www.mirkopagliai.it/wp-content/uploads/2011/10/bash-script-180x180.png" alt="" width="78" height="78" />Mettiamo che &#8211; come nel mio caso &#8211; state scrivendo uno script (magari proprio in bash, ma &#8211; perché no&#8230; &#8211; anche in altri linguaggi) che ha bisogno che sul sistema siano correttamente <strong>installate determinate dipendenze</strong>, utili alla sua esecuzione .<br />
Mettiamo che &#8211; come nel mio caso &#8211; avete previsto uno <strong>script bash</strong> che si occupi dell&#8217;<strong>installazione dello script</strong> (qualcosa del tipo <em>install.sh</em>, che crea, sposta, modifica alcuni file) e che vogliate che questo si occupi anche dell&#8217;installazione delle suddette dipendenze.</p>
<p>Si può fare? Sì, si può fare. Vi spiego come.<br />
Analizziamo innanzitutto i passaggi che si dovrebbero svolgere, ordinandoli:</p>
<ol>
<li>vengono elencate (ad esempio, tramite un array) le dipendenze necessarie;</li>
<li>ricerca di un <strong>gestore di pacchetti</strong> valido;</li>
<li>verifica delle dipendenze mancanti nel sistema in uso, elencando anche queste (un nuovo array);</li>
<li>ricerca di un gestore di pacchetti valido;</li>
<li>installazione delle dipendenze segnate come mancanti.</li>
</ol>
<p>Prima osservazione, più che lecita: i punti 2) e 4) non fanno la stessa cosa? A che serve ripetere due volte la stessa operazione?<br />
Risposta: serve ripetere la stessa operazione perché sì, nonostante facciano la stessa cosa (ricerca un gestore di pacchetti valido), la ricerca, nei due casi, può e anzi dovrebbe portare a risultati diversi; questo perché bisogna tenere in conto che il gestore selezionato al punto 2) deve svolgere l&#8217;operazione indicata come 3), mentre il gestore selezionato al punto 4) svolgerà il compito 5).<br />
E non è detto che per entrambe le operazioni sia opportuno utilizzare lo stesso gestore (anche se è cosa possibile), anzi&#8230;</p>
<p>Un esempio concreto chiarificherà questa spiegazione: visto che il gestore selezionato al punto 4) dovrà procedere all&#8217;installazione di alcuni pacchetti &#8211; come indicato al punto 5) &#8211; se la distribuzione è openSuse si utilizzerà <em>zypper</em>, se è Mandriva si utilizzerà <em>urpmi</em>, se è Fedora si utilizzerà <em>yum</em>. Mentre invece il punto 3), in tutti questi tre casi (openSuse, Mandriva e Fedora) può essere sempre svolto da <em>rpm</em>. Che per giunta svolge il compito 3) meglio degli altri già elencati; al contrario, non sarebbe invece molto indicato per svolgere il punto 5), per motivi che tutti conosciamo.<br />
Lo stesso dicasi per altre distribuzioni. Ad esempio, per Debian, Ubuntu e derivate varie, il punto 3) verrà svolto da <em>dpkg</em>, il punto 5) da <em>apt-get</em>.</p>
<p>Seconda osservazione: è proprio necessario <strong>verificare quali dipendenze sono mancanti</strong>? Non si fa prima a proporre l&#8217;installazione di tutte le dipendenze, così che sia poi il gestore a occuparsi di installare solo quelle mancanti e eventualmente a segnalare quelle già presenti? Sì, certo, si può fare e sicuramente è più comodo e veloce. Ma qui si valuterà il processo &#8220;più complesso&#8221;, negli altri casi non dovrebbe essere difficile (per voi, per chi legge, per chi è interessato) snellire la procedura, a seconda delle proprie esigenze.<br />
Si tenga anche in conto che lo script potrebbe fallire, per tanti motivi (perché non è stato trovato un gestore di pacchetti adatto, cosa possibile perché non si possono considerare tutte le distribuzioni Linux esistenti, con i loro relativi gestori): in questo caso, potremo indicare all&#8217;utente quali dipendenze sono appunto mancanti, e invitarlo a installarle manualmente. Cosa che è molto più elegante, in questo caso, dell&#8217;indicare tutte le dipendenze necessarie, installate o meno, mettendo così l&#8217;utente nella condizione di dover controllare quali deve provvedere a installare manualmente.</p>
<p>Terza osservazione: l&#8217;installazione, ovvero il passaggio 5), avviene del tutto automaticamente, cioè senza nessun interazione con l&#8217;utente? No, volutamente no. Lo script che propongo lancia il gestore con il corretto comando d&#8217;installazione: è facile e molto probabile che poi &#8211; qualsiasi sia la distribuzione, qualsiasi sia il gestore selezionato &#8211; verrà chiesto all&#8217;utente di confermare.<br />
È una scelta voluta, perché esperienza mi ha insegnato che non è corretto installare software senza renderne consapevole e partecipe l&#8217;utente e che non è corretto installare senza aver prima visionato quali cambiamenti verranno apportati al sistema (in alcuni casi, l&#8217;installazione di alcuni pacchetti, per via di errati calcoli o problemi con le dipendenze che si portano dietro, possono rendere un sistema instabile&#8230;).</p>
<p>Finite le osservazioni, passiamo al codice. È innanzitutto necessario stabilire quali sono le dipendenze necessarie. Vorrei subito chiarire, a scanso di equivoci, che:</p>
<ol>
<li>quando parlo di &#8220;dipendenze&#8221; o di &#8220;dipendenze necessarie&#8221; mi riferisco alle dipendenze richieste dal nostro script (affinché funzioni correttamente);</li>
<li>quando parlo di &#8220;dipendenze mancanti&#8221; mi riferisco alle dipendenze del nostro script <span style="text-decoration: underline;">e</span> che mancano sul sistema in uso (è quindi questo un sotto-insieme o una selezione del precedente).</li>
</ol>
<p>Avevamo previsto un array, che mi sembra la scelta più opportuna:</p>
<pre class="brush: bash; light: true; title: ; notranslate">DEPENDENCIES=(adduser curlftpfs dialog inotify-tools libnotify-bin nfs-common)</pre>
<p>Questo soddisfa il punto 1) nella lista dei passaggi da compiere. Passiamo ai punti 2) e 3), ovvero alla selezione di un opportuno gestore di pacchetti e alla verifica di quali dipendenze sono mancanti:</p>
<pre class="brush: bash; title: ; notranslate"># What dependencies are missing?
PKGSTOINSTALL=&quot;&quot;
for (( i=0; i&lt;${tLen=${#DEPENDENCIES[@]}}; i++ )); do
	# Debian, Ubuntu and derivatives (with dpkg)
	if which dpkg &amp;&gt; /dev/null; then
		if [[ ! `dpkg -l | grep -w &quot;ii  ${DEPENDENCIES[$i]} &quot;` ]]; then
			PKGSTOINSTALL=$PKGSTOINSTALL&quot; &quot;${DEPENDENCIES[$i]}
		fi
	# OpenSuse, Mandriva, Fedora, CentOs, ecc. (with rpm)
	elif which rpm &amp;&gt; /dev/null; then
		if [[ ! `rpm -q ${DEPENDENCIES[$i]}` ]]; then
			PKGSTOINSTALL=$PKGSTOINSTALL&quot; &quot;${DEPENDENCIES[$i]}
		fi
	# ArchLinux (with pacman)
	elif which pacman &amp;&gt; /dev/null; then
		if [[ ! `pacman -Qqe | grep &quot;${DEPENDENCIES[$i]}&quot;` ]]; then
			PKGSTOINSTALL=$PKGSTOINSTALL&quot; &quot;${DEPENDENCIES[$i]}
		fi
	# If it's impossible to determine if there are missing dependencies, mark all as missing
	else
		PKGSTOINSTALL=$PKGSTOINSTALL&quot; &quot;${DEPENDENCIES[$i]}
	fi
done</pre>
<p>Nonostante reputi questo codice abbastanza comprensibile, vado a commentare:</p>
<ol>
<li>innanzitutto vado a creare la variabile (vuota) <em>PKGSTOINSTALL</em>, che conterrà l&#8217;elenco (non è un array, ma una stringa, con gli spazi a mò di divisore) delle dipendenze mancanti;</li>
<li>viene quindi eseguito un ciclo (riga 3) per ognuna delle <strong>dipendenze da verificare</strong>;</li>
<li>all&#8217;interno del ciclo, tramite un (complesso) <strong>costrutto if-elif-else</strong>, vado a verificare se è disponibile un gestore di pacchetti, avvalendomi di <em>which</em> (che stampa la localizzazione di un eseguibile, quando è presente, altrimenti nulla) e, se disponibile, quale (righe 5, 10 e 15).<br />
Qui, in particolare, ricerchiamo tra <em>dpkg</em> (per Debian, Ubuntu e derivate, come Mint), <em>rpm</em> (per OpenSuse, Mandriva, Fedora, CentOs e altre) e <em>pacman</em> (per ArchLinux), che dovrebbero coprire la stragrande maggioranza delle distribuzioni, sicuramente tutte quelle più diffuse;</li>
<li>viene quindi verificata se la singola dipendenza (che stiamo ciclando) è già installata o meno, eseguendo un comando specifico per il gestore che abbiamo selezionato (righe 6, 11 e 16);</li>
<li>se la dipendenza non risulta installata, viene accodata alla stringa <em>PKGSTOINSTALL</em> (righe 7, 12 e 17), preceduta da uno spazio. Se invece è già installata, passa alla successiva dipendenza da controllare;</li>
<li>se non viene trovato un gestore utile (alternativo quindi a quanto descritto al punto 3) di questo elenco), allora segna automaticamente la dipendenza come mancante (riga 21), segnando di fatto tutte le dipendenze come mancanti (perché, ovviamente, anche la successiva iterazione del ciclo porterà allo stesso risultato&#8230;).</li>
</ol>
<p>Alla fine di questo blocco di codice &#8211; come per altro già accennato &#8211; la variabile <em>PKGSTOINSTALL </em>conterrà quindi l&#8217;elenco delle dipendenze mancanti (e quindi da installare!), separate l&#8217;un l&#8217;altra da uno spazio (come tutti i gestori si aspettano siano passato l&#8217;elenco).</p>
<p>Si noti che questo codice non è &#8220;perfetto&#8221;: ad ogni ciclo, di fatti, si va a rieseguire il controllo del gestore. Non dovrebbe portare a chissà quali performance negative e/o penalizzanti, ma non escludo assolutamente che si possano scrivere numerosi varianti migliori di questa e che portino allo stesso risultato. Anzi, se ne avete voglia, prendetelo come un esercizio, visto che sicuramente si può fare (e si dovrebbe fare&#8230;) di meglio.</p>
<p>Passiamo al codice che si occupa dell&#8217;installazione effettiva:</p>
<pre class="brush: bash; title: ; notranslate"># If some dependencies are missing, asks if user wants to install
if [ &quot;$PKGSTOINSTALL&quot; != &quot;&quot; ]; then
	echo -n &quot;Some dependencies are missing. Want to install them? (Y/n): &quot;
	read SURE
	# If user want to install missing dependencies
	if [[ $SURE = &quot;Y&quot; || $SURE = &quot;y&quot; || $SURE = &quot;&quot; ]]; then
		# Debian, Ubuntu and derivatives (with apt-get)
		if which apt-get &amp;&gt; /dev/null; then
			apt-get install $PKGSTOINSTALL
		# OpenSuse (with zypper)
		elif which zypper &amp;&gt; /dev/null; then
			zypper in $PKGSTOINSTALL
		# Mandriva (with urpmi)
		elif which urpmi &amp;&gt; /dev/null; then
			urpmi $PKGSTOINSTALL
		# Fedora and CentOS (with yum)
		elif which yum &amp;&gt; /dev/null; then
			yum install $PKGSTOINSTALL
		# ArchLinux (with pacman)
		elif which pacman &amp;&gt; /dev/null; then
			pacman -Sy $PKGSTOINSTALL
		# Else, if no package manager has been founded
		else
			# Set $NOPKGMANAGER
			NOPKGMANAGER=TRUE
			echo &quot;ERROR: impossible to found a package manager in your sistem. Please, install manually ${DEPENDENCIES[*]}.&quot;
		fi
		# Check if installation is successful
		if [[ $? -eq 0 &amp;&amp; ! -z $NOPKGMANAGER ]] ; then
			echo &quot;All dependencies are satisfied.&quot;
		# Else, if installation isn't successful
		else
			echo &quot;ERROR: impossible to install some missing dependencies. Please, install manually ${DEPENDENCIES[*]}.&quot;
		fi
	# Else, if user don't want to install missing dependencies
	else
		echo &quot;WARNING: Some dependencies may be missing. So, please, install manually ${DEPENDENCIES[*]}.&quot;
	fi
fi</pre>
<p>Vado anche qui a commentare:</p>
<ol>
<li>innanzitutto, un semplice <strong>costrutto if</strong> verifica che la variabile <em>PKGSTOINSTALL</em> non sia vuota (riga 2) e quindi &#8211; in altri termini &#8211; verifica che ci sia qualcosa da installare. Ricordo &#8211; visto che l&#8217;avevo già precisato &#8211; che se precedentemente non è stato possibile determinare quali dipendenze siano mancanti e quali presenti, qui risulteranno tutte come mancanti;</li>
<li>a questo punto, viene chiesto all&#8217;utente se vuole procedere con l&#8217;installazione (la riga 3 stampa la richiesta, la riga 4 salva l&#8217;input in <em>READ</em>);</li>
<li>se la risposta è affermativa (riga 6), allora viene ricercato un gestore di pacchetti (righe 8, 11, 14, 17, 20) tra <em>apt-get</em>, <em>zypper</em>, <em>urpmi</em>, <em>yum</em> e <em>pacman</em>, sempre tramite un costrutto if-elif-else;</li>
<li>se è stato trovato un gestore dei pacchetti, allora procede con l&#8217;installazione, avvalendosi dell&#8217;opportuna istruzione (righe 9, 12, 15, 18, 21). Altrimenti (riga 23), imposta la variabile <em>NOPKGMANAGER</em> a <em>TRUE</em> (riga 25, ci servirà successivamente per controllo) e stampa a schermo un errore (riga 26);</li>
<li>quindi viene verificato l&#8217;<strong>esito dell&#8217;installazione</strong> (riga 29). Se l&#8217;istruzione di installazione non ha restituito nessun errore (per qualsiasi motivo che abbia portato il gestore di turno ad un fallimento) <span style="text-decoration: underline;">e</span> se non è presente la variabile <em>NOPKGMANAGER</em> (impostata quando non viene correttamente rilevato un gestore di pacchetti), allora l&#8217;installazione ha avuto successo e quindi stampa un messaggio di conferma (riga 30). Se invece le due ipotesi non sono entrambe e contemporaneamente vere (riga 32), allora l&#8217;installazione non è andata a buon fine e quindi stampa un messaggio di errore e la lista delle dipendenze segnate come mancanti, che l&#8217;utente dovrà (a questo punto) <strong>provvedere a installare manualmente</strong> (riga  33);</li>
<li>se invece l&#8217;utente ha inizialmente risposto negativamente alla richiesta di procedere con l&#8217;installazione (riga 36), allora stampa un messaggio di avviso e &#8211; anche qui &#8211; la lista delle dipendenze da installare manualmente.</li>
</ol>
<img src="http://feeds.feedburner.com/~r/mirkopagliai/~4/53uJ_xO4FgU" height="1" width="1"/>]]></content:encoded><description>Mettiamo che &amp;#8211; come nel mio caso &amp;#8211; state scrivendo uno script (magari proprio in bash, ma &amp;#8211; perché no&amp;#8230; &amp;#8211; anche in altri linguaggi) che ha bisogno che sul sistema siano correttamente installate determinate dipendenze, utili alla sua esecuzione . Mettiamo che &amp;#8211; come nel mio caso &amp;#8211; avete previsto uno script bash che [...]</description><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.mirkopagliai.it/bash-scripting-verificare-e-installare-dipendenze-mancanti/feed/</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">0</slash:comments><feedburner:origLink>http://www.mirkopagliai.it/bash-scripting-verificare-e-installare-dipendenze-mancanti/</feedburner:origLink></item><item><title>Linux day 2011</title><link>http://feedproxy.google.com/~r/mirkopagliai/~3/qYEim3DKKFo/</link><category>Unix</category><category>GNU/Linux</category><category>Italian Linux Society</category><category>Linux</category><category>Linux day</category><category>LUG italiani</category><category>promuovere GNU/Linux</category><category>software libero</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Mirko Pagliai</dc:creator><pubDate>Wed, 19 Oct 2011 14:44:52 PDT</pubDate><guid isPermaLink="false">http://www.mirkopagliai.it/?p=2132</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p><img class="alignnone size-full wp-image-2138" style="background-color:black" title="Linux Day 2011" src="http://www.mirkopagliai.it/wp-content/uploads/2011/10/logo.png" alt="Linux Day 2011" width="261" height="54" /></p>
<p>Il 22 ottobre in tutta Italia è il <strong>Linux day</strong>.</p>
<blockquote><p>Il Linux Day è una manifestazione nazionale articolata in eventi locali che ha lo scopo di promuovere GNU/Linux e il software libero. Il Linux Day è promosso da ILS (Italian Linux Society) e organizzato localmente dai LUG italiani e dagli altri gruppi che condividono le finalità della manifestazione.<br />
La responsabilità dei singoli eventi locali è lasciata ai rispettivi gruppi organizzatori, che hanno libertà di scelta per quanto riguarda i dettagli delle iniziative locali, nel rispetto delle <a href="http://www.linuxday.it/node/7">linee guida</a> generali della manifestazione. La prima edizione del Linux Day si è tenuta il 1 dicembre 2001 in circa quaranta città sparse su tutto il territorio nazionale. Il numero è notevolmente cresciuto negli anni divenendo ormai un appuntamento immancabile nel panorama del software libero italiano.</p></blockquote>
<p>Date un&#8217;<a href="http://www.linuxday.it/">occhiata</a> al sito ufficiale, dove trovate la mappa delle 109 città italiane, dell&#8217;utile <a href="http://www.linuxday.it/materiale">materiale informativo</a> e le <a href="http://www.linuxday.it/news">ultime news</a> sull&#8217;iniziativa.</p>
<p>Se tutto andrà bene, io sarò presente a <a href="http://www.pescaralug.org/2011/09/19/linux-day-2011-alle-porte/">quello di Pescara</a>, organizzato dal <a href="http://www.pescaralug.org">Pescara Lug</a>. Il programma (se ci fossero altri della zona interessati):</p>
<blockquote><p>Mattina Inizio ore 9.30<br />
Ore 10.00 Introduzione e saluti<br />
Ore 10.15 Panoramica del mondo Linux<br />
Ore 10.45 Utilizzo di Linux tutti i giorni<br />
Ore 12.30 Pausa Pranzo</p>
<p>Pomeriggio Inizio ore 15.30<br />
Ore 15.30 Impaginazione e Scribus<br />
Ore 16.00 Crittografia dei dati e Tomb<br />
Ore 17.00 Sicurezza reti Wifi<br />
Ore 17.30 Android</p></blockquote>
<p>p.s. non ne sono stati organizzati in provincia di Chieti. Ce ne sono invece due a L&#8217;Aquila (<a href="http://haqlab.wordpress.com/">quello dell&#8217;hAQ-lab</a> e <a href="https://asilo.noblogs.org/linuxday-aq-2210/">quello Linux Crew CaseMatte</a>), <a href="http://avezzanolug.org/">uno ad Avezzano</a> e <a href="http://www.telug.it/">uno a Teramo</a>.</p>
<img src="http://feeds.feedburner.com/~r/mirkopagliai/~4/qYEim3DKKFo" height="1" width="1"/>]]></content:encoded><description>Il 22 ottobre in tutta Italia è il Linux day. Il Linux Day è una manifestazione nazionale articolata in eventi locali che ha lo scopo di promuovere GNU/Linux e il software libero. Il Linux Day è promosso da ILS (Italian Linux Society) e organizzato localmente dai LUG italiani e dagli altri gruppi che condividono le [...]</description><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.mirkopagliai.it/linux-day-2011/feed/</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">0</slash:comments><feedburner:origLink>http://www.mirkopagliai.it/linux-day-2011/</feedburner:origLink></item><item><title>Checkgmail: errore 401</title><link>http://feedproxy.google.com/~r/mirkopagliai/~3/bRPsTsnrAuY/</link><category>Unix</category><category>checkgmail</category><category>checkgmail.path</category><category>errore 401</category><category>patch per checkgmail</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Mirko Pagliai</dc:creator><pubDate>Wed, 21 Sep 2011 01:23:16 PDT</pubDate><guid isPermaLink="false">http://www.mirkopagliai.it/?p=2116</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p><img class="alignleft size-full wp-image-2123" title="Checkgmail" src="http://www.mirkopagliai.it/wp-content/uploads/2011/09/images.jpeg" alt="Checkgmail" width="61" height="61" />Googlando qua e là, ho scoperto che il problema che mi perseguita ormai da un mesetto, affligge molti utenti: <em>checkgmail</em> non riesce ad accedere al server di posta e notifica un <strong>errore 401</strong>, &#8220;unauthorized&#8221;.</p>
<p>Conseguenza diretta è che, imperterrito, <em>checkgmail</em> chiede continuamente le credenziali di accesso alla casella di posta:</p>
<p style="text-align: center;"><img class="aligncenter size-full wp-image-2119" title="Checkgmail Errore 401" src="http://www.mirkopagliai.it/wp-content/uploads/2011/09/Checkgmail-Errore-401.jpg" alt="Checkgmail Errore 401" width="245" height="62" /></p>
<p style="text-align: center;"><img class="aligncenter size-full wp-image-2120" title="Checkgmail Errore 401" src="http://www.mirkopagliai.it/wp-content/uploads/2011/09/Checkgmail-Errore-401b.jpg" alt="Checkgmail Errore 401" width="325" height="165" /></p>
<p>Lanciando l&#8217;update da terminale (`<em>checkmail -update</em>`), qualcosa viene aggiornato, ma la situazione non cambia, tant&#8217;è che lo stesso terminale dà in output un tristissimo:</p>
<pre class="brush: bash; light: true; title: ; notranslate">Unable to find gmail_ik ... full message text won't work :(</pre>
<p>Per nostra fortuna, qualche buon samaritano si è preso la briga di realizzare una piccola <strong>patch per checkgmail</strong> che potete scaricare da <a href="https://launchpadlibrarian.net/80056943/checkgmail.patch" target="_blank">qui</a>. Terminato il download, la potete applicare come segue (sono necessari i privilegi di root):</p>
<pre class="brush: bash; light: true; title: ; notranslate"># patch /usr/bin/checkgmail checkgmail.patch</pre>
<p>Ovviamente dovete indicare la path corretta di <em>checkgmail.path</em>. A questo punto sarà sufficiente riavviare <em>checkgmail</em> (click destro sull&#8217;icona, quindi &#8220;Restart&#8230;&#8221;) e tutto dovrebbe tornare alla normalità.</p>
<img src="http://feeds.feedburner.com/~r/mirkopagliai/~4/bRPsTsnrAuY" height="1" width="1"/>]]></content:encoded><description>Googlando qua e là, ho scoperto che il problema che mi perseguita ormai da un mesetto, affligge molti utenti: checkgmail non riesce ad accedere al server di posta e notifica un errore 401, &amp;#8220;unauthorized&amp;#8221;. Conseguenza diretta è che, imperterrito, checkgmail chiede continuamente le credenziali di accesso alla casella di posta: Lanciando l&amp;#8217;update da terminale (`checkmail [...]</description><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.mirkopagliai.it/checkgmail-errore-401/feed/</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">0</slash:comments><feedburner:origLink>http://www.mirkopagliai.it/checkgmail-errore-401/</feedburner:origLink></item><item><title>Popstar</title><link>http://feedproxy.google.com/~r/mirkopagliai/~3/km_izQYLFi4/</link><category>Senza categoria</category><category>Annamaria Talone</category><category>Coinvolgimento dei giovani nella valorizzazione delle specificità territoriali</category><category>Popstar</category><category>provincia di Chieti</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Mirko Pagliai</dc:creator><pubDate>Mon, 05 Sep 2011 15:57:40 PDT</pubDate><guid isPermaLink="false">http://www.mirkopagliai.it/?p=2111</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p><img class="alignleft size-thumbnail wp-image-2112" title="Popstar" src="http://www.mirkopagliai.it/wp-content/uploads/2011/09/276705_157576127643990_8313737_n-180x148.jpg" alt="Popstar" width="180" height="148" />Sfrutto lo spazio del mio blog per pubblicizzare il progetto di <a href="http://www.facebook.com/profile.php?id=1462747610" target="_blank">un&#8217;amica</a>, perché mi sembra meritevole ed interessante. Di seguito trovate la presentazione dello stesso. Se qualcuno fosse interessato &#8211; e mi rivolgo principalmente ai giovani della provincia di Chieti &#8211; si faccia riferimento all&#8217;<a href="http://www.facebook.com/groups/157576127643990/doc/167443526657250/" target="_blank">apposito gruppo su Facebook</a>.</p>
<blockquote><p>&#8220;Pop&#8221; da popolare, come la cultura viva che crea la nostra identità di individui e di collettività. “Stars” da stelle, non quelle del divismo spettacolare ma quelle naturali che ci portano indietro ad un tempo dove gli uomini erano in equilibrio con la natura, e questo dava loro un benessere individuale e collettivo.</p>
<p>Il Comune di Palombaro in qualità di comune capofila e la provincia di Chieti, annunciano l’avvio di &#8220;Popstars&#8221;, unico progetto abruzzese, selezionato nel bando “Piccoli Comuni per il Coinvolgimento dei giovani nella valorizzazione delle specificità territoriali – Giovani Energie in comune” promosso dall’Anci e dal Dipartimento della Gioventù della Presidenza del Consiglio dei Ministri.</p>
<p>Il progetto abruzzese coinvolge una rete di comuni dislocati in diverse zone dell’entroterra della Provincia di Chieti: Altino, Carunchio, Castelfrentano, Fraine, Miglianico, Pennapiedimonte, Pretoro, Rapino, Roccamontepiano, Roccaspinalveti, Sant’Eusanio del Sangro. I partners istituzionali oltre la Provincia di Chieti sono: CUSPD Centro Universitario di Sociologia della Prevenzione Disagio &#8211; Facoltà di Scienze Sociali Università G. D’Annunzio, Comunità Montana Alto Vastese, Comunità Montana della Maielletta, C.M.A – Centro Montano di Assistenza, Pro loco Carunchio, Pro loco Roccaspinalveti, Pro loco Fraine. Il consorzio Civica è responsabile del project Management.</p>
<p>La finalità principale di Pop Stars è quella di guidare i giovani in un percorso di recupero della memoria e dell’identità culturale del territorio attingendo al bagaglio di conoscenze e saperi di cui sono custodi gli anziani. Gli elementi della tradizione popolare saranno ri-letti e ri-utilizzati dai giovani attraverso i linguaggi della comunicazione e dell’arte contemporanea. Il progetto prevede per i mesi estivi lo svolgimento di un’attività di ricerca nei territori che coinvolge gli anziani. A partire da settembre e per tutto l’autunno, si svolgeranno i percorsi formativi in ambito socio – culturale rivolti ai giovani: laboratori di teatro, musica e canto, performance, video, fotografia e gestione siti web.</p>
<p>Le attività formative ideate e coordinate dalla regista Annamaria Talone dell’Associazione Maglab saranno realizzate da artisti ed operatori culturali esperti appartenenti alle associazioni abruzzesi Euritmi e Rogoteatro, e da una formatrice d’eccellenza Helen Chadwick  &#8211; musicista inglese, vocal trainer della Royal Shakespeare Company e del National Theatre. Le attività di ricerca e monitoraggio saranno guidate dal CUSPD diretto dal prof. Benvenuti &#8211; Facoltà di Scienze Sociali Università G. D’Annunzio.</p>
<p>Per poter partecipare i giovani devono avere un’età compresa tra i 18 e i 30 anni e la residenza in uno dei comuni coinvolti. Nel caso in cui non si raggiunge il numero minimo di adesioni per singolo laboratorio, sarà data la possibilità di fare domanda di partecipazione anche ai giovani residenti in tutti i comuni della Provincia di Chieti. Per informazioni sulle modalità di partecipazione ci si può rivolgere al proprio comune di residenza oppure visitare il sito <a href="http://www.facebook.com/groups/157576127643990/doc/167443526657250/www.giovanipopstars.it">www.giovanipopstars.it</a>. La domanda va presentata entro il 30.07.2011</p>
<p>Il progetto si conclude con delle feste finali promosse dai giovani insieme agli anziani e a tutta la popolazione dei paesi. Il valore sociale del progetto non tocca solo le giovani generazioni ma ha una ricaduta positiva sulle comunità dei paesi coinvolti, rafforzando il senso di appartenenza, l’identità territoriale e la comunicazione tra diverse generazioni.</p></blockquote>
<img src="http://feeds.feedburner.com/~r/mirkopagliai/~4/km_izQYLFi4" height="1" width="1"/>]]></content:encoded><description>Sfrutto lo spazio del mio blog per pubblicizzare il progetto di un&amp;#8217;amica, perché mi sembra meritevole ed interessante. Di seguito trovate la presentazione dello stesso. Se qualcuno fosse interessato &amp;#8211; e mi rivolgo principalmente ai giovani della provincia di Chieti &amp;#8211; si faccia riferimento all&amp;#8217;apposito gruppo su Facebook. &amp;#8220;Pop&amp;#8221; da popolare, come la cultura viva [...]</description><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.mirkopagliai.it/popstar/feed/</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">0</slash:comments><feedburner:origLink>http://www.mirkopagliai.it/popstar/</feedburner:origLink></item><item><title>Sviluppo web in locale</title><link>http://feedproxy.google.com/~r/mirkopagliai/~3/VYOBT1XSxxk/</link><category>Programmazione</category><category>Unix</category><category>/etc/apache2/ports.conf</category><category>/etc/phpmyadmin/config.inc.php</category><category>Apache in ascolto solo in locale</category><category>applicazioni web in locale</category><category>database mysql</category><category>host locale</category><category>PhpMyAdmin senza password</category><category>server Apache</category><category>Sviluppo web in locale</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Mirko Pagliai</dc:creator><pubDate>Mon, 29 Aug 2011 10:57:49 PDT</pubDate><guid isPermaLink="false">http://www.mirkopagliai.it/?p=2101</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p><img class="alignleft size-thumbnail wp-image-2102" title="Apache" src="http://www.mirkopagliai.it/wp-content/uploads/2011/08/apache-http-server-logo1-180x135.jpg" alt="Apache" width="142" height="106" />Due veloci tips and tricks per chi &#8211; come il sottoscritto &#8211; sviluppa <strong>applicazioni web in locale</strong>.</p>
<h2>Apache in ascolto solo in locale</h2>
<p>Questo impedisce che il nostro <strong>server Apache</strong> sia raggiungibile dall&#8217;esterno, lan inclusa. In altri termini, sarà raggiungibile solo dall&#8217;<strong>host locale</strong>, ovvero dalla stessa macchina su cui è in funzione il web server.<br />
Modificare il file <em>/etc/apache2/ports.conf</em> da:</p>
<pre class="brush: plain; light: true; title: ; notranslate">Listen 80</pre>
<p>a:</p>
<pre class="brush: plain; light: true; title: ; notranslate">Listen 127.0.0.1:80</pre>
<p>È possibile indicare un indirizzo per riga. Quindi, volendo abilitare anche la lan (e supponendo che l&#8217;ip della macchina, al suo interno, sia 192.168.0.100), modificare in:</p>
<pre class="brush: plain; light: true; title: ; notranslate">Listen 127.0.0.1:80
Listen 192.168.0.100:80</pre>
<p>E quindi riavviare il servizio:</p>
<pre class="brush: bash; light: true; title: ; notranslate"># /etc/init.d/apache2 restart</pre>
<h2>PhpMyAdmin senza password</h2>
<p>Questo ci permette di loggarci automaticamente all&#8217;interno di PhpMyAdmin senza doverci autenticare ogni volta. Di default, è richiesta l&#8217;autenticazione, che viene mantenuta tramite l&#8217;utilizzo di cookie.<br />
Modificare il file <em>/etc/phpmyadmin/config.inc.php</em> da:</p>
<pre class="brush: plain; title: ; notranslate">/* Authentication type */
$cfg['Servers'][$i]['auth_type'] = 'cookie';</pre>
<p>a:</p>
<pre class="brush: plain; title: ; notranslate">/* Authentication type */
$cfg['Servers'][$i]['auth_type'] = 'config';
$cfg['Servers'][$i]['user'] = 'root';
$cfg['Servers'][$i]['password'] = 'mypwd';</pre>
<p><span class="small">(dove <em>mypwd</em> è la password dell&#8217;utente root)</span></p>
<p>Assicurarsi, in questo caso, che PhpMyAdmin non sia accessibile dall&#8217;esterno (modificando come prima illustrato), onde evitare di esporsi a gravi pericoli (ovvero avere i propri <strong>database mysql</strong> accessibili a tutti).</p>
<img src="http://feeds.feedburner.com/~r/mirkopagliai/~4/VYOBT1XSxxk" height="1" width="1"/>]]></content:encoded><description>Due veloci tips and tricks per chi &amp;#8211; come il sottoscritto &amp;#8211; sviluppa applicazioni web in locale. Apache in ascolto solo in locale Questo impedisce che il nostro server Apache sia raggiungibile dall&amp;#8217;esterno, lan inclusa. In altri termini, sarà raggiungibile solo dall&amp;#8217;host locale, ovvero dalla stessa macchina su cui è in funzione il web server. [...]</description><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.mirkopagliai.it/sviluppo-web-in-locale/feed/</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">0</slash:comments><feedburner:origLink>http://www.mirkopagliai.it/sviluppo-web-in-locale/</feedburner:origLink></item><item><title>Ati &amp; Debian: installazione dei driver fglrx</title><link>http://feedproxy.google.com/~r/mirkopagliai/~3/cKqTdCXOBlQ/</link><category>Unix</category><category>/etc/apt/sources.list</category><category>/etc/X11/xorg.conf</category><category>accelerazione 2D e 3D</category><category>chipset di schede grafiche AMD/ATI</category><category>Debian</category><category>descrizione degli fglrx</category><category>display manager</category><category>driver Ati</category><category>driver Ati debian</category><category>driver Debian</category><category>driver fglrx</category><category>driver open per Ati</category><category>fglrx Debian</category><category>fglrx-control</category><category>fle</category><category>gdm3</category><category>installazione dei driver fglrx su Debian</category><category>installazione fglrx</category><category>kdm</category><category>sistema X Window</category><category>sources.list</category><category>xorg.conf</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Mirko Pagliai</dc:creator><pubDate>Sun, 28 Aug 2011 06:59:48 PDT</pubDate><guid isPermaLink="false">http://www.mirkopagliai.it/?p=2093</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p><img class="alignleft size-thumbnail wp-image-2097" title="Logo Ati" src="http://www.mirkopagliai.it/wp-content/uploads/2011/08/ati-logo-20100118-152818-180x166.jpg" alt="Logo Ati" width="92" height="84" />In rete sono disponibili più guide e procedimenti (vedere le fonti alla fine di questo articolo) per l&#8217;<strong>installazione dei driver fglrx su Debian</strong>, che purtroppo o non sono sufficientemente aggiornate oppure sono troppo dispersive o confusionarie. Provo quindi a scrivere una guida semplice e chiara.</p>
<p>Anzitutto, la <strong>descrizione degli fglrx</strong>, reperita direttamente dal <a href="http://wiki.debian.org/ATIProprietary" target="_blank">Wiki di Debian</a>:</p>
<blockquote><p>fglrx sta per FireGL and Radeon for X, ed è il driver proprietario (non libero) per display reso disponibile da ATI Technologies (ora AMD). Questo driver fornisce accelerazione 2D e 3D per chipset di schede grafiche AMD/ATI.</p></blockquote>
<p>Veniamo velocemente al dunque:<br />
1) aggiungere la componente &#8220;non-free&#8221; al proprio repository principale indicato nel file <em>sources.list</em> (<em>/etc/apt/sources.list</em>). Ad esempio, modificando così (per <em>Debian testing</em>, nel mio caso):</p>
<pre class="brush: bash; light: true; title: ; notranslate">deb http://ftp.it.debian.org/debian/ testing main contrib non-free</pre>
<p>2) aggiornare l&#8217;elenco dei pacchetti e installare i pacchetti necessari tramite:</p>
<pre class="brush: bash; light: true; title: ; notranslate"># aptitude update
# aptitude install linux-headers-2.6-$(uname -r|sed 's,[^-]*-[^-]*-,,') fglrx-driver fglrx-modules-dkms fglrx-glx fglrx-atieventsd</pre>
<p>Il comando installare tutte le dipendenze necessarie. L&#8217;output dovrebbe essere questo:</p>
<pre class="brush: bash; light: true; title: ; notranslate"># aptitude install linux-headers-2.6-$(uname -r|sed 's,[^-]*-[^-]*-,,') fglrx-driver fglrx-modules-dkms fglrx-glx fglrx-atieventsd
I seguenti pacchetti NUOVI (NEW) saranno installati:
fglrx-atieventsd fglrx-driver fglrx-glx fglrx-modules-dkms
glx-alternative-fglrx{a} glx-alternative-mesa{a} glx-diversions{a}
linux-headers-2.6-amd64 linux-headers-amd64{a}
nvidia-installer-cleanup{a}
I seguenti pacchetti sono RACCOMANDATI ma NON verranno installati:
fglrx-glx-ia32
0 pacchetti aggiornati, 10 installati, 0 da rimuovere e 2 non aggiornati.
È necessario prelevare 22,7 MB di archivi. Dopo l'estrazione, verranno occupati 74,0 MB.</pre>
<p>Il pacchetto <em>fglrx-control</em> è (diversamente da come indicato altrove) assolutamente facoltativo ed offre un pannello di controllo utile all&#8217;impostazione di alcune opzioni per il video. Come riporta la stessa descrizione:</p>
<blockquote><p>The control panel shows detailed information on your display adapter and allows you to set dual screen options, adjust gamma correction and set TV out options.</p></blockquote>
<p>3) fermare il <strong>sistema X Window</strong>. È possibile passando a una console virtuale, ovvero premendo contemporaneamente CTRL+ALT+F1. Alternativamente, si può riavviare il sistema in modalità ripristino (ma non è necessario). Fermare quindi il <strong>display manager</strong> in uso dopo essersi autenticati come root. Nel caso di <em>gdm3</em> (per ambiente Gnome):</p>
<pre class="brush: bash; light: true; title: ; notranslate"># /etc/init.d/gdm3 stop</pre>
<p>Nel caso di <em>kdm</em> (per  ambiente Kde):</p>
<pre class="brush: bash; light: true; title: ; notranslate"># /etc/init.d/kdm stop</pre>
<p>4) generare un file <em>xorg.conf</em> (<em>/etc/X11/xorg.conf</em>) ad hoc per la propria scheda Ati:</p>
<pre class="brush: bash; light: true; title: ; notranslate"># aticonfig --initial</pre>
<p>Verificare che nel file in questione, sotto la sezione &#8220;Device&#8221;, alla voce &#8220;Driver&#8221; sia correttamente indicato &#8220;fglrx&#8221;.</p>
<p>5) Riavviare <em>X Window</em> o meglio riavviare il display manager. Nel caso di <em>gdm3</em> (per ambiente Gnome):</p>
<pre class="brush: bash; light: true; title: ; notranslate"># /etc/init.d/gdm3 start</pre>
<p>Nel caso di <em>kdm</em> (per  ambiente Kde):</p>
<pre class="brush: bash; light: true; title: ; notranslate"># /etc/init.d/kdm start</pre>
<p>6) Verificare il corretto funzionamento dei driver e dell&#8217;accelerazione 3D con:</p>
<pre class="brush: bash; light: true; title: ; notranslate">$ fglrxinfo</pre>
<p>e (è necessaria l&#8217;installazione del pacchetto mesa-utils):</p>
<pre class="brush: bash; light: true; title: ; notranslate">$ glxinfo | grep rendering</pre>
<p>L&#8217;output dovrebbe essere:</p>
<pre class="brush: bash; light: true; title: ; notranslate">$ fglrxinfo
display: :0.0  screen: 0
OpenGL vendor string: ATI Technologies Inc.
OpenGL renderer string: ATI Mobility Radeon HD 4650
OpenGL version string: 3.3.11005 Compatibility Profile Context</pre>
<pre class="brush: bash; light: true; title: ; notranslate">$ glxinfo | grep rendering
direct rendering: Yes</pre>
<p>Fonti:<br />
<a href="http://wiki.debian.org/ATIProprietary" target="_blank">http://wiki.debian.org/ATIProprietary</a><br />
<a href="http://guide.debianizzati.org/index.php/Installazione_driver_proprietari_Ati" target="_blank">http://guide.debianizzati.org/index.php/Installazione_driver_proprietari_Ati</a></p>
<p>Per gli interessati ai <strong>driver open per Ati</strong>, fare riferimento a <a href="http://wiki.debian.org/it/AtiHowTo" target="_blank">questa guida</a>.</p>
<img src="http://feeds.feedburner.com/~r/mirkopagliai/~4/cKqTdCXOBlQ" height="1" width="1"/>]]></content:encoded><description>In rete sono disponibili più guide e procedimenti (vedere le fonti alla fine di questo articolo) per l&amp;#8217;installazione dei driver fglrx su Debian, che purtroppo o non sono sufficientemente aggiornate oppure sono troppo dispersive o confusionarie. Provo quindi a scrivere una guida semplice e chiara. Anzitutto, la descrizione degli fglrx, reperita direttamente dal Wiki di [...]</description><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.mirkopagliai.it/ati-debian-installazione-dei-driver-fglrx/feed/</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">0</slash:comments><feedburner:origLink>http://www.mirkopagliai.it/ati-debian-installazione-dei-driver-fglrx/</feedburner:origLink></item><item><title>Sudo senza password</title><link>http://feedproxy.google.com/~r/mirkopagliai/~3/HGjyDZqKIzs/</link><category>Unix</category><category>account di root</category><category>configurazione di sudo</category><category>Debian</category><category>distribuzione GNU/Linux</category><category>GNU/Linux</category><category>Linux</category><category>password di root</category><category>password di sudo</category><category>password in chiaro</category><category>privilegi di root</category><category>script bash</category><category>sicurezza</category><category>sicurezza informatica</category><category>Sudo</category><category>sudo senza password</category><category>utilizzo di sudo</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Mirko Pagliai</dc:creator><pubDate>Mon, 22 Aug 2011 08:20:18 PDT</pubDate><guid isPermaLink="false">http://mirkopagliai.it/?p=796</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p><strong><img class="alignleft size-medium wp-image-803" title="Sudo" src="http://mirkopagliai.it/wp-content/uploads/2010/11/sudo1-300x249.jpg" alt="Sudo" width="220" height="182" />Sudo</strong> (<em>su</em>peruser <em>do</em>) è una manna dal cielo. In estrema sintesi permette a un normale utente di svolgere operazioni assumendo temporaneamente i <strong>privilegi di root</strong>, pur non autenticandosi effettivamente come tale.</p>
<p>I vantaggi di sudo sono indiscutibili. Tra i più importanti: non è necessario condividere la <strong>password di root</strong> con chi necessiti dei privilegi di root; l&#8217;utente deve porre maggiore attenzione per ogni singolo comando che lancia con sudo e (quindi) una maggiore attenzione porta a una sensibile diminuzione di errori dovuti alla disattenzione; l&#8217;<strong>utilizzo di sudo</strong> può essere limitato e limitato sotto molti aspetti, mentre invece l&#8217;<strong>account di root</strong> non ha nessun limite &#8211; ne consegue che se la necessità è quella di utilizzare i privilegi di root in alcuni contesti ben definiti, sudo è conveniente rispetto a un accesso totale come root.</p>
<p>Può succedere che qualcuno abbia la necessità di utilizzare <strong>sudo senza password</strong>, soprattutto scrivendo <strong>script bash</strong> che per svolgere determinati passaggi necessitano appunto dei privilegi di root. Cercando su Google &#8220;sudo senza password&#8221; (senza virgolette) vengono fuori numerosi articoli che consigliano sistematicamente di aggirare il problema così:</p>
<pre class="brush: bash; light: true; title: ; notranslate">echo password | sudo -S comando</pre>
<p><span style="font-size: 10px;">(dove <em>password</em> è la password dell&#8217;utente e <em>comando</em> è il comando da eseguire. La password, scritta in chiaro, viene stampata e semplicemente passata a sudo)</span></p>
<p>Questa è la conseguenza di un fenomeno ormai pericolosamente diffuso e imperante sul web: ridistribuire notizie, informazioni, istruzioni senza sapere esattamente cosa si stia facendo e di cosa si stia parlando. Qualcuno scrive una cazzata (cosa comprensibile) e altri diecimila copia-incollano alla &#8220;zozza maniera&#8221; senza porsi il minimo dubbio su quello che stanno facendo.</p>
<p>Faccio subito due puntualizzazioni fondamentali:</p>
<ol>
<li>aggirare il controllo della <strong>password di sudo</strong> può essere solo una pessima idea. Ognuno di noi è libero di farlo (d&#8217;altronde io stesso lo faccio, la comodità della cosa è innegabile), ma bisognerebbe avere consapevolezza di quello che si sta facendo, delle conseguenze che può portare e soprattutto essere nella situazione di assumersi poi le responsabilità di quella che &#8211; lo ripeto &#8211; può essere solo una pessima idea;</li>
<li>generalmente e in qualsiasi contesto, non bisogna mai salvare la propria <strong>password in chiaro</strong>, per nessun motivo, nemmeno per questioni di comodità come questa. Si mette in grave rischio la <strong>sicurezza informatica</strong> del sistema dove si esegue questa scelta scellerata (il vostro sistema <strong>GNU/Linux</strong>, in questo caso specifico). Se non esistono alternative a questa scelta, allora è meglio lasciar perdere e rassegnarsi al dover inserire (manualmente) la password ogni volta che ci viene richiesta.</li>
</ol>
<p>Si può aggirare il controllo della password di sudo semplicemente modificando il file di <strong>configurazione di sudo</strong> con il comando (come root):</p>
<pre class="brush: bash; light: true; title: ; notranslate">visudo</pre>
<p>In fondo alla configurazione è sufficiente aggiungere qualcosa come:</p>
<pre class="brush: bash; light: true; title: ; notranslate">utente   ALL=NOPASSWD: ALL</pre>
<p><span style="font-size: 10px;">(dove <em>utente</em> è il nome dell&#8217;utente)</span></p>
<p>In questo modo l&#8217;utente specificato è autorizzato a utilizzare sudo senza che gli venga richiesta la password. Nell&#8217;esempio specifico, inoltre, questa autorizzazione è valida per qualsivoglia comando voglia eseguire l&#8217;utente. Sarebbe quindi meglio limitare questa possibilità.</p>
<p>A questo scopo (ma anche per approfondire sufficiente l&#8217;argomento) vi rimando alle pagine del manuale:</p>
<pre class="brush: bash; light: true; title: ; notranslate">man sudo</pre>
<p>E ad un&#8217;ottima guida per Ubuntu (comunque valida per qualsiasi <strong>distribuzione GNU/Linux</strong>, tanto il file di configurazione è sempre quello) che potete trovare <a href="http://wiki.ubuntu-it.org/AmministrazioneSistema/Sudo">qui</a>.</p>
<img src="http://feeds.feedburner.com/~r/mirkopagliai/~4/HGjyDZqKIzs" height="1" width="1"/>]]></content:encoded><description>Sudo (superuser do) è una manna dal cielo. In estrema sintesi permette a un normale utente di svolgere operazioni assumendo temporaneamente i privilegi di root, pur non autenticandosi effettivamente come tale. I vantaggi di sudo sono indiscutibili. Tra i più importanti: non è necessario condividere la password di root con chi necessiti dei privilegi di [...]</description><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.mirkopagliai.it/sudo-senza-password/feed/</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">1</slash:comments><feedburner:origLink>http://www.mirkopagliai.it/sudo-senza-password/</feedburner:origLink></item><item><title>Skype a 64bit: aggiornamenti</title><link>http://feedproxy.google.com/~r/mirkopagliai/~3/15iVyqs6PLc/</link><category>Unix</category><category>/usr/bin/skype64</category><category>Debian</category><category>Debian 64bit</category><category>Debian testing a 64bit</category><category>forzare l'architettura</category><category>installazione di Skype</category><category>pacchetto a 64bit</category><category>Skype</category><category>Skype 2.2.0.35</category><category>Skype 64bit</category><category>skype64</category><category>versione a 64bit</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Mirko Pagliai</dc:creator><pubDate>Fri, 19 Aug 2011 04:37:41 PDT</pubDate><guid isPermaLink="false">http://www.mirkopagliai.it/?p=2081</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p><img class="alignleft size-thumbnail wp-image-483" title="Skype" src="http://www.mirkopagliai.it/wp-content/uploads/2010/10/skype-150x150.jpg" alt="Skype" width="150" height="150" />Ieri ho avuto la necessità di fare un&#8217;installazione pulita di una <strong>Debian testing a 64bit</strong> su un nuovo computer desktop, così oggi sono passato all&#8217;installazione di <strong>Skype a 64bit</strong>. Ho potuto quindi constatare di persona i miglioramenti raggiunti grazie alla disponibilità di un <strong>pacchetto a 64bit</strong> (di cui avevo già parlato <a href="http://www.mirkopagliai.it/skype-2-2/" target="_blank">qui</a>).</p>
<p>Con l&#8217;ultima versione disponibile (in questo momento la <em>2.2.0.35</em>) non è più necessario seguire la complessa <a href="http://www.mirkopagliai.it/skype-a-64bit/" target="_blank">procedura</a> che avevo illustrato lo scorso ottobre. In particolare, adesso:</p>
<ul>
<li>non è più necessario <strong>forzare l&#8217;architettura</strong>, essendo disponibile appunto un pacchetto a 64bit;</li>
<li>non è più necessario installare manualmente le dipendenze mancante, in quanto ora sono vengono tutte installate correttamente;</li>
<li>non è più presente il bug legato alle Qt che impediva la corretta visualizzazione degli avatar dei contatti.</li>
</ul>
<p>La <strong>versione a 64bit</strong> è scaricabile da <a href="http://www.skype.com/go/getskype-linux-deb-64" target="_blank">qui</a>. È sufficiente aprire il <em>.deb</em> con <em>Gdebi</em> e avviare l&#8217;installazione: tutto andrà a buon fine. Non è quindi più necessario &#8211; ripeto &#8211; installare dipendenze mancanti e poi procedere con l&#8217;<strong>installazione di Skype</strong> tramite <em>dpkg</em> per forzare l&#8217;architettura.</p>
<p>Persiste tuttavia un piccolo problema. Lanciando Skype dal terminale, possiamo verificare l&#8217;esistenza di due warning (tutto comunque funzionerà normalmente). Ovvero questo:</p>
<pre class="brush: bash; light: true; title: ; notranslate">Gtk-Message: Failed to load module &quot;canberra-gtk-module&quot;: /usr/lib/gtk-2.0/modules/libcanberra-gtk-module.so: classe ELF errata: ELFCLASS64</pre>
<p>E questo:</p>
<pre class="brush: bash; light: true; title: ; notranslate">(&lt;unknown&gt;:3043): Gtk-WARNING **: /usr/lib/gtk-2.0/2.10.0/engines/libclearlooks.so: classe ELF errata: ELFCLASS64</pre>
<p>Possono essere entrambi risolti con un workaround <a href="http://www.mirkopagliai.it/skype-a-64bit/" target="_blank">già descritto</a>. Create, con i privilegi di root, il file <em>/usr/bin/skype64</em>:</p>
<pre class="brush: bash; light: true; title: ; notranslate">touch /usr/bin/skype64</pre>
<p>Quindi copia-incollate al suo interno quanto segue:</p>
<pre class="brush: bash; title: ; notranslate">#!/bin/bash
export GTK_PATH=/usr/lib32/gtk-2.0
skype</pre>
<p>E infine assegnategli i permessi di esecuzione:</p>
<pre class="brush: bash; light: true; title: ; notranslate">chmod +x /usr/bin/skype64</pre>
<p>A questo punto sarà sufficiente lanciare Skype con il nuovo comando <em>skype64</em>, affinché tutto funzioni correttamente.</p>
<p>Mi raccomando a modificare opportunamente i vari lanciatori, primo fra tutti quello del menù:</p>
<p><a href="http://www.mirkopagliai.it/wp-content/uploads/2011/08/Skype-64bit.jpg"><img class="aligncenter size-large wp-image-2082" title="Skype a 64bit" src="http://www.mirkopagliai.it/wp-content/uploads/2011/08/Skype-64bit-680x553.jpg" alt="Skype a 64bit" width="680" height="553" /></a></p>
<p>E quello delle &#8220;Applicazioni d&#8217;avvio&#8221;, se ne avete impostato l&#8217;avvio automatico:<br />
<a href="http://www.mirkopagliai.it/wp-content/uploads/2011/08/Skype-a-64bitb.jpg"><img class="aligncenter size-full wp-image-2083" title="Skype a 64bit" src="http://www.mirkopagliai.it/wp-content/uploads/2011/08/Skype-a-64bitb.jpg" alt="Skype a 64bit" width="629" height="386" /></a>Buone videochiamate a tutti :-)</p>
<img src="http://feeds.feedburner.com/~r/mirkopagliai/~4/15iVyqs6PLc" height="1" width="1"/>]]></content:encoded><description>Ieri ho avuto la necessità di fare un&amp;#8217;installazione pulita di una Debian testing a 64bit su un nuovo computer desktop, così oggi sono passato all&amp;#8217;installazione di Skype a 64bit. Ho potuto quindi constatare di persona i miglioramenti raggiunti grazie alla disponibilità di un pacchetto a 64bit (di cui avevo già parlato qui). Con l&amp;#8217;ultima versione [...]</description><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.mirkopagliai.it/skype-a-64bit-aggiornamenti/feed/</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">0</slash:comments><feedburner:origLink>http://www.mirkopagliai.it/skype-a-64bit-aggiornamenti/</feedburner:origLink></item><item><title>Se è notte si farà giorno: convegno sulla mafia</title><link>http://feedproxy.google.com/~r/mirkopagliai/~3/nhFkVocsLgc/</link><category>Blog</category><category>Antonio Mazzeo</category><category>convegno su mafia</category><category>convegno su mafia e criminalità organizzata</category><category>Die Brücke</category><category>I 100 passi</category><category>Monica Micolucci</category><category>Pino Masciari</category><category>Riccardo Salvatore</category><category>Salvatore La Battaglia</category><category>Se è notte si farà giorno</category><category>Stefano Barbati</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Mirko Pagliai</dc:creator><pubDate>Wed, 10 Aug 2011 05:49:20 PDT</pubDate><guid isPermaLink="false">http://www.mirkopagliai.it/?p=2074</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p>Venerdì 12 agosto, a partire dalla 19, <strong>convegno su mafia e criminalità organizzata</strong> <em>Se è notte si farà giorno</em>, presso il Polo museale di Santo Spirito di Lanciano.</p>
<p>L&#8217;iniziativa è organizzata da <em>Die Brücke</em> (<a href="http://www.diebrucke.it" target="_blank">www.diebrucke.it</a>) in collaborazione con la <em>Cooperativa sociale onlus Futura</em> (<a href="http://www.futurasociale.it/" target="_blank">www.futurasociale.it</a>) e il patrocinio del comune di Lanciano.</p>
<p>Interverranno <strong>Pino Masciari</strong> (<a href="http://www.pinomasciari.it/" target="_blank">www.pinomasciari.it</a>), <strong>Antonio Mazzeo</strong> (<a href="http://www.antoniomazzeoblog.blogspot.com/" target="_blank">www.antoniomazzeoblog.blogspot.com</a>), Marcello D&#8217;Ovidio, Giovanni Legnini, Michael Lusi, Mirko Pagliai, Stefano Di Bucchianico e Rosalba Di Giuseppe. I lavori saranno coordinati da Maria Rosaria La Morgia.<br />
A margine del convegno, esposizione artistica di <strong>Salvatore La Battaglia</strong> (<a href="http://www.salvatorelabattaglia.com/" target="_blank">www.salvatorelabattaglia.com</a>) e intervento artistico con <strong>Riccardo Salvatore</strong> (attore), <strong>Stefano Barbati</strong> (chitarrista, <a href="http://www.stefanobarbati.com/it/" target="_blank">www.stefanobarbati.com</a>) e <strong>Monica Micolucci</strong> (cantante) che interpreteranno tra musica e parole alcuni passi del film <em>I 100 passi</em>, dedicato alla figura di Peppino Impastato ucciso dalla mafia il 9 maggio 1978.</p>
<p>C&#8217;è anche &#8211; voglio ricordarlo &#8211; la 54° esposizione internazionale d&#8217;arte della biennale di Venezia (<a href="http://www.comune.lanciano.chieti.it:8080/entra/Engine/RAServePG.php/P/51741LAN0100/M/32281LAN0101" target="_blank">informazioni</a>).</p>
<p>Il convegno su Facebook: <a href="http://www.facebook.com/event.php?eid=214453148606417" target="_blank">http://www.facebook.com/event.php?eid=214453148606417</a><br />
Lo spettacolo su Facebook: <a href="http://www.facebook.com/event.php?eid=262791873733542" target="_blank">http://www.facebook.com/event.php?eid=262791873733542</a></p>
<p><a href="http://docs.diebrucke.it/convegno_12-08-2011/flyer.jpg"><img class="aligncenter" title="Se è notte si farà giorno" src="http://docs.diebrucke.it/convegno_12-08-2011/flyer.jpg" alt="Se è notte si farà giorno" width="753" height="730" /></a></p>
<img src="http://feeds.feedburner.com/~r/mirkopagliai/~4/nhFkVocsLgc" height="1" width="1"/>]]></content:encoded><description>Venerdì 12 agosto, a partire dalla 19, convegno su mafia e criminalità organizzata Se è notte si farà giorno, presso il Polo museale di Santo Spirito di Lanciano. L&amp;#8217;iniziativa è organizzata da Die Brücke (www.diebrucke.it) in collaborazione con la Cooperativa sociale onlus Futura (www.futurasociale.it) e il patrocinio del comune di Lanciano. Interverranno Pino Masciari (www.pinomasciari.it), [...]</description><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.mirkopagliai.it/se-e-notte-si-fara-giorno-convegno-sulla-mafia/feed/</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">0</slash:comments><feedburner:origLink>http://www.mirkopagliai.it/se-e-notte-si-fara-giorno-convegno-sulla-mafia/</feedburner:origLink></item><item><title>Se è notte si farà giorno</title><link>http://feedproxy.google.com/~r/mirkopagliai/~3/YutERlVcsT8/</link><category>Senza categoria</category><category>12 agosto</category><category>Antonio Mazzeo</category><category>attività di denuncia</category><category>conferenza sulla criminalità organizzata</category><category>criminalità organizzata e grandi opere</category><category>Die Brücke</category><category>I padrini del Ponte. Affari di mafia sullo stretto di Messina</category><category>Organizzare il coraggio - La nostra vita contro la ’ndrangheta</category><category>personalità appartenenti alla società civile</category><category>Pino Masciari</category><category>ponte sullo Stretto di Messina</category><category>Salvatore La Battaglia</category><category>Se è notte si farà giorno</category><category>sessione di reading</category><category>Stefano Barbati</category><category>testimone di giustizia</category><category>vivere sotto scorta</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Mirko Pagliai</dc:creator><pubDate>Tue, 26 Jul 2011 14:32:55 PDT</pubDate><guid isPermaLink="false">http://www.mirkopagliai.it/?p=2064</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p>Il <strong>12 agosto</strong> <em>Se è notte si farà giorno</em>. Visto che mancano poco più di due settimane, possiamo cominciare a fornire qualche dettaglio circa la <strong>conferenza sulla criminalità organizzata</strong> promossa da <em>Die Brücke</em> e patrocinata dal comune di Lanciano, che l&#8217;ha inserita nel proprio programma di iniziative estive (scaricabile in formato <em>pdf</em> <a href="http://www.lancianocultura.eu/it/images/stories/Opuscolo%20Estate%20%202011.pdf" target="_blank">qui</a>).<br />
Il luogo scelto è la sala convegni del polo museale di Santo Spirito, che ben si presta non solo alla conferenza in oggetto, ma &#8211; grazie allo splendido chiostro &#8211; anche all&#8217;esposizione fotografica dell&#8217;artista lucano <strong>Salvatore La Battaglia</strong> (<a href="http://www.salvatorelabattaglia.com/" target="_blank">sito internet</a>), che farà da cornice all&#8217;iniziativa.</p>
<p>Nell&#8217;intenzione di proporre un argomento forse già da molti conosciuto (ma mai affrontato a sufficienza) sotto un nuovo punto di vista, che permettesse così di offrire maggiore risalto all&#8217;iniziativa nonché di stimolare maggiormente l&#8217;attenzione del pubblico, abbiamo pensato di invitare a presenziare non solo esperti e studiosi del fenomeno (criminalità organizzata e &#8211; più precisamente &#8211; mafia), ma anche e soprattutto <strong>personalità appartenenti alla società civile</strong> che vi sono state direttamente coinvolte e che quindi possano relazionare il pubblico sulle proprie esperienze personali.</p>
<p>A questo scopo, l&#8217;intera conferenza si articolerà principalmente e a partire dal racconto autobiografico di <strong>Pino Masciari</strong> (<a href="http://www.pinomasciari.it" target="_blank">sito personale</a> e <a href="http://it.wikipedia.org/wiki/Pino_Masciari" target="_blank">voce su Wikipedia</a>), imprenditore edile calabrese. Più volte ricattato, vittima di violenze ed estorsioni nonché ostacolato nella sua attività imprenditoriale dalla &#8216;ndrangheta, a partire dagli anni &#8217;90 il sig. Masciari ha svolto un&#8217;intensa <strong>attività di denuncia</strong>, per la quale attualmente è impegnato in qualità di <strong>testimone di giustizia</strong> e costretto a <strong>vivere sotto scorta</strong> (è stato inserito nel <em>Programma di protezione</em> promosso dallo Stato). Insieme alla moglie Marisa, ha recentemente pubblicato il libro autobiografico <em>Organizzare il coraggio &#8211; La nostra vita contro la ’ndrangheta</em> (<a href="http://www.addeditore.it/Organizzare-il-coraggio.html" target="_blank">scheda del libro</a>), a testimonianza proprio della sua storia.<br />
L&#8217;intervento del sig. Masciari in seno alla conferenza calcherà presumibilmente gli argomenti e la struttura presenti nel suo stesso libro.<br />
Insomma, mi sento di poter dire con estrema sicurezza che Pino Masciari ha &#8220;una bella storia da raccontare&#8221;.</p>
<p>Al racconto del sig. Masciari si affiancherà successivamente quello di <strong>Antonio Mazzeo</strong> (<a href="http://antoniomazzeoblog.blogspot.com" target="_blank">blog</a>), giornalista e scrittore siciliano che da anni segue con interesse e professionalità l&#8217;inquietante rapporto tra <strong>criminalità organizzata e grandi opere</strong> del nostro Paese, con particolare attenzione alle infiltrazioni malavitose negli appalti riguardanti i lavori per il <strong>ponte sullo Stretto di Messina</strong>.<br />
Grazie a un continuo e attento studio delle indagini e dei processi promossi e portati avanti dalla magistratura siciliana, il sig. Mazzeo ha recentemente dato una forma alla sua attività di indagine, pubblicando il libro-inchiesta <em>I padrini del Ponte. Affari di mafia sullo stretto di Messina</em> (<a href="http://www.bsicilia.it/i-padrini-del-ponte-affari-di-mafia-sullo-stretto-di-messina.html" target="_blank">scheda del libro</a>).</p>
<p>Ai due (che hanno già confermato la propria partecipazione) verrà affiancata la presenza di istituzioni e politici locali (ci stiamo ancora lavorando&#8230;), presumibilmente di due parlamentari e del Commissario o del Tenente della Guardia di Finanza di Lanciano, se questi vorranno accettare l&#8217;invito che verrà formalizzato nei prossimi giorni. Speriamo anche nella presenza delle associazioni impegnate nella lotte alla mafia. L&#8217;invito sarà esteso anche alla Giunta e al Consiglio comunale di Lanciano, e in particolare inviteremo il Sindaco ad aprire la conferenza con un saluto alla cittadinanza, sicuri della sua presenza.</p>
<p>A margine dell&#8217;iniziativa, oltre all&#8217;esposizione di cui ho già accennato, <strong>Stefano Barbati</strong>, musicista e artista lancianese (<a href="http://www.stefanobarbati.com" target="_blank">sito personale</a>), curerà una <strong>sessione di reading</strong> (&#8220;narrazione orale di opere&#8221;) di poesie e testi sul tema, occupandosi personalmente dell&#8217;accompagnamento musicale.</p>
<p>Inutile dire che durante l&#8217;iniziativa potranno essere acquistati entrambi i libri sopra menzionati. Stiamo anche lavorando a una nostra produzione, che vorrebbe raccogliere i migliori articoli da noi prodotti negli ultimi tre anni di attività del giornale, anche per finanziare l&#8217;iniziativa e soprattutto per far conoscere il nostro impegno anche oltre lo schermo e il web.</p>
<p>Sì, la data scelta non è tra le migliori e non sarà semplice riempire la sala. Qualcuno (molti) preferirà andare al mare o rimanere fuori Lanciano. Ma il programma è ricco, direi &#8220;inedito&#8221; e soprattutto promette di essere originalmente interessante. Si spera che questa volta non ci siano scusanti. Cercate di partecipare&#8230;</p>
<p style="margin-bottom: 0cm;" align="JUSTIFY"><span style="font-family: Verdana,sans-serif;"><span style="font-size: x-small;">la sala convegni del polo museale Santo Spirito di Lanciano</span></span></p>
<img src="http://feeds.feedburner.com/~r/mirkopagliai/~4/YutERlVcsT8" height="1" width="1"/>]]></content:encoded><description>Il 12 agosto Se è notte si farà giorno. Visto che mancano poco più di due settimane, possiamo cominciare a fornire qualche dettaglio circa la conferenza sulla criminalità organizzata promossa da Die Brücke e patrocinata dal comune di Lanciano, che l&amp;#8217;ha inserita nel proprio programma di iniziative estive (scaricabile in formato pdf qui). Il luogo [...]</description><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.mirkopagliai.it/se-e-giorno-si-fara-notte/feed/</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">1</slash:comments><feedburner:origLink>http://www.mirkopagliai.it/se-e-giorno-si-fara-notte/</feedburner:origLink></item><item><title>I segreti della casta</title><link>http://feedproxy.google.com/~r/mirkopagliai/~3/X0KiU-Q9RAc/</link><category>Breviario politico</category><category>collage di informazioni</category><category>i portaborse sono tutti precari</category><category>mandato parlamentare</category><category>notizie che circolano su Facebook</category><category>paragone con Julian Assange</category><category>progetto WikiLeaks</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Mirko Pagliai</dc:creator><pubDate>Mon, 18 Jul 2011 00:50:53 PDT</pubDate><guid isPermaLink="false">http://www.mirkopagliai.it/?p=2058</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p>Se si leggessero più giornali e si offrisse meno credito a tutte le notizie che circolano su <em>Facebook</em>, non si sarebbe potuto fare a meno di notare come &#8211; oltre alle accuse anonime, infondate e non provate &#8211; gli unici elementi attendibili presenti non siano altro che un sapiente frullato, un <strong>collage di informazioni</strong> vecchie già riportate da varie testate negli anni passati. Non c&#8217;è nulla di nuovo o che non si sapesse già, almeno per il tangibile; il resto invece non vale nulla, almeno finché non si riportano nomi e cognomi o si mostrano prove, e sfido io.</p>
<p>Ma questo l&#8217;hanno notato in pochi, visto che in questo Paese nessuno legge più i giornali; tant&#8217;è che &#8211; credo &#8211; la scusa de &#8220;l&#8217;informazione in Italia fa schifo ed è manipolata&#8221;, presentata anche da chi si riconosce nelle file del movimento anti-casta che oggi ha dato ampia pubblicità a questo caso, sia diventata un ottimo alibi per alleggerire il proprio impegno e dare origine a una protesta qualunquista.</p>
<p>Il <strong>paragone con Julian Assange</strong>, oltre ad essere veramente ingrato, è semplicemente da idioti. E sintomo del non aver capito nulla, ma davvero nulla del <strong>progetto WikiLeaks</strong>.</p>
<p>Ma mettiamo che sia tutto vero, che i privilegi documentati (si fa per dire&#8230;) su quella pagina siano reali. Certe volte &#8211; anche con una certa cattiveria &#8211; penso che, fosse così, ci meriteremmo tutto questo. Almeno stando alla facilità con cui &#8220;abbocchiamo&#8221; al primo troll, al primo personaggio in cerca dei suoi cinque minuti di visibilità.<br />
Non vi preoccupate e non state troppo lì a scalpitare, che ai &#8220;signori del palazzo&#8221; tutto questo va benissimo, rientra anzi nelle loro migliori aspettative, visto che rende sterile e assolutamente innocua qualsiasi protesta.</p>
<p>Un&#8217;ultima cosa, e forse la più importante: a Montecitorio <strong>i portaborse sono tutti precari</strong>. E &#8211; cazzo &#8211; ci mancherebbe che non fosse così. Quindi smettetela di protestare per questo.<br />
Il <strong>mandato parlamentare</strong> ha una durata massima di cinque anni. Poi può anche essere rinnovato, come nei più dei casi accade, certo, ma la durata è sempre quella. Ci manca solo che un parlamentare con un mandato di cinque anni assuma relativi portaborse con un contratto trentennale o che scaduto il suo mandato (cioè non essendo stato rieletto) i suoi portaborse restassero lì con le mani in mano, in attesa che venga rieletto al successivo giro di ruota. E chi dovrebbe pagare tutto questo?<br />
Fosse così, immagino l&#8217;ennesima protesta per i cosiddetti &#8220;sprechi della casta&#8221;, che pur senza avere la certezza comprovata di essere rieletti, assumono portaborse a vita e a nome e a spese dello Stato. E si protesterebbe anche qui, no? Allora è solo un &#8220;servire proteste pronte&#8221;, senza nessun senso critico.</p>
<p>Certo, se prima di lanciarsi nell&#8217;ennesima protesta si accendesse il cervello per due minuti e ci si porrebbero un paio di domande, si eviterebbe di dare origine ogni volta a quello che è solo un lagnosismo fastidioso e senza arte né parte.</p>
<img src="http://feeds.feedburner.com/~r/mirkopagliai/~4/X0KiU-Q9RAc" height="1" width="1"/>]]></content:encoded><description>Se si leggessero più giornali e si offrisse meno credito a tutte le notizie che circolano su Facebook, non si sarebbe potuto fare a meno di notare come &amp;#8211; oltre alle accuse anonime, infondate e non provate &amp;#8211; gli unici elementi attendibili presenti non siano altro che un sapiente frullato, un collage di informazioni vecchie [...]</description><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.mirkopagliai.it/i-segreti-della-casta/feed/</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">0</slash:comments><feedburner:origLink>http://www.mirkopagliai.it/i-segreti-della-casta/</feedburner:origLink></item><item><title>Jquery: pagina ad altezza massima</title><link>http://feedproxy.google.com/~r/mirkopagliai/~3/-lwLYeNYTSg/</link><category>Programmazione</category><category>(x)html e css</category><category>altezza minima di #content</category><category>calcolare l'altezza minima</category><category>codice html della pagina</category><category>css</category><category>elementi html</category><category>html e css</category><category>imposti dinamicamente altezza minima</category><category>jQuery</category><category>leggere l'altezza di un elemento</category><category>min-height</category><category>minHeight</category><category>outerHeight()</category><category>pagina html</category><category>proprietà css</category><category>struttura della pagina</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Mirko Pagliai</dc:creator><pubDate>Sat, 16 Jul 2011 07:59:00 PDT</pubDate><guid isPermaLink="false">http://www.mirkopagliai.it/?p=2046</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p><img class="alignleft size-full wp-image-2054" title="Jquery" src="http://www.mirkopagliai.it/wp-content/uploads/2011/07/Jquery.gif" alt="" width="230" height="57" />Chi programma per il web con una certa frequenza avrà notato, sotto più di un aspetto, i limiti imposti da <strong>(x)html e css</strong>, che spesso costringono ad operare pessime scelte stilistiche pur di ottenere il layout desiderato. Senza contare alcuni risultati che, a meno di non utilizzare altri linguaggi, non possono proprio essere raggiunti.</p>
<p>Un esempio su tutti: la <strong>pagina con gli elementi html</strong> può essere più corta della pagina totale mostrata dal browser, nel momento in cui i vari <strong>elementi html</strong> della prima non riescono a coprirne l&#8217;intera altezza della seconda.<br />
Conseguentemente ed immaginando una classica pagina composta da <em>#header</em>, <em>#content</em>, <em>#sidebar</em> (alla sinistra di <em>#content</em>) e <em>#footer</em>, il <em>#footer</em> non apparirà in fondo alla pagina come magari si aspetterebbe un visitatore, bensì in mezzo, lasciando uno spazio vuoto sotto.<br />
Uno schema esplicativo:</p>
<p><a href="http://www.mirkopagliai.it/wp-content/uploads/2011/07/disegno1.jpg"><img class="aligncenter size-full wp-image-2047" title="Disegno1" src="http://www.mirkopagliai.it/wp-content/uploads/2011/07/disegno1.jpg" alt="" width="492" height="390" /></a>Accade perché &#8211; ripeto &#8211; le altezze di <em>#header</em>, <em>#content</em> e <em>#footer</em> (escludiamo <em>#sidebar</em>, essendo in questo caso più bassa di <em>#content</em>), inclusi i margini, se sommate sono pur sempre inferiori all&#8217;altezza totale della pagina mostrata dal browser.<br />
Potete vedere una <strong>pagina html</strong> di esempio <a href="http://docs.mirkopagliai.it/html/problema_altezza_pagina1.html" target="_blank">qui</a>.</p>
<p>Al contrario, l&#8217;effetto desiderato dovrebbe essere questo più o meno questo:</p>
<p><a href="http://www.mirkopagliai.it/wp-content/uploads/2011/07/disegno2.jpg"><img class="aligncenter size-full wp-image-2049" title="Disegno2" src="http://www.mirkopagliai.it/wp-content/uploads/2011/07/disegno2.jpg" alt="" width="534" height="356" /></a></p>
<p>In altri termini, si vorrebbe che l&#8217;altezza di <em>#content</em> (o anche di <em>#sidebar</em>, ma nei più dei casi si preferirà il primo) occupi tutto lo spazio possibile, nel momento in cui è appunto disponibile dello spazio vuoto. Questo problema può essere facilmente risolto avvalendosi di <strong>jquery</strong>, affinché <strong>imposti dinamicamente l&#8217;altezza minima</strong> (proprietà <em>min-height</em>) di <em>#content</em>.<br />
L&#8217;altezza minima può infatti essere correttamente impostata pari alla differenza tra l&#8217;altezza della pagina mostrata dal browser e l&#8217;altezza di <em>#header</em> e <em>#footer</em>, margini, padding e bordi compresi.</p>
<p>In nostro aiuto troviamo tre utili funzioni offerte da jquery:</p>
<ol>
<li><em>css()</em> (<a href="http://api.jquery.com/css/" target="_blank">documentazione</a>), che permette di leggere o di impostare il valore di una <strong>proprietà css</strong>, e quindi nel nostro caso di impostare l&#8217;altezza minima di <em>#content</em>;</li>
<li><em>height()</em> (<a href="http://api.jquery.com/height/" target="_blank">documentazione</a>), che permette di <strong>leggere l&#8217;altezza di un elemento</strong>, e quindi nel nostro caso l&#8217;altezza della pagina mostrata dal browser;</li>
<li><em>outerHeight()</em> (<a href="http://api.jquery.com/outerHeight/" target="_blank">documentazione</a>), che permette di leggere l&#8217;altezza di un elemento, comprensiva di bordi e padding, opzionalmente anche dei margini (accetta come argomento un booleano, se questo è <em>TRUE</em> include anche i margini) e quindi nel nostro caso l&#8217;altezza effettiva di <em>#header</em> e <em>#footer</em>.</li>
</ol>
<p>Quindi (codice parziale!) l&#8217;altezza minima (<em>min-height</em>, che in jquery diventa <em>minHeight</em>) potrebbe essere calcolata con questa equazione:</p>
<pre class="brush: jscript; light: true; title: ; notranslate">$(window).height() - $('#header').outerHeight(true) - $('#footer').outerHeight(true)</pre>
<p>E, in definitiva, il codice sarebbe questo:</p>
<pre class="brush: jscript; title: ; notranslate">&lt;script type=&quot;text/javascript&quot;&gt;
$(&quot;document&quot;).ready(function() {
   $('#content').css('minHeight', $(window).height() - $('#header').outerHeight(true) - $('#footer').outerHeight(true) - 2);
});
&lt;/script&gt;</pre>
<p><span class="small">(in questo caso ho aggiunto un <em>-2</em> per via del bordo, sia superiore che inferiore, di <em>#content</em>, che dobbiamo tenere in conto. Per fare una cosa fatta per bene, piuttosto che indicare il valore del bordo, bisognerebbe leggere anche quello, rendendo così il calcolo completamente dinamico e utile anche a successive modifiche. Ma più avanti vedremo che non abbiamo bisogno del bordo di <em>#content</em>&#8230;)</span></p>
<p>Ovviamente non ci si dimentichi di includere innanzitutto Jquery. All&#8217;interno di <em>head</em> e <span style="text-decoration: underline;">prima</span> del codice per <strong>calcolare l&#8217;altezza minima</strong>:</p>
<pre class="brush: xml; light: true; title: ; notranslate">&lt;script src=&quot;http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;</pre>
<p>Potete vedere il risultato in una <strong>pagina html</strong> di esempio <a href="http://docs.mirkopagliai.it/html/problema_altezza_pagina2.html" target="_blank">qui</a>.<br />
Se però confrontate questo risultato con il secondo schema prima presentato, noterete un&#8217;importante differenza: nello schema c&#8217;è dello spazio vuoto prima di <em>#footer</em>, mentre qui <em>#content</em> occupa tutto lo spazio vuoto. Ma il risultato non poteva che essere questo, visto che siamo andati a intervenire sull&#8217;altezza minima di <em>#content</em>. E non è proprio un granché di risultato, visto che <em>#content</em> ha bordo e sfondo colorato (se non avesse né bordo, né sfondo, come spesso può essere, tutto sommato andrebbe comunque bene così, visto che non si vedrebbe comunque la differenza).</p>
<p>È allora necessaria un&#8217;ulteriore e ultima modifica: bisogna inserire <em>#sidebar</em> e <em>#content</em> all&#8217;interno di un nuovo elemento (<em>div</em>), che sfrutteremo proprio per ottenere il risultato voluto e che chiameremo in questo esempio <em>#container</em>. Se quindi il <strong>codice html della pagina</strong> prima era questo (sintetizzato al massimo):</p>
<pre class="brush: xml; title: ; notranslate">&lt;html&gt;
   &lt;head&gt;
   &lt;!-- qui va jquery e lo script visto precedentemente --&gt;
   &lt;/head&gt;
   &lt;body&gt;
      &lt;div id=&quot;header&quot;&gt;&lt;!-- L'header --&gt;&lt;/div&gt;

      &lt;div id=&quot;sidebar&quot;&gt;&lt;!-- La sidebar --&gt;&lt;/div&gt;
      &lt;div id=&quot;content&quot;&gt;&lt;!-- Il contenuto effettivo della pagina --&gt;&lt;/div&gt;

      &lt;div id=&quot;footer&quot;&gt;&lt;!-- Il footer --&gt;&lt;/div&gt;
   &lt;/body&gt;
&lt;/html&gt;</pre>
<p>Dobbiamo modificarlo per ottenere più o meno questa <strong>struttura della pagina</strong>:</p>
<pre class="brush: xml; title: ; notranslate">&lt;html&gt;
   &lt;head&gt;
   &lt;!-- qui va jquery e lo script visto precedentemente --&gt;
   &lt;/head&gt;
   &lt;body&gt;
      &lt;div id=&quot;header&quot;&gt;&lt;!-- L'header --&gt;&lt;/div&gt;

      &lt;div id=&quot;container&quot;&gt;
         &lt;div id=&quot;sidebar&quot;&gt;&lt;!-- La sidebar --&gt;&lt;/div&gt;
         &lt;div id=&quot;content&quot;&gt;&lt;!-- Il contenuto effettivo della pagina --&gt;&lt;/div&gt;
      &lt;/div&gt;

      &lt;div id=&quot;footer&quot;&gt;&lt;!-- Il footer --&gt;&lt;/div&gt;
   &lt;/body&gt;
&lt;/html&gt;</pre>
<p>E quindi aggiornare il calcolo dell&#8217;altezza minima:</p>
<pre class="brush: jscript; title: ; notranslate">&lt;script type=&quot;text/javascript&quot;&gt;
$(&quot;document&quot;).ready(function() {
   $('#container').css('minHeight', $(window).height() - $('#header').outerHeight(true) - $('#footer').outerHeight(true));
});
&lt;/script&gt;</pre>
<p><span class="small">(notare che abbiamo rimosso il -2 precedentemente aggiunto, visto che <em>#container</em> non ha bordi, essendo funzionale solo a questo trucchetto)</span></p>
<p>Ora il risultato sarà davvero quello desiderato e possiamo vederlo <a href="http://docs.mirkopagliai.it/html/problema_altezza_pagina3.html" target="_blank">qui</a>.</p>
<img src="http://feeds.feedburner.com/~r/mirkopagliai/~4/-lwLYeNYTSg" height="1" width="1"/>]]></content:encoded><description>Chi programma per il web con una certa frequenza avrà notato, sotto più di un aspetto, i limiti imposti da (x)html e css, che spesso costringono ad operare pessime scelte stilistiche pur di ottenere il layout desiderato. Senza contare alcuni risultati che, a meno di non utilizzare altri linguaggi, non possono proprio essere raggiunti. Un [...]</description><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.mirkopagliai.it/jquery-pagina-ad-altezza-massima/feed/</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">0</slash:comments><feedburner:origLink>http://www.mirkopagliai.it/jquery-pagina-ad-altezza-massima/</feedburner:origLink></item><item><title>Symfony: option senza value</title><link>http://feedproxy.google.com/~r/mirkopagliai/~3/ed2PgHeWy6o/</link><category>Programmazione</category><category>attributo disabled</category><category>attributo value</category><category>form con jquery</category><category>html</category><category>jQuery</category><category>menù a tendina</category><category>modificare il form con jquery</category><category>php</category><category>popolare le opzioni</category><category>riscrivere il widget</category><category>sfWidgetFormChoice</category><category>Symfony</category><category>value vuoto</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Mirko Pagliai</dc:creator><pubDate>Fri, 15 Jul 2011 17:11:22 PDT</pubDate><guid isPermaLink="false">http://www.mirkopagliai.it/?p=2012</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p><img class="alignleft size-thumbnail wp-image-2010" title="Symfony" src="http://www.mirkopagliai.it/wp-content/uploads/2011/07/symfony-180x49.gif" alt="Symfony" width="180" height="49" />È diffusa l&#8217;abitudine, quando si crea un <strong>menù a tendina</strong>, di inserire al primo posto un&#8217;opzione cosiddetta &#8220;neutra&#8221;, che magari inviti l&#8217;utente appunto ad operare una scelta (e da non scegliere effettivamente). Più o meno qualcosa del genere:</p>
<pre class="brush: xml; title: ; notranslate">&lt;select name=&quot;mySelect&quot;&gt;
   &lt;option disabled=&quot;disabled&quot;&gt;-- seleziona --&lt;/option&gt;
   &lt;option value=&quot;1&quot;&gt;Prima opzione&lt;/option&gt;
   &lt;option value=&quot;2&quot;&gt;Seconda opzione&lt;/option&gt;
&lt;/select&gt;</pre>
<p>Proprio perché le ultime due opzioni sono &#8220;reali&#8221;, a differenza della prima hanno un valore espresso tramite l&#8217;attributo <em>value</em>. La prima ha inoltre l&#8217;attributo <em>disabled</em> (opzionale), utile per disabilitare appunto l&#8217;opzione.</p>
<p>Se non si conosce questo attributo, si consulti la <a href="http://www.w3schools.com/TAGS/att_button_disabled.asp" target="_blank">documentazione</a>, da quale:</p>
<blockquote><p>The disabled attribute specifies that a button should be disabled.<br />
A disabled button is unusable and un-clickable.<br />
The disabled attribute can be set to keep a user from clicking on the button until some other condition has been met (like selecting a checkbox, etc.). Then, a JavaScript is required to remove the disabled value, and make the button usable.</p></blockquote>
<p>In <em>Symfony</em> sembra che non ci sia nulla per fare tutto questo: non è possibile non impostare l&#8217;attributo <em>value</em>, come non è possibile aggiungere l&#8217;attributo <em>disabled</em>. Value è l&#8217;unico attributo impostabile e per giunta obbligatorio (ci sono alternative, invece, per altri widget, come ad esempio <em>sfWidgetFormDoctrineChoice</em> o <em>sfWidgetFormPropelChoice</em>).<br />
Il motivo è semplice: il widget che genera un menù a tendina, <em>sfWidgetFormChoice</em> (<a href="http://www.symfony-project.org/api/1_4/sfWidgetFormChoice" target="_blank">documentazione</a>) accetta un array per <strong>popolare le opzioni</strong>, dove le chiavi dell&#8217;array saranno gli attributi <em>value</em> delle opzioni e i valori dell&#8217;array le loro relative etichette.</p>
<p>Il problema è che <em>Php</em> non può &#8211; per ovvi motivi &#8211; accettare valori per un array senza che tutti abbiano una relativa chiave, che altrimenti verrà sempre e comunque creata. Di conseguenza, il <em>value</em> delle opzioni, popolato a partire dalle chiavi, esisterà sempre, anche se magari è vuoto.</p>
<p>Ad esempio, impostando una chiave vuota:</p>
<pre class="brush: php; light: true; title: ; notranslate">$form-&gt;setWidget(new sfWidgetFormChoice(array('choices' =&gt; array('' =&gt; '-- seleziona --', '1' =&gt; 'Prima opzione', '2' =&gt; 'Seconda opzione'))));</pre>
<p>Il codice generato sarà il seguente (<em>value</em> è vuoto, ma esiste comunque, e non è la stessa cosa):</p>
<pre class="brush: xml; title: ; notranslate">&lt;select name=&quot;mySelect&quot;&gt;
   &lt;option value=&quot;&quot;&gt;-- seleziona --&lt;/option&gt;
   &lt;option value=&quot;1&quot;&gt;Prima opzione&lt;/option&gt;
   &lt;option value=&quot;2&quot;&gt;Seconda opzione&lt;/option&gt;
&lt;/select&gt;</pre>
<p>Mentre invece, non indicando nessuna chiave per il primo elemento:</p>
<pre class="brush: php; light: true; title: ; notranslate">$form-&gt;setWidget(new sfWidgetFormChoice(array('choices' =&gt; array('-- seleziona --', '1' =&gt; 'Prima opzione', '2' =&gt; 'Seconda opzione'))));</pre>
<p><em>Php</em>, automaticamente, gli assegnerà la chiave 0 e quindi il codice generato sarà il seguente:</p>
<pre class="brush: xml; title: ; notranslate">&lt;select name=&quot;mySelect&quot;&gt;
   &lt;option value=&quot;&quot;&gt;-- seleziona --&lt;/option&gt;
   &lt;option value=&quot;1&quot;&gt;Prima opzione&lt;/option&gt;
   &lt;option value=&quot;2&quot;&gt;Seconda opzione&lt;/option&gt;
&lt;/select&gt;</pre>
<p>Infine, in nessun caso è possibile impostare l&#8217;attributo <em>disabled</em>.</p>
<p>Le soluzioni sono allora due:</p>
<ol>
<li><strong>riscrivere il widget</strong> (<em>sfWidgetFormChoice.class.php</em>, <em>sfWidgetFormChoiceBase.class.php</em> e <em>sfWidgetFormSelect.class.php</em>, tutti in <em>/lib/widget</em>);</li>
<li><strong>modificare il form con jquery</strong>.</li>
</ol>
<p>Ho scelto la seconda strada (buona fortuna a quelli che dovessero scegliere la prima&#8230;), nonostante non possa nascondere che l&#8217;altra sarebbe più brillante e pulita, sebbene molto più complessa.<br />
In questo caso, il codice è breve e facilmente comprensibile: è sufficiente selezionare tutti gli <em>option</em> con <em>value</em> vuoto ma esistente (evitiamo invece di lavorare sugli 0 e nel widget sarà sempre meglio usare una chiave vuota, semmai poi dovessimo avere realmente bisogno di un <em>option</em> con <em>value</em> 0), rimuovere completamente l&#8217;attributo <em>value</em> e (opzionalmente) aggiungere l&#8217;attributo <em>disabled</em> con valore <em>disabled</em>:</p>
<pre class="brush: jscript; title: ; notranslate">$(&quot;document&quot;).ready(function() {
   $('option[value=&quot;&quot;]').removeAttr(&quot;value&quot;).attr(&quot;disabled&quot;, &quot;disabled&quot;);
});</pre>
<img src="http://feeds.feedburner.com/~r/mirkopagliai/~4/ed2PgHeWy6o" height="1" width="1"/>]]></content:encoded><description>È diffusa l&amp;#8217;abitudine, quando si crea un menù a tendina, di inserire al primo posto un&amp;#8217;opzione cosiddetta &amp;#8220;neutra&amp;#8221;, che magari inviti l&amp;#8217;utente appunto ad operare una scelta (e da non scegliere effettivamente). Più o meno qualcosa del genere: Proprio perché le ultime due opzioni sono &amp;#8220;reali&amp;#8221;, a differenza della prima hanno un valore espresso tramite [...]</description><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.mirkopagliai.it/symfony-option-senza-value/feed/</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">0</slash:comments><feedburner:origLink>http://www.mirkopagliai.it/symfony-option-senza-value/</feedburner:origLink></item></channel></rss>

