Megacurso programación en Python3 | 3. Cómo publicar en Steemit desde Github

in #steemit7 years ago (edited)

Esta vez vamos a aprender cómo publicar un artículo en Steemit escribiéndolo desde el editor de texto de Github. Para ello, vamos a construir código jugando con las APIs de Steemit y de Github.

Carpeta del proyecto

En la carpeta del curso encontrarás el índice con las clases publicadas.

Lo que haremos será crear este mismo artículo que estás leyendo en Github como un proyecto .md (markdown), y lo subiremos a Steemit mediante el código que diseñaremos.

API Wrappers

Lo primero será instalar las envolturas. Ejecutamos:

pip3 install uritemplate
pip3 install --pre github3.py

git clone https://github.com/xeroc/piston-lib/
cd piston-lib
python3 setup.py install --user

Documentación de github3 - Repositorio de piston-lib


Extraer el contenido de Github

El siguiente paso será extraer el código de un archivo de nuestra carpeta de Github. Para ello, vamos a utilizar la biblioteca github3:

# Introduce here your Github username and password
GITHUB_USERNAME = ''
GITHUB_PASSWORD = ''

# Introduce here your Steemit username and keys
STEEMIT_ACCOUNT_NAME = ''
STEEMIT_POSTING_KEY = ''

# Global imports
import github3
git = github3.login(GITHUB_USERNAME, GITHUB_PASSWORD)

from piston.steem import Steem
wif = {"posting": STEEMIT_POSTING_KEY'}
steem = Steem(nobroadcast=True, keys=wif)

# -------------------------------------------------

def get_code(username, repo, filepath):
        # Devuelve el contenido del archivo del repo indicado
        repository_selected = git.repository(username, repo)
        content = repository_selected.file_contents(filepath)
        try:
                response = content.__dict__['decoded'].decode('utf-8')
        except KeyError:
                message='El archivo {} no existe en el repositorio'
                print(message.format(path))
                return None
        else:
                return response

Todo el código compartido se encuentra en este archivo.

Introducimos nuestro usuario y contraseña de github, nos logueamos en la API y creamos una función que nos devuelve el contenido de un fichero de un usuario. En ella seleccionamos un repositorio de un usuario con repository y con file_contents(filepath) extraemos el contenido de un archivo. Como este viene en un objeto Content, extraemos sus datos con el método __dict__, y de ellos el parámetro decoded del diccionario para extraer el contenido descodificado. Para rematar, lo descodificamos en utf-8 para que no nos dé problemas.

Si salta un KeyError significa que no ha podido extraer nada del diccionario porque no existe un archivo con ese nombre. Si no, retornamos el código.


Procesar el código

Extraer las imágenes

Ahora vamos a extraer las urls de las imágenes del artículo para luego poder mostrarlas en Steemit centradas. Para ello utilizaremos la bilioteca de expresiones regulares de Python3, regex.

Es importante que las rutas de las imágenes de los artículos estén alojadas en la nube, no tengan una dirección local a una carpeta de github del mismo proyecto, si no no se mostrarán en Steemit.

Creamos la siguiente función:

def extract_url_images(code):
        from re import findall
        extensions = ('png', 'jpg', 'bmp', 'gif', 'jpeg')
        images = []
        urls = findall(r'http.*\.[png|jpg|jpeg|bmp|gif]*', code)
        print(urls)
        for u in urls:
                if u[-3:] in extensions:
                        images.append(u)
        return images

Tomamos como parámetro el código que hemos extraído, importamos findall para buscar todas las coincidencias de un patrón y creamos una tupla con extensiones de imágenes. Entonces buscamos todos los patrones que empiecen con 'http' y terminen con una extensión de imagen, y de ellos nos quedamos con los que tienen una de las extensiones al final, para asegurarnos acertar.

Desde aquí puedes acceder a la documentación de regex, para expresiones regulares en python.

Centrar las imágenes en Steemit

Al publicar un artículo en Steemit podemos centrar las imágenes usando las etiquetas HTML <center></center>. Sin embargo, en Github no funciona esto.

En lugar de escribir en Github las etiquetas, que luego no se renderizan y nos afectan en la legibilidad de nuestro artículo, vamos a centrar todas las imágenes automáticamente por defecto al publicar en Steemit. Creamos una última función de apoyo:

def center_images(image_urls_list, code):
        from re import sub
        for i in image_urls:
                code = sub(r'![[].*[]][(]' + i + '[)]', 
                                   '<center>' + i + '</center>', code)
        return code

Le pasamos la lista de urls y el código del artículo, para, usando la función sub de regex, substituir el código url de una imagen en Github (de este estilo: <center>https://s3.postimg.org/q0f8sw7bn/metarticulo.png</center>) a su versión simplificada y centrada en Steemit (<center>https://s3.postimg.org/q0f8sw7bn/metarticulo.png</center>).


Crear un publicador

Ya podemos crear un objeto que nos permita publicar un artículo en Steemit desde nuestro repositorio en Github. Para ello, debajo del código hasta ahora creamos una clase Publisher:

class Publisher(object):
        def __init__(self, repo, filepath,
                                git_user=GITHUB_USERNAME, verbose=False):
                self.git_user = git_user
                self.repo = repo
                self.filepath = filepath
                self.verbose = verbose

        def github_to_steem(self, title, tags=[], image_center=True)
                # Primero extraemos el código del archivo de github
                code = get_code(self.git_user, self.repo, self.filepath)
                if code:
                        # Extraemos las urls de las imágenes del contenido
                        image_urls = extract_url_images(code)

                        # Centramos las imágenes en Steemit
                        if image_center == True:
                                code = center_images(image_urls, code)
                         if self.verbose == True:
                                print(code)
            
                        # Publicamos en Steemit
                        meta = {'allow_votes': True,
                                  'allow_curation_rewards': True,
                                  'percent_steem_dollars': 10000}
                        steem.post(title, code, author=STEEMIT_ACCOUNT_NAME, 
                                   tags=tags, meta=meta)

Esta sería la llamada que voy a realizar para publicar este artículo:

Al instanciar la clase indicamos el repositorio y el path al archivo que queremos publicar en Steemit.

Cambiando el parámetros verbose a True y comentando la última línea, podemos ver el resultado antes de publicarlo:

Tú mism@ puedes adaptar el programa a tus necesidades. ¡Un saludo y hasta la próxima!