joe di castrohttp://joedicastro.com2013-12-25T10:20:00+01:00La Democratizacion de la Educacion2013-12-25T10:20:00+01:00joe di castrohttp://joedicastro.com/la-democratizacion-de-la-educacion.html<p>Permitidme que os hable un poco de mí historia académica antes de entrar en
materia. Podéis saltaros esta parte biográfica (mis batallitas) e ir
directamente al siguiente punto.</p>
<p>Normalmente la adolescencia es una edad difícil en la que nos encontramos
envueltos en un mar de dudas y conflictos entre el niño que eramos y el adulto
que queremos ser. Es entonces cuando comienza el difícil dilema de plantearnos
que vamos a hacer con nuestra vida. Delicada cuestión que muchos ni siquiera
llegan a resolver, se encuentran con que la vida les impone una respuesta.</p>
<p>Ya en los dos primeros años de <a href="https://es.wikipedia.org/wiki/BUP">BUP</a> (si, uno ya no está en la veintena)
mis objetivos se dividían entre Arquitectura y Medicina, dos áreas que me
apasionaban y aún lo hacen hoy en día. Al mismo tiempo mi hobby era la
informática, un hobby singular, en cuanto a que solo tenía a mi disposición un
<a href="http://es.wikipedia.org/wiki/Amstrad_CPC_464">Amstrad CPC 464</a> que solo empleaba para jugar (y muy poco). Aparte de
aquello solo había aprendido cuatro tonterías en <a href="https://es.wikipedia.org/wiki/BASIC">BASIC</a> en el ultimo
curso de la <a href="https://es.wikipedia.org/wiki/EGB">EGB</a> en un <a href="https://es.wikipedia.org/wiki/Sinclair_ZX_Spectrum">Sinclair ZX Spectrum</a> y en un <a href="https://es.wikipedia.org/wiki/MSX">MSX</a> de
Philips. Y sin embargo, tenia acceso a varias revistas de Informática mensuales
que devoraba desde la primera a la ultima página, soñando con tener algún día
uno de aquellos PCs (<a href="https://es.wikipedia.org/wiki/Intel_80386">386</a>) para poder hacer mis primeros pinitos en aquel
"mágico" mundo.</p>
<p>Ya a mediados de 3º de BUP comencé a tener claro que la Informática era para mi
algo más que un hobby, quería dedicarme a ello y quería hacerlo ya. Así que
decidí que lo mejor para mi era matricularme en <a href="https://es.wikipedia.org/wiki/Formaci%C3%B3n_profesional_en_Espa%C3%B1a">FP II </a> de Informática de
Gestión y después de dos años, encontrar trabajo en lo que me gustaba. Vengo de
una familia humilde y ni me apetecía pasarme tres años en la facultad a costa de
mis padres, ni aquello que enseñaban me atraía demasiado. En aquellos tiempos
para mi la informática era algo inminentemente practico, me gustaban los PCs y
quería cacharrear con ellos.</p>
<p>Fui admitido en aquel curso, pero la vida me deparaba una sorpresa, había
suspendido Inglés de tercero. No me lo esperaba, aún hoy no sé como suspendí
aquella asignatura. Me vi entonces en el dilema de estudiar <a href="https://es.wikipedia.org/wiki/Curso_de_Orientaci%C3%B3n_Universitaria">COU</a> y
recuperar aquella asignatura de tercero, mis planes se habían torcido. No me
sentó nada bien aquello, estaba en una edad difícil, en un instituto singular de
un barrio obrero y conflictivo. Me tome aquel año como sabático, sabía lo que
quería y no era aquello. Me pase el curso entre billares y futbolines. Al final
de año solicite plaza en los dos cursos disponibles de FP II que me interesaban,
Gestión y Sistemas (Equipos Informáticos). En Gestión me rechazaron (aunque me
colé entre los suplentes), había +800 solicitudes para 24 plazas y yo la había
rechazado el año anterior, pero conseguí ser admitido en Sistemas. El final de
curso en COU no pudo ser más significativo: Sobresaliente en Ingles de COU y de
3º, Notable en Gallego y Filosofía y No Presentado en el resto. Era mi forma de
rebelarme contra el sistema visto desde el punto de vista estúpido e inmaduro de
un tardo-adolescente, podía, pero no quise. También era la forma de evitar la
presión familiar para presentarme a la Selectividad y una carrera que no quería
hacer.</p>
<p>La vida me deparaba otra sorpresa más, los estudios de FP II de Sistemas duraban
tres y no dos años como creía (Gestion solo duraba dos años). Y gracias a las
asignaturas convalidadas por BUP, me encontraba con un horario con muy pocas
clases y pocas asignaturas. El nivel de las asignaturas comunes (la mayoría
convalidadas) era sorprendentemente muy inferior al de BUP y COU. Y lo más
sorprendente aún es que las asignaturas técnicas de Informática tenían un nivel
muy inferior a lo que me esperaba, sin haber tenido acceso a un PC, me
encontraba con que prácticamente ya conocía todo aquello. En segundo año me
regalaron mi primer PC (un 486 DX2 a 66 MHz) y en pocos meses aprendería
prácticamente todo lo que tendría que saber para el resto de aquel año y el
siguiente por mi cuenta. Solo cuatro asignaturas en los tres años me aportaron
conocimientos que no tenia: Electrónica, Comunicaciones, Arquitectura de
ordenadores y Programación. La experiencia personal fue fantástica gracias más a
mis compañeros y profesores que a las materias. En el entorno familiar y de
amigos se me animaba a continuar después con la carrera, pero yo en mi interior
me sentía estafado, como si hubiera perdido tres años por algo que podría haber
aprendido en medio año.</p>
<p>Paralelamente yo estaba haciendo practicas en un empresa de Informática, donde
pasaría casi dos años de mi vida sin contrato y sin apenas cobrar, solo por el
placer de aprender y coger experiencia. Fue una de las mejores épocas de mi
vida y con aquella gente fantástica aprendí las bases de mi oficio.</p>
<p>Luego con el paso de los años acabe trabajando en varias empresas desempeñando
diferentes puestos y responsabilidades, siempre dentro del área de Sistemas.
Solo ampliaría mi formación académica durante estos años con un curso de Fibra
Óptica (cuando lo realice apenas había empresas de cable en España) y un curso
de Gestión de Empresas.</p>
<p>Lo que nunca he abandonado es al autoaprendizaje, simplemente porque mi segunda
mayor pasión después de esta profesión es aprender algo nuevo cada día. Y mi
curiosidad se ha extendido a muchas áreas, como la música, la fotografía, el
diseño, la literatura, etc con mayor o menor fortuna.</p>
<h2 id="auto-aprendizaje_vs_aprendizaje_guiado">Auto-Aprendizaje vs Aprendizaje Guiado</h2>
<p>Durante todos estos años lo he hecho lo mejor que he podido, aprendiendo sobre
la marcha y rellenando las numerosas lagunas que mi deficiente educación oficial
jamas cubrieron, del mejor modo que podía, aprendiendo por mi cuenta. No lo
he debido hacer del todo mal, cuando algunos profesionales que si habían cursado
alguna carrera Informática se han sorprendido del nivel de conocimientos de un
"simple FP II", del mismo modo que yo me he sorprendido del pobre nivel de
conocimientos de más de un "Licenciado".</p>
<p>Pero si es cierto que tengo bastantes lagunas, sobre todo en las bases teóricas
que se dan en algunas asignaturas de las carreras. Donde siempre me he sentido
limitado es en el terreno de la programación, donde después de acabar FP II,
apenas había vuelto a tocar y los conocimientos adquiridos era muy básicos
(Pascal y Ensamblador a nivel de conceptos básicos).</p>
<p>Pero desde hace unos años me he ido interesando poco a poco y cada vez más en la
programación, empleando Python como punto de partida y la auto-formación en mis
ratos libres como medio. He llegado al punto en que no me importaría desarrollar
el resto de mi carrera como Programador en lugar de Administrador de Sistemas. Y
donde mi auto-confianza en este campo se va incrementando gradualmente.</p>
<p>Pero el auto-aprendizaje aún siendo muy gratificante, por el hecho de que
aprendes básicamente lo que quieres y las recompensas son en muchas ocasiones
inmediatas, no deja de ser un camino plagado de trampas:</p>
<ul>
<li>
<p><strong>Carencias Autoimpuestas</strong> Aprender por tu cuenta lo que te gusta implica
muchas veces evitar aprender las partes que no te interesan, te aburren o
directamente no soportas. Esto te crea lagunas importantes en aspectos muchas
veces básicos y necesarios, y cuando no elementales para "unir los puntos"
entre unos conocimientos y otros.</p>
</li>
<li>
<p><strong>Ignorancia de lo ignorado</strong> El mismo hecho de emplear recursos dispersos y
muchas veces no ordenados para aprender algo que necesitas ya (o que te llama
la atención en ese momento) ocasiona que muchas veces ignores completamente
siquiera la existencia de materias completas que son básicas para "tejer la
red de conocimientos" que da sentido al resto.</p>
</li>
<li>
<p><strong>Conocimientos no asimilados</strong> Aún leyendo algunos de los mejores libros
sobre la materia, no siempre es suficiente para la completa comprensión de la
misma. La practica es necesaria para asimilar y afianzar muchos conceptos y
muchas veces es difícil de suplir la explicación oral de alguien que si
comprende la materia.</p>
</li>
<li>
<p><strong>Calidad deficiente</strong> No siempre se aprende correctamente, a veces aprendemos
algo a través de recursos pobres, incompletos o deficientes. No es menos
frecuente asimilar "malas practicas" o "vicios" a consecuencia de esto. Esto
nos lleva muchas a veces a tener que "re-aprender" lo que creímos que ya
sabíamos. A veces este tipo de aprendizaje nos dota de una falsa seguridad en
nosotros mismos que nos convierte en el peor tipo de profesional posible: el
"manazas inconsciente", un peligroso "coctel" cargado de buenas intenciones
que puede "armarla" en cualquier momento.</p>
</li>
<li>
<p><strong>Pesima gestión del tiempo</strong> La innumerable cantidad de recursos que están a
disposición de cualquiera gracias a Internet: libros, manuales, how-tos,
vídeos, charlas, foros, sitios de preguntas y respuestas, etc puede ser
apabullante pero no ayudarnos, si no entorpecernos. Es necesario mucha
disciplina y orden para no perder el tiempo saltando entre esto y lo otro,
asimilando a veces muy pocos conocimientos en función al tiempo empleado. La
procrastinación es nuestro enemigo y nada puede sustituir a un camino marcado
de antemano por alguien con conocimientos en la materia.</p>
</li>
<li>
<p><strong>El efecto "Isla"</strong> El "no poder interactuar con otros alumnos/profesor"
reduce en cierta parte las posibilidades de reforzar el aprendizaje, resolver
dudas de una forma más pro-activa y respaldar la confianza en lo aprendido. Y
no menos importante, darte una idea de tu nivel de comprensión y conocimientos
en comparación a otros.</p>
</li>
<li>
<p><strong>Carencia de titulación</strong> No menos importante para algunos, es que no
disponemos de un titulo que respalde los conocimientos adquiridos.</p>
</li>
</ul>
<p>Pero a pesar de todos inconvenientes, el auto-aprendizaje es esencial hoy en
día, y en muchas profesiones como la mía, no hacerlo se convierte en un suicidio
profesional. Siendo sincero, yo jamás contrataría a alguien que no tenga
espíritu de autodidacta, en realidad, jamás contrataría a nadie que no tenga
curiosidad, que no se haga preguntas. Personalmente pienso que el día que dejas
de tener curiosidad por lo que te rodea, te conviertes en un "espectador". De
hecho creo que la curiosidad, el hacerse preguntas, es uno de los indicadores
más evidentes de inteligencia. Aquel que se mueve, no importa lo lento que sea,
siempre llegará más lejos que el que se queda quieto.</p>
<h2 id="formarse_a_trav+s_de_la_gamificaci+n">Formarse a través de la Gamificación</h2>
<p>De unos años a esta parte han empezado a surgir en la red ciertos sitios que
persiguen la auto-formación a través de la consecución de pequeñas recompensas,
lo que se conoce como <a href="https://es.wikipedia.org/wiki/Gamificaci%C3%B3n">Gamificación</a>.</p>
<p>Bajo esta idea han surgido múltiples proyectos para aprender diversas materias,
desde un idioma hasta programar, pasando por las matemáticas. Hay bastantes
proyectos vigentes y siguen apareciendo nuevas ideas constantemente. Algunos
ejemplos de este tipo de proyectos son: <a href="http://www.codecademy.com/">Codecademy</a>,
<a href="http://www.duolingo.com/">DuoLingo</a>, <a href="https://www.khanacademy.org/">Khan Academy</a>, <a href="http://teamtreehouse.com/">treehouse</a>, <a href="http://www.codeavengers.com/">Code Avengers</a>,
<a href="http://www.programmr.com/">Programmr</a>, <a href="https://www.codeschool.com/">code school</a>, <a href="http://www.checkio.org">CheckiO</a>, etc</p>
<p>Este tipo de sitos están enfocados principalmente a iniciar a principiantes en
una materia y emplear las técnicas de gamificación para alentar el aprendizaje,
evitar la desmotivación y que se abandone el mismo. He participado en alguno de
estos sitios y si bien la mecánica es atractiva, no han cumplido con mis
expectativas en cuanto a nivel de conocimientos y la dinámica de los mismos. Un
par de ejemplos:</p>
<ul>
<li>
<p><strong>Codecademy</strong>: Te permite iniciarte en Javascript, HTML/CSS, Ruby, Python y
PHP. Complete muchos ejercicios de las cuatro primeras materias, pero la
sensación que me quedaba era de falta de profundidad en lo que se enseñaba y
que el ritmo de aprendizaje era demasiado lento para el nivel de lo enseñado.
Después de un tiempo acabe abandonando el sitio y borrando la cuenta. No es
para mí, no es lo que busco. Además en el momento en el que yo lo probé,
estaba plagado de errores en los evaluadores del código escrito que lo hacían
en cierta medida insufrible.</p>
</li>
<li>
<p><strong>DuoLingo</strong>: Se trata de aprender un segundo idioma a través de traducciones
colaborativas de textos en la red. Tiene una parte teórica de conocimientos de
gramática que fue la que me animo a participar, pues esta es la parte que más
necesitaba reforzar. Tras terminar esta parte de conocimientos básicos y ver que
no seguía ampliándose (que era mi interés principal) y tras innumerables
traducciones (que en general eran muy bien valoradas) acabé abandonando el
sitio y borrando la cuenta.</p>
</li>
</ul>
<p>Y aunque me decepcionaron parcialmente, tengo que reconocer que haber probado
estos sitios fue lo que me animó a dar el siguiente paso hacia algo más serio.</p>
<h2 id="reforzar_conocimientos_a_trav+s_de_retos">Reforzar conocimientos a través de Retos</h2>
<p>Otra alternativa para reforzar/ampliar conocimientos es la de resolver retos
planteados en diversos sitios donde se nos anima a comprobar nuestro nivel de
conocimientos frente a problemas de diversa dificultad. Existe también una
diversa variedad de este tipo de sitios, por poner algunos ejemplos: <a href="http://projecteuler.net/">Project
Euler</a>, <a href="http://www.pythonchallenge.com/">Python Challenge</a>, <a href="https://github.com/gregmalcolm/python_koans">Python Koans</a>, <a href="http://vimgolf.com/">VimGolf</a>,
<a href="http://www.codewars.com/">codewars</a>, <a href="http://coderbyte.com/CodingArea/Challenges/">coderbyte</a>, <a href="https://www.codeeval.com/">code_eval</a>,
<a href="https://www.hackerrank.com/">HackerRank</a>, <a href="http://code.google.com/codejam">Google Code Jam</a>, <a href="http://programmingpraxis.com/">Programming Praxis</a>,
<a href="http://community.topcoder.com/tc?module=ProblemArchive">TopCoder</a>, <a href="http://www.spoj.com/problems/classical/">Sphere online judge</a>, <a href="http://uva.onlinejudge.org/">UVa Online Judge</a>, <a href="http://www.ocf.berkeley.edu/%7Ewwu/riddles/intro.shtml">wu
riddles</a>, <a href="http://golf.shinh.org/">Anarchy Golf</a>, <a href="http://codegolf.stackexchange.com/">StackExchange CodeGolf</a>,
<a href="http://codeforces.com/">CodeForces</a>, <a href="http://www.mindcipher.com/">MindCipher</a>, <a href="http://www.codechef.com/">CodeChef</a>, <a href="http://acm.timus.ru/">Timus</a></p>
<p>Este tipo de sitios no solo nos ayudan a "tener afilada la sierra", si no que en
muchos casos nos obligan a aprender temas nuevos para resolver algunos
problemas. Por contar mi experiencia en dos de los varios sitios de este tipo
que he probado:</p>
<ul>
<li>
<p><strong>Project Euler</strong>: Es un sitio que nos reta a resolver problemas matemáticos
mediante cualquier lenguaje de programación (o simplemente usando bolígrafo y
papel) pero haciéndolo de manera eficiente. Los problemas pueden ser sencillos
o muy difíciles y resolver un gran número de ellos requiere de una buena base
matemática y algorítmica. He resuelto unos cuantos (68) y aunque deje de
hacerlo hace un tiempo, tengo la intención de retomarlo en algún momento. Un
sitio muy recomendable.</p>
</li>
<li>
<p><strong>Python Challenge</strong>: Se trata de resolver cierto de tipo de problemas a
través de código Python. La dificultad no solo reside en resolver el problema,
si no en encontrar el problema en si mismo, pues a medida que avanzamos se nos
van dando pistas (algunas ocultas) pero no se nos da un planteamiento
concreto. Es difícil completarlo y es muy, muy entretenido, a parte de
forzarte a usar un buen número de librerías distintas. Consta de 33 niveles y
yo me quedé atascado en el 26, aunque tengo intención de retomarlo y acabarlo
algún día. Altamente recomendable.</p>
</li>
</ul>
<p>La eficacia de estos sitos reside en el reto contra el problema y contra uno
mismo, muchos hacen trampa copiando soluciones previas de otros en la red, y lo
único que consiguen es engañarse a si mismos. En algunos sitios es tan patente
que me han quitado las ganas de seguir participado, pese a encantarme el sitio,
como es el caso de VimGolf.</p>
<h2 id="el_autodidacta_pragm+tico">El autodidacta pragmático</h2>
<p>Otra forma muy recomendable y muy frecuente de aprender una materia es a través
de la realización de un proyecto partiendo de cero. Es un camino a veces largo,
lleno de tropiezos y de dificultades que nos enriquecen enormemente cuando
conseguimos superarlos. Se puede aprender mucho de la materia en cuestión y
se suele aprender también un buen puñado de otras materias de manera transversal
por la interacción que estas tienen con nuestro proyecto.</p>
<p>Es la manera más cercana al aprendizaje real que ocurre en el mundo laboral y el
de que mayor experiencia nos provee, y es el que he realizado la mayor parte de
mi vida. Afortunadamente para mi, siempre he tenido una habilidad innata para
esta profesión y siempre me he caracterizado por una gran capacidad resolutiva.
En parte ha sido forzado, porque desde mis mas tempranas experiencias laborales
me he visto obligado a resolver un montón de problemas por mi cuenta y sin ayuda
alguna, y durante gran parte de mi carrera he trabajado en solitario, dando
solución a multitud de problemas distintos para los que no siempre estaba
preparado. Pero es el trabajo en equipo el que más enriquece y siempre se
aprende algo de cualquiera, por mucha experiencia que se tenga. Afortunadamente
para mi también he trabajado bastante en equipo.</p>
<p>Pero esta manera de aprender es también la más propensa a crear lagunas de
aprendizaje y malas practicas, cuando no, lo que yo llamo "supersticiones". Más
de una vez me he topado con profesionales experimentados que hacían las cosas
porque siempre las habían hecho así, tenían <em>miedo</em> de hacerlas de otra manera,
y el trasfondo del asunto es que no realmente no entendían lo que estaban
haciendo, les faltaba el conocimiento básico, el "porqué". Mentiría si dijera
que esto nunca me ha pasado, aunque siempre he intentado tarde o temprano el
comprender siempre el fondo del asunto. Es la mejor herramienta de diagnostico
posible para resolver cualquier problema, comprenderlo. Aunque esto no siempre
es posible, porque sobre todo en sistemas privativos tanto hardware como
software existe mucho "conocimiento cautivo" que a las empresas no les interesa
revelar.</p>
<h2 id="la_educaci+n_formal_al_alcance_de_todos_moocs">La Educación Formal al alcance de todos: MOOCs</h2>
<p>Pero fue con la aparición de los <a href="https://es.wikipedia.org/wiki/MOOC">MOOCs</a> cuando realmente empezamos a
tener disponible al alcance de todo el mundo una educación formal de calidad
para la auto-formación o formación continua.</p>
<p>Estas plataformas de enseñanza se caracterizan por ofrecer una educación de
calidad, de un nivel muy próximo (o igual, algunos cursos son
idénticos) a muchos cursos universitarios, con una experiencia
muy cercana a la de la educación tradicional. Aunque tienen ciertos
inconvenientes, que espero ser irán resolviendo con el tiempo, tienen la enorme
ventaja de estar disponibles al alcance todo el mundo y en muchas ocasiones de
forma totalmente gratuita. Muchos de ellos ofrecen Certificados de Aptitud de
mayor o menor relevancia.</p>
<p>Suelen ser cursos masivos (algunos han contado con mas de 160.000 personas
inscritas) donde el medio principal de enseñanza son lecciones grabadas en
vídeo, acompañadas frecuentemente de documentación en soporte PDF. Dependiendo
del curso, se efectúan tests, ejercicios y exámenes para evaluar los
conocimientos de los estudiantes. Se ofrecen ademas foros donde los alumnos
pueden comunicarse para compartir conocimientos, ayudarse entre ellos y crear
grupos de estudio.</p>
<h3 id="la_calidad_como_bandera">La calidad como bandera</h3>
<p>Pero la verdadera revolución reside en el gran respaldo que estas plataformas
han recibido de algunas de las mejores universidades del mundo, donde también
algunos de los mejores profesores del mundo imparten cursos que en algunos casos
son iguales a los que se imparten a los alumnos de esas mismas universidades.
Esto constituye un hito histórico en cuanto se pone al alcance de una gran masa
de población unos recursos educativos que hasta hace no muy poco estaban
reservados a una pequeña élite. Quien pensaría jamás que un chaval en África o
en la India, sin demasiados recursos económicos, solo con un ordenador y el
conocimiento del Ingles, podría esta recibiendo una clase que se imparte en el
MIT, Harvard o Stanford. Aunque no todos los cursos, ni todas las plataformas
están vinculados a Universidades.</p>
<p>Algunas de estas Universidades de prestigio (y otras instituciones educativas)
que imparten cursos en estas plataformas son Harvard, MIT, Stanford, Yale,
Princeton, Penn, Berkeley, Brown, Cornell, Caltech, UCLA, Duke, Columbia,
Oxford, Trinity College, Lausanne, Copenhaguen, Zurich, Tokyo, UAB, UNAM,
Peking, IESE, ... Muchas de estas universidades ofrecen ademas sus propias
plataformas donde imparten muchos de sus cursos.</p>
<p>De hecho vivimos una verdadera explosión de este sistema donde cada vez aparecen
más plataformas y donde más y más instituciones académicas se suman a esta
iniciativa, aumentando de este modo también el número de cursos disponibles. De
hecho existe ya un gran numero de áreas y materias distintas para las que hay
cursos disponibles. Podríamos decir que nos encontramos en las primeras etapas
de una verdadera democratización de la educación.</p>
<h3 id="las_plataformas_moocs">Las plataformas (MOOCs)</h3>
<p>Algunas de estas plataformas son las siguientes:</p>
<ul>
<li>
<p><a href="https://www.coursera.org/">Coursera</a>: La más famosa, la que más cursos ofrece
y la que mas Universidades apoyan. Fue una de las pioneras, creada por dos
profesores de la Universidad de Stanford. Su plataforma también es una de las
mejores y de las más completas. Mi experiencia con ella me permite decir que
es altamente recomendable. Un aspecto que me he encontrado en esta plataforma
y no he visto en otras es el concepto de "revisión entre pares", donde uno
evalúa los ejercicios de otros estudiantes y luego los compara con el suyo. Me
parece un recurso valiosisimo y de gran utilidad pedagógica. También ofrecen
tutorías, certificaciones oficiales pagadas e incluso acceso a oportunidades
laborales. Hay que cumplir con fechas de entrega límite.</p>
</li>
<li>
<p><a href="https://www.edx.org/">edX</a>: Creada por el MIT y la universidad de Harvard,
ofrece menos cursos que Coursera, pero de una calidad sobresaliente. También
tiene el apoyo de algunas de las mejores universidades del mundo. El nivel
suele ser elevado y bastante exigente. Su plataforma también es una de las
mejores, que ademas es open-source con su propio repositorio en
<a href="https://github.com/edx">GitHub</a>. Altamente recomendable. Hay que cumplir con fechas de entrega
límite.</p>
</li>
<li>
<p><a href="https://www.udacity.com/">Udacity</a>: La ultima de las tres grandes. Una gran
diferencia con las anteriores es que no hay fechas limite y uno puede seguir
los cursos a su ritmo, lo que la convierte en el complemento perfecto para
seguir cursos entre los tiempos muertos que te permiten las otras plataformas,
que es como yo la empleo. Su plataforma también es muy buena, aunque por lo
que yo he visto los cursos no están a la altura de la anteriores en general.
Recomendable.</p>
</li>
<li>
<p><a href="https://education.mongodb.com/">MongoDB University</a>: La empresa detrás de la
base de datos NoSQL MongoDB utiliza la plataforma de edX para ofrecer cursos
de capacitación para su herramienta. Son bastante buenos, aunque pienso que se
podrían pulir un poco más. Tienen cursos gratis y de pago. Si tienes que
trabajar con esta herramienta o curiosidad son muy recomendables.</p>
</li>
</ul>
<p>Con el resto de las plataformas no tengo experiencia personal así que me
limitare a citarlas brevemente:</p>
<ul>
<li>
<p><a href="https://www.iversity.org/">Iversity</a>: Plataforma creada en Europa y que
cuenta aun con pocos cursos y Universidades. Pero que promete mucho.</p>
</li>
<li>
<p><a href="http://www.udemy.com/">Udemy</a>: Una de las más dispersas en cuanto a que se ha
construido en torno a la idea de ofrecer una plataforma en la que los
profesores pueden crear cursos y no cuenta con la colaboración de ninguna
institución educativa en concreto. Muchos de sus cursos son de pago. Cierto es
que ofrecen algunos cursos muy interesantes y un nivel aceptable. Aunque
también se han visto envueltos en cierta polémica por la violación de
copyright de algunos contenidos.</p>
</li>
<li>
<p><a href="https://www.futurelearn.com/">FutureLearn</a>: Iniciativa Británica, agrupa un
buen numero de universidades del Reino Unido y pretende ser la respuesta a la
plataformas americanas.</p>
</li>
<li>
<p><a href="http://www.france-universite-numerique.fr/">France Université Numérique</a>:
Francia tampoco quiere quedarse atrás y en colaboración con edX ha creado una
plataforma cuyo despegue es inminente y que por supuesto estará disponible en
idioma Francés. Pretende aglutinar a más de 100 instituciones educativas del
país. </p>
</li>
<li>
<p><a href="https://www.miriadax.net/">Miriada-X</a>: Iniciativa Española y en Español que
puede ser la mejor alternativa para aquellos que no dominen el idioma Ingles.
Cuenta con un buen numero de universidades españolas. De momento no ofrece un
gran número de cursos.</p>
</li>
<li>
<p><a href="https://p2pu.org/en/">Peer to Peer University</a>: Iniciativa distinta a las
anteriores, se basa en compartir conocimientos entre los estudiantes y
cualquiera puede crear un curso. Diríamos que seria algo así como la Wikipedia
de los MOOCs. La idea podría ser muy buena a largo plazo, pero me temo que a
corto y medio plazo dista mucho de la calidad de las anteriores.</p>
</li>
<li>
<p>Otras plataformas que me limito a nombrar son <a href="http://www.instructure.com/">Canvas
Network</a>, <a href="http://academicearth.org/">Academic
Earth</a>, <a href="https://openlearning.com/">OpenLearning</a>,
<a href="http://www.saylor.org/">Saylor.org</a></p>
</li>
</ul>
<p>Un buen recurso para localizar cursos en estas plataformas y ver la evaluación
de los mismos por algunos de sus estudiantes es
<a href="http://coursetalk.org">coursetalk</a></p>
<p>Hoy en día gracias a la variedad de plataformas y cursos disponibles es posible
recibir una educación universitaria completa de calidad de este modo. Un
articulo muy recomendable en el que se comenta como es posible adquirir los
mismo conocimientos de una carrera de cuatro años del MIT a través de este
sistema es el siguiente: <a href="http://www.thesimplelogic.com/2012/09/24/you-say-you-want-an-education/">You say you want an Education?</a></p>
<p>Evidentemente hay que matizar que los estudios presenciales ofrecen una serie de
ventajas que no puede ofrecer este modelo, y que siempre se contara con más
recursos, sobre todo si hablamos de las instituciones que participan en estas
plataformas. Y no, no me refiero a jugar al mus en la cafetería, ni a ligar con
las chavalas, las fiestas o en el caso americano, las fraternidades. Tu ya me
entiendes. Pero aún de ese modo podemos acceder a unos recursos más que
suficientes para asentar unos conocimientos de calidad.</p>
<h2 id="mi_experiencia">Mi experiencia</h2>
<p>Mi experiencia con varias de estas plataformas no se extiende a más allá de un
año cuando empece con los primeros cursos, aunque no fue hasta hace medio año
que me tome alguno en serio y he llegado a completar algunos.</p>
<p>Lo primero que hay que tener claro es que muchos de estos cursos requieren
esfuerzo, tiempo y dedicación, en definitiva, disciplina. Y que el nivel de
algunos es bastante elevado y que requieren de conocimientos previos a veces
bastante profundos. Recomiendo empezar con alguno de los básicos para coger
soltura y la dinámica de estas plataformas. Mi mayor error fue empezar al
principio con cursos bastante complejos que requerían mucha dedicación, y más
aún teniendo en cuenta que hacia muchos años que no seguía ninguna formación
reglada. Empece varios que no pude completar porque no encontraba el tiempo
para dedicarles, y porque no reconocerlo, me encontraba bastante oxidado en
algunas materias, sobre todo en el área de Matemáticas.</p>
<p>Otro error que cometí es apuntarme a demasiados cursos a la vez, si tu tiempo
libre es limitado y quieres seguir disfrutando de unas horas de sueño
razonables, elige bien lo que quieres hacer. Aunque nadie te impide apuntarte a
varios, completar una o dos semanas y abandonarlo si no te interesan, no tienes
tiempo, prefieres hacer otros o simplemente no llegas al nivel necesario. No se
penaliza el abandonar estos cursos, e incluso puedes cursarlos varias veces si
quieres. Ademas puedes descargar los contenidos de estos cursos (existen
algunas herramientas para automatizar estas tareas) y poder hacer uso de ellos
en otro momento (para haceros una idea, en estos momentos tengo más de 50 GiB en
contenidos educativos de estas plataformas). También es posible que algunos
cursos no estén disponibles en este momento, pero si podamos acceder al
contenido de estos cursos dados con anterioridad. Yo he realizado así un par de
cursos que aunque no te proporcionan un Certificado de Aptitud si te aportan
unos conocimientos muy valiosos.</p>
<p>Evidentemente también existe un "Código de Honor" en el que se espera que nadie
haga trampas y viole los principios de cada curso. Desgraciadamente me he
encontrado varios casos evidentes de que esto no siempre se respeta y cuando los
profesores dan cuenta de ello, toman las medidas pertinentes. Del mismo modo se
espera que nadie publique soluciones en la red. Yo que no he tenido
inconveniente en publicar mis soluciones para problemas en Project Euler y
Python Challenge en mis repositorios en GitHub (entiendo que cada uno es adulto
para saber lo que hace), si que no me ha parecido de recibo hacer lo mismo con
las de estos cursos, teniendo en cuenta de que se entregan certificados de
aptitud y nos encontramos ante un planteamiento mucho más formal.</p>
<p>Pero la experiencia con estas plataformas, ya fuera en cursos que he completado
o en otros que he abandonando, es magnifica. Esa sensación de que empiezas a
entender muchas cosas que antes solo conocías por encima o de oídas, es
increíble. O cuando empiezas a conectar los puntos entre unas materias y otras y
comienzas a tener una visión mas global y completa de una cierta materia. Y por
lo general el tener a tu alcance a algunos profesores vale su peso en oro,
muchos son magníficos y te ayudan a comprender mucho más fácilmente las
materias. Esa es una gran ventaja de este sistema sobre las facultades normales,
por ejemplo en España, ni uno puede elegir siempre la facultad a la que quiere
ir y ni mucho menos a sus profesores, y la disparidad de calidad entre dos
facultades distintas puede ser bastante elevada. Y en estas plataformas podemos
contar a veces con profesores de autentico lujo. Profesores a los que hay que
agradecer mucho el enorme esfuerzo, a veces a costa de su vida personal, que
conlleva crear e impartir muchos de estos cursos.</p>
<p>No me cabe ninguna duda de que vivimos en una edad dorada en este sentido, y que
hay que aprovechar el momento.</p>
<h2 id="cursos_completados_con_+xito">Cursos completados con éxito</h2>
<p>Aquí iré relacionando algunos de los cursos que he completado con éxito, dando
una breve reseña sobre ellos y mi experiencia personal sobre los mismos. Lo iré
ampliando a medida que vaya completando más cursos, con los más interesantes.</p>
<ul>
<li>
<p><a href="https://www.coursera.org/course/proglang">Programming Languages</a> de la Universidad de Washington por Dan Grossman
en Coursera. Un curso increíble, de un nivel y exigencias elevadas. Este curso
es prácticamente idéntico al curso que imparte a sus alumnos en la Universidad
en el tercer año de carrera. Para mi ha supuesto todo un reto y una
satisfacción enorme el poder superarlo. Las lecciones son muy completas y los
ejercicios de programación rápidamente crecen en su nivel de dificultad. Se
acaba programando en SML, Racket y Ruby, y aunque se estudia también la OOP,
buena parte del curso está centrado en la programación funcional. Me ha dejado
un muy buen sabor de boca y Dan Grossman es un profesor magnifico.</p>
</li>
<li>
<p><a href="https://www.coursera.org/course/interactivepython">An Introduction to Interactive Programming in Python</a> de la Rice
University en Coursera. Es un curso introductorio y se nota, para mi ha sido
fácil completarlo con éxito y con un resultado perfecto. Pero el curso es muy
ameno, se aprenden las bases para crear un juego interactivo y los profesores
son muy majos. Pero por encima de todo te encuentras con una comunidad de
estudiantes de los mas diversos backgrounds, muy activa, muy participativa y
con un buen rollo increíble. En otros cursos se nota mucho la competitividad y
el ego, donde se intenta demasiado sacar pecho. Aquí se veo otro estilo, mas
colaborativo. Es un un curso muy recomendable para iniciarse en los MOOCs</p>
</li>
</ul>Vim as Python code editor2013-08-20T16:53:00+02:00joe di castrohttp://joedicastro.com/vim-as-python-code-editor.html<p><strong>This article is a translation from the original one in Spanish, <a href="http://joedicastro.com/vim-como-editor-de-codigo-python.html">Vim como
editor de codigo Python</a>, published in April 2013.</strong></p>
<p>This is an article that I've always wanted to write: "Vim as Python IDE". Two
years ago I had a Vim configuration that I thought that was just right for this,
even a half-written article. But while I was polishing the config and finishing
the article, a bunch of similar articles appeared in the internet and after
reading them I realized something: many of them were already obsolete at the
time they were published. And I say this because many of them employed plugins
that were outdated by the emerge of other fresh and more powerful. In fact in
the last two years, the Vim environment has evolved too much that from all the
plugins that I used in those days (and the ones pending to test), currently I'm
using only 10% of them, the rest are new ones. And this "race" to provide new
and more powerful features for Vim continues nowadays, with some great tools.</p>
<p>On the other hand, as one is adding plugins and "tuning" his config, there comes
a time when you don't know where and what is already mapped, even no
remember at all the plugins at features available for you, and which you
implemented with so much effort and time.</p>
<h2 id="my_configuration">My configuration</h2>
<p>Given these two premises I had the idea of kill two birds with one stone:
<strong>Document my Vim setup</strong>. What I'm trying with this is that should work for me
as sort of cheat-sheet to remember all that I had available in my config, and at
the same time to have a coherent mapping and avoid duplicates (at least is the
idea). By the other hand, it works also to demonstrate all the Vim's potential
to edit Python code and compete with almost any IDE, but with all the advantages
of the unique Vim's way.</p>
<p>The idea is to have a continuously updated document with respect to my current
setup, What better article than this, an always updated one?</p>
<p>This is the link to this doc, <code>README.md</code>, included in my dotfiles
repository:</p>
<ul>
<li><a href="https://github.com/joedicastro/dotfiles/tree/master/vim">Doc at GitHub</a></li>
</ul>
<p><em>English is not my mother tongue, so maybe the article (and the doc) can be full
of grammatical mistakes due to my poor English. Sorry for that, I did my best.</em></p>Vim como editor de codigo Python2013-04-08T10:29:00+02:00joe di castrohttp://joedicastro.com/vim-como-editor-de-codigo-python.html<p>Este es un articulo que siempre he deseado escribir: <em>Vim como IDE para Python</em>.
Hace dos años tenia una configuración de Vim que creía ideal para esto e incluso
el articulo a medio escribir. Pero a medida que iba puliendo la configuración y
completando el articulo, empezaron a surgir varios similares en la red (sobre
todo en inglés) y caí en la cuenta de algo: muchos ya estaban obsoletos al
publicarse. Y cuando digo esto lo digo porque muchos de estos artículos
empleaban plugins que se habían quedado desfasados por la aparición de otros mas
recientes y potentes. De hecho en los dos últimos años ha cambiado tanto el
panorama en el ecosistema en torno a Vim, que de la lista de plugins que
empleaba por aquel entonces (y los que tenía pendientes de probar) solo empleo
actualmente el 10%, el resto son nuevos. Y esta "carrera" por nutrir a Vim de
características nuevas y cada vez más potentes continua hoy en día, con algunas
herramientas excelentes.</p>
<p>Por otro lado, a medida que uno va añadiendo plugins y "tuneando" su
configuración llega un momento que ya no sabes ni donde tienes "mapeados" los
atajos, ni recuerdas todas las características que tienes a tu disposición y
tanto tiempo empleaste en implantar.</p>
<h2 id="mi_configuraci+n">Mi configuración</h2>
<p>Partiendo de estas dos premisas se me ocurrió una idea de atajar los dos
problemas de un golpe: <strong>Documentar mi configuración</strong>. Lo que trato por un lado
es que me sirva personalmente tanto para recordar todo lo que tengo disponible
en el editor, como para poder organizar coherentemente todos los atajos y evitar
duplicados. Por el otro lado, también me sirve para la idea de demostrar el
potencial que tiene Vim a la hora de ser un editor de código que puede estar a
la altura de cualquier IDE, pero con todas las ventajas inherentes a la
filosofía única de Vim.</p>
<p>La idea es que el documento esté permanentemente actualizado a la par que mi
configuración real, ¿que mejor articulo que este, que siempre estará
actualizado?</p>
<p>La configuración está documentada en un <code>README.md</code> dentro de la carpeta de Vim
del repositorio de mis dotfiles. Aquí se puede acceder directamente a mi
configuración y ver el documento. Actualmente el articulo está en Inglés, aquí
se pude acceder a la última revisión en español.</p>
<ul>
<li><a href="https://github.com/joedicastro/dotfiles/blob/a87b42deb9c1132c8f801bb91d119f0b26d21d68/vim/README.md">Documento en GitHub</a></li>
</ul>Productividad & Linux: Ncdu2012-10-19T22:40:00+02:00joe di castrohttp://joedicastro.com/productividad-linux-ncdu.html<p>Esta es una pequeña aplicación que sigue la máxima de <a href="http://es.wikipedia.org/wiki/Douglas_McIlroy">Doug Mcllroy</a> que
acabaría resumiendo la filosofía Unix <em>"Escribe programas que hagan una sola
cosa y que la hagan bien"</em>. Y siguiendo la línea de los programas que engloban
esta serie de productividad sobre Linux, es un programa de consola que se maneja
íntegramente con el teclado, y donde además los atajos están inspirados en los
de <a href="http://www.vim.org/">Vim</a>.</p>
<h2 id="ncdu">Ncdu</h2>
<p><a href="http://dev.yorhel.nl/ncdu">Ncdu</a> es un acrónimo para "NCurses Disk Usage", es decir, "Uso de disco
con interfaz ncurses". Lo que pretendía <a href="https://github.com/yorhel">Yoran Heling</a>, su autor, cuando
creo <strong>ncdu</strong>, era obtener un analizador de uso de disco en consola que fuera lo
suficientemente ligero para poder emplearlo en un servidor remoto a través de
<a href="https://es.wikipedia.org/wiki/Ssh">ssh</a>. El gran acierto fue emplear la interfaz <a href="https://es.wikipedia.org/wiki/Ncurses">ncurses</a> para
poder navegar por los directorios con extrema facilidad al mismo tiempo que se
presentaba la información en un formato legible y amigable. El segundo y no
menos importante acierto, es emplear los conocidos atajos de teclado de Vim para
navegar entre los directorios.</p>
<p>El resultado es un analizador de ocupación de disco que es realmente útil,
agradable de utilizar y que es tan rápido y ligero que se puede emplear sin
interfaz gráfica y en maquinas remotas. Es una gran ayuda para los
administradores de sistemas, que hasta ahora nos teníamos que pelear con otras
herramientas bastante menos agradables. Es la típica herramienta que cuando la
utilizas por primera vez piensas ¿Por qué demonios no la habría encontrado
antes?</p>
<p style="text-align:center;"><img src="pictures/ncdu.png" width="700"
height="559" alt="ncdu" /></p>
<p>Como se puede ver la interfaz es muy limpia y carece de elementos superfluos que
nos distraigan de lo importante, un pecado que cometen algunas de las
aplicaciones gráficas más famosas, que cuentan con unos gráficos muy bonitos,
pero realmente no demasiado útiles. Es sencillisima de emplear una vez que
conoces los atajos y cuenta con ayuda integrada a la que se accede pulsando
<strong><code>?</code></strong>. Incluso para aquellos que no están acostumbrados a navegar empleando
las típicas teclas de vim (<strong>h</strong>, <strong>j</strong>, <strong>k</strong>, <strong>l</strong>), se pueden utilizar las
teclas de dirección.</p>
<h3 id="caracter+sticas">Características</h3>
<p>Un programa de este tipo no necesita una funcionalidad muy elevada, pero
destacare aquí algunas de las posibilidades que nos ofrece:</p>
<ul>
<li>Podemos ordenar los directorios/ficheros en función de su nombre o de su
tamaño y en orden ascendente o descendente </li>
<li>Se pueden eliminar directamente ficheros o directorios desde la aplicación,
aunque también podemos iniciarla en modo solo lectura para prevenir borrados
accidentales</li>
<li>Se muestra o no, el porcentaje de espacio ocupado de forma gráfica y/o numérica</li>
<li>El espacio empleado en disco puede hacer referencia al real o al aparente</li>
<li>Los directorios y ficheros ocultos pueden ser o no mostrados</li>
<li>Nos permite recalcular el espacio ocupado de un directorio concreto sin
necesidad de volver a recalcular todo </li>
<li>Tenemos la posibilidad de volcar la información a un archivo, que puede
también ser leído por el mismo programa</li>
<li>Es posible mostrar la información de un elemento individual en un cuadro
emergente</li>
</ul>
<p>La verdad es que lo único que hecho en falta en el programa es quizás un poco de
color para distinguir entre ficheros y directorios de forma más visual. Por lo
demás, es muy rápido calculando el espacio, no he hecho una comparación directa,
pero me parece ligeramente más rápido que Baobab.</p>
<h3 id="alternativas">Alternativas</h3>
<p>Existen varias alternativas decentes como aplicaciones gráficas, como los
conocidos <a href="http://www.marzocca.net/linux/baobab/">Baobab</a> (que viene con las herramientas de Gnome) o
<a href="http://www.jgoodies.com/freeware/jdiskreport/">JDiskReport</a>. Después existen múltiples alternativas tanto en modo
gráfico como en modo consola que, sinceramente, no puedo recomendar a nadie,
bien porque son más vistosos que prácticos o bien porque son directamente
insufribles. Existe una alternativa en modo texto que algunos prefieren a ncdu
que es <a href="http://gt5.sourceforge.net/">gt5</a>.</p>Productividad & Linux: Ranger2012-10-18T21:50:00+02:00joe di castrohttp://joedicastro.com/productividad-linux-ranger.html<p>Algunos pensarán, de acuerdo, podemos entender que prefieras un <a href="http://joedicastro.com/productividad-en-el-escritorio-linux-tiling.html">gestor de
ventanas de mosaico</a>, o que emplees aplicaciones como <a href="http://joedicastro.com/productividad-linux-pentadactyl.html">Pentadactyl</a>,
<a href="http://joedicastro.com/productividad-linux-newsbeuter.html">Newsbeuter</a>, <a href="http://joedicastro.com/productividad-linux-zathura.html">Zathura</a> o <a href="http://joedicastro.com/productividad-linux-turses.html">Turses</a>, pero <strong>Ranger</strong>... ya es
demasiado. ¿A quien en su sano juicio se le ocurriría utilizar semejante
engendro? A mí, y no solo lo utilizo a diario, si no que además opino que es
quizás la mejor aplicación que he descubierto en el último año y medio. Y esto
último es mucho decir para alguien, que como yo, está continuamente buscando
formas de mejorar su modo de trabajo.</p>
<p><a href="http://ranger.nongnu.org/">Ranger</a> es un administrador de archivos en modo texto. Pero no es un
administrador de archivos en modo texto clásico a dos columnas, como el norton
commander y similares. No, Ranger es una pequeña joya con un planteamiento
distinto y tan potente, que puede conseguir que olvides que no podías vivir sin
un gestor de archivos gráfico como <a href="https://es.wikipedia.org/wiki/Nautilus_(software)">Nautilus</a>, <a href="https://es.wikipedia.org/wiki/Konqueror">Konqueror</a>,
<a href="https://es.wikipedia.org/wiki/Dolphin_(administrador_de_archivos)">Dolphin</a> o <a href="https://es.wikipedia.org/wiki/Thunar">Thunar</a>.</p>
<h2 id="ranger">Ranger</h2>
<p>Tengo que estar enormemente agradecido a su autor, <a href="https://github.com/hut">Roman Zimbelmann</a> no
solo por su trabajo, si no por mostrarme que incluso en modo texto, se puede
revolucionar el mundo de la usabilidad. Evidentemente, en una aplicación que
basa su control en el teclado (tiene un soporte muy básico del ratón), es
requisito imprescindible invertir algún tiempo en aprender a utilizarlo, ya que
no es tan intuitivo como una aplicación gráfica. A menos que seas un usuario
típico de <a href="https://es.wikipedia.org/wiki/Vim">Vim</a>, entonces te encontrarás como en casa. Una vez que dominas
esta aplicación, el moverse entre los directorios y el realizar operaciones se
hace a velocidad de vértigo y con control absoluto (siempre que no seas un
manazas con el teclado).</p>
<p><strong>Ranger</strong> está desarrollado en <strong>Python</strong> y emplea una interfaz ncurses igual que
<a href="http://joedicastro.com/productividad-linux-turses.html">Turses</a>. Al contrario de lo que algunos puedan pensar, el estar
desarrollado en Python no lo convierte ni en pesado ni en lento, si no que se
mueve a velocidad endiablada y consume una cantidad de memoria ridícula
comparada con cualquier gestor de archivos gráfico.</p>
<p style="text-align:center;"><img src="pictures/ranger.png" width="700"
height="437" alt="Ranger" /></p>
<p>Aquí puede verse una imagen típica de ranger, visualizando el contenido de un
directorio y previsualizando el contenido de un fichero, en este caso un fichero
de código python.</p>
<h3 id="caracter+sticas">Características</h3>
<p>¿Qué se puede hacer con ranger?, bueno, quizás es mejor preguntarse que no se
puede hacer con Ranger. Prácticamente todas las funciones a las que estés
acostumbrado en un administrador de archivos gráfico se pueden realizar con
Ranger. Vamos primero a ver un resumen de sus características:</p>
<ul>
<li>Soporte de UTF-8 por defecto</li>
<li>Visualización en múltiples columnas</li>
<li>Previsualización del directorio o fichero seleccionado</li>
<li>Operaciones comunes sobre los ficheros. Crear, copiar, borrar, cambiar
atributos (<code>chmod</code>), etc...</li>
<li>Combinaciones de teclado y consola inspiradas en Vim</li>
<li>Autodetección de tipos de fichero y apertura de los mismos con el programa
adecuado</li>
<li>Permite establecer etiquetas y marcadores sobre archivos y directorios</li>
<li>Empleo de pestañas. Nos permite navegar por varios directorios simultáneamente
sin necesidad de abrir otra instancia del programa. Además se pueden realizar
operaciones entre ellas</li>
<li>Muestra una barra de progreso para las operaciones que lo necesitan</li>
</ul>
<p>Conviene dejar claro que no es un programa para <em>impacientes</em>, hacerse con él y
sus innumerables opciones requiere tiempo. Hay que leerse la ayuda del programa
y practicar con él. A su vez, si queremos personalizar las opciones o ampliarlo,
debemos comprender como funcionan sus archivos de configuración, mejor aún si
tenemos conocimientos de Python. La documentación de su web, así como la de sus
páginas <em>man</em> está un poco desactualizada, por lo que sacarle todo su jugo
requiere algo de paciencia.</p>
<h3 id="ejemplos">Ejemplos</h3>
<p>Voy a intentar dar algo de visibilidad a algunas de las capacidades que nos
ofrece ranger empleando una par de ejemplos que lo ilustren.</p>
<p>En el siguiente ejemplo vemos la previsualización que hace ranger en función del
tipo de fichero que se trate.</p>
<div style="text-align:center">
<iframe src="http://player.vimeo.com/video/62061254?title=0&byline=0&portrait=0"
width="700" height="438">
</iframe>
<p>Previsualización de archivos en ranger con varios tipos de archivo.
Recomiendo ver en alta resolución y a pantalla completa.</p>
</div>
<p>La previsualización de imágenes en ASCII puede parecer una tontería, pero
resulta muy útil a la hora de diferenciar entre distintas imágenes con nombre
muy parecido. El fichero en HTML está renderizado en vez de mostrarnos el texto
plano, algo más amigable. También se agradece mucho el que los ficheros de
código se vean con resaltado de sintaxis.</p>
<blockquote>
<p>Conviene aclarar que para realizar esta previsualización es necesario tener
instalado una serie de pequeñas aplicaciones que se detallan en el sitio de
ranger como dependencias.</p>
</blockquote>
<p>Aquí vemos como se abren automáticamente los programas adecuados en función del
tipo de archivo (se puede configurar que aplicaciones emplear y cuales usar en
cada momento)</p>
<div style="text-align:center">
<iframe src="http://player.vimeo.com/video/62634892?title=0&byline=0&portrait=0"
width="700" height="438">
</iframe>
<p>Ejecución automática de aplicaciones en función del tipo de archivo.
Recomiendo ver en alta resolución y a pantalla completa.</p>
</div>
<p>En el caso del fichero Torrent, al que no tengo asociada ninguna aplicación en
ranger, me abre un comando en el que puedo especificar directamente la
aplicación que deseo emplear para gestionarlo. En este caso, ninguna. En el
archivo comprimido solo me muestra el contenido del mismo, podría asociarle
alguna aplicación, pero ya tengo comandos para manejarlos dentro del propio
ranger, algo que veremos a continuación.</p>
<h2 id="mi_configuraci+n">Mi configuración</h2>
<p>No he personalizado mucho mi configuración de momento, pero quien quiera echarle
un vistazo puede hacerlo en mi repositorio dotfiles en <a href="http://github.com/joedicastro/dotfiles">GitHub</a></p>
<h3 id="archivos_de_configuraci+n">Archivos de configuración</h3>
<p>Para configurar ranger necesitamos editar ciertos archivos, que crearemos por
primera vez con el siguiente comando:</p>
<div class="codehilite"><pre><span class="nv">$ </span>ranger --copy-config<span class="o">=</span>all
</pre></div>
<p>qué nos creara los siguientes archivos por defecto en la carpeta
<code>~/.config/ranger/</code>:</p>
<ul>
<li><code>commands.py</code> <em>(python)</em>, en este archivo se configuran los comandos a emplear
en la línea de comandos de ranger</li>
<li><code>options.py</code> <em>(python)</em>, el fichero de opciones principal de ranger</li>
<li><code>rc.conf</code> <em>(texto)</em>, aquí configuramos los atajos de teclado de ranger</li>
<li><code>rifle.conf</code> <em>(texto)</em>, para establecer los programas que ejecutaran o abrirán
un tipo de archivo en orden de preferencia</li>
<li><code>scope.sh</code> <em>(bash)</em>, los programas empleados para previsualizar un determinado
tipo de archivo</li>
</ul>
<p>Adicionalmente, con el uso se añadirán tres ficheros más: <code>bookmarks</code>, <code>history</code>
y <code>tagged</code> que guardarán los marcadores, la historia de comandos y las etiquetas
respectivamente.</p>
<h3 id="gestionar_la_papelera">Gestionar la papelera</h3>
<p>Por defecto ranger no contempla la gestión de la papelera de Linux que
implementan escritorios como Gnome. Aunque no empleo ningún entorno
de escritorio ni gestores de archivos gráficos, si me interesa gestionar la
papelera, pues cada vez más aplicaciones la emplean para eliminar los archivos.
De hecho en <em>bash</em> y <em>zsh</em> tengo un alias para <code>rm</code> que mueve los archivos a la
papelera en vez de eliminarlos.</p>
<div class="codehilite"><pre><span class="nb">alias </span><span class="nv">rm</span><span class="o">=</span><span class="s1">'mv --target-directory ~/.local/share/Trash/files'</span>
</pre></div>
<p>Para gestionar la papelera desde ranger, añado dos atajos de teclado y un
comando editando varios archivos de configuración de la siguiente manera:</p>
<p><strong>Mandar archivos a la papelera</strong></p>
<p>Para mandar a la papelera lo que tengamos seleccionado actualmente, en lugar de
eliminarlo directamente, añadimos esta línea al fichero <code>rc.conf</code></p>
<div class="codehilite"><pre><span class="c"># move to trash</span>
<span class="nb">map</span> <span class="n">DD</span> <span class="n">shell</span> <span class="n">mv</span> <span class="o">-</span><span class="n">t</span> <span class="o">~/.</span><span class="n">local</span><span class="o">/</span><span class="n">share</span><span class="o">/</span><span class="n">Trash</span><span class="o">/</span><span class="n">files</span> <span class="o">%</span><span class="n">s</span>
</pre></div>
<p>de este modo, cada vez que pulsemos <strong><code>DD</code></strong> el contenido seleccionado es movido
al directorio donde tenemos nuestra papelera.</p>
<p><strong>Movernos a la papelera</strong></p>
<p>Del mismo modo que ranger provee por defecto de atajos de teclado para movernos
al directorio <code>home</code>, al directorio raiz, etc, he añadido un atajo de teclado
siguiendo el mismo criterio para acceder a nuestra papelera. Añadimos lo
siguiente al fichero <code>rc.conf</code></p>
<div class="codehilite"><pre><span class="c"># go to trash</span>
<span class="nb">map</span> <span class="n">gp</span> <span class="n">cd</span> <span class="o">~/.</span><span class="n">local</span><span class="o">/</span><span class="n">share</span><span class="o">/</span><span class="n">Trash</span><span class="o">/</span><span class="n">files</span>
</pre></div>
<p>así, pulsando <strong><code>gp</code></strong> vamos directamente a la papelera, estemos donde estemos.</p>
<p><strong>Vaciar la papelera</strong></p>
<p>Para vaciar la papelera opto por emplear un comando, para ello tenemos que
editar otro fichero, <code>commands.py</code>, y añadir lo siguiente</p>
<div class="codehilite"><pre><span class="k">class</span> <span class="nc">empty</span><span class="p">(</span><span class="n">Command</span><span class="p">):</span>
<span class="sd">"""</span>
<span class="sd"> :empty</span>
<span class="sd"> Empties the trash directory ~/.local/share/Trash/files</span>
<span class="sd"> """</span>
<span class="k">def</span> <span class="nf">execute</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">fm</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="s">"rm -rf ~/.local/share/Trash/files/{*,.[^.]*}"</span><span class="p">)</span>
</pre></div>
<p>por lo que vaciar la papelera se convierte en algo tan simple como teclear
<strong><code>:empty</code></strong> o para los más cómodos <strong><code>:em↹</code></strong></p>
<h3 id="desmontar_una_unidad_con_udiskie">Desmontar una unidad con udiskie</h3>
<p>Dada mi "particular" configuración, ya que no empleo ningún escritorio, empleo
la herramienta <a href="https://bitbucket.org/byronclark/udiskie">udiskie</a> para automontar unidades de almacenamiento
externas, como unidades USB o tarjetas de memoria. El montado se hace de forma
automática y solo el desmontado ha de hacerse de forma manual. Ya que no quiero
teclear el comando cada vez que desee desmontar una unidad, lo que hago es
hacerlo desde ranger. En el fichero <code>rc.conf</code> mapeamos este atajo</p>
<div class="codehilite"><pre><span class="c"># umount a drive with udiskie</span>
<span class="nb">map</span> <span class="n">un</span> <span class="n">shell</span> <span class="o">-</span><span class="n">d</span> <span class="n">udiskie</span><span class="o">-</span><span class="n">umount</span> <span class="o">%</span><span class="n">d</span><span class="o">/%</span><span class="n">f</span>
</pre></div>
<p>así para desmontar una unidad inicio ranger (en mi caso <strong><code>Win + F1</code></strong>), me
dirijo a las unidades externas montadas, <strong><code>gm</code></strong>, selecciono la unidad deseada
y la desmonto, <strong><code>un</code></strong>. Un proceso que me lleva apenas dos segundos, sin
abandonar las manos del teclado, compárese con hacerlo con un ratón y un entorno
gráfico.</p>
<h3 id="expulsar_un_cddvd">Expulsar un CD/DVD</h3>
<p>Del mismo modo, en lugar de abrir un terminal y escribir el comando <code>eject</code>, en
determinadas circunstancias, por ejemplo al acabar de examinar el contenido de
un disco, prefiero hacerlo directamente desde ranger. Para ello en el fichero
<code>rc.conf</code> creamos este atajo de teclado</p>
<div class="codehilite"><pre><span class="c"># eject a CD-ROM/DVD</span>
<span class="nb">map</span> <span class="n">ej</span> <span class="n">shell</span> <span class="o">-</span><span class="n">d</span> <span class="n">eject</span>
</pre></div>
<h3 id="trabajar_con_archivos_comprimidos">Trabajar con archivos comprimidos</h3>
<p>Estos comandos los he sacado de el <a href="https://wiki.archlinux.org/index.php/Ranger">Wiki de Arch Linux</a> y los he adaptado
a la versión de ranger que estoy empleando en este momento, la 1.5.5</p>
<p><strong>Extraer los ficheros de un archivo comprimido</strong></p>
<p>Con el comando <strong><code>:extracthere</code></strong> extraemos el contenido de un archivo/s
comprimido que previamente habremos seleccionado para copia (es decir empleando
el atajo <strong><code>yy</code></strong>). El contenido se extrae en el directorio en el que nos
encontremos actualmente. Es muy comodo para extraer múltiples archivos
comprimidos a la vez, si quisieramos descomprimir solo un archivo y en el mismo
directorio en el que este se encuentra, podríamos emplear el atajo <strong><code>1l</code></strong></p>
<p>Para añadir el comando a ranger, tenemos que insertar esta clase en el fichero
<code>commands.py</code></p>
<div class="codehilite"><pre><span class="k">class</span> <span class="nc">extracthere</span><span class="p">(</span><span class="n">Command</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">execute</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">""" Extract copied files to current directory """</span>
<span class="n">copied_files</span> <span class="o">=</span> <span class="nb">tuple</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">fm</span><span class="o">.</span><span class="n">env</span><span class="o">.</span><span class="n">copy</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">copied_files</span><span class="p">:</span>
<span class="k">return</span>
<span class="k">def</span> <span class="nf">refresh</span><span class="p">(</span><span class="n">_</span><span class="p">):</span>
<span class="n">cwd</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">fm</span><span class="o">.</span><span class="n">env</span><span class="o">.</span><span class="n">get_directory</span><span class="p">(</span><span class="n">original_path</span><span class="p">)</span>
<span class="n">cwd</span><span class="o">.</span><span class="n">load_content</span><span class="p">()</span>
<span class="n">one_file</span> <span class="o">=</span> <span class="n">copied_files</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="n">cwd</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">fm</span><span class="o">.</span><span class="n">thisdir</span>
<span class="n">original_path</span> <span class="o">=</span> <span class="n">cwd</span><span class="o">.</span><span class="n">path</span>
<span class="n">au_flags</span> <span class="o">=</span> <span class="p">[</span><span class="s">'-X'</span><span class="p">,</span> <span class="n">cwd</span><span class="o">.</span><span class="n">path</span><span class="p">]</span>
<span class="n">au_flags</span> <span class="o">+=</span> <span class="bp">self</span><span class="o">.</span><span class="n">line</span><span class="o">.</span><span class="n">split</span><span class="p">()[</span><span class="mi">1</span><span class="p">:]</span>
<span class="n">au_flags</span> <span class="o">+=</span> <span class="p">[</span><span class="s">'-e'</span><span class="p">]</span>
<span class="bp">self</span><span class="o">.</span><span class="n">fm</span><span class="o">.</span><span class="n">env</span><span class="o">.</span><span class="n">copy</span><span class="o">.</span><span class="n">clear</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">fm</span><span class="o">.</span><span class="n">env</span><span class="o">.</span><span class="n">cut</span> <span class="o">=</span> <span class="bp">False</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">copied_files</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
<span class="n">descr</span> <span class="o">=</span> <span class="s">"extracting: "</span> <span class="o">+</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">basename</span><span class="p">(</span><span class="n">one_file</span><span class="o">.</span><span class="n">path</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">descr</span> <span class="o">=</span> <span class="s">"extracting files from: "</span> <span class="o">+</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">basename</span><span class="p">(</span><span class="n">one_file</span><span class="o">.</span><span class="n">dirname</span><span class="p">)</span>
<span class="n">obj</span> <span class="o">=</span> <span class="n">CommandLoader</span><span class="p">(</span><span class="n">args</span><span class="o">=</span><span class="p">[</span><span class="s">'aunpack'</span><span class="p">]</span> <span class="o">+</span> <span class="n">au_flags</span> \
<span class="o">+</span> <span class="p">[</span><span class="n">f</span><span class="o">.</span><span class="n">path</span> <span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">copied_files</span><span class="p">],</span> <span class="n">descr</span><span class="o">=</span><span class="n">descr</span><span class="p">)</span>
<span class="n">obj</span><span class="o">.</span><span class="n">signal_bind</span><span class="p">(</span><span class="s">'after'</span><span class="p">,</span> <span class="n">refresh</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">fm</span><span class="o">.</span><span class="n">loader</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span>
</pre></div>
<p><strong>Crear un archivo comprimido</strong></p>
<p>Este comando te permite seleccionar uno o varios ficheros y crear un archivo
comprimido al llamar al comando <strong><code>:compress</code></strong>. Este comando te permite (a
través del autocompletado) darle un nombre automático a partir del directorio o
uno personalizado. Te permite además seleccionar el tipo de compresión en
función de la extension empleada.</p>
<p>En el fichero <code>commands.py</code> añadimos el siguiente código.</p>
<div class="codehilite"><pre><span class="k">class</span> <span class="nc">compress</span><span class="p">(</span><span class="n">Command</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">execute</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">""" Compress marked files to current directory """</span>
<span class="n">cwd</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">fm</span><span class="o">.</span><span class="n">thisdir</span>
<span class="n">marked_files</span> <span class="o">=</span> <span class="n">cwd</span><span class="o">.</span><span class="n">get_selection</span><span class="p">()</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">marked_files</span><span class="p">:</span>
<span class="k">return</span>
<span class="k">def</span> <span class="nf">refresh</span><span class="p">(</span><span class="n">_</span><span class="p">):</span>
<span class="n">cwd</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">fm</span><span class="o">.</span><span class="n">env</span><span class="o">.</span><span class="n">get_directory</span><span class="p">(</span><span class="n">original_path</span><span class="p">)</span>
<span class="n">cwd</span><span class="o">.</span><span class="n">load_content</span><span class="p">()</span>
<span class="n">original_path</span> <span class="o">=</span> <span class="n">cwd</span><span class="o">.</span><span class="n">path</span>
<span class="n">parts</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">line</span><span class="o">.</span><span class="n">split</span><span class="p">()</span>
<span class="n">au_flags</span> <span class="o">=</span> <span class="n">parts</span><span class="p">[</span><span class="mi">1</span><span class="p">:]</span>
<span class="n">descr</span> <span class="o">=</span> <span class="s">"compressing files in: "</span> <span class="o">+</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">basename</span><span class="p">(</span><span class="n">parts</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
<span class="n">obj</span> <span class="o">=</span> <span class="n">CommandLoader</span><span class="p">(</span><span class="n">args</span><span class="o">=</span><span class="p">[</span><span class="s">'apack'</span><span class="p">]</span> <span class="o">+</span> <span class="n">au_flags</span> <span class="o">+</span> \
<span class="p">[</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">relpath</span><span class="p">(</span><span class="n">f</span><span class="o">.</span><span class="n">path</span><span class="p">,</span> <span class="n">cwd</span><span class="o">.</span><span class="n">path</span><span class="p">)</span> <span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">marked_files</span><span class="p">],</span> <span class="n">descr</span><span class="o">=</span><span class="n">descr</span><span class="p">)</span>
<span class="n">obj</span><span class="o">.</span><span class="n">signal_bind</span><span class="p">(</span><span class="s">'after'</span><span class="p">,</span> <span class="n">refresh</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">fm</span><span class="o">.</span><span class="n">loader</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">tab</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">""" Complete with current folder name """</span>
<span class="n">extension</span> <span class="o">=</span> <span class="p">[</span><span class="s">'.zip'</span><span class="p">,</span> <span class="s">'.tar.gz'</span><span class="p">,</span> <span class="s">'.rar'</span><span class="p">,</span> <span class="s">'.7z'</span><span class="p">]</span>
<span class="k">return</span> <span class="p">[</span><span class="s">'compress '</span> <span class="o">+</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">basename</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">fm</span><span class="o">.</span><span class="n">thisdir</span><span class="o">.</span><span class="n">path</span><span class="p">)</span> <span class="o">+</span> <span class="n">ext</span> <span class="k">for</span> <span class="n">ext</span> <span class="ow">in</span> <span class="n">extension</span><span class="p">]</span>
</pre></div>Productividad & Linux: zathura2012-07-16T23:32:00+02:00joe di castrohttp://joedicastro.com/productividad-linux-zathura.html<p><a href="http://pwmt.org/projects/zathura/">zathura</a> es un programa minimalista que procura seguir el principio de
<em>"menos es más"</em> que acuñara <a href="https://es.wikipedia.org/wiki/Ludwig_Mies_van_der_Rohe">Mies van der Rohe</a> en la arquitectura y que
en la informática se correspondería con el principio <a href="https://es.wikipedia.org/wiki/Principio_KISS">KISS</a> y la
<a href="http://en.wikipedia.org/wiki/Unix_philosophy">filosofía UNIX</a>. Siguiendo esta filosofía, zathura es una aplicación que
hace una sola cosa, la hace bien y consume muy pocos recursos. Sus autores, la
comunidad <a href="http://pwmt.org/about">PWMT.org</a> (<em>programas con nombre de película</em>), tienen como
propósito el crear aplicaciones de software libre que se centren en un interfaz
simple, que no malgaste espacio y que se maneje íntegramente desde el teclado.</p>
<p>La aplicación es un visor de documentos, y es modular, por lo que puedes
instalar los plugins que quieras en función del formato de documentos que
quieras que soporte. Actualmente están disponibles los siguientes plugins:</p>
<ul>
<li>
<p><em>pdf-poppler</em>: Lectura de <a href="http://es.wikipedia.org/wiki/Pdf">PDF</a> a través de la famosa librería
<a href="http://poppler.freedesktop.org/">Poppler</a>, que es empleada por aplicaciones como Evince, Okular o
Inkscape.</p>
</li>
<li>
<p><em>pdf-mupdf</em>: Lectura de PDF mediante la librería <a href="http://mupdf.com/">mupdf</a> empleada por
ejemplo por Sumatra PDF.</p>
</li>
<li>
<p><em>djvu</em>: Para visionar documentos <a href="https://es.wikipedia.org/wiki/Djvu">DJVU</a>. Emplea la librería
<a href="http://djvu.sourceforge.net/">djvulibre</a> que emplean por ejemplo Evince y Okular.</p>
</li>
<li>
<p><em>ps</em>: Para poder ver documentos <a href="https://es.wikipedia.org/wiki/Postscript">Postscript</a>. Usa la librería
<a href="http://libspectre.freedesktop.org/">libspectre</a> que es utilizada por Evince y Okular.</p>
</li>
<li>
<p><em>cb</em>: Para poder abrir archivos en formato <a href="https://es.wikipedia.org/wiki/Archivo_de_historieta">Comic Book</a>.</p>
</li>
</ul>
<p>Como se puede ver emplea las mismas librerías que emplean la mayoría de
programas similares para Linux, por lo tanto nos ofrecen la misma calidad que
estos pero con un interfaz minimalista donde el protagonista es el contenido, y
proporcionándonos un control absoluto del documento desde el teclado.</p>
<p style="text-align:center;"><img src="pictures/zathura.png" width="700"
height="957" alt="Zathura" /></p>
<p>El interfaz es simple, una ventana de contenido y una barra de estado/línea de
comandos. El control de la misma recae en el teclado (aunque puede usarse el
ratón para funciones básicas) y sus atajos están inspirados en los de Vim.</p>
<h2 id="caracter+sticas">Características</h2>
<p>Las características principales de Zathura son las siguientes:</p>
<ul>
<li>Interfaz minimalista</li>
<li>Controlable completamente desde el teclado, inspirado en vim y muy parecido a
pentadactyl. Permite seguir enlaces y saltos directos a páginas</li>
<li>Recarga automática de documentos si estos cambian. Útil para previsualizar la
salida en PDF de documentos de LaTeX, por ejemplo</li>
<li>Permite establecer marcadores y marcadores rápidos dentro de un documento. Muy
útil para labores de investigación y documentación</li>
<li>Exporta imágenes y adjuntos de un documento</li>
<li>Puede abrir documentos protegidos por contraseña (proporcionándosela, claro)</li>
<li>Imprime el documento completo o simplemente las hojas que deseemos</li>
<li>Permite buscar en el documento y desplazarse por los resultados</li>
<li>Se puede abrir y navegar por el indice del documento</li>
<li>Muestra la información disponible (metadatos) sobre el documento</li>
<li>Zoom y Rotar documentos</li>
<li>Permite cambiar el color del documento. Sirve para visualizar el documento en
duotono con los colores invertidos</li>
<li>Se pueden personalizar los atajos de teclado y los colores empleados</li>
<li>Se personaliza a través de un fichero de texto plano</li>
</ul>
<p>En esta imagen se puede apreciar el resultado de aplicar el comando <code>:info</code>
sobre un documento.</p>
<p style="text-align:center;"><img src="pictures/zathura_info.png" width="700"
height="957" alt="zathura info dialog" /></p>
<p>El poder cambiar los colores del documento, invirtiéndolos, es una
característica muy útil, por ejemplo, para leer largos documentos sin fatigar
demasiado nuestra vista. Aquí se puede ver la diferencia entre ver un documento
a pantalla completa en modo normal y con los colores invertidos.</p>
<p style="text-align:center;"><img src="pictures/zathura.gif" width="640"
height="400" alt="zathura full screen" /></p>
<h2 id="alternativas">Alternativas</h2>
<p>No hay demasiadas alternativas a Zathura que tengan un planteamiento parecido,
de hecho la única que conozco es <a href="http://naihe2010.github.com/apvlv/">apvlv</a>. Aunque para mi no es tan
completa como Zathura.</p>
<h2 id="mi_configuraci+n">Mi configuración</h2>
<p>Aunque mi configuración no tiene nada de particular, está disponible en mis
<em>dotfiles</em> alojados en <a href="http://github.com/joedicastro/dotfiles">GitHub</a>.</p>Productividad & Linux: tmux2012-07-09T22:42:00+02:00joe di castrohttp://joedicastro.com/productividad-linux-tmux.html<p><a href="http://tmux.sourceforge.net/">Tmux</a> es un <strong>multiplexor</strong> de terminales. Es una herramienta básica,
casi diría imprescindible, para los que trabajamos habitualmente con la consola
de Linux. El termino multiplexor es empleado en electrónica para designar un
dispositivo que combina múltiples entradas en una única salida. Esto es lo que
hace tmux, combinar varios terminales en una sola ventana, de forma que podamos
organizarlos de la forma más eficiente posible. Si lo primero que te viene a la
cabeza son terminales con múltiples pestañas o paneles como <a href="https://launchpad.net/terminator/">Terminator</a>,
olvídalo, tmux es un concepto diferente y más potente.</p>
<p>La gran diferencia es que tmux está basado en un modelo cliente-servidor. El
servidor puede albergar múltiples sesiones y cada instancia (ventana de
terminal) puede estar asociado con una o más sesiones. Se pueden abrir, cerrar
sesiones, moverse entre ellas, renombrarlas. Una sesión puede ser compartida por
varios clientes, lo que es empleado por ejemplo para sesiones de <a href="https://es.wikipedia.org/wiki/Programaci%C3%B3n_en_pareja">pair
programming</a>. Si se cierra un cliente, la sesión sigue corriendo en segundo
plano, pudiéndose volver a ella cuando se desee. A su vez cada sesión puede
albergar varias ventanas (el equivalente a las pestañas en otros terminales) y
cada ventana puede subdividirse en varios paneles.</p>
<p>Es una aplicación muy flexible y con muchas posibilidades, no voy a entrar en
detalle en todas ellas porque me extendería demasiado. Es totalmente controlable
desde el teclado, lo que lo hace muy ágil en su manejo. Yo lo uso a diario y es
muy raro que trabaje en un terminal sin hacerlo dentro de una sesión de tmux.
Tmux te permite tener perfectamente organizadas todas esas ventanas de terminal
que los SysAdmins manejamos y que de otra manera se convierten en un caos. Antes
de emplear tmux empleaba screen y terminator dependiendo de la tarea y el equipo
a emplear, pero tmux me da lo mejor de ambas aplicaciones y aún más. Y si además
los combinamos con un terminal ligero, superrápido y con soporte para UTF-8 y
256 colores como <code>rxvt-unicode</code> tenemos un entorno ideal para cualquier tarea
que desarrollemos en la consola.</p>
<h2 id="caracter+sticas">Características</h2>
<p>Este es un resumen de las características de tmux:</p>
<ul>
<li>Modelo cliente/servidor</li>
<li>Linea de comandos potente, consistente y fácilmente programable</li>
<li>Totalmente controlable desde el teclado, aunque tiene un soporte básico de
ratón</li>
<li>División de las ventanas en múltiples paneles horizontales y/o verticales</li>
<li>Los paneles pueden ser movidos, redimensionados y pueden reorganizarse en
esquemas predefinidos</li>
<li>Sincronizar paneles. Introducir el mismo texto en varios paneles a la vez</li>
<li>Soporte para UTF-8 y 256 colores</li>
<li>Copiar y pegar con múltiples bufferes</li>
<li>Menús interactivos para seleccionar ventanas, sesiones o clientes</li>
<li>Bloqueo de terminal manualmente o por cuenta atrás</li>
<li>Moverse a una ventana mediante una búsqueda del texto existente dentro de ella</li>
<li>Barra de estado por defecto y muy personalizable</li>
<li>Fichero de configuración basado en texto plano</li>
<li>Soporte para combinaciones de teclas basadas en Vim o Emacs</li>
<li>Documentación bastante completa</li>
</ul>
<p>En esta imagen se puede ver la configuración por defecto de tmux, a primera
vista no se puede apreciar toda la potencia que se esconde detrás de esta
aplicación.</p>
<p style="text-align:center;"><img src="pictures/tmux.png" width="700"
height="481" alt="tmux" /></p>
<h2 id="alternativas">Alternativas</h2>
<p>La alternativa más directa es el veterano <a href="http://es.wikipedia.org/wiki/GNU_Screen">GNU Screen</a> en el que se
inspira tmux. Sigue siendo una aplicación muy utilizada, pero en mi opinión tmux
la ha superado hace tiempo. Otra alternativa es <a href="https://launchpad.net/byobu">Byobu</a> que no es más que
un frontend para tmux o screen que los hace más amigables para los usuarios
menos avanzados.</p>
<h2 id="scripts">Scripts</h2>
<p>Una de las posibilidades más potentes que nos permite tmux es la de la creación
de scripts para iniciar una o varias sesiones con configuraciones
predeterminadas. De esto modo se pueden crear sesiones predefinidas para
desarrollo, web, ssh, etc. Pero crear scripts en tmux es una tarea bastante
árida, por lo que se han desarrollado algunas utilidades de terceros para
realizar esto de forma más cómoda y agradable:</p>
<ul>
<li>
<p><a href="https://github.com/aziz/tmuxinator">Tmuxinator</a> es una utilidad escrita en <a href="http://www.ruby-lang.org/es/">Ruby</a> para crear y
modificar sesiones de Tmux, permitiendo crear sesiones complejas de una forma
muy sencilla ya que emplea ficheros de configuración en formato <a href="https://es.wikipedia.org/wiki/YAML">YAML</a>
para ello.</p>
</li>
<li>
<p><a href="https://github.com/remiprev/teamocil">teamocil</a> es una utilidad que nos permite crear esquemas de ventanas y
paneles predefinidos con facilidad empleando el formato YAML. También está
escrito en Ruby, en cuya comunidad de desarrolladores tmux está muy implantado.</p>
</li>
</ul>
<p>Aquí se puede ver una ventana de tmux con mi configuración en la que se muestra
la sesión <code>www</code> donde tengo agrupadas varias ventanas con aplicaciones
relacionadas con la web. Se puede ver como estoy en la ventana 2 de 4 y como he
personalizado la barra de estado:</p>
<p style="text-align:center;"><img src="pictures/tmux_www.png" width="700"
height="429" alt="tmux con una sesión para internet" /></p>
<h2 id="mi_configuraci+n">Mi configuración</h2>
<p>Mi configuración de tmux puede encontrarse en mi repositorio <em>dotfiles</em> en
<a href="http://github.com/joedicastro/dotfiles">GitHub</a>. Mi configuración se apoya en la muchos otros usuarios que me han
aportado ideas y en buena parte gracias a la lectura del libro <a href="http://pragprog.com/book/bhtmux/tmux">tmux: Productive
Mouse-Free Development</a> de Brian P. Hogan.</p>
<p>En esta otra imagen se puede ver una sesión de desarrollo con tmux, donde tengo
abiertos tres paneles con tres aplicaciones (de izquierda a derecha y de arriba
a abajo): vim, <a href="http://ipython.org/">ipython </a> y <a href="http://jonas.nitro.dk/tig/">tig</a>. Así mismo hay una ventana adicional
donde tengo un shell bash. Pulsar sobre ella para ver a tamaño completo.</p>
<p style="text-align:center;"><a href="pictures/tmux_develop_full.png" alt="tmux
como entorno de desarrollo" title="tmux como entorno de desarrollo"><img
src="pictures/tmux_develop.png" width="700" height="430" alt="tmux como entorno
de desarrollo" /></a></p>
<p>Voy a destacar algunos puntos reseñables de mi configuración. Lo primero que
configuro es la combinación de teclas conocida como <code>Prefix</code> que es la
combinación que precede a los atajos de teclado de tmux. Esto se hace de este
modo para no interferir con los atajos de teclado de las aplicaciones que
ejecutemos dentro de tmux. El prefijo por defecto de tmux es <strong><code>Ctrl + b</code></strong>,
pero para los que estábamos acostumbrados a <strong>screen</strong> la combinación <strong><code>Ctrl +
a</code></strong> es más idónea. Y también porque es más cómodo de teclear, sobre todo si
como en mi caso, tienes mapeada una tecla de <strong><code>Ctrl</code></strong> adicional en lugar de
<strong><code>Bloq Mays</code></strong>. Bueno, en realidad uso la tecla <strong><code>Bloq Mays</code></strong> también como
tecla <strong><code>Esc</code></strong> cuando no es pulsada en combinación con otras, gracias a la
maravillosa pequeña utilidad <a href="https://github.com/alols/xcape">xcape</a>, muy útil para los usuarios de Vim.</p>
<div class="codehilite"><pre><span class="gp">#</span> Use C-a instead of C-b as the prefix
<span class="go">set -g prefix C-a</span>
<span class="go">unbind-key C-b</span>
<span class="go">bind-key C-a send-prefix</span>
</pre></div>
<p>Para emplear 256 colores y indicarle que interprete de shell emplear, se lo
indico mediante las siguientes lineas</p>
<div class="codehilite"><pre><span class="gp">#</span> <span class="nb">set </span>256 colors
<span class="go">set -g default-terminal "screen-256color"</span>
<span class="gp">#</span> <span class="nb">set </span>default shell
<span class="go">set -g default-command "exec /bin/bash"</span>
</pre></div>
<p>También cambio el retraso inicial después de pulsado el prefijo, para que no de
problemas con otras aplicaciones como vim y para mejorar su respuesta.</p>
<div class="codehilite"><pre><span class="gp">#</span> be more responsive, changing the default delay
<span class="go">set -sg escape-time 1</span>
</pre></div>
<p>Para hacer más fácil el cambio entre ventanas y paneles a través de los números
de los mismos, lo que hago es que empiecen a contar desde 1 y no desde 0</p>
<div class="codehilite"><pre><span class="gp">#</span> Start numbering at 1
<span class="go">set -g base-index 1</span>
<span class="go">setw -g pane-base-index 1</span>
</pre></div>
<p>Esto es muy útil para comprobar cambios en la configuración sobre la marcha sin
necesidad de cerrar las sesiones. Este comando me permite recargar la
configuración en vivo con la combinación <strong><code>prefix r</code></strong></p>
<div class="codehilite"><pre><span class="gp">#</span> force a reload of the config file
<span class="go">unbind r</span>
<span class="go">bind r source-file ~/.tmux.conf \; display "Reloaded!"</span>
</pre></div>
<p>Para moverme entre los paneles y cambiar su tamaño empleo las teclas típicas de
movimiento de vim para no tener que abandonar los dedos de la fila principal del
teclado.</p>
<div class="codehilite"><pre><span class="gp">#</span> moving between panes
<span class="go">bind h select-pane -L</span>
<span class="go">bind j select-pane -D</span>
<span class="go">bind k select-pane -U</span>
<span class="go">bind l select-pane -R</span>
<span class="gp">#</span> Quick pane selection
<span class="go">bind -r C-h select-window -t :-</span>
<span class="go">bind -r C-l select-window -t :+</span>
<span class="gp">#</span> Pane resizing
<span class="go">bind -r H resize-pane -L 5</span>
<span class="go">bind -r J resize-pane -D 5</span>
<span class="go">bind -r K resize-pane -U 5</span>
<span class="go">bind -r L resize-pane -R 5</span>
</pre></div>
<p>La barra de estado que empleo está inspirada en el plugin de Vim,
<a href="https://github.com/Lokaltog/vim-powerline/">vim-powerline</a>, que le otorga una estética más lograda que la original. Es
necesario emplear para ello una fuente monoespaciada parcheada especialmente,
con los símbolos que emplea vim-powerline. Se pueden encontrar varias en su
<a href="https://github.com/Lokaltog/vim-powerline/wiki/Patched-fonts">wiki</a>. Yo empleo mi fuente preferida que es Dejavu Sans Mono.</p>
<div class="codehilite"><pre><span class="gp">#</span> Custom status bar
<span class="gp">#</span> Powerline symbols: ⮂ ⮃ ⮀ ⮁ ⭤
<span class="go">set -g status-utf8 on</span>
<span class="go">set -g status-left-length 32</span>
<span class="go">set -g status-right-length 150</span>
<span class="go">set -g status-interval 2</span>
<span class="go">set -g status-left '#[fg=colour15,bg=colour238,bold] #S #[fg=colour238,bg=colour234,nobold]⮀'</span>
<span class="go">set -g status-right '#[fg=colour245]⮃ %R ⮃ %d %b #[fg=colour254,bg=colour234,nobold]⮂#[fg=colour16,bg=colour254,bold] #h '</span>
<span class="go">set -g window-status-format "#[fg=white,bg=colour234] #I #W "</span>
<span class="go">set -g window-status-current-format "#[fg=colour234,bg=colour39]⮀#[fg=colour16,bg=colour39,noreverse,bold] #I ⮁ #W #F #[fg=colour39,bg=colour234,nobold]⮀"</span>
</pre></div>
<p>Por último unos atajos de teclado muy útiles que me permiten hacer un zoom
temporal de un panel a ventana completa y luego regresar a la distribución
original de paneles.</p>
<div class="codehilite"><pre><span class="gp">#</span> Maximize and restore a pane
<span class="go">unbind Up</span>
<span class="go">bind Up new-window -d -n tmp \; swap-pane -s tmp.1 \; select-window -t tmp</span>
<span class="go">unbind Down</span>
<span class="go">bind Down last-window \; swap-pane -s tmp.1 \; kill-window -t tmp</span>
</pre></div>Productividad & Linux: Turses2012-06-21T22:50:00+02:00joe di castrohttp://joedicastro.com/productividad-linux-turses.html<p>Que medio mundo parece estar conectado a <a href="http://twitter.com">Twitter</a> no es
ninguna novedad. Y que si sigues a un buen número de personas, el intentar estar
al tanto de todo lo que ocurre es una temeridad, tampoco debería sorprender a
nadie. De hecho, dado su éxito y el enorme flujo de información que circula por
él, se han desarrollado cientos de herramientas para gestionarlo.</p>
<p>Desde que cree mi cuenta en twitter, he probado unas cuantas, unas veinte (y
solo en Linux, en el resto uso la web). La primera, y la elección más obvia ya
que por aquel entonces usaba Ubuntu, fue <strong>Gwibber</strong> . Luego cansado de sus
muchos problemas, probé un sinnúmero de aplicaciones, solo merece la pena
reseñar una: <a href="http://hotot.org/">Hotot</a>. Es la mejor aplicación gráfica para twitter en Linux
que conozco.</p>
<p>Pero guiado por el mismo objetivo de <a href="http://joedicastro.com/tag/productividad.html">mejorar la productividad</a> en mis
herramientas habituales de trabajo, me lancé a la búsqueda de un cliente de
twitter que encajara en la misma filosofía. No hay muchas alternativas, la
mayoría, hay que reconocerlo, son demasiado "crudas" incluso para mí, que soy un
amante de la consola. Pero entonces dí con una pequeña joya, <a href="http://tyrs.nicosphere.net/">Tyrs</a>,
desarrollada por <a href="https://github.com/Nic0">Nicolas Paris</a>. Era una herramienta sencilla, pero que
cumplía muy bien con todo lo que buscaba de ella. Pero un buen día, Nicolas, en
su afán por mejorarla, empezó a reescribir la herramienta empleando una nueva
librería para gestionar el interfaz. Las primeras versiones tenían varios fallos
y Nicolas pronto se vio desbordado por una tarea que no le apetecía continuar y
a la que no podía dedicar más tiempo. Y <a href="http://www.nicosphere.net/small-projects-life-depends-on-his-owner/">decidió abandonar el proyecto</a>,
con la esperanza de que alguien se atreviera a retomarlo. Cuando leí la entrada
de su blog no perdí la esperanza del todo, al fin y al cabo, estaba desarrollado
en Python, un lenguaje con el que me desenvuelvo. Mientras esperaba que hacer,
seguí usando la última versión estable a diario. Pero entonces, apareció el
milagro, <strong>Turses</strong></p>
<h2 id="turses">Turses</h2>
<p><a href="https://github.com/alejandrogomez/">Alejandro Gómez</a>, un usuario de <strong>Tyrs</strong> <a href="http://dialelo.com/Python/turses/2012/03/02/turses-un-cliente-de-twitter-con-interfaz-ncurses.html">se lanzó</a> a crear su
propia aplicación basándose en él. Y no solo garantizaba la continuidad del buen
trabajo empezado por Nicolas, si no que llegaba lleno de ideas frescas y muchas
ganas de hacerlo bien. El propio Nicolas <a href="http://www.nicosphere.net/turses-a-fork-from-tyrs-ncurses-twitter-client/">le felicitó</a> por el trabajo
y la iniciativa. A día de hoy, el proyecto se sigue desarrollando, y aunque aún
tiene algunas metas marcadas por delante, la aplicación es perfectamente usable
en el día a día, de hecho es mi cliente habitual.</p>
<p>Como ya se habrá podido deducir, <a href="https://github.com/alejandrogomez/Turses">Turses</a> es un cliente de twitter para la
consola con interfaz <a href="https://es.wikipedia.org/wiki/Ncurses">ncurses</a>. Está desarrollado en Python y emplea la
librería <a href="http://excess.org/urwid/">Urwid</a> para crear la interfaz en curses. Lo mejor de esta
aplicación es que emplea atajos de teclado inspirados en <strong>Vim</strong> y es
totalmente controlable desde el teclado. Esto unido a que emplea una interfaz
basada en texto, la convierten en la aplicación más ágil de todas las que haya
probado. <strong>Hotot</strong> también tiene algunas combinaciones de teclas muy útiles,
pero ni se acercan a lo que <strong>Turses</strong> te permite.</p>
<p>Aquí se puede ver el aspecto por defecto de Turses</p>
<p style="text-align:center;"><img src="pictures/turses.png" width="700"
height="290" alt="Turses" /></p>
<p>Pero no se acaban ahí las bondades de Turses, tiene algunas características
geniales como la gestión dinámica de bufferes (líneas temporales) y de columnas.
Demos un repaso a lo que nos permite la aplicación:</p>
<ul>
<li><strong>Múltiples líneas temporales</strong> (<em>bufferes</em>). Es decir, nos permite consultar
los tweets de la gente a la que seguimos, los nuestros, menciones, etc. Es
decir, los bufferes habituales, incluidos conversaciones, búsquedas y
hashtags. Y podemos tenerlas simultáneamente abiertas y navegar entre ellas
muy fácilmente.</li>
<li><strong>Múltiples columnas</strong>. En cada columna se sitúa un buffer, y podemos añadir
o quitar columnas a voluntad de forma muy sencilla. Es decir, que podemos
visualizar un solo buffer de forma predefinida, o podemos ver varios a la vez
distribuidos en múltiples columnas.</li>
<li><strong>Tweet, Reply, Retweet, Borrar</strong>. Vamos, que permite las operaciones
habituales con los tweets. Además se puede hacer un Retweet editando el texto,
algo que parece obvio, pero que en algunas aplicaciones no es tan sencillo.</li>
<li><strong>Seguir/dejar de seguir</strong> a un usuario. Podemos hacerlo bien a través de un
tweet o bien introduciendo el nombre del usuario.</li>
<li><strong>Des/Marcar como favorito</strong>.</li>
<li><strong>Enviar mensajes directos</strong>.</li>
<li><strong>Abrir URLs en un navegador</strong>. Nos permite abrir las direcciones que aparecen
en un tweet, así como abrir el propio tweet.</li>
<li><strong>Visualizar conversaciones</strong>. Podemos abrir un nuevo buffer con la
conversación relacionada con un tweet.</li>
<li><strong>Contador de los no leídos</strong> funciona para todos los bufferes y nos permite
ponerlo a cero manualmente cuando queremos ignorar algunos no leídos.</li>
<li><strong>Búsqueda</strong>. Se puede buscar tanto por usuario como por termino.</li>
<li><strong>Ver los tweets de cualquier usuario </strong>.</li>
<li><strong>Visualizar el perfil de un usuario</strong>.</li>
<li><strong>Totalmente personalizable</strong> y la configuración se guarda en un fichero de
texto plano.</li>
<li><strong>Múltiples cuentas</strong>, eso sí, una por ejecución.</li>
<li><strong>Ayuda en línea</strong> con todas las combinaciones de teclas posibles. Accesible a
través de la tecla <strong><code>?</code></strong></li>
</ul>
<p>Interfaz de Turses mostrando múltiples columnas</p>
<p style="text-align:center;"><img src="pictures/turses_2cols.png" width="700"
height="285" alt="Turses con multiples columnas" /></p>
<p>Y entre las metas que tiene marcadas su autor, nos encontramos con el soporte
para listas, streaming, notificaciones emergentes y múltiples sesiones. Estoy
seguro de que las acabará incorporando, le sobra capacidad. Aunque he de reseñar
que actualmente he contribuido con una porción de código minúscula al proyecto y
que tengo la intención de seguir colaborando en todo lo que pueda. Si eres
programador Python y te apetece echar una mano, <a href="https://github.com/alejandrogomez/Turses">anímate</a>, Alejandro es muy
receptivo y un tío muy majo que estará encantado con toda la ayuda que le
podamos dar.</p>
<h2 id="mi_configuraci+n">Mi configuración</h2>
<p>Si a alguien le puede servir como inspiración mi configuración, esta disponible
en <a href="http://github.com/joedicastro/dotfiles">GitHub</a></p>
<p>Turses mostrando la información del perfil del autor de un tweet</p>
<p style="text-align:center;"><img src="pictures/turses_uinfo.png" width="700"
height="429" alt="Turses mostrando la información de un usuario" /></p>
<h2 id="alternativas">Alternativas</h2>
<p>Solo conozco dos alternativas en la misma línea que merezca la pena reseñar, las
demás que he probado no estaban a la altura:</p>
<ul>
<li>
<p><a href="http://www.vim.org/scripts/script.php?script_id=2204">TwitVim</a>, es un plugin para Vim. Funciona fantásticamente bien, eso sí,
solo apropiado para usuarios de Vim. La probé un tiempo y me gusto, pero
personalmente no me gusta emplear Vim para esta tarea y Turses es bastante más
manejable.</p>
</li>
<li>
<p><a href="http://www.floodgap.com/software/ttytter/">TTYtter</a>, está escrito en Perl y no tiene interfaz. Trabaja en la línea
de comandos a modo de interprete. Funciona muy bien y también lo usé un
tiempo, pero su propio funcionamiento le reste eficiencia comparado con
Turses.</p>
</li>
</ul>Productividad & Linux: Newsbeuter2012-06-18T23:26:00+02:00joe di castrohttp://joedicastro.com/productividad-linux-newsbeuter.html<p>Uno de los pilares de la productividad es, como no, la gestión del tiempo. Otro
de los pilares fundamentales es, inexorablemente, el conocimiento. Si pierdes el
tiempo en tareas irrelevantes (o directamente procrastinando), tu productividad
se resiente irremediablemente. Si no tiene los conocimientos adecuados y
suficientes, consumes el tiempo aprendiendo a hacerlo o directamente lo pierdes
haciéndolo mal. Hoy en día, rara es la actividad donde la formación continua no
sea un requisito indispensable, no ya para mejorar o mantener tu rendimiento, si
no simplemente para poder seguir ejerciéndola.</p>
<p>Por lo tanto nos vemos condenados a intentar mantenernos al día (y ampliar
conocimientos), mientras que procuramos dedicarle el menor tiempo posible para
no menoscabar nuestro rendimiento. Tal delicado equilibrio no es poca hazaña en
nuestros días. Nos vemos inundados de tal cantidad de información, que el
filtrado es la única manera de intentar sobrevivir a esa enorme vorágine de
datos a la que nos enfrentamos. Afortunadamente tenemos herramientas. Desde hace
muchos años he confiado esta tarea a emplear fuentes <strong>RSS</strong> de calidad y una
buena herramienta para gestionarlas.</p>
<h2 id="mi_b+squeda_del_cliente_rss_ideal">Mi búsqueda del cliente RSS ideal</h2>
<p>He empleado muchas herramientas distintas para esta tarea, siempre intentando
tener la más idónea para filtrar muchas fuentes RSS en el menor tiempo posible,
sin pasar por alto lo que me interesa conocer. Algunas muy buenas, que usaba
cuando aún empleaba Windows como SO principal, ya no existen. En Linux he pasado
por las más conocidas (en orden cronológico):</p>
<ul>
<li>
<p><a href="http://liferea.sourceforge.net/">Liferea</a>, era muy buena cuando la deje, lo de mostrar los comentarios en
las entradas es algo que no he vuelto a ver en ninguna otra herramienta. Pero
después de varios años de uso, la abandoné cuando se había convertido en
insufriblemente lenta.</p>
</li>
<li>
<p><a href="http://userbase.kde.org/Akregator">Akregator</a>, no era para mí, nunca acabe encontrándome a gusto con ella.
Lo hacía todo medianamente bien, pero no destacaba en nada, pronto la
abandoné.</p>
</li>
<li>
<p><a href="http://www.blogbridge.com/">Blogbride</a>, su planteamiento es diferente al resto. Es una buena
aplicación y estuve con ella muchos meses. Pero siempre seguí buscando algo
más eficiente.</p>
</li>
<li>
<p><a href="http://www.rssowl.org/">RSSOwl</a>, la mejor aplicación para leer RSS para escritorio que he
conocido. La he usado durante años. Está construida sobre Eclipse. Ofrece
muchas posibilidades de personalización y filtrado. Es muy rápida, pero debido
a que depende de Eclipse y java, si manejas un número considerable de fuentes
(+1000 en aquella época), se puede volver un poco pesada. Además, si como yo,
dejabas muchos artículos para leer en otro momento, la base de datos crecía de
tal manera, que podía llegar a ser muy lenta. La abandoné buscando algo aún
más ágil y productivo.</p>
</li>
<li>
<p><a href="https://es.wikipedia.org/wiki/Google_Reader">Google Reader</a>, decidí darle una oportunidad. Por aquella época
había empezado a usar Read it Later (hoy <a href="http://getpocket.com">Pocket</a>) para guardar aquello
que quería leer en otro momento o con más calma. La integración con RIL me
obligaba a abandonar el teclado y usar el ratón. Además el rediseño que hizo
Google no me convencía. Decidí buscar algo aún más rápido y eficiente.</p>
</li>
</ul>
<p>Durante todo ese tiempo probé muchísimas otras alternativas (incluidos
complementos para navegadores web) y no encontraba nada que me valiese. Es
muy difícil encontrar una aplicación de este tipo que te permita manejar un gran
número de fuentes RSS de forma realmente eficiente. Al final ya estaba decidido
a regresar a RSSOwl. Pero acostumbrado a <a href="http://joedicastro.com/productividad-linux-pentadactyl.html">Pentadactyl</a> y Vim y las aplicaciones
<a href="https://es.wikipedia.org/wiki/Ncurses">ncurses</a>, decidí buscar algo en esa línea, y lo encontré.</p>
<h2 id="newsbeuter">Newsbeuter</h2>
<p><a href="http://www.newsbeuter.org/">Newsbeuter</a> es un juego de palabras con la palabra alemana "Wildbeuter"
que significa <a href="https://es.wikipedia.org/wiki/Cazador_recolector">cazador-recolector</a>, por lo que Newsbeuter vendría a ser
algo así como <em>Cazador/Recolector de Noticias</em>. Newsbeuter es una aplicación
para leer fuentes RSS y Atom que utiliza una interfaz tipo ncurses para consola.
Quién esté familiarizado con el cliente de correo <a href="https://es.wikipedia.org/wiki/Mutt">Mutt</a> se sentirá cómodo
enseguida, ya que se inspira en este. Está programado en C++ y dado que funciona
en modo texto, una de sus ventajas es la enorme agilidad que proporciona para
moverse entre fuentes y noticias.</p>
<p>Un resumen de sus características:</p>
<ul>
<li>Permite suscribirnos a fuentes RSS y Atom</li>
<li>Soporta <a href="https://es.wikipedia.org/wiki/OPML">OPML</a> tanto para importar como para exportar las subscripciones</li>
<li>Descarga de podcasts</li>
<li>Se pueden configurar todos los atajos de teclado libremente</li>
<li>Podemos realizar búsquedas entre todos los artículos descargados. Similar a
Vim</li>
<li>Es posible crear etiquetas para dividir nuestras subscripciones en categorías y
realizar filtrados y búsquedas en función a ellas</li>
<li>Se pueden sincronizar las fuentes con Google Reader y <a href="http://tt-rss.org/redmine/">Tiny Tiny RSS</a></li>
<li>Podemos configurar el color y las cadenas de texto para personalizar su
aspecto</li>
<li>Se pueden eliminar de forma automática artículos que no deseemos a través
de un <a href="https://en.wikipedia.org/wiki/Kill_file">"killfile"</a></li>
<li>Es posible integrar cualquier fuente de datos a través de un flexible sistema
de filtros y plugins: Fichero con urls, fichero OPML, fichero OPML online, Google
Reader, varios ficheros...</li>
<li>Se pueden crear "meta fuentes" empleando un potente lenguaje de consultas</li>
<li>Permite crear marcadores a partir de cualquier enlace del articulo empleando
una aplicación externa o un script</li>
<li>Permite guardar artículos en texto plano</li>
<li>Podemos otorgar etiquetas de un solo carácter que el autor denomina "flags"
por articulo y varias por articulo. Útiles para emplearlas conjuntamente con
los filtros</li>
<li>Se pueden definir macros</li>
<li>Linea de comandos para poder ejecutar comandos y cambiar opciones sobre la
marcha</li>
<li>Funciona en Linux, Mac OS y FreeBSD</li>
<li>Programado en C++ y guarda los artículos en una BDD <a href="http://sqlite.org/">SQLite</a></li>
<li><a href="http://newsbeuter.org/doc/newsbeuter.html">Documentación</a> bastante completa</li>
</ul>
<p>Pantalla con la configuración por defecto de Newsbeuter</p>
<p style="text-align:center;"><img src="pictures/newsbeuter_default.png" width="700"
height="410" alt="Newsbeuter" /></p>
<h2 id="lo_que_lo_distingue">Lo que lo distingue</h2>
<p>Muchas de estas características las comparte con otras aplicaciones de las
mencionadas antes, pero lo que realmente distingue a Newsbeuter de todas ellas
es lo siguiente:</p>
<ul>
<li>Totalmente controlable desde el teclado, lo que unido a su velocidad, le
proporciona una agilidad inigualable.</li>
<li>Basado en texto, lo que nos evita distraernos de lo importante, el contenido.</li>
<li>Consumo ridículo de memoria y recursos comparado con cualquiera aplicación
mencionada antes. En el peor de los casos, me ha consumido unos 30 MiB de RAM
(para la versión de 64 bits)</li>
<li>Se puede configurar el números de hilos de proceso para descargar noticias. En
mi caso, con 8 hilos, tarda unos 40s en leer unos 250 canales RSS. Solo Google
Reader por su funcionamiento, puede mejorar esto.</li>
<li>Configurable con un fichero de texto plano</li>
</ul>
<p>Como dijo <a href="http://www.zedshaw.com/essays/i_want_the_mutt_of_feed_readers.html">Zed Shaw</a> y refrenda el autor de la aplicación, <a href="http://synflood.at/">Andreas
Krennmair</a>,</p>
<blockquote>
<p>"Newsbeuter es el Mutt de los lectores de noticias RSS"</p>
</blockquote>
<p>Desde mi propia experiencia puedo decir que este programa ha cambiado mi forma
de leer las <em>noticias del día</em>. Antes, para mi, era muy importante que el lector
de noticias que empleara, utilizara un estilo homogéneo entre todas las fuentes y
artículos, con el fin de centrarme en el contenido y no perder el tiempo con
nimiedades. Es algo más importante de lo que pueda parecer a simple vista, cuando
quieres emplear el menor tiempo posible en adquirir la información y al mismo
tiempo quieres asimilar lo que lees. Si cuando vas a leer las noticias tienes 45
minutos y 300 artículos sin leer, el cambiar de un articulo con fondo negro y
letra Sans Serif mediana a uno con fondo blanco y letra Serif enorme, te supone
una distracción y una adaptación de la vista innecesarias e incomodas.</p>
<p>Vista de un articulo con mi configuración</p>
<p style="text-align:center;"><img src="pictures/newsbeuter_articulo.png"
width="700" height="843" alt="Articulo en Newsbeuter" /></p>
<p>Pero al comenzar a emplear Newsbeuter me di enseguida cuenta de algo, el carecer
por completo de imágenes y compartir cabecera entre todos los artículos, me ha
servido para pasar por alto o leer en diagonal aquello que menos me interesa. No
solo filtro más rápido, si no que lo hago más eficientemente. Evidentemente hay
artículos en los que las imágenes complementan necesariamente al articulo. En
estos casos o bien la abro directamente en el navegador (tan sencillo como
pulsar <strong><code>o</code></strong> ) o bien puedo abrir las imágenes de forma independiente en el
mismo si me interesa por ejemplo ver solo una. En este sentido, Newsbeuter
proporciona una lista de todas las Urls presentes en el articulo en forma de
lista al final del mismo, pudiendo abrir cualquiera de ellas introduciendo el
indice de la misma. De hecho, empleando el comando <strong><code>u</code></strong> podemos acceder a la
lista completa de las mimas en una nueva ventana.</p>
<h2 id="mi_configuraci+n">Mi configuración</h2>
<p>Mi configuración no tiene demasiado de especial, quizás que emplea una
combinación de colores distinta a la habitual y que empleo un par de scripts
para las notificaciones y para crear marcadores. Esta se puede encontrar en mi
repositorio de mis <em>dotfiles</em> en <a href="http://github.com/joedicastro/dotfiles">GitHub</a></p>
<h2 id="notificaciones">Notificaciones</h2>
<p>Para las notificaciones que emite Newsbeuter después de refrescar las noticias
empleo el script <code>notify.py</code> que comentaba en este <a href="http://joedicastro.com/notificaciones-de-escritorio-en-ubuntu-desde-python.html">articulo</a>
ligeramente modificado para trabajar con Newsbeuter. En la imagen se puede ver
una notificación del programa.</p>
<p style="text-align:center;"><img src="pictures/newsbeuter_notify.png"
width="487" height="68" alt="Notificación de Newsbeuter" /></p>
<div class="codehilite"><pre><span class="k">try</span><span class="p">:</span>
<span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">import</span> <span class="nn">gtk</span>
<span class="kn">import</span> <span class="nn">pynotify</span>
<span class="kn">import</span> <span class="nn">textwrap</span>
<span class="n">NOT_NOTIFY</span> <span class="o">=</span> <span class="bp">False</span>
<span class="k">except</span> <span class="ne">ImportError</span><span class="p">:</span>
<span class="n">NOT_NOTIFY</span> <span class="o">=</span> <span class="bp">True</span>
<span class="k">def</span> <span class="nf">notify</span><span class="p">(</span><span class="n">title</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="n">icon</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">wrap</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
<span class="sd">"""Send notification icon messages through libnotify.</span>
<span class="sd"> Parameters:</span>
<span class="sd"> (str) title -- The notification title</span>
<span class="sd"> (str) msg -- The message to display into notification</span>
<span class="sd"> (str / uri) icon -- Type of icon (ok|info|error|warm|ask|sync) or icon file</span>
<span class="sd"> """</span>
<span class="k">if</span> <span class="n">NOT_NOTIFY</span><span class="p">:</span>
<span class="k">return</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">pynotify</span><span class="o">.</span><span class="n">is_initted</span><span class="p">():</span>
<span class="n">pynotify</span><span class="o">.</span><span class="n">init</span><span class="p">(</span><span class="n">title</span><span class="p">)</span>
<span class="n">gtk_icon</span> <span class="o">=</span> <span class="p">{</span><span class="s">'ok'</span><span class="p">:</span> <span class="n">gtk</span><span class="o">.</span><span class="n">STOCK_YES</span><span class="p">,</span>
<span class="s">'info'</span><span class="p">:</span> <span class="n">gtk</span><span class="o">.</span><span class="n">STOCK_DIALOG_INFO</span><span class="p">,</span>
<span class="s">'error'</span><span class="p">:</span> <span class="n">gtk</span><span class="o">.</span><span class="n">STOCK_DIALOG_ERROR</span><span class="p">,</span>
<span class="s">'warm'</span><span class="p">:</span> <span class="n">gtk</span><span class="o">.</span><span class="n">STOCK_DIALOG_WARNING</span><span class="p">,</span>
<span class="s">'ask'</span><span class="p">:</span> <span class="n">gtk</span><span class="o">.</span><span class="n">STOCK_DIALOG_QUESTION</span><span class="p">,</span>
<span class="s">'sync'</span><span class="p">:</span> <span class="n">gtk</span><span class="o">.</span><span class="n">STOCK_JUMP_TO</span><span class="p">}</span>
<span class="k">if</span> <span class="n">wrap</span><span class="p">:</span>
<span class="n">msg</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">linesep</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">textwrap</span><span class="o">.</span><span class="n">wrap</span><span class="p">(</span><span class="n">msg</span><span class="p">,</span> <span class="n">wrap</span><span class="p">))</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">note</span> <span class="o">=</span> <span class="n">pynotify</span><span class="o">.</span><span class="n">Notification</span><span class="p">(</span><span class="n">title</span><span class="p">,</span> <span class="n">msg</span><span class="p">)</span>
<span class="n">helper</span> <span class="o">=</span> <span class="n">gtk</span><span class="o">.</span><span class="n">Button</span><span class="p">()</span>
<span class="n">gtk_icon</span> <span class="o">=</span> <span class="n">helper</span><span class="o">.</span><span class="n">render_icon</span><span class="p">(</span><span class="n">gtk_icon</span><span class="p">[</span><span class="n">icon</span><span class="p">],</span> <span class="n">gtk</span><span class="o">.</span><span class="n">ICON_SIZE_BUTTON</span><span class="p">)</span>
<span class="n">note</span><span class="o">.</span><span class="n">set_icon_from_pixbuf</span><span class="p">(</span><span class="n">gtk_icon</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
<span class="n">note</span> <span class="o">=</span> <span class="n">pynotify</span><span class="o">.</span><span class="n">Notification</span><span class="p">(</span><span class="n">title</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="n">icon</span><span class="p">)</span>
<span class="n">note</span><span class="o">.</span><span class="n">show</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
<span class="sd">"""Main section"""</span>
<span class="n">notify</span><span class="p">(</span><span class="s">'Newsbeuter'</span><span class="p">,</span> <span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="s">'/home/joedicastro/.newsbeuter/icon.png'</span><span class="p">)</span>
<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">"__main__"</span><span class="p">:</span>
<span class="n">main</span><span class="p">()</span>
</pre></div>
<h2 id="integraci+n_con_pocket">Integración con Pocket</h2>
<p>Utilizo <a href="http://getpocket.com">Pocket</a> como nexo de unión entre el navegador y el Newsbeuter para
archivar todos aquello artículos que me interesa leer, pero que quiero dejar
para otro momento más idóneo. Hubo un tiempo en que empleaba <a href="http://delicious.com/">Delicious</a>
para esta tarea, pero me parece más adecuado Pocket.</p>
<p>Esto lo consigo empleando el comando para crear marcadores de Newsbeuter y un
script en Python creado para ello. Esta es la parte del archivo de configuración
que relaciona el comando con el script:</p>
<div class="codehilite"><pre><span class="n">bookmark</span><span class="o">-</span><span class="n">cmd</span> "<span class="o">~/</span><span class="p">.</span><span class="n">newsbeuter</span><span class="o">/</span><span class="n">send2ril</span><span class="p">.</span><span class="n">py</span>"
</pre></div>
<p>El script hace uso de la <a href="https://bitbucket.org/Surgo/ril/src">API Python</a> para Read it Later (como se llamaba
anteriormente Pocket) para guardar la url del articulo en mi cuenta de Pocket.
Así pulsando <strong><code>Ctrl + b</code></strong> se guarda el marcador en Pocket.</p>
<div class="codehilite"><pre><span class="c">#!/usr/bin/env python</span>
<span class="c"># -*- coding: utf8 -*-</span>
<span class="sd">"""</span>
<span class="sd"> send2ril.py: Send a new url to Read it Later</span>
<span class="sd">"""</span>
<span class="n">__author__</span> <span class="o">=</span> <span class="s">"joe di castro <joe@joedicastro.com>"</span>
<span class="n">__license__</span> <span class="o">=</span> <span class="s">"GNU General Public License version 3"</span>
<span class="n">__date__</span> <span class="o">=</span> <span class="s">"18/06/2012"</span>
<span class="n">__version__</span> <span class="o">=</span> <span class="s">"0.1"</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">import</span> <span class="nn">readitlater</span>
<span class="kn">import</span> <span class="nn">ril_config</span> <span class="kn">as</span> <span class="nn">config</span>
<span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
<span class="sd">"""Main section"""</span>
<span class="n">api</span> <span class="o">=</span> <span class="n">readitlater</span><span class="o">.</span><span class="n">API</span><span class="p">(</span><span class="n">config</span><span class="o">.</span><span class="n">RIL_APIKEY</span><span class="p">,</span> <span class="n">config</span><span class="o">.</span><span class="n">RIL_USERNAME</span><span class="p">,</span>
<span class="n">config</span><span class="o">.</span><span class="n">RIL_PASSWORD</span><span class="p">)</span>
<span class="n">new</span> <span class="o">=</span> <span class="p">[{</span><span class="s">"url"</span><span class="p">:</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="s">"title"</span><span class="p">:</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">2</span><span class="p">]}]</span>
<span class="n">api</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="n">new</span><span class="o">=</span><span class="n">new</span><span class="p">)</span>
<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">"__main__"</span><span class="p">:</span>
<span class="n">main</span><span class="p">()</span>
</pre></div>
<p>En el script se importa un modulo, <code>ril_config</code>, que es el que contiene las
claves de mi cuenta de Pocket, este modulo sería algo similar a esto
(evidentemente los valores son falsos):</p>
<div class="codehilite"><pre><span class="c"># ril credentials</span>
<span class="n">RIL_APIKEY</span> <span class="o">=</span> <span class="s">'987u1ksjsdfRk54kKLKL34jkjij9945k'</span>
<span class="n">RIL_USERNAME</span> <span class="o">=</span> <span class="s">'usuario'</span>
<span class="n">RIL_PASSWORD</span> <span class="o">=</span> <span class="s">'ADRKSD-Xk3kj5kjljFl'</span>
</pre></div>
<p>Por lo tanto para hacerlo funcionar necesitamos crear un fichero <code>ril_config.py</code>
con las credenciales de cada uno para Pocket. Los campos <code>RIL_USERNAME</code> y
<code>RIL_PASSWORD</code> se corresponden evidentemente con el usuario y la contraseña que
tengamos para el servicio. El otro campo, <code>RIL_APIKEY</code> es una clave que podemos
obtener en <a href="http://getpocket.com/api/signup/">esta página</a> para registrar nuestra aplicación (en este caso
nuestro script) y que pueda acceder de forma autorizada a la API de Pocket.</p>
<h3 id="copia_de_seguridad_de_las_urls_de_pocket">Copia de seguridad de las urls de Pocket</h3>
<p>Del mismo modo, aprovechando la misma API que empleo en el anterior script, he
creado otro script que ejecuto regularmente con cron, que me guarda una copia en
mi disco duro con todas las urls que tengo guardadas en Pocket. Vamos, una copia
de seguridad, uno nunca sabe cuando este tipo de servicios pueden dejar de
funcionar. Estas direcciones las guardo en un fichero con formato <a href="https://es.wikipedia.org/wiki/Org-mode">Org-mode</a></p>
<div class="codehilite"><pre><span class="c">#!/usr/bin/env python</span>
<span class="c"># -*- coding: utf8 -*-</span>
<span class="sd">"""</span>
<span class="sd"> get.py: Get the urls stored in Read it Later & save them in a Org-mode file</span>
<span class="sd">"""</span>
<span class="n">__author__</span> <span class="o">=</span> <span class="s">"joe di castro <joe@joedicastro.com>"</span>
<span class="n">__license__</span> <span class="o">=</span> <span class="s">"GNU General Public License version 3"</span>
<span class="n">__date__</span> <span class="o">=</span> <span class="s">"18/06/2012"</span>
<span class="n">__version__</span> <span class="o">=</span> <span class="s">"0.1"</span>
<span class="k">try</span><span class="p">:</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">readitlater</span>
<span class="kn">import</span> <span class="nn">ril_config</span> <span class="kn">as</span> <span class="nn">config</span>
<span class="k">except</span> <span class="ne">ImportError</span><span class="p">:</span>
<span class="c"># Checks the installation of the necessary python modules</span>
<span class="k">print</span><span class="p">((</span><span class="n">os</span><span class="o">.</span><span class="n">linesep</span> <span class="o">*</span> <span class="mi">2</span><span class="p">)</span><span class="o">.</span><span class="n">join</span><span class="p">([</span><span class="s">"An error found importing one module:"</span><span class="p">,</span>
<span class="nb">str</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">exc_info</span><span class="p">()[</span><span class="mi">1</span><span class="p">]),</span> <span class="s">"You need to install it"</span><span class="p">,</span> <span class="s">"Stopping..."</span><span class="p">]))</span>
<span class="n">sys</span><span class="o">.</span><span class="n">exit</span><span class="p">(</span><span class="o">-</span><span class="mi">2</span><span class="p">)</span>
<span class="kn">import</span> <span class="nn">os</span>
<span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
<span class="sd">"""Main section"""</span>
<span class="n">api</span> <span class="o">=</span> <span class="n">readitlater</span><span class="o">.</span><span class="n">API</span><span class="p">(</span><span class="n">config</span><span class="o">.</span><span class="n">RIL_APIKEY</span><span class="p">,</span> <span class="n">config</span><span class="o">.</span><span class="n">RIL_USERNAME</span><span class="p">,</span>
<span class="n">config</span><span class="o">.</span><span class="n">RIL_PASSWORD</span><span class="p">)</span>
<span class="n">items</span> <span class="o">=</span> <span class="n">api</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">state</span><span class="o">=</span><span class="s">"unread"</span><span class="p">)</span>
<span class="n">lista</span> <span class="o">=</span> <span class="n">items</span><span class="p">[</span><span class="s">"list"</span><span class="p">]</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s">"ril_urls.org"</span><span class="p">,</span> <span class="s">"w"</span><span class="p">)</span> <span class="k">as</span> <span class="n">output</span><span class="p">:</span>
<span class="n">output</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">"* Read It Later URLs"</span> <span class="o">+</span> <span class="n">os</span><span class="o">.</span><span class="n">linesep</span><span class="p">)</span>
<span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">k</span> <span class="ow">in</span> <span class="n">lista</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
<span class="n">output</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">"** {0}{1}"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">k</span><span class="p">[</span><span class="s">'title'</span><span class="p">]</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s">"utf8"</span><span class="p">),</span>
<span class="n">os</span><span class="o">.</span><span class="n">linesep</span><span class="p">))</span>
<span class="n">output</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">" [[{0}][Enlace]]{1}{1}"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">k</span><span class="p">[</span><span class="s">'url'</span><span class="p">]</span><span class="o">.</span>
<span class="n">encode</span><span class="p">(</span><span class="s">"utf8"</span><span class="p">),</span> <span class="n">os</span><span class="o">.</span><span class="n">linesep</span><span class="p">))</span>
<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">"__main__"</span><span class="p">:</span>
<span class="n">main</span><span class="p">()</span>
</pre></div>
<h2 id="conclusi+n">Conclusión</h2>
<p>Newsbeuter no es para todo el mundo, por supuesto, la gran mayoría considerarían
decimonónico el emplear un interfaz de texto en vez de uno gráfico. Muchos
incluso llamarían herejía a usar el teclado en vez de el ratón (aunque luego se
vuelvan locos con las pantallas táctiles). Lo respeto y lo entiendo, pero para
aquellos que aman su tiempo y no están dispuestos a desperdiciarlo, deberían
darle una oportunidad a esta aplicación.</p>Productividad & Linux: Pentadactyl2012-06-14T20:52:00+02:00joe di castrohttp://joedicastro.com/productividad-linux-pentadactyl.html<p><a href="http://5digits.org/pentadactyl/">Pentadactyl</a> como su nombre sugiere (<em>"que tiene cinco dedos"</em>), está
pensado para ser usado con los cinco dedos de cada mano, ergo, el teclado. No es
una aplicación en si misma, si no un complemento para el navegador web
<strong>Firefox</strong>. Básicamente podríamos resumirlo en que es un complemento que te
permite controlar Firefox desde el teclado. Pero sería un resumen bastante
injusto para todo lo que te ofrece este plugin. Una pista, los atajos de teclado
están basados en los de
<a href="https://es.wikipedia.org/wiki/Vim">Vim</a>.</p>
<p>Ejemplo de navegación web con Pentadactyl empleando únicamente el teclado.
Observar como el puntero del ratón permanece estático en la misma posición
(parte superior derecha de la pantalla). Es un ejemplo muy básico, pero llega
para hacerse una idea.</p>
<p style="text-align:center;"><img src="pictures/pentadactyl_demo.gif"
width="600" height="400" alt="Pentadactyl" /></p>
<p>En esta imagen se puede ver una ventana de Firefox estándar y una otra de
Firefox con el complemento Pentadactyl activado (con mi configuración). Como se
puede observar, se puede ganar una cantidad significativa de espacio en la
ventana para la página web. En este caso son 170px, un 6% más de espacio
vertical. En el caso de que abriéramos otra pestaña más, aparecería la barra de
pestañas y solo ahorraríamos el espacio que ocupan la barra de menús y la de
navegación. Aunque en mi configuración actual ya he eliminado también la barra de
pestañas e incluso las barras de desplazamiento, solo se ve la línea de estado
de Pentadactyl.</p>
<p style="text-align:center;"><img src="pictures/pentadactyl_vs_ffox.png"
width="700" height="431" alt="Pentadactyl vs Firefox" /></p>
<p>Pero... y la barra de herramientas de navegación, ¿no es necesaria? No, con este
complemento no lo es, dado que las direcciones las introduces a través de la
línea de comandos y la dirección de la página web siempre está visible en la
linea de estado inferior de Pentadactyl. Por ejemplo, para abrir la página web
de google, pulsamos la tecla <strong><code>o</code></strong> y luego escribimos <code>google.es</code> y pulsamos
<strong><code>↵</code></strong> así de sencillo. Si quisiéramos abrirla en una nueva pestaña, bastaría
con pulsar <strong><code>t</code></strong> en lugar de <strong><code>o</code></strong></p>
<p style="text-align:center;"><img src="pictures/pentadactyl_command.png"
width="700" height="118" alt="Linea de comandos de Pentadactyl" /></p>
<p>Aquí se puede ver la línea de estado y la linea de comandos. La línea de
comandos tiene autocompletado y en la imagen se ve como se va a introducir el
comando que activa la completísima ayuda que proporciona el complemento. A la
línea de comandos se accede igual que en Vim, pulsando la tecla <strong><code>:</code></strong></p>
<h2 id="caracter+sticas">Características</h2>
<p>Estas son algunas de las funciones que proporciona Pentadactyl para Firefox, sin
contar con las <a href="http://5digits.org/pentadactyl/plugins">extensiones disponibles para el mismo Pentadactyl</a>:</p>
<ul>
<li>Atajos de teclado basados en vim. Soporta las mismas opciones de contexto que
Vim, por ejemplo, desplazarse dos pestañas hacia la derecha <strong><code>2 <ctrl> +
n</code></strong></li>
<li>Comandos para prácticamente cualquier función de Firefox. Ejemplo: abrir la
ventana de complementos, <strong><code>:dialog addons</code></strong> que puede abreviarse como <strong><code>:dia
addo↹</code></strong></li>
<li>Autocompletado para todos los comandos, opciones, marcadores, bufferes,
motores de búsqueda, ...</li>
<li>Características de privacidad adicionales a las de Firefox y muy potentes</li>
<li>Búsqueda dentro de la página (con resaltado) y navegación a través de los
resultados. Similar a la búsqueda de Vim. Se pueden emplear expresiones
regulares</li>
<li>Macros de teclado (se pueden grabar sobre la marcha) y se pueden personalizar
los atajos de teclado y los comandos (pudiendo ademas añadir otros)</li>
<li>Esquemas de color y extensiones (algunas muy interesantes)</li>
<li>Navegación potente y rápida a través de enlaces, campos de formularios, áreas
de texto, ... desde el teclado</li>
<li>Linea de estado similar a la de Vim</li>
<li>Se pueden ejecutar comandos de shell directamente en la línea de comandos de
Pentadactyl</li>
<li>Interfaz mínimo, pudiendo ocultar menús, barras de herramientas, barras de
desplazamiento y pestañas</li>
<li>Se pueden cargar scripts directamente con el comando <strong><code>:source</code></strong>, soportando
ficheros javascript y CSS, además de comandos propios de Pentadactyl</li>
<li>Se pueden emplear alarmas visuales o sonoras para indicarnos errores</li>
<li>Posibilidad de establecer marcadores de posición dentro de páginas</li>
<li>Marcadores rápidos para acceder de forma rápida a los sitios que queramos</li>
<li>Se pueden editar los campos de texto desde un editor externo</li>
<li>AutoComandos para ejecutar acciones activadas por ciertos eventos</li>
<li>Sistema de ayuda incorporado completísimo que cubre todo lo que el plugin
puede hacer. A la ayuda se accede bien a través de los comandos <strong><code>:help</code></strong> o
<strong><code>:helpall</code></strong> o bien pulsando la tecla <strong><code>F1</code></strong></li>
</ul>
<p>No es mi intención explicar aquí la forma de trabajar con el complemento, ya que
posee tantas opciones y una ayuda tan completa, que lo considero excesivo.
Además no es necesario conocer toda su funcionalidad, de hecho yo sigo
infrautilizandolo y voy descubriendo funciones nuevas de vez en cuando. Por
ejemplo, hasta que no he vuelto a repasar sus funciones para escribir este
articulo, estaba empleando un plugin (It's All Text!) para editar los campos de
texto con gVim, ahora lo hago también con Pentadactyl y de manera aún más
sencilla. Y con este ya van ocho complementos para Firefox que he dejado de
usar porque los suplo con Pentadactyl.</p>
<h2 id="mi_configuraci+n">Mi configuración</h2>
<p>Mi configuración es realmente sencilla, ya que aparte de emplear un par de
extensiones, un par de comandos y un esquema de color, lo demás es cambiar
ciertas opciones predefinidas del mismo. La configuración la he dejado
disponible en mi repositorio de <code>dotfiles</code>, en <a href="http://github.com/joedicastro/dotfiles">GitHub</a>.</p>
<h3 id="validar_el_html_de_una_p+gina">Validar el HTML de una página</h3>
<p>Este es un comando que he añadido a la configuración para poder validar el HTML
de una página empleando la <a href="http://validator.w3.org/">herramienta del W3C</a>. Como se puede ver, se
basa en emplear javascript para definir lo que queremos hacer:</p>
<div class="codehilite"><pre><span class="nx">command</span><span class="o">!</span> <span class="o">-</span><span class="nx">description</span><span class="o">=</span><span class="s1">'Validar XHTML'</span> <span class="nx">valid</span> <span class="o">:</span><span class="nx">open</span>
<span class="nx">javascript</span><span class="o">:</span><span class="k">void</span><span class="p">(</span><span class="nx">location</span><span class="o">=</span><span class="s1">'http://validator.w3.org/check?uri='</span><span class="o">+</span><span class="nx">escape</span><span class="p">(</span><span class="nx">location</span><span class="p">))</span>
</pre></div>
<p>Aquí se puede ver como funciona:</p>
<p style="text-align:center;"><img src="pictures/validate.gif" width="640"
height="400" alt="validate HTML" /></p>
<p>Gracias al autocompletado de Pentadactyl, solo es necesario escribir las dos
primeras letras del comando y pulsar el tabulador y finalmente Intro para
ejecutar la operación. Nos aparece la herramienta del W3C diciendo que la página
ha validado correctamente como HTML 5. Y desde luego esto es más rápido que
emplear el ratón conjuntamente con otro plugin.</p>
<h3 id="guardar_paginas_en_pocket_anteriormente_read_it_later">Guardar paginas en Pocket (anteriormente Read it Later)</h3>
<p>Para guardar páginas en <a href="http://getpocket.com">Pocket</a>, el que hasta hace unas semanas era Read
it Later, empleo también otro comando. Antes empleaba el plugin oficial, pero no
solo consumía memoria si no que para emplear solamente una combinación de
teclas, empleo un comando de Pentadactyl y me ahorro el tenerlo instalado.</p>
<div class="codehilite"><pre><span class="nx">command</span><span class="o">!</span> <span class="nx">pocket</span> <span class="o">-</span><span class="nx">description</span> <span class="s2">"Bookmarklet: Save to Pocket"</span> <span class="nx">open</span>
<span class="nx">javascript</span><span class="o">:</span><span class="p">(</span><span class="kd">function</span><span class="p">(){</span><span class="nx">ISRIL_H</span><span class="o">=</span><span class="s1">'83dd'</span><span class="p">;</span><span class="nx">PKT_D</span><span class="o">=</span><span class="s1">'getpocket.com'</span><span class="p">;</span><span class="nx">ISRIL_SCRIPT</span><span class="o">=</span><span class="nb">document</span><span class="p">.</span><span class="nx">createElement</span><span class="p">(</span><span class="s1">'SCRIPT'</span><span class="p">);</span><span class="nx">ISRIL_SCRIPT</span><span class="p">.</span><span class="nx">type</span><span class="o">=</span><span class="s1">'text/javascript'</span><span class="p">;</span><span class="nx">ISRIL_SCRIPT</span><span class="p">.</span><span class="nx">src</span><span class="o">=</span><span class="s1">'http://'</span><span class="o">+</span><span class="nx">PKT_D</span><span class="o">+</span><span class="s1">'/b/r.js'</span><span class="p">;</span><span class="nb">document</span><span class="p">.</span><span class="nx">getElementsByTagName</span><span class="p">(</span><span class="s1">'head'</span><span class="p">)[</span><span class="mi">0</span><span class="p">].</span><span class="nx">appendChild</span><span class="p">(</span><span class="nx">ISRIL_SCRIPT</span><span class="p">)})();</span>
</pre></div>
<p>Podemos ver en esta animación como funciona este comando:</p>
<p style="text-align:center;"><img src="pictures/pocket.gif" width="640"
height="400" alt="Guardar pagina en Pocket" /></p>
<p>La clave para este comando es bien sencilla, primero tener una cuenta en Pocket,
luego ir a la página en la que se nos proporciona un <a href="http://getpocket.com/add/">botón para la barra de
marcadores </a> para añadir las páginas a Pocket. Copiad con el botón derecho
la ruta del enlace que os proporciona ese botón, <em>et voilà!</em>, ahí tenéis el
código javascript que necesitáis para el comando. Luego para ejecutar el comando
solo necesitáis estar logueados en Pocket para que funcione.</p>
<h3 id="editar_+reas_de_texto_con_un_editor_externo">Editar áreas de texto con un editor externo</h3>
<p>Esta opción es para muy cómoda cuando se trata de editar grandes áreas de texto,
pues un editor externo te proporciona mejores y más cómodas herramientas. Además
en caso de que haya algún problema al enviar el texto, sigues teniendo la copia
en el editor.</p>
<p>Activar esta opción es muy sencillo, para Linux y Gvim, añadir esto a el archivo
de configuración:</p>
<div class="codehilite"><pre><span class="k">set</span> editor<span class="p">=</span><span class="s1">'/usr/bin/gvim -f +<line> <file>'</span>
</pre></div>
<p>Después puede ser empleado como comentaba para editar áreas de texto, o para
abrir el código fuente de una página, entre otras posibilidades.</p>
<h3 id="readability">Readability</h3>
<p>Para usar este servicio empleo una extension, <a href="https://github.com/grassofhust/dotfiles/blob/master/.pentadactyl/plugins/readability.js">readability.js</a>, que es
necesario descargar y añadir al directorio <code>~/.pentadactyl/plugins/</code>. Para
ejecutarlo solo necesitamos emplear el comando <strong><code>:rea ↹ ↵</code></strong>, como podemos ver
en esta animación:</p>
<p style="text-align:center;"><img src="pictures/readability.gif" width="640"
height="400" alt="Readability + Pentadactyl" /></p>
<h3 id="http_headers">HTTP Headers</h3>
<p>Esta es otra extensión que nos permite ver las cabeceras HTTP de una página. Es
una de las <a href="http://5digits.org/pentadactyl/plugins">extensiones oficiales </a> y al igual que la anterior, basta con
añadirla al directorio de plugins de Pentadactyl.</p>
<p>Si queremos ver la información que Pentadactyl nos ofrece de una página,
escribimos el siguiente comando <strong><code>:pageinfo</code></strong> y podemos ver algo como esto:</p>
<p style="text-align:center;"><img src="pictures/pageinfo.png" width="700"
height="190" alt="pageinfo" /></p>
<p>Ahora, si queremos ver las cabeceras, tenemos estas dos opciones:</p>
<ul>
<li>Request Headers, <strong><code>:pageinfo h</code></strong></li>
</ul>
<p style="text-align:center;"><img src="pictures/requesth.png" width="700"
height="141" alt="Request Headers" /></p>
<ul>
<li>Response Headers, <strong><code>:pageinfo H</code></strong></li>
</ul>
<p style="text-align:center;"><img src="pictures/responseh.png" width="700"
height="150" alt="Response Headers" /></p>
<p>Y podemos ver las dos a la vez empleando <strong><code>:pageinfo hH</code></strong></p>
<h2 id="alternativas">Alternativas</h2>
<p>Existen diferentes alternativas para este complemento, tanto para el mismo
Firefox, como para otros navegadores. Pero ninguna es tan completa como este.</p>
<p>Podríamos empezar por <a href="http://www.vimperator.org/vimperator">Vimperator</a>, que es el plugin original, ya que
Pentadactyl es un fork del mismo por parte de algunos de los desarrolladores
originales del mismo. Luego tenemos a <a href="http://code.google.com/p/vimium-firefox/">Vimium</a> que en este caso es una
versión del mismo plugin para Chrome.</p>
<p>Para Chrome/Chromium tenemos también varios plugins disponibles,</p>
<ul>
<li><a href="https://chrome.google.com/webstore/detail/godjoomfiimiddapohpmfklhgmbfffjj">Vrome</a></li>
<li><a href="https://chrome.google.com/webstore/detail/dbepggeogbaibhgnhhndojpepiihcmeb">Vimium</a></li>
<li><a href="https://chrome.google.com/webstore/detail/gghkfhpblkcmlkmpcpgaajbbiikbhpdi">vichrome</a></li>
</ul>
<p>Existen alguno que otra solución para Safari y Opera, si no me equivoco.</p>
<h3 id="navegadores_con_control_a_trav+s_del_teclado">Navegadores con control a través del teclado</h3>
<p>Existen una serie de navegadores, todos ellos pensados para ser muy ligeros y
todos basados en <a href="http://es.wikipedia.org/wiki/WebKit">Webkit</a>, que implementan la navegación por teclado por
defecto. Además estos que muestro están basados en los atajos de teclado de
Vim.</p>
<ul>
<li><a href="http://www.uzbl.org/">Uzbl</a></li>
<li><a href="http://sourceforge.net/apps/trac/vimprobable/">Vimprobable</a></li>
<li><a href="http://portix.bitbucket.org/dwb/">dwb</a></li>
<li><a href="http://mason-larobina.github.com/luakit/">luakit</a>, orientado a programadores y usuarios avanzados.</li>
</ul>
<h2 id="teledactyl">Teledactyl</h2>
<p>Los mismo desarrolladores de Pentadactyl tienen disponible otro plugin para la
otra gran herramienta de la <a href="https://es.wikipedia.org/wiki/Mozilla_Foundation">Mozilla Foundation</a>, el cliente de correo
electrónico <strong>Thunderbird</strong> , y aunque está en desarrollo en fase muy temprana, se
puede usar: <a href="http://5digits.org/teledactyl">Teledactyl</a>. Aunque si queremos emplear un plugin similar,
pero con un desarrollo más maduro, podemos escoger la herramienta hermana de
Vimperator, <a href="http://test.vimperator.org/muttator">Muttator</a></p>
<h2 id="productividad">Productividad</h2>
<p>Se qué me dejo muchas posibilidades de este plugin en el tintero, pero el
articulo se haría eterno. Si no ha despertado ya tu curiosidad por lo que te he
contado y mostrado, difícilmente lo hará ya. Ahora bien, si decides probarlo,
entonces seguro que serás el primero en mirar la ayuda para intentar sacarle
todo el jugo que este complemento te aporta. A lo poco que lo domines,
incrementara tu productividad en la navegación web considerablemente.</p>
<p>Y es que una vez te acostumbras a él -si conoces Vim y tienes soltura con él,
todo te será muy natural- la diferencia entre navegar con el teclado y el ratón
es abismal, no hay color. Tamaña es la diferencia que ni siquiera me planteo el
cambio de navegador por otro, porque todos carecen de Pentadactyl. Si navegas
habitualmente por la red, agradecerás mucho el tiempo que un plugin como este te
devuelve para emplearlo en otras tareas.</p>Mantener la temperatura adecuada en un portátil Dell con Linux2012-06-12T10:44:00+02:00joe di castrohttp://joedicastro.com/mantener-la-temperatura-adecuada-en-un-portatil-dell-con-linux.html<p>Los que tengáis o hayáis tenido un portátil <strong>Dell</strong>, sabréis que es posible
controlar la velocidad de funcionamiento de sus ventiladores de forma manual.
Existen aplicaciones para Windows, pero también es posible hacerlo desde Linux
con el paquete <code>i8kutils</code> creado por Massimo Dal Zotto. Este paquete incluye un
modulo del kernel <code>i8k</code> que necesita ser cargado al inicio y una serie de
utilidades para controlar el ventilador e informar de la temperatura y otros
valores de la <a href="https://es.wikipedia.org/wiki/Bios">BIOS</a>.</p>
<p>Este paquete fue creado originalmente para el portátil Dell Inspiron 8000, de
ahí su nombre. Esta utilidad aprovecha el modo <a href="http://es.wikipedia.org/wiki/Modo_de_Gerencia_del_Sistema">SMM </a> de la BIOS que estaba
presente en los modelos Inspiron para controlar la velocidad de los ventiladores
(algo que también permiten otras marcas como Toshiba y Lenovo, para las que
también hay algunas utilidades). Dell también ofrece el soporte de SMM BIOS en
otras gamas y portátiles, como los de la serie Latitude o XPS. Aunque está
utilidad no funciona en algunos modelos.</p>
<p>Esta utilidad funciona bajo la línea de comandos, pero al amparo del modulo del
kernel surgieron varias aplicaciones, principalmente applets para el panel de
Gnome 2, que permitían un control gráfico de los ventiladores y su temperatura.
Este control podía ser automático o manual. Yo personalmente me decanté en su
momento por emplear <a href="http://conky.sourceforge.net/">Conky</a> para mostrar las velocidades y la temperatura y
emplear un script, <code>i8kapplet</code> por Wheelspin, para controlar automáticamente la
temperatura dentro de unos rangos.</p>
<h2 id="i8kfanspy">i8kfans.py</h2>
<p>Este era un script bash que lleva dándome servicio mucho años (el portátil ya
tiene sus siete años) pero que por la forma que tiene de controlar cuando se
debe subir/bajar la velocidad de los ventiladores, provocaba que se sucediesen
de vez en cuando continuos acelerones y frenazos en los mismos. Esto al principio
no me disgustaba, pero con los años los ventiladores hacen cada vez más ruido y
si bien el sonido constante a alta velocidad es ligeramente molesto, esos
cambios bruscos de velocidad se me han vuelto insoportables. Y dado que el
portátil se acerca al final de su vida útil, sustituir los ventiladores, aunque
es la solución adecuada, no lo veo económicamente rentable.</p>
<p>Yo sabía que el problema por el que esto sucedía es porque la BIOS por defecto
regula las temperaturas de los ventiladores en unos rangos predefinidos y esto
no se desactiva, de hecho trabaja conjuntamente con el script. Como los rangos
de temperatura que yo predefino son inferiores a los de la BIOS, en algunas
ocasiones los dos pelean por el control de los ventiladores y es lo que ocasiona
el problema. Pero el calor es el peor enemigo de la electrónica, y en los
portátiles esto es un factor critico. De hecho estoy seguro de que este equipo
(muy bien amortizado) me ha durado tantos años gracias a que me he preocupado de
este punto. Estoy cansado de ver morir a portátiles y discos duros en verano
porque la gente no se preocupa de este tema. Por favor, limpiad el polvo de los
ventiladores al llegar el verano, os ahorrareis muchos disgustos.</p>
<p>Así que descartado el reemplazar los ventiladores, me planteé el crear un script
que intentara hacer lo mismo pero de forma más suave, intentado reducir el
número de cambios bruscos de velocidad y fruto de ello es el siguiente script,
que está disponible en <a href="http://github.com/joedicastro/i8kfans">GitHub</a>:</p>
<div class="codehilite"><pre><span class="c">#!/usr/bin/env python</span>
<span class="c"># -*- coding: utf8 -*-</span>
<span class="sd">"""</span>
<span class="sd"> i8kfans.py: Adjust the fans speed in various Dell laptops (with a nvidia</span>
<span class="sd"> graphics card) to maintain the right temperatures. This affect both fans,</span>
<span class="sd"> the cpu and the gpu fan. Originally i8k was created to run in a Dell</span>
<span class="sd"> Inspiron 8000 laptop, but this Dell fan control via SMM BIOS is available</span>
<span class="sd"> in others laptops of various series (Inspiron, XPS, Latitude, etcetera),</span>
<span class="sd"> but not all of them are supported. Mine is an Inspiron 9400 but I tested</span>
<span class="sd"> this successfully in a XPS m1330 too.</span>
<span class="sd"> Based on a 2006 bash script by Wheelspin, `i8kapplet`. This old script</span>
<span class="sd"> served faithfully me for many years, but my ears couldn't stand much longer</span>
<span class="sd"> its random and common slow downs/speed ups. Over the years, fans have</span>
<span class="sd"> become more and more loud. This new script runs in a more smooth way, with</span>
<span class="sd"> less sudden changes. It's cheaper than replace booth fans, don't you</span>
<span class="sd"> think?</span>
<span class="sd"> This script needs the `i8kutils` linux package installed and the `i8k`</span>
<span class="sd"> kernel module loaded to work.</span>
<span class="sd">"""</span>
<span class="c">#==============================================================================</span>
<span class="c"># Copyright 2012 joe di castro <joe@joedicastro.com></span>
<span class="c">#</span>
<span class="c"># This program is free software: you can redistribute it and/or modify</span>
<span class="c"># it under the terms of the GNU General Public License as published by</span>
<span class="c"># the Free Software Foundation, either version 3 of the License, or</span>
<span class="c"># (at your option) any later version.</span>
<span class="c">#</span>
<span class="c"># This program is distributed in the hope that it will be useful,</span>
<span class="c"># but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
<span class="c"># MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span>
<span class="c"># GNU General Public License for more details.</span>
<span class="c">#</span>
<span class="c"># You should have received a copy of the GNU General Public License</span>
<span class="c"># along with this program. If not, see <http://www.gnu.org/licenses/>.</span>
<span class="c">#==============================================================================</span>
<span class="n">__author__</span> <span class="o">=</span> <span class="s">"joe di castro <joe@joedicastro.com>"</span>
<span class="n">__license__</span> <span class="o">=</span> <span class="s">"GNU General Public License version 3"</span>
<span class="n">__date__</span> <span class="o">=</span> <span class="s">"12/06/2012"</span>
<span class="n">__version__</span> <span class="o">=</span> <span class="s">"0.3"</span>
<span class="k">try</span><span class="p">:</span>
<span class="kn">from</span> <span class="nn">os</span> <span class="kn">import</span> <span class="n">linesep</span>
<span class="kn">from</span> <span class="nn">subprocess</span> <span class="kn">import</span> <span class="n">check_output</span><span class="p">,</span> <span class="n">Popen</span><span class="p">,</span> <span class="n">PIPE</span>
<span class="kn">from</span> <span class="nn">sys</span> <span class="kn">import</span> <span class="nb">exit</span><span class="p">,</span> <span class="n">exc_info</span>
<span class="kn">from</span> <span class="nn">time</span> <span class="kn">import</span> <span class="n">sleep</span>
<span class="k">except</span> <span class="ne">ImportError</span><span class="p">:</span>
<span class="c"># Checks the installation of the necessary python modules</span>
<span class="k">print</span><span class="p">((</span><span class="n">linesep</span> <span class="o">*</span> <span class="mi">2</span><span class="p">)</span><span class="o">.</span><span class="n">join</span><span class="p">([</span><span class="s">"An error found importing one module:"</span><span class="p">,</span>
<span class="nb">str</span><span class="p">(</span><span class="n">exc_info</span><span class="p">()[</span><span class="mi">1</span><span class="p">]),</span> <span class="s">"You need to install it"</span><span class="p">,</span> <span class="s">"Stopping..."</span><span class="p">]))</span>
<span class="nb">exit</span><span class="p">(</span><span class="o">-</span><span class="mi">2</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">check_execs</span><span class="p">(</span><span class="o">*</span><span class="n">progs</span><span class="p">):</span>
<span class="sd">"""Check if the programs are installed, if not exit and report."""</span>
<span class="k">for</span> <span class="n">prog</span> <span class="ow">in</span> <span class="n">progs</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">Popen</span><span class="p">([</span><span class="n">prog</span><span class="p">,</span> <span class="s">'--help'</span><span class="p">],</span> <span class="n">stdout</span><span class="o">=</span><span class="n">PIPE</span><span class="p">,</span> <span class="n">stderr</span><span class="o">=</span><span class="n">PIPE</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">OSError</span><span class="p">:</span>
<span class="n">msg</span> <span class="o">=</span> <span class="s">'The {0} program is necessary to run this script'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">prog</span><span class="p">)</span>
<span class="nb">exit</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">def</span> <span class="nf">get_right_fan_speed</span><span class="p">(</span><span class="n">current_temperature</span><span class="p">,</span> <span class="n">current_fan_speed</span><span class="p">,</span> <span class="n">temp_triggers</span><span class="p">):</span>
<span class="sd">"""Get the right fan speed to use with i8kfan command.</span>
<span class="sd"> :current_temperature: current temperature value for the fan implied</span>
<span class="sd"> :current_fan_speed: current fan speed</span>
<span class="sd"> :temp_triggers: the threshold temperatures to trigger the fan speed change</span>
<span class="sd"> :returns: right fan speed or "-" (means change nothing to i8kfan)</span>
<span class="sd"> """</span>
<span class="n">right_fan_speed</span> <span class="o">=</span> <span class="bp">None</span> <span class="c"># the right fan speed for the current temp</span>
<span class="k">if</span> <span class="n">current_temperature</span> <span class="o">>=</span> <span class="n">temp_triggers</span><span class="p">[</span><span class="mi">0</span><span class="p">]:</span>
<span class="k">if</span> <span class="n">current_temperature</span> <span class="o">>=</span> <span class="n">temp_triggers</span><span class="p">[</span><span class="mi">1</span><span class="p">]:</span>
<span class="n">right_fan_speed</span> <span class="o">=</span> <span class="mi">2</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">right_fan_speed</span> <span class="o">=</span> <span class="mi">1</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">right_fan_speed</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">return</span> <span class="n">right_fan_speed</span> <span class="k">if</span> <span class="n">right_fan_speed</span> <span class="o">!=</span> <span class="n">current_fan_speed</span> <span class="k">else</span> <span class="s">"-"</span>
<span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
<span class="sd">"""Main section"""</span>
<span class="c"># time between temperature checks</span>
<span class="n">interval</span> <span class="o">=</span> <span class="mi">1</span>
<span class="c"># the temp thresholds to jump to a faster fan speed. Values greater than</span>
<span class="c"># [g|c]pu[0] set the fan speed to 1 and the ones greater than [g|c]pu[1]</span>
<span class="c"># set the speed to 2. Obviously, values minor than [g|c]pu[0] stop the fan</span>
<span class="n">gpu_temps</span> <span class="o">=</span> <span class="p">[</span><span class="mi">45</span><span class="p">,</span> <span class="mi">53</span><span class="p">]</span>
<span class="n">cpu_temps</span> <span class="o">=</span> <span class="p">[</span><span class="mi">40</span><span class="p">,</span> <span class="mi">50</span><span class="p">]</span>
<span class="c"># check if the i8k kernel module is already loaded</span>
<span class="k">if</span> <span class="s">"i8k"</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">check_output</span><span class="p">(</span><span class="s">"ls /proc/"</span><span class="o">.</span><span class="n">split</span><span class="p">()):</span>
<span class="nb">exit</span><span class="p">(</span><span class="s">"The i8k kernel module is not loaded"</span><span class="p">)</span>
<span class="k">while</span> <span class="bp">True</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="c"># get current values</span>
<span class="n">cpu_temp</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">check_output</span><span class="p">(</span><span class="s">"i8kctl temp"</span><span class="o">.</span><span class="n">split</span><span class="p">()))</span>
<span class="n">gpu_out</span> <span class="o">=</span> <span class="n">check_output</span><span class="p">(</span><span class="s">"nvidia-smi -q -d TEMPERATURE"</span><span class="o">.</span><span class="n">split</span><span class="p">())</span>
<span class="n">gpu_temp</span> <span class="o">=</span> <span class="nb">int</span><span class="p">([</span><span class="n">s</span> <span class="k">for</span> <span class="n">s</span> <span class="ow">in</span> <span class="n">gpu_out</span><span class="o">.</span><span class="n">split</span><span class="p">()</span> <span class="k">if</span> <span class="n">s</span><span class="o">.</span><span class="n">isdigit</span><span class="p">()][</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span>
<span class="n">cpu_fan</span><span class="p">,</span> <span class="n">gpu_fan</span> <span class="o">=</span> <span class="p">[</span><span class="nb">int</span><span class="p">(</span><span class="n">f</span><span class="p">)</span> <span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">check_output</span><span class="p">(</span><span class="s">"i8kfan"</span><span class="p">)</span><span class="o">.</span><span class="n">split</span><span class="p">()]</span>
<span class="c"># get the right speed values for each fan</span>
<span class="n">cpu_rfs</span> <span class="o">=</span> <span class="n">get_right_fan_speed</span><span class="p">(</span><span class="n">cpu_temp</span><span class="p">,</span> <span class="n">cpu_fan</span><span class="p">,</span> <span class="n">cpu_temps</span><span class="p">)</span>
<span class="n">gpu_rfs</span> <span class="o">=</span> <span class="n">get_right_fan_speed</span><span class="p">(</span><span class="n">gpu_temp</span><span class="p">,</span> <span class="n">gpu_fan</span><span class="p">,</span> <span class="n">gpu_temps</span><span class="p">)</span>
<span class="c"># if any of the fans needs to change their speed, change it!</span>
<span class="k">if</span> <span class="n">cpu_rfs</span> <span class="o">!=</span> <span class="s">"-"</span> <span class="ow">or</span> <span class="n">gpu_rfs</span> <span class="o">!=</span> <span class="s">"-"</span><span class="p">:</span>
<span class="n">Popen</span><span class="p">(</span><span class="s">"i8kfan {0} {1}"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">cpu_rfs</span><span class="p">,</span> <span class="n">gpu_rfs</span><span class="p">)</span><span class="o">.</span><span class="n">split</span><span class="p">(),</span>
<span class="n">stdout</span><span class="o">=</span><span class="n">PIPE</span><span class="p">)</span>
<span class="c"># wait a moment. We want a cooler laptop, aren't we?</span>
<span class="n">sleep</span><span class="p">(</span><span class="n">interval</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">KeyboardInterrupt</span><span class="p">:</span>
<span class="nb">exit</span><span class="p">()</span>
<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">"__main__"</span><span class="p">:</span>
<span class="n">check_execs</span><span class="p">(</span><span class="s">"i8kctl"</span><span class="p">,</span> <span class="s">"i8kfan"</span><span class="p">,</span> <span class="s">"nvidia-smi"</span><span class="p">)</span>
<span class="n">main</span><span class="p">()</span>
<span class="c">###############################################################################</span>
<span class="c"># Changelog #</span>
<span class="c">###############################################################################</span>
<span class="c">#</span>
<span class="c"># 0.3:</span>
<span class="c">#</span>
<span class="c"># * Better documentation</span>
<span class="c">#</span>
<span class="c"># 0.2:</span>
<span class="c">#</span>
<span class="c"># * Fix an error in a function docstring due to refactorization</span>
<span class="c"># * Give appropriate credit to original idea' script</span>
<span class="c">#</span>
<span class="c"># 0.1:</span>
<span class="c">#</span>
<span class="c"># * First attempt</span>
<span class="c">#</span>
</pre></div>
<p>De momento, aunque aún sufre del mismo problema inevitable por el conflicto
por el control entre el script y la BIOS, de momento he observado que se produce
con menos frecuencia y durante menos tiempo. Aunque quizás realice algunos
cambios para intentar reducir aún más esos conflictos.</p>Productividad & Linux: Aplicaciones2012-06-07T22:40:00+02:00joe di castrohttp://joedicastro.com/productividad-linux-aplicaciones.html<p>En la anterior serie de artículos sobre <a href="http://joedicastro.com/productividad-en-el-escritorio-linux-introduccion.html">Productividad en el escritorio
Linux</a>, hacia referencia a los lanzadores de aplicaciones y a los gestores
de ventanas de mosaico como elementos diferenciadores a la hora de ser más
productivos. Aunque la productividad en el escritorio es fundamental para
trabajar de forma más eficiente, son las aplicaciones que empleamos, las que en
último lugar, determinaran la realidad de nuestro día a día frente a la
pantalla.</p>
<p>Gran parte de las aplicaciones para Linux (las más conocidas y extendidas) son
realmente una adaptación de los conceptos de los sistemas operativos más
difundidos: Windows & Mac OS. Esto es, aplicaciones muy pesadas, repletas de
opciones y funciones de las que se aprovechan en realidad muy pocas. Además
están por lo general fuertemente orientadas al empleo del ratón y muchas veces
con un interfaz gráfico muy agradable visualmente pero con un concepto de
usabilidad, en mi opinión, no siempre bien enfocado.</p>
<h2 id="la_usabilidad_mal_entendida_como_enemiga_de_la_productividad">La usabilidad mal entendida, como enemiga de la productividad</h2>
<p>La <a href="https://es.wikipedia.org/wiki/Usabilidad">usabilidad</a>, ese concepto tan de moda últimamente, está desde mi
punto de vista, frecuentemente muy mal enfocado. Dejando a un lado lo que
teóricamente se pretende, en el 80% de las ocasiones esto se traduce en la
práctica en dos palabras en ingles: <em>For dummies</em> ("pá tontos", en castizo). Es
decir, que cualquiera pueda manejar la aplicación sin grandes dificultades y en
el menor tiempo posible. Reducir las barreras de entrada está muy bien, pero
desgraciadamente muchas veces esto es una estrategia a corto plazo que no
debería emplearse <strong>NUNCA de este modo</strong> en aplicaciones profesionales.
Entiendo, y además apoyo, está estrategia en aplicaciones web y aplicaciones de
consumo, pero lo veo nocivo a la hora de aplicaciones destinadas a producir
datos y contenidos de forma masiva e intensiva. Y a mi modo de ver es un
problema serio en un gran número de escenarios.</p>
<h3 id="un_caso_real_de_usabilidad_enga+osa">Un caso real de usabilidad engañosa</h3>
<p>No proporcionare datos reales por respeto a las partes implicadas, pero quiero
aportar aquí un ejemplo real que he podido vivir de cerca durante varios años,
de lo que la pretendida usabilidad, ni lo es, ni ayuda a sacar más partido de
las herramientas:</p>
<p><strong>Escenario fallido</strong> : un negocio que se dedica el 90% del tiempo a editar
grandes cantidades de texto. Se informatizan a mediados de los 80 y adoptan como
procesador de textos WordPerfect para consola. Después de varios años, están en
la versión de WordPerfect 5.1 para MSDOS con un 90% de los empleados (unos
diez), con un dominio asombroso de la aplicación, basando todo su trabajo en
atajos de teclado y una pantalla donde únicamente se visualiza el texto sobre el
que están trabajando. Productividad: realmente elevada. Principios del siglo
XXI, un consultor informático embaucador (<em>aka</em> comercial) los convence de que
el futuro es <a href="https://es.wikipedia.org/wiki/Wysiwyg">WYSIWYG</a> y que eso del terminal de texto es cosa del pasado.
Tras una primera migración a WordPerfect para Windows, la productividad baja de
forma significativa. La solución propuesta: Word, la productividad cae de forma
dramática. La excusa del "asesor": necesidad de adaptación al nuevo concepto.
Dos años después, la productividad sigue sin incrementarse, el trabajo se
acumula y se contratan a dos personas más para refuerzo. El personal ya se ha
adaptado y están tan hipnotizados por el ratón, los iconos y los "regalitos" que
su software les proporciona en cada nueva versión, que se oponen radicalmente a
volver al "pasado". En realidad, nadie desde dentro se cuestionaba que el
problema real era que habían dejado de centrarse en el contenido, para centrarse
en el continente. Lo más irónico: lo que realmente hacían era crear e imprimir
documentos, impresos en impresoras matriciales que seguían imprimiendo con la
misma calidad y la misma fuente Courier 11 sobre el mismo tipo de documentos
oficiales.</p>
<p><strong>Escenario exitoso</strong> : Paralelamente, en un área de negocio distinta, pero
estrechamente relacionada con la anterior, una empresa que ha trabajado siempre
en entorno de terminal contra un <a href="https://es.wikipedia.org/wiki/As/400">AS/400,</a> presentaba una mentalidad y un
resultado totalmente opuestos. Nunca se han dejado seducir por los cantos de
sirena del marketing y se han opuesto radicalmente a cualquier cambio de
sistema, simplemente han evolucionado el que ya tenían y conservando su
plantilla prácticamente intacta durante el mismo periodo. El resultado: la
productividad se ha mantenido constante a lo largo de los años y han podido
asumir importantes picos de carga de trabajo sin demasiadas dificultades. Y un
efecto secundario de esta toma de decisiones: el haberse mantenido dentro de un
sistema maduro y estable les ha librado de un mantenimiento casi nulo en el área
de software, limitándose el mismo al área de hardware (lo habitual). Como podéis
imaginar, en un sistema basado en plataforma Windows y actualizaciones sucesivas
de SO y aplicaciones, el mantenimiento del área de software les ha supuesto una
importante carga económica al otro negocio.</p>
<p>Que cada uno extraiga sus propias conclusiones. La mía: que la carrera hacia
adelante de fabricantes de sistemas operativos y aplicaciones (cuyo único
recurso para seguir vendiendo ha sido con frecuencia un simple
lavado de cara) ha supuesto, en muchos aspectos, un paso atrás en varias áreas de
la informática.</p>
<h2 id="la_usabilidad_bien_entendida">La usabilidad bien entendida</h2>
<p>No quiero decir con lo anterior, que las aplicaciones gráficas sean el problema
ni mucho menos. De hecho, hay aplicaciones gráficas que son una maravilla de la
usabilidad. Por ejemplo, Autocad, que te permite un control casi absoluto como
usuario avanzado (con los comandos y <a href="https://es.wikipedia.org/wiki/Autolisp">AutoLISP</a>) y que al mismo tiempo te
permite realizar gran parte del trabajo de manera muy intuitiva (siempre
teniendo en cuenta el contexto del usuario al que va dirigido) empleando la
interfaz gráfica. Lo que permite que sea muy usable sin detrimento de la
productividad. Lo que quiero decir, es que es necesario añadir el sentido común
como un criterio más, si no el primero, a la hora de implementar la usabilidad.</p>
<p>Si consultamos la Wikipedia, encontramos dos definiciones de la ISO para el
concepto de <a href="https://es.wikipedia.org/wiki/Usabilidad">usabilidad</a> :</p>
<blockquote>
<p>La usabilidad se refiere a la capacidad de un software de ser comprendido,
aprendido, usado y ser atractivo para el usuario, en condiciones específicas de
uso</p>
<p>Usabilidad es la eficacia, eficiencia y satisfacción con la que un producto
permite alcanzar objetivos específicos a usuarios específicos en un contexto de
uso específico</p>
</blockquote>
<p>Como decía anteriormente, la realidad dista mucho de la teoría. En la
práctica se ha adoptado con bastante fidelidad la primera definición, eso sí,
ignorando con bastante frecuencia la parte de "condiciones específicas" y la
segunda definición parece haber sido ampliamente ignorada.</p>
<p>Si bien es cierto que la mayoría de las aplicaciones actuales pueden ser muy
potentes, lo que yo veo mirando al pasado, es que la gran mayoría de los
empleados que utilizaban una aplicación a diario eran usuarios avanzados y
cuando no expertos. Hoy en día, y ciñéndonos al ámbito profesional, a algunos
les cambias el icono de la misma, y no saben iniciarla. Y no es culpa de ellos,
las aplicaciones se diseñan para que las puedan usar hasta los más reacios a la
tecnología (siempre en su contexto), pero una vez que necesitas realizar algo
complejo, existe un salto conceptual que la mayoría de los usuarios, ni se
atreven a dar, ni quieren darlo.</p>
<p>Es realmente complejo, muy complejo, conseguir una interfaz de usuario que sea
realmente amigable e intuitiva y que al mismo tiempo consiga satisfacer las
necesidades reales tanto del usuario profesional, como del usuario ocasional. El
problema de base está en intentar crear herramientas todoterreno. Ni maldita
falta que le hace un Word actual a un usuario domestico y que demonios hace un
escritor profesional empleándolo en vez de algo como Latex + editor de texto.
Ni un usuario domestico necesita de herramientas para correspondencia, programar
macros, etc, ni un escritor necesita preocuparse del formato del texto. Y sin
embargo es empleado hasta por editores que deberían estar empleando
herramientas de autoedición.</p>
<p>Por ejemplo, una aplicación que es un claro ejemplo de buena usabilidad y que
está teniendo una buena acogida últimamente, es <a href="http://www.sublimetext.com/">Sublime Text</a>. Es bonita,
es potente, es amigable y es francamente muy, muy usable. Realmente lo que han
hecho ha sido recoger el testigo que dejo <a href="http://macromates.com/">TextMate</a>, que fueron los
primeros en darse cuenta de algo muy sencillo. Esto es, los editores de texto y
los IDEs para programadores son una de las aplicaciones en las que nunca llueve
a gusto de todos, surgen continuamente nuevas alternativas, pero no se acaba por
imponer ninguna. Por que en realidad, si nos fijamos en los programadores más
experimentados, dos de los editores más utilizados y defendidos a muerte, son
<a href="https://es.wikipedia.org/wiki/Vim">Vim</a> y <a href="https://es.wikipedia.org/wiki/Emacs">Emacs</a>, ambos basados en conceptos de hace casi cuatro
décadas. Es que la usabilidad ya estaba inventada hace mucho tiempo, y no tiene
nada que ver ni con gráficos bonitos, ni con tratar a los usuarios como
imbéciles. La usabilidad, señores, está en la adaptación del interfaz del
ordenador de la manera más optima posible al interfaz que la naturaleza nos dio,
nuestras manos. Y desde luego, jamás un ratón, con los botones que quieras
ponerle, sera más eficaz que un teclado (usado con los diez deditos), al igual
que no lo es más que un bolígrafo o una tableta gráfica con lápiz. Que para eso
tenemos los dedos y no muñones. Si vamos a comprar un libro en Internet, el
ratón es nuestro gran aliado para hacerlo de forma intuitiva sin conocimientos
previos, pero si me vas a obligar a introducir entradas de almacén 40 horas a la
semana con la misma aplicación, por favor, no me condenes a usar el ratón cada
dos pasos. Sentido común!</p>
<h2 id="las_aplicaciones_amigas_de_la_productividad">Las aplicaciones amigas de la productividad</h2>
<p>Este entrada pretende ser la introducción y el indice de una nueva serie de
artículos dedicada a esas aplicaciones para Linux que para mi marcan la
diferencia entre <em>hacer el trabajo</em> y <em>marear la perdiz</em>. Estas aplicaciones
comparten en general tres puntos en común:</p>
<ul>
<li>Son muy eficientes y ayudan a incrementar nuestra productividad.</li>
<li>Realizan a una sola tarea y lo hacen bien o muy bien.</li>
<li>No están muy extendidas.</li>
</ul>
<p>Iré actualizando la entrada a medida que vaya creando los artículos para cada
aplicación.</p>
<h3 id="aplicaciones">Aplicaciones</h3>
<p>Estas son algunas de las aplicaciones que yo empleo a menudo y que al igual que
a mí, pueden servirte para incrementar de forma notable tu productividad.</p>
<ul>
<li>
<p><a href="http://joedicastro.com/productividad-linux-pentadactyl.html">Pentadactyl</a>, complemento para Firefox para controlar el navegador
completamente desde el teclado, permite navegar entre las páginas a velocidad
de vértigo. Además es muy potente y posee muchísimas opciones y posibilidades.</p>
</li>
<li>
<p><a href="http://joedicastro.com/productividad-linux-newsbeuter.html">Newsbeuter</a>, aplicación para leer subscripciones RSS y Atom. Funciona
en modo texto, con una interfaz tipo ncurses y completamente controlable desde
el teclado. Es una aplicación rapidisima y con un consumo muy escaso de
recursos.</p>
</li>
<li>
<p><a href="http://joedicastro.com/productividad-linux-turses.html">Turses</a>, cliente twitter para la consola con interfaz ncurses.
Controlable desde el teclado con atajos basados en Vim. Muy personalizable y
con un funcionamiento muy versátil y ágil.</p>
</li>
<li>
<p><a href="http://joedicastro.com/productividad-linux-tmux.html">tmux</a>, es un multiplexor de terminales. Permite agrupar varios
terminales en una sola ventana de forma muy eficiente. La herramienta ideal
para los amantes de la consola, desarrolladores y administradores de sistemas.</p>
</li>
<li>
<p><a href="http://joedicastro.com/productividad-linux-zathura.html">zathura</a>, es un visor de documentos minimalista y controlable desde
el teclado. Soporta documentos en formato PDF, DJVU, PostScript y Comic Book.</p>
</li>
<li>
<p><a href="http://joedicastro.com/productividad-linux-ranger.html">Ranger</a>, es un administrador de archivos en modo texto y
revolucionario en su interfaz y manejo. Muy potente y personalizable. </p>
</li>
<li>
<p><a href="http://joedicastro.com/productividad-linux-ncdu.html">Ncdu</a>, una herramienta con interfaz ncurses que nos permite conocer el
espacio consumido en nuestro disco duro y navegar por los distintos
directorios. La mejor herramienta del estilo que existe para la consola.</p>
</li>
</ul>