update tamaulipas
This commit is contained in:
parent
b61a638078
commit
c8426f005b
4
.obsidian/appearance.json
vendored
4
.obsidian/appearance.json
vendored
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"cssTheme": "",
|
"cssTheme": "",
|
||||||
"baseFontSizeAction": true,
|
"baseFontSizeAction": true,
|
||||||
"baseFontSize": 21,
|
"baseFontSize": 30,
|
||||||
"theme": "obsidian"
|
"theme": "moonstone"
|
||||||
}
|
}
|
4
.obsidian/core-plugins.json
vendored
4
.obsidian/core-plugins.json
vendored
@ -27,5 +27,7 @@
|
|||||||
"file-recovery": true,
|
"file-recovery": true,
|
||||||
"publish": false,
|
"publish": false,
|
||||||
"sync": true,
|
"sync": true,
|
||||||
"webviewer": false
|
"webviewer": false,
|
||||||
|
"footnotes": false,
|
||||||
|
"bases": true
|
||||||
}
|
}
|
35
.obsidian/workspace.json
vendored
35
.obsidian/workspace.json
vendored
@ -53,7 +53,7 @@
|
|||||||
"state": {
|
"state": {
|
||||||
"type": "search",
|
"type": "search",
|
||||||
"state": {
|
"state": {
|
||||||
"query": "",
|
"query": "pagos",
|
||||||
"matchingCase": false,
|
"matchingCase": false,
|
||||||
"explainSearch": false,
|
"explainSearch": false,
|
||||||
"collapseAll": false,
|
"collapseAll": false,
|
||||||
@ -160,6 +160,7 @@
|
|||||||
},
|
},
|
||||||
"left-ribbon": {
|
"left-ribbon": {
|
||||||
"hiddenItems": {
|
"hiddenItems": {
|
||||||
|
"bases:Crear nueva base": false,
|
||||||
"switcher:Abrir selector rápido": false,
|
"switcher:Abrir selector rápido": false,
|
||||||
"graph:Abrir vista gráfica": false,
|
"graph:Abrir vista gráfica": false,
|
||||||
"canvas:Crear nuevo lienzo": false,
|
"canvas:Crear nuevo lienzo": false,
|
||||||
@ -168,12 +169,26 @@
|
|||||||
"command-palette:Abrir paleta de comandos": false
|
"command-palette:Abrir paleta de comandos": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"active": "5ff6ca2da58ba6f5",
|
"active": "db862854e8b7e53a",
|
||||||
"lastOpenFiles": [
|
"lastOpenFiles": [
|
||||||
|
"ELIMINAR/FIVE_MUSEO.docx.md",
|
||||||
|
"ELIMINAR/Sin título.md",
|
||||||
|
"ELIMINAR/DOF_LINEAMIENTOS para el ciclo de gestión de los programas y proyectos de inversión, a cargo de las dependencias y entidades de la Administración Pública Federal..md",
|
||||||
|
"DIX-Notes/Otras_varias/Pagos Jesús.md",
|
||||||
|
"ELIMINAR",
|
||||||
|
"eliminar.md",
|
||||||
|
"Agencia_Espacial_Mexicana/Excel-Macros_AEM/Tabla de Excel a Markdown.md",
|
||||||
|
"DIX-Notes/INSTALAR TESSERACT-OCT.md",
|
||||||
|
"DIX-Notes/dns arrancar con el sistema.md",
|
||||||
|
"DIX-Notes/notas_express.md",
|
||||||
|
"DIX-Notes/bash profile.md",
|
||||||
|
"Agencia_Espacial_Mexicana/Registro_Proyecto_Cartera_Inversion/1.- Análisis Financiero Sistema Satelital de Telecomunicaciones..md",
|
||||||
|
"DIX-Notes/DDNS RASTREO CON CLOUDFLARE.md",
|
||||||
|
"DIX-Notes/Wireguard con obfuscación.md",
|
||||||
|
"DIX-Notes/script_bash_servers/crontab.md",
|
||||||
"DIX-Notes/SERVERS - DIX/adjuntos/~$servers.xlsm",
|
"DIX-Notes/SERVERS - DIX/adjuntos/~$servers.xlsm",
|
||||||
"DIX-Notes/SERVERS - DIX/adjuntos/C87ED000",
|
"DIX-Notes/SERVERS - DIX/adjuntos/C87ED000",
|
||||||
"DIX-Notes/SERVERS - DIX/SERVERS DIX.md",
|
"DIX-Notes/SERVERS - DIX/SERVERS DIX.md",
|
||||||
"DIX-Notes/script_bash_servers/crontab.md",
|
|
||||||
"DIX-Notes/script_bash_servers/scripts_linux/shutdown_weekends.sh",
|
"DIX-Notes/script_bash_servers/scripts_linux/shutdown_weekends.sh",
|
||||||
"DIX-Notes/script_bash_servers/scripts_linux/shutdown.sh",
|
"DIX-Notes/script_bash_servers/scripts_linux/shutdown.sh",
|
||||||
"DIX-Notes/script_bash_servers/scripts_linux/cron.log",
|
"DIX-Notes/script_bash_servers/scripts_linux/cron.log",
|
||||||
@ -181,19 +196,13 @@
|
|||||||
"DIX-Notes/script_bash_servers/scripts_linux/history_log.txt",
|
"DIX-Notes/script_bash_servers/scripts_linux/history_log.txt",
|
||||||
"DIX-Notes/script_bash_servers/scripts_linux",
|
"DIX-Notes/script_bash_servers/scripts_linux",
|
||||||
"DIX-Notes/script_bash_servers",
|
"DIX-Notes/script_bash_servers",
|
||||||
"DIX-Notes/SERVERS - DIX/adjuntos/6C708000",
|
|
||||||
"DIX-Notes/dns arrancar con el sistema.md",
|
|
||||||
"Agencia_Espacial_Mexicana/notas_express.md",
|
"Agencia_Espacial_Mexicana/notas_express.md",
|
||||||
"DIX-Notes/Sin nombre",
|
|
||||||
"Agencia_Espacial_Mexicana/ELIMINAR_NOTAS/3. Museo de las Telecomunicaciones - PPI_.md",
|
"Agencia_Espacial_Mexicana/ELIMINAR_NOTAS/3. Museo de las Telecomunicaciones - PPI_.md",
|
||||||
"DIX-Notes/notas_express.md",
|
|
||||||
"Agencia_Espacial_Mexicana/DEFINICIONES Y EXPLICACIONES PROYECTOS CARTERA DE INVERSIÓN.md",
|
"Agencia_Espacial_Mexicana/DEFINICIONES Y EXPLICACIONES PROYECTOS CARTERA DE INVERSIÓN.md",
|
||||||
"DIX-Notes/Transcribir Videos (WSL).md",
|
"DIX-Notes/Transcribir Videos (WSL).md",
|
||||||
"DIX-Notes/DIX_Cluster.canvas",
|
"DIX-Notes/DIX_Cluster.canvas",
|
||||||
"Sin título.canvas",
|
"Sin título.canvas",
|
||||||
"DIX-Notes/DDNS RASTREO CON CLOUDFLARE.md",
|
|
||||||
"DIX-Notes/corregir error ip.xala.dev vs dix-ip.duckdns.org.md",
|
"DIX-Notes/corregir error ip.xala.dev vs dix-ip.duckdns.org.md",
|
||||||
"Agencia_Espacial_Mexicana/Excel-Macros_AEM/Tabla de Excel a Markdown.md",
|
|
||||||
"Agencia_Espacial_Mexicana/Excel-Macros_AEM/Prorrateo.md",
|
"Agencia_Espacial_Mexicana/Excel-Macros_AEM/Prorrateo.md",
|
||||||
"Agencia_Espacial_Mexicana/Estatuto Orgánico AEM/Estatuto Orgánico AEM.md",
|
"Agencia_Espacial_Mexicana/Estatuto Orgánico AEM/Estatuto Orgánico AEM.md",
|
||||||
"trabajar_script_mc_backup.md",
|
"trabajar_script_mc_backup.md",
|
||||||
@ -201,14 +210,6 @@
|
|||||||
"Install_n8n.md",
|
"Install_n8n.md",
|
||||||
"bash profile.md",
|
"bash profile.md",
|
||||||
"DIX_Cluster.canvas",
|
"DIX_Cluster.canvas",
|
||||||
"Otras_varias/Jellyfin en ubuntu server 24.04.md",
|
|
||||||
"Otras_varias/Notificaciones con ntfy.sh.md",
|
|
||||||
"Otras_varias/Servidor SAMBA.md",
|
|
||||||
"Otras_varias/Pagos Jesús.md",
|
|
||||||
"Otras_varias/SSL red local con HAProxy.md",
|
|
||||||
"Otras_varias/Visualización carga de trabajo servers.md",
|
|
||||||
"Bash_functions/Script_sincronizar_obsidian.md",
|
|
||||||
"Bash_functions/ip_device.md",
|
|
||||||
"Agencia_Espacial_Mexicana/Cursos_Capacitación/Introducción a la Administración Pública Federal/adjuntos/Pasted image 20250801164816.png",
|
"Agencia_Espacial_Mexicana/Cursos_Capacitación/Introducción a la Administración Pública Federal/adjuntos/Pasted image 20250801164816.png",
|
||||||
"Agencia_Espacial_Mexicana/Cursos_Capacitación/Introducción a la Administración Pública Federal/adjuntos/Pasted image 20250801164759.png",
|
"Agencia_Espacial_Mexicana/Cursos_Capacitación/Introducción a la Administración Pública Federal/adjuntos/Pasted image 20250801164759.png",
|
||||||
"Agencia_Espacial_Mexicana/Cursos_Capacitación/Introducción a la Administración Pública Federal/adjuntos/Pasted image 20250801164742.png",
|
"Agencia_Espacial_Mexicana/Cursos_Capacitación/Introducción a la Administración Pública Federal/adjuntos/Pasted image 20250801164742.png",
|
||||||
|
@ -1,84 +1,84 @@
|
|||||||
Código de VBA para convertir una tabla de excel a un formato markdown
|
Código de VBA para convertir una tabla de excel a un formato markdown
|
||||||
|
|
||||||
```vba
|
```vba
|
||||||
' activar la referencia de Microsoft Forms 2.0 Object Library (solo la primera vez)
|
' activar la referencia de Microsoft Forms 2.0 Object Library (solo la primera vez)
|
||||||
|
|
||||||
Option Explicit
|
Option Explicit
|
||||||
|
|
||||||
Sub rangeToMarkDown()
|
Sub rangeToMarkDown()
|
||||||
|
|
||||||
Dim cell As Range
|
Dim cell As Range
|
||||||
Dim selectedRange As Range
|
Dim selectedRange As Range
|
||||||
Set selectedRange = Application.Selection
|
Set selectedRange = Application.Selection
|
||||||
|
|
||||||
If selectedRange Is Nothing Then
|
If selectedRange Is Nothing Then
|
||||||
MsgBox "Selecciona un rango antes de ejecutar la macro.", vbExclamation
|
MsgBox "Selecciona un rango antes de ejecutar la macro.", vbExclamation
|
||||||
Exit Sub
|
Exit Sub
|
||||||
End If
|
End If
|
||||||
|
|
||||||
Dim rowCounter As Integer
|
Dim rowCounter As Integer
|
||||||
Dim columnCounter As Integer
|
Dim columnCounter As Integer
|
||||||
Dim totalColumns As Integer
|
Dim totalColumns As Integer
|
||||||
Dim currentColumnWidth As Integer
|
Dim currentColumnWidth As Integer
|
||||||
|
|
||||||
totalColumns = selectedRange.Columns.Count
|
totalColumns = selectedRange.Columns.Count
|
||||||
|
|
||||||
Dim columnWidth(1 To 50) As Integer ' Máximo 50 columnas
|
Dim columnWidth(1 To 50) As Integer ' Máximo 50 columnas
|
||||||
Dim markdown As String
|
Dim markdown As String
|
||||||
Dim i As Integer, j As Integer, k As Integer
|
Dim i As Integer, j As Integer, k As Integer
|
||||||
Dim extraSpaces As Integer
|
Dim extraSpaces As Integer
|
||||||
Dim currentLine As String
|
Dim currentLine As String
|
||||||
|
|
||||||
' Inicializa anchos de columna
|
' Inicializa anchos de columna
|
||||||
For i = 1 To totalColumns
|
For i = 1 To totalColumns
|
||||||
columnWidth(i) = 0
|
columnWidth(i) = 0
|
||||||
Next i
|
Next i
|
||||||
|
|
||||||
' Calcular el ancho máximo de cada columna
|
' Calcular el ancho máximo de cada columna
|
||||||
For Each Row In selectedRange.Rows
|
For Each Row In selectedRange.Rows
|
||||||
columnCounter = 1
|
columnCounter = 1
|
||||||
For Each cell In Row.Cells
|
For Each cell In Row.Cells
|
||||||
currentColumnWidth = Len(CStr(cell.Text))
|
currentColumnWidth = Len(CStr(cell.Text))
|
||||||
If currentColumnWidth > columnWidth(columnCounter) Then
|
If currentColumnWidth > columnWidth(columnCounter) Then
|
||||||
columnWidth(columnCounter) = currentColumnWidth
|
columnWidth(columnCounter) = currentColumnWidth
|
||||||
End If
|
End If
|
||||||
columnCounter = columnCounter + 1
|
columnCounter = columnCounter + 1
|
||||||
Next cell
|
Next cell
|
||||||
Next Row
|
Next Row
|
||||||
|
|
||||||
' Construir tabla Markdown
|
' Construir tabla Markdown
|
||||||
rowCounter = 0
|
rowCounter = 0
|
||||||
For Each Row In selectedRange.Rows
|
For Each Row In selectedRange.Rows
|
||||||
columnCounter = 1
|
columnCounter = 1
|
||||||
currentLine = "|"
|
currentLine = "|"
|
||||||
For Each cell In Row.Cells
|
For Each cell In Row.Cells
|
||||||
currentColumnWidth = columnWidth(columnCounter)
|
currentColumnWidth = columnWidth(columnCounter)
|
||||||
currentLine = currentLine & " " & cell.Text & _
|
currentLine = currentLine & " " & cell.Text & _
|
||||||
Space(currentColumnWidth - Len(CStr(cell.Text))) & " |"
|
Space(currentColumnWidth - Len(CStr(cell.Text))) & " |"
|
||||||
columnCounter = columnCounter + 1
|
columnCounter = columnCounter + 1
|
||||||
Next cell
|
Next cell
|
||||||
markdown = markdown & currentLine & vbCrLf
|
markdown = markdown & currentLine & vbCrLf
|
||||||
|
|
||||||
' Agrega línea separadora después del encabezado
|
' Agrega línea separadora después del encabezado
|
||||||
If rowCounter = 0 Then
|
If rowCounter = 0 Then
|
||||||
currentLine = "|"
|
currentLine = "|"
|
||||||
For j = 1 To totalColumns
|
For j = 1 To totalColumns
|
||||||
currentLine = currentLine & " " & String(columnWidth(j), "-") & " |"
|
currentLine = currentLine & " " & String(columnWidth(j), "-") & " |"
|
||||||
Next j
|
Next j
|
||||||
markdown = markdown & currentLine & vbCrLf
|
markdown = markdown & currentLine & vbCrLf
|
||||||
End If
|
End If
|
||||||
|
|
||||||
rowCounter = rowCounter + 1
|
rowCounter = rowCounter + 1
|
||||||
Next Row
|
Next Row
|
||||||
|
|
||||||
' Copiar al portapapeles
|
' Copiar al portapapeles
|
||||||
Dim clipboard As New DataObject
|
Dim clipboard As New DataObject
|
||||||
clipboard.SetText markdown
|
clipboard.SetText markdown
|
||||||
clipboard.PutInClipboard
|
clipboard.PutInClipboard
|
||||||
|
|
||||||
MsgBox "? Tabla Markdown copiada al portapapeles.", vbInformation
|
MsgBox "? Tabla Markdown copiada al portapapeles.", vbInformation
|
||||||
|
|
||||||
End Sub
|
End Sub
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -1,36 +1,36 @@
|
|||||||
|
|
||||||
## 1.- Información del Proyecto
|
## 1.- Información del Proyecto
|
||||||
|
|
||||||
### 1.1.- Datos Generales
|
### 1.1.- Datos Generales
|
||||||
|
|
||||||
**Nombre del proyecto:** Sistema Satelital de Telecomunicaciones.
|
**Nombre del proyecto:** Sistema Satelital de Telecomunicaciones.
|
||||||
**Descripción del Proyecto:** Renovar y fortalecer las capacidades satelitales nacionales mediante una coordinación integral de actividades relacionadas a las telecomunicaciones espaciales que permita desplegar un nuevo satélite de telecomunicaciones, ampliar su uso, así como garantizar su sostenibilidad operativa.
|
**Descripción del Proyecto:** Renovar y fortalecer las capacidades satelitales nacionales mediante una coordinación integral de actividades relacionadas a las telecomunicaciones espaciales que permita desplegar un nuevo satélite de telecomunicaciones, ampliar su uso, así como garantizar su sostenibilidad operativa.
|
||||||
**Presupuesto:** $13,785,000,000.00 (Trece mil setecientos ochenta y cinco millones de pesos 00/100 MXN)
|
**Presupuesto:** $13,785,000,000.00 (Trece mil setecientos ochenta y cinco millones de pesos 00/100 MXN)
|
||||||
**Tiempo de vida del Proyecto (años):** 15 una vez que el satélite esté en órbita.
|
**Tiempo de vida del Proyecto (años):** 15 una vez que el satélite esté en órbita.
|
||||||
**Tiempo inicial preparativos previo al lanzamiento (años):** 5 (2026 - 2030)
|
**Tiempo inicial preparativos previo al lanzamiento (años):** 5 (2026 - 2030)
|
||||||
**Monto a ejercer de forma anual:** $2,757,000,000.00 (Dos mil setecientos cincuenta y siete millones de pesos 00/100 MXN)
|
**Monto a ejercer de forma anual:** $2,757,000,000.00 (Dos mil setecientos cincuenta y siete millones de pesos 00/100 MXN)
|
||||||
|
|
||||||
### 1.2.- Costos de Inversión Inicial
|
### 1.2.- Costos de Inversión Inicial
|
||||||
|
|
||||||
Para la estimación de los costos de inversión se toma como referencia los datos de los documentos: "Libro Blanco Mexsat.pdf" y "2013_0432_a.pdf" los cual está en la carpeta de "Anexos Proyecto 1", para la estimación presupuestal se consideran los siguientes conceptos mencionados en los documentos de referencia los cuales son costos al 2015:
|
Para la estimación de los costos de inversión se toma como referencia los datos de los documentos: "Libro Blanco Mexsat.pdf" y "2013_0432_a.pdf" los cual está en la carpeta de "Anexos Proyecto 1", para la estimación presupuestal se consideran los siguientes conceptos mencionados en los documentos de referencia los cuales son costos al 2015:
|
||||||
|
|
||||||
Tabla 1.2.1
|
Tabla 1.2.1
|
||||||
|
|
||||||
| Concepto de Gasto | Costo USD | Costo MXN |
|
| Concepto de Gasto | Costo USD | Costo MXN |
|
||||||
| ------------------------------------------ | ------------ | ------------ |
|
| ------------------------------------------ | ------------ | ------------ |
|
||||||
| Fabricación del satélite | $292,200,000 | $0 |
|
| Fabricación del satélite | $292,200,000 | $0 |
|
||||||
| Seguro en órbita (2016–2017) | $272,914,800 | $0 |
|
| Seguro en órbita (2016–2017) | $272,914,800 | $0 |
|
||||||
| Lanzamiento del satélite (Atlas V - LMCLS) | $148,250,000 | $0 |
|
| Lanzamiento del satélite (Atlas V - LMCLS) | $148,250,000 | $0 |
|
||||||
| Seguro lanzamiento + primer año | $24,605,403 | $0 |
|
| Seguro lanzamiento + primer año | $24,605,403 | $0 |
|
||||||
| Terminales satelitales | $4,500,000 | $0 |
|
| Terminales satelitales | $4,500,000 | $0 |
|
||||||
| Mantenimiento y operación | $0 | $105,494,451 |
|
| Mantenimiento y operación | $0 | $105,494,451 |
|
||||||
| Consultoría técnica terminales móviles | $2,203,200 | $0 |
|
| Consultoría técnica terminales móviles | $2,203,200 | $0 |
|
||||||
| Desarrollo terminales aeronáuticas | $0 | $20,000,000 |
|
| Desarrollo terminales aeronáuticas | $0 | $20,000,000 |
|
||||||
| Almacenamiento | $5,400,000 | $0 |
|
| Almacenamiento | $5,400,000 | $0 |
|
||||||
| Total | $750,073,403 | $125,494,451 |
|
| Total | $750,073,403 | $125,494,451 |
|
||||||
|
|
||||||
Para actualizar los valores que se pagaron en USD, se le suma la tasa de inflación de 2015 al 2025 la cual puede ser consultada en
|
Para actualizar los valores que se pagaron en USD, se le suma la tasa de inflación de 2015 al 2025 la cual puede ser consultada en
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,208 +1,208 @@
|
|||||||
Para crear un script que rastree nuestra ip pública con ayuda de cloudflare vamos a necesitar los siguientes datos:
|
Para crear un script que rastree nuestra ip pública con ayuda de cloudflare vamos a necesitar los siguientes datos:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
ZONE_ID=""
|
ZONE_ID=""
|
||||||
RECORD_ID=""
|
RECORD_ID=""
|
||||||
API_TOKEN=""
|
API_TOKEN=""
|
||||||
EMAIL=""
|
EMAIL=""
|
||||||
DOMAIN=""
|
DOMAIN=""
|
||||||
```
|
```
|
||||||
|
|
||||||
Para obtener el `ZONE_ID`, te recomiendo crear un registro de un subdominio en tu perfil de cloudflare, ejemplo registro:
|
Para obtener el `ZONE_ID`, te recomiendo crear un registro de un subdominio en tu perfil de cloudflare, ejemplo registro:
|
||||||
|
|
||||||
Tipo: A
|
Tipo: A
|
||||||
Nombre: mi-ip
|
Nombre: mi-ip
|
||||||
Contenido: 187.123.32.45
|
Contenido: 187.123.32.45
|
||||||
> En **contenido** va la ip pública.
|
> En **contenido** va la ip pública.
|
||||||
|
|
||||||
|
|
||||||
Una vez creado tu subdomino, debemos crear API Token, vamos a **Perfil > Tokens de API > Crear Token > Editar zona DNS > (sección Recursos de Zona) opción 1: Incluir, Opción 2: Zona específica, Opción 3: selecciona tu dominio > Ir a resumen**, eso te dará tu ==`API_TOKEN` ==,
|
Una vez creado tu subdomino, debemos crear API Token, vamos a **Perfil > Tokens de API > Crear Token > Editar zona DNS > (sección Recursos de Zona) opción 1: Incluir, Opción 2: Zona específica, Opción 3: selecciona tu dominio > Ir a resumen**, eso te dará tu ==`API_TOKEN` ==,
|
||||||
|
|
||||||
Una Vez tengas el `API Token` vamos a obtener el `ZONE_ID`, en tu consola ejecuta el comando:
|
Una Vez tengas el `API Token` vamos a obtener el `ZONE_ID`, en tu consola ejecuta el comando:
|
||||||
```bash
|
```bash
|
||||||
curl -X GET "https://api.cloudflare.com/client/v4/zones?name=TU-DOMINIO-NO-SUBDOMINIO.com" \
|
curl -X GET "https://api.cloudflare.com/client/v4/zones?name=TU-DOMINIO-NO-SUBDOMINIO.com" \
|
||||||
-H "Authorization: Bearer TU-API-TOKEN" \
|
-H "Authorization: Bearer TU-API-TOKEN" \
|
||||||
-H "Content-Type: application/json"
|
-H "Content-Type: application/json"
|
||||||
```
|
```
|
||||||
|
|
||||||
Ejecuta ese comando en tu consola linux, la salida será algo como:
|
Ejecuta ese comando en tu consola linux, la salida será algo como:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
{"result":[
|
{"result":[
|
||||||
{"id":"TU-ZONE-ID","name":"TU-DOMINIO-NO-SUBDOMINIO.com","status":"active","paused":false, ... (más cosas)
|
{"id":"TU-ZONE-ID","name":"TU-DOMINIO-NO-SUBDOMINIO.com","status":"active","paused":false, ... (más cosas)
|
||||||
```
|
```
|
||||||
|
|
||||||
Del primer bloque verás un diccionario con una clave `id`, el valor es tu ==`ZONE_ID`==, para obtener el `RECORD_ID` es un poco similar al paso anterior, el comando a ejecutar es:
|
Del primer bloque verás un diccionario con una clave `id`, el valor es tu ==`ZONE_ID`==, para obtener el `RECORD_ID` es un poco similar al paso anterior, el comando a ejecutar es:
|
||||||
```bash
|
```bash
|
||||||
curl -s -X GET "https://api.cloudflare.com/client/v4/zones/TU-ZONE-ID/dns_records?type=A&name=TU-SUBDOMINIO.COM" \
|
curl -s -X GET "https://api.cloudflare.com/client/v4/zones/TU-ZONE-ID/dns_records?type=A&name=TU-SUBDOMINIO.COM" \
|
||||||
-H "Authorization: Bearer TU-API-TOKEN" \
|
-H "Authorization: Bearer TU-API-TOKEN" \
|
||||||
-H "Content-Type: application/json"
|
-H "Content-Type: application/json"
|
||||||
```
|
```
|
||||||
|
|
||||||
Obtendrás una respuesta como esta:
|
Obtendrás una respuesta como esta:
|
||||||
```bash
|
```bash
|
||||||
{"result":[{"id":"TU-RECORD-ID","name":"TU-SUBDOMINIO.COM","type":"A", ... (más cosas)
|
{"result":[{"id":"TU-RECORD-ID","name":"TU-SUBDOMINIO.COM","type":"A", ... (más cosas)
|
||||||
```
|
```
|
||||||
Del primer bloque verás un diccionario, con una clave `id`, el valor es tu ==`RECORD_ID`==, en el valor de ==`EMAIL`==, coloca el email con el que inicias sesión en tu cuenta de cloudflare, y en ==`DOMAIN`== coloca el nombre de tu subdominio, una vez que ya tenemos esos datos podemos continuar con el script completo:
|
Del primer bloque verás un diccionario, con una clave `id`, el valor es tu ==`RECORD_ID`==, en el valor de ==`EMAIL`==, coloca el email con el que inicias sesión en tu cuenta de cloudflare, y en ==`DOMAIN`== coloca el nombre de tu subdominio, una vez que ya tenemos esos datos podemos continuar con el script completo:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# Configuración
|
# Configuración
|
||||||
ZONE_ID="abcdef1234567890abcdef1234567890"
|
ZONE_ID="abcdef1234567890abcdef1234567890"
|
||||||
RECORD_ID="c3f9a7e6b24d48b2a6f481c2a9d2f9c1"
|
RECORD_ID="c3f9a7e6b24d48b2a6f481c2a9d2f9c1"
|
||||||
API_TOKEN="e4b-2f6c9a81d4b87f0a927ec5b3c6a59f0e7a45b"
|
API_TOKEN="e4b-2f6c9a81d4b87f0a927ec5b3c6a59f0e7a45b"
|
||||||
EMAIL="tu.email@mail.com"
|
EMAIL="tu.email@mail.com"
|
||||||
DOMAIN="subdominio.dominio.com"
|
DOMAIN="subdominio.dominio.com"
|
||||||
|
|
||||||
# Obtener IP actual
|
# Obtener IP actual
|
||||||
IP=$(curl -s https://api.ipify.org)
|
IP=$(curl -s https://api.ipify.org)
|
||||||
|
|
||||||
# Obtener IP actual del DNS
|
# Obtener IP actual del DNS
|
||||||
DNS_IP=$(dig +short $DOMAIN @1.1.1.1)
|
DNS_IP=$(dig +short $DOMAIN @1.1.1.1)
|
||||||
|
|
||||||
# Comparar
|
# Comparar
|
||||||
if [ "$IP" != "$DNS_IP" ]; then
|
if [ "$IP" != "$DNS_IP" ]; then
|
||||||
echo "La IP cambió: $DNS_IP → $IP. Actualizando en Cloudflare..."
|
echo "La IP cambió: $DNS_IP → $IP. Actualizando en Cloudflare..."
|
||||||
curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$RECORD_ID" \
|
curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$RECORD_ID" \
|
||||||
-H "Authorization: Bearer $API_TOKEN" \
|
-H "Authorization: Bearer $API_TOKEN" \
|
||||||
-H "Content-Type: application/json" \
|
-H "Content-Type: application/json" \
|
||||||
--data "{\"type\":\"A\",\"name\":\"$DOMAIN\",\"content\":\"$IP\",\"ttl\":120,\"proxied\":true}" | jq
|
--data "{\"type\":\"A\",\"name\":\"$DOMAIN\",\"content\":\"$IP\",\"ttl\":120,\"proxied\":true}" | jq
|
||||||
else
|
else
|
||||||
echo "La IP no ha cambiado: $IP"
|
echo "La IP no ha cambiado: $IP"
|
||||||
fi
|
fi
|
||||||
```
|
```
|
||||||
|
|
||||||
==Versión Mejorada==
|
==Versión Mejorada==
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# Configuración
|
# Configuración
|
||||||
ZONE_ID="e70540b388ab9d20bfe27d9a31cd474b"
|
ZONE_ID="e70540b388ab9d20bfe27d9a31cd474b"
|
||||||
RECORD_ID="5d05a48c9d76c7767302442fffa096bd"
|
RECORD_ID="5d05a48c9d76c7767302442fffa096bd"
|
||||||
API_TOKEN="9BD-GB7PtGd5pgXTEBxnv3k1eJlJYJoIWx9HgLLs"
|
API_TOKEN="9BD-GB7PtGd5pgXTEBxnv3k1eJlJYJoIWx9HgLLs"
|
||||||
DOMAIN="ip.xala.dev"
|
DOMAIN="ip.xala.dev"
|
||||||
|
|
||||||
# Obtener IP pública actual
|
# Obtener IP pública actual
|
||||||
IP=$(curl -s https://api.ipify.org)
|
IP=$(curl -s https://api.ipify.org)
|
||||||
|
|
||||||
# Obtener IP configurada en Cloudflare (usando la API)
|
# Obtener IP configurada en Cloudflare (usando la API)
|
||||||
DNS_IP=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$RECORD_ID" \
|
DNS_IP=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$RECORD_ID" \
|
||||||
-H "Authorization: Bearer $API_TOKEN" \
|
-H "Authorization: Bearer $API_TOKEN" \
|
||||||
-H "Content-Type: application/json" | jq -r '.result.content')
|
-H "Content-Type: application/json" | jq -r '.result.content')
|
||||||
|
|
||||||
# Comparar
|
# Comparar
|
||||||
if [ "$IP" != "$DNS_IP" ]; then
|
if [ "$IP" != "$DNS_IP" ]; then
|
||||||
echo "La IP cambió: $DNS_IP → $IP. Actualizando en Cloudflare..."
|
echo "La IP cambió: $DNS_IP → $IP. Actualizando en Cloudflare..."
|
||||||
curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$RECORD_ID" \
|
curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$RECORD_ID" \
|
||||||
-H "Authorization: Bearer $API_TOKEN" \
|
-H "Authorization: Bearer $API_TOKEN" \
|
||||||
-H "Content-Type: application/json" \
|
-H "Content-Type: application/json" \
|
||||||
--data "{\"type\":\"A\",\"name\":\"$DOMAIN\",\"content\":\"$IP\",\"ttl\":120,\"proxied\":true}" | jq
|
--data "{\"type\":\"A\",\"name\":\"$DOMAIN\",\"content\":\"$IP\",\"ttl\":120,\"proxied\":true}" | jq
|
||||||
else
|
else
|
||||||
echo "La IP no ha cambiado: $IP"
|
echo "La IP no ha cambiado: $IP"
|
||||||
fi
|
fi
|
||||||
```
|
```
|
||||||
|
|
||||||
==LA MEJOR VERSIÓN==
|
==LA MEJOR VERSIÓN==
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# echo "[$(date '+%Y-%m-%d %H:%M:%S')] Ejecutando actualización de IP..."
|
# echo "[$(date '+%Y-%m-%d %H:%M:%S')] Ejecutando actualización de IP..."
|
||||||
|
|
||||||
# Configuración
|
# Configuración
|
||||||
ZONE_ID="e70540b388ab9d20bfe27d9a31cd474b"
|
ZONE_ID="e70540b388ab9d20bfe27d9a31cd474b"
|
||||||
RECORD_ID="5d05a48c9d76c7767302442fffa096bd"
|
RECORD_ID="5d05a48c9d76c7767302442fffa096bd"
|
||||||
API_TOKEN="9BD-GB7PtGd5pgXTEBxnv3k1eJlJYJoIWx9HgLLs"
|
API_TOKEN="9BD-GB7PtGd5pgXTEBxnv3k1eJlJYJoIWx9HgLLs"
|
||||||
DOMAIN="ip.xala.dev"
|
DOMAIN="ip.xala.dev"
|
||||||
|
|
||||||
|
|
||||||
# Obtener IP pública actual
|
# Obtener IP pública actual
|
||||||
IP=$(curl -s https://api.ipify.org)
|
IP=$(curl -s https://api.ipify.org)
|
||||||
|
|
||||||
# Obtener IP registrada en Cloudflare
|
# Obtener IP registrada en Cloudflare
|
||||||
DNS_IP=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$RECORD_ID" \
|
DNS_IP=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$RECORD_ID" \
|
||||||
-H "Authorization: Bearer $API_TOKEN" \
|
-H "Authorization: Bearer $API_TOKEN" \
|
||||||
-H "Content-Type: application/json" | jq -r '.result.content')
|
-H "Content-Type: application/json" | jq -r '.result.content')
|
||||||
|
|
||||||
# Comparar
|
# Comparar
|
||||||
if [ "$IP" != "$DNS_IP" ]; then
|
if [ "$IP" != "$DNS_IP" ]; then
|
||||||
echo "La IP cambió: $DNS_IP → $IP. Actualizando en Cloudflare..."
|
echo "La IP cambió: $DNS_IP → $IP. Actualizando en Cloudflare..."
|
||||||
curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$RECORD_ID" \
|
curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$RECORD_ID" \
|
||||||
-H "Authorization: Bearer $API_TOKEN" \
|
-H "Authorization: Bearer $API_TOKEN" \
|
||||||
-H "Content-Type: application/json" \
|
-H "Content-Type: application/json" \
|
||||||
--data "{\"type\":\"A\",\"name\":\"$DOMAIN\",\"content\":\"$IP\",\"ttl\":120,\"proxied\":true}" | jq
|
--data "{\"type\":\"A\",\"name\":\"$DOMAIN\",\"content\":\"$IP\",\"ttl\":120,\"proxied\":true}" | jq
|
||||||
else
|
else
|
||||||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] La IP no ha cambiado: $IP"
|
echo "[$(date '+%Y-%m-%d %H:%M:%S')] La IP no ha cambiado: $IP"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# echo "[$(date '+%Y-%m-%d %H:%M:%S')] Fin de ejecución."
|
# echo "[$(date '+%Y-%m-%d %H:%M:%S')] Fin de ejecución."
|
||||||
```
|
```
|
||||||
|
|
||||||
**integra ntfy, que llegue un mensaje cuando cambie la ip**
|
**integra ntfy, que llegue un mensaje cuando cambie la ip**
|
||||||
|
|
||||||
|
|
||||||
==MEJORADO, CON PROXIED FALSE==
|
==MEJORADO, CON PROXIED FALSE==
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# Configuración
|
# Configuración
|
||||||
ZONE_ID="e70540b388ab9d20bfe27d9a31cd474b"
|
ZONE_ID="e70540b388ab9d20bfe27d9a31cd474b"
|
||||||
RECORD_ID="5d05a48c9d76c7767302442fffa096bd"
|
RECORD_ID="5d05a48c9d76c7767302442fffa096bd"
|
||||||
API_TOKEN="9BD-GB7PtGd5pgXTEBxnv3k1eJlJYJoIWx9HgLLs"
|
API_TOKEN="9BD-GB7PtGd5pgXTEBxnv3k1eJlJYJoIWx9HgLLs"
|
||||||
DOMAIN="ip.xala.dev"
|
DOMAIN="ip.xala.dev"
|
||||||
|
|
||||||
|
|
||||||
# Obtener IP pública actual
|
# Obtener IP pública actual
|
||||||
IP=$(curl -s https://api.ipify.org)
|
IP=$(curl -s https://api.ipify.org)
|
||||||
|
|
||||||
# Obtener IP registrada actualmente en Cloudflare
|
# Obtener IP registrada actualmente en Cloudflare
|
||||||
DNS_RECORD=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$RECORD_ID" \
|
DNS_RECORD=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$RECORD_ID" \
|
||||||
-H "Authorization: Bearer $API_TOKEN" \
|
-H "Authorization: Bearer $API_TOKEN" \
|
||||||
-H "Content-Type: application/json")
|
-H "Content-Type: application/json")
|
||||||
|
|
||||||
DNS_IP=$(echo "$DNS_RECORD" | jq -r '.result.content')
|
DNS_IP=$(echo "$DNS_RECORD" | jq -r '.result.content')
|
||||||
|
|
||||||
# validaciones
|
# validaciones
|
||||||
if [ -z "$IP" ]; then
|
if [ -z "$IP" ]; then
|
||||||
# Notificación vía ntfy
|
# Notificación vía ntfy
|
||||||
# curl -d "🌎 [$(date '+%Y-%m-%d %H:%M:%S')] IP actualizada: $DNS_IP → $IP" ntfy.xala.dev/alerts
|
# curl -d "🌎 [$(date '+%Y-%m-%d %H:%M:%S')] IP actualizada: $DNS_IP → $IP" ntfy.xala.dev/alerts
|
||||||
curl -d "🚨 [$(date '+%Y-%m-%d %H:%M:%S')] No se pudo obtener la IP pública." ntfy.xala.dev/alerts
|
curl -d "🚨 [$(date '+%Y-%m-%d %H:%M:%S')] No se pudo obtener la IP pública." ntfy.xala.dev/alerts
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$IP" != "$DNS_IP" ]; then
|
if [ "$IP" != "$DNS_IP" ]; then
|
||||||
curl -d "🌐 La IP ha cambiado: $DNS_IP → $IP. Actualizando en Cloudflare..." ntfy.xala.dev/alerts
|
curl -d "🌐 La IP ha cambiado: $DNS_IP → $IP. Actualizando en Cloudflare..." ntfy.xala.dev/alerts
|
||||||
|
|
||||||
UPDATE_RESPONSE=$(curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$RECORD_ID" \
|
UPDATE_RESPONSE=$(curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$RECORD_ID" \
|
||||||
-H "Authorization: Bearer $API_TOKEN" \
|
-H "Authorization: Bearer $API_TOKEN" \
|
||||||
-H "Content-Type: application/json" \
|
-H "Content-Type: application/json" \
|
||||||
--data "{
|
--data "{
|
||||||
\"type\": \"A\",
|
\"type\": \"A\",
|
||||||
\"name\": \"$DOMAIN\",
|
\"name\": \"$DOMAIN\",
|
||||||
\"content\": \"$IP\",
|
\"content\": \"$IP\",
|
||||||
\"ttl\": 1,
|
\"ttl\": 1,
|
||||||
\"proxied\": false
|
\"proxied\": false
|
||||||
}")
|
}")
|
||||||
|
|
||||||
SUCCESS=$(echo "$UPDATE_RESPONSE" | jq -r '.success')
|
SUCCESS=$(echo "$UPDATE_RESPONSE" | jq -r '.success')
|
||||||
|
|
||||||
if [ "$SUCCESS" == "true" ]; then
|
if [ "$SUCCESS" == "true" ]; then
|
||||||
curl -d "🌎 [$(date '+%Y-%m-%d %H:%M:%S')] IP actualizada: $DNS_IP → $IP" ntfy.xala.dev/alerts
|
curl -d "🌎 [$(date '+%Y-%m-%d %H:%M:%S')] IP actualizada: $DNS_IP → $IP" ntfy.xala.dev/alerts
|
||||||
else
|
else
|
||||||
curl -d "🚨 [$(date '+%Y-%m-%d %H:%M:%S')] Falló la actualización en Cloudflare." ntfy.xala.dev/alerts
|
curl -d "🚨 [$(date '+%Y-%m-%d %H:%M:%S')] Falló la actualización en Cloudflare." ntfy.xala.dev/alerts
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
echo "ℹ️ [$(date '+%Y-%m-%d %H:%M:%S')] La IP no ha cambiado: $IP"
|
echo "ℹ️ [$(date '+%Y-%m-%d %H:%M:%S')] La IP no ha cambiado: $IP"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,129 +1,129 @@
|
|||||||
```bash
|
```bash
|
||||||
# instalar tesseract-ocr
|
# instalar tesseract-ocr
|
||||||
sudo apt update && sudo apt upgrade -y
|
sudo apt update && sudo apt upgrade -y
|
||||||
sudo apt install tesseract-ocr tesseract-ocr-spa poppler-utils
|
sudo apt install tesseract-ocr tesseract-ocr-spa poppler-utils
|
||||||
sudo apt install tesseract-ocr-all poppler-utils
|
sudo apt install tesseract-ocr-all poppler-utils
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|
||||||
|
|
||||||
function getTxtFromPdf() {
|
function getTxtFromPdf() {
|
||||||
local pdf_path="$1"
|
local pdf_path="$1"
|
||||||
local base_name=$(basename "$pdf_path" .pdf)
|
local base_name=$(basename "$pdf_path" .pdf)
|
||||||
local tmp_prefix="pagina"
|
local tmp_prefix="pagina"
|
||||||
|
|
||||||
# Limpiar residuos anteriores
|
# Limpiar residuos anteriores
|
||||||
rm -f ${tmp_prefix}-*.png ${tmp_prefix}-*.txt salida_${base_name}.txt
|
rm -f ${tmp_prefix}-*.png ${tmp_prefix}-*.txt salida_${base_name}.txt
|
||||||
|
|
||||||
# Convertir PDF a PNG por página
|
# Convertir PDF a PNG por página
|
||||||
pdftoppm "$pdf_path" "$tmp_prefix" -png
|
pdftoppm "$pdf_path" "$tmp_prefix" -png
|
||||||
|
|
||||||
# OCR cada imagen y concatenar en un solo archivo de salida
|
# OCR cada imagen y concatenar en un solo archivo de salida
|
||||||
for img in ${tmp_prefix}-*.png; do
|
for img in ${tmp_prefix}-*.png; do
|
||||||
echo "Procesando $img..."
|
echo "Procesando $img..."
|
||||||
tesseract "$img" temp -l spa
|
tesseract "$img" temp -l spa
|
||||||
cat temp.txt >> salida_${base_name}.txt
|
cat temp.txt >> salida_${base_name}.txt
|
||||||
echo -e "\n\n---- FIN DE PÁGINA ----\n\n" >> salida_${base_name}.txt
|
echo -e "\n\n---- FIN DE PÁGINA ----\n\n" >> salida_${base_name}.txt
|
||||||
done
|
done
|
||||||
|
|
||||||
rm -f temp.txt
|
rm -f temp.txt
|
||||||
echo "OCR completado. Archivo final: salida_${base_name}.txt"
|
echo "OCR completado. Archivo final: salida_${base_name}.txt"
|
||||||
}
|
}
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
getHighQualityTxtFromPdf() {
|
getHighQualityTxtFromPdf() {
|
||||||
# Verificar que se proporcionó al menos un argumento
|
# Verificar que se proporcionó al menos un argumento
|
||||||
if [[ $# -lt 1 ]]; then
|
if [[ $# -lt 1 ]]; then
|
||||||
echo "Error: Debes especificar la ruta del archivo PDF." >&2
|
echo "Error: Debes especificar la ruta del archivo PDF." >&2
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
local pdf_path="$1"
|
local pdf_path="$1"
|
||||||
local base_name
|
local base_name
|
||||||
base_name=$(basename "$pdf_path" .pdf)
|
base_name=$(basename "$pdf_path" .pdf)
|
||||||
local output_file="${2:-salida_hq_${base_name}.txt}" # Permitir archivo de salida opcional
|
local output_file="${2:-salida_hq_${base_name}.txt}" # Permitir archivo de salida opcional
|
||||||
local tmp_prefix="hq_pagina"
|
local tmp_prefix="hq_pagina"
|
||||||
local lang="spa"
|
local lang="spa"
|
||||||
local dpi=1000
|
local dpi=1000
|
||||||
local oem=1
|
local oem=1
|
||||||
local psm=6
|
local psm=6
|
||||||
|
|
||||||
# Verificar existencia del archivo
|
# Verificar existencia del archivo
|
||||||
if [[ ! -f "$pdf_path" ]]; then
|
if [[ ! -f "$pdf_path" ]]; then
|
||||||
echo "Error: El archivo '$pdf_path' no existe." >&2
|
echo "Error: El archivo '$pdf_path' no existe." >&2
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Verificar dependencias
|
# Verificar dependencias
|
||||||
if ! command -v pdftoppm &> /dev/null || ! command -v tesseract &> /dev/null; then
|
if ! command -v pdftoppm &> /dev/null || ! command -v tesseract &> /dev/null; then
|
||||||
echo "Error: Se requieren 'pdftoppm' y 'tesseract'." >&2
|
echo "Error: Se requieren 'pdftoppm' y 'tesseract'." >&2
|
||||||
echo "Instala con: sudo apt install poppler-utils tesseract-ocr tesseract-ocr-spa" >&2
|
echo "Instala con: sudo apt install poppler-utils tesseract-ocr tesseract-ocr-spa" >&2
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Limpiar residuos anteriores
|
# Limpiar residuos anteriores
|
||||||
rm -f "${tmp_prefix}-"*.png "$output_file" 2>/dev/null
|
rm -f "${tmp_prefix}-"*.png "$output_file" 2>/dev/null
|
||||||
|
|
||||||
echo "Convirtiendo PDF a imágenes de alta calidad (${dpi} DPI)..."
|
echo "Convirtiendo PDF a imágenes de alta calidad (${dpi} DPI)..."
|
||||||
if ! pdftoppm -png -r "$dpi" -aa yes -aaVector yes "$pdf_path" "$tmp_prefix"; then
|
if ! pdftoppm -png -r "$dpi" -aa yes -aaVector yes "$pdf_path" "$tmp_prefix"; then
|
||||||
echo "Error al convertir PDF a imágenes." >&2
|
echo "Error al convertir PDF a imágenes." >&2
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Contar número total de páginas generadas
|
# Contar número total de páginas generadas
|
||||||
local page_imgs=("${tmp_prefix}-"*.png)
|
local page_imgs=("${tmp_prefix}-"*.png)
|
||||||
local total_pages=${#page_imgs[@]}
|
local total_pages=${#page_imgs[@]}
|
||||||
if [[ $total_pages -eq 0 ]]; then
|
if [[ $total_pages -eq 0 ]]; then
|
||||||
echo "Error: No se generaron imágenes del PDF." >&2
|
echo "Error: No se generaron imágenes del PDF." >&2
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "" > "$output_file"
|
echo "" > "$output_file"
|
||||||
|
|
||||||
local page_count=0
|
local page_count=0
|
||||||
for img in "${page_imgs[@]}"; do
|
for img in "${page_imgs[@]}"; do
|
||||||
((page_count++))
|
((page_count++))
|
||||||
echo "Procesando página $page_count: $img"
|
echo "Procesando página $page_count: $img"
|
||||||
|
|
||||||
# Crear archivo temporal para esta página
|
# Crear archivo temporal para esta página
|
||||||
local tmp_txt_file
|
local tmp_txt_file
|
||||||
tmp_txt_file=$(mktemp --suffix=.txt)
|
tmp_txt_file=$(mktemp --suffix=.txt)
|
||||||
|
|
||||||
# OCR con configuraciones avanzadas
|
# OCR con configuraciones avanzadas
|
||||||
if ! tesseract "$img" "$tmp_txt_file" -l "$lang" --dpi "$dpi" --oem "$oem" --psm "$psm" \
|
if ! tesseract "$img" "$tmp_txt_file" -l "$lang" --dpi "$dpi" --oem "$oem" --psm "$psm" \
|
||||||
-c tessedit_pageseg_mode=$psm \
|
-c tessedit_pageseg_mode=$psm \
|
||||||
-c preserve_interword_spaces=1 \
|
-c preserve_interword_spaces=1 \
|
||||||
-c textord_debug_tabfind=0 \
|
-c textord_debug_tabfind=0 \
|
||||||
-c textord_min_linesize=2.5 2>/dev/null; then
|
-c textord_min_linesize=2.5 2>/dev/null; then
|
||||||
echo "Advertencia: OCR falló en $img. Reintentando con configuración básica..." >&2
|
echo "Advertencia: OCR falló en $img. Reintentando con configuración básica..." >&2
|
||||||
tesseract "$img" "$tmp_txt_file" -l "$lang" --dpi "$dpi" 2>/dev/null || continue
|
tesseract "$img" "$tmp_txt_file" -l "$lang" --dpi "$dpi" 2>/dev/null || continue
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Agregar texto al archivo final
|
# Agregar texto al archivo final
|
||||||
cat "${tmp_txt_file}.txt" >> "$output_file"
|
cat "${tmp_txt_file}.txt" >> "$output_file"
|
||||||
|
|
||||||
# Separador de página
|
# Separador de página
|
||||||
if [[ $page_count -lt $total_pages ]]; then
|
if [[ $page_count -lt $total_pages ]]; then
|
||||||
echo -e "\n\n---- FIN DE PÁGINA $page_count ----\n\n" >> "$output_file"
|
echo -e "\n\n---- FIN DE PÁGINA $page_count ----\n\n" >> "$output_file"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Limpieza
|
# Limpieza
|
||||||
rm -f "$img" "${tmp_txt_file}.txt"
|
rm -f "$img" "${tmp_txt_file}.txt"
|
||||||
done
|
done
|
||||||
|
|
||||||
echo "Realizando post-procesamiento..."
|
echo "Realizando post-procesamiento..."
|
||||||
sed -i 's/fi/fi/g; s/fl/fl/g; s/ff/ff/g; s/ffi/ffi/g; s/ffl/ffl/g' "$output_file"
|
sed -i 's/fi/fi/g; s/fl/fl/g; s/ff/ff/g; s/ffi/ffi/g; s/ffl/ffl/g' "$output_file"
|
||||||
sed -i '/^[[:space:]]*$/d' "$output_file"
|
sed -i '/^[[:space:]]*$/d' "$output_file"
|
||||||
sed -i 's/[[:space:]]\+/ /g' "$output_file"
|
sed -i 's/[[:space:]]\+/ /g' "$output_file"
|
||||||
|
|
||||||
echo -e "\n=============================="
|
echo -e "\n=============================="
|
||||||
echo " OCR COMPLETADO EXITOSAMENTE "
|
echo " OCR COMPLETADO EXITOSAMENTE "
|
||||||
echo "=============================="
|
echo "=============================="
|
||||||
echo "Archivo final: $output_file"
|
echo "Archivo final: $output_file"
|
||||||
echo "Páginas procesadas: $page_count"
|
echo "Páginas procesadas: $page_count"
|
||||||
echo "Tamaño final: $(du -h "$output_file" | cut -f1)"
|
echo "Tamaño final: $(du -h "$output_file" | cut -f1)"
|
||||||
}
|
}
|
||||||
```
|
```
|
@ -1,6 +1,9 @@
|
|||||||
11/02/2025 10,000
|
11/02/2025 10,000
|
||||||
17/03/2025 7,500
|
17/03/2025 7,500
|
||||||
30/03/2025 1,000
|
30/03/2025 1,000
|
||||||
17/07/2025 16,500
|
17/07/2025 16,500
|
||||||
|
|
||||||
60,000 - 18,500 = 25,000
|
|
||||||
|
60,000 - 18,500 = 25,000
|
||||||
|
|
||||||
|
costco 3,800
|
||||||
|
@ -1,132 +1,132 @@
|
|||||||
¡Claro! Configurar un túnel WireGuard con **obfs4proxy** es una excelente manera de evitar que el tráfico VPN sea detectado, ya que `obfs4proxy` es un protocolo de ofuscación diseñado específicamente para ocultar el tráfico VPN y hacerlo parecer tráfico normal HTTPS.
|
¡Claro! Configurar un túnel WireGuard con **obfs4proxy** es una excelente manera de evitar que el tráfico VPN sea detectado, ya que `obfs4proxy` es un protocolo de ofuscación diseñado específicamente para ocultar el tráfico VPN y hacerlo parecer tráfico normal HTTPS.
|
||||||
|
|
||||||
A continuación, te guiaré a través de los pasos básicos para configurar esto. Aquí tienes un esquema general para hacerlo:
|
A continuación, te guiaré a través de los pasos básicos para configurar esto. Aquí tienes un esquema general para hacerlo:
|
||||||
|
|
||||||
### **1. Instalar WireGuard y obfs4proxy en el servidor**
|
### **1. Instalar WireGuard y obfs4proxy en el servidor**
|
||||||
|
|
||||||
1. **Instalar WireGuard**:
|
1. **Instalar WireGuard**:
|
||||||
Si no tienes WireGuard instalado en tu servidor, primero instálalo:
|
Si no tienes WireGuard instalado en tu servidor, primero instálalo:
|
||||||
|
|
||||||
En **Ubuntu/Debian**:
|
En **Ubuntu/Debian**:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo apt update
|
sudo apt update
|
||||||
sudo apt install wireguard
|
sudo apt install wireguard
|
||||||
```
|
```
|
||||||
|
|
||||||
2. **Instalar obfs4proxy**:
|
2. **Instalar obfs4proxy**:
|
||||||
`obfs4proxy` se utiliza para ofuscar el tráfico VPN. Puedes instalarlo en el servidor y el cliente.
|
`obfs4proxy` se utiliza para ofuscar el tráfico VPN. Puedes instalarlo en el servidor y el cliente.
|
||||||
|
|
||||||
En **Ubuntu/Debian**:
|
En **Ubuntu/Debian**:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo apt install obfs4proxy
|
sudo apt install obfs4proxy
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### **2. Configurar WireGuard en el servidor**
|
### **2. Configurar WireGuard en el servidor**
|
||||||
|
|
||||||
Ya que tienes WireGuard instalado, tendrás que configurar la parte básica de la VPN. Aquí te dejo un ejemplo de configuración de servidor WireGuard (`/etc/wireguard/wg0.conf`):
|
Ya que tienes WireGuard instalado, tendrás que configurar la parte básica de la VPN. Aquí te dejo un ejemplo de configuración de servidor WireGuard (`/etc/wireguard/wg0.conf`):
|
||||||
|
|
||||||
```ini
|
```ini
|
||||||
[Interface]
|
[Interface]
|
||||||
Address = 10.10.10.1/24 # Dirección IP del servidor WireGuard
|
Address = 10.10.10.1/24 # Dirección IP del servidor WireGuard
|
||||||
ListenPort = 51820 # Puerto para WireGuard (por defecto 51820)
|
ListenPort = 51820 # Puerto para WireGuard (por defecto 51820)
|
||||||
PrivateKey = <private-key>
|
PrivateKey = <private-key>
|
||||||
|
|
||||||
[Peer]
|
[Peer]
|
||||||
PublicKey = <peer-public-key>
|
PublicKey = <peer-public-key>
|
||||||
AllowedIPs = 10.10.10.2/32 # IP del cliente
|
AllowedIPs = 10.10.10.2/32 # IP del cliente
|
||||||
```
|
```
|
||||||
|
|
||||||
Asegúrate de generar las claves privadas y públicas con `wg genkey` y `wg pubkey`, como se indica en la documentación de WireGuard.
|
Asegúrate de generar las claves privadas y públicas con `wg genkey` y `wg pubkey`, como se indica en la documentación de WireGuard.
|
||||||
|
|
||||||
### **3. Configurar `obfs4proxy`**
|
### **3. Configurar `obfs4proxy`**
|
||||||
|
|
||||||
El siguiente paso es configurar `obfs4proxy` para usarlo con WireGuard. Vamos a usar el puerto 443 para hacer que el tráfico de WireGuard se vea como HTTPS.
|
El siguiente paso es configurar `obfs4proxy` para usarlo con WireGuard. Vamos a usar el puerto 443 para hacer que el tráfico de WireGuard se vea como HTTPS.
|
||||||
|
|
||||||
1. **Generar un "bridge" de `obfs4proxy`**:
|
1. **Generar un "bridge" de `obfs4proxy`**:
|
||||||
|
|
||||||
Primero, necesitarás crear un "bridge" para `obfs4proxy`. Esto se hace ejecutando el siguiente comando en tu servidor para obtener un identificador único de obfs4 (también conocido como bridge):
|
Primero, necesitarás crear un "bridge" para `obfs4proxy`. Esto se hace ejecutando el siguiente comando en tu servidor para obtener un identificador único de obfs4 (también conocido como bridge):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
obfs4proxy -generate
|
obfs4proxy -generate
|
||||||
```
|
```
|
||||||
|
|
||||||
Esto generará algo como:
|
Esto generará algo como:
|
||||||
|
|
||||||
```
|
```
|
||||||
Bridge obfs4 <IP:Puerto> <identificador-obfs4>
|
Bridge obfs4 <IP:Puerto> <identificador-obfs4>
|
||||||
```
|
```
|
||||||
|
|
||||||
Guarda esta información porque la necesitarás en el cliente.
|
Guarda esta información porque la necesitarás en el cliente.
|
||||||
|
|
||||||
2. **Configurar el `obfs4proxy` en el servidor**:
|
2. **Configurar el `obfs4proxy` en el servidor**:
|
||||||
|
|
||||||
Una vez que tengas el "bridge", puedes configurar `obfs4proxy` para que actúe como un "proxy" en el servidor de WireGuard. Para hacerlo, necesitas ejecutar `obfs4proxy` y asociarlo con el puerto 443.
|
Una vez que tengas el "bridge", puedes configurar `obfs4proxy` para que actúe como un "proxy" en el servidor de WireGuard. Para hacerlo, necesitas ejecutar `obfs4proxy` y asociarlo con el puerto 443.
|
||||||
|
|
||||||
Para hacerlo, puedes usar este comando en el servidor:
|
Para hacerlo, puedes usar este comando en el servidor:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
obfs4proxy -enableServer -listenAddr 0.0.0.0:443
|
obfs4proxy -enableServer -listenAddr 0.0.0.0:443
|
||||||
```
|
```
|
||||||
|
|
||||||
Esto hará que el servidor WireGuard pase su tráfico por el `obfs4proxy`, y lo hará parecer tráfico HTTPS.
|
Esto hará que el servidor WireGuard pase su tráfico por el `obfs4proxy`, y lo hará parecer tráfico HTTPS.
|
||||||
|
|
||||||
|
|
||||||
### **4. Configurar WireGuard en el cliente**
|
### **4. Configurar WireGuard en el cliente**
|
||||||
|
|
||||||
En el lado del cliente, deberás configurar WireGuard para que se conecte al servidor, pero a través del túnel ofuscado. Aquí está un ejemplo de cómo hacerlo:
|
En el lado del cliente, deberás configurar WireGuard para que se conecte al servidor, pero a través del túnel ofuscado. Aquí está un ejemplo de cómo hacerlo:
|
||||||
|
|
||||||
1. **Configurar WireGuard**:
|
1. **Configurar WireGuard**:
|
||||||
|
|
||||||
El archivo de configuración del cliente (`wg0-client.conf`) se verá de esta forma:
|
El archivo de configuración del cliente (`wg0-client.conf`) se verá de esta forma:
|
||||||
|
|
||||||
```ini
|
```ini
|
||||||
[Interface]
|
[Interface]
|
||||||
PrivateKey = <private-key>
|
PrivateKey = <private-key>
|
||||||
Address = 10.10.10.2/32
|
Address = 10.10.10.2/32
|
||||||
|
|
||||||
[Peer]
|
[Peer]
|
||||||
PublicKey = <server-public-key>
|
PublicKey = <server-public-key>
|
||||||
Endpoint = <IP-del-servidor>:443 # Usa el puerto 443 (HTTPS) para la conexión
|
Endpoint = <IP-del-servidor>:443 # Usa el puerto 443 (HTTPS) para la conexión
|
||||||
AllowedIPs = 0.0.0.0/0, ::/0
|
AllowedIPs = 0.0.0.0/0, ::/0
|
||||||
PersistentKeepalive = 25
|
PersistentKeepalive = 25
|
||||||
```
|
```
|
||||||
|
|
||||||
2. **Configurar `obfs4proxy` en el cliente**:
|
2. **Configurar `obfs4proxy` en el cliente**:
|
||||||
|
|
||||||
En el lado del cliente, también tendrás que usar `obfs4proxy`. Puedes instalarlo de la misma manera que en el servidor.
|
En el lado del cliente, también tendrás que usar `obfs4proxy`. Puedes instalarlo de la misma manera que en el servidor.
|
||||||
|
|
||||||
Una vez instalado, ejecuta `obfs4proxy` en el cliente:
|
Una vez instalado, ejecuta `obfs4proxy` en el cliente:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
obfs4proxy -proxy <bridge-del-servidor>
|
obfs4proxy -proxy <bridge-del-servidor>
|
||||||
```
|
```
|
||||||
|
|
||||||
El `bridge-del-servidor` es la información que obtuviste del paso de configuración del servidor.
|
El `bridge-del-servidor` es la información que obtuviste del paso de configuración del servidor.
|
||||||
|
|
||||||
|
|
||||||
### **5. Verificar la conexión**
|
### **5. Verificar la conexión**
|
||||||
|
|
||||||
Finalmente, verifica que la conexión está funcionando. Si todo está configurado correctamente, el tráfico de WireGuard se verá como tráfico HTTPS y debería ser mucho más difícil de bloquear.
|
Finalmente, verifica que la conexión está funcionando. Si todo está configurado correctamente, el tráfico de WireGuard se verá como tráfico HTTPS y debería ser mucho más difícil de bloquear.
|
||||||
|
|
||||||
Para verificar:
|
Para verificar:
|
||||||
|
|
||||||
1. Asegúrate de que el servicio de WireGuard y `obfs4proxy` esté activo en ambos lados (`sudo systemctl status wg-quick@wg0`).
|
1. Asegúrate de que el servicio de WireGuard y `obfs4proxy` esté activo en ambos lados (`sudo systemctl status wg-quick@wg0`).
|
||||||
|
|
||||||
2. Realiza una conexión desde el cliente al servidor usando WireGuard, y asegúrate de que se esté enrutando correctamente a través de `obfs4proxy`.
|
2. Realiza una conexión desde el cliente al servidor usando WireGuard, y asegúrate de que se esté enrutando correctamente a través de `obfs4proxy`.
|
||||||
|
|
||||||
|
|
||||||
### **Resumen de pasos clave:**
|
### **Resumen de pasos clave:**
|
||||||
|
|
||||||
- Instalar y configurar **WireGuard** en el servidor y cliente.
|
- Instalar y configurar **WireGuard** en el servidor y cliente.
|
||||||
|
|
||||||
- Instalar y ejecutar **obfs4proxy** en el servidor y cliente, usando el puerto 443 para pasar por tráfico HTTPS.
|
- Instalar y ejecutar **obfs4proxy** en el servidor y cliente, usando el puerto 443 para pasar por tráfico HTTPS.
|
||||||
|
|
||||||
- Configurar la VPN para usar la ofuscación, de modo que el tráfico de WireGuard sea indetectable.
|
- Configurar la VPN para usar la ofuscación, de modo que el tráfico de WireGuard sea indetectable.
|
||||||
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
Este proceso es un poco más avanzado debido a la necesidad de configurar `obfs4proxy` y combinarlo con WireGuard, pero definitivamente vale la pena si las restricciones de red son severas. Si necesitas más detalles o tienes alguna pregunta durante la configuración, no dudes en preguntar.
|
Este proceso es un poco más avanzado debido a la necesidad de configurar `obfs4proxy` y combinarlo con WireGuard, pero definitivamente vale la pena si las restricciones de red son severas. Si necesitas más detalles o tienes alguna pregunta durante la configuración, no dudes en preguntar.
|
@ -1,46 +1,46 @@
|
|||||||
```bash
|
```bash
|
||||||
# speedtest: https://www.speedtest.net/es/apps/cli
|
# speedtest: https://www.speedtest.net/es/apps/cli
|
||||||
# calendar: https://hijosdeinit.gitlab.io/howto_instalacion_cal_debian11_y_derivados/
|
# calendar: https://hijosdeinit.gitlab.io/howto_instalacion_cal_debian11_y_derivados/
|
||||||
|
|
||||||
# dix_zip() {
|
# dix_zip() {
|
||||||
# # sudo apt install zip -y
|
# # sudo apt install zip -y
|
||||||
# # sudo apt install unzip
|
# # sudo apt install unzip
|
||||||
# # https://www.tecmint.com/install-zip-and-unzip-in-linux/
|
# # https://www.tecmint.com/install-zip-and-unzip-in-linux/
|
||||||
# name=$1
|
# name=$1
|
||||||
# fecha=$(date +'%d.%m.%Y')
|
# fecha=$(date +'%d.%m.%Y')
|
||||||
# hora=$(date +'%H-%M-%S')
|
# hora=$(date +'%H-%M-%S')
|
||||||
# full_name="${name}_date_${fecha}_time_${hora}.zip"
|
# full_name="${name}_date_${fecha}_time_${hora}.zip"
|
||||||
# zip -r $full_name . -i ".*" "*" -x "./.venv/*"
|
# zip -r $full_name . -i ".*" "*" -x "./.venv/*"
|
||||||
# }
|
# }
|
||||||
|
|
||||||
ip_device=$(ip addr show | grep -w 'inet' | grep -v '127.0.0.1' | awk '{print $2}' | cut -d'/' -f1 | head -n 1)
|
ip_device=$(ip addr show | grep -w 'inet' | grep -v '127.0.0.1' | awk '{print $2}' | cut -d'/' -f1 | head -n 1)
|
||||||
|
|
||||||
declare -A ip_icon=(
|
declare -A ip_icon=(
|
||||||
['192.168.10.40']='uk'
|
['192.168.10.40']='uk'
|
||||||
['192.168.10.234']='lb'
|
['192.168.10.234']='lb'
|
||||||
['192.168.10.44']='db'
|
['192.168.10.44']='db'
|
||||||
['192.168.10.122']='mb'
|
['192.168.10.122']='mb'
|
||||||
['192.168.10.37']='web1'
|
['192.168.10.37']='web1'
|
||||||
['192.168.10.245']='web2'
|
['192.168.10.245']='web2'
|
||||||
['192.168.10.232']='web3'
|
['192.168.10.232']='web3'
|
||||||
['192.168.10.42']='web5'
|
['192.168.10.42']='web5'
|
||||||
['192.168.10.43']='web5'
|
['192.168.10.43']='web5'
|
||||||
['192.168.10.59']='web6'
|
['192.168.10.59']='web6'
|
||||||
)
|
)
|
||||||
|
|
||||||
# Asignar el nombre del servidor o un valor por defecto
|
# Asignar el nombre del servidor o un valor por defecto
|
||||||
if [[ -n "${ip_icon[$ip_device]}" ]]; then
|
if [[ -n "${ip_icon[$ip_device]}" ]]; then
|
||||||
n_server="${ip_icon[$ip_device]}"
|
n_server="${ip_icon[$ip_device]}"
|
||||||
else
|
else
|
||||||
n_server="WSL"
|
n_server="WSL"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
export PS1="\[\e[31m\][\[\e[38;5;214m\]$n_server\[\e[31m\]]\[\e[0m\] 📂 > \[\033[01;32m\]\W \[\033[00m\]\n 💀 > "
|
export PS1="\[\e[31m\][\[\e[38;5;214m\]$n_server\[\e[31m\]]\[\e[0m\] 📂 > \[\033[01;32m\]\W \[\033[00m\]\n 💀 > "
|
||||||
|
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
# sudo apt install fastfetch -y
|
# sudo apt install fastfetch -y
|
||||||
fastfetch
|
fastfetch
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
```
|
```
|
@ -1,22 +1,22 @@
|
|||||||
Reunión en instalaciones de la SHCP 05/08/2025 11:00 am
|
Reunión en instalaciones de la SHCP 05/08/2025 11:00 am
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Temas vistos:
|
Temas vistos:
|
||||||
|
|
||||||
- Revisión de cada uno de los proyectos de inversión para ver los estudios de preinversión que les aplican.
|
- Revisión de cada uno de los proyectos de inversión para ver los estudios de preinversión que les aplican.
|
||||||
|
|
||||||
- Aclaración de dudas relacionados con los proyectos por parte de la Lic. María Asereth.
|
- Aclaración de dudas relacionados con los proyectos por parte de la Lic. María Asereth.
|
||||||
|
|
||||||
|
|
||||||
Acuerdos:
|
Acuerdos:
|
||||||
|
|
||||||
- Se designan a las contadoras Lic. Guadalupe y Lic. Alba como enlaces con la Lic. María Asereth para asesorías en el desarrollo de los estudios de preinversión.
|
- Se designan a las contadoras Lic. Guadalupe y Lic. Alba como enlaces con la Lic. María Asereth para asesorías en el desarrollo de los estudios de preinversión.
|
||||||
|
|
||||||
- La Lic. María Asereth gestionará apartar una sala de reuniones para permitir que podamos trabajar en las instalaciones de la SHCP a fin de facilitar y atender dudas y aclaraciones en el desarrollo de los estudios de preinversión, para ello hay que compartir mediante los enlaces los nombres de los que estarán yendo a las instalaciones.
|
- La Lic. María Asereth gestionará apartar una sala de reuniones para permitir que podamos trabajar en las instalaciones de la SHCP a fin de facilitar y atender dudas y aclaraciones en el desarrollo de los estudios de preinversión, para ello hay que compartir mediante los enlaces los nombres de los que estarán yendo a las instalaciones.
|
||||||
|
|
||||||
- La Lic. María Asereth compartirá un ejemplo de cartera de inversión.
|
- La Lic. María Asereth compartirá un ejemplo de cartera de inversión.
|
||||||
|
|
||||||
- Los estudios de preinversión deben ser entregados a más tardar el 20 de agosto.
|
- Los estudios de preinversión deben ser entregados a más tardar el 20 de agosto.
|
||||||
|
|
||||||
- IMPORTANTE: decidir si se debe involucrar al nuevo Director General Satelital de la AEM.
|
- IMPORTANTE: decidir si se debe involucrar al nuevo Director General Satelital de la AEM.
|
Loading…
x
Reference in New Issue
Block a user