g360-cli 1.4.0 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/README.md +122 -0
  2. package/package.json +11 -4
  3. package/src/assets/brand/brand.json +43 -0
  4. package/src/assets/brand/cipsa/logotypes/Logo_cipsa_borde.png +0 -0
  5. package/src/assets/brand/cipsa/logotypes/Logo_cipsa_borde.svg +9 -0
  6. package/src/assets/brand/cipsa/logotypes/Logo_cipsa_solid.png +0 -0
  7. package/src/assets/brand/cipsa/logotypes/Logo_cipsa_solid.svg +9 -0
  8. package/src/assets/brand/g360/logotypes/logo-g360-dark.svg +19 -0
  9. package/src/assets/brand/g360/logotypes/logo-g360-light.svg +19 -0
  10. package/src/assets/brand/g360/logotypes/logo_g360_dark_b64.txt +1 -0
  11. package/src/assets/brand/g360/logotypes/logo_g360_light_b64.txt +1 -0
  12. package/src/assets/config/g360-skills.json +60 -0
  13. package/src/assets/snippets/snippets.json +293 -101
  14. package/src/assets/templates/lit-web/src/core/skill.json +12 -5
  15. package/src/assets/templates/python-cli/build-portable.bat +19 -9
  16. package/src/assets/templates/python-cli/src/core/skill.json +25 -6
  17. package/src/assets/templates/python-customtkinter/README.md +32 -31
  18. package/src/assets/templates/python-customtkinter/assets/images/logo-g360-dark.svg +19 -0
  19. package/src/assets/templates/python-customtkinter/assets/images/logo-g360-light.svg +19 -0
  20. package/src/assets/templates/python-customtkinter/build.bat +50 -0
  21. package/src/assets/templates/python-customtkinter/pyproject.toml +26 -0
  22. package/src/assets/templates/python-customtkinter/run.bat +11 -20
  23. package/src/assets/templates/python-customtkinter/src/core/g360_theme.py +101 -0
  24. package/src/assets/templates/python-customtkinter/src/core/skill.json +23 -10
  25. package/src/assets/templates/python-customtkinter/src/main.py +61 -81
  26. package/src/assets/templates/python-flet/README.md +52 -93
  27. package/src/assets/templates/python-flet/assets/images/Logo_cipsa_borde.png +0 -0
  28. package/src/assets/templates/python-flet/assets/images/Logo_cipsa_borde.svg +9 -0
  29. package/src/assets/templates/python-flet/assets/images/Logo_cipsa_solid.png +0 -0
  30. package/src/assets/templates/python-flet/assets/images/Logo_cipsa_solid.svg +9 -0
  31. package/src/assets/templates/python-flet/assets/images/logo-g360-dark.svg +19 -0
  32. package/src/assets/templates/python-flet/assets/images/logo-g360-light.svg +19 -0
  33. package/src/assets/templates/python-flet/build.bat +36 -0
  34. package/src/assets/templates/python-flet/pyproject.toml +26 -0
  35. package/src/assets/templates/python-flet/run.bat +11 -72
  36. package/src/assets/templates/python-flet/src/core/__init__.py +0 -0
  37. package/src/assets/templates/python-flet/src/core/g360_theme.py +186 -0
  38. package/src/assets/templates/python-flet/src/core/skill.json +28 -8
  39. package/src/assets/templates/python-flet/src/export/__init__.py +0 -0
  40. package/src/assets/templates/python-flet/src/main.py +113 -68
  41. package/src/assets/templates/python-flet/src/test_app.py +41 -37
  42. package/src/assets/templates/python-flet/src/ui/__init__.py +0 -0
  43. package/src/assets/templates/python-flet-migrate/README.md +70 -0
  44. package/src/assets/templates/python-flet-migrate/assets/images/logo-g360-dark.svg +19 -0
  45. package/src/assets/templates/python-flet-migrate/assets/images/logo-g360-light.svg +19 -0
  46. package/src/assets/templates/python-flet-migrate/build.bat +36 -0
  47. package/src/assets/templates/python-flet-migrate/pyproject.toml +26 -0
  48. package/src/assets/templates/python-flet-migrate/run.bat +20 -0
  49. package/src/assets/templates/python-flet-migrate/src/core/__init__.py +0 -0
  50. package/src/assets/templates/python-flet-migrate/src/core/g360_theme.py +186 -0
  51. package/src/assets/templates/python-flet-migrate/src/core/skill.json +34 -0
  52. package/src/assets/templates/python-flet-migrate/src/main.py +71 -42
  53. package/src/assets/templates/solid-web/src/core/skill.json +12 -5
  54. package/src/assets/templates/svelte-web/src/core/skill.json +12 -5
  55. package/src/assets/templates/web-pwa/index.html +2 -7
  56. package/src/assets/templates/web-pwa/public/favicon.svg +4 -0
  57. package/src/assets/templates/web-pwa/public/manifest.json +11 -0
  58. package/src/assets/templates/web-pwa/src/App.jsx +22 -0
  59. package/src/assets/templates/web-pwa/src/components/FooterSignature.jsx +9 -0
  60. package/src/assets/templates/web-pwa/src/components/Header.jsx +12 -0
  61. package/src/assets/templates/web-pwa/src/components/LoadingOverlay.jsx +10 -0
  62. package/src/assets/templates/web-pwa/src/core/skill.json +25 -0
  63. package/src/assets/templates/web-pwa/src/main.jsx +9 -0
  64. package/src/assets/templates/web-pwa/src/styles/main.css +133 -0
  65. package/src/assets/templates/web-pwa/vite.config.js +12 -0
  66. package/src/cli.js +4 -4
  67. package/src/commands/bring.js +81 -6
  68. package/src/commands/list.js +79 -9
  69. package/src/lib/asset-validator.js +145 -0
  70. package/src/lib/auditor.js +48 -0
  71. package/src/lib/global-config.js +260 -0
  72. package/src/lib/i18n.js +238 -0
  73. package/src/lib/logger.js +100 -0
  74. package/src/lib/manifest.js +70 -1
  75. package/src/lib/validator.js +39 -0
  76. package/src/schemas/skills-schema.json +1 -0
  77. package/src/schemas/snippets-schema.json +1 -0
  78. package/dist/g360.exe +0 -0
  79. package/src/assets/templates/python-customtkinter/build-portable.bat +0 -28
  80. package/src/assets/templates/python-customtkinter/requirements.txt +0 -1
  81. package/src/assets/templates/python-flet/build-portable.bat +0 -42
  82. package/src/assets/templates/python-flet/create_shortcut.vbs +0 -35
  83. package/src/assets/templates/python-flet/requirements.txt +0 -3
  84. package/src/assets/templates/web-pwa/app.js +0 -1
  85. package/src/assets/templates/web-pwa/styles.css +0 -28
@@ -1,101 +1,146 @@
1
- import flet as ft
2
1
  import sys
2
+ from pathlib import Path
3
+ import flet as ft
4
+ from core.g360_theme import G360Theme
5
+
6
+ BASE_DIR = Path(__file__).resolve().parent.parent
7
+ if str(BASE_DIR) not in sys.path:
8
+ sys.path.insert(0, str(BASE_DIR))
3
9
 
4
10
 
5
11
  class G360App:
6
12
  def __init__(self, page: ft.Page):
7
13
  self.page = page
8
- self.setup_theme()
9
- self.create_ui()
14
+ self.theme = G360Theme()
15
+ self._setup_page()
16
+ self._build_ui()
10
17
 
11
- def setup_theme(self):
12
- self.page.title = "G360 Desktop App"
18
+ def _setup_page(self):
19
+ self.page.title = self.theme.build_name()
13
20
  self.page.theme_mode = ft.ThemeMode.DARK
14
- self.page.padding = 20
15
- self.page.bgcolor = "#0b1220"
16
- self.page.window_width = 1200
17
- self.page.window_height = 800
21
+ self.page.bgcolor = self.theme.bg
22
+ self.page.padding = 0
23
+ self.page.window_width = 1350
24
+ self.page.window_height = 900
18
25
  self.page.window_resizable = True
19
26
  self.page.window_center()
20
27
 
21
- def create_ui(self):
28
+ def _build_ui(self):
29
+ self.loading = self.theme.loading_overlay()
22
30
  self.page.add(
23
- ft.Container(
24
- content=ft.Column([
25
- self.create_header(),
26
- self.create_content(),
27
- ]),
31
+ ft.Stack(
32
+ controls=[
33
+ ft.Column(
34
+ controls=[
35
+ self._build_header(),
36
+ ft.Container(
37
+ content=self._build_content(),
38
+ expand=True,
39
+ padding=20,
40
+ ),
41
+ self.theme.footer_signature(),
42
+ ],
43
+ spacing=0,
44
+ expand=True,
45
+ ),
46
+ self.loading,
47
+ ],
28
48
  expand=True,
29
- spacing=20
30
49
  )
31
50
  )
32
51
 
33
- def create_header(self):
34
- return ft.Container(
35
- content=ft.Row([
36
- ft.Text(
37
- "G360",
38
- size=32,
39
- weight=ft.FontWeight.BOLD,
40
- color="#00d084"
41
- ),
42
- ft.Text(
43
- "Desktop App",
44
- size=20,
45
- color="#94a3b8"
46
- ),
47
- ft.Container(expand=True),
48
- ft.IconButton(
49
- icon=ft.icons.SETTINGS,
50
- on_click=self.on_settings
51
- ),
52
- ], alignment=ft.MainAxisAlignment.START),
52
+ def show_loading(self, message="Procesando..."):
53
+ self.loading.content.controls[2].value = message
54
+ self.loading.visible = True
55
+ self.page.update()
56
+
57
+ def hide_loading(self):
58
+ self.loading.visible = False
59
+ self.page.update()
60
+
61
+ def _build_header(self):
62
+ return self.theme.container(
63
+ content=ft.Row(
64
+ controls=[
65
+ ft.Row(
66
+ controls=[
67
+ self.theme.logo_component(height=32),
68
+ ft.Container(width=8),
69
+ self.theme.styled_text(
70
+ "Desktop App", size=20, color=self.theme.muted
71
+ ),
72
+ ],
73
+ spacing=0,
74
+ ),
75
+ ft.Container(expand=True),
76
+ ft.IconButton(
77
+ icon=ft.icons.SETTINGS,
78
+ on_click=lambda _: print("Settings"),
79
+ ),
80
+ ],
81
+ alignment=ft.MainAxisAlignment.START,
82
+ ),
53
83
  padding=20,
54
- bgcolor="#151e2e",
55
- border_radius=12
84
+ bgcolor=self.theme.surface,
56
85
  )
57
86
 
58
- def create_content(self):
59
- return ft.Container(
60
- content=ft.Column([
61
- ft.Text(
87
+ def _build_content(self):
88
+ return ft.Column(
89
+ controls=[
90
+ self.theme.styled_text(
62
91
  "Bienvenido a G360 Desktop",
63
92
  size=24,
64
- color="#f0f4f8"
93
+ weight=ft.FontWeight.BOLD,
65
94
  ),
66
95
  ft.Container(height=20),
67
- ft.Row([
68
- self.create_card("Usuarios", "Gestión de usuarios", ft.icons.PEOPLE),
69
- self.create_card("Reportes", "Ver reportes", ft.icons.ANALYTICS),
70
- self.create_card("Configuración", "Ajustes del sistema", ft.icons.SETTINGS),
71
- ], spacing=20),
72
- ], scroll=ft.ScrollMode.AUTO),
73
- expand=True,
74
- padding=20
96
+ ft.Row(
97
+ controls=[
98
+ self._build_card(
99
+ "Usuarios", "Gestión de usuarios", ft.icons.PEOPLE
100
+ ),
101
+ self._build_card(
102
+ "Reportes", "Ver reportes", ft.icons.ANALYTICS
103
+ ),
104
+ self._build_card(
105
+ "Configuración", "Ajustes del sistema", ft.icons.SETTINGS
106
+ ),
107
+ ],
108
+ spacing=20,
109
+ ),
110
+ ],
111
+ scroll=ft.ScrollMode.AUTO,
75
112
  )
76
113
 
77
- def create_card(self, title, subtitle, icon):
78
- return ft.Container(
79
- content=ft.Column([
80
- ft.Icon(icon, size=48, color="#00d084"),
81
- ft.Text(title, size=18, weight=ft.FontWeight.BOLD, color="#f0f4f8"),
82
- ft.Text(subtitle, size=14, color="#94a3b8"),
83
- ], horizontal_alignment=ft.CrossAxisAlignment.CENTER, spacing=10),
84
- width=200,
85
- height=180,
86
- bgcolor="#151e2e",
87
- border_radius=12,
88
- padding=20,
89
- alignment=ft.alignment.center
114
+ def _build_card(self, title, subtitle, icon):
115
+ return self.theme.container(
116
+ content=ft.Column(
117
+ controls=[
118
+ ft.Icon(icon, size=48, color=self.theme.accent),
119
+ self.theme.styled_text(
120
+ title, size=18, weight=ft.FontWeight.BOLD
121
+ ),
122
+ self.theme.styled_text(
123
+ subtitle, size=14, color=self.theme.muted
124
+ ),
125
+ ],
126
+ horizontal_alignment=ft.CrossAxisAlignment.CENTER,
127
+ spacing=10,
128
+ ),
129
+ width=220,
130
+ height=190,
131
+ alignment=ft.alignment.center,
90
132
  )
91
133
 
92
- def on_settings(self, e):
93
- print("Settings clicked")
94
-
95
134
 
96
135
  def main(page: ft.Page):
97
136
  G360App(page)
98
137
 
99
138
 
100
139
  if __name__ == "__main__":
101
- ft.app(target=main)
140
+ try:
141
+ ft.run(main)
142
+ except Exception as e:
143
+ print(f"\n[FATAL] Error al iniciar la aplicacion: {e}", flush=True)
144
+ import traceback
145
+ traceback.print_exc()
146
+ input("\nPresione Enter para salir...")
@@ -1,21 +1,42 @@
1
- """
2
- Tests para la aplicación G360 Flet
3
- Usa: pytest test_app.py -v
4
- """
5
-
6
1
  import unittest
7
2
  from unittest.mock import Mock, patch
3
+ import json
4
+ from pathlib import Path
8
5
  import flet as ft
6
+ from core.g360_theme import G360Theme
9
7
 
10
8
 
11
- class TestG360App(unittest.TestCase):
12
- """Tests básicos para la aplicación Flet"""
9
+ class TestG360Theme(unittest.TestCase):
10
+ def setUp(self):
11
+ self.theme = G360Theme(skill_path=Path(__file__).parent / "core" / "skill.json")
12
+
13
+ def test_default_colors(self):
14
+ self.assertEqual(self.theme.bg, "#0b1220")
15
+ self.assertEqual(self.theme.surface, "#1a2332")
16
+ self.assertEqual(self.theme.accent, "#00d084")
17
+ self.assertEqual(self.theme.text, "#f0f4f8")
18
+ self.assertEqual(self.theme.muted, "#94a3b8")
19
+ self.assertEqual(self.theme.success, "#22c55e")
20
+ self.assertEqual(self.theme.warning, "#f59e0b")
21
+ self.assertEqual(self.theme.error, "#ef4444")
22
+
23
+ def test_as_dict(self):
24
+ d = self.theme.as_dict
25
+ self.assertEqual(d["bg"], "#0b1220")
26
+ self.assertEqual(d["surface"], "#1a2332")
27
+ self.assertEqual(d["accent"], "#00d084")
28
+
29
+ def test_effects(self):
30
+ self.assertTrue(self.theme.glassmorphism)
31
+ self.assertEqual(self.theme.blur, "12px")
32
+ self.assertEqual(self.theme.rounded, "12px")
13
33
 
34
+
35
+ class TestG360App(unittest.TestCase):
14
36
  def setUp(self):
15
37
  self.mock_page = Mock(spec=ft.Page)
16
38
 
17
39
  def test_page_theme_setup(self):
18
- """Verifica que la página se configura con el tema correcto"""
19
40
  self.mock_page.title = "G360 Desktop App"
20
41
  self.mock_page.theme_mode = ft.ThemeMode.DARK
21
42
  self.mock_page.bgcolor = "#0b1220"
@@ -25,79 +46,62 @@ class TestG360App(unittest.TestCase):
25
46
  self.assertEqual(self.mock_page.bgcolor, "#0b1220")
26
47
 
27
48
  def test_colors_g360(self):
28
- """Verifica los colores del tema G360"""
29
49
  colors = {
30
50
  "bg": "#0b1220",
31
- "surface": "#151e2e",
51
+ "surface": "#1a2332",
32
52
  "accent": "#00d084",
33
53
  "text": "#f0f4f8",
34
- "muted": "#94a3b8"
54
+ "muted": "#94a3b8",
35
55
  }
36
-
37
56
  for key, value in colors.items():
38
57
  self.assertIsNotNone(value)
39
58
 
40
59
  def test_button_styles(self):
41
- """Verifica estilos de botones G360"""
42
60
  button = ft.ElevatedButton(
43
61
  text="Test",
44
62
  bgcolor="#00d084",
45
- color="#0b1220"
63
+ color="#0b1220",
46
64
  )
47
-
48
65
  self.assertIsNotNone(button)
49
66
 
50
67
  def test_container_styles(self):
51
- """Verifica estilos de contenedores G360"""
52
68
  container = ft.Container(
53
- bgcolor="#151e2e",
69
+ bgcolor="#1a2332",
54
70
  border_radius=12,
55
- padding=20
71
+ padding=20,
56
72
  )
57
-
58
73
  self.assertIsNotNone(container)
59
- self.assertEqual(container.bgcolor, "#151e2e")
74
+ self.assertEqual(container.bgcolor, "#1a2332")
60
75
  self.assertEqual(container.border_radius, 12)
61
76
 
62
77
 
63
78
  class TestMigration(unittest.TestCase):
64
- """Tests para migración desde tkinter/ctkinter"""
65
-
66
79
  def test_convert_tkinter_widgets(self):
67
- """Verifica mapeo de widgets tkinter a Flet"""
68
80
  mapping = {
69
- 'tk.Label': 'ft.Text',
70
- 'tk.Button': 'ft.ElevatedButton',
71
- 'tk.Entry': 'ft.TextField',
72
- 'tk.Frame': 'ft.Container',
81
+ "tk.Label": "ft.Text",
82
+ "tk.Button": "ft.ElevatedButton",
83
+ "tk.Entry": "ft.TextField",
84
+ "tk.Frame": "ft.Container",
73
85
  }
74
-
75
86
  for tk, flet in mapping.items():
76
87
  self.assertIsNotNone(tk)
77
88
  self.assertIsNotNone(flet)
78
89
 
79
90
 
80
91
  class TestCalculations(unittest.TestCase):
81
- """Tests para cálculos y procesamiento de datos"""
82
-
83
92
  def test_sum_basic(self):
84
- """Test básico de suma"""
85
- result = 2 + 2
86
- self.assertEqual(result, 4)
93
+ self.assertEqual(2 + 2, 4)
87
94
 
88
95
  def test_list_operations(self):
89
- """Test operaciones con listas"""
90
96
  items = [1, 2, 3, 4, 5]
91
97
  self.assertEqual(sum(items), 15)
92
98
  self.assertEqual(len(items), 5)
93
- self.assertEqual(max(items), 5)
94
99
 
95
100
  def test_dict_operations(self):
96
- """Test operaciones con diccionarios"""
97
101
  data = {"sku": "ABC001", "cantidad": 10, "precio": 50.0}
98
102
  self.assertIn("sku", data)
99
103
  self.assertEqual(data["cantidad"] * data["precio"], 500.0)
100
104
 
101
105
 
102
- if __name__ == '__main__':
106
+ if __name__ == "__main__":
103
107
  unittest.main()
@@ -0,0 +1,70 @@
1
+ # G360 Python Flet Migration App
2
+
3
+ Template para migrar aplicaciones de **tkinter/CustomTkinter a Flet** con el ecosistema G360.
4
+
5
+ ## Estructura del Proyecto
6
+
7
+ ```
8
+ mi-proyecto/
9
+ ├── src/
10
+ │ ├── main.py # Entry point: ft.run(main)
11
+ │ ├── migrate_tkinter.py # Asistente de migracion
12
+ │ ├── core/
13
+ │ │ ├── skill.json # Configuracion del skill G360
14
+ │ │ └── g360_theme.py # Theme engine
15
+ ├── assets/
16
+ │ └── images/
17
+ ├── skill.json # Skill G360 aplicado
18
+ ├── pyproject.toml # Dependencias
19
+ ├── run.bat # Ejecutar app
20
+ ├── build.bat # Build EXE standalone
21
+ └── README.md
22
+ ```
23
+
24
+ ## Migracion de tkinter/CustomTkinter
25
+
26
+ ### Paso 1: Reemplazar imports
27
+ ```python
28
+ # Antes (tkinter)
29
+ import tkinter as tk
30
+ from tkinter import ttk, messagebox
31
+
32
+ # Despues (Flet)
33
+ import flet as ft
34
+ ```
35
+
36
+ ### Paso 2: Convertir widgets
37
+ | tkinter | Flet |
38
+ |---------|------|
39
+ | `tk.Button` | `ft.ElevatedButton` |
40
+ | `tk.Entry` | `ft.TextField` |
41
+ | `tk.Label` | `ft.Text` |
42
+ | `tk.Frame` | `ft.Container` |
43
+ | `ttk.Treeview` | `ft.DataTable` |
44
+ | `messagebox` | `ft.AlertDialog` |
45
+
46
+ ### Paso 3: Aplicar tema G360
47
+ ```python
48
+ class MigratedApp:
49
+ def __init__(self, page: ft.Page):
50
+ self.theme = G360Theme()
51
+ self.page = page
52
+ self._setup_page()
53
+
54
+ def _setup_page(self):
55
+ self.page.title = self.theme.build_name()
56
+ self.page.theme_mode = ft.ThemeMode.DARK
57
+ self.page.bgcolor = self.theme.bg
58
+ ```
59
+
60
+ ## Ejecucion
61
+
62
+ ```bash
63
+ run.bat
64
+ ```
65
+
66
+ ## Build Windows
67
+
68
+ ```bash
69
+ build.bat
70
+ ```
@@ -0,0 +1,19 @@
1
+ <svg viewBox="0 0 280 70" xmlns="http://www.w3.org/2000/svg">
2
+ <defs>
3
+ <filter id="glow-dark" x="-40%" y="-40%" width="180%" height="180%">
4
+ <feGaussianBlur stdDeviation="3" result="blur" />
5
+ <feFlood flood-color="#22c55e" flood-opacity="0.8" result="glowColor"/>
6
+ <feComposite in="glowColor" in2="blur" operator="in" result="softGlow"/>
7
+ <feMerge>
8
+ <feMergeNode in="softGlow"/>
9
+ <feMergeNode in="SourceGraphic"/>
10
+ </feMerge>
11
+ </filter>
12
+ </defs>
13
+ <circle cx="20" cy="20" r="5" fill="#94a3b8" />
14
+ <circle cx="20" cy="40" r="5" fill="#22c55e" filter="url(#glow-dark)" />
15
+ <circle cx="20" cy="60" r="5" fill="#94a3b8" />
16
+ <path d="M45 20 L 65 40 L 45 60" fill="none" stroke="#22c55e" stroke-width="6" stroke-linecap="round" stroke-linejoin="round" filter="url(#glow-dark)"/>
17
+ <text x="85" y="45" font-family="Arial Black, sans-serif" font-weight="bold" font-size="38" fill="#f8fafc">G360</text>
18
+ <text x="85" y="65" font-family="monospace" font-size="12" fill="#94a3b8" letter-spacing="4">BY CCUSI</text>
19
+ </svg>
@@ -0,0 +1,19 @@
1
+ <svg viewBox="0 0 280 70" xmlns="http://www.w3.org/2000/svg">
2
+ <defs>
3
+ <filter id="glow-light" x="-30%" y="-30%" width="160%" height="160%">
4
+ <feGaussianBlur stdDeviation="2.5" result="blur" />
5
+ <feFlood flood-color="#22c55e" flood-opacity="0.6" result="glowColor"/>
6
+ <feComposite in="glowColor" in2="blur" operator="in" result="softGlow"/>
7
+ <feMerge>
8
+ <feMergeNode in="softGlow"/>
9
+ <feMergeNode in="SourceGraphic"/>
10
+ </feMerge>
11
+ </filter>
12
+ </defs>
13
+ <circle cx="20" cy="20" r="5" fill="#475569" />
14
+ <circle cx="20" cy="40" r="5" fill="#22c55e" filter="url(#glow-light)" />
15
+ <circle cx="20" cy="60" r="5" fill="#475569" />
16
+ <path d="M45 20 L 65 40 L 45 60" fill="none" stroke="#22c55e" stroke-width="6" stroke-linecap="round" stroke-linejoin="round" filter="url(#glow-light)"/>
17
+ <text x="85" y="45" font-family="Arial Black, sans-serif" font-weight="bold" font-size="38" fill="#1e293b">G360</text>
18
+ <text x="85" y="65" font-family="monospace" font-size="12" fill="#64748b" letter-spacing="4">BY CCUSI</text>
19
+ </svg>
@@ -0,0 +1,36 @@
1
+ @echo off
2
+ chcp 65001 >nul
3
+ cd /d "%~dp0"
4
+
5
+ echo.
6
+ echo ========================================
7
+ echo G360 - Build Windows App
8
+ echo Genera ejecutable standalone
9
+ echo ========================================
10
+ echo.
11
+
12
+ REM Verificar uv
13
+ where uv >nul 2>&1
14
+ if errorlevel 1 (
15
+ echo Instalando uv...
16
+ powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
17
+ )
18
+
19
+ REM Build con flet (maneja dependencias automaticamente)
20
+ echo [BUILD] Generando ejecutable...
21
+ uv run flet build windows --name "G360-App" --icon assets/images/app.ico
22
+
23
+ if errorlevel 1 (
24
+ echo.
25
+ echo ERROR: Fallo la generacion del ejecutable.
26
+ pause
27
+ exit /b 1
28
+ )
29
+
30
+ echo.
31
+ echo ========================================
32
+ echo BUILD EXITOSO
33
+ echo Ejecutable en: build/windows/
34
+ echo ========================================
35
+ echo.
36
+ pause
@@ -0,0 +1,26 @@
1
+ [project]
2
+ name = "g360-app"
3
+ version = "1.0.0"
4
+ description = "G360 Desktop Application (Flet Migration)"
5
+ authors = [
6
+ { name = "ccusi", email = "ccusi@cipsa.com.pe" },
7
+ ]
8
+ requires-python = ">=3.11,<4.0"
9
+ dependencies = [
10
+ "flet>=0.25.0",
11
+ "openpyxl>=3.1.0",
12
+ "pandas>=2.0.0",
13
+ ]
14
+
15
+ [project.optional-dependencies]
16
+ dev = [
17
+ "pytest>=8.0.0",
18
+ "pytest-cov>=5.0.0",
19
+ ]
20
+
21
+ [build-system]
22
+ requires = ["hatchling"]
23
+ build-backend = "hatchling.build"
24
+
25
+ [tool.hatch.build.targets.wheel]
26
+ packages = ["src"]
@@ -0,0 +1,20 @@
1
+ @echo off
2
+ chcp 65001 >nul
3
+ cd /d "%~dp0"
4
+
5
+ echo.
6
+ echo ========================================
7
+ echo G360 Flet Migration App
8
+ echo powered by G360
9
+ echo ========================================
10
+ echo.
11
+
12
+ REM uv run detecta/instala Python y dependencias automaticamente
13
+ uv run python src/main.py
14
+
15
+ if errorlevel 1 (
16
+ echo.
17
+ echo ERROR: La aplicacion fallo.
18
+ echo Verifique que uv este instalado: https://docs.astral.sh/uv/
19
+ pause
20
+ )