mirror of https://github.com/interlegis/sapl.git
Browse Source
- implementação dos botões excluir na edição de dispositivos - implementação de perfis estruturais de textos normativos - refatoração do algoritmo de seleção de provaveis inserções - refatoração do algoritimo de inserção - parte da implementação do parser básico para import de arquivos odfpull/10/head
LeandroRoberto
9 years ago
19 changed files with 1002 additions and 152 deletions
@ -0,0 +1,327 @@ |
|||
import re |
|||
|
|||
from odf.element import Node, Text |
|||
from odf.opendocument import load |
|||
from odf.table import Table, TableCell, TableRow |
|||
from odf.text import (List, ListHeader, ListItem, ListLevelStyleBullet, |
|||
ListLevelStyleNumber, ListStyle, Note) |
|||
|
|||
from sapl import utils |
|||
|
|||
|
|||
class Parser(object): |
|||
|
|||
parser_list = [] |
|||
|
|||
def parser(self, _filepath): |
|||
|
|||
self.filepath = _filepath |
|||
|
|||
return self.re_parser() |
|||
|
|||
def re_parser(self): |
|||
|
|||
self.parser_list = [] |
|||
|
|||
# odt identificado pela extensão ou teste caso o arquivo sem extensão |
|||
if self.filepath.endswith('.odt') or\ |
|||
not re.search(r"(\w+)\.(\w+)", self.filepath): |
|||
|
|||
try: |
|||
odtparser = OdtParser() |
|||
|
|||
self.parser_list = odtparser.parser(self.filepath) |
|||
|
|||
return self.parser_list |
|||
except Exception as e: |
|||
print(e) |
|||
# TODO: Continue para outros formatos |
|||
pass |
|||
|
|||
# doc identificado pela extensão ou teste caso o arquivo sem extensão |
|||
if self.filepath.endswith(('.doc', 'docx')) or\ |
|||
not re.search(r"(\w+)\.(\w+)", self.filepath): |
|||
|
|||
try: |
|||
# TODO |
|||
return [] |
|||
except Exception as e: |
|||
# TODO: Continue para outros formatos |
|||
pass |
|||
|
|||
return [] |
|||
|
|||
def _reduce_terms(self, _nodes=None, level=0): |
|||
print(level) |
|||
if not _nodes: |
|||
nodes = self.parser_list |
|||
else: |
|||
nodes = _nodes |
|||
|
|||
fstr = True |
|||
i = -1 |
|||
for nd in nodes: |
|||
i += 1 |
|||
# print(nd) |
|||
|
|||
if not _nodes: |
|||
fstr = False |
|||
if nd[0] == 'table:table': |
|||
continue |
|||
|
|||
if isinstance(nd, list): |
|||
fstr = False |
|||
nodes[i] = self._reduce_terms(nd, level=level + 1) |
|||
|
|||
if fstr: |
|||
return ' '.join(nodes) |
|||
return nodes |
|||
|
|||
|
|||
class OdtParser(Parser): |
|||
FNC1 = '1' |
|||
FNCI = 'I' |
|||
FNCi = 'i' |
|||
FNCA = 'A' |
|||
FNCa = 'a' |
|||
FNC8 = '*' |
|||
FNCN = 'N' |
|||
|
|||
def re_parser(self): |
|||
|
|||
self.textdoc = load(self.filepath) |
|||
self.level_list = 0 |
|||
self.control_list = {} |
|||
|
|||
# mm = ODF2MoinMoin(self.filepath) |
|||
# self.parser_list = [mm.toString(), ] |
|||
|
|||
self.parser_list = self._import_itens(self.textdoc.text, level=0) |
|||
|
|||
# self._reduce_terms() |
|||
|
|||
return self.parser_list |
|||
|
|||
def _import_itens(self, element, level=0): |
|||
try: |
|||
result = [] |
|||
for el in element.childNodes: |
|||
print(level, el.tagName) |
|||
_r = '' |
|||
if el.tagName == 'Text': |
|||
_r = str(el) |
|||
else: |
|||
if el.isInstanceOf(Note): |
|||
continue |
|||
elif el.isInstanceOf(Table): |
|||
_r = self._import_table(el, level=level + 1) |
|||
elif el.isInstanceOf(List): |
|||
_r = self._import_list(el, level=level + 1) |
|||
# elif el.isInstanceOf(P): |
|||
# _r = [self.extractText(el),] |
|||
elif el.hasChildNodes(): |
|||
_r = self._import_itens(el, level=level + 1) |
|||
else: |
|||
_r = str(el) |
|||
|
|||
if _r: |
|||
if isinstance(_r, str): |
|||
result += [_r, ] |
|||
else: |
|||
result += _r |
|||
|
|||
return result |
|||
except Exception as e: |
|||
print(e) |
|||
|
|||
def _import_table(self, element, level=0): |
|||
result = '' |
|||
print(level) |
|||
try: |
|||
if element.isInstanceOf(Table): |
|||
result += '<table width="100%">' |
|||
|
|||
for el in element.childNodes: |
|||
_r = '' |
|||
if isinstance(el, Text): |
|||
_r = str(el) |
|||
else: |
|||
if el.isInstanceOf(TableRow): |
|||
_r = self._import_table(el, level=level + 1) |
|||
_r = '<tr>%s</tr>' % (''.join(_r)) |
|||
result += ''.join(_r) |
|||
elif el.isInstanceOf(TableCell): |
|||
_r = self._import_table(el, level=level + 1) |
|||
if el.getAttribute('numberrowsspanned'): |
|||
_r = '<td rowspan="%s">%s</td>' % ( |
|||
el.getAttribute('numberrowsspanned'), |
|||
''.join(_r)) |
|||
elif el.getAttribute('numbercolumnsspanned'): |
|||
_r = '<td colspan="%s">%s</td>' % ( |
|||
el.getAttribute('numbercolumnsspanned'), |
|||
''.join(_r)) |
|||
else: |
|||
_r = '<td>%s</td>' % (''.join(_r)) |
|||
|
|||
result += ''.join(_r) |
|||
else: |
|||
_r = self.extractText(el) |
|||
# _r = self._reduce_terms(_r) |
|||
if isinstance(_r, list): |
|||
result += '<br>'.join(_r) |
|||
else: |
|||
if _r: |
|||
result += _r + '<br>' |
|||
|
|||
if element.isInstanceOf(Table): |
|||
result += '</table>' |
|||
|
|||
return [result, ] |
|||
except Exception as e: |
|||
print(e) |
|||
|
|||
def _import_list(self, element, level=0): |
|||
self.level_list += 1 |
|||
result = [] |
|||
print(level) |
|||
|
|||
numsufixo = '' |
|||
numformat = '' |
|||
startvalue = '' |
|||
|
|||
count_list_item = 0 |
|||
|
|||
try: |
|||
if element.isInstanceOf(List): |
|||
_stylename = element.getAttribute('stylename') |
|||
|
|||
if _stylename: |
|||
self.stylename = _stylename |
|||
|
|||
liststyles = self.textdoc.getElementsByType(ListStyle) |
|||
|
|||
for liststyle in liststyles: |
|||
if liststyle.getAttribute('name') == self.stylename: |
|||
break |
|||
|
|||
stylesnumbers = liststyle.getElementsByType( |
|||
ListLevelStyleNumber) |
|||
|
|||
for item in stylesnumbers: |
|||
if item.getAttribute('level') == str(self.level_list): |
|||
numsufixo = item.getAttribute('numsuffix') or '' |
|||
numformat = item.getAttribute('numformat') or '' |
|||
startvalue = item.getAttribute('startvalue') or '' |
|||
break |
|||
|
|||
if not numformat: |
|||
stylesbullets = liststyle.getElementsByType( |
|||
ListLevelStyleBullet) |
|||
for item in stylesbullets: |
|||
if item.getAttribute('level') == str(self.level_list): |
|||
numformat = '*' |
|||
break |
|||
|
|||
_id = element.getAttribute('id') |
|||
if _id: |
|||
self.id_last_list = _id |
|||
|
|||
if self.id_last_list not in self.control_list: |
|||
self.control_list[self.id_last_list] = [0, ] * 10 |
|||
|
|||
if _id: |
|||
if not element.getAttribute('continuelist') and\ |
|||
self.level_list == 1: |
|||
self.control_list[self.id_last_list] = [0, ] * 10 |
|||
|
|||
except Exception as e: |
|||
print(e) |
|||
|
|||
try: |
|||
flag_first = True |
|||
for el in element.childNodes: |
|||
prefixo = '' |
|||
if isinstance(el, Text): |
|||
_r = [str(el), ] |
|||
else: |
|||
if el.isInstanceOf(ListHeader) or\ |
|||
el.isInstanceOf(ListItem): |
|||
|
|||
if startvalue and flag_first: |
|||
self.control_list[self.id_last_list][ |
|||
self.level_list - 1] = int(startvalue) - 1 |
|||
flag_first = False |
|||
|
|||
self.control_list[self.id_last_list][ |
|||
self.level_list - 1] += 1 |
|||
count_list_item = self.control_list[self.id_last_list][ |
|||
self.level_list - 1] |
|||
|
|||
if numformat == OdtParser.FNC1: |
|||
prefixo = str(count_list_item) |
|||
elif numformat == OdtParser.FNCI: |
|||
prefixo = utils.int_to_roman(count_list_item) |
|||
elif numformat == OdtParser.FNCi: |
|||
prefixo = utils.int_to_roman( |
|||
count_list_item).lower() |
|||
elif numformat == OdtParser.FNCA: |
|||
prefixo = utils.int_to_letter(count_list_item) |
|||
elif numformat == OdtParser.FNCa: |
|||
prefixo = utils.int_to_letter( |
|||
count_list_item).lower() |
|||
elif numformat == OdtParser.FNC8: |
|||
prefixo = '*' |
|||
else: |
|||
prefixo = str(count_list_item) |
|||
|
|||
prefixo += numsufixo |
|||
|
|||
_r = self._import_itens(el, level=level + 1) |
|||
|
|||
if _r: |
|||
if prefixo: |
|||
_r[0] = '%s %s' % (prefixo, _r[0]) |
|||
result += _r |
|||
else: |
|||
result += _r |
|||
|
|||
self.level_list -= 1 |
|||
return result |
|||
|
|||
except Exception as e: |
|||
print(e) |
|||
|
|||
def extractText(self, odfElement): |
|||
""" Extract text content from an Element, with whitespace represented |
|||
properly. Returns the text, with tabs, spaces, and newlines |
|||
correctly evaluated. This method recursively descends through the |
|||
children of the given element, accumulating text and "unwrapping" |
|||
<text:s>, <text:tab>, and <text:line-break> elements along the way. |
|||
""" |
|||
result = [] |
|||
|
|||
if len(odfElement.childNodes) != 0: |
|||
for child in odfElement.childNodes: |
|||
if child.nodeType == Node.TEXT_NODE: |
|||
result.append(child.data) |
|||
elif child.nodeType == Node.ELEMENT_NODE: |
|||
subElement = child |
|||
tagName = subElement.qname |
|||
if tagName == (u"urn:oasis:names:tc:opendocument:xmlns:" + |
|||
"text:1.0", u"line-break"): |
|||
result.append("\n") |
|||
elif tagName == (u"urn:oasis:names:tc:opendocument:" + |
|||
"xmlns:text:1.0", u"tab"): |
|||
result.append("\t") |
|||
elif tagName == (u"urn:oasis:names:tc:opendocument:" + |
|||
"xmlns:text:1.0", u"s"): |
|||
c = subElement.getAttribute('c') |
|||
if c: |
|||
spaceCount = int(c) |
|||
else: |
|||
spaceCount = 1 |
|||
|
|||
result.append(" " * spaceCount) |
|||
else: |
|||
result.append(self.extractText(subElement)) |
|||
return ''.join(result) |
@ -0,0 +1,24 @@ |
|||
# -*- coding: utf-8 -*- |
|||
from __future__ import unicode_literals |
|||
|
|||
from django.db import migrations, models |
|||
|
|||
|
|||
class Migration(migrations.Migration): |
|||
|
|||
dependencies = [ |
|||
('compilacao', '0014_auto_20151107_1836'), |
|||
] |
|||
|
|||
operations = [ |
|||
migrations.AddField( |
|||
model_name='tipodispositivo', |
|||
name='dispositivo_de_alteracao', |
|||
field=models.BooleanField(choices=[(True, 'Sim'), (False, 'Não')], default=False, verbose_name='Dispositivo de Alteração'), |
|||
), |
|||
migrations.AlterField( |
|||
model_name='tipodispositivorelationship', |
|||
name='filho_permitido', |
|||
field=models.ForeignKey(related_name='possiveis_pais', to='compilacao.TipoDispositivo'), |
|||
), |
|||
] |
@ -0,0 +1,48 @@ |
|||
# -*- coding: utf-8 -*- |
|||
from __future__ import unicode_literals |
|||
|
|||
from django.db import migrations, models |
|||
import datetime |
|||
from django.utils.timezone import utc |
|||
|
|||
|
|||
class Migration(migrations.Migration): |
|||
|
|||
dependencies = [ |
|||
('compilacao', '0015_auto_20151115_2310'), |
|||
] |
|||
|
|||
operations = [ |
|||
migrations.CreateModel( |
|||
name='PerfilEstruturalTextosNormativos', |
|||
fields=[ |
|||
('id', models.AutoField(auto_created=True, serialize=False, primary_key=True, verbose_name='ID')), |
|||
('nome', models.CharField(max_length=50, verbose_name='Nome')), |
|||
], |
|||
options={ |
|||
'verbose_name_plural': 'Perfis Estruturais de Textos Normativos', |
|||
'verbose_name': 'Perfil Estrutural de Textos Normativos', |
|||
}, |
|||
), |
|||
migrations.RemoveField( |
|||
model_name='dispositivo', |
|||
name='timestamp', |
|||
), |
|||
migrations.AddField( |
|||
model_name='dispositivo', |
|||
name='created', |
|||
field=models.DateTimeField(default=datetime.datetime(2015, 11, 19, 11, 49, 55, 455058, tzinfo=utc), auto_now_add=True, verbose_name='created'), |
|||
preserve_default=False, |
|||
), |
|||
migrations.AddField( |
|||
model_name='dispositivo', |
|||
name='modified', |
|||
field=models.DateTimeField(auto_now=True, default=datetime.datetime(2015, 11, 19, 11, 50, 5, 86839, tzinfo=utc), verbose_name='modified'), |
|||
preserve_default=False, |
|||
), |
|||
migrations.AddField( |
|||
model_name='tipodispositivorelationship', |
|||
name='perfil', |
|||
field=models.ForeignKey(blank=True, related_name='+', null=True, default=None, to='compilacao.PerfilEstruturalTextosNormativos'), |
|||
), |
|||
] |
@ -0,0 +1,28 @@ |
|||
# -*- coding: utf-8 -*- |
|||
from __future__ import unicode_literals |
|||
|
|||
from django.db import migrations, models |
|||
|
|||
|
|||
class Migration(migrations.Migration): |
|||
|
|||
dependencies = [ |
|||
('compilacao', '0016_auto_20151119_0950'), |
|||
] |
|||
|
|||
operations = [ |
|||
migrations.AddField( |
|||
model_name='perfilestruturaltextosnormativos', |
|||
name='padrao', |
|||
field=models.BooleanField(verbose_name='Padrão', choices=[(True, 'Sim'), (False, 'Não')], default=False), |
|||
), |
|||
migrations.AlterField( |
|||
model_name='tipodispositivorelationship', |
|||
name='perfil', |
|||
field=models.ForeignKey(to='compilacao.PerfilEstruturalTextosNormativos'), |
|||
), |
|||
migrations.AlterUniqueTogether( |
|||
name='tipodispositivorelationship', |
|||
unique_together=set([('pai', 'filho_permitido', 'perfil')]), |
|||
), |
|||
] |
@ -0,0 +1,23 @@ |
|||
# -*- coding: utf-8 -*- |
|||
from __future__ import unicode_literals |
|||
|
|||
from django.db import migrations, models |
|||
|
|||
|
|||
class Migration(migrations.Migration): |
|||
|
|||
dependencies = [ |
|||
('compilacao', '0017_auto_20151119_1035'), |
|||
] |
|||
|
|||
operations = [ |
|||
migrations.RemoveField( |
|||
model_name='tipodispositivo', |
|||
name='quantidade_permitida', |
|||
), |
|||
migrations.AddField( |
|||
model_name='tipodispositivorelationship', |
|||
name='quantidade_permitida', |
|||
field=models.IntegerField(default=-1, verbose_name='Quantidade permitida nesta relação'), |
|||
), |
|||
] |
@ -0,0 +1,20 @@ |
|||
# -*- coding: utf-8 -*- |
|||
from __future__ import unicode_literals |
|||
|
|||
from django.db import migrations, models |
|||
|
|||
|
|||
class Migration(migrations.Migration): |
|||
|
|||
dependencies = [ |
|||
('compilacao', '0018_auto_20151119_1052'), |
|||
] |
|||
|
|||
operations = [ |
|||
migrations.AddField( |
|||
model_name='perfilestruturaltextosnormativos', |
|||
name='sigla', |
|||
field=models.CharField(max_length=10, verbose_name='Sigla', default='LC95'), |
|||
preserve_default=False, |
|||
), |
|||
] |
@ -0,0 +1,20 @@ |
|||
# -*- coding: utf-8 -*- |
|||
from __future__ import unicode_literals |
|||
|
|||
from django.db import migrations, models |
|||
|
|||
|
|||
class Migration(migrations.Migration): |
|||
|
|||
dependencies = [ |
|||
('compilacao', '0019_auto_20151119_1120'), |
|||
] |
|||
|
|||
operations = [ |
|||
migrations.AlterField( |
|||
model_name='perfilestruturaltextosnormativos', |
|||
name='sigla', |
|||
field=models.CharField( |
|||
max_length=10, verbose_name='Sigla', unique=True), |
|||
), |
|||
] |
@ -0,0 +1,23 @@ |
|||
# -*- coding: utf-8 -*- |
|||
from __future__ import unicode_literals |
|||
|
|||
from django.db import migrations, models |
|||
|
|||
|
|||
class Migration(migrations.Migration): |
|||
|
|||
dependencies = [ |
|||
('compilacao', '0020_auto_20151119_1126'), |
|||
] |
|||
|
|||
operations = [ |
|||
migrations.AlterModelOptions( |
|||
name='perfilestruturaltextosnormativos', |
|||
options={'verbose_name': 'Perfil Estrutural de Textos Normativos', 'verbose_name_plural': 'Perfis Estruturais de Textos Normativos', 'ordering': ['-padrao', 'sigla']}, |
|||
), |
|||
migrations.AddField( |
|||
model_name='tipodispositivorelationship', |
|||
name='permitir_variacao', |
|||
field=models.BooleanField(choices=[(True, 'Sim'), (False, 'Não')], verbose_name='Permitir Variação Numérica', default=True), |
|||
), |
|||
] |
Loading…
Reference in new issue