Ti sei mai preoccupato di Google Maps e di quanto quell’app riesca a vedere della tua casa, della tua auto, dei tuoi vicini e… forse… di te stesso?!?
Beh, forse hai ragione! Dai un’occhiata a questo video dei the vacationeers…
;D
Ti sei mai preoccupato di Google Maps e di quanto quell’app riesca a vedere della tua casa, della tua auto, dei tuoi vicini e… forse… di te stesso?!?
Beh, forse hai ragione! Dai un’occhiata a questo video dei the vacationeers…
;D
3 semplici regole:
NON lasciare il caricatore collegato quando la batteria è carica, neanche quando vai a dormire.
LASCIA che si scarichi completamente: quando lo usi aspetta che arrivi allo 0%, quando vai a dormire lascialo lì; quando ti sveglierai e lo aprirai, un bel resume da suspend to disk ti darà il buongiorno. OSX FTW.
Monitorala e fai vedere i contatori di performance di OSX ai tuoi amici (immagini per gentile concessione di CoconutBattery.app e System Profiler.app)
urllib2 non esistono più — urllib2 è stato incorporato in urllib.request in Python 3.
Mentre installavo allegramente i prerequisiti per compilare un’applicazione su
Solaris 11, ho apprezzato il fatto di
trovare Mercurial già installato nel sistema
base… tranne per un GROSSO problema: la digest authentication era rotta. Ho
fatto un tcpdump del traffico scambiato tra il client Mercurial e il server
CGI e ho visto che non veniva inviato nessun header Authorization, e
ovviamente il server si rifiutava di servire il repository hg.
Prima di reinstallare Python, magari da sorgente e sostituendo l’installazione di default oppure tenendo affiancate due versioni diverse, con le conseguenti seccature e sporcizia nel sistema, ho provato un patch davvero minuscolo a urllib2.py che… con mio divertimento, ha risolto il problema:
--- urllib2.py~ Fri Jan 25 02:35:59 2008
+++ urllib2.py Fri Jan 25 03:27:52 2008
@@ -815,7 +815,7 @@
auth_val = 'Digest %s' % auth
if req.headers.get(self.auth_header, None) == auth_val:
return None
- req.add_unredirected_header(self.auth_header, auth_val)
+ req.add_header(self.auth_header, auth_val)
resp = self.parent.open(req)
return resp
Non sono un ca**o di esperto Python (ma il linguaggio è interessante), quindi
non chiedetemi PERCHÉ funziona: ho semplicemente seguito il commento di
add_header che diceva “questo metodo è utile per aggiungere header di
autenticazione” e ho sostituito il metodo unredirected_header con il primo.
Non ho proprio idea del perché con urllib2 di Python2.5 “tutto funziona” anche
con quel metodo; qualcosa deve essere rotto da qualche altra parte. Un diff
tra le due urllib non mi ha dato niente, dovrei davvero imparare Python prima
o poi.
config/locales/*.yml con la gem i18n. I messaggi di errore di ActiveRecord, i nomi dei campi e tutte le stringhe dell’interfaccia sono gestiti nativamente — niente plugin, niente monkey-patching.
AGGIORNAMENTO: non ti serve questo codice, perché a partire dalla versione 2.2 di Rails il supporto alla localizzazione è integrato.
Oggi ho dovuto rispondere a una delle domande su cui ogni sviluppatore Rails non anglofono prima o poi inciampa… come localizzare i messaggi di errore di AR per mostrarli in modo decente a un cliente che non parla inglese ;).
Prima di tutto, grazie all’eccellente plugin gibberish di defunkt e al modo in cui gli errori di validazione di AR sono esposti, il compito è stato portato a termine in modo semplice e pulito, senza mettere troppo le mani negli internals di AR.
Ho cominciato traducendo ogni messaggio di errore predefinito di AR, con questo
file di traduzione in lang/it.yml:
# Active Record errors
#
ar_accepted: "deve essere accettato"
ar_not_a_number: "non è un numero"
ar_blank: "è un campo obbligatorio"
ar_empty: "è un campo obbligatorio"
ar_inclusion: "non è nella lista dei valori validi"
ar_too_long: "è troppo lungo (massimo %d caratteri)"
ar_exclusion: "è riservato"
ar_too_short: "è troppo corto (minimo %d caratteri)"
ar_invalid: "non è valido"
ar_wrong_length: "è errato, dovrebbe essere di %d caratteri"
ar_confirmation: "non corrisponde"
ar_taken: "esiste già"
# This one is not a default key, but I use it in my validations
ar_greater_zero: "deve essere maggiore di zero"
e quattro righe in config/environment.rb:
com.apple.WebKit.Networking in un formato blob binario — il vecchio Cache.db non esiste più.
Cinque minuti fa ho sovrascritto il nuovissimo e fiammante foglio di stile CSS che implementa la combinazione di colori attuale, perché volevo ripristinare quello originale e metterlo in un nuovo tema per questo sito, così che chi apprezzava il vecchio tema potesse continuare a usarlo. Ma, come il più principiante degli amministratori di sistema, ho decompresso i file originali dall’archivio di backup SOPRA quelli attuali…
Safari in soccorso! Ogni elemento nella cache di Safari è memorizzato in un
database SQLite3 che si trova in ~/Library/Caches/com.apple.Safari,
andiamo a vedere com’è strutturato:
13:54:42 vjt@voyager:~/Library/Caches/com.apple.Safari$ sqlite3 Cache.db
SQLite version 3.5.1
Enter ".help" for instructions
sqlite> .tables
cfurl_cache_blob_data cfurl_cache_schema_version
cfurl_cache_response
sqlite> .schema cfurl_cache_response
CREATE TABLE cfurl_cache_response(
entry_ID INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE,
version INTEGER,
hash_value INTEGER,
storage_policy INTEGER,
request_key TEXT UNIQUE,
time_stamp NOT NULL DEFAULT CURRENT_TIMESTAMP);
sqlite> .schema cfurl_cache_blob_data
CREATE TABLE cfurl_cache_blob_data(
entry_ID INTEGER PRIMARY KEY,
response_object BLOB,
request_object BLOB,
receiver_data BLOB,
proto_props BLOB,
user_info BLOB);
sqlite> select * from cfurl_cache_response limit 3;
1|0|1897220634|0|http://..../|2008-01-19 11:10:33
2|0|-662909776|0|http://..../|2008-01-19 11:10:33
Wow. Impressionante. Ecco perché adoro i prodotti Apple: sono così ben strutturati che puoi liberamente ispezionarli e usare le loro risorse per qualsiasi compito imprevisto tu debba completare… anche per rimediare ai tuoi stessi errori ;). Ed è anche stimolante, perché devi rimboccarti le maniche e trovare la soluzione esplorando un prodotto software costruito splendidamente.
05:01:24 vjt@voyager:~/Antani/trunk$ replace(){ sed -e "s|$1|$2|g"
< $3 > ${3}X; mv ${3}X $3; }; egrep -r 'XP_[A-Z_]+[[:space:]]+-?[[
:digit:]]' Headers |ruby -ne "f,m=scan(/(.+):.+(XP_[\w_]+)/).first
;puts '%s %s %s' % [ f, m, 'kXP'<<m.scan(/(_[A-Z])([A-Z]+)/).map {
|a,b| a[1..1]<<b. downcase }.join ]" | while read hdr from to; do
replace $from $to $hdr; for src in `grep -rl $from Sources`; do
replace $from $to $src; done; done
SCO_SV os507 3.2 5.0.7 i386Se hai UDK, lancia:
$ CFLAGS='-I/usr/local/include -belf' LDFLAGS='-L/usr/local/lib' \
./configure --with-threads --with-pth --disable-shared --disable-ipv6
/usr/local/include a BASECFLAGS nel Makefile (autocrap fa schifo).Modules/ctypes/_ctypes_test.c mettendo un #ifdef HAVE_LONG_LONG attorno alle funzioni che usano PY_LONG_LONG (suggerimenti: righe 384 e 318).Objects/longobject.c e alla riga 817 metti la macro IS_LITTLE_ENDIAN prima del blocco #ifdef HAVE_LONG_LONG, e metti _PyLong_FromSsize_t e _PyLong_FromSize_t dopo il blocco HAVE_LONG_LONG.Se hai GCC, lancia:
$ CFLAGS='-I/usr/local/include' LDFLAGS='-L/usr/local/lib' \
./configure --with-threads --with-pth --disable-shared --disable-ipv6
Sia con UDK che con GCC:
pyconfig.h e commenta il define di socklen_tModules/socketmodule.c e alla riga 226 aggiungi || defined(SCO5) per definire INET_ADDRSTRLEN.make (o gmake se preferisci)_curses.so, _curses_panel.so, _locale.so e readline.so se usi GCC, e anche senza pyexpat, elementtree e sha512 se usi UDK. __ ____ __ __ ____ __
\ \ / / \/ | \/ \ \ / /
\ V /| |\/| | |\/| |\ \ / /
| | | | | | | | | \ V /_
|_| |_| |_|_| |_| \_/(_)
[vjt@os507 ~/Python-2.5.1-vjt] $ python
Python 2.5.1 (r251:31337, Sep 13 2007, 22:40:33)
[GCC 4.2.1] on sco_sv3
Type "help", "copyright", "credits" or "license" for more information.
>>> import socket
>>>
[vjt@os507 ~] $ hg clone http://code.wuhrer.thc/hg/Antani
destination directory: Antani
http authorization required
!! YAY! :D
Symbol.all_symbols non include più questo easter egg — è stato rimosso da un pezzo. La risposta alla vita, all’universo e a tutto quanto resta 42.
22:33:24 vjt@voyager:~$ irb19 -f
irb(main):001:0> Symbol.all_symbols.grep /^the/
=> [:the_answer_to_life_the_universe_and_everything]
sfortunatamente, la risposta non è 42:
irb(main):002:0> _.first.object_id
=> 5048
:\
Grazie per questa strana scoperta, nextie! :D
Un romanzo davvero, davvero, davvero NERD di Cory Doctorow che racconta di un gruppo di sysadmin che lottano per tenere in piedi la cara vecchia Rete dopo un evento catastrofico che ha messo il mondo intero in ginocchio. Combattono con scorte limitate di energia e cibo e comunicano via Usenet… usando la buona vecchia gerarchia alt.
Voto: 10+ per la cosa più geek che abbia mai letto. Vale davvero l’ora necessaria per leggerlo tutto.
Ingredienti: Debian, Netatalk, Avahi, un po’ di trucchetti.
Ricompila Netatalk con il supporto SSL.
Puoi tranquillamente ignorare la roba del “.passwd”, perché afpd usa PAM per l’autenticazione degli utenti.
Suggerimento: Disabilita i gestori del protocollo atalk in /etc/default/netatalk per un avvio più veloce:
# Set which daemons to run (papd is dependent upon atalkd):
ATALKD_RUN=no # appletalk protocol
PAPD_RUN=no # printer sharing daemon (printers are soooo '90s)
CNID_METAD_RUN=yes # don't remember but is needed, rtfm!
AFPD_RUN=yes # you will always need this
TIMELORD_RUN=no # my time lord's name is <a href="http://openntpd.org">openntpd</a>
A2BOOT_RUN=no # boot? nah! :P
# path name perms charset
/some/where/tm "Time Machine" allow:vjt volcharset:"UTF8"
in /etc/netatalk/AppleVolumes.default.
Scarica il file di servizio avahi, mettilo in /etc/avahi/services e ricarica avahi con /etc/init.d/avahi-daemon reload (scusate, i link originali sono rotti).
Ti servono due file sulla condivisione di rete AFP: .com.apple.timemachine.supported e un dot-file che prende il nome dal MAC address della tua en0. Per crearlo, il modo più semplice è collegare un disco USB/Firewire, rinominarlo con il nome della condivisione di rete desiderata (specificata nel file AppleVolumes) e abilitare Time Machine su di esso.