Nunca te pierdas un artículo de la revista: crea tu propio sistema de notificación RSS

Python es un gran lenguaje de programación para construir rápidamente aplicaciones que nos hacen la vida más fácil. En este artículo aprenderemos a usar Python para construir un sistema de notificación RSS, con el objetivo de divertirnos aprendiendo Python usando Fedora. Si está buscando una aplicación notificadora de RSS completa, hay algunas ya empaquetadas en Fedora.

Fedora y Python – comenzando

Python 3.6 está disponible por defecto en Fedora, que incluye la extensa biblioteca estándar de Python. La biblioteca estándar proporciona una colección de módulos que nos simplifican algunas tareas. Para exampleen nuestro caso usaremos elsqlite3módulo para crear, agregar y leer datos de una base de datos. En el caso de que un problema en particular que estamos tratando de resolver no esté cubierto por la biblioteca estándar, lo más probable es que alguien ya haya desarrollado un módulo para que lo usen todos. El mejor lugar para buscar dichos módulos es el Índice de paquetes de Python conocido comoPyPI. En nuestro example vamos a usar elalimentadorpara analizar una fuente RSS.

Ya quealimentadorno está en la biblioteca estándar, tenemos que instalarlo en nuestro sistema. Por suerte para nosotros, hay un paquete rpm en Fedorapor lo que la instalación dealimentadores tan simple como:

$ sudo dnf install python3-feedparser

Ahora tenemos todo lo que necesitamos para comenzar a codificar nuestra aplicación.

Almacenamiento de los datos del feed

Necesitamos almacenar datos de los artículos que ya se han publicado para que enviemos una notificación solo para artículos nuevos. Los datos que queremos almacenar nos darán una forma única de identificar un artículo. Por lo tanto, almacenaremos eltítuloy elfecha de publicacióndel articulo

Así que vamos a crear nuestra base de datos usando pythonsqlite3módulo y una simple consulta SQL. También estamos agregando los módulos que vamos a usar más adelante (alimentador,smtplibyCorreo electrónico).

Crear la base de datos

#!/usr/bin/python3
import sqlite3
import smtplib 
from email.mime.text import MIMEText

import feedparser

db_connection = sqlite3.connect('/var/tmp/magazine_rss.sqlite')
db = db_connection.cursor()
db.execute('CREATE TABLE IF NOT EXISTS magazine (title TEXT, date TEXT)')

Estas pocas líneas de código crean una nueva base de datos sqlite almacenada en un archivo llamado ‘magazine_rss.sqlite’, y luego crean una nueva tabla dentro de la base de datos llamada ‘magazine’. Esta tabla tiene dos columnas, ‘título’ y ‘fecha’, que pueden almacenar datos del tipo TEXTO, lo que significa que el valor de cada columna será una cadena de texto.

Comprobación de la base de datos en busca de artículos antiguos

Dado que solo queremos agregar nuevos artículos a nuestra base de datos, necesitamos una función que verifique si el artículo que obtenemos de la fuente RSS ya está en nuestra base de datos o no. Lo usaremos para decidir si debemos enviar una notificación por correo electrónico (artículo nuevo) o no (artículo antiguo). Ok, codifiquemos esta función.

def article_is_not_db(article_title, article_date):
    """ Check if a given pair of article title and date
    is in the database.
    Args:
        article_title (str): The title of an article
        article_date  (str): The publication date of an article
    Return:
        True if the article is not in the database
        False if the article is already present in the database
    """
    db.execute("SELECT * from magazine WHERE title=? AND date=?", (article_title, article_date))
    if not db.fetchall():
        return True
    else:
        return False

La parte principal de esta función es la consulta SQL que ejecutamos para buscar en la base de datos. Estamos utilizando una instrucción SELECT para definir en qué columna de nuestra tabla de revistas ejecutaremos la consulta. Estamos usando el símbolo * para seleccionar todas las columnas (título y fecha). Luego, le pedimos que seleccione solo las filas de la tabla DONDE las cadenas article_title y article_date son iguales al valor de la columna de título y fecha.

Para finalizar, tenemos una lógica simple que devolverá True si la consulta no arrojó ningún resultado y False si la consulta encontró un artículo en la base de datos que coincida con nuestro título, par de fechas.

Agregar un nuevo artículo a la base de datos

Ahora podemos codificar la función para agregar un nuevo artículo a la base de datos.

def add_article_to_db(article_title, article_date):
    """ Add a new article title and date to the database
    Args:
        article_title (str): The title of an article
        article_date (str): The publication date of an article
    """
    db.execute("INSERT INTO magazine VALUES (?,?)", (article_title, article_date))
    db_connection.commit()

Esta función es sencilla, estamos usando una consulta SQL para INSERTAR una nueva fila EN la tabla de la revista con los VALORES del título_del_artículo y la fecha_del_artículo. Luego confirmamos el cambio para que sea persistente.

Eso es todo lo que necesitamos desde el punto de vista de la base de datos, veamos el sistema de notificación y cómo podemos usar Python para enviar correos electrónicos.

Envío de una notificación por correo electrónico

Vamos a crear una función para enviar un correo electrónico usando el módulo de biblioteca estándar de pythonsmtplib.También estamos usando elCorreo electrónicomódulo de la biblioteca estándar para formatear nuestro mensaje de correo electrónico.

def send_notification(article_title, article_url):
    """ Add a new article title and date to the database

    Args:
        article_title (str): The title of an article
        article_url (str): The url to access the article
    """

    smtp_server = smtplib.SMTP('smtp.gmail.com', 587)
    smtp_server.ehlo()
    smtp_server.starttls()
    smtp_server.login('[email protected]', '123your_password')
    msg = MIMEText(f'\nHi there is a new Fedora Magazine article : {article_title}. \nYou can read it here {article_url}')
    msg['Subject'] = 'New Fedora Magazine Article Available'
    msg['From'] = '[email protected]'
    msg['To'] = '[email protected]'
    smtp_server.send_message(msg)
    smtp_server.quit()

En esto example Estoy usando el servidor smtp de correo de Google para enviar un correo electrónico, pero esto funcionará con cualquier servicio de correo electrónico que le proporcione un servidor SMTP. La mayor parte de esta función es repetitiva necesaria para configurar el acceso al servidor smtp. Deberá actualizar el código con su dirección de correo electrónico y sus credenciales.

Si está utilizando la autenticación de 2 factores con su cuenta de Gmail, puede configurar una aplicación de contraseña que le dará una contraseña única para usar en esta aplicación. Mira esta ayudapágina.

Leer Fedora Fuente RSS de la revista

Ahora tenemos funciones para almacenar un artículo en la base de datos y enviar una notificación por correo electrónico, creemos una función que analice el Fedora Feed RSS de la revista y extraer los datos de los artículos.

def read_article_feed():
    """ Get articles from RSS feed """
    feed = feedparser.parse('https://fedoramagazine.org/feed/')
    for article in feed['entries']:
        if article_is_not_db(article['title'], article['published']):
            send_notification(article['title'], article['link'])
            add_article_to_db(article['title'], article['published'])

if __name__ == '__main__':
    read_article_feed()
    db_connection.close()

Aquí estamos haciendo uso de lafeedparser.parsefunción. La función devuelve una representación de diccionario de la fuente RSS, para la referencia completa de la representación que puede consultaralimentador'sdocumentación.

El analizador de fuentes RSS devolverá los últimos 10 artículos como entradas y luego extraeremos la siguiente información: el título, el enlace y la fecha en que se publicó el artículo. Como resultado, ahora podemos usar las funciones que hemos definido anteriormente para verificar si el artículo no está en la base de datos, luego enviar un correo electrónico de notificación y, finalmente, agregar el artículo a nuestra base de datos.

La última declaración if se usa para ejecutar nuestra función read_article_feed y luego close la conexión a la base de datos cuando ejecutamos nuestro script.

Ejecutando nuestro script

Finalmente, para ejecutar nuestro script, debemos otorgar el permiso correcto al archivo. A continuación, hacemos uso de lacronutilidad para ejecutar automáticamente nuestro script cada hora (1 minuto después de la hora).crones un programador de trabajos que podemos usar para ejecutar una tarea en un tiempo fijo.

$ chmod a+x my_rss_notifier.py
$ sudo cp my_rss_notifier.py /etc/cron.hourly

Para simplificar este tutorial, estamos usando el directorio cron.hourly para ejecutar el script cada hora. Si desea obtener más información sobrecrony como configurar elcrontab,por favor leede cronWikipediapágina.

Conclusión

En este tutorial, hemos aprendido a usar Python para crear una base de datos sqlite simple, analizar una fuente RSS y enviar correos electrónicos. Espero que esto le haya mostrado cómo puede construir fácilmente su propia aplicación usando Python y Fedora.

El script está disponible en githubaquí.

Artículos Relacionados