init iplocate repo

This commit is contained in:
jp.av.dev 2022-05-14 03:18:52 -04:00
commit 885d4bc3d6
6 changed files with 725 additions and 0 deletions

4
.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
__pycache__/
test/
*.db
config.cfg

167
README.md Normal file
View File

@ -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 <IP> - Muestra la información de <IP>.
iploc -f <archivo> - Muestra info. de las IPs en <archivo>
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 <IP>`:
- Muestra la información sobre \<IP\> disponible en ipinfo.io.
`iploc -t <IP>`: **PENDIENTE**
- Muestra la información sobre \<IP\> disponible en ipinfo.io
usando el **token** especificado en `./config.cfg`.
`iploc -d <IP>`: **PENDIENTE**
- Muestra toda la información disponible en BD acerca de \<IP\>
`iploc -f <archivo_IPs>`:
- Muestra la información disponible en ipinfo.io para cada \<IP\>
en archivo pasado como argumento.
`iploc -D <archivo_IPs>`: **PENDIENTE**
- Muestra toda la información disponible en BD para cada \<IP\>
en archivo pasado como argumento.
ej. formato \<archivo_IPs\>.
```
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: </ruta/segun/config.cfg>
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=</ruta/user/docs/logs/nginx_log.old>
```
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/)

143
iplocate.py Executable file
View File

@ -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}<IP> {co_Grn}- Muestra la información de <IP>.{co_rst}
{co_YelB}iploc -f {co_Blu}<archivo> {co_Grn}- Muestra info. de las IPs en <archivo>
{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()

161
muevelog.sh Executable file
View File

@ -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
"$@"

26
muevelogz.sh Executable file
View File

@ -0,0 +1,26 @@
#!/usr/bin/env bash
# logdest debe ser la misma ruta especificada en config.cfg como *ruta_base*
logdest=</ruta/user/docs/logs/nginx_log.old>
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

224
sql_alch.py Normal file
View File

@ -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)