commit 885d4bc3d6abb24b4dacc496a2be21210b34811d Author: jp.av.dev Date: Sat May 14 03:18:52 2022 -0400 init iplocate repo diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e44b238 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +__pycache__/ +test/ +*.db +config.cfg diff --git a/README.md b/README.md new file mode 100644 index 0000000..1480924 --- /dev/null +++ b/README.md @@ -0,0 +1,167 @@ +# iplocate + +## Gestión de logs *nginx* archivados + +Mueve archivos ***log.?.gz*** del servidor existentes en `/var/log/nginx` al directorio +de usuario "**ruta_base**" en el servidor especificado en `./config.cfg`. Utiliza el +script `muevelogz.sh` (script en servidor). + +Mueve los archivos ***log.?.gz*** del directorio de usuario del servidor al directorio +local "**destino_log**" especificado en `./config.cfg`. +Descomprime archivos **`.gz`** y concatena los respectivos archivos de log. +Borra los archivos utilizados en concatenación. Script `./muevelog.sh`. + +ej. archivo de configuración `./config.cfg` +```cfg +[bash_script] +ruta_base=mi_server://home/server_user/nginx_log.old/ +destino_log=/home/server_logs/nginx_old +server_name=mi_server +server_script=//home/server_user/scripts/muevelogz.sh + +[iplocate] +token = '?token=1234567890abc' +``` +- ***mi_server***: parte de *ruta_base*, nombre del host según configuración + en `~/.ssh/config`. +- **ruta_base** : es la ruta en el servidor donde se mueven los logs + archivados (.gz) desde `/var/log/nginx/` (termina en `/`). +- **destino_log** : ruta donde se guardan local y temporalmente los + archivos *log.?.gz*. +- **server_name** : nombre del host según configuración en `~/.ssh/config`. +- **server_script** : ruta en el servidor, del script que mueve los *log.?.gz*. + + +Crea base de datos ***SQLite3*** **`./ipinfo.db`** con tablas de **registro** y de **visitas**. + +## Uso +`./iplocate.py -h` +ej. alias `alias iploc='~/ruta/script/iplocate.py'` +```bash + ipLocate + Muestra información disponible en ipinfo.io sobre IPs consultadas. + + Uso: + iploc - Muestra la información de . + iploc -f - Muestra info. de las IPs en + iploc -c - Carga logs en base de datos. + iploc -g - Guarda ipinfo de IPs sin registro en la BD. + iploc -h - Muestra esta ayuda. + iploc --sync - Sincroniza logs del servidor (bash script). + +``` + +**`iploc --sync`** +Realiza el proceso de copia de archivos del servidor, extracción y concatenado. +Explicado con detalle mas arriba. + +**`iploc -c`** +Poblar la tabla **visita** de la BD. Carga los registros en archivos de log en la tabla. + +**`iploc -g`** +Consulta a `ipinfo.io` por cada ip registrada en **visita** (una vez por ip). +Guarda los datos en tabla **registro**. + +### Otras opciones + +`iploc `: + - Muestra la información sobre \ disponible en ipinfo.io. + +`iploc -t `: **PENDIENTE** + - Muestra la información sobre \ disponible en ipinfo.io + usando el **token** especificado en `./config.cfg`. + +`iploc -d `: **PENDIENTE** + - Muestra toda la información disponible en BD acerca de \ + +`iploc -f `: + - Muestra la información disponible en ipinfo.io para cada \ + en archivo pasado como argumento. + +`iploc -D `: **PENDIENTE** + - Muestra toda la información disponible en BD para cada \ + en archivo pasado como argumento. + +ej. formato \. +``` +1.1.1.1 +8.8.8.8 +... +``` + +### Sicronización manual + +No es necesario el uso manual de este script, ya que es llamado por `iploc --sync`. +Pero ya que existe por que no tener la opción de llamar manualmente a las funciones. + +`./muevelog.sh -h` +``` + Ejecuta script del servidor que mueve los logs archivados, copia en ruta + de trabajo, concatena y elimina los archivos sobrantes. + + Programa pensado para ser llamado por iplocate.py (muevelog.sh --start). + + Operación manual: ./muevelog.sh [OPCION] + + Ruta de trabajo: + + Opciones: + -s, --start - Copia, extrae y concatena logs. + -S, --sync - Mueve logs.gz en el servidor (Pre-Copia). + -C, --copia - Copia logs del servidor en ruta de trabajo (Post-sync). + -x, --extraer - Descomprime logs en ruta de trabajo. + -c, --concat [error.log, all...] - Concatena logs de la ruta de trabajo. + -v, --version - Muestra la fecha de la versión. + -h, --help - Muestra información de ayuda. +``` + +`./muevelog.sh --start`: +Realiza todo el proceso **--sync**, **--copia**, **--extraer** y **--concat**. + + +### Implementación +Clonar proyecto en directorio ej. `~/nginx_data`. + +Crear `alias iploc='~/nginx_data/iplocate.py'`. + +Modificar ruta **logdest** en `muevelogz.sh` y copiar en el servidor. +``` +# logdest debe ser la misma ruta especificada en config.cfg como *ruta_base* +logdest= +``` +Crear archivo de configuración según ejemplo mostrado en la primera sección +de este documento. + +Correr `iploc -h` para crear base de datos. + +``` +📂️ nginx_data/ +├── 📄️ config.cfg +├── 📄️ ipinfo.db +├── 📄️ iplocate.py +├── 📄️ muevelog.sh +├── 📄️ muevelogz.sh +├── 📄️ README.md +└── 📄️ sql_alch.py +``` + +Seguir los pasos explicados en **Uso**. + +### Requerimientos, dependencias + +Servidor: +- Bash >= 5.0 +- rsync + +Local: +- Bash local >= 5.1.16 +- SQLite3 3.38.5 +- sqlitebrowser 3.35.5 (opc.) +- Python >= 3.10 + - requests + - SQLAlchemy 1.4.32 + - colorama + +Token API [ipinfo.io](https://ipinfo.io/) + + diff --git a/iplocate.py b/iplocate.py new file mode 100755 index 0000000..76dd82f --- /dev/null +++ b/iplocate.py @@ -0,0 +1,143 @@ +#!/usr/bin/env python + +import os +import sys +import subprocess +import requests +import re +import configparser as cfg +from os.path import isfile +from json import loads +from colorama import Fore, Back, Style +import sql_alch + +selfpath = os.path.abspath(os.path.dirname(__file__)) +ownip = requests.get('https://ifconfig.me/').text +parser = cfg.ConfigParser() +parser.read(f'{selfpath}/config.cfg') +token = parser.get('iplocate','token') +token = token.strip("'") +muevelog = f'{selfpath}/muevelog.sh ' + +# Colores +co_rst = Style.RESET_ALL +co_Blu = Fore.BLUE+Style.NORMAL +co_BluD = Fore.BLUE+Style.DIM +co_BluB = Fore.BLUE+Style.BRIGHT +co_Red = Fore.RED+Style.NORMAL +co_RedD = Fore.RED+Style.DIM +co_RedB = Fore.RED+Style.BRIGHT +co_Grn = Fore.GREEN+Style.NORMAL +co_GrnD = Fore.GREEN+Style.DIM +co_GrnB = Fore.GREEN+Style.BRIGHT +co_Yel = Fore.YELLOW+Style.NORMAL +co_YelD = Fore.YELLOW+Style.DIM +co_YelB = Fore.YELLOW+Style.BRIGHT +co_BluLWh = Fore.BLUE+Back.LIGHTWHITE_EX+Style.NORMAL +co_BluLWhB = Fore.BLUE+Back.LIGHTWHITE_EX+Style.BRIGHT +co_GrnMgnB = Fore.GREEN+Back.MAGENTA+Style.BRIGHT +co_RedBluD = Fore.RED+Back.BLUE+Style.DIM +co_LRedBleD = Fore.LIGHTRED_EX+Back.BLUE+Style.DIM +co_BlkMgnB = Fore.BLACK+Back.MAGENTA+Style.BRIGHT +co_BlkMgn = Fore.BLACK+Back.MAGENTA+Style.NORMAL +co_LGrLBlk = Fore.LIGHTGREEN_EX+Back.LIGHTBLACK_EX +co_RdYl = Fore.RED+Back.YELLOW+Style.NORMAL +co_RdYlB = Fore.RED+Back.YELLOW+Style.BRIGHT +co_BlkLBlkD = Fore.BLACK+Back.LIGHTBLACK_EX+Style.DIM +co_BluLBlkD = Fore.BLUE+Back.LIGHTBLACK_EX+Style.DIM +co_cuBlu = '\33[38;5;122m' +# IP validate https://stackoverflow.com/questions/319279/how-to-validate-ip-address-in-python +ip_regx = "^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])$" + +def filtro_ip_propia(ip): + return True if ip != ownip else False + + +def consulta_db(ip_consulta): + consulta = f'https://ipinfo.io/{ip_consulta}{token}' + info_ip = requests.get(consulta).text + return loads(info_ip) + + +def consulta(ip_consulta): + consulta = f'https://ipinfo.io/{ip_consulta}' + info_ip = requests.get(consulta).text + info_ip = loads(info_ip) + for llave, valor in info_ip.items(): + print(f'{co_YelB}{llave}\b\t{co_Blu}->{co_rst} {co_Grn}{valor}{co_rst}') + + +def ipLocate(ip): + if (re.search(ip_regx, ip)): + consulta(ip) + print(f'{co_RedB}------------------------------', end='') + print(f'--------------------------------{co_rst}') + else: + ipr = ip.split('\n')[0] + print(f'{co_Red}[{co_BlkMgn}{ipr}{co_rst}{co_Red}] no es una IP válida!{co_rst}') + + +def archivo_ips(ips): + with open(ips, 'r') as lista: + for linea in lista: + ipLocate(linea) + sys.exit(0) + + +def main(): + try: + match sys.argv[1]: + case '--sync': + print(f'{co_YelB}Sincronizando logs del servidor(bash script){co_rst}') + subprocess.check_call( + muevelog+"%s" % "--start", + shell=True) + case '-c': + print(f'{co_YelB}Cargando logs en base de datos{co_rst}') + sql_alch.carga_logs() + case '-g': + print(f'{co_YelB}Registrando datos de ipinfo{co_rst}') + sql_alch.registro_ips() + case '-f': + if isfile(sys.argv[2]): + archivo_ips(sys.argv[2]) + else: + print(f'{co_Red}Archivo [{co_BlkMgn}{sys.argv[2]}'+ + f'{co_rst}{co_Red}] no es válido''') + sys.exit(0) + case '-h': + uso() + exit(0) + case _: + ip = sys.argv[1] + ipLocate(ip) + except IndexError: + print(f'\n{co_Blu}Ingresa una {co_BluB}IP o \'s\' ',end='') + print(f'{co_Blu}para salir:{co_rst}') + while True: + ip = input(f'{co_BluB} -> {co_rst}') + if ip in 'sq0SQnN': + exit(0) + ipLocate(ip) + finally: + sys.exit(0) + + +def uso(): + ayuda = f""" + {co_BluB}ipLocate{co_rst} + {co_cuBlu}Muestra información disponible en ipinfo.io sobre IPs consultadas.{co_rst} + + {co_BluB}Uso:{co_rst} + {co_YelB}iploc {co_Blu} {co_Grn}- Muestra la información de .{co_rst} + {co_YelB}iploc -f {co_Blu} {co_Grn}- Muestra info. de las IPs en + {co_YelB}iploc -c {co_Grn}- Carga logs en base de datos.{co_rst} + {co_YelB}iploc -g {co_Grn}- Guarda ipinfo de IPs sin registro en la BD.{co_rst} + {co_YelB}iploc -h {co_Grn}- Muestra esta ayuda.{co_rst} + {co_YelB}iploc --sync {co_Grn}- Sincroniza logs del servidor (bash script).{co_rst} + + """ + print(ayuda) + +if __name__ == "__main__": + main() diff --git a/muevelog.sh b/muevelog.sh new file mode 100755 index 0000000..30fa592 --- /dev/null +++ b/muevelog.sh @@ -0,0 +1,161 @@ +#!/usr/bin/env bash + +Progrm=$0 +VersionStr='2022-05-14' +rutaprgrm=$(dirname $(realpath -s $0)) + +while read line; do + declare "$line" 2>/dev/null +done < $rutaprgrm/config.cfg + + +REd="\e[0;31m"; GRn="\e[0;32m"; BLu="\e[0;34m"; +RED="\e[1;31m"; GRN="\e[1;32m"; BLU="\e[1;34m"; +RST="\e[0m"; + +Err(){ + printf '%bERROR: %s%b\n' "${RED}" "$2" "${RST}" 1>&2 + [ $1 -gt 0 ] && exit $1 +} + +Info(){ + printf '%bINFO: %s%b\n' "${REd}" "$2" "${RST}" 1>&2 + [ $1 -gt 0 ] && exit $1 +} + +Uso(){ + while read; do + printf '%s\n' "$REPLY" + done <<-EOF + Ejecuta script del servidor que mueve los logs archivados, copia en ruta + de trabajo, concatena y elimina los archivos sobrantes. + + Programa pensado para ser llamado por iplocate.py (muevelog.sh --start). + + Operación manual: ./muevelog.sh [OPCION] + + Ruta de trabajo: $destino_log + + Opciones: + -s, --start - Copia, extrae y concatena logs. + -S, --sync - Mueve logs.gz en el servidor (Pre-Copia). + -C, --copia - Copia logs del servidor en ruta de trabajo (Post-sync). + -x, --extraer - Descomprime logs en ruta de trabajo. + -c, --concat [error.log, all...] - Concatena logs de la ruta de trabajo. + -v, --version - Muestra la fecha de la versión. + -h, --help - Muestra información de ayuda. +EOF +} + +sync_logs(){ + printf '%b - Sincronizando con %s%b\n' "${GRn}" "${server_name}" "${RST}" + ssh -M -t $server_name $server_script || Info 1 'No hay logs.gz en este momento' +} + +copia_logs(){ + mkdir "$destino_log" 2>/dev/null + if [[ "$(ls $destino_log/*.* 2>/dev/null)" ]]; then + Info 0 'Hay logs pendientes de ser cargados a base de datos\n' + else + printf '%b - Moviendo logs.gz%b' "${GRn}" "${RST}" + rsync --remove-source-files -ha --info=progress2 "${ruta_base}" "${destino_log}" + fi +} + +extrae_logs(){ + if [[ "$(ls $destino_log/*.gz 2>/dev/null)" ]]; then + for file in $(ls $destino_log/*.gz); do + gunzip ${file} + done + else + Info 0 'No existen logs.gz para extraer!' + fi +} + +concat_log(){ + log_tipo="${1}" + if [[ "$(ls $destino_log/$log_tipo.* 2>/dev/null)" ]]; then + printf '%b - Concatenando log %s %b\n' "${GRn}" "${1}" "${RST}" + for file in $(\ls -v $destino_log/$log_tipo.*); do + cat $file >> $destino_log/$log_tipo + rm -f $file + done + else + Info 0 "No existen logs [${log_tipo}] para concatenar" + fi #2>/dev/null +} + +concatena_logs(){ + concat_log access.log && + concat_log error.log && + concat_log reverse-access.log && + concat_log reverse-error.log +} + +main(){ + printf '%b - Preparación del servidor, pre-copia:%b\n' "${GRN}" "${RST}" && + sync_logs || Err 0 'Error al syncronizar!' + wait + printf '%b - Copiando logs del servidor en\n - %s :%b\n' "${GRN}" "${destino_log}" "${RST}" && + copia_logs && printf '%b Copia completada%b\n' "${BLu}" "${RST}" || Err 0 'Error al copiar!' + wait + printf '%b - Descomprimiendo archivos gunzip%b\n' "${GRN}" "${RST}" && + extrae_logs && printf '%b Extración completada%b\n' "${BLu}" "${RST}" || + Err 0 'Error al descomprimir!' + wait + printf '%b - Concatenando archivos:%b\n' "${GRN}" "${RST}" && concatena_logs && + printf '%b Archivos concatenados%b\n\n' "${BLu}" "${RST}" || Err 0 'Error al concatenar logs!' + printf '%bProceso terminado %b\n' "${BLU}" "${RST}" +} + +if [ -n "${1}" ]; then + case $1 in + --sync|-S) + sync_logs + exit 0 + ;; + --copia|-C) + copia_logs + exit 0 + ;; + --extraer|-x) + extrae_logs + exit 0 + ;; + --concat|-c) + case ${2} in + access.log) + concat_log ${2} ;; + error.log) + concat_log ${2} ;; + reverse-access.log) + concat_log ${2} ;; + reverse-error.log) + concat_log ${2} ;; + all) + concatena_logs ;; + *) + Err 1 'Ingresa el tipo de log a concatenar (access.log, all, etc)' ;; + esac + exit 0 + ;; + --help|-h) + Uso; exit 0 + ;; + --version|-v) + printf '%s\n' "$VersionStr"; exit 0 + ;; + --help|-h) + Uso; exit 0 + ;; + --start|-s) + main; exit 0 + ;; + *) + Err 1 'Argumento(s) invalido(s).' ;; + esac +else + Err 1 'Debes incluir una opción. ej: --help' +fi + +"$@" diff --git a/muevelogz.sh b/muevelogz.sh new file mode 100755 index 0000000..3a61cbc --- /dev/null +++ b/muevelogz.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash + +# logdest debe ser la misma ruta especificada en config.cfg como *ruta_base* +logdest= +serv_user="${USER}" + +logdir=/var/log/nginx + +mueve_loggz(){ + if [[ "$(ls $logdir/*.log.*.gz 2>/dev/null)" ]]; then + printf 'Moviendo logs.gz de %s/\n' "${logdir}" + sudo mv $logdir/*.log.*.gz $logdest + sudo chown $serv_user:$serv_user $logdest/* + else + printf 'No hay logs archivados para mover\n' + exit 1 + fi + exit 0 +} + +if [[ "$(ls $logdest/*.gz 2>/dev/null)" ]]; then + printf 'Existen logs pendientes de respaldo\n' +else + mueve_loggz +fi +exit 0 diff --git a/sql_alch.py b/sql_alch.py new file mode 100644 index 0000000..438971b --- /dev/null +++ b/sql_alch.py @@ -0,0 +1,224 @@ +import os +import time +from datetime import datetime +from sqlalchemy import create_engine +from sqlalchemy.orm import sessionmaker +from sqlalchemy.ext.declarative import declarative_base +from sqlalchemy import Column, Integer, String, Sequence, update +from sqlalchemy.orm.session import Session +from sqlalchemy.sql.expression import select +import iplocate as ipl + +logs_dir = ipl.parser.get('bash_script', 'destino_log') +logs_dir = logs_dir.strip("'") +base_de_datos = f'sqlite:////{ipl.selfpath}/ipinfo.db' + +Base = declarative_base() + +class Visita(Base): + __tablename__ = 'visita' + id = Column(Integer, Sequence('visita_id_seq'), primary_key=True) + ip = Column(String) + html = Column(Integer) + fecha = Column(Integer) + registro = Column(Integer, default=0) + + def get_fecha(self): + return time.asctime(time.localtime(int(self.fecha.__repr__()))) + + def fecha_local(self): + fecha_l = self.get_fecha() + #fecha_l = time.asctime(self.fecha) + return fecha_l + #fecha_l = time.strftime(fecha_l) + + def consulta_registro(self): + return True if self.registro == 1 else False + + def __repr__(self) -> str: + return "ID: {}\nIP: {}\nHtmlCode: {}\n" \ + "Fecha: {}\nRegistrado: {}\n".format( + self.id, + self.ip, + self.html, + self.get_fecha(), + self.consulta_registro()) + + +# Tabla registro ip info +class Registro(Base): + __tablename__ = 'registro' + id = Column(Integer, Sequence('registro_id_seq'), primary_key=True) + ip = Column(String) + hostname = Column(String, nullable=True) + anycast = Column(String, nullable=True) + cuidad = Column(String, nullable=True) + region = Column(String, nullable=True) + pais = Column(String, nullable=True) + geoloc = Column(String, nullable=True) + organizacion = Column(String, nullable=True) + fecha_reg = Column(Integer, default=int(time.mktime(time.localtime()))) + tzone = Column(String, nullable=True) + cod_post = Column(String, nullable=True) + link = Column(String, nullable=True) + + +engine = create_engine(base_de_datos) +Base.metadata.create_all(engine) +#Base.metadata.create_all(engine.execution_options(synchronize_session="fetch")) +Session = sessionmaker(bind=engine) +session = Session() + + +# Formatos fechas logs: +""" +# access.log == reverse_access.log +# error.log == reverse_error.log +fecha_error = "2022/05/10 07:11:46" +fecha_access = "10/May/2022:11:42:14 -0400".split(' ')[0] +""" + +def fecha_access_to_epoch(fecha): + """Convierte al fecha del formato entregado por access.log + y reverse_access.log(nginx) al formato unix epoch. + + :fecha: str Fecha + :returns: int unix epoch fecha (secs) + """ + fecha = datetime.strptime(fecha, '%d/%b/%Y:%H:%M:%S') + fecha_unix = int(time.mktime(fecha.timetuple())) + return fecha_unix + +def fecha_error_to_epoch(fecha): + """Convierte al fecha del formato entregado por error.log + y reverse_error.log (nginx) al formato unix epoch. + + :fecha_local: str Fecha + :returns: int unix epoch fecha (secs) + """ + fecha = datetime.strptime(fecha, '%Y/%m/%d %H:%M:%S') + fecha_unix = int(time.mktime(fecha.timetuple())) + return fecha_unix + +def epoch_to_local(fecha): + """Convierte fecha unix epoch a localtime + + :fecha: int Fecha (secs) + :returns: str Fecha + """ + return time.asctime(time.localtime(int(fecha))) + + +def ip_registrada(ip): + ip_reg = session.query(Visita).filter(Visita.ip==ip).filter(Visita.registro==1).first() + return 0 if ip_reg is None else ip_reg.registro + + +def carga_access_log(log): + if os.path.exists(log): + print(f'{ipl.co_Yel}Registrando [{log}]{ipl.co_rst}') + try: + with open(log, 'r') as lista: + for linea in lista: + ip = linea.split(' ')[0] + if ipl.filtro_ip_propia(ip): + fecha = fecha_access_to_epoch(linea.split(' ')[3][1:]) + codigo= int(linea.split('"')[2].split(' ')[1]) + if ip_registrada(ip): + session.add(Visita(ip=ip, html=codigo, fecha=fecha, registro=1)) + else: + session.add(Visita(ip=ip, html=codigo, fecha=fecha)) + session.commit() + print(f'{ipl.co_Grn}Carga completa.. borrando log{ipl.co_rst}\n') + os.remove(log) + return True + except: + print(f'{ipl.co_Red}Ocurrio un error al intentar abrir/cargar: [{log}]{ipl.co_rst}\n') + return False + else: + print(f'{ipl.co_Red}log: [{log}] inexistente.{ipl.co_rst}\n') + return False + + +def carga_error_logs(log): + if os.path.exists(log): + print(f'{ipl.co_Yel}Registrando [{log}]{ipl.co_rst}') + try: + with open(log, 'r') as lista: + for linea in lista: + ip = linea.split('client: ')[1].split(',')[0] + if ipl.filtro_ip_propia(ip): + fecha = fecha_error_to_epoch(' '.join(linea.split()[0:2])) + codigo = 300 + if ip_registrada(ip): + session.add(Visita(ip=ip, html=codigo, fecha=fecha, registro=1)) + else: + session.add(Visita(ip=ip, html=codigo, fecha=fecha)) + session.commit() + print(f'{ipl.co_Grn}Carga completa.. borrando log{ipl.co_rst}\n') + os.remove(log) + return True + except: + print(f'{ipl.co_Red}Ocurrio un error'+ + f'al intentar abrir/cargar: [{log}]{ipl.co_rst}\n') + return False + else: + print(f'{ipl.co_Red}log: [{log}] inexistente.{ipl.co_rst}\n') + return False + + +def carga_logs(): + print(f'{ipl.co_Grn}Carga de logs en base de datos:{ipl.co_rst}\n') + carga_access_log(logs_dir+'/access.log') + carga_access_log(logs_dir+'/reverse-access.log') + carga_error_logs(logs_dir+'/error.log') + carga_error_logs(logs_dir+'/reverse-error.log') + + +def carga_registro_ip(ip_info): + if not ip_registrada(ip_info['ip']): + info_dic = {} + info_dic['ip'] = ip_info['ip'] + info_dic['hostname'] = ip_info['hostname'] if 'hostname' in ip_info else None + info_dic['anycast'] = ip_info['anycast'] if 'anycast' in ip_info else None + info_dic['ciudad'] = ip_info['city'] if 'city' in ip_info else None + info_dic['region'] = ip_info['region'] if 'region' in ip_info else None + info_dic['pais'] = ip_info['country'] if 'country' in ip_info else None + info_dic['geoloc'] = ip_info['loc'] if 'loc' in ip_info else None + info_dic['organizacion'] = ip_info['org'] if 'org' in ip_info else None + info_dic['tzone'] = ip_info['timezone'] if 'timezone' in ip_info else None + info_dic['cod_post'] = ip_info['postal'] if 'postal' in ip_info else None + info_dic['link'] = ip_info['readme'] if 'readme' in ip_info else None + session.add(Registro( ip = info_dic['ip'], + hostname = info_dic['hostname'], + anycast = info_dic['anycast'], + cuidad = info_dic['ciudad'], + region = info_dic['region'], + pais = info_dic['pais'], + geoloc = info_dic['geoloc'], + organizacion = info_dic['organizacion'], + fecha_reg = int(time.mktime(time.localtime())), + tzone = info_dic['tzone'], + cod_post = info_dic['cod_post'], + link = info_dic['link'], + )) + session.commit() + stmt = update(Visita).where(Visita.ip == ip_info['ip']).values(registro=1).\ + execution_options(synchronize_session="fetch") + #result = session.execute(stmt) + session.execute(stmt) + session.commit() + + +def registro_ips(): + registrar = True + while registrar: + statement = select(Visita).filter_by(registro=0) + res = session.execute(statement).scalars().first() + if res is None: + print(f'{ipl.co_Grn}Registro ipinfo en DB finzalizado.{ipl.co_rst}') + registrar = False + #ip_actual= res.ip.split('\n')[0] + ip_actual= res.ip + ip_info = ipl.consulta_db(ip_actual) + carga_registro_ip(ip_info)