Consultar CAE Scotiabank [CLI UTIL] [Python 3]

freishner

Capo
Se incorporó
16 Noviembre 2021
Mensajes
285
A continuación un simple script, para consultar tus cuotas del CAE en Scotiabank.

Nota:
Me reservo el porqué de la aparente pérdida de tiempo que conllevó hacer éste escript.

Importante:

Antes de usar éste script, se deben instalar algunas cosas: python3, pip y el módulo requests.

Instrucciones para sistemas linux debian con gestor de paquetes apt-get (debian, ubuntu, mate...):

Instalar python3
Bash:
sudo apt-get install python3

Instalar pip en python3
Bash:
sudo apt-get install python3-pip

Instalar módulo request
Bash:
pip3 install requests

Yo particularmente uso python3.8, pero usted es libre de usar cualquier versión 3+.

Python:
#!/usr/bin/python3
# -*- coding: utf-8 -*-
from math import ceil
from requests import post
from shutil import get_terminal_size
from sys import argv
from re import match
from json import dumps

class Colors:
    HEADER = '\033[95m'
    OKBLUE = '\033[94m'
    OKCYAN = '\033[96m'
    OKGREEN = '\033[92m'
    WARNING = '\033[93m'
    FAIL = '\033[91m'
    ENDC = '\033[0m'
    BOLD = '\033[1m'
    UNDERLINE = '\033[4m'

class DNIError(Exception):
    def __init__(self, message):
        self.__message = message

    def __str__(self):
        return f"{Colors.FAIL}{self.__message}{Colors.ENDC}"

class DNI:
    def __init__(self, dni):
        self.__dni = dni
        self.__cleanFormat()
   
        if not self.__isValidFormat():
            raise DNIError('[ERROR] ¡Formato inválido del RUT \'X[X].XXX.XXX-X\'!')
        if not self.__check():
            raise DNIError('[ERROR] ¡RUT inválido!')

    def __str__(self):
        return str(self.__dni)

    def __cleanFormat(self):
        self.__dni = self.__dni.replace('.', '') \
            .replace('-', '')

    def __isValidFormat(self):
        dni = self.__dni.lower()
        return len(dni) >= 8 and len(dni) <= 9  \
            and match(r'(?P<dni>[0-9k]{8,9}){1}', dni).group('dni') == dni

    def __check(self):
        vd = 'k' if self.__dni[-1].lower() == 'k' else int(self.__dni[-1].lower());
        m, s = (2, 0)
        for d in self.__dni.lower()[::-1][1:]:
            s += (int(d) * m)
            m = m + 1 if m < 7 else 2
        cvd = 11 - (s % 11)
        if cvd >= 0 and cvd <= 9:
            return vd == cvd
        elif cvd == 10:
            return vd == 'k'
        elif cvd == 1:
            return vd == 0

    def getDNI(self):
        return self.__dni

    def getFormated(self):
        dv = self.__dni[-1]
        if len(self.__dni) == 8:
            p1 = self.__dni[0]
            p2 = self.__dni[1:4]
            p3 = self.__dni[4:7]
        else:
            p1 = self.__dni[0:2]
            p2 = self.__dni[2:5]
            p3 = self.__dni[5:8]

        return '%s.%s.%s-%s' % (p1, p2, p3, dv)

class CAE:
    def __init__(self, dni):
        self.__dni = dni
 
    def __printResponse(self, data):
        if 'code' in data and data['code'] == 1:
            exit(f"[INFO] {Colors.WARNING}{data['message']}...{Colors.ENDC}")

        if data['message'] == 'SUCCESS':
            r = data['result']
            dniFormated = DNI(r['rutCliente']).getFormated()
            clientName = r['nombreCliente'].split(' ')
            clientName = ' '.join(clientName[2:]) + ' ' + ' '.join(clientName[0:2])

            br = '{C}%s{/}\n' % ('-' * 50)
            br2 = '{W}%s{/}\n' % ('=' * 50)

            toPrint = '{TC}RUT Consultado: {/}{W}%s{/}\n' % dniFormated \
                + '\n{TC}Información del Cliente{/}\n' \
                + br \
                + '{C}Nombre: {/}%s\n' % clientName \
                + '{C}Email: {/}%s\n' % r['email'] \
                + br

            if len(r['cuotas']) > 0:
                toPrint += '\n{TC}Cuotas del crédito{/}\n\n'

                for c in r['cuotas']:
                    toPrint += '{W}Cuota: #%s{/}\n%s' % (c['nroCuota'], br2) \
                        + '{TC}Resúmen:{/}\n' \
                        + br \
                        + '{C}Total: {/}$%s\n' % int(ceil(c['totalCuota'])) \
                        + '{C}Fecha de vencimiento: {/}%s\n' % c['fechaVencimiento'] \
                        + '{C}Morosidad: {/}%s\n' % ('Sí' if c['moroso'] else 'No') \
                        + '\n{TC}Detalle:{/}\n' \
                        + br \
                        + '{C}Cuenta: {/}%s\n' % c['nroCuenta'] \
                        + '{C}Tipo: {/}%s\n' % c['item'] \
                        + '{C}Año Licitación: {/}%s\n' % c['anioLicitacion'] \
                        + '{C}Monto por Mora: {/}$%s\n' % int(ceil(c['mora'])) \
                        + '{C}Monto Principal: {/}$%s\n' % int(ceil(c['montoPrincipal'])) \
                        + '{C}Interés: {/}$%s\n' % int(ceil(c['interes'])) \
                        + '{C}Reajuste: {/}$%s\n' % int(ceil(c['reajuste'])) \
                        + '{C}Deducciones: {/}$%s\n' % int(ceil(c['deducciones'])) \
                        + br2
            toPrint = toPrint.replace('{TC}', Colors.BOLD + Colors.OKCYAN) \
                .replace('{W}', Colors.WARNING) \
                .replace('{C}', Colors.OKCYAN) \
                .replace('{/}', Colors.ENDC)
            print(toPrint)

    def query(self):
        payload = dumps({ \
            'rut': self.__dni, \
            'codTipoCredito': 'CAE' \
            } \
        )
        url = 'https://appservtrx.scotiabank.cl/botonpago/credito/getCuotas'
        headers = {'Content-Type': 'application/json'}
        r = post(url, data=payload, headers=headers)
   
        if r.status_code == 200:
            self.__printResponse(r.json())
        else:
            while True:
                r = input('[ERROR] ¡No pude obtener la información! ¿reintentar? [s/n]: ')
                if not 's' in r and not 'n' in r:
                    print('[ERROR] ¡Respuesta errónea!\n')
                    continue
                elif r == 's':
                    self.query()
                else:
                    raise KeyboardInterrupt

def run():
    # NARROW SCREEN: LOCKED
    ####################################################################################
    screenLocked = False
    while get_terminal_size().columns < 60:
        if not screenLocked:
            print( \
                f"{Colors.FAIL}[ERROR] ¡La consola es muy estrecha!{Colors.ENDC}\n" \
                + f"{Colors.OKCYAN}Debes agrandarla...{Colors.ENDC}" \
                , end=''
            )
        screenLocked = True

    if screenLocked:
        print(f"{Colors.OKCYAN}[OK]{Colors.ENDC}\n")
    ####################################################################################

    try:
        if len(argv) > 1:
            dni = argv[1]
        else:
            dni = input('RUT: ')

        CAE(DNI(dni).getDNI()).query()

    except DNIError as e:
        if len(argv) > 1:
            argv.pop()

        print(e, "\n")
        run()

if __name__ == '__main__':
    try:
        run()
    except KeyboardInterrupt as e:
        print("\n\n...quit!")

Guardado
Ahora guarde el script en un archivo llamado cae.py.

Ejecución
Para ejecutarlo se realiza de la siguiente forma:

Código:
python3 cae.py [RUT]
o
Código:
python3 cae.py

El solo le pedirá el RUT a consultar cuando no es entregado como parámetro (como en la primera forma).

Salida
Dependiendo del internet es lo que demora en salir la info, para mi con 3G en zona rural, tarda alrededor de 1~2 segundos.

1649540071581.png

Bonus: alias de 1 comando (sistemas linux debian)
Con ésto conseguiremos un comando llamado cae para ejecutar y tener al instante la información.

Paso 1:
En su archivo de configuración de bash (.bashrc), ingrese al final lo siguiente:

Bash:
alias cae="python3 RUTA-ARCHIVO/cae.py RUT-CONSULTA"

Si el archivo estuviera en nuestra carpeta de usuario, y dicho usuario se llamara "homero", quedaría de la siguiente forma (reemplacé el rut por uno inventado, los puntos y el guión son omitibles):

Bash:
alias cae="python3 /home/homero/cae.py 111111111"

Guarde los cambios, cierre la terminal y ábrala nuevamente. El comando cae estará disponible, ejecútelo y en unos instantes obtendrá la información en pantalla.
 
Última modificación:

PENTIUM4HT

Capo
Se incorporó
26 Junio 2021
Mensajes
103
Buena, yo quiero postear una guia para ataques ddos, aunque nose si me permitan tanto en este foro :zippy
 
Upvote 0

EITSAEB

Team Peacemaker Hater
Se incorporó
10 Septiembre 2006
Mensajes
4.636
¿Qué partes comentarías tu? (para hacerme una idea)
usualmente hago una breve descripción de que hace cada método. y donde obtiene los datos con los que voy a trabajar. por ejemplo si vienen de otro método u archivo etc. En general lo pienso como a mi me gustaría encontrar un código para poder entenderlo.
 
Upvote 0

freishner

Capo
Se incorporó
16 Noviembre 2021
Mensajes
285
Ésto mismo está en el bot de telegram @flc_util_bot, a la larga, era mas práctico desde ahí.

Se usa con el rut sin puntos ni guión.
/caescotiabank RUT

PD: de momento no hay persistencia, así que el rut tiene que ir...
PD: el bot es experimental y explorativo...
 
Upvote 0

VitouXY

Miembro Activo
Se incorporó
28 Diciembre 2021
Mensajes
15
👍🏻 Perfecto, quizás lo utilice en mi Raspberry... para saber cuánto toca pagar...😓

Bash:
curl --request POST --header 'Content-Type: application/json' --json '{ "rut":"00.000.000-0", "codTipoCredito": "CAE" }'  'https://appservtrx.scotiabank.cl/botonpago/credito/getCuotas'
 
Upvote 0

freishner

Capo
Se incorporó
16 Noviembre 2021
Mensajes
285
👍🏻 Perfecto, quizás lo utilice en mi Raspberry... para saber cuánto toca pagar...😓

Bash:
curl --request POST --header 'Content-Type: application/json' --json '{ "rut":"00.000.000-0", "codTipoCredito": "CAE" }'  'https://appservtrx.scotiabank.cl/botonpago/credito/getCuotas'
ojo que hay veces que tira error, he probado otros ruts y nada, pero el mío da error de la nada, debe ser si lo consultas mucho.
 
Upvote 0
Subir