Commit 4892f503045408c7e1047cb9a6967b439de8ab97

Authored by Erickson Silva
2 parents a6c9bbbf a537f5f0
Exists in master

Merge branch 'devel'

data/preposicoes.csv
... ... @@ -13,6 +13,5 @@ pelo
13 13 pela
14 14 pelos
15 15 pelas
16   -para
17 16 ao
18 17 aos
19 18 \ No newline at end of file
... ...
data/regras.xml
... ... @@ -195,6 +195,46 @@
195 195 <newtokenpos>next</newtokenpos>
196 196 </class>
197 197 </rule>
  198 + <rule name = "SE"><!-- Eliminar SE -->
  199 + <active>true</active>
  200 + <count>1</count>
  201 + <class>
  202 + <title>SE</title>
  203 + <action>remove</action>
  204 + </class>
  205 + </rule>
  206 + <rule name = "CL"><!-- Eliminar conjunção -->
  207 + <active>true</active>
  208 + <count>1</count>
  209 + <class>
  210 + <title>CL</title>
  211 + <action>remove</action>
  212 + </class>
  213 + </rule>
  214 + <rule name = "CONJ"><!-- Eliminar conjunção -->
  215 + <active>true</active>
  216 + <count>1</count>
  217 + <class>
  218 + <title>CONJ</title>
  219 + <action>remove</action>
  220 + </class>
  221 + </rule>
  222 + <rule name = "+"><!-- Eliminar + -->
  223 + <active>true</active>
  224 + <count>1</count>
  225 + <class>
  226 + <title>+</title>
  227 + <action>remove</action>
  228 + </class>
  229 + </rule>
  230 + <rule name = "-R"><!-- Eliminar -R -->
  231 + <active>true</active>
  232 + <count>1</count>
  233 + <class>
  234 + <title>-R</title>
  235 + <action>remove</action>
  236 + </class>
  237 + </rule>
198 238 <rule name = "D"><!-- Eliminar artigo definido masculino singular -->
199 239 <active>true</active>
200 240 <count>1</count>
... ... @@ -389,7 +429,7 @@
389 429 <newtokenpos>next</newtokenpos>
390 430 </class>
391 431 </rule>
392   - <rule name = "SR-P"><!-- tempo verbal - presente com AdvP(t) -->
  432 + <rule name = "SR-P"><!-- tempo verbal - presente com AdvP(t) -->
393 433 <active>true</active>
394 434 <count>1</count>
395 435 <class>
... ... @@ -922,7 +962,7 @@
922 962 </class>
923 963 </rule>
924 964 <rule name = "VP(VB_ADV-NEG)"><!-- tratamento do adverbio de negação modificador da raiz do verbo -->
925   - <active>false</active>
  965 + <active>true</active>
926 966 <count>2</count>
927 967 <class>
928 968 <title>VB</title>
... ... @@ -936,7 +976,7 @@
936 976 </class>
937 977 </rule>
938 978 <rule name = "VP(VB_ADV-NEG)"><!-- tratamento do adverbio de negação modificador de expressão facial do verbo -->
939   - <active>false</active>
  979 + <active>true</active>
940 980 <count>2</count>
941 981 <class>
942 982 <title>VB</title>
... ... @@ -1267,7 +1307,7 @@
1267 1307 </class>
1268 1308 </rule>
1269 1309 <rule name = "AP(ADV-NEG_ADJ)"><!-- tratamento do adverbio de negação modificador do adjetivo masculino -->
1270   - <active>false</active>
  1310 + <active>true</active>
1271 1311 <count>2</count>
1272 1312 <class>
1273 1313 <title>ADV-NEG</title>
... ... @@ -1280,7 +1320,7 @@
1280 1320 </class>
1281 1321 </rule>
1282 1322 <rule name = "AP(ADJ_ADV-NEG)"><!-- tratamento do adverbio de negação modificador do adjetivo masculino (inverso) -->
1283   - <active>false</active>
  1323 + <active>true</active>
1284 1324 <count>2</count>
1285 1325 <class>
1286 1326 <title>ADJ</title>
... ... @@ -1293,7 +1333,7 @@
1293 1333 </class>
1294 1334 </rule>
1295 1335 <rule name = "AP(ADV-NEG_ADJ-P)"><!-- tratamento do adverbio de negação modificador do adjetivo masculino plural -->
1296   - <active>false</active>
  1336 + <active>true</active>
1297 1337 <count>2</count>
1298 1338 <class>
1299 1339 <title>ADV-NEG</title>
... ... @@ -1306,7 +1346,7 @@
1306 1346 </class>
1307 1347 </rule>
1308 1348 <rule name = "AP(ADJ-P_ADV-NEG)"><!-- tratamento do adverbio de negação modificador do adjetivo masculino plural (inverso) -->
1309   - <active>false</active>
  1349 + <active>true</active>
1310 1350 <count>2</count>
1311 1351 <class>
1312 1352 <title>ADJ-P</title>
... ... @@ -1319,7 +1359,7 @@
1319 1359 </class>
1320 1360 </rule>
1321 1361 <rule name = "AP(ADV-NEG_ADJ-F)"><!-- tratamento do adverbio de negação modificador do adjetivo feminino -->
1322   - <active>false</active>
  1362 + <active>true</active>
1323 1363 <count>2</count>
1324 1364 <class>
1325 1365 <title>ADV-NEG</title>
... ... @@ -1332,7 +1372,7 @@
1332 1372 </class>
1333 1373 </rule>
1334 1374 <rule name = "AP(ADJ-F_ADV-NEG)"><!-- tratamento do adverbio de negação modificador do adjetivo feminino (inverso) -->
1335   - <active>false</active>
  1375 + <active>true</active>
1336 1376 <count>2</count>
1337 1377 <class>
1338 1378 <title>ADJ-F</title>
... ... @@ -1345,7 +1385,7 @@
1345 1385 </class>
1346 1386 </rule>
1347 1387 <rule name = "AP(ADV-NEG_ADJ-F-P)"><!-- tratamento do adverbio de negação modificador do adjetivo feminino plural -->
1348   - <active>false</active>
  1388 + <active>true</active>
1349 1389 <count>2</count>
1350 1390 <class>
1351 1391 <title>ADV-NEG</title>
... ... @@ -1358,7 +1398,7 @@
1358 1398 </class>
1359 1399 </rule>
1360 1400 <rule name = "AP(ADJ-F-P_ADV-NEG)"><!-- tratamento do adverbio de negação modificador do adjetivo feminino plural (inverso) -->
1361   - <active>false</active>
  1401 + <active>true</active>
1362 1402 <count>2</count>
1363 1403 <class>
1364 1404 <title>ADJ-F-P</title>
... ... @@ -1371,7 +1411,7 @@
1371 1411 </class>
1372 1412 </rule>
1373 1413 <rule name = "AP(ADV-NEG_ADJ-G)"><!-- tratamento do adverbio de negação modificador do adjetivo geral -->
1374   - <active>false</active>
  1414 + <active>true</active>
1375 1415 <count>2</count>
1376 1416 <class>
1377 1417 <title>ADV-NEG</title>
... ... @@ -1384,7 +1424,7 @@
1384 1424 </class>
1385 1425 </rule>
1386 1426 <rule name = "AP(ADJ-G_ADV-NEG)"><!-- tratamento do adverbio de negação modificador do adjetivo geral (inverso) -->
1387   - <active>false</active>
  1427 + <active>true</active>
1388 1428 <count>2</count>
1389 1429 <class>
1390 1430 <title>ADJ-G</title>
... ... @@ -1397,7 +1437,7 @@
1397 1437 </class>
1398 1438 </rule>
1399 1439 <rule name = "AP(ADV-NEG_ADJ-G-P)"><!-- tratamento do adverbio de negação modificador do adjetivo geral plural -->
1400   - <active>false</active>
  1440 + <active>true</active>
1401 1441 <count>2</count>
1402 1442 <class>
1403 1443 <title>ADV-NEG</title>
... ... @@ -1410,7 +1450,7 @@
1410 1450 </class>
1411 1451 </rule>
1412 1452 <rule name = "AP(ADJ-G-P_ADV-NEG)"><!-- tratamento do adverbio de negação modificador do adjetivo geral plural (inverso) -->
1413   - <active>false</active>
  1453 + <active>true</active>
1414 1454 <count>2</count>
1415 1455 <class>
1416 1456 <title>ADJ-G-P</title>
... ...
install/linux/install.sh
... ... @@ -11,13 +11,24 @@ read -r -p &quot;Deseja fazer o download das dependências? [Y/n] &quot; response
11 11  
12 12 wget 150.165.204.30:8080/translate/linux/aelius-install.tar.gz
13 13  
  14 + MACHINE_TYPE=`uname -m`
  15 + if [ ${MACHINE_TYPE} == 'x86_64' ]; then
  16 + wget 150.165.204.30:8080/translate/linux/hunpos/x86_64/hunpos-tag
  17 + else
  18 + wget 150.165.204.30:8080/translate/linux/hunpos/i386/hunpos-tag
  19 + fi
  20 +
14 21 read -r -p "Deseja instalar as dependências? [Y/n] " response
15 22 response=${response,,} # tolower
16 23 if [[ $response =~ ^(yes|y| ) ]]; then
17 24 echo -e "\n# Extraindo...\n"
18 25 tar -xf aelius-install.tar.gz -C .
19   -
  26 + mkdir bin
  27 + mv hunpos-tag bin/
  28 + chmod 777 bin/hunpos-tag
  29 +
20 30 echo -e "# Instalando dependências...\n"
  31 + sudo apt-get update
21 32 sudo apt-get install -y python-dev python-setuptools python-pip python-yaml python-numpy python-matplotlib
22 33 sudo pip install nltk nltk_tgrep --upgrade
23 34  
... ...
src/AplicaRegras.py
... ... @@ -10,7 +10,7 @@ import platform
10 10 import re
11 11 import xml.etree.ElementTree as ET
12 12 from os.path import expanduser
13   -from os import environ
  13 +from os import environ, path
14 14 from collections import deque
15 15 from LerDicionarios import *
16 16 from Iterator import *
... ... @@ -41,6 +41,9 @@ class AplicaRegras(object):
41 41 '''
42 42 if platform.system() == 'Windows':
43 43 return ET.parse(environ.get("HOMEDRIVE")+'\\vlibras-libs\\vlibras-translate\data\\regras.xml').getroot()
  44 + elif "TRANSLATE_DATA" in environ:
  45 + arq_regras = path.join(environ.get("TRANSLATE_DATA"), "regras.xml")
  46 + return ET.parse(arq_regras).getroot()
44 47 return ET.parse(expanduser("~")+'/vlibras-translate/data/regras.xml').getroot()
45 48  
46 49 # Aplica regras morfológicas apartir do arquivo regras.xml
... ... @@ -225,14 +228,15 @@ class AplicaRegras(object):
225 228 node_pai[nodes_positions[count_temp]][0][0].set_label(newprop.text)
226 229  
227 230 elif action_text == "concate_neg":
228   - print "TODO"
229   -
  231 + token = filter(None, node_pai[nodes_positions[count_temp]].leaves())[0]
  232 + token_concate = token + "_não"
  233 + node_pai[nodes_positions[count_temp]][0][0][0] = token_concate
  234 + # TODO: PRECISA ADD NEWPROP?
230 235  
231 236 if newprop is not None:
232 237 node_pai[nodes_positions[self.count]].set_label(newprop.text)
233 238  
234 239 break
235   -
236 240 return self.converter_arv_para_lista(p_arvore)
237 241  
238 242 def adaptar_regras_morfo_arvore(self, lista, arvore):
... ... @@ -255,7 +259,10 @@ class AplicaRegras(object):
255 259  
256 260 # Corrige arvore de acordo com a lista após aplicar as regras morfológicas
257 261 for i in range(0, len(morfo)):
258   - if morfo[i] is not None and morfo[i][1] == "NTK":
  262 + #TODO: Corrigir essa verificação de FUTURO e PASSADO]
  263 + #TODO: Exclusão do nó inteiro (VBar) - Removendo palavra junto com a marcação de tempo
  264 + # EU FELIZ PASSADO -> EU FELIZ
  265 + if morfo[i] is not None and morfo[i][1] == "NTK" and morfo[i][0]:
259 266 new_node = self.gerar_no(morfo[i])
260 267 arvore[lista_pos_arv[i-1][:-3]].insert(2, new_node)
261 268 #arvore[lista_pos_arv[i-1][:-2]].insert(2, new_node)
... ... @@ -403,8 +410,8 @@ class AplicaRegras(object):
403 410 lista_simplificada = self.converter_extenso(lista_simplificada)
404 411 except:
405 412 pass
406   -
407   - return " ".join([x[0] for x in lista_simplificada])
  413 +
  414 + return lista_simplificada
408 415  
409 416  
410 417 def analisar_plural(self, token):
... ...
src/ConverteExtenso.py
... ... @@ -90,6 +90,8 @@ o resultado.
90 90 def convert_extenso(extenso):
91 91 global newToken, auxToken
92 92 extensoQuebrado = extenso.lower().split(" ")
  93 + if len(extensoQuebrado) == 1 and und.has_key(simplifica(extensoQuebrado[0])):
  94 + return extenso
93 95 nums = []
94 96 it = Iterator()
95 97 it.load(extensoQuebrado)
... ...
src/LerDicionarios.py
... ... @@ -6,8 +6,7 @@
6 6  
7 7 #LAViD - Laboratório de Aplicações de Vídeo Digital
8 8  
9   -from os.path import expanduser
10   -from os import environ
  9 +import os
11 10 import csv
12 11 import platform
13 12  
... ... @@ -44,8 +43,10 @@ class LerDicionarios(Singleton):
44 43 '''Verifica qual o SO e gera o path de onde se encontra o diretório data.
45 44 '''
46 45 if platform.system() == 'Windows':
47   - return environ.get("HOMEDRIVE") + "\\vlibras-libs\\vlibras-translate\data\\"
48   - return expanduser("~") + "/vlibras-translate/data/"
  46 + return os.environ.get("HOMEDRIVE") + "\\vlibras-libs\\vlibras-translate\data\\"
  47 + elif "TRANSLATE_DATA" in os.environ:
  48 + return os.environ.get("TRANSLATE_DATA")
  49 + return os.path.expanduser("~") + "/vlibras-translate/data"
49 50  
50 51 def carregar_dicionarios(self):
51 52 '''Realiza a leitura dos arquivos e atribui à estruturas de dicionários e sets.
... ... @@ -62,11 +63,14 @@ class LerDicionarios(Singleton):
62 63 self.carregar_verbos_ligacao()
63 64 self.carregar_verbos_muda_negacao
64 65  
  66 + def montar_diretorio(self, arquivo):
  67 + return os.path.join(self.path, arquivo)
  68 +
65 69 def carregar_excecoes_plural(self):
66 70 '''Carrega arquivo de exceções de plural.
67 71 '''
68 72 try:
69   - self.file = csv.reader(open(self.path+"excecoesPlural.csv"))
  73 + self.file = csv.reader(open(self.montar_diretorio("excecoesPlural.csv")))
70 74 except IOError, (errno, strerror):
71 75 print "I/O error(%s): %s" % (errno, strerror)
72 76 print "carregar_excecoes_plural"
... ... @@ -80,7 +84,7 @@ class LerDicionarios(Singleton):
80 84 '''Carrega arquivo de adverbios de intensidade.
81 85 '''
82 86 try:
83   - self.file = csv.reader(open(self.path+"adverbiosIntensidade.csv"), delimiter=";")
  87 + self.file = csv.reader(open(self.montar_diretorio("adverbiosIntensidade.csv")), delimiter=";")
84 88 except IOError, (errno, strerror):
85 89 print "I/O error(%s): %s" % (errno, strerror)
86 90 print "carregar_adverbios_intensidade"
... ... @@ -93,7 +97,7 @@ class LerDicionarios(Singleton):
93 97 '''Carrega arquivo de advérbios de tempo.
94 98 '''
95 99 try:
96   - self.file = csv.reader(open(self.path+"adverbiosTempo.csv"))
  100 + self.file = csv.reader(open(self.montar_diretorio("adverbiosTempo.csv")))
97 101 except IOError, (errno, strerror):
98 102 print "I/O error(%s): %s" % (errno, strerror)
99 103 print "carregar_adverbios_tempo"
... ... @@ -107,7 +111,7 @@ class LerDicionarios(Singleton):
107 111 '''Carrega arquivo de artigos a serem removidos.
108 112 '''
109 113 try:
110   - self.file = csv.reader(open(self.path+"artigos.csv"))
  114 + self.file = csv.reader(open(self.montar_diretorio("artigos.csv")))
111 115 except IOError, (errno, strerror):
112 116 print "I/O error(%s): %s" % (errno, strerror)
113 117 print "carregar_artigos"
... ... @@ -121,7 +125,7 @@ class LerDicionarios(Singleton):
121 125 '''Carrega arquivo de preposições a serem removidas.
122 126 '''
123 127 try:
124   - self.file = csv.reader(open(self.path+"preposicoes.csv"))
  128 + self.file = csv.reader(open(self.montar_diretorio("preposicoes.csv")))
125 129 except IOError, (errno, strerror):
126 130 print "I/O error(%s): %s" % (errno, strerror)
127 131 print "carregar_preposicoes"
... ... @@ -135,7 +139,7 @@ class LerDicionarios(Singleton):
135 139 '''Carrega arquivo de sinônimos.
136 140 '''
137 141 try:
138   - self.file = csv.reader(open(self.path+"sinonimos.csv"), delimiter=";")
  142 + self.file = csv.reader(open(self.montar_diretorio("sinonimos.csv")), delimiter=";")
139 143 except IOError, (errno, strerror):
140 144 print "I/O error(%s): %s" % (errno, strerror)
141 145 print "carregar_sinonimos"
... ... @@ -151,7 +155,7 @@ class LerDicionarios(Singleton):
151 155 '''Carrega arquivo dos substantivos comuns de 2 generos.
152 156 '''
153 157 try:
154   - self.file = csv.reader(open(self.path+"subs2Generos.csv"))
  158 + self.file = csv.reader(open(self.montar_diretorio("subs2Generos.csv")))
155 159 except IOError, (errno, strerror):
156 160 print "I/O error(%s): %s" % (errno, strerror)
157 161 print "carregar_subs_2_generos"
... ... @@ -165,7 +169,7 @@ class LerDicionarios(Singleton):
165 169 '''Carrega arquivo de verbos no infinitivo.
166 170 '''
167 171 try:
168   - self.file = csv.reader(open(self.path+"verbosInfinitivo.csv"), delimiter=";")
  172 + self.file = csv.reader(open(self.montar_diretorio("verbosInfinitivo.csv")), delimiter=";")
169 173 except IOError, (errno, strerror):
170 174 print "I/O error(%s): %s" % (errno, strerror)
171 175 print "carregar_verbos_infinitivo"
... ... @@ -181,7 +185,7 @@ class LerDicionarios(Singleton):
181 185 '''Carrega arquivo de verbos de ligação.
182 186 '''
183 187 try:
184   - self.file = csv.reader(open(self.path+"verbosLigacao.csv"))
  188 + self.file = csv.reader(open(self.montar_diretorio("verbosLigacao.csv")))
185 189 except IOError, (errno, strerror):
186 190 print "I/O error(%s): %s" % (errno, strerror)
187 191 print "carregar_verbos_ligacao"
... ... @@ -195,7 +199,7 @@ class LerDicionarios(Singleton):
195 199 '''Carrega arquivo de pronomes de tratamento.
196 200 '''
197 201 try:
198   - self.file = csv.reader(open(self.path+"pronomesTratamento.csv"))
  202 + self.file = csv.reader(open(self.montar_diretorio("pronomesTratamento.csv")))
199 203 except IOError, (errno, strerror):
200 204 print "I/O error(%s): %s" % (errno, strerror)
201 205 print "carregar_pronomes_tratamento"
... ... @@ -209,7 +213,7 @@ class LerDicionarios(Singleton):
209 213 '''Carrega arquivo de verbos que mudam a negação.
210 214 '''
211 215 try:
212   - self.file = csv.reader(open(self.path+"verbosMudaNegacao.csv"), delimiter=";")
  216 + self.file = csv.reader(open(self.montar_diretorio("verbosMudaNegacao.csv")), delimiter=";")
213 217 except IOError, (errno, strerror):
214 218 print "I/O error(%s): %s" % (errno, strerror)
215 219 print "carregar_verbos_muda_negacao"
... ...
src/PortGlosa.py
... ... @@ -14,43 +14,50 @@ from LerDicionarios import *
14 14  
15 15 tradutor = TraduzSentencas()
16 16 dicionario = LerDicionarios()
  17 +taxas = []
17 18  
18   -def traduzir(texto, threads=False):
  19 +def traduzir(texto, log=None, threads=False, taxa_qualidade=False):
  20 + tradutor.set_level(log) if log != None else tradutor.desativar_logging()
19 21 if texto.isspace() or texto == "":
20 22 return "ESCOLHER TEXTO CERTO"
21 23  
22 24 elif threads:
23   - return iniciar_com_threads(texto)
  25 + return iniciar_com_threads(texto, taxa_qualidade)
24 26  
25 27 else:
26   - return iniciar_sem_threads(texto)
  28 + return iniciar_sem_threads(texto, taxa_qualidade)
27 29  
28   -def iniciar_com_threads(texto):
  30 +def iniciar_com_threads(texto, taxa_qualidade):
29 31 texto_quebrado = quebrar_texto(texto)
30 32 num_threads = len(texto_quebrado)
31   - texto_traduzido = []
  33 + saidas = []
32 34 threads = []
33 35  
34 36 for i in range(num_threads):
35 37 if texto_quebrado[i] > 0 and texto_quebrado[i] != " ":
36   - threads.insert(i, ThreadTradutor(texto_quebrado[i]))
  38 + threads.insert(i, ThreadTradutor(texto_quebrado[i],taxa_qualidade))
37 39 threads[i].start()
38 40 for i in range(num_threads):
39 41 threads[i].join()
40   - texto_traduzido.append(threads[i].obter_glosa())
  42 + saidas.append(threads[i].obter_glosa())
  43 +
  44 + if taxa_qualidade:
  45 + return gerar_taxa_qualidade(saidas)
41 46  
42 47 try:
43   - return " ".join(texto_traduzido)
  48 + return " ".join(saidas)
44 49 except:
45 50 return None
46 51  
47   -def iniciar_sem_threads(texto):
  52 +def iniciar_sem_threads(texto, taxa_qualidade):
48 53 texto_quebrado = quebrar_texto(texto)
49   - texto_traduzido = []
  54 + saidas = []
50 55 for texto in texto_quebrado:
51   - glosa = tradutor.iniciar_traducao(texto)
52   - texto_traduzido.append(glosa)
53   - return " ".join(texto_traduzido)
  56 + saida = tradutor.iniciar_traducao(texto, taxa_qualidade)
  57 + saidas.append(saida)
  58 + if taxa_qualidade:
  59 + return gerar_taxa_qualidade(saidas)
  60 + return " ".join(saidas)
54 61  
55 62 def quebrar_texto(texto):
56 63 if '.' not in texto:
... ... @@ -69,9 +76,24 @@ def quebrar_texto(texto):
69 76 lista_texto = []
70 77 continue
71 78 if lista_texto:
72   - sentencas.append( " ".join(lista_texto))
  79 + sentencas.append(" ".join(lista_texto))
73 80 return sentencas
74 81  
  82 +def gerar_taxa_qualidade(lista_saidas):
  83 + soma_taxas = 0
  84 + quant_analise_sintatica = 0
  85 + glosas = []
  86 + for saida in lista_saidas:
  87 + glosas.append(saida['glosa'])
  88 + soma_taxas += saida['taxa']
  89 + if saida['sintatica'] is True:
  90 + quant_analise_sintatica += 1
  91 +
  92 + taxa_sintatica = (float(quant_analise_sintatica)/len(lista_saidas)) * 0.20
  93 + taxa_sentenca = (float(soma_taxas)/len(lista_saidas)) * 0.80
  94 + return {'glosa':" ".join(glosas), 'taxa_qualidade': float("%.2f" % (taxa_sintatica+taxa_sentenca))}
  95 +
  96 +
75 97 def ajuda():
76 98 #TODO: Adicionar um pequeno tuto aqui
77 99 print "Help"
... ...
src/ThreadTradutor.py
... ... @@ -12,7 +12,7 @@ from threading import Thread
12 12 class ThreadTradutor(Thread):
13 13 '''Thread que inicia uma tradução'''
14 14  
15   - def __init__(self, sentenca):
  15 + def __init__(self, sentenca, taxa):
16 16 ''' Recebe o texto a ser traduzido e o atribui a uma variável.
17 17 Além disso, instancia variável que será armazenada a glosa e a classe responsável pelo processo de tradução.
18 18 '''
... ... @@ -20,11 +20,12 @@ class ThreadTradutor(Thread):
20 20 self.sentenca = sentenca
21 21 self.glosa = ""
22 22 self.tradutor = TraduzSentencas()
  23 + self.taxa_qualidade = taxa
23 24  
24 25 def run(self):
25 26 ''' Metódo executado ao 'startar' a Thread. É responsável por iniciar a tradução passando o texto como parâmetro.
26 27 '''
27   - self.glosa = self.tradutor.iniciar_traducao(self.sentenca)
  28 + self.glosa = self.tradutor.iniciar_traducao(self.sentenca, self.taxa_qualidade)
28 29  
29 30 def obter_glosa(self):
30 31 ''' Obtém a glosa após o processo de tradução.
... ...
src/TraduzSentencas.py
1   -#!/usr/bin/python
  1 + #!/usr/bin/python
2 2 # -*- coding: utf-8 -*-
3 3  
4 4 #Autor: Erickson Silva
... ... @@ -9,7 +9,12 @@
9 9 import alexp
10 10 from AplicaRegras import *
11 11 import logging
  12 +import logging.handlers
12 13 import traceback
  14 +import subprocess
  15 +import re, string
  16 +import getopt
  17 +import sys
13 18  
14 19 class TraduzSentencas(object):
15 20 '''Realiza a tradução do texto em português para glosa
... ... @@ -19,40 +24,88 @@ class TraduzSentencas(object):
19 24 '''Instancia os aplicadores de regras e sinônimos.
20 25 '''
21 26 self.aplic_regras = AplicaRegras()
22   - #logging.basicConfig(filename='translate.log',
23   - # format='%(asctime)s - %(levelname)s:\n\n%(message)s\n\n\n##############################################\n\n',
24   - # level=logging.ERROR)
25   -
26   - def iniciar_traducao(self, sentenca):
  27 + self.check_level()
  28 +
  29 + def iniciar_traducao(self, sentenca, taxa=False):
27 30 '''Metódo responsável por executar todos componentes necessários para a geração da glosa.
28 31 '''
29 32 try:
  33 + has_sintatica = True
30 34 analise_sintatica = alexp.run(sentenca)
31 35 except Exception as ex:
32   - #self.salvar_log(str(traceback.format_exc()))
  36 + self.salvar_log(str(traceback.format_exc()))
33 37 analise_sintatica = None
  38 + has_sintatica = False
34 39  
35 40 analise_morfologica = alexp.getAnaliseMorfologica()
36   -
  41 +
37 42 if (isinstance(analise_sintatica,type(None))):
38   - #print "# ANÁLISE MORFOLÓGICA"
39 43 regras_aplicadas = self.aplic_regras.aplicar_regras_morfo(analise_morfologica)
40 44 else:
41   - #print "# ANÁLISE SINTÁTICA"
42 45 try:
43 46 regras_aplicadas = self.aplic_regras.aplicar_regras_sint(analise_morfologica, analise_sintatica)
44 47 except:
45 48 regras_aplicadas = self.aplic_regras.aplicar_regras_morfo(analise_morfologica)
46 49  
47 50 sentenca_corrigida = self.aplic_regras.simplificar_sentenca(regras_aplicadas)
48   - sentenca_sem_acentos = self.aplic_regras.remover_acento(sentenca_corrigida)
  51 + glosa = " ".join([x[0] for x in sentenca_corrigida])
  52 +
  53 + if glosa:
  54 + if taxa:
  55 + taxa_qualidade = self.gerar_metrica_qualidade(sentenca_corrigida)
  56 + return {'glosa':glosa_sem_acentos, 'taxa':taxa_qualidade, 'sintatica':has_sintatica}
  57 + return glosa.upper().encode('utf-8')
  58 + return "TEXTO ERRADO ESCOLHER OUTRO"
49 59  
50   - if sentenca_sem_acentos:
51   - return sentenca_sem_acentos.upper().encode('utf-8')
52   - return "TEXTO ERRADO ESCOLHER OUTRO"
53 60  
54 61 def salvar_log(self, erro):
55 62 '''Salva traceback de uma excessão do analisador sintático
56 63 '''
57   - logging.error(erro)
58   -
  64 + logger = logging.getLogger('error-feedback')
  65 + logger.propagate = False
  66 + logger.error(erro)
  67 +
  68 + def criar_logger_error(self):
  69 + error_log = logging.getLogger('error-feedback')
  70 + error_log.setLevel(logging.ERROR)
  71 + ##print os.path.dirname(__file__) -- Salvar no direitorio do arquivo .py?
  72 + error_handler = logging.handlers.RotatingFileHandler('/var/tmp/vlibras-translate.log', maxBytes=1024, backupCount=5)
  73 + formatter = logging.Formatter('%(asctime)s - %(levelname)s:\n\n%(message)s\n\n\n##############################################\n\n')
  74 + error_handler.setFormatter(formatter)
  75 + error_log.addHandler(error_handler)
  76 +
  77 + def check_level(self):
  78 + for opt in sys.argv[1:]:
  79 + if "--log" in opt:
  80 + self.set_level(opt[6:])
  81 + return
  82 + self.desativar_logging()
  83 +
  84 + def set_level(self, level):
  85 + numeric_level = getattr(logging, level.upper(), None)
  86 + if not isinstance(numeric_level, int):
  87 + raise ValueError('Nível de log inválido: %s' % level)
  88 + logging.disable(logging.NOTSET)
  89 + logging.getLogger().setLevel(numeric_level)
  90 + if numeric_level == 40 or numeric_level == 10:
  91 + self.criar_logger_error()
  92 +
  93 + def desativar_logging(self):
  94 + logging.disable(logging.DEBUG)
  95 + logging.disable(logging.INFO)
  96 + logging.disable(logging.WARNING)
  97 + logging.disable(logging.ERROR)
  98 + logging.disable(logging.CRITICAL)
  99 +
  100 + def gerar_metrica_qualidade(self, lista):
  101 + #TODO: resolver path do arquivo
  102 + arqSinais = open("sinais.txt", "r").read().split()
  103 + quantSinaisTotal = len(lista)
  104 + quantSinaisEncontradas = 0
  105 + for x in lista:
  106 + if x[0].upper()+".anim" in arqSinais:
  107 + quantSinaisEncontradas += 1
  108 + else:
  109 + if x[1] == "NPR":
  110 + quantSinaisTotal-=1
  111 + return float(quantSinaisEncontradas)/quantSinaisTotal
... ...
src/alexp.py
... ... @@ -29,12 +29,11 @@
29 29 """
30 30 import re,nltk,platform, time, random
31 31 from os.path import expanduser
32   -from os import environ
  32 +from os import environ, path
33 33 from Aelius.Extras import carrega
34 34 from Aelius import AnotaCorpus
35 35 from unicodedata import normalize
36 36  
37   -
38 37 sentenca_anotada=""
39 38 sleep_times=[0.1,0.2]
40 39  
... ... @@ -46,7 +45,6 @@ def toqueniza(s):
46 45  
47 46 def getAnaliseMorfologica():
48 47 return sentenca_anotada
49   - #return [list(x) for x in sentenca_anotada]
50 48  
51 49 def etiquetaSentenca(s):
52 50 """Aplica um dos etiquetadores do Aelius na etiquetagem da sentença dada como lista de tokens.
... ... @@ -56,10 +54,17 @@ def etiquetaSentenca(s):
56 54 while (anotada[0][1] is None):
57 55 time.sleep(random.choice(sleep_times))
58 56 anotada = AnotaCorpus.anota_sentencas([s],etiquetador,"hunpos")[0]
59   - #anotada[0] = (anotada[0][0].lower(), anotada[0][1])
60   - #return anotada
  57 + regex = re.compile('[%s]' % re.escape('!"#&\'()*+,-./:;<=>?@[\\]^_`{|}~'))
61 58 tag_punctuation = [".",",","QT","("]
62   - return [[x[0].lower(),x[1]] for x in anotada if x[1] not in tag_punctuation]
  59 + anotada_corrigida = []
  60 + for x in anotada:
  61 + if x[1] not in tag_punctuation:
  62 + if x[1] == "NUM":
  63 + anotada_corrigida.append(x)
  64 + continue
  65 + tupla = [regex.sub('',x[0]).lower(),x[1]]
  66 + if tupla[0] != "": anotada_corrigida.append(tupla)
  67 + return anotada_corrigida
63 68  
64 69 def geraEntradasLexicais(lista):
65 70 """Gera entradas lexicais no formato CFG do NLTK a partir de lista de pares constituídos de tokens e suas etiquetas.
... ... @@ -88,8 +93,9 @@ def encontraArquivo():
88 93 so = platform.system()
89 94 if so == 'Windows':
90 95 return environ.get("HOMEDRIVE") + "\\vlibras-libs\\vlibras-translate\data\cfg.syn.nltk"
91   - else:
92   - return expanduser("~") + "/vlibras-translate/data/cfg.syn.nltk"
  96 + elif "TRANSLATE_DATA" in environ:
  97 + return path.join(environ.get("TRANSLATE_DATA"), "cfg.syn.nltk")
  98 + return expanduser("~") + "/vlibras-translate/data/cfg.syn.nltk"
93 99  
94 100 def extraiSintaxe():
95 101 """Extrai gramática armazenada em arquivo cujo caminho é definido relativamente ao diretório nltk_data.
... ... @@ -107,7 +113,7 @@ def analisaSentenca(sentenca):
107 113 """Retorna lista de árvores de estrutura sintagmática para a sentença dada sob a forma de uma lista de tokens, com base na gramática CFG cujo caminho é especificado como segundo argumento da função. Esse caminho é relativo à pasta nltk_data da instalação local do NLTK. A partir da etiquetagem morfossintática da sentença são geradas entradas lexicais que passam a integrar a gramática CFG. O caminho da gramática e o parser gerado são armazenados como tupla na variável ANALISADORES.
108 114 """
109 115 parser=constroiAnalisador(sentenca)
110   - codificada=[removeAcento(w).encode("utf-8") for w in sentenca]
  116 + codificada=[removeAcento(w[0]).encode("utf-8") for w in sentenca_anotada]
111 117 trees=parser.parse_one(codificada)
112 118 return trees
113 119  
... ...