joe di castrohttp://joedicastro.com2012-06-18T23:26:00+02:00Productividad & 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>