tx3bas commited on
Commit
3c3ebfd
·
verified ·
1 Parent(s): 8017c3e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +124 -93
app.py CHANGED
@@ -1,74 +1,49 @@
1
  import gradio as gr
2
  from mtranslate import translate
3
  import re
 
4
 
5
  # Diccionario de idiomas y sus códigos
6
  lang_dict = {
7
  'Automático': 'auto',
8
- 'Español': 'es',
9
- 'English': 'en',
10
- 'Mandarín': 'zh',
11
- 'Hindi': 'hi',
12
- 'Árabe': 'ar',
13
- 'Portugués': 'pt',
14
- 'Bengalí': 'bn',
15
- 'Ruso': 'ru',
16
- 'Japonés': 'ja',
17
- 'Panyabí': 'pa',
18
- 'Alemán': 'de',
19
- 'Javanés': 'jw',
20
- 'Coreano': 'ko',
21
- 'Francés': 'fr',
22
- 'Vietnamita': 'vi',
23
- 'Turco': 'tr',
24
- 'Italiano': 'it',
25
- 'Ucraniano': 'uk',
26
- 'Tailandés': 'th',
27
- 'Guyaratí': 'gu',
28
- 'Polaco': 'pl',
29
- 'Griego': 'el',
30
- 'Neerlandés': 'nl',
31
- 'Sueco': 'sv',
32
- 'Rumano': 'ro',
33
- 'Checo': 'cs',
34
- 'Húngaro': 'hu',
35
- 'Hebreo': 'he',
36
- 'Indonesio': 'id',
37
- 'Nepalí': 'ne',
38
- 'Gallego': 'gl',
39
- 'Catalán': 'ca',
40
  'Vasco': 'eu'
41
  }
42
 
43
  lang_list = list(lang_dict.keys())
44
 
45
- def split_html_content(text):
46
- """Separa etiquetas HTML completas y texto traducible"""
47
- # Expresión regular para capturar etiquetas HTML completas y texto fuera de ellas
48
- pattern = r'(<[^>]+(?:>.*?</[^>]+>|>))|([^<]+)'
49
- parts = []
50
-
51
- for match in re.finditer(pattern, text, re.DOTALL):
52
- if match.group(1): # Elemento HTML completo (incluye etiquetas y contenido interno)
53
- html_tag = match.group(1)
54
- # Si tiene contenido interno, separarlo
55
- content_match = re.search(r'>(.*?)</', html_tag, re.DOTALL)
56
- if content_match and content_match.group(1).strip():
57
- content = content_match.group(1).strip()
58
- opening = html_tag[:content_match.start(1) + 1]
59
- closing = html_tag[content_match.end(1):]
60
- parts.append(('html', opening))
61
- parts.append(('text', content))
62
- parts.append(('html', closing))
63
- else:
64
- parts.append(('html', html_tag))
65
- elif match.group(2): # Texto fuera de etiquetas
66
- parts.append(('text', match.group(2).strip()))
67
-
68
- return parts
69
-
70
  def split_text(text, limit=4000):
71
- """Divide texto en fragmentos respetando el límite"""
72
  sentences = re.split(r'([;.])', text)
73
  chunks = []
74
  chunk = ''
@@ -82,55 +57,111 @@ def split_text(text, limit=4000):
82
  chunks.append(chunk)
83
  return chunks
84
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
85
  def translate_text(source_lang, target_lang, text):
86
- """Traduce contenido manteniendo etiquetas HTML intactas"""
 
 
 
87
  source_code = lang_dict[source_lang]
88
  target_code = lang_dict[target_lang]
89
 
90
- # Separar HTML y contenido
91
- parts = split_html_content(text)
92
-
93
- # Lista de términos que no deben traducirse (nombres propios, marcas, etc.)
94
- preserve_terms = {'DGM Services', 'Alexandru George Bratosin', 'X2596200v', 'info@dgm-services.com',
95
- 'https://dgm-services.com/', 'Calle Federico García Lorca', '722 17 99 13'}
96
 
97
- # Traducir solo las partes de texto
98
- translated_parts = []
99
- for part_type, content in parts:
100
- if part_type == 'text' and content:
101
- # Verificar si el contenido está en la lista de términos a preservar
102
- if content in preserve_terms:
103
- translated_parts.append(content)
104
- else:
105
- # Dividir en fragmentos si es necesario
106
- chunks = split_text(content)
107
- translated_chunks = [
108
- translate(chunk, target_code, source_code)
109
- for chunk in chunks
110
- ]
111
- translated_parts.append(''.join(translated_chunks))
112
  else:
113
- # Mantener etiquetas HTML sin cambios
114
- translated_parts.append(content)
 
 
 
 
 
 
115
 
116
- return ''.join(translated_parts)
117
 
118
- def main(Texto, source_lang, target_lang):
 
 
 
 
119
  # Realizar la traducción
120
- translated_text = translate_text(source_lang, target_lang, Texto)
121
- return translated_text
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
122
 
123
  iface = gr.Interface(
124
  fn=main,
125
  inputs=[
126
- gr.Textbox(label="Texto a traducir", lines=5),
127
- gr.Dropdown(lang_list, label="Idioma origen", value="Automático"),
128
- gr.Dropdown(lang_list, label="Idioma destino", value="Español")
129
  ],
130
- outputs="text", # Salida como texto plano
131
- title="<div style='margin:0 auto;text-align:center'><div style='margin:0 auto;text-align:center'><img style='width:100px;display: inline-table;margin-bottom:-10px' src='https://artxeweb.com/media/files/idioma.jpg'><p>Traducción sin límites</p></div>",
132
- description="<p style='margin-bottom:10px;text-align:center;background: #ffffff; padding: 8px; border-radius: 8px; border-width: 1px; border: solid 1px #e5e7eb;'>Ingresa el texto que deseas traducir, selecciona el idioma origen (o deja 'Automático') y el idioma de destino. ¡No hay límites!</p>",
133
- article="<div style='margin-top:10px'><p style='text-align: center !important; background: #ffffff; padding: 5px 30px; border-radius: 8px; border-width: 1px; border: solid 1px #e5e7eb; width: fit-content; margin: auto;'>Desarrollada por <a style='text-decoration: none !important; color: #e12a31 !important;' title='Artxe Web' href='https://artxeweb.com'>© Artxe Web</a></p></div>"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
134
  )
135
 
136
  iface.launch()
 
1
  import gradio as gr
2
  from mtranslate import translate
3
  import re
4
+ import html
5
 
6
  # Diccionario de idiomas y sus códigos
7
  lang_dict = {
8
  'Automático': 'auto',
9
+ 'Español': 'es',
10
+ 'English': 'en',
11
+ 'Mandarín': 'zh',
12
+ 'Hindi': 'hi',
13
+ 'Árabe': 'ar',
14
+ 'Portugués': 'pt',
15
+ 'Bengalí': 'bn',
16
+ 'Ruso': 'ru',
17
+ 'Japonés': 'ja',
18
+ 'Panyabí': 'pa',
19
+ 'Alemán': 'de',
20
+ 'Javanés': 'jw',
21
+ 'Coreano': 'ko',
22
+ 'Francés': 'fr',
23
+ 'Vietnamita': 'vi',
24
+ 'Turco': 'tr',
25
+ 'Italiano': 'it',
26
+ 'Ucraniano': 'uk',
27
+ 'Tailandés': 'th',
28
+ 'Guyaratí': 'gu',
29
+ 'Polaco': 'pl',
30
+ 'Griego': 'el',
31
+ 'Neerlandés': 'nl',
32
+ 'Sueco': 'sv',
33
+ 'Rumano': 'ro',
34
+ 'Checo': 'cs',
35
+ 'Húngaro': 'hu',
36
+ 'Hebreo': 'he',
37
+ 'Indonesio': 'id',
38
+ 'Nepalí': 'ne',
39
+ 'Gallego': 'gl',
40
+ 'Catalán': 'ca',
41
  'Vasco': 'eu'
42
  }
43
 
44
  lang_list = list(lang_dict.keys())
45
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
  def split_text(text, limit=4000):
 
47
  sentences = re.split(r'([;.])', text)
48
  chunks = []
49
  chunk = ''
 
57
  chunks.append(chunk)
58
  return chunks
59
 
60
+ def protect_html_tags(text):
61
+ # Identificar y extraer etiquetas HTML
62
+ html_pattern = re.compile(r'<([^>]+)>')
63
+ html_matches = html_pattern.finditer(text)
64
+
65
+ # Crear un diccionario de reemplazo
66
+ replacements = {}
67
+
68
+ # Crear una versión del texto con marcadores únicos en lugar de las etiquetas HTML
69
+ protected_text = text
70
+
71
+ for i, match in enumerate(html_matches):
72
+ placeholder = f"__HTML_TAG_{i}__"
73
+ replacements[placeholder] = match.group(0)
74
+ protected_text = protected_text.replace(match.group(0), placeholder, 1)
75
+
76
+ return protected_text, replacements
77
+
78
+ def restore_html_tags(text, replacements):
79
+ # Restaurar las etiquetas HTML originales
80
+ restored_text = text
81
+ for placeholder, original in replacements.items():
82
+ restored_text = restored_text.replace(placeholder, original)
83
+ return restored_text
84
+
85
  def translate_text(source_lang, target_lang, text):
86
+ # Proteger etiquetas HTML
87
+ protected_text, replacements = protect_html_tags(text)
88
+
89
+ # Obtener códigos de idioma
90
  source_code = lang_dict[source_lang]
91
  target_code = lang_dict[target_lang]
92
 
93
+ # Dividir el texto en fragmentos para no superar el límite
94
+ chunks = split_text(protected_text)
 
 
 
 
95
 
96
+ # Traducir cada fragmento respetando el idioma de origen
97
+ translated_chunks = []
98
+ for chunk in chunks:
99
+ if source_lang == 'Automático':
100
+ # Si es automático, no especificamos el idioma de origen
101
+ translated_chunk = translate(chunk, target_code)
 
 
 
 
 
 
 
 
 
102
  else:
103
+ # Si se especificó un idioma de origen, lo usamos
104
+ translated_chunk = translate(chunk, target_code, source=source_code)
105
+ translated_chunks.append(translated_chunk)
106
+
107
+ translated_text = ''.join(translated_chunks)
108
+
109
+ # Restaurar etiquetas HTML
110
+ final_text = restore_html_tags(translated_text, replacements)
111
 
112
+ return final_text
113
 
114
+ def main(texto, source_lang, target_lang):
115
+ # Verificar si hay texto para traducir
116
+ if not texto.strip():
117
+ return "<div>Por favor, ingresa un texto para traducir.</div>"
118
+
119
  # Realizar la traducción
120
+ translated_text = translate_text(source_lang, target_lang, texto)
121
+
122
+ # Escapar el texto traducido para JavaScript (para el botón de copia)
123
+ escaped_text = html.escape(translated_text).replace("'", "\\'").replace('"', '\\"')
124
+
125
+ # Generar HTML con botón de copia
126
+ html_output = f"""
127
+ <div style="position: relative;">
128
+ <div>{translated_text}</div>
129
+ <button
130
+ style="position: absolute; top: 0; right: 0; font-size: small; padding: 5px; background-color: #f0f0f0; color: #333; border: 1px solid #ccc; border-radius: 4px; cursor: pointer;"
131
+ onclick='navigator.clipboard.writeText("{escaped_text}").then(() => alert("Texto copiado al portapapeles"))'>
132
+ Copiar
133
+ </button>
134
+ </div>
135
+ """
136
+
137
+ return html_output
138
 
139
  iface = gr.Interface(
140
  fn=main,
141
  inputs=[
142
+ "text",
143
+ gr.Dropdown(lang_list, value="Automático", label="Idioma de Origen"),
144
+ gr.Dropdown(lang_list, label="Idioma de Destino")
145
  ],
146
+ outputs="html",
147
+ title="""<div style='margin:0 auto;text-align:center'>
148
+ <div style='margin:0 auto;text-align:center'>
149
+ <img style='width:100px;display: inline-table;margin-bottom:-10px' src='https://artxeweb.com/media/files/idioma.jpg'>
150
+ <p>Traducción sin límites</p>
151
+ </div>
152
+ </div>""",
153
+ description="""<p style='margin-bottom:10px;text-align:center;background: #ffffff; padding: 8px; border-radius: 8px;
154
+ border-width: 1px; border: solid 1px #e5e7eb;'>
155
+ Ingresa el texto que deseas traducir, selecciona el idioma de origen (o déjalo en "Automático")
156
+ y selecciona el idioma de destino. Las etiquetas HTML serán preservadas. ¡No hay límites!
157
+ </p>""",
158
+ article="""<div style='margin-top:10px'>
159
+ <p style='text-align: center !important; background: #ffffff; padding: 5px 30px;
160
+ border-radius: 8px; border-width: 1px; border: solid 1px #e5e7eb; width: fit-content; margin: auto;'>
161
+ Desarrollada por <a style='text-decoration: none !important; color: #e12a31 !important;'
162
+ title='Artxe Web' href='https://artxeweb.com'>© Artxe Web</a>
163
+ </p>
164
+ </div>"""
165
  )
166
 
167
  iface.launch()