Asi organizo mis libreria personal con Notion y Python

Helguera
Escrito por Helguera el
Link

Introducción

Siempre he querido tener una gran colección de libros, la mayoria relacionados con la programación, en una gran biblioteca donde poder consultarlos siempre que lo necesite. Pero la verdad es que ese sueño va a tener que esperar un poco ya que ahora mismo, con mi estilo de vida semi-nómada, me sería imposible moverlos cada vez que me mudo de lugar.

Así que hace un tiempo, tomé la decisión de siempre comprar o descargar todos los libros en formato digital y leerlos en el iPad o en el iPhone. Al principio, cuando tenía pocos, podía hacerme una idea mental de los libros que tenía para poder consultarlos rápidamente. Pero cuando la librería comenzo a crecer, empecé a perder el seguimiento de que libros tenía exactamente y al final nunca recurría a ellos.

Desde hace un tiempo utilizo Notion para organizar toda mi vida, tanto personal como profesional, por lo que decidí utilizarlo también para organizar mis libros y que me sirviese a modo de buscador. Pero claro, no iba a insertar cada libro manualmente, no me dedico al desarrollo del software para eso, así que creé un pequeño script en Python que lo hace por mi.

Mi Script

Los pasos del script son los siguientes:

  1. Obtener la ruta de todos los libros en la carpeta y subcarpetas especificada. Siempre intento adquirir los libro en formato .epub, por lo que este script sólo funcionará con dicho formato.

  2. Extraer la información de los libros tal como título, autor, ISBN, editor...

  3. Generar un fichero CSV con los resultados.

  4. Subir el fichero a una base de datos en Notion, respetando los datos que previamente contenía.

Librerías necesarias

  • epub_meta: para extraer la información de los ficheros .epub
  • openpyxl: para generar el fichero .xlsx
  • os: para ejecutar el comando que subirá los datos a Notion
  • pandas: para convertir el fichero .xlsx a .csv y que Csv2Notion lo pueda procesar.
import epub_meta
import openpyxl
import os
import pandas as pd

Configuración inicial

Antes de nada, se necesitan las siguientes líneas de código para inicializar openpyxl, establecer el nombre de la hoja de cálculo y la ruta a partir de la que buscar los ficheros .epub. En este caso, la ruta es la misma desde la que se ejecuta el script.

wb = openpyxl.Workbook() 
ws1 = wb.active
ws1.title = "epubs"
path = './'

Obtener los libros

El siguiente bucle for se encarga de buscar todos los ficheros .epub en el directorio especificado y todos sus subdirectorios. Los resultados se almacenarán en el array "files_path":

files_path = []
for r, d, f in os.walk(path):
    for file in f:
        if '.epub' in file:
            files_path.append(os.path.join(r, file))
files_path = filter(lambda x: '._' not in x, files_path)

for f in files_path:
    print(f)

La línea que hace uso de la función lambda sólo es necesaria si utilizas MacOS, como es mi caso, para ignorar los ficheros ocultos duplicados que empiezan por "._".

Extraer información

A continuación, es necesario crear los encabezados de las columnas del fichero .xlsx. En mi caso he decidido que los siguientes son suficientes como información que quiero almacenar de cada libro.

Aunque las columnas "Tags", "Priority", "Status" y "Comments" no es información que vaya a extraer del fichero .epub, si que son columnas que quiero que aparezcan en la base de datos en Notion, por lo tanto, tengo que añadirlas aunque nunca vayan a tener un valor.

ws1.cell(row=1, column=1).value = 'Identifier'
ws1.cell(row=1, column=2).value = 'Title'
ws1.cell(row=1, column=3).value = 'Priority'
ws1.cell(row=1, column=4).value = 'Tags'
ws1.cell(row=1, column=5).value = 'Status'
ws1.cell(row=1, column=6).value = 'Author'
ws1.cell(row=1, column=7).value = 'Publisher'
ws1.cell(row=1, column=8).value = 'Comments'

Una vez se tenga la ruta de cada libro, simplemente hay que iterar cada uno de ellos, extraer la información con la ayuda de la librería epub_meta y guardar la información en filas diferentes, una por libro, del fichero .xlsx.

for index, my_file in enumerate(files_path, start=1):
    if '.epub' in my_file:
        # print(my_file)
        data = epub_meta.get_epub_metadata(my_file, read_cover_image=True, read_toc=True)
        if ' '.join(data.identifiers) == '':
            ws1.cell(row=index+1, column=1).value = data.title
        else:
            ws1.cell(row=index+1, column=1).value = ' '.join(data.identifiers)
        ws1.cell(row=index+1, column=2).value = data.title
        ws1.cell(row=index+1, column=3).value = ''
        ws1.cell(row=index+1, column=4).value = '' #' '.join(data.subject).replace('/',',')
        ws1.cell(row=index+1, column=5).value = 'Not started'
        ws1.cell(row=index+1, column=6).value = ' '.join(data.authors)
        if data.publisher:
            ws1.cell(row=index+1, column=7).value = data.publisher.replace(',','')
        ws1.cell(row=index+1, column=8).value = ''

Generar CSV

Por último, sólo queda guardar el fichero .xlsx y convertirlo a .csv:

wb.save(filename='epubs.xlsx')
df = pd.read_excel('epubs.xlsx', sheet_name=None)
df['epubs'].to_csv('output.csv', index=False, encoding='utf-8')  

Subir los datos a Notion (Csv2Notion)

Para subir los datos a Notion utilizo una herramienta llamada Csv2Notion que he encontrado en GitHub. Haz click aquí para acceder al repositorio.

Hay varias formas de instalarlo, la más fácil es mediante PIP:

$ pip install --user csv2notion

De todas maneras, te recomiendo consultar el repositorio oficial para más información.

El comando que se necesita es el siguiente:

csv2notion --token [your__token] --url [your_notion_db_url] --merge output.csv --merge-only-column "Identifier" --merge-only-column "Title" --merge-only-column "Author" --merge-only-column "Publisher" --verbose

Para obtener tu token, es necesario que abras Notion en un navegador web y analices las cookies para obtener el valor de la que se llama token_v2. Yo utilizo Firefox con la extensión Cookie-Editor.

Nota: Es muy importante que no compartas este token con nadie!!

Para obtener el link de la base de datos, haz click derecho en el nombre de la vista y "Copiar link a la vista".

El último paso se debe hacer es determinar que columnas del fichero .csv queremos que se combinen con las existentes. En mi caso, "Identifier", "Title, "Author" y "Publisher". Los únicos valores que han sido extraidos de los ficheros .epub.

El comando se puede ejecutar manualmente desde una consola, pero considero que es mejor integrarlo directamente en el script en Python. Para ello, hay que guardar el comando en un fichero en el mismo directorio que el script en Python con extensión ".sh":

#!/bin/bash

csv2notion --token [your__token] --url [your_notion_db_url] --merge output.csv --merge-only-column "Identifier" --merge-only-column "Title" --merge-only-column "Author" --merge-only-column "Publisher" --verbose

Y añadir la siguiente línea de código al final del todo en el script en Python para que ejecute el nuevo fichero ".sh".

os.system('sh csv2notion.sh')

Script Completo

Puedes encontrar el script completo en mi GitHub haciendo click aquí.

Conclusión

Cada vez que añadamos uno o varios libros a la carpeta y ejecutemos el script, estos apareceran automáticamente en Notion. Lo más importante es que no nos tenemos que preocupar por los ya existentes en Notion ya que no se verán afectados y ni duplicados siempre y cuando la clave primaria de la base de datos no cambie. En mi caso es el ISBN ("Identifier").

Espero que te haya resultado útil este post.

Javier Helguera.

Comentarios