Browse Source

Limpeza inicial para migração para django 3

unstable/3.0
Sesostris Vieira 4 years ago
parent
commit
759b950793
  1. 26
      Vagrantfile
  2. 29
      bin/run_sigi
  3. 42
      conftest.py
  4. 17
      etc/apache/sites-available/sigi.erb
  5. BIN
      etc/data/ibge/geoftp.ibge.gov.br/organizacao_territorial/divisao_territorial/2009/dtb_05_05_2009.zip
  6. 56
      etc/data/ibge/leiame.txt
  7. 43
      etc/data/ibge/sigi-import-ibge-2009.py_DOES_NOT_COMPILE
  8. 179
      etc/data/ibge/sigi-import-ibge-2009.sh
  9. 137
      etc/data/ibge/sigi_ibge_import.mesorregiao.csv
  10. 558
      etc/data/ibge/sigi_ibge_import.microrregiao.csv
  11. 5565
      etc/data/ibge/sigi_ibge_import.municipio.csv
  12. 5
      etc/data/ibge/sigi_ibge_import.regiao.csv
  13. 27
      etc/data/ibge/sigi_ibge_import.uf.csv
  14. 5565
      etc/data/ibge_pop2008.csv
  15. 439
      etc/migracao/migra.py
  16. 31
      etc/nginx/sites-available/sigi.vhost
  17. 5
      etc/supervisor/conf.d/sigi.conf
  18. 39
      install.sh
  19. 20
      manage.py
  20. 13
      puppet/bootstrap.sh
  21. 212
      puppet/manifests/site.pp
  22. 23
      puppet/puppet_module_install_from_github.sh
  23. 9
      pytest.ini
  24. 8
      requirements/dev-requirements.txt
  25. 7
      requirements/observacoes.txt
  26. 27
      requirements/requirements.txt
  27. 10
      requirements/test-requirements.txt
  28. 8
      setup.py
  29. 66
      sigi/apps/contatos/admin.py
  30. 124
      sigi/apps/contatos/management/commands/importa_mesomicro.py
  31. 12
      sigi/apps/contatos/migrations/0001_initial.py
  32. 6
      sigi/apps/contatos/migrations/0002_auto_20151104_0810.py
  33. 364
      sigi/apps/contatos/models.py
  34. 9
      sigi/apps/utils/__init__.py
  35. 212
      sigi/apps/utils/filters.py
  36. 8
      sigi/settings/__init__.py
  37. 232
      sigi/settings/base.py
  38. 28
      sigi/settings/dev.py
  39. 61
      sigi/urls.py
  40. 6
      sigi/wsgi.py
  41. 12
      templates/404.html
  42. 12
      templates/500.html
  43. 19
      templates/503.html
  44. 16
      templates/admin/actions.html
  45. 10
      templates/admin/app_index.html
  46. 204
      templates/admin/base.html
  47. 62
      templates/admin/base_site.html
  48. 98
      templates/admin/carrinho.html
  49. 121
      templates/admin/change_list.html
  50. 64
      templates/admin/login.html
  51. 25
      templates/admin/search_form.html
  52. 33
      templates/admin/tabs_style.html
  53. 20
      templates/base_change_form.html
  54. 56
      templates/base_mobile.html
  55. 108
      templates/base_report.html
  56. 18
      templates/change_form_with_report_and_labels.html
  57. 10
      templates/change_list_with_cart.html
  58. 5
      templates/clear_all_filter.html
  59. 36
      templates/index.html
  60. 16
      templates/mobile/404.html
  61. 92
      templates/snippets/modules/charts-convenios.html
  62. 69
      templates/snippets/modules/resumo_convenios.html
  63. 38
      templates/snippets/modules/resumo_seit.html

26
Vagrantfile

@ -1,26 +0,0 @@
# -*- mode: ruby -*-
# vi: set ft=ruby :
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.box = "ubuntu/trusty64"
config.vm.network :forwarded_port, guest: 80, host: 8080
config.vm.provision :shell, :path => "puppet/bootstrap.sh"
# XXX Usando provisoriamente o modulo oficial ate que sincronizemos nosso repo
# XXX descomentar este trecho entao
# config.vm.provision :shell,
# :path => "puppet/puppet_module_install_from_github.sh",
# :args => "jfryman-nginx interlegis/puppet-nginx"
config.vm.provision :puppet do |puppet|
puppet.manifests_path = "puppet/manifests"
puppet.manifest_file = "site.pp"
end
end

29
bin/run_sigi

@ -1,29 +0,0 @@
#!/bin/bash
NAME="sigi"
DJANGODIR=/srv/sigi
VENVDIR=/srv/.virtualenvs/sigi/bin
SOCKFILE=/var/run/sigi/sigi.sock
USER=sigi
GROUP=sigi
NUM_WORKERS=3 # = 2 * CPUs + 1
DJANGO_SETTINGS_MODULE=sigi.settings
DJANGO_WSGI_MODULE=sigi.wsgi
echo "Starting $NAME as `whoami`"
cd $DJANGODIR
export DJANGO_SETTINGS_MODULE=$DJANGO_SETTINGS_MODULE
export PYTHONPATH=$DJANGODIR:$PYTHONPATH
RUNDIR=$(dirname $SOCKFILE)
test -d $RUNDIR || mkdir -p $RUNDIR
exec ${VENVDIR}/gunicorn ${DJANGO_WSGI_MODULE}:application \
--name $NAME \
--workers $NUM_WORKERS \
--user=$USER --group=$GROUP \
--log-level=debug \
--timeout=180 \
--graceful-timeout=180 \
--bind=unix:$SOCKFILE

42
conftest.py

@ -1,42 +0,0 @@
# -*- coding: utf-8 -*-
import pytest
from django_webtest import DjangoTestApp, WebTestMixin
DEFAULT_MARK = object()
class SigiTestApp(DjangoTestApp):
def __init__(self, extra_environ=None, relative_to=None, default_user=None):
super(SigiTestApp, self).__init__(extra_environ, relative_to)
self.default_user = default_user
def get(self, url, params=None, headers=None, extra_environ=None,
status=None, expect_errors=False, user=DEFAULT_MARK, auto_follow=True,
content_type=None, **kwargs):
# note we altered the default values for user and auto_follow
if user is DEFAULT_MARK: # a trick to allow explicit user=None
user = self.default_user
return super(SigiTestApp, self).get(url, params, headers, extra_environ,
status, expect_errors, user, auto_follow,
content_type, **kwargs)
@pytest.fixture(scope='function')
def app(request, admin_user):
"""WebTest's TestApp.
Patch and unpatch settings before and after each test.
WebTestMixin, when used in a unittest.TestCase, automatically calls
_patch_settings() and _unpatchsettings.
source: https://gist.github.com/magopian/6673250
"""
wtm = WebTestMixin()
wtm._patch_settings()
request.addfinalizer(wtm._unpatch_settings)
return SigiTestApp(default_user=admin_user.username)

17
etc/apache/sites-available/sigi.erb

@ -1,17 +0,0 @@
NameVirtualHost 10.1.2.126:80
<VirtualHost 10.1.2.126:80>
ServerName sigi01h.interlegis.leg.br
WSGIScriptAlias /sigi /srv/sigi/sigi/wsgi.py
Alias /sigi/static /srv/sigi/static
Alias /sigi/sigiStatic /srv/sigi/sigiStatic
ErrorLog /var/log/apache2/sigi-error.log
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevel warn
CustomLog /var/log/apache2/sigi-access.log combined
ServerSignature Off
</VirtualHost>

BIN
etc/data/ibge/geoftp.ibge.gov.br/organizacao_territorial/divisao_territorial/2009/dtb_05_05_2009.zip

Binary file not shown.

56
etc/data/ibge/leiame.txt

@ -1,56 +0,0 @@
21/05/2012
Procedimento para importação de dados públicos obtidos do IBGE.
- Tabela de Municípios:
Disponível desde 1940, foi atualizada a cada década entre os anos
1940 e 2000 e depois anualmente até a última atualização em 2009 (este
parágrafo foi escrito em maio de 2012).
A atualização mais recente, portanto, é do ano de 2009. Considerando
que o formato de publicação tem variado bastante, o roteiro abaixo é
específico para os dados referentes ao ano 2009.
- Procedimentos e instruções:
1. Questões óbvias como configuração de PROXY são omitidas por não serem
relacionadas ao procedimento.
2. O diretório-base de referência no projeto é o raiz do projeto conforme
foi exportado do repositório, referenciado por $
3. O URL-base de obtenção dos dados é:
ftp://geoftp.ibge.gov.br
4. Tornar o diretório corrente para:
$/SIGI/trunk/etc/data/ibge
5. Baixar o arquivo de 2009. O comando executado com sucesso considerando a
configuração da intranet do Interlegis na data corrente - maio de 2012 - é:
wget -r --no-proxy ftp://geoftp.ibge.gov.br/organizacao_territorial/divisao_territorial/2009/ organizacao_territorial/divisao_territorial/2009
(o comando acima criará o caminho local "geoftp.ibge.gov.br/organizacao_territorial/divisao_territorial/2009/")
6. Torne corrente o caminho onde o arquivo de 2009 está baixado:
cd geoftp.ibge.gov.br/organizacao_territorial/divisao_territorial/2009
7. Expanda o arquivo obtido:
unzip dtb_05_05_2009.zip
8. Converta o arquivo expandido para o formato "CSV":
xls2csv DTB_05_05_2009.xls > DTB_05_05_2009.csv
9. Volte para o diretório-base do IBGE:
$/SIGI/trunk/etc/data/ibge
10. Execute o script de importação, cuja documentação dos processos encontra-se
nos fontes:
sigi-import-ibge-2009.sh geoftp.ibge.gov.br/organizacao_territorial/divisao_territorial/2009/DTB_05_05_2009.csv

43
etc/data/ibge/sigi-import-ibge-2009.py_DOES_NOT_COMPILE

@ -1,43 +0,0 @@
import sys
import csv
"""
"""
_root_dict = None
def getUFdict(root, ufid):
return(root[ufid])
def getCidadesDict(macrodict, microid):
if macrodict = None:
return(None)
microdoct = macrodict['__children']
if microdict = None:
microdict = {}
macrodict['__children'] = microdict
def main():
argc = len(sys.argv)
arquivo = open('geoftp.ibge.gov.br/organizacao_territorial/divisao_territorial/2009/DTB_05_05_2009.csv', 'r')
# despreza o cabecalho
arquivo.readline()
lnum = 0
csv_reader = csv.reader(arquivo, delimiter=',', quotechar='"')
for registro in csv_reader:
if uf[registro[0]] = None:
uf[registro[0]] = {}
uf[registro[0]]['nome'] = registro[1]
uf[registro[0]]['macrorregioes'] = {}
# print "lnum: %s - %s" % ( lnum, registro )
lnum = lnum + 1
if lnum >= 10:
break
if __name__ = "__main__":
main()
dumpdicts()

179
etc/data/ibge/sigi-import-ibge-2009.sh

@ -1,179 +0,0 @@
#!/bin/sh
arquivo_csv=""
limite=0
# Caso a variavel _DEBUG nao tenha sido preparada externamente,
# assumir que o default é sem DEBUG
if [ -z "${_DEBUG}" ]
then
_DEBUG="0"
fi
# Default verboso
if [ -z "${_VERBOSE}" ]
then
_VERBOSE="1"
fi
PrintDebug( )
{
# para a mensagem ser mostrada, _DEBUG deve ser configurada
# e o valor deve ser diferente de "0"
if [ -n "${_DEBUG}" -a "${_DEBUG}" -ne "0" ]
then
echo "$@"
fi
}
PrintHelp( )
{
PrintMessage `basename "${0}"` " -- importa tabelas de cidades do IBGE"
PrintMessage "Opcoes aceitas:"
PrintMessage " arquivo_csv=[caminho]"
PrintMessage " informa o caminho para o arquivo no formato 2009"
PrintMessage " limite=N"
PrintMessage " determina a quantidade maxima de registros de entrada processados"
PrintMessage " _VERBOSE=[verbose]"
PrintMessage " 0 para nao mostrar mensagens, 1 para mostrar"
PrintMessage " _DEBUG=[debug]"
PrintMessage " 0 para nao mostrar mensagens de depuracao, 1 para mostrar"
}
PrintMessage( )
{
# para a mensagem NAO ser mostrada, _VERBOSE deve ser configurada
# e o valor deve ser "0"
if [ -z "${_VERBOSE}" -o "${_VERBOSE}" -ne "0" ]
then
echo "$@"
fi
}
# Processar os argumentos passados pela linha de comando. Devem estar no
# formato de atribuicao de variaveis em Shell, ou entao devem ser atribuidos
# e exportados pelo processo chamador. Caso na expressao [var]=[valor] exista
# separadores, todo o argumento deve estar entre aspas: "[var]=[valor]"
while [ "${#}" -gt 0 ]
do
if echo "${1}" | grep "=" 2>&1 > /dev/null
then
PrintDebug "Argumento de configuracao: \"${1}\""
eval "${1}"
else
PrintDebug "Argumento desconhecido: \"${1}\""
PrintHelp
exit 1
fi
shift
done
####################################
# Secao de validacao de parametros
if [ -z "${arquivo_csv}" ]
then
PrintMessage "ERRO: informe o arquivo de importacao."
PrintHelp
exit 2
fi
if [ ! -f "${arquivo_csv}" ]
then
PrintMessage "ERRO: o arquivo de importacao nao existe ou nao pode ser acessado (\"${arquivo_csv}\")."
PrintHelp
exit 3
fi
if [ ! -r "${arquivo_csv}" ]
then
PrintMessage "ERRO: o arquivo de importacao nao pode ser lido (\"${arquivo_csv}\")."
PrintHelp
exit 4
fi
# filtrar o arquivo original para area de trabalho, por
# UF, Mesorregiao, Microrregiao, Municipio e depois executar
# os scripts Python para atualização do banco.
# O formato do arquivo obtido do IBGE e' CSV com as seguintes colunas:
#
# 1: "UF"
# 2: "Nome_UF"
# 3: "MesorregiãoGeográfica"
# 4: "MesorregiãoGeográfica_Nome"
# 5: "MicrorregiãoGeográfica"
# 6: "MicrorregiãoGeográfica_Nome"
# 7: "Município"
# 8: "Município_Nome"
# 9: "Distrito"
# 10: "Distrito_Nome"
# 11: "Subdistrito"
# 12: "Subdistrito_Nome"
nome_base=sigi_ibge_import
niveis="uf mesorregiao microrregiao municipio"
for nivel in $niveis
do
eval "arquivo_${nivel}=/tmp/${nome_base}.${nivel}.csv"
done
exec 3< "${arquivo_csv}" 4> "${arquivo_uf}" 5> "${arquivo_mesorregiao}" 6> "${arquivo_microrregiao}" 7> "${arquivo_municipio}"
lnum=0
PrintMessage "Iniciando leitura dos dados..."
read linha <&3
while read linha <&3
do
lnum=$(($lnum + 1))
if [ $(($lnum % 100)) -eq 0 ]
then
PrintMessage -n "${lnum} "
fi
# extrair o codigo da regiao a partir do codigo da UF
# e criar o novo campo 1 com o codigo da regiao
codregiao=`echo "$linha" | cut -b2-2`
linha="\"${codregiao}\",$linha"
# UFs: cod_regiao,cod_uf,nome_uf
# -- a sigla por enquanto devera ser adicionada manualmente
echo "$linha" | cut -s -d, -f1,2,3 >&4
# Mesorregiao: cod_regiao,cod_uf,cod_mesorregiao,nome_mesorregiao
echo "$linha" | cut -s -d, -f1,2,4,5 >&5
# Microrregiao: cod_regiao,cod_uf,cod_mesorregiao,cod_microrregiao,nome_microrregiao
echo "$linha" | cut -s -d, -f1,2,4,6,7 >&6
# Municipio: cod_regiao,cod_uf,cod_mesorregiao,cod_microrregiao,cod_municipio,nome_municipio
# 7> "${arquivo_municipio}"
echo "$linha" | cut -s -d, -f1,2,4,6,8,9 >&7
if [ -n "${limite}" -a "${limite}" -gt 0 -a "${lnum}" -ge "${limite}" ]
then
break
fi
done
PrintMessage "\n${lnum} registros processados"
# fecha os descritores de saida
exec 3<&- 4>&- 5>&- 6>&- 7>&-
for nivel in $niveis
do
eval "arq_in=/tmp/${nome_base}.${nivel}.csv"
eval "arq_out=/tmp/${nome_base}.${nivel}.csv.tmp"
sort < $arq_in > $arq_out
uniq < $arq_out > $arq_in
rm $arq_out
done
ifs="$IFS"
IFS="
"
for l in `wc -l /tmp/${nome_base}*`
do
PrintDebug $l
done
IFS="$ifs"
# Processar arquivos: INSERT ou UPDATE no banco

137
etc/data/ibge/sigi_ibge_import.mesorregiao.csv

@ -1,137 +0,0 @@
"1","11","1101","Madeira-Guaporé"
"1","11","1102","Leste Rondoniense"
"1","12","1201","Vale do Juruá"
"1","12","1202","Vale do Acre"
"1","13","1301","Norte Amazonense"
"1","13","1302","Sudoeste Amazonense"
"1","13","1303","Centro Amazonense"
"1","13","1304","Sul Amazonense"
"1","14","1401","Norte de Roraima"
"1","14","1402","Sul de Roraima"
"1","15","1501","Baixo Amazonas"
"1","15","1502","Marajó"
"1","15","1503","Metropolitana de Belém"
"1","15","1504","Nordeste Paraense"
"1","15","1505","Sudoeste Paraense"
"1","15","1506","Sudeste Paraense"
"1","16","1601","Norte do Amapá"
"1","16","1602","Sul do Amapá"
"1","17","1701","Ocidental do Tocantins"
"1","17","1702","Oriental do Tocantins"
"2","21","2101","Norte Maranhense"
"2","21","2102","Oeste Maranhense"
"2","21","2103","Centro Maranhense"
"2","21","2104","Leste Maranhense"
"2","21","2105","Sul Maranhense"
"2","22","2201","Norte Piauiense"
"2","22","2202","Centro-Norte Piauiense"
"2","22","2203","Sudoeste Piauiense"
"2","22","2204","Sudeste Piauiense"
"2","23","2301","Noroeste Cearense"
"2","23","2302","Norte Cearense"
"2","23","2303","Metropolitana de Fortaleza"
"2","23","2304","Sertões Cearenses"
"2","23","2305","Jaguaribe"
"2","23","2306","Centro-Sul Cearense"
"2","23","2307","Sul Cearense"
"2","24","2401","Oeste Potiguar"
"2","24","2402","Central Potiguar"
"2","24","2403","Agreste Potiguar"
"2","24","2404","Leste Potiguar"
"2","25","2501","Sertão Paraibano"
"2","25","2502","Borborema"
"2","25","2503","Agreste Paraibano"
"2","25","2504","Mata Paraibana"
"2","26","2601","Sertão Pernambucano"
"2","26","2602","São Francisco Pernambucano"
"2","26","2603","Agreste Pernambucano"
"2","26","2604","Mata Pernambucana"
"2","26","2605","Metropolitana de Recife"
"2","27","2701","Sertão Alagoano"
"2","27","2702","Agreste Alagoano"
"2","27","2703","Leste Alagoano"
"2","28","2801","Sertão Sergipano"
"2","28","2802","Agreste Sergipano"
"2","28","2803","Leste Sergipano"
"2","29","2901","Extremo Oeste Baiano"
"2","29","2902","Vale São-Franciscano da Bahia"
"2","29","2903","Centro Norte Baiano"
"2","29","2904","Nordeste Baiano"
"2","29","2905","Metropolitana de Salvador"
"2","29","2906","Centro Sul Baiano"
"2","29","2907","Sul Baiano"
"3","31","3101","Noroeste de Minas"
"3","31","3102","Norte de Minas"
"3","31","3103","Jequitinhonha"
"3","31","3104","Vale do Mucuri"
"3","31","3105","Triângulo Mineiro/Alto Paranaíba"
"3","31","3106","Central Mineira"
"3","31","3107","Metropolitana de Belo Horizonte"
"3","31","3108","Vale do Rio Doce"
"3","31","3109","Oeste de Minas"
"3","31","3110","Sul/Sudoeste de Minas"
"3","31","3111","Campo das Vertentes"
"3","31","3112","Zona da Mata"
"3","32","3201","Noroeste Espírito-santense"
"3","32","3202","Litoral Norte Espírito-santense"
"3","32","3203","Central Espírito-santense"
"3","32","3204","Sul Espírito-santense"
"3","33","3301","Noroeste Fluminense"
"3","33","3302","Norte Fluminense"
"3","33","3303","Centro Fluminense"
"3","33","3304","Baixadas"
"3","33","3305","Sul Fluminense"
"3","33","3306","Metropolitana do Rio de Janeiro"
"3","35","3501","São José do Rio Preto"
"3","35","3502","Ribeirão Preto"
"3","35","3503","Araçatuba"
"3","35","3504","Bauru"
"3","35","3505","Araraquara"
"3","35","3506","Piracicaba"
"3","35","3507","Campinas"
"3","35","3508","Presidente Prudente"
"3","35","3509","Marília"
"3","35","3510","Assis"
"3","35","3511","Itapetininga"
"3","35","3512","Macro Metropolitana Paulista"
"3","35","3513","Vale do Paraíba Paulista"
"3","35","3514","Litoral Sul Paulista"
"3","35","3515","Metropolitana de São Paulo"
"4","41","4101","Noroeste Paranaense"
"4","41","4102","Centro Ocidental Paranaense"
"4","41","4103","Norte Central Paranaense"
"4","41","4104","Norte Pioneiro Paranaense"
"4","41","4105","Centro Oriental Paranaense"
"4","41","4106","Oeste Paranaense"
"4","41","4107","Sudoeste Paranaense"
"4","41","4108","Centro-Sul Paranaense"
"4","41","4109","Sudeste Paranaense"
"4","41","4110","Metropolitana de Curitiba"
"4","42","4201","Oeste Catarinense"
"4","42","4202","Norte Catarinense"
"4","42","4203","Serrana"
"4","42","4204","Vale do Itajaí"
"4","42","4205","Grande Florianópolis"
"4","42","4206","Sul Catarinense"
"4","43","4301","Noroeste Rio-grandense"
"4","43","4302","Nordeste Rio-grandense"
"4","43","4303","Centro Ocidental Rio-grandense"
"4","43","4304","Centro Oriental Rio-grandense"
"4","43","4305","Metropolitana de Porto Alegre"
"4","43","4306","Sudoeste Rio-grandense"
"4","43","4307","Sudeste Rio-grandense"
"5","50","5001","Pantanais Sul Mato-grossense"
"5","50","5002","Centro Norte de Mato Grosso do Sul"
"5","50","5003","Leste de Mato Grosso do Sul"
"5","50","5004","Sudoeste de Mato Grosso do Sul"
"5","51","5101","Norte Mato-grossense"
"5","51","5102","Nordeste Mato-grossense"
"5","51","5103","Sudoeste Mato-grossense"
"5","51","5104","Centro-Sul Mato-grossense"
"5","51","5105","Sudeste Mato-grossense"
"5","52","5201","Noroeste Goiano"
"5","52","5202","Norte Goiano"
"5","52","5203","Centro Goiano"
"5","52","5204","Leste Goiano"
"5","52","5205","Sul Goiano"
"5","53","5301","Distrito Federal"
Can't render this file because it contains an unexpected character in line 58 and column 10.

558
etc/data/ibge/sigi_ibge_import.microrregiao.csv

@ -1,558 +0,0 @@
"1","11","1101","11001","Porto Velho"
"1","11","1101","11002","Guajará-Mirim"
"1","11","1102","11003","Ariquemes"
"1","11","1102","11004","Ji-Paraná"
"1","11","1102","11005","Alvorada D'Oeste"
"1","11","1102","11006","Cacoal"
"1","11","1102","11007","Vilhena"
"1","11","1102","11008","Colorado do Oeste"
"1","12","1201","12001","Cruzeiro do Sul"
"1","12","1201","12002","Tarauacá"
"1","12","1202","12003","Sena Madureira"
"1","12","1202","12004","Rio Branco"
"1","12","1202","12005","Brasiléia"
"1","13","1301","13001","Rio Negro"
"1","13","1301","13002","Japurá"
"1","13","1302","13003","Alto Solimões"
"1","13","1302","13004","Juruá"
"1","13","1303","13005","Tefé"
"1","13","1303","13006","Coari"
"1","13","1303","13007","Manaus"
"1","13","1303","13008","Rio Preto da Eva"
"1","13","1303","13009","Itacoatiara"
"1","13","1303","13010","Parintins"
"1","13","1304","13011","Boca do Acre"
"1","13","1304","13012","Purus"
"1","13","1304","13013","Madeira"
"1","14","1401","14001","Boa Vista"
"1","14","1401","14002","Nordeste de Roraima"
"1","14","1402","14003","Caracaraí"
"1","14","1402","14004","Sudeste de Roraima"
"1","15","1501","15001","Óbidos"
"1","15","1501","15002","Santarém"
"1","15","1501","15003","Almeirim"
"1","15","1502","15004","Portel"
"1","15","1502","15005","Furos de Breves"
"1","15","1502","15006","Arari"
"1","15","1503","15007","Belém"
"1","15","1503","15008","Castanhal"
"1","15","1504","15009","Salgado"
"1","15","1504","15010","Bragantina"
"1","15","1504","15011","Cametá"
"1","15","1504","15012","Tomé-Açu"
"1","15","1504","15013","Guamá"
"1","15","1505","15014","Itaituba"
"1","15","1505","15015","Altamira"
"1","15","1506","15016","Tucuruí"
"1","15","1506","15017","Paragominas"
"1","15","1506","15018","São Félix do Xingu"
"1","15","1506","15019","Parauapebas"
"1","15","1506","15020","Marabá"
"1","15","1506","15021","Redenção"
"1","15","1506","15022","Conceição do Araguaia"
"1","16","1601","16001","Oiapoque"
"1","16","1601","16002","Amapá"
"1","16","1602","16003","Macapá"
"1","16","1602","16004","Mazagão"
"1","17","1701","17001","Bico do Papagaio"
"1","17","1701","17002","Araguaína"
"1","17","1701","17003","Miracema do Tocantins"
"1","17","1701","17004","Rio Formoso"
"1","17","1701","17005","Gurupi"
"1","17","1702","17006","Porto Nacional"
"1","17","1702","17007","Jalapão"
"1","17","1702","17008","Dianópolis"
"2","21","2101","21001","Litoral Ocidental Maranhense"
"2","21","2101","21002","Aglomeração Urbana de São Luís"
"2","21","2101","21003","Rosário"
"2","21","2101","21004","Lençois Maranhenses"
"2","21","2101","21005","Baixada Maranhense"
"2","21","2101","21006","Itapecuru Mirim"
"2","21","2102","21007","Gurupi"
"2","21","2102","21008","Pindaré"
"2","21","2102","21009","Imperatriz"
"2","21","2103","21010","Médio Mearim"
"2","21","2103","21011","Alto Mearim e Grajaú"
"2","21","2103","21012","Presidente Dutra"
"2","21","2104","21013","Baixo Parnaíba Maranhense"
"2","21","2104","21014","Chapadinha"
"2","21","2104","21015","Codó"
"2","21","2104","21016","Coelho Neto"
"2","21","2104","21017","Caxias"
"2","21","2104","21018","Chapadas do Alto Itapecuru"
"2","21","2105","21019","Porto Franco"
"2","21","2105","21020","Gerais de Balsas"
"2","21","2105","21021","Chapadas das Mangabeiras"
"2","22","2201","22001","Baixo Parnaíba Piauiense"
"2","22","2201","22002","Litoral Piauiense"
"2","22","2202","22003","Teresina"
"2","22","2202","22004","Campo Maior"
"2","22","2202","22005","Médio Parnaíba Piauiense"
"2","22","2202","22006","Valença do Piauí"
"2","22","2203","22007","Alto Parnaíba Piauiense"
"2","22","2203","22008","Bertolínia"
"2","22","2203","22009","Floriano"
"2","22","2203","22010","Alto Médio Gurguéia"
"2","22","2203","22011","São Raimundo Nonato"
"2","22","2203","22012","Chapadas do Extremo Sul Piauiense"
"2","22","2204","22013","Picos"
"2","22","2204","22014","Pio IX"
"2","22","2204","22015","Alto Médio Canindé"
"2","23","2301","23001","Litoral de Camocim e Acaraú"
"2","23","2301","23002","Ibiapaba"
"2","23","2301","23003","Coreaú"
"2","23","2301","23004","Meruoca"
"2","23","2301","23005","Sobral"
"2","23","2301","23006","Ipu"
"2","23","2301","23007","Santa Quitéria"
"2","23","2302","23008","Itapipoca"
"2","23","2302","23009","Baixo Curu"
"2","23","2302","23010","Uruburetama"
"2","23","2302","23011","Médio Curu"
"2","23","2302","23012","Canindé"
"2","23","2302","23013","Baturité"
"2","23","2302","23014","Chorozinho"
"2","23","2302","23015","Cascavel"
"2","23","2303","23016","Fortaleza"
"2","23","2303","23017","Pacajus"
"2","23","2304","23018","Sertão de Cratéus"
"2","23","2304","23019","Sertão de Quixeramobim"
"2","23","2304","23020","Sertão de Inhamuns"
"2","23","2304","23021","Sertão de Senador Pompeu"
"2","23","2305","23022","Litoral de Aracati"
"2","23","2305","23023","Baixo Jaguaribe"
"2","23","2305","23024","Médio Jaguaribe"
"2","23","2305","23025","Serra do Pereiro"
"2","23","2306","23026","Iguatu"
"2","23","2306","23027","Várzea Alegre"
"2","23","2306","23028","Lavras da Mangabeira"
"2","23","2307","23029","Chapada do Araripe"
"2","23","2307","23030","Caririaçu"
"2","23","2307","23031","Barro"
"2","23","2307","23032","Cariri"
"2","23","2307","23033","Brejo Santo"
"2","24","2401","24001","Mossoró"
"2","24","2401","24002","Chapada do Apodi"
"2","24","2401","24003","Médio Oeste"
"2","24","2401","24004","Vale do Açu"
"2","24","2401","24005","Serra de São Miguel"
"2","24","2401","24006","Pau dos Ferros"
"2","24","2401","24007","Umarizal"
"2","24","2402","24008","Macau"
"2","24","2402","24009","Angicos"
"2","24","2402","24010","Serra de Santana"
"2","24","2402","24011","Seridó Ocidental"
"2","24","2402","24012","Seridó Oriental"
"2","24","2403","24013","Baixa Verde"
"2","24","2403","24014","Borborema Potiguar"
"2","24","2403","24015","Agreste Potiguar"
"2","24","2404","24016","Litoral Nordeste"
"2","24","2404","24017","Macaíba"
"2","24","2404","24018","Natal"
"2","24","2404","24019","Litoral Sul"
"2","25","2501","25001","Catolé do Rocha"
"2","25","2501","25002","Cajazeiras"
"2","25","2501","25003","Sousa"
"2","25","2501","25004","Patos"
"2","25","2501","25005","Piancó"
"2","25","2501","25006","Itaporanga"
"2","25","2501","25007","Serra do Teixeira"
"2","25","2502","25008","Seridó Ocidental Paraibano"
"2","25","2502","25009","Seridó Oriental Paraibano"
"2","25","2502","25010","Cariri Ocidental"
"2","25","2502","25011","Cariri Oriental"
"2","25","2503","25012","Curimataú Ocidental"
"2","25","2503","25013","Curimataú Oriental"
"2","25","2503","25014","Esperança"
"2","25","2503","25015","Brejo Paraibano"
"2","25","2503","25016","Guarabira"
"2","25","2503","25017","Campina Grande"
"2","25","2503","25018","Itabaiana"
"2","25","2503","25019","Umbuzeiro"
"2","25","2504","25020","Litoral Norte"
"2","25","2504","25021","Sapé"
"2","25","2504","25022","João Pessoa"
"2","25","2504","25023","Litoral Sul"
"2","26","2601","26001","Araripina"
"2","26","2601","26002","Salgueiro"
"2","26","2601","26003","Pajeú"
"2","26","2601","26004","Sertão do Moxotó"
"2","26","2602","26005","Petrolina"
"2","26","2602","26006","Itaparica"
"2","26","2603","26007","Vale do Ipanema"
"2","26","2603","26008","Vale do Ipojuca"
"2","26","2603","26009","Alto Capibaribe"
"2","26","2603","26010","Médio Capibaribe"
"2","26","2603","26011","Garanhuns"
"2","26","2603","26012","Brejo Pernambucano"
"2","26","2604","26013","Mata Setentrional Pernambucana"
"2","26","2604","26014","Vitória de Santo Antão"
"2","26","2604","26015","Mata Meridional Pernambucana"
"2","26","2605","26016","Itamaracá"
"2","26","2605","26017","Recife"
"2","26","2605","26018","Suape"
"2","26","2605","26019","Fernando de Noronha"
"2","27","2701","27001","Serrana do Sertão Alagoano"
"2","27","2701","27002","Alagoana do Sertão do São Francisco"
"2","27","2701","27003","Santana do Ipanema"
"2","27","2701","27004","Batalha"
"2","27","2702","27005","Palmeira dos Índios"
"2","27","2702","27006","Arapiraca"
"2","27","2702","27007","Traipu"
"2","27","2703","27008","Serrana dos Quilombos"
"2","27","2703","27009","Mata Alagoana"
"2","27","2703","27010","Litoral Norte Alagoano"
"2","27","2703","27011","Maceió"
"2","27","2703","27012","São Miguel dos Campos"
"2","27","2703","27013","Penedo"
"2","28","2801","28001","Sergipana do Sertão do São Francisco"
"2","28","2801","28002","Carira"
"2","28","2802","28003","Nossa Senhora das Dores"
"2","28","2802","28004","Agreste de Itabaiana"
"2","28","2802","28005","Tobias Barreto"
"2","28","2802","28006","Agreste de Lagarto"
"2","28","2803","28007","Propriá"
"2","28","2803","28008","Cotinguiba"
"2","28","2803","28009","Japaratuba"
"2","28","2803","28010","Baixo Cotinguiba"
"2","28","2803","28011","Aracaju"
"2","28","2803","28012","Boquim"
"2","28","2803","28013","Estância"
"2","29","2901","29001","Barreiras"
"2","29","2901","29002","Cotegipe"
"2","29","2901","29003","Santa Maria da Vitória"
"2","29","2902","29004","Juazeiro"
"2","29","2902","29005","Paulo Afonso"
"2","29","2902","29006","Barra"
"2","29","2902","29007","Bom Jesus da Lapa"
"2","29","2903","29008","Senhor do Bonfim"
"2","29","2903","29009","Irecê"
"2","29","2903","29010","Jacobina"
"2","29","2903","29011","Itaberaba"
"2","29","2903","29012","Feira de Santana"
"2","29","2904","29013","Jeremoabo"
"2","29","2904","29014","Euclides da Cunha"
"2","29","2904","29015","Ribeira do Pombal"
"2","29","2904","29016","Serrinha"
"2","29","2904","29017","Alagoinhas"
"2","29","2904","29018","Entre Rios"
"2","29","2905","29019","Catu"
"2","29","2905","29020","Santo Antônio de Jesus"
"2","29","2905","29021","Salvador"
"2","29","2906","29022","Boquira"
"2","29","2906","29023","Seabra"
"2","29","2906","29024","Jequié"
"2","29","2906","29025","Livramento do Brumado"
"2","29","2906","29026","Guanambi"
"2","29","2906","29027","Brumado"
"2","29","2906","29028","Vitória da Conquista"
"2","29","2906","29029","Itapetinga"
"2","29","2907","29030","Valença"
"2","29","2907","29031","Ilhéus-Itabuna"
"2","29","2907","29032","Porto Seguro"
"3","31","3101","31001","Unaí"
"3","31","3101","31002","Paracatu"
"3","31","3102","31003","Januária"
"3","31","3102","31004","Janaúba"
"3","31","3102","31005","Salinas"
"3","31","3102","31006","Pirapora"
"3","31","3102","31007","Montes Claros"
"3","31","3102","31008","Grão Mogol"
"3","31","3102","31009","Bocaiúva"
"3","31","3103","31010","Diamantina"
"3","31","3103","31011","Capelinha"
"3","31","3103","31012","Araçuaí"
"3","31","3103","31013","Pedra Azul"
"3","31","3103","31014","Almenara"
"3","31","3104","31015","Teófilo Otoni"
"3","31","3104","31016","Nanuque"
"3","31","3105","31017","Ituiutaba"
"3","31","3105","31018","Uberlândia"
"3","31","3105","31019","Patrocínio"
"3","31","3105","31020","Patos de Minas"
"3","31","3105","31021","Frutal"
"3","31","3105","31022","Uberaba"
"3","31","3105","31023","Araxá"
"3","31","3106","31024","Três Marias"
"3","31","3106","31025","Curvelo"
"3","31","3106","31026","Bom Despacho"
"3","31","3107","31027","Sete Lagoas"
"3","31","3107","31028","Conceição do Mato Dentro"
"3","31","3107","31029","Pará de Minas"
"3","31","3107","31030","Belo Horizonte"
"3","31","3107","31031","Itabira"
"3","31","3107","31032","Itaguara"
"3","31","3107","31033","Ouro Preto"
"3","31","3107","31034","Conselheiro Lafaiete"
"3","31","3108","31035","Guanhães"
"3","31","3108","31036","Peçanha"
"3","31","3108","31037","Governador Valadares"
"3","31","3108","31038","Mantena"
"3","31","3108","31039","Ipatinga"
"3","31","3108","31040","Caratinga"
"3","31","3108","31041","Aimorés"
"3","31","3109","31042","Piuí"
"3","31","3109","31043","Divinópolis"
"3","31","3109","31044","Formiga"
"3","31","3109","31045","Campo Belo"
"3","31","3109","31046","Oliveira"
"3","31","3110","31047","Passos"
"3","31","3110","31048","São Sebastião do Paraíso"
"3","31","3110","31049","Alfenas"
"3","31","3110","31050","Varginha"
"3","31","3110","31051","Poços de Caldas"
"3","31","3110","31052","Pouso Alegre"
"3","31","3110","31053","Santa Rita do Sapucaí"
"3","31","3110","31054","São Lourenço"
"3","31","3110","31055","Andrelândia"
"3","31","3110","31056","Itajubá"
"3","31","3111","31057","Lavras"
"3","31","3111","31058","São João Del Rei"
"3","31","3111","31059","Barbacena"
"3","31","3112","31060","Ponte Nova"
"3","31","3112","31061","Manhuaçu"
"3","31","3112","31062","Viçosa"
"3","31","3112","31063","Muriaé"
"3","31","3112","31064","Ubá"
"3","31","3112","31065","Juiz de Fora"
"3","31","3112","31066","Cataguases"
"3","32","3201","32001","Barra de São Francisco"
"3","32","3201","32002","Nova Venécia"
"3","32","3201","32003","Colatina"
"3","32","3202","32004","Montanha"
"3","32","3202","32005","São Mateus"
"3","32","3202","32006","Linhares"
"3","32","3203","32007","Afonso Cláudio"
"3","32","3203","32008","Santa Teresa"
"3","32","3203","32009","Vitória"
"3","32","3203","32010","Guarapari"
"3","32","3204","32011","Alegre"
"3","32","3204","32012","Cachoeiro de Itapemirim"
"3","32","3204","32013","Itapemirim"
"3","33","3301","33001","Itaperuna"
"3","33","3301","33002","Santo Antônio de Pádua"
"3","33","3302","33003","Campos dos Goytacazes"
"3","33","3302","33004","Macaé"
"3","33","3303","33005","Três Rios"
"3","33","3303","33006","Cantagalo-Cordeiro"
"3","33","3303","33007","Nova Friburgo"
"3","33","3303","33008","Santa Maria Madalena"
"3","33","3304","33009","Bacia de São João"
"3","33","3304","33010","Lagos"
"3","33","3305","33011","Vale do Paraíba Fluminense"
"3","33","3305","33012","Barra do Piraí"
"3","33","3305","33013","Baía da Ilha Grande"
"3","33","3306","33014","Vassouras"
"3","33","3306","33015","Serrana"
"3","33","3306","33016","Macacu-Caceribu"
"3","33","3306","33017","Itaguaí"
"3","33","3306","33018","Rio de Janeiro"
"3","35","3501","35001","Jales"
"3","35","3501","35002","Fernandópolis"
"3","35","3501","35003","Votuporanga"
"3","35","3501","35004","São José do Rio Preto"
"3","35","3501","35005","Catanduva"
"3","35","3501","35006","Auriflama"
"3","35","3501","35007","Nhandeara"
"3","35","3501","35008","Novo Horizonte"
"3","35","3502","35009","Barretos"
"3","35","3502","35010","São Joaquim da Barra"
"3","35","3502","35011","Ituverava"
"3","35","3502","35012","Franca"
"3","35","3502","35013","Jaboticabal"
"3","35","3502","35014","Ribeirão Preto"
"3","35","3502","35015","Batatais"
"3","35","3503","35016","Andradina"
"3","35","3503","35017","Araçatuba"
"3","35","3503","35018","Birigui"
"3","35","3504","35019","Lins"
"3","35","3504","35020","Bauru"
"3","35","3504","35021","Jaú"
"3","35","3504","35022","Avaré"
"3","35","3504","35023","Botucatu"
"3","35","3505","35024","Araraquara"
"3","35","3505","35025","São Carlos"
"3","35","3506","35026","Rio Claro"
"3","35","3506","35027","Limeira"
"3","35","3506","35028","Piracicaba"
"3","35","3507","35029","Pirassununga"
"3","35","3507","35030","São João da Boa Vista"
"3","35","3507","35031","Moji Mirim"
"3","35","3507","35032","Campinas"
"3","35","3507","35033","Amparo"
"3","35","3508","35034","Dracena"
"3","35","3508","35035","Adamantina"
"3","35","3508","35036","Presidente Prudente"
"3","35","3509","35037","Tupã"
"3","35","3509","35038","Marília"
"3","35","3510","35039","Assis"
"3","35","3510","35040","Ourinhos"
"3","35","3511","35041","Itapeva"
"3","35","3511","35042","Itapetininga"
"3","35","3511","35043","Tatuí"
"3","35","3511","35044","Capão Bonito"
"3","35","3512","35045","Piedade"
"3","35","3512","35046","Sorocaba"
"3","35","3512","35047","Jundiaí"
"3","35","3512","35048","Bragança Paulista"
"3","35","3513","35049","Campos do Jordão"
"3","35","3513","35050","São José dos Campos"
"3","35","3513","35051","Guaratinguetá"
"3","35","3513","35052","Bananal"
"3","35","3513","35053","Paraibuna/Paraitinga"
"3","35","3513","35054","Caraguatatuba"
"3","35","3514","35055","Registro"
"3","35","3514","35056","Itanhaém"
"3","35","3515","35057","Osasco"
"3","35","3515","35058","Franco da Rocha"
"3","35","3515","35059","Guarulhos"
"3","35","3515","35060","Itapecerica da Serra"
"3","35","3515","35061","São Paulo"
"3","35","3515","35062","Mogi das Cruzes"
"3","35","3515","35063","Santos"
"4","41","4101","41001","Paranavaí"
"4","41","4101","41002","Umuarama"
"4","41","4101","41003","Cianorte"
"4","41","4102","41004","Goioerê"
"4","41","4102","41005","Campo Mourão"
"4","41","4103","41006","Astorga"
"4","41","4103","41007","Porecatu"
"4","41","4103","41008","Floraí"
"4","41","4103","41009","Maringá"
"4","41","4103","41010","Apucarana"
"4","41","4103","41011","Londrina"
"4","41","4103","41012","Faxinal"
"4","41","4103","41013","Ivaiporã"
"4","41","4104","41014","Assaí"
"4","41","4104","41015","Cornélio Procópio"
"4","41","4104","41016","Jacarezinho"
"4","41","4104","41017","Ibaiti"
"4","41","4104","41018","Wenceslau Braz"
"4","41","4105","41019","Telêmaco Borba"
"4","41","4105","41020","Jaguariaíva"
"4","41","4105","41021","Ponta Grossa"
"4","41","4106","41022","Toledo"
"4","41","4106","41023","Cascavel"
"4","41","4106","41024","Foz do Iguaçu"
"4","41","4107","41025","Capanema"
"4","41","4107","41026","Francisco Beltrão"
"4","41","4107","41027","Pato Branco"
"4","41","4108","41028","Pitanga"
"4","41","4108","41029","Guarapuava"
"4","41","4108","41030","Palmas"
"4","41","4109","41031","Prudentópolis"
"4","41","4109","41032","Irati"
"4","41","4109","41033","União da Vitória"
"4","41","4109","41034","São Mateus do Sul"
"4","41","4110","41035","Cerro Azul"
"4","41","4110","41036","Lapa"
"4","41","4110","41037","Curitiba"
"4","41","4110","41038","Paranaguá"
"4","41","4110","41039","Rio Negro"
"4","42","4201","42001","São Miguel do Oeste"
"4","42","4201","42002","Chapecó"
"4","42","4201","42003","Xanxerê"
"4","42","4201","42004","Joaçaba"
"4","42","4201","42005","Concórdia"
"4","42","4202","42006","Canoinhas"
"4","42","4202","42007","São Bento do Sul"
"4","42","4202","42008","Joinville"
"4","42","4203","42009","Curitibanos"
"4","42","4203","42010","Campos de Lages"
"4","42","4204","42011","Rio do Sul"
"4","42","4204","42012","Blumenau"
"4","42","4204","42013","Itajaí"
"4","42","4204","42014","Ituporanga"
"4","42","4205","42015","Tijucas"
"4","42","4205","42016","Florianópolis"
"4","42","4205","42017","Tabuleiro"
"4","42","4206","42018","Tubarão"
"4","42","4206","42019","Criciúma"
"4","42","4206","42020","Araranguá"
"4","43","4301","43001","Santa Rosa"
"4","43","4301","43002","Três Passos"
"4","43","4301","43003","Frederico Westphalen"
"4","43","4301","43004","Erechim"
"4","43","4301","43005","Sananduva"
"4","43","4301","43006","Cerro Largo"
"4","43","4301","43007","Santo Ângelo"
"4","43","4301","43008","Ijuí"
"4","43","4301","43009","Carazinho"
"4","43","4301","43010","Passo Fundo"
"4","43","4301","43011","Cruz Alta"
"4","43","4301","43012","Não-Me-Toque"
"4","43","4301","43013","Soledade"
"4","43","4302","43014","Guaporé"
"4","43","4302","43015","Vacaria"
"4","43","4302","43016","Caxias do Sul"
"4","43","4303","43017","Santiago"
"4","43","4303","43018","Santa Maria"
"4","43","4303","43019","Restinga Seca"
"4","43","4304","43020","Santa Cruz do Sul"
"4","43","4304","43021","Lajeado-Estrela"
"4","43","4304","43022","Cachoeira do Sul"
"4","43","4305","43023","Montenegro"
"4","43","4305","43024","Gramado-Canela"
"4","43","4305","43025","São Jerônimo"
"4","43","4305","43026","Porto Alegre"
"4","43","4305","43027","Osório"
"4","43","4305","43028","Camaquã"
"4","43","4306","43029","Campanha Ocidental"
"4","43","4306","43030","Campanha Central"
"4","43","4306","43031","Campanha Meridional"
"4","43","4307","43032","Serras de Sudeste"
"4","43","4307","43033","Pelotas"
"4","43","4307","43034","Jaguarão"
"4","43","4307","43035","Litoral Lagunar"
"5","50","5001","50001","Baixo Pantanal"
"5","50","5001","50002","Aquidauana"
"5","50","5002","50003","Alto Taquari"
"5","50","5002","50004","Campo Grande"
"5","50","5003","50005","Cassilândia"
"5","50","5003","50006","Paranaíba"
"5","50","5003","50007","Três Lagoas"
"5","50","5003","50008","Nova Andradina"
"5","50","5004","50009","Bodoquena"
"5","50","5004","50010","Dourados"
"5","50","5004","50011","Iguatemi"
"5","51","5101","51001","Aripuanã"
"5","51","5101","51002","Alta Floresta"
"5","51","5101","51003","Colíder"
"5","51","5101","51004","Parecis"
"5","51","5101","51005","Arinos"
"5","51","5101","51006","Alto Teles Pires"
"5","51","5101","51007","Sinop"
"5","51","5101","51008","Paranatinga"
"5","51","5102","51009","Norte Araguaia"
"5","51","5102","51010","Canarana"
"5","51","5102","51011","Médio Araguaia"
"5","51","5103","51012","Alto Guaporé"
"5","51","5103","51013","Tangará da Serra"
"5","51","5103","51014","Jauru"
"5","51","5104","51015","Alto Paraguai"
"5","51","5104","51016","Rosário Oeste"
"5","51","5104","51017","Cuiabá"
"5","51","5104","51018","Alto Pantanal"
"5","51","5105","51019","Primavera do Leste"
"5","51","5105","51020","Tesouro"
"5","51","5105","51021","Rondonópolis"
"5","51","5105","51022","Alto Araguaia"
"5","52","5201","52001","São Miguel do Araguaia"
"5","52","5201","52002","Rio Vermelho"
"5","52","5201","52003","Aragarças"
"5","52","5202","52004","Porangatu"
"5","52","5202","52005","Chapada dos Veadeiros"
"5","52","5203","52006","Ceres"
"5","52","5203","52007","Anápolis"
"5","52","5203","52008","Iporá"
"5","52","5203","52009","Anicuns"
"5","52","5203","52010","Goiânia"
"5","52","5204","52011","Vão do Paranã"
"5","52","5204","52012","Entorno de Brasília"
"5","52","5205","52013","Sudoeste de Goiás"
"5","52","5205","52014","Vale do Rio dos Bois"
"5","52","5205","52015","Meia Ponte"
"5","52","5205","52016","Pires do Rio"
"5","52","5205","52017","Catalão"
"5","52","5205","52018","Quirinópolis"
"5","53","5301","53001","Brasília"
Can't render this file because it has a wrong number of fields in line 56.

5565
etc/data/ibge/sigi_ibge_import.municipio.csv

File diff suppressed because it is too large

5
etc/data/ibge/sigi_ibge_import.regiao.csv

@ -1,5 +0,0 @@
"1","N","Norte"
"2","NE","Nordeste"
"3","SE","Sudeste"
"4","S","Sul"
"5","CO","Centro Oeste"
1 1 N Norte
2 2 NE Nordeste
3 3 SE Sudeste
4 4 S Sul
5 5 CO Centro Oeste

27
etc/data/ibge/sigi_ibge_import.uf.csv

@ -1,27 +0,0 @@
"1","11","Rondônia"
"1","12","Acre"
"1","13","Amazonas"
"1","14","Roraima"
"1","15","Pará"
"1","16","Amapá"
"1","17","Tocantins"
"2","21","Maranhão"
"2","22","Piauí"
"2","23","Ceará"
"2","24","Rio Grande do Norte"
"2","25","Paraíba"
"2","26","Pernambuco"
"2","27","Alagoas"
"2","28","Sergipe"
"2","29","Bahia"
"3","31","Minas Gerais"
"3","32","Espírito Santo"
"3","33","Rio de Janeiro"
"3","35","São Paulo"
"4","41","Paraná"
"4","42","Santa Catarina"
"4","43","Rio Grande do Sul"
"5","50","Mato Grosso do Sul"
"5","51","Mato Grosso"
"5","52","Goiás"
"5","53","Distrito Federal"
1 1 11 Rondônia
2 1 12 Acre
3 1 13 Amazonas
4 1 14 Roraima
5 1 15 Pará
6 1 16 Amapá
7 1 17 Tocantins
8 2 21 Maranhão
9 2 22 Piauí
10 2 23 Ceará
11 2 24 Rio Grande do Norte
12 2 25 Paraíba
13 2 26 Pernambuco
14 2 27 Alagoas
15 2 28 Sergipe
16 2 29 Bahia
17 3 31 Minas Gerais
18 3 32 Espírito Santo
19 3 33 Rio de Janeiro
20 3 35 São Paulo
21 4 41 Paraná
22 4 42 Santa Catarina
23 4 43 Rio Grande do Sul
24 5 50 Mato Grosso do Sul
25 5 51 Mato Grosso
26 5 52 Goiás
27 5 53 Distrito Federal

5565
etc/data/ibge_pop2008.csv

File diff suppressed because it is too large

439
etc/migracao/migra.py

@ -1,439 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Script para fazer a migração dos dados do SIGI antigo (Access), exportados para
CSV, para o novo SIGI.
Conversão dos dados para CSV::
mdb-export -d "|" -D "%Y-%m-%d" <database>.mdb "Assembléias" > assembleias.csv
mdb-export -d "|" -D "%Y-%m-%d" <database>.mdb "municipios" > casas.csv
mdb-export -d "|" -D "%Y-%m-%d" <database>.mdb "CNPJ DAS CM" > cnpj.csv
Coloque os arquivos no diretório deste script e execute ``./migra.py`` para
fazer a migração.
Nota: é recomendado que o banco de dados esteja em seu estado inicial (de
pós-instalação) para a migração dos dados. Este script não foi feito para um
banco de dados em produção.
"""
from django.core.management import setup_environ
from sigi import settings
setup_environ(settings)
import csv
from datetime import datetime
from sigi.apps.casas.models import *
from sigi.apps.contatos.models import *
from sigi.apps.convenios.models import *
from sigi.apps.inventario.models import *
from sigi.apps.parlamentares.models import *
ERROR_MSG_0 = ('<ERRO> %s[%s]: erro desconhecido! Possível erro de integridade '
'do banco de dados. Favor verificar e inserir manualmente caso '
'necessário.')
ERROR_MSG_1 = ('<ERRO> %s[%s]: erro ao inserir item, será necessário inserção '
'manual.')
OBS_CONVENIO = ('Convênio sem termo de adesão')
def migra_assembleias(filename):
# identificação das colunas nos arquivo CSV
UF_COL = 5
NOME_COL = 8
FONE_1_COL = 32
FONE_2_COL = 33
FAX_COL = 34
FONE_PREFEITURA = 35
OBS_COL = 37
PRESIDENTE_COL = 38
ENDERECO_COL = 39
CEP_COL = 40
EMAIL_COL = 41
EMAIL_PRESIDENTE_COL = 42
PAGINA_COL = 43
#REPRESENTANTE_COL = 86
reader = csv.reader(open(filename, 'r'), delimiter='|', skipinitialspace=True)
header = reader.next()
tipo_casa = TipoOrgao.objects.filter(sigla='AL').get()
for line in reader:
uf = UnidadeFederativa.objects.get(sigla=line[UF_COL])
municipio = Municipio.objects.get(uf=uf, is_capital=True)
aux_end = line[ENDERECO_COL].split('-')
bairro = ''
if(aux_end.__len__() > 1):
bairro = aux_end[1].replace(' ', '', 1)
else:
bairro = ''
casa = Orgao(
municipio=municipio,
nome=line[NOME_COL],
tipo=tipo_casa,
logradouro=aux_end[0],
bairro=bairro,
cep=line[CEP_COL],
email=line[EMAIL_COL],
pagina_web=line[PAGINA_COL],
observacoes=line[OBS_COL],
presidente=line[PRESIDENTE_COL],
telefone=line[FONE_1_COL]
)
if line[UF_COL] == 'DF':
casa.tipo = TipoOrgao.objects.filter(sigla='CT').get()
casa.save()
if line[FONE_2_COL]:
fone2 = Telefone(numero=line[FONE_2_COL], tipo='I', content_object=casa)
fone2.save()
if line[FAX_COL]:
fax = Telefone(numero=line[FAX_COL], tipo='X', content_object=casa)
fax.save()
if line[FONE_PREFEITURA]:
fone_prefeitura = Telefone(
numero=line[FONE_PREFEITURA],
tipo='F',
content_object=casa,
nota='Telefone da Prefeitura.'
)
fone_prefeitura.save()
# Presidente será um atributo de casa legislativa
# if line[REPRESENTANTE_COL]:
# representante = Contato(nome=line[REPRESENTANTE_COL], content_object=casa)
# representante.save()
# if line[PRESIDENTE_COL]:
# mesa = MesaDiretora(casa_legislativa=casa)
# mesa.save()
# parlamentar = Parlamentar(nome_completo=line[PRESIDENTE_COL], email=line[EMAIL_PRESIDENTE_COL])
# parlamentar.save()
# cargo_presidente = Cargo.objects.get(descricao__iexact='presidente')
# presidente = MembroMesaDiretora(
# parlamentar=parlamentar,
# cargo=cargo_presidente,
# mesa_diretora=mesa
# )
# presidente.save()
def migra_casas(filename):
# identificação das colunas no arquivo CSV
COD_IBGE_COL = 1
COD_TSE_COL = 2
NOME_COL = 8
ENDERECO_COL = 40
CEP_COL = 41
EMAIL_COL = 42
PAGINA_COL = 44
OBS_COL = 38
FONE_1_COL = 33
FONE_2_COL = 34
FAX_COL = 35
FONE_PREFEITURA = 36
PRESIDENTE_COL = 39
EMAIL_PRESIDENTE_COL = 43
REPRESENTANTE_COL = 85
reader = csv.reader(open(filename, 'r'), delimiter='|', skipinitialspace=True)
header = reader.next()
tipo_casa = TipoOrgao.objects.filter(sigla='CM').get()
linenum = 1
for line in reader:
linenum += 1
try:
municipio = Municipio.objects.get(codigo_ibge=line[COD_IBGE_COL])
except Municipio.DoesNotExist:
print "Municipio não existe"
print ERROR_MSG_1 % (filename, linenum)
continue
except ValueError:
print ERROR_MSG_1 % (filename, linenum)
continue
aux_end = line[ENDERECO_COL].split('-')
bairro = ''
if(aux_end.__len__() > 1):
bairro = aux_end[1].replace(' ', '', 1)
casa = Orgao(
municipio=municipio,
nome='Câmara Municipal de ' + line[NOME_COL],
tipo=tipo_casa,
logradouro=aux_end[0],
bairro=bairro,
cep=line[CEP_COL],
email=line[EMAIL_COL],
pagina_web=line[PAGINA_COL],
observacoes=line[OBS_COL],
presidente=line[PRESIDENTE_COL],
telefone=line[FONE_1_COL]
)
try:
casa.save()
except:
print "Erro ao inserir casa..."
print ERROR_MSG_0 % (filename, linenum)
continue
if line[FONE_2_COL]:
fone2 = Telefone(numero=line[FONE_2_COL], tipo='I', content_object=casa)
fone2.save()
if line[FAX_COL]:
fax = Telefone(numero=line[FAX_COL], tipo='X', content_object=casa)
fax.save()
if line[FONE_PREFEITURA]:
fone_prefeitura = Telefone(
numero=line[FONE_PREFEITURA],
tipo='F',
content_object=casa,
nota='Telefone da Prefeitura.'
)
fone_prefeitura.save()
if line[REPRESENTANTE_COL]:
representante = Contato(nome=line[REPRESENTANTE_COL], content_object=casa)
representante.save()
def migra_cnpj(filename):
# identificação das colunas no arquivo CSV
COD_TSE_COL = 0
COD_CNPJ1_COL = 3
COD_CNPJ2_COL = 4
reader = csv.reader(open(filename, 'r'), delimiter='|', skipinitialspace=True)
header = reader.next()
linenum = 1
for line in reader:
linenum += 1
try:
casa = Orgao.objects.get(municipio__codigo_tse=line[COD_TSE_COL])
except Orgao.DoesNotExist:
print ERROR_MSG_1 % (filename, linenum)
continue
except Orgao.MultipleObjectsReturned:
print ERROR_MSG_1 % (filename, linenum)
continue
except ValueError:
print ERROR_MSG_1 % (filename, linenum)
continue
casa.cnpj = line[COD_CNPJ1_COL] if not 'EM BRANCO' in line[COD_CNPJ1_COL] else line[COD_CNPJ2_COL]
casa.save()
def migra_convenios_casas(filename):
def get_datetime_obj(data):
ldata = data.split('-')
if len(ldata) != 3:
return None
return datetime(int(ldata[0]), int(ldata[1]), int(ldata[2]))
# identificação das colunas no arquivo CSV
# No arquivo CSV colunas que contém _100 são do Programa Interlegis
COD_IBGE_COL = 1
DATA_ADESAO_COL = 10
DATA_TERMO_ACEITE_COL = 21
NUM_CONVENIO_COL = 23
DATA_POSTAGEM_CORREIO = 26
NUM_PROCESSO_SF_COL = 27
DATA_RETORNO_ASSINATURA = 28
DATA_PUB_DIARIO = 30
DATA_DEV_VIA_CONV_CM = 32
DATA_ADESAO_100_COL = 11
DATA_TERMO_ACEITE_100_COL = 22
NUM_CONVENIO_100_COL = 24
NUM_PROCESSO_SF_100_COL = 25
DATA_RETORNO_ASSINATURA_100_COL = 29
DATA_PUB_DIARIO_100_COL = 31
# DATA_DEV_VIA_CONV_CM_100 = 32 Não foi registrado para as 100
#DATA_POSTAGEM_CORREIO_100 = 26
reader = csv.reader(open(filename, 'r'), delimiter='|', skipinitialspace=True)
header = reader.next()
linenum = 1
###Geração de arquivos para análise###
import codecs
f1 = codecs.open('file1.txt', 'w', encoding="utf-8")
f1.write(u'Casas que não tem Número Processo Senado Federal\n')
f2 = codecs.open('file2.txt', 'w', encoding="utf-8")
f2.write(u'Casas que não tem data de adesão e não tem convênio mas recebeu equipamentos\n')
######
for line in reader:
linenum += 1
try:
casa = Orgao.objects.get(municipio__codigo_ibge=line[COD_IBGE_COL])
except Orgao.DoesNotExist:
print "Erro ao inserir convênio. Casa não existe"
print ERROR_MSG_1 % (filename, linenum)
continue
except Orgao.MultipleObjectsReturned:
print ERROR_MSG_1 % (filename, linenum)
continue
except ValueError:
print ERROR_MSG_1 % (filename, linenum)
continue
# Se o convênio não tiver data de adesão mas tiver data retorno assinatura copiar essa data para a data de adesão.
obs = ''
projeto = None
convenio1 = None
convenio2 = None
if line[DATA_ADESAO_COL] == '1001-01-01' and line[DATA_RETORNO_ASSINATURA].__len__() != 0:
line[DATA_ADESAO_COL] = line[DATA_RETORNO_ASSINATURA]
obs = OBS_CONVENIO
if line[DATA_ADESAO_COL] != '1001-01-01':
projeto = Projeto.objects.get(id=1)
if projeto:
convenio1 = Convenio(
casa_legislativa=casa,
projeto=projeto,
num_processo_sf=line[NUM_PROCESSO_SF_COL],
num_convenio=line[NUM_CONVENIO_COL],
data_adesao=get_datetime_obj(line[DATA_ADESAO_COL]),
data_retorno_assinatura=get_datetime_obj(line[DATA_TERMO_ACEITE_COL]),
data_pub_diario=get_datetime_obj(line[DATA_RETORNO_ASSINATURA]),
data_termo_aceite=get_datetime_obj(line[DATA_PUB_DIARIO]),
data_devolucao_via=get_datetime_obj(line[DATA_DEV_VIA_CONV_CM]),
data_postagem_correio=get_datetime_obj(line[DATA_POSTAGEM_CORREIO]),
observacao=obs,)
###Relatório###
if((projeto or line[DATA_TERMO_ACEITE_COL]) and line[NUM_PROCESSO_SF_COL].__len__() == 0):
f1.write(casa.nome + "," + casa.municipio.uf.sigla + "\n")
if(projeto is None and line[DATA_TERMO_ACEITE_COL].__len__() != 0):
f2.write(casa.nome + "," + casa.municipio.uf.sigla + "\n")
######
projeto = None
obs = ''
if line[DATA_ADESAO_100_COL] == '1001-01-01' and line[DATA_RETORNO_ASSINATURA_100_COL].__len__() != 0:
line[DATA_ADESAO_100_COL] = line[DATA_RETORNO_ASSINATURA_100_COL]
obs = OBS_CONVENIO
if line[DATA_ADESAO_100_COL] != '1001-01-01':
projeto = Projeto.objects.get(id=2)
if projeto:
convenio2 = Convenio(
casa_legislativa=casa,
projeto=projeto,
num_processo_sf=line[NUM_PROCESSO_SF_100_COL],
num_convenio=line[NUM_CONVENIO_100_COL],
data_adesao=get_datetime_obj(line[DATA_ADESAO_100_COL]),
data_retorno_assinatura=get_datetime_obj(line[DATA_TERMO_ACEITE_100_COL]),
data_pub_diario=get_datetime_obj(line[DATA_RETORNO_ASSINATURA_100_COL]),
data_termo_aceite=get_datetime_obj(line[DATA_PUB_DIARIO_100_COL]),
observacao=obs,
)
try:
if convenio1:
convenio1.save()
if convenio2:
convenio2.save()
except:
print "Erro ao inserir convênio"
print ERROR_MSG_0 % (filename, linenum)
continue
f1.close()
f2.close()
def migra_convenios_assembleias(filename):
def get_datetime_obj(data):
ldata = data.split('-')
if len(ldata) != 3:
return None
return datetime(int(ldata[0]), int(ldata[1]), int(ldata[2]))
# identificação das colunas no arquivo CSV
SIGLA_COL = 5
DATA_ADESAO_COL = 10
DATA_TERMO_ACEITE_COL = 21
NUM_CONVENIO_COL = 23
NUM_PROCESSO_SF_COL = 26
DATA_RETORNO_ASSINATURA = 27
DATA_PUB_DIARIO = 29
reader = csv.reader(open(filename, 'r'), delimiter='|', skipinitialspace=True)
header = reader.next()
linenum = 1
tipo_casa = TipoOrgao.objects.filter(sigla='AL').get()
for line in reader:
linenum += 1
try:
assembleia = Orgao.objects.get(municipio__uf__sigla=line[SIGLA_COL], tipo=tipo_casa)
except Orgao.DoesNotExist:
print ERROR_MSG_1 % (filename, linenum)
continue
except Orgao.MultipleObjectsReturned:
print ERROR_MSG_1 % (filename, linenum)
continue
except ValueError:
print ERROR_MSG_1 % (filename, linenum)
continue
projeto = Projeto.objects.get(id=2)
convenio = Convenio(
casa_legislativa=assembleia,
num_processo_sf=line[NUM_PROCESSO_SF_COL],
num_convenio=line[NUM_CONVENIO_COL],
projeto=projeto,
data_adesao=get_datetime_obj(line[DATA_ADESAO_COL]),
data_retorno_assinatura=get_datetime_obj(line[DATA_TERMO_ACEITE_COL]),
data_pub_diario=get_datetime_obj(line[DATA_RETORNO_ASSINATURA]),
data_termo_aceite=get_datetime_obj(line[DATA_PUB_DIARIO]),
)
try:
convenio.save()
except:
print ERROR_MSG_0 % (filename, linenum)
print convenio
continue
def popula():
"""
Será preciso cadastrar no banco os seguintes Projeto:
1 - Projeto Interlegis
2 - Projeto Piloto de Modernização
3 - Projeto Modernização Legislativo
"""
projeto1 = Projeto(sigla='PI', nome='Projeto Interlegis')
projeto1.save()
projeto2 = Projeto(sigla='PPM', nome='Projeto Piloto de Modernização')
projeto2.save()
projeto3 = Projeto(sigla='PML', nome='Projeto Modernização Legislativo')
projeto3.save()
tipo1 = TipoOrgao(sigla='CM', nome='Câmara Municipal')
tipo1.save()
tipo2 = TipoOrgao(sigla='AL', nome='Assembléia Legislativa')
tipo2.save()
tipo3 = TipoOrgao(sigla='CT', nome='Câmara Distrital')
tipo3.save()
if __name__ == '__main__':
popula()
print "<iniciando migração das assembléias legislativas>"
migra_assembleias('assembleias.csv')
print "<iniciando migração das demais casas legislativas>"
migra_casas('casas.csv')
print "<iniciando migração dos CNPJ das casas>"
migra_cnpj('cnpj.csv')
print "<iniciando migração dos convênios das casas municipais>"
migra_convenios_casas('casas.csv')
print "<iniciando migração dos convênios das assembléias>"
migra_convenios_assembleias('assembleias.csv')

31
etc/nginx/sites-available/sigi.vhost

@ -1,31 +0,0 @@
upstream sigi_app_server {
server unix:/var/run/sigi/sigi.sock fail_timeout=0;
}
server {
listen 80;
server_name sigi01h.interlegis.leg.br;
client_max_body_size 4G;
access_log /var/log/sigi/sigi-access.log;
error_log /var/log/sigi/sigi-error.log;
location /static/ {
alias /srv/sigi/static/;
}
location /media/ {
alias /srv/sigi/media/;
}
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
if (!-f $request_filename) {
proxy_pass http://sigi_app_server;
break;
}
}
}

5
etc/supervisor/conf.d/sigi.conf

@ -1,5 +0,0 @@
[program:sigi]
command = /srv/sigi/bin/run_sigi
user = sigi
stdout_logfile = /var/log/sigi/sigi-supervisor.log
redirect_stderr = true

39
install.sh

@ -1,39 +0,0 @@
#!/bin/bash
THIS_SHELL=`ps --no-heading -p $$ | awk '{print $4}'`
if [ $THIS_SHELL != 'bash' ] ; then
echo "Você está executando este script com o interpretador '$THIS_SHELL'"
echo "mas ele só funciona com o 'bash'."
echo "Tente executar usando 'bash install.sh'."
exit 1
fi
echo "Instalando python-pip, python-dev e python-psycopg2..."
sudo apt-get install -y python-pip python-dev python-virtualenv
echo "Criando virtualenv..."
virtualenv ./env/
echo "Instalando pacotes python requeridos pelo SIGI..."
pip install --environment=./env/ -r requirements.txt
echo "Ativando o virtualenv..."
source ./env/bin/activate
echo "Isolando arquivos temporários..."
mkdir tmp
echo "Instalando geraldo reports..."
git clone git@github.com:marinho/geraldo.git
cd geraldo
python setup.py install
cp -Rfv reporting geraldo `python -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())"`
cd ..
echo "Excluindo arquivos temporários..."
cd ..
rm -Rf tmp
echo "Criando e populando o banco de dados..."
pwd
python manage.py syncdb

20
manage.py

@ -1,10 +1,22 @@
#!/usr/bin/env python
"""Django's command-line utility for administrative tasks."""
import os
import sys
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "sigi.settings")
from django.core.management import execute_from_command_line
def main():
"""Run administrative tasks."""
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'sigi.settings')
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
) from exc
execute_from_command_line(sys.argv)
if __name__ == '__main__':
main()

13
puppet/bootstrap.sh

@ -1,13 +0,0 @@
#!/bin/bash
puppet_install () {
puppet module list | grep $1 || puppet module install $1
}
puppet_install puppetlabs-vcsrepo
puppet_install stankevich-python
# XXX Usando provisoriamente o modulo oficial ate que sincronizemos nosso repo
# XXX retirar esta linha entao
puppet_install jfryman-nginx

212
puppet/manifests/site.pp

@ -1,212 +0,0 @@
Exec {
path => '/usr/bin:/usr/sbin:/bin:/usr/local/bin',
}
group { 'sigi':
ensure => 'present',
}
user { 'sigi':
ensure => 'present',
system => true,
gid => 'sigi',
require => Group['sigi']
}
$package_deps = [
# gerais
'git', 'supervisor', 'memcached',
# para psycopg ('python-dev' ja eh instalado pelo modulo python)
'libpq-dev',
# para ldap
'libldap2-dev', 'libsasl2-dev', 'libssl-dev']
package { $package_deps: }
$sigi_dir = '/srv/sigi'
$sigidata_dir = '/srv/sigidata'
vcsrepo { $sigi_dir:
ensure => latest,
provider => git,
source => 'https://github.com/interlegis/sigi.git',
revision => 'producao',
require => Package['git'],
}
file { [
'/var/log/sigi',
'/var/run/sigi',
]:
ensure => 'directory',
owner => 'sigi',
group => 'sigi',
require => Vcsrepo[$sigi_dir],
}
file { "${sigi_dir}/media":
ensure => link,
target => "${sigidata_dir}/media",
}
# TODO A pasta "${sigi_dir}/media" deve ser compartilhada entre instancias de cluster
file { '/var/log/sigi/sigi-supervisor.log':
ensure => file,
}
###########################################################################
# PYTHON
if !defined(Class['python']) {
class { 'python':
version => 'system',
dev => true,
virtualenv => true,
pip => true,
}
}
$sigi_venv_dir = '/srv/.virtualenvs/sigi'
file { ['/srv/.virtualenvs',]:
ensure => 'directory',
}
python::virtualenv { $sigi_venv_dir :
require => File['/srv/.virtualenvs'],
}
python::requirements { "${sigi_dir}/requirements/requirements.txt":
virtualenv => $sigi_venv_dir,
forceupdate => true,
require => [
Python::Virtualenv[$sigi_venv_dir],
Vcsrepo[$sigi_dir],
Package[$package_deps] ]
}
###########################################################################
# GERALDO (reporting)
file { "${sigi_venv_dir}/lib/python2.7/site-packages/reporting":
ensure => link,
target => "${sigi_venv_dir}/src/geraldo/reporting",
}
###########################################################################
# DJANGO
exec { 'collectstatic':
command => "${sigi_venv_dir}/bin/python manage.py collectstatic --noinput",
cwd => $sigi_dir,
require => [
Python::Virtualenv[$sigi_venv_dir],
Vcsrepo[$sigi_dir],
Python::Requirements["${sigi_dir}/requirements/requirements.txt"],
]
}
# TODO local_settings.py ...
###########################################################################
# SUPERVISOR
# XXX trocar isso por algum plugin do puppet?
$supervisor_conf = '/etc/supervisor/conf.d/sigi.conf'
file { $supervisor_conf:
ensure => link,
target => "${sigi_dir}/etc/supervisor/conf.d/sigi.conf",
require => [
Vcsrepo[$sigi_dir],
Package['supervisor'] ]
}
exec { 'supervisor_update':
command => 'supervisorctl reread && supervisorctl update',
refreshonly => true,
subscribe => [ File[$supervisor_conf], Vcsrepo[$sigi_dir]],
}
###########################################################################
# NGINX
class { 'nginx': }
nginx::resource::upstream { 'sigi_app_server':
members => [ 'unix:/var/run/sigi/sigi.sock' ],
upstream_fail_timeout => 0
}
# XXX trocar nome para server_name, p.ex. sigi01h.interlegis.leg.br
$sigi_vhost = 'localhost'
nginx::resource::vhost { $sigi_vhost:
client_max_body_size => '4G',
access_log => '/var/log/sigi/sigi-access.log',
error_log => '/var/log/sigi/sigi-error.log',
use_default_location => false,
require => Vcsrepo[$sigi_dir],
# TODO tentar usar try_files ao inves desse "if"
# vide http://stackoverflow.com/questions/19845566/in-nginxs-configuration-could-if-f-request-filename-cause-a-performan
# XXX este raw_append foi uma apelacao devido a limitacoes do modulo nginx
raw_append => '
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
if (!-f $request_filename) {
proxy_pass http://sigi_app_server;
break;
}
}
'
}
nginx::resource::location { '/static/':
vhost => $sigi_vhost,
location_alias => '/srv/sigi/static/',
}
nginx::resource::location { '/media/':
vhost => $sigi_vhost,
location_alias => '/srv/sigi/media/',
}
###########################################################################
# CRON
cron { 'atualiza_uso_servico':
command => "${sigi_venv_dir}/bin/python ${sigi_dir}/manage.py atualiza_uso_servico -v 0",
user => 'sigi',
hour => [0,]
}
cron { 'clearsessions':
command => "${sigi_venv_dir}/bin/python ${sigi_dir}/manage.py clearsessions -v 0",
user => 'sigi',
hour => [0,]
}
cron { 'sync_ldap':
command => "${sigi_venv_dir}/bin/python ${sigi_dir}/manage.py sync_ldap",
user => 'sigi',
hour => [0,]
}
cron { 'gera_map_data':
command => "${sigi_venv_dir}/bin/python ${sigi_dir}/manage.py gera_map_data",
user => 'sigi',
hour => "*/1",
}
cron { 'get_moodle_stats':
command => "${sigi_venv_dir}/bin/python ${sigi_dir}/manage.py get_moodle_stats -v 0",
user => 'sigi',
hour => "*/1",
}

23
puppet/puppet_module_install_from_github.sh

@ -1,23 +0,0 @@
#!/bin/bash
# argumentos: <nome do modulo> <github_user/nome_repo>
nome_modulo=$1
github_path=$2
nome_repo=$(echo $github_path | cut -d / -f 2)
modulo_instalado=$( puppet module list | grep -ic $nome_modulo )
if [ $modulo_instalado -eq 0 ]
then
TAR_FILE="/tmp/$nome_modulo.tar.gz"
wget "https://github.com/$github_path/archive/master.tar.gz" -O $TAR_FILE
rm -fr "/tmp/$nome_repo-master"
tar -C /tmp -xf $TAR_FILE
echo "Building module $nome_modulo..."
TAR_MODULE=$(puppet module build "/tmp/$nome_repo-master" | grep 'Module built' | cut -d\ -f 3)
echo "Installing module $nome_modulo from " $TAR_MODULE ' ...'
puppet module install $TAR_MODULE
fi

9
pytest.ini

@ -1,9 +0,0 @@
[pytest]
DJANGO_SETTINGS_MODULE=sigi.settings.test
# REUSING DATABASE BY DEFAULT (as a performance optimization)
# http://pytest-django.readthedocs.org/en/latest/database.html#example-work-flow-with-reuse-db-and-create-db
#
# Run "py.test --create-db" if you need to recreate the database
#
addopts = --reuse-db

8
requirements/dev-requirements.txt

@ -1,5 +1,3 @@
-r test-requirements.txt
django-debug-toolbar==1.2.2
ipdb==0.8
ipython==2.3.1
pygraphviz==1.2
-r requirements.txt
pygraphviz==1.7
django-extensions==3.1.3

7
requirements/observacoes.txt

@ -1,7 +0,0 @@
Observações sobre as dependências:
Produção:
* Geraldo: Eh importante usar "-e" pois precisamos do modulo reporting do fonte que nao eh instalado
Desevenvolvimento:
* pygraphviz: para usar o comando "graph_models" do "django-extensions"

27
requirements/requirements.txt

@ -1,23 +1,4 @@
-e git://github.com/marinho/geraldo.git@868ebdce67176d9b6205cddc92476f642c783fff#egg=geraldo
django-bootstrap3==6.2.2
django-admin-bootstrapped==2.4.0
django-auth-ldap==1.2.7
django-autoslug==1.9.3
django-extensions==1.5.7
django-image-cropping==1.0.2
django-localflavor==1.1
Django==1.7.10
easy-thumbnails==2.2
eav-django==1.4.7
gunicorn==19.3.0
html5lib==0.9999999
Pillow==2.9.0
pisa==3.0.33
psycopg2==2.6.1
python-memcached==1.53
PyYAML==3.11
reportlab==2.7
requests==2.8.1
six==1.10.0
djangorestframework==2.4.8
django-ipware==1.1.6
ipython==7.24.1
Django==3.2.4
psycopg2==2.8.6
django-bootstrap5==2.0.1

10
requirements/test-requirements.txt

@ -1,10 +0,0 @@
-r requirements.txt
coverage==3.7.1
django-dynamic-fixture==1.8.1
django-webtest==1.7.7
pyPdf==1.13
pyquery==1.2.9
pytest-cov==1.8.1
pytest-django==2.8.0
pytest==2.6.4
WebTest==2.0.17

8
setup.py

@ -1,8 +0,0 @@
# py.test precisa deste arquivo para que o projeto seja instalado no virtualenv com:
# "pip install -e ."
# vide http://pytest-django.readthedocs.org/en/latest/faq.html#i-see-an-error-saying-could-not-import-myproject-settings
#
from distutils.core import setup
setup(name='sigi', version='2.x')

66
sigi/apps/contatos/admin.py

@ -1,12 +1,12 @@
# -*- coding: utf-8 -*-
from django.contrib import admin
from django.utils.translation import ugettext as _
from sigi.apps.contatos.filters import PopulationFilter
from sigi.apps.contatos.models import (UnidadeFederativa, Mesorregiao, Microrregiao,
Municipio, Telefone, Contato)
from sigi.apps.contatos.models import (UnidadeFederativa, Mesorregiao,
Microrregiao, Municipio)
from sigi.apps.utils import queryset_ascii
from sigi.apps.utils.base_admin import BaseModelAdmin
from sigi.apps.utils.filters import (MultiChoicesFieldListFilter,
MultiRelatedFieldListFilter,
RangeFieldListFilter)
class MesorregiaoInline(admin.TabularInline):
model = Mesorregiao
@ -14,59 +14,51 @@ class MesorregiaoInline(admin.TabularInline):
class MicrorregiaoInline(admin.TabularInline):
model = Microrregiao
class UnidadeFederativaAdmin(BaseModelAdmin):
@admin.register(UnidadeFederativa)
class UnidadeFederativaAdmin(admin.ModelAdmin):
actions = None
list_display = ('codigo_ibge', 'nome', 'sigla', 'regiao', 'populacao')
list_display_links = ('codigo_ibge', 'nome')
list_filter = ('regiao', 'populacao', PopulationFilter,)
list_filter = (
('regiao', MultiChoicesFieldListFilter),
('populacao', RangeFieldListFilter),
)
search_fields = ('search_text', 'codigo_ibge', 'sigla', 'regiao')
get_queryset = queryset_ascii
queryset = queryset_ascii
inlines = (MesorregiaoInline, )
class MesorregiaoAdmin(BaseModelAdmin):
@admin.register(Mesorregiao)
class MesorregiaoAdmin(admin.ModelAdmin):
actions = None
list_display = ('codigo_ibge', 'uf', 'nome')
list_display_links = ('codigo_ibge', 'nome')
list_filter = ('uf',)
search_fields = ('uf__search_text', 'search_text', 'codigo_ibge', 'uf__sigla')
search_fields = ('uf__search_text', 'search_text', 'codigo_ibge',
'uf__sigla')
get_queryset = queryset_ascii
inlines = (MicrorregiaoInline,)
class MunicipioAdmin(BaseModelAdmin):
@admin.register(Municipio)
class MunicipioAdmin(admin.ModelAdmin):
actions = None
list_display = ('codigo_ibge', 'codigo_tse', 'nome', 'uf', 'is_capital', 'populacao', 'is_polo', 'idh', 'pib_ano',
'pib_total', 'pib_percapita')
list_display = ('codigo_ibge', 'codigo_tse', 'nome', 'uf', 'is_capital',
'populacao', 'is_polo', 'idh', 'pib_ano', 'pib_total',
'pib_percapita')
list_display_links = ('codigo_ibge', 'codigo_tse', 'nome')
list_filter = ('is_capital', 'is_polo', 'idh', 'populacao', 'uf', )
list_filter = ('is_capital', 'is_polo', ('idh', RangeFieldListFilter),
('populacao', RangeFieldListFilter),
('uf', MultiRelatedFieldListFilter),
('uf__regiao', MultiChoicesFieldListFilter))
get_queryset = queryset_ascii
fieldsets = (
(None, {
'fields': ('codigo_ibge', 'codigo_tse', 'nome', 'data_criacao', 'uf', 'microrregiao',
'is_capital', 'populacao', 'is_polo', 'idh', 'pib_ano', 'pib_total', 'pib_percapita')
'fields': ('codigo_ibge', 'codigo_tse', 'nome', 'data_criacao',
'uf', 'microrregiao', 'is_capital', 'populacao',
'is_polo', 'idh', 'pib_ano', 'pib_total',
'pib_percapita')
}),
(_(u'Posição geográfica'), {
'fields': ('latitude', 'longitude'),
}),
)
search_fields = ('search_text', 'codigo_ibge', 'codigo_tse', 'uf__sigla')
class TelefoneAdmin(BaseModelAdmin):
list_display = ('numero', 'tipo', 'nota')
list_display_links = ('numero',)
list_filter = ('tipo',)
radio_fields = {'tipo': admin.VERTICAL}
search_fields = ('numero', 'tipo', 'nota')
class ContatoAdmin(BaseModelAdmin):
list_display = ('nome', 'nota', 'email', 'municipio')
list_display_links = ('nome',)
list_filter = ('nome',)
search_fields = ('nome', 'nota', 'email', 'municipio__nome', 'municipio__uf__nome')
admin.site.register(UnidadeFederativa, UnidadeFederativaAdmin)
admin.site.register(Mesorregiao, MesorregiaoAdmin)
admin.site.register(Municipio, MunicipioAdmin)
admin.site.register(Telefone, TelefoneAdmin)
admin.site.register(Contato, ContatoAdmin)

124
sigi/apps/contatos/management/commands/importa_mesomicro.py

@ -1,100 +1,96 @@
# -*- coding: utf-8 -*-
#
# sigi.apps.contatos.management.commands.importa_mesomicro
#
# Copyright (c) 2015 by Interlegis
#
# GNU General Public License (GPL)
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.
#
import csv
import os
from django.core.management.base import BaseCommand, CommandError
from sigi.apps.contatos.models import Municipio, UnidadeFederativa, Mesorregiao, Microrregiao
from django.core.management.base import BaseCommand, CommandError, CommandParser
from sigi.apps.contatos.models import (Municipio, UnidadeFederativa,
Mesorregiao, Microrregiao)
class Command(BaseCommand):
args = u"data_file.csv"
help = u"""Importa arquivo do IBGE para preencher as tabelas de meso e microrregiões para os municípios.
A primeira linha do arquivo deve possuir um cabeçalho com os seguintes campos obrigatórios:
- cod_uf : Código IBGE da Unidade da Federação
- cod_mesorregiao : Código IBGE da mesorregião
- nome_mesorregiao : Nome da mesorregião
- cod_microrregiao : Código IBGE da microrregião
- nome_microrregiao : Nome da microrregião
- cod_municipio : Código IBGE do município
* Os nomes dos campos devem ser grafados exatamente como descrito."""
campos = {'cod_uf', 'cod_mesorregiao', 'nome_mesorregiao', 'cod_microrregiao',
'nome_microrregiao', 'cod_municipio'}
help = """
Importa arquivo do IBGE para preencher as tabelas de meso e microrregiões para
os municípios. A primeira linha do arquivo deve possuir um cabeçalho com os
seguintes campos obrigatórios (Os nomes dos campos devem ser grafados exatamente
como descrito):
"cod_uf" (Código IBGE da Unidade da Federação),
"cod_mesorregiao" (Código IBGE da mesorregião),
"nome_mesorregiao" (Nome da mesorregião),
"cod_microrregiao" (Código IBGE da microrregião),
"nome_microrregiao" (Nome da microrregião),
"cod_municipio" (Código IBGE do município\n)
"""
campos = {'cod_uf', 'cod_mesorregiao', 'nome_mesorregiao',
'cod_microrregiao', 'nome_microrregiao', 'cod_municipio'}
def add_arguments(self, parser: CommandParser) -> None:
parser.add_argument('file_name', type=str,
help="Arquivo CSV a ser importado")
def handle(self, *args, **options):
if len(args) != 1:
raise CommandError(u"Informe UM arquivo csv a importar")
file_name = args[0]
file_name = options['file_name']
if not os.path.isfile(file_name):
raise CommandError(u"Arquivo %s não encontrado" % [file_name,])
raise CommandError("Arquivo %s não encontrado" % file_name)
with open(file_name, 'rb') as csvfile:
with open(file_name, 'rt') as csvfile:
reader = csv.DictReader(csvfile)
if not self.campos.issubset(reader.fieldnames):
raise CommandError(u"O arquivo não possui todos os campos obrigatórios")
raise CommandError(
"O arquivo não possui todos os campos obrigatórios"
)
erros = 0
for reg in reader:
try:
uf = UnidadeFederativa.objects.get(codigo_ibge=reg['cod_uf'])
uf = UnidadeFederativa.objects.get(
codigo_ibge=reg['cod_uf']
)
except UnidadeFederativa.DoesNotExist:
self.stdout.write(u"(Linha %s): não existe UF com código IBGE '%s'" %
(reader.line_num, reg['cod_uf'],))
self.stdout.write(self.style.ERROR(
"(Linha %s): não existe UF com código IBGE '%s'" %
(reader.line_num, reg['cod_uf'])
))
erros = erros + 1
continue
try:
municipio = Municipio.objects.get(codigo_ibge=reg['cod_municipio'])
municipio = Municipio.objects.get(
codigo_ibge=reg['cod_municipio']
)
except Municipio.DoesNotExist:
self.stdout.write(u"(Linha %s): não existe Município com código IBGE '%s'" %
(reader.line_num, reg['cod_municipio'],))
self.stdout.write(self.style.ERROR(
"(Linha %s): não existe Município com código IBGE '%s'"
% (reader.line_num, reg['cod_municipio'])
))
erros = erros + 1
continue
cod_meso = reg['cod_uf'] + reg['cod_mesorregiao']
cod_micro = cod_meso + reg['cod_microrregiao']
if Mesorregiao.objects.filter(codigo_ibge=cod_meso).exists():
meso = Mesorregiao.objects.get(codigo_ibge=cod_meso)
else:
meso = Mesorregiao(codigo_ibge=cod_meso, uf=uf, nome=reg['nome_mesorregiao'])
meso.nome = reg['nome_mesorregiao']
meso, _ = Mesorregiao.objects.get_or_create(
codigo_ibge=cod_meso,
defaults={
'uf': uf,
'nome': reg['nome_mesorregiao']
}
)
meso.save()
if Microrregiao.objects.filter(codigo_ibge=cod_micro).exists():
micro = Microrregiao.objects.get(codigo_ibge=cod_micro)
else:
micro = Microrregiao(codigo_ibge=cod_micro, mesorregiao=meso, nome=reg['nome_microrregiao'])
micro.nome = reg['nome_microrregiao']
micro, _ = Microrregiao.objects.get_or_create(
codigo_ibge=cod_micro,
defaults={
'mesorregiao': meso,
'nome': reg['nome_microrregiao']
}
)
micro.save()
municipio.microrregiao = micro
municipio.save()
self.stdout.write(u"Importação concluída. %s erros em %s linhas" % (erros, reader.line_num,))
self.stdout.write(self.style.NOTICE(
"Importação concluída. %s erros em %s linhas" %
(erros, reader.line_num)
))

12
sigi/apps/contatos/migrations/0001_initial.py

@ -21,7 +21,7 @@ class Migration(migrations.Migration):
('nota', models.CharField(max_length=70, blank=True)),
('email', models.EmailField(max_length=75, verbose_name='e-mail', blank=True)),
('object_id', models.PositiveIntegerField()),
('content_type', models.ForeignKey(to='contenttypes.ContentType')),
('content_type', models.ForeignKey(to='contenttypes.ContentType', on_delete=models.CASCADE)),
],
options={
'ordering': ('nome',),
@ -42,7 +42,7 @@ class Migration(migrations.Migration):
('bairro', models.CharField(max_length=100, blank=True)),
('cep', models.CharField(help_text='Formato: <em>XXXXX-XXX</em>.', max_length=9, null=True, verbose_name='CEP', blank=True)),
('object_id', models.PositiveIntegerField()),
('content_type', models.ForeignKey(to='contenttypes.ContentType')),
('content_type', models.ForeignKey(to='contenttypes.ContentType', on_delete=models.CASCADE)),
],
options={
'ordering': ('logradouro', 'numero'),
@ -87,7 +87,7 @@ class Migration(migrations.Migration):
('nota', models.CharField(max_length=70, null=True, blank=True)),
('ult_alteracao', models.DateTimeField(auto_now=True, verbose_name='\xdaltima altera\xe7\xe3o', null=True)),
('object_id', models.PositiveIntegerField()),
('content_type', models.ForeignKey(to='contenttypes.ContentType')),
('content_type', models.ForeignKey(to='contenttypes.ContentType', on_delete=models.CASCADE)),
],
options={
'ordering': ('numero',),
@ -118,19 +118,19 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='municipio',
name='uf',
field=models.ForeignKey(verbose_name='UF', to='contatos.UnidadeFederativa'),
field=models.ForeignKey(verbose_name='UF', to='contatos.UnidadeFederativa', on_delete=models.CASCADE),
preserve_default=True,
),
migrations.AddField(
model_name='endereco',
name='municipio',
field=models.ForeignKey(verbose_name='munic\xedpio', blank=True, to='contatos.Municipio', null=True),
field=models.ForeignKey(verbose_name='munic\xedpio', blank=True, to='contatos.Municipio', null=True, on_delete=models.CASCADE),
preserve_default=True,
),
migrations.AddField(
model_name='contato',
name='municipio',
field=models.ForeignKey(verbose_name='munic\xedpio', blank=True, to='contatos.Municipio', null=True),
field=models.ForeignKey(verbose_name='munic\xedpio', blank=True, to='contatos.Municipio', null=True, on_delete=models.CASCADE),
preserve_default=True,
),
]

6
sigi/apps/contatos/migrations/0002_auto_20151104_0810.py

@ -18,7 +18,7 @@ class Migration(migrations.Migration):
('codigo_ibge', models.PositiveIntegerField(help_text='C\xf3digo da mesorregi\xe3o segundo o IBGE', unique=True, serialize=False, verbose_name='C\xf3digo IBGE', primary_key=True)),
('nome', models.CharField(max_length=100, verbose_name='Nome mesorregi\xe3o')),
('search_text', sigi.apps.utils.SearchField(field_names=[b'nome'], editable=False)),
('uf', models.ForeignKey(verbose_name='UF', to='contatos.UnidadeFederativa')),
('uf', models.ForeignKey(verbose_name='UF', to='contatos.UnidadeFederativa', on_delete=models.CASCADE)),
],
options={
'ordering': ('uf', 'nome'),
@ -33,7 +33,7 @@ class Migration(migrations.Migration):
('codigo_ibge', models.PositiveIntegerField(help_text='C\xf3digo da microrregi\xe3o segundo o IBGE', unique=True, serialize=False, verbose_name='C\xf3digo IBGE', primary_key=True)),
('nome', models.CharField(max_length=100, verbose_name='Nome microrregi\xe3o')),
('search_text', sigi.apps.utils.SearchField(field_names=[b'nome'], editable=False)),
('mesorregiao', models.ForeignKey(to='contatos.Mesorregiao')),
('mesorregiao', models.ForeignKey(to='contatos.Mesorregiao', on_delete=models.CASCADE)),
],
options={
'ordering': ('mesorregiao', 'nome'),
@ -53,7 +53,7 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='municipio',
name='microrregiao',
field=models.ForeignKey(verbose_name='Microrregi\xe3o', blank=True, to='contatos.Microrregiao', null=True),
field=models.ForeignKey(verbose_name='Microrregi\xe3o', blank=True, to='contatos.Microrregiao', null=True, on_delete=models.CASCADE),
preserve_default=True,
),
]

364
sigi/apps/contatos/models.py

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
from django.contrib.contenttypes import generic
from django.contrib.contenttypes.fields import (GenericForeignKey,
GenericRelation)
from django.contrib.contenttypes.models import ContentType
from django.core.validators import MaxValueValidator, MinValueValidator
from django.db import models
@ -7,335 +7,319 @@ from django.utils.translation import ugettext as _
from sigi.apps.utils import SearchField
class UnidadeFederativa(models.Model):
""" Modelo que representa um estado brasileiro
"""
REGIAO_CHOICES = (
('CO', _(u'Centro-Oeste')),
('NE', _(u'Nordeste')),
('NO', _(u'Norte')),
('SD', _(u'Sudeste')),
('SL', _(u'Sul')),
('CO', _('Centro-Oeste')),
('NE', _('Nordeste')),
('NO', _('Norte')),
('SD', _('Sudeste')),
('SL', _('Sul')),
)
codigo_ibge = models.PositiveIntegerField(
u'código IBGE',
_('código IBGE'),
primary_key=True,
unique=True,
help_text=_(u'Código do estado segundo IBGE.')
help_text=_('código do estado segundo IBGE.')
)
nome = models.CharField(_(u'Nome UF'), max_length=25)
# Campo de busca em caixa baixa sem acento
nome = models.CharField(_('nome UF'), max_length=25)
search_text = SearchField(field_names=['nome'])
sigla = models.CharField(
_('sigla'),
max_length=2,
unique=True,
help_text=_(u"Exemplo") + ": <em>MG</em>.",
help_text=_(u"Exemplo: <em>MG</em>."),
)
regiao = models.CharField(_(u'região'), max_length=2, choices=REGIAO_CHOICES)
populacao = models.PositiveIntegerField(_(u'população'))
regiao = models.CharField(_('região'), max_length=2, choices=REGIAO_CHOICES)
populacao = models.PositiveIntegerField(_('população'))
class Meta:
ordering = ('nome',)
verbose_name = _(u'Unidade Federativa')
verbose_name_plural = _(u'Unidades Federativas')
verbose_name = _('Unidade Federativa')
verbose_name_plural = _('Unidades Federativas')
def __unicode__(self):
def __str__(self):
return self.nome
class Mesorregiao(models.Model):
codigo_ibge = models.PositiveIntegerField(
_(u'Código IBGE'),
_('código IBGE'),
primary_key=True,
unique=True,
help_text=_(u'Código da mesorregião segundo o IBGE')
help_text=_('código da mesorregião segundo o IBGE')
)
uf = models.ForeignKey(
UnidadeFederativa,
on_delete=models.CASCADE,
verbose_name=_(u'UF')
verbose_name=_('UF')
)
nome = models.CharField(_(u"Nome mesorregião"), max_length=100)
# Campo de busca em caixa baixa sem acento
nome = models.CharField(_(u"nome mesorregião"), max_length=100)
search_text = SearchField(field_names=['nome'])
class Meta:
ordering = ('uf', 'nome',)
verbose_name, verbose_name_plural = _(u'Mesorregião'), _(u'Mesorregiões')
verbose_name = _('mesorregião')
verbose_name_plural = _('mesorregiões')
def __unicode__(self):
def __str__(self):
return self.nome
class Microrregiao(models.Model):
codigo_ibge = models.PositiveIntegerField(
_(u'Código IBGE'),
_('código IBGE'),
primary_key=True,
unique=True,
help_text=_(u'Código da microrregião segundo o IBGE')
help_text=_('código da microrregião segundo o IBGE')
)
mesorregiao = models.ForeignKey(
Mesorregiao,
on_delete=models.CASCADE
on_delete=models.CASCADE,
verbose_name=_('mesorregião')
)
nome = models.CharField(_(u"Nome microrregião"), max_length=100)
# Campo de busca em caixa baixa sem acento
nome = models.CharField(_(u"nome microrregião"), max_length=100)
search_text = SearchField(field_names=['nome'])
class Meta:
ordering = ('nome',)
verbose_name, verbose_name_plural = _(u'Microrregião'), _(u'Microrregiões')
verbose_name = _('microrregião')
verbose_name_plural = _('microrregiões')
def __unicode__(self):
def __str__(self):
return u"%s (%s)" % (self.nome, self.mesorregiao.nome)
class Municipio(models.Model):
""" Modelo para representar as cidades brasileiras
"""
codigo_ibge = models.PositiveIntegerField(
_(u'código IBGE'),
_('código IBGE'),
primary_key=True,
unique=True,
help_text=_(u'Código do município segundo IBGE.')
help_text=_('código do município segundo IBGE.')
)
microrregiao = models.ForeignKey(
Microrregiao,
on_delete=models.PROTECT,
verbose_name=_(u'Microrregião'),
blank=True,
null=True
null=True,
verbose_name=_('microrregião')
)
# codio designado pelo Tribunal Superior Eleitoral
codigo_tse = models.PositiveIntegerField(
_(u'código TSE'),
_('código TSE'),
unique=True,
null=True,
help_text=_(u'Código do município segundo TSE.')
help_text=_('código do município segundo TSE.')
)
nome = models.CharField(max_length=50)
search_text = SearchField(field_names=[_(u'nome'), _(u'uf')])
nome = models.CharField(_('nome'), max_length=50)
search_text = SearchField(field_names=['nome', 'uf'])
uf = models.ForeignKey(
UnidadeFederativa,
on_delete=models.PROTECT,
verbose_name=_(u'UF')
verbose_name=_('UF')
)
is_capital = models.BooleanField(_('capital'), default=False)
populacao = models.PositiveIntegerField(_('população'))
is_polo = models.BooleanField(_('pólo'), default=False)
data_criacao = models.DateField(
_('data de criação do município'),
null=True,
blank=True
)
# verdadeiro se o município é capital do estado
is_capital = models.BooleanField(_(u'capital'), default=False)
populacao = models.PositiveIntegerField(_(u'população'))
populacao.list_filter_range = [10000, 100000, 1000000]
is_polo = models.BooleanField(_(u'pólo'), default=False)
data_criacao = models.DateField(_(u'data de criação do município'), null=True, blank=True)
# posição geográfica do município
latitude = models.DecimalField(
_('latitude'),
max_digits=10,
decimal_places=8,
null=True,
blank=True,
help_text=_(u'Exemplo') + ': <em>-20,464</em>.'
help_text=_('Exemplo') + ': <em>-20,464</em>.'
)
longitude = models.DecimalField(
_('longitude'),
max_digits=11,
decimal_places=8,
null=True,
blank=True,
help_text=_(u'Exemplo') + ': <em>-45,426</em>.'
help_text=_('Exemplo') + ': <em>-45,426</em>.'
)
idh = models.DecimalField(
_('IDH'),
help_text=_('Índice de Desenvolvimento Humano'),
max_digits=4,
decimal_places=3,
validators=[MinValueValidator(0), MaxValueValidator(1)]
)
pib_total = models.DecimalField(
_('PIB total'),
max_digits=18,
decimal_places=3,
blank=True,
null=True
)
pib_percapita = models.DecimalField(
_('PIB per capita'),
max_digits=18,
decimal_places=3,
blank=True,
null=True
)
pib_ano = models.IntegerField(
_('ano de apuração do PIB'),
blank=True,
null=True
)
idh = models.DecimalField(_(u'IDH'), help_text=_(u'Índice de desenvolvimento Humano'), max_digits=4, decimal_places=3,
validators=[MinValueValidator(0), MaxValueValidator(1)])
idh.list_filter_range = [0.500, 0.800]
pib_total = models.DecimalField(_(u'PIB total'), max_digits=18, decimal_places=3, blank=True, null=True)
pib_percapita = models.DecimalField(_(u'PIB per capita'), max_digits=18, decimal_places=3, blank=True, null=True)
pib_ano = models.IntegerField(_(u'Ano de apuração do PIB'), blank=True, null=True)
class Meta:
ordering = ('nome', 'codigo_ibge')
verbose_name = _(u'município')
verbose_name_plural = _(u'municípios')
verbose_name = _('município')
verbose_name_plural = _('municípios')
def __unicode__(self):
def __str__(self):
return "%s - %s" % (self.nome, self.uf)
def get_google_maps_url(self):
return "http://maps.google.com.br/maps/mm?ie=UTF8&hl=pt-BR&t=h&ll=%s,%s&spn=1.61886,1.812744&z=9&source=embed" % \
(self.latitude, self.longitude)
class Telefone(models.Model):
""" Modelo genérico para agrupar telefones dos modulos do sistema
"""
TELEFONE_CHOICES = (
('F', _(u'Fixo')),
('M', _(u'Móvel')),
('X', _(u'Fax')),
('I', _(u'Indefinido')),
('F', _('Fixo')),
('M', _('Móvel')),
('X', _('Fax')),
('I', _('Indefinido')),
)
numero = models.CharField(
_(u'número'),
_('número'),
max_length=64, # TODO: diminuir tamanho de campo após migração de dados
help_text=_(u'Exemplo') + ': <em>(31)8851-9898</em>.',
help_text=_('Exemplo: <em>(31)8851-9898</em>.'),
)
tipo = models.CharField(
_('tipo'),
max_length=1,
choices=TELEFONE_CHOICES,
default='I'
)
nota = models.CharField(max_length=70, null=True, blank=True)
ult_alteracao = models.DateTimeField(_(u'Última alteração'), null=True, blank=True, editable=False, auto_now=True)
# guarda o tipo do objeto (classe) vinculado a esse registro
nota = models.CharField(
_('nota'),
max_length=70,
null=True,
blank=True
)
ult_alteracao = models.DateTimeField(
_('última alteração'),
null=True,
blank=True,
editable=False,
auto_now=True
)
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
# identificador do registro na classe vinculado a esse registro
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey(
'content_type',
'object_id',
)
content_object = GenericForeignKey('content_type', 'object_id')
class Meta:
ordering = ('numero',)
unique_together = ('numero', 'tipo')
verbose_name = _('telefone')
verbose_name_plural = _('telefones')
def __unicode__(self):
return unicode(self.numero)
def __str__(self):
return str(self.numero)
class Contato(models.Model):
""" Modelo generico para registrar contatos vinculados aos
modulos do sistema
"""
nome = models.CharField(_(u'nome completo'), max_length=120)
nome.alphabetic_filter = True
nota = models.CharField(max_length=70, blank=True)
email = models.EmailField(_(u'e-mail'), blank=True)
telefones = generic.GenericRelation(Telefone)
nome = models.CharField(_('nome completo'), max_length=120)
nota = models.CharField(_('nota'), max_length=70, blank=True)
email = models.EmailField(_('e-mail'), blank=True)
telefones = GenericRelation(Telefone, verbose_name=_('telefones'))
municipio = models.ForeignKey(
Municipio,
on_delete=models.SET_NULL,
verbose_name=_(u'município'),
blank=True,
null=True,
verbose_name=_('município')
)
# guarda o tipo do objeto (classe) vinculado a esse registro
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
# identificador do registro na classe vinculado a esse registro
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey(
'content_type',
'object_id',
)
content_object = GenericForeignKey('content_type','object_id')
class Meta:
ordering = ('nome',)
verbose_name = _(u'contato Interlegis')
verbose_name_plural = _(u'contatos Interlegis')
verbose_name = _('contato Interlegis')
verbose_name_plural = _('contatos Interlegis')
def __unicode__(self):
def __str__(self):
return self.nome
class Endereco(models.Model):
TIPO_CHOICES = (
('aeroporto', _(u'Aeroporto')),
('alameda', _(u'Alameda')),
('area', _(u'Área')),
('avenida', _(u'Avenida')),
('campo', _(u'Campo')),
('chacara', _(u'Chácara')),
('colonia', _(u'Colônia')),
('condominio', _(u'Condomínio')),
('conjunto', _(u'Conjunto')),
('distrito', _(u'Distrito')),
('esplanada', _(u'Esplanada')),
('estacao', _(u'Estação')),
('estrada', _(u'Estrada')),
('favela', _(u'Favela')),
('fazenda', _(u'Fazenda')),
('feira', _(u'Feira')),
('jardim', _(u'Jardim')),
('ladeira', _(u'Ladeira')),
('lago', _(u'Lago')),
('lagoa', _(u'Lagoa')),
('largo', _(u'Largo')),
('loteamento', _(u'Loteamento')),
('morro', _(u'Morro')),
('nucleo', _(u'Núcleo')),
('parque', _(u'Parque')),
('passarela', _(u'Passarela')),
('patio', _(u'Pátio')),
('praca', _(u'Praça')),
('quadra', _(u'Quadra')),
('recanto', _(u'Recanto')),
('residencial', _(u'Residencial')),
('rodovia', _(u'Rodovia')),
('rua', _(u'Rua')),
('setor', _(u'Setor')),
('sitio', _(u'Sítio')),
('travessa', _(u'Travessa')),
('trecho', _(u'Trecho')),
('trevo', _(u'Trevo')),
('vale', _(u'Vale')),
('vereda', _(u'Vereda')),
('via', _(u'Via')),
('viaduto', _(u'Viaduto')),
('viela', _(u'Viela')),
('vila', _(u'Vila')),
('outro', _(u'Outro')),
('aeroporto', _('Aeroporto')),
('alameda', _('Alameda')),
('area', _('Área')),
('avenida', _('Avenida')),
('campo', _('Campo')),
('chacara', _('Chácara')),
('colonia', _('Colônia')),
('condominio', _('Condomínio')),
('conjunto', _('Conjunto')),
('distrito', _('Distrito')),
('esplanada', _('Esplanada')),
('estacao', _('Estação')),
('estrada', _('Estrada')),
('favela', _('Favela')),
('fazenda', _('Fazenda')),
('feira', _('Feira')),
('jardim', _('Jardim')),
('ladeira', _('Ladeira')),
('lago', _('Lago')),
('lagoa', _('Lagoa')),
('largo', _('Largo')),
('loteamento', _('Loteamento')),
('morro', _('Morro')),
('nucleo', _('Núcleo')),
('parque', _('Parque')),
('passarela', _('Passarela')),
('patio', _('Pátio')),
('praca', _('Praça')),
('quadra', _('Quadra')),
('recanto', _('Recanto')),
('residencial', _('Residencial')),
('rodovia', _('Rodovia')),
('rua', _('Rua')),
('setor', _('Setor')),
('sitio', _('Sítio')),
('travessa', _('Travessa')),
('trecho', _('Trecho')),
('trevo', _('Trevo')),
('vale', _('Vale')),
('vereda', _('Vereda')),
('via', _('Via')),
('viaduto', _('Viaduto')),
('viela', _('Viela')),
('vila', _('Vila')),
('outro', _('Outro')),
)
# tipo do endereço obtido no site dos correios
tipo = models.CharField(max_length=15, choices=TIPO_CHOICES)
logradouro = models.CharField(
max_length=100,
)
logradouro.alphabetic_filter = True
numero = models.CharField(max_length=15, blank=True)
complemento = models.CharField(max_length=15, blank=True)
# campo de texto livre
referencia = models.CharField(max_length=100, blank=True)
bairro = models.CharField(max_length=100, blank=True)
tipo = models.CharField(_('tipo'), max_length=15, choices=TIPO_CHOICES)
logradouro = models.CharField(_('logradouro'), max_length=100)
numero = models.CharField(_('número'), max_length=15, blank=True)
complemento = models.CharField(_('complemento'), max_length=15, blank=True)
referencia = models.CharField(_('referência'), max_length=100, blank=True)
bairro = models.CharField(_('bairro'), max_length=100, blank=True)
cep = models.CharField(
_(u'CEP'),
_('CEP'),
max_length=9,
blank=True,
null=True,
help_text=_(u"Formato") + ": <em>XXXXX-XXX</em>."
help_text=_(u"formato: <em>XXXXX-XXX</em>.")
)
municipio = models.ForeignKey(
Municipio,
on_delete=models.SET_NULL,
verbose_name=_(u'município'),
blank=True,
null=True,
verbose_name=_('município')
)
municipio.uf_filter = True
# guarda o tipo do objeto (classe) vinculado a esse registro
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
# identificador do registro na classe vinculado a esse registro
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey(
'content_type',
'object_id',
)
content_object = GenericForeignKey('content_type','object_id')
class Meta:
ordering = ('logradouro', 'numero')
verbose_name = _(u'endereço')
verbose_name_plural = _(u'endereços')
verbose_name = _('endereço')
verbose_name_plural = _('endereços')
def __unicode__(self):
def __str__(self):
return self.tipo + ' ' + self.logradouro + ', ' + self.numero \
+ ' ' + self.complemento + ' - ' + self.bairro

9
sigi/apps/utils/__init__.py

@ -28,10 +28,9 @@ class SearchField(models.TextField):
def to_ascii(txt, codif='utf-8'):
if not isinstance(txt, basestring):
txt = unicode(txt)
if isinstance(txt, unicode):
txt = txt.encode('utf-8')
if not isinstance(txt, str):
txt = str(txt)
txt = txt.encode('utf-8')
return normalize('NFKD', txt.decode(codif)).encode('ASCII', 'ignore')
@ -39,4 +38,4 @@ def queryset_ascii(self, request):
if 'q' in request.GET:
request.GET._mutable = True
request.GET['q'] = to_ascii(request.GET['q'])
return admin.ModelAdmin.queryset(self, request)
return admin.ModelAdmin.get_queryset(self, request)

212
sigi/apps/utils/filters.py

@ -1,31 +1,191 @@
# coding: utf-8
import string
from django.utils.translation import gettext as _
from django.contrib import admin
from django.contrib.admin.utils import reverse_field_path
class RangeFieldListFilter(admin.FieldListFilter):
slices = 5
def __init__(self, field, request, params, model, model_admin, field_path):
self.lookup_kwarg_gte = '%s__gte' % field_path
self.lookup_kwarg_lt = '%s__lt' % field_path
self.lookup_kwarg_isnull = '%s__isnull' % field_path
self.lookup_val_gte = params.get(self.lookup_kwarg_gte)
self.lookup_val_lt = params.get(self.lookup_kwarg_lt)
self.lookup_val_isnull = params.get(self.lookup_kwarg_isnull)
self.empty_value_display = model_admin.get_empty_value_display()
parent_model, reverse_path = reverse_field_path(model, field_path)
# Obey parent ModelAdmin queryset when deciding which options to show
if model == parent_model:
queryset = model_admin.get_queryset(request)
else:
queryset = parent_model._default_manager.all()
self.lookup_choices = self.slice_range(queryset.order_by(field.name)
.values_list(field.name, flat=True))
super().__init__(field, request, params, model, model_admin, field_path)
class AlphabeticFilter(admin.SimpleListFilter):
# Human-readable title which will be displayed in the
# right admin sidebar just above the filter options.
title = ''
# Parameter for the filter that will be used in the URL query.
parameter_name = ''
def lookups(self, request, model_admin):
"""
Returns a list of tuples. The first element in each
tuple is the coded value for the option that will
appear in the URL query. The second element is the
human-readable name for the option that will appear
in the right sidebar.
"""
return ((letter, letter,) for letter in string.ascii_uppercase)
def queryset(self, request, queryset):
"""
Returns the filtered queryset based on the value
provided in the query string and retrievable via
`self.value()`.
"""
if self.value():
return queryset.filter((self.parameter_name + '__istartswith', self.value()))
def expected_parameters(self):
return [self.lookup_kwarg_gte, self.lookup_kwarg_lt,
self.lookup_kwarg_isnull]
def choices(self, changelist):
yield {
'selected': (self.lookup_val_gte is None and
self.lookup_val_lt is None and
self.lookup_val_isnull is None),
'query_string': changelist.get_query_string(remove=[
self.lookup_kwarg_gte, self.lookup_kwarg_lt,
self.lookup_kwarg_isnull]),
'display': _('All'),
}
last_val = None
for val in self.lookup_choices:
val = str(val)
if last_val is None:
last_val = val
yield {
'selected': self.lookup_val_lt == val,
'query_string': changelist.get_query_string(
{self.lookup_kwarg_lt: val},
[self.lookup_kwarg_isnull, self.lookup_kwarg_gte]),
'display': _('Menor que %s') % val,
}
else:
yield {
'selected': (self.lookup_val_gte == last_val and
self.lookup_val_lt == val),
'query_string': changelist.get_query_string(
{self.lookup_kwarg_gte: last_val,
self.lookup_kwarg_lt: val},
[self.lookup_kwarg_isnull]),
'display': _("De %s até %s") % (last_val, val),
}
last_val = val
yield {
'selected': self.lookup_val_gte == last_val,
'query_string': changelist.get_query_string(
{self.lookup_kwarg_gte: last_val},
[self.lookup_kwarg_isnull, self.lookup_kwarg_lt]),
'display': _("De %s acima") % last_val,
}
def slice_range(self, queryset):
if queryset.distinct().count() < self.slices:
return list(queryset.distinct())
total = queryset.count()
salt = total // self.slices
result = []
for pos in range(salt, salt*self.slices, salt):
result.append(queryset[pos])
return result
class MultiRelatedFieldListFilter(admin.RelatedFieldListFilter):
template = "admin/multifilter.html"
def __init__(self, field, request, params, model, model_admin, field_path):
super().__init__(field, request, params, model, model_admin, field_path)
self.lookup_kwarg = '%s__%s__in' % (field_path, field.target_field.name)
self.lookup_kwarg_isnull = '%s__isnull' % field_path
self.lookup_val = params.get(self.lookup_kwarg)
def expected_parameters(self):
return [self.lookup_kwarg, self.lookup_kwarg_isnull]
def choices(self, changelist):
yield {
'selected': self.lookup_val is None and not self.lookup_val_isnull,
'query_string': changelist.get_query_string(
remove=[self.lookup_kwarg, self.lookup_kwarg_isnull]
),
'display': _('All'),
}
for pk_val, val in self.lookup_choices:
values = (set(self.lookup_val.split(',')) if self.lookup_val
else set())
selected = str(pk_val) in values
if selected:
values.discard(str(pk_val))
else:
values.add(str(pk_val))
if values:
yield {
'selected': selected,
'query_string': changelist.get_query_string(
{self.lookup_kwarg: ",".join(values)},
[self.lookup_kwarg_isnull]),
'display': val,
}
else:
yield {
'selected': selected,
'query_string': changelist.get_query_string(
remove=[self.lookup_kwarg, self.lookup_kwarg_isnull]),
'display': val,
}
if self.include_empty_choice:
yield {
'selected': bool(self.lookup_val_isnull),
'query_string': changelist.get_query_string(
{self.lookup_kwarg_isnull: 'True'}, [self.lookup_kwarg]
),
'display': self.empty_value_display,
}
class MultiChoicesFieldListFilter(admin.ChoicesFieldListFilter):
template = "admin/multifilter.html"
def __init__(self, field, request, params, model, model_admin, field_path):
super().__init__(field, request, params, model, model_admin, field_path)
self.lookup_kwarg = '%s__in' % field_path
self.lookup_val = params.get(self.lookup_kwarg)
def choices(self, changelist):
yield {
'selected': self.lookup_val is None,
'query_string': changelist.get_query_string(
remove=[self.lookup_kwarg, self.lookup_kwarg_isnull]
),
'display': _('All')
}
none_title = ''
for lookup, title in self.field.flatchoices:
values = (set(self.lookup_val.split(',')) if self.lookup_val
else set())
selected = str(lookup) in values
if selected:
values.discard(str(lookup))
else:
values.add(str(lookup))
if lookup is None:
none_title = title
continue
if values:
yield {
'selected': selected,
'query_string': changelist.get_query_string(
{self.lookup_kwarg: ",".join(values)},
[self.lookup_kwarg_isnull]),
'display': title,
}
else:
yield {
'selected': selected,
'query_string': changelist.get_query_string(
remove=[self.lookup_kwarg, self.lookup_kwarg_isnull]),
'display': title,
}
if none_title:
yield {
'selected': bool(self.lookup_val_isnull),
'query_string': changelist.get_query_string(
{self.lookup_kwarg_isnull: 'True'}, [self.lookup_kwarg]
),
'display': none_title,
}

8
sigi/settings/__init__.py

@ -1,6 +1,6 @@
try:
from prod import *
except ImportError:
from sigi.settings.prod import *
except ImportError as e:
from django.core.exceptions import ImproperlyConfigured
msg = """
@ -9,5 +9,7 @@ except ImportError:
Se vc esta num ambiente de desenvolvimento pode cria-lo com
ln -s dev.py prod.py
######################################################################
"""
""" + str(e)
raise ImproperlyConfigured(msg)

232
sigi/settings/base.py

@ -1,190 +1,126 @@
# -*- coding: utf-8 -*-
"""
Django settings for sigi project.
For more information on this file, see
https://docs.djangoproject.com/en/dev/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/dev/ref/settings/
Generated by 'django-admin startproject' using Django 3.2.4.
"""
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
import os
from os.path import dirname
import django.conf.global_settings as DEFAULT_SETTINGS
from pathlib import Path
BASE_DIR = dirname(dirname(dirname(__file__)))
BASE_DIR = Path(__file__).resolve().parent.parent.parent
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/dev/howto/deployment/checklist/
# Security settings
SECRET_KEY = 'django-insecure-7-gj3=#0f5sbwac6k$_rws5-47kze&-vtq=yt=2x9e%)27x%5g'
DEBUG = True
ALLOWED_HOSTS = []
ADMINS = (
# ('Your Name', 'your_email@example.com'),
)
MANAGERS = ADMINS
SITE_ID = 1
TEMPLATE_CONTEXT_PROCESSORS = DEFAULT_SETTINGS.TEMPLATE_CONTEXT_PROCESSORS + (
'django.core.context_processors.request',
)
# List of callables that know how to import templates from various sources.
TEMPLATE_LOADERS = ('django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
)
# Application definition
INSTALLED_APPS = (
'bootstrap3',
'django_admin_bootstrapped',
INSTALLED_APPS = [
'django_bootstrap5',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
# Local apps
'sigi.apps.home',
'sigi.apps.utils',
# 'sigi.apps.home',
'sigi.apps.contatos',
'sigi.apps.servidores',
'sigi.apps.parlamentares',
'sigi.apps.casas',
'sigi.apps.convenios',
'sigi.apps.inventario',
'sigi.apps.servicos',
'sigi.apps.metas',
'sigi.apps.ocorrencias',
'sigi.apps.financeiro',
'sigi.apps.diagnosticos',
'sigi.apps.eventos',
'sigi.apps.whois',
# Third-party apps
'localflavor',
'reporting',
# 'sigi.apps.servidores',
# 'sigi.apps.parlamentares',
# 'sigi.apps.casas',
# 'sigi.apps.convenios',
# 'sigi.apps.inventario',
# 'sigi.apps.servicos',
# 'sigi.apps.metas',
# 'sigi.apps.ocorrencias',
# 'sigi.apps.financeiro',
# 'sigi.apps.diagnosticos',
# 'sigi.apps.eventos',
# 'sigi.apps.whois',
'django_extensions',
'easy_thumbnails',
'image_cropping',
'rest_framework',
)
MIDDLEWARE_CLASSES = (
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
)
]
ROOT_URLCONF = 'sigi.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR / "templates",],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'sigi.wsgi.application'
# Database
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'sigi',
'USER': 'sigi',
'PASSWORD': '123456',
'HOST': 'localhost',
},
}
# Password validation
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/dev/topics/i18n/
LANGUAGE_CODE = 'pt-br'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
USE_THOUSAND_SEPARATOR = True
gettext_noop = lambda s: s # for gettext discovery
LANGUAGES = (
('en', gettext_noop('English')),
('pt-br', gettext_noop('Brazilian Portuguese')),
)
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/dev/howto/static-files/
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
STATIC_URL = '/static/'
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'sigiStatic'),
)
SERVER_EMAIL = 'sigi@interlegis.leg.br'
DEFAULT_FROM_EMAIL = 'spdt@interlegis.leg.br'
EMAIL_SUBJECT_PREFIX = u'[SIGI]'
TEMPLATE_DIRS = (
os.path.join(BASE_DIR, 'templates'),
)
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
SESSION_EXPIRE_AT_BROWSER_CLOSE = True
LOGIN_REDIRECT_URL = '/'
LOGIN_URL = '/login/'
STATIC_ROOT = BASE_DIR / 'static'
STATIC_URL = '/static/'
STATICFILES_DIRS = (BASE_DIR / 'sigiStatic', )
# Using pytest directly (without a test runner)
TEST_RUNNER = None
# Media files (uploaded by user)
from easy_thumbnails.conf import Settings as thumbnail_settings
THUMBNAIL_PROCESSORS = (
'image_cropping.thumbnail_processors.crop_corners',
) + thumbnail_settings.THUMBNAIL_PROCESSORS
MEDIA_ROOT = BASE_DIR / 'media'
MEDIA_URL = '/media/'
THUMBNAIL_ALIASES = {
'': {
'small': {'size': (300, 225), 'crop': True, },
'thumb': {'size': (160, 120), 'crop': True, },
'portrait': {'size': (73,100), 'crop': True},
'icon': {'size': (36,50), 'crop': True},
},
}
IMAGE_CROPPING_SIZE_WARNING = True
IMAGE_CROPPING_THUMB_SIZE = (800, 600)
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'filters': {
'require_debug_false': {
'()': 'django.utils.log.RequireDebugFalse'
}
},
'handlers': {
'mail_admins': {
'level': 'ERROR',
'class': 'django.utils.log.AdminEmailHandler',
'include_html': True,
'filters': ['require_debug_false'],
},
'file': {
'level': 'DEBUG',
'class': 'logging.FileHandler',
'filename': '/var/log/sigi/application.log',
},
},
'loggers': {
'django.request': {
'handlers': ['mail_admins', 'file'],
'level': 'ERROR',
'propagate': True,
},
},
}
# Default primary key field type
OSTICKET_URL = 'https://suporte.interlegis.leg.br/scp/tickets.php?a=search&query=%s'
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
REST_FRAMEWORK = {
# Use Django's standard `django.contrib.auth` permissions,
# or allow read-only access for unauthenticated users.
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.AllowAny',
]
}
# Admin interface
# Lista de endereços IP que podem acessar a API de whois
WHOIS_WHITELIST = [
'127.0.0.1',
]
X_FRAME_OPTIONS='SAMEORIGIN'
SILENCED_SYSTEM_CHECKS = ['security.W019']

28
sigi/settings/dev.py

@ -1,31 +1,11 @@
from base import *
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '0$ip1fb5xtq%a=)-k_4r^(#jn0t^@+*^kihkxkozg-mip7+w3+'
from sigi.settings.base import *
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'sigi',
'NAME': 'sigi-3',
'USER': 'sigi',
'PASSWORD': 'sigi',
'HOST': 'localhost',
'PASSWORD': '123456',
'HOST': 'database',
},
}
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
TEMPLATE_DEBUG = DEBUG
DEBUG_TOOLBAR_CONFIG = {
'SHOW_TEMPLATE_CONTEXT': True,
}
INSTALLED_APPS += (
'debug_toolbar',
)
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.dummy.DummyCache',
}
}

61
sigi/urls.py

@ -1,41 +1,30 @@
#-*- coding:utf-8 -*-
"""sigi URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/3.2/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.conf import settings
from django.conf.urls import patterns, include, url
from django.conf.urls.static import static
from django.contrib import admin
from django.views.generic.base import TemplateView
admin.site.index_template = 'index.html'
admin.autodiscover()
urlpatterns = patterns(
'',
from django.views.static import serve
from django.urls import path
url(r'^parlamentares/', include('sigi.apps.parlamentares.urls')),
url(r'^casas/', include('sigi.apps.casas.urls')),
url(r'^convenios/', include('sigi.apps.convenios.urls')),
url(r'^diagnosticos/', include('sigi.apps.diagnosticos.urls')),
url(r'^servicos/', include('sigi.apps.servicos.urls')),
url(r'^dashboard/', include('sigi.apps.metas.urls')),
url(r'^ocorrencias/', include('sigi.apps.ocorrencias.urls')),
url(r'^eventos/', include('sigi.apps.eventos.urls')),
url(r'^whois/', include('sigi.apps.whois.urls')),
url(r'^', include('sigi.apps.home.urls')),
url(r'^', include(admin.site.urls)),
# to enable language selection
# Suspended
#url(r'^i18n/', include('django.conf.urls.i18n')),
) + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urlpatterns = [
path('admin/', admin.site.urls),
]
if settings.DEBUG:
urlpatterns = patterns(
'',
url(r'^404/$', TemplateView.as_view(template_name='404.html')),
url(r'^500/$', TemplateView.as_view(template_name='500.html')),
url(r'^503/$', TemplateView.as_view(template_name='503.html')),
url(r'^media/(?P<path>.*)$', 'django.views.static.serve', {
'document_root': settings.MEDIA_ROOT, }),
) + urlpatterns
urlpatterns += [
path('media/<path:path>/', serve, {
'document_root': settings.MEDIA_ROOT,
}),
]

6
sigi/wsgi.py

@ -4,11 +4,13 @@ WSGI config for sigi project.
It exposes the WSGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/dev/howto/deployment/wsgi/
https://docs.djangoproject.com/en/3.2/howto/deployment/wsgi/
"""
import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "sigi.settings")
from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'sigi.settings')
application = get_wsgi_application()

12
templates/404.html

@ -1,12 +0,0 @@
{% extends "admin/base_site.html" %}
{% load i18n %}
{% block title %}{% trans 'Page not found' %}{% endblock %}
{% block content %}
<h2>{% trans 'Page not found' %}</h2>
<p>{% trans "We're sorry, but the requested page could not be found." %}</p>
{% endblock %}

12
templates/500.html

@ -1,12 +0,0 @@
{% extends "admin/base_site.html" %}
{% load i18n %}
{% block breadcrumbs %}<div class="breadcrumbs"><a href="/">{% trans "Home" %}</a> &rsaquo; {% trans "Server error" %}</div>{% endblock %}
{% block title %}{% trans 'Server error (500)' %}{% endblock %}
{% block content %}
<h1>{% trans 'Server Error <em>(500)</em>' %}</h1>
<p>{% trans "There's been an error. It's been reported to the site administrators via e-mail and should be fixed shortly. Thanks for your patience." %}</p>
{% endblock %}

19
templates/503.html

@ -1,19 +0,0 @@
{% extends "admin/base_site.html" %}
{% load i18n %}
{% block title %}{% trans 'Serviço em manutenção (503) | SIGI' %}{% endblock %}
{% block branding %}{% endblock %}
{% block menu-principal %}{% endblock %}
{% block breadcrumbs %}{% endblock %}
{% block content %}
<h1>{% trans 'SIGI em manutenção' %}</h1>
<p>{% trans 'Esta página está atualmente em manutenção! Por favor, tente novamente mais tarde.' %}</p>
<p>{% trans 'Obrigado pela paciência' %},<br />
{% trans 'Serviço de Pesquisa e Desenvolvimento Tecnológico (SPDT)' %}</p>
{% endblock %}
{% block footer %}{% endblock %}

16
templates/admin/actions.html

@ -1,16 +0,0 @@
{% load i18n %}
<div class="actions" style="display:inline-block;">
{% for field in action_form %}{% if field.label %}<span style="vertical-align:middle">{{ field.label }}</span> {% endif %}{{ field }}{% endfor %}
<button type="submit" class="btn btn-default btn-sm" title="{% trans "Run the selected action" %}" name="index" value="{{ action_index|default:0 }}">{% trans "Go" %}</button>
{% if actions_selection_counter %}
<script type="text/javascript">var _actions_icnt="{{ cl.result_list|length|default:"0" }}";</script>
<span class="action-counter" style="vertical-align:middle">{{ selection_note }}</span>
{% if cl.result_count != cl.result_list|length %}
<span class="all" style="vertical-align:middle">{{ selection_note_all }}</span>
<span class="question" style="vertical-align:middle">
<a class="btn" href="javascript:;" title="{% trans "Click here to select the objects across all pages" %}">{% blocktrans with cl.result_count as total_count %}Select all {{ total_count }} {{ module_name }}{% endblocktrans %}</a>
</span>
<span class="clear" style="vertical-align:middle"><a class="btn" href="javascript:;">{% trans "Clear selection" %}</a></span>
{% endif %}
{% endif %}
</div>

10
templates/admin/app_index.html

@ -1,10 +0,0 @@
{% extends "admin/index.html" %}
{% load static from staticfiles %}
{% block extrastyle %}
<link rel="stylesheet" type="text/css" href="{% static 'css/globalnav-estilos.css' %}" />
<link rel="stylesheet" type="text/css" href="{% static 'css/base_site.css' %}" />
<link rel="stylesheet" type="text/css" href="{% static 'css/app_index.css' %}" />
{% endblock %}
{% block breadcrumbs %}{% endblock %}

204
templates/admin/base.html

@ -1,188 +1,16 @@
{% load admin_static bootstrapped_goodies_tags %}
{% load i18n %}
{% load menus %}
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="{{ LANGUAGE_CODE|default:"en-us" }}" {% if LANGUAGE_BIDI %}dir="rtl"{% endif %}>
<head>
<title>{% block title %}{% endblock %}</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<meta http-equiv="Content-Type" content="text/xhtml; charset=UTF-8" />
{% block extrastyle %}{% endblock %}
<!-- Le styles, placed after extrastyle to correctly override default styling -->
<link href="{% static "bootstrap/css/bootstrap.min.css" %}" rel="stylesheet"/>
<style type="text/css">
body {
padding: 10px 20px 40px;
}
</style>
<link href="{% static "bootstrap/css/bootstrap-theme.min.css" %}" rel="stylesheet"/>
<link rel="stylesheet" type="text/css" href="{% static "admin/css/overrides.css" %}" />
<!-- <link rel="stylesheet" type="text/css" href="{% block stylesheet %}{% static "admin/css/base.css" %}{% endblock %}" /> -->
<script type="text/javascript">
//<![CDATA[
window.__admin_media_prefix__ = "{% filter escapejs %}{% static "admin/" %}{% endfilter %}";
//]]>
</script>
{% block default_javascript %}
{# We should be able to turn this off, to avoid conflict in integrated pages like petaho's dashboards #}
<script src="{% static "admin/js/jquery-1.9.1.min.js" %}"></script>
<script src="{% static "admin/js/jquery-migrate-1.2.1.min.js" %}"></script>
<script src="{% static "bootstrap/js/bootstrap.min.js" %}"></script>
{% endblock %}
{% block extrahead %}{% endblock %}
{% block blockbots %}<meta name="robots" content="NONE,NOARCHIVE" />{% endblock %}
<script type="text/javascript">
//<![CDATA[
(function($) {
$(document).ready(function() {
$('input[type="submit"]').addClass('btn');
$('[title]').tooltip();
});
}(jQuery));
//]]>
</script>
</head>
<body class="{% if is_popup %}popup {% endif %}{% block bodyclass %}{% endblock %}">
<!-- Container -->
<div class="container-fluid">
{% if not is_popup %}
{% block container-top %}{% endblock %}
<!-- Header -->
<div id="navbar-title-tools" class="navbar navbar-static-top">
<div class="navbar-inner">
<div class="container-fluid">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
{% block branding %}{% endblock %}
</div>
<div class="navbar-collapse collapse navbar-right">
<ul class="nav navbar-nav">
{% if user.is_active and user.is_staff %}
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">{% trans 'Welcome,' %} <strong>{% filter force_escape %}{% firstof user.get_short_name user.get_username user.first_name user.username %}{% endfilter %}</strong> <span class="caret"></span></a>
<ul class="dropdown-menu">
{% if user.has_usable_password %}
<li><a href="{% url 'admin:password_change' %}">{% trans 'Change password' %}</a></li>
{% endif %}
<li><a href="{% url 'admin:logout' %}">{% trans 'Log out' %}</a></li>
</ul>
</li>
{% block languages %}
<li class="divider-vertical"></li>
{% language_selector %}
{% endblock languages %}
{% block logs %}
<li class="dropdown" id="recent-actions-module">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">{% trans 'Recent Actions' %} <b class="caret"></b></a>
{% load log %}
{% get_admin_log 10 as admin_log for_user user %}
<ul class="dropdown-menu">
{% for entry in admin_log %}
<li class="{% if entry.is_addition %}addlink{% endif %}{% if entry.is_change %}changelink{% endif %}{% if entry.is_deletion %}deletelink{% endif %}">
<a href="{% if entry.is_deletion or not entry.get_admin_url %}#{% else %}{{ entry.get_admin_url }}{% endif %}">
<i class="icon-{% if entry.is_addition %}plus{% endif %}{% if entry.is_change %}edit{% endif %}{% if entry.is_deletion %}remove{% endif %}"></i>
{{ entry.object_repr }}
{% if entry.content_type %}
<span class="mini quiet">({% filter capfirst %}{% trans entry.content_type.name %}{% endfilter %})</span>
{% else %}
<span class="mini quiet">({% trans 'Unknown content' %})</span>
{% endif %}
</a>
</li>
{% empty %}
<li class="disabled"><a href="#">{% trans 'None available' %}</a></li>
{% endfor %}
</ul>
</li>
{% endblock %}
{% block userlinks %}
{% url 'django-admindocs-docroot' as docsroot %}
{% if docsroot %}
<li class="divider-vertical"></li>
<li><a href="{{ docsroot }}">{% trans 'Documentation' %}</a></li>
{% endif %}
{% endblock %}
{% endif %}
{% block nav-global %}{% endblock %}
</ul>
</div><!--/.nav-collapse -->
</div>
</div>
</div>
<!-- END Header -->
{% block menu-principal %}
<div role="navigation" class="navbar navbar-default">
<div class="container-fluid">
<div class="navbar-header">
<button data-target=".navbar-collapse" data-toggle="collapse" class="navbar-toggle collapsed" type="button">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
</div>
<div class="navbar-collapse collapse">
{% show_menu "main_menu" %}
</div><!--/.nav-collapse -->
</div><!--/.container-fluid -->
</div>
{% endblock %}
{% endif %}
<!-- Content -->
<div id="content" class="{% block coltype %}colM{% endblock %}">
{% block content_title %}{% if title %}<h1>{{ title }}</h1>{% endif %}{% endblock %}
{% block navbar %}
<div id="navbar-object-tools" class="nav">
{% block object-tools %}
<ul class="object-tools pull-left nav nav-pills">
{% block object-tools-items %}{% endblock %}
</ul>
{% endblock %}
</div>
{% endblock navbar %}
{% block messages %}
{% if messages %}
<div class="row">
<div class="col-sm-12">
{% for message in messages %}
<div class="alert alert-info {% if message.tags %}{{ message.tags }}{% endif %}">
{{ message }}
</div>
{% endfor %}
</div>
</div>
{% endif %}
{% endblock messages %}
{% block content %}{{ content }}{% endblock %}
{% block sidebar %}{% endblock %}
</div>
<!-- END Content -->
{% block footer %}<footer id="footer"></footer>{% endblock %}
</div>
<!-- END Container -->
</body>
</html>
{% extends "admin/base.html" %}
{% load django_bootstrap5 %}
{% block extrastyle %}
{% bootstrap_css %}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.5.0/font/bootstrap-icons.css">
{% endblock %}
{% block extrahead %}
{% bootstrap_javascript %}
{% endblock %}
{% block responsive %}
{{ block.super }}
<meta charset="utf-8">
{% endblock %}

62
templates/admin/base_site.html

@ -1,62 +0,0 @@
{% extends "admin/base.html" %}
{% load i18n %}{% load admin_static bootstrapped_goodies_tags %}
{% load static from staticfiles %}
{% block title %}{{ title }} | SIGI{% endblock %}
{% block extrastyle %}
<link rel="stylesheet" type="text/css" href="{% static 'css/globalnav-estilos.css' %}" />
<link rel="stylesheet" type="text/css" href="{% static 'css/base_site.css' %}" />
{% endblock %}
{% block extrahead %}
<meta name="copyright" content="Copyright (c) 2008 Interlegis. Todos
Direitos Reservados." />
{% endblock %}
{% block container-top %}
<ul id="globalnavbar">
<li class="globalnav-busca">
<form action="http://www.interlegis.leg.br/search">
<input type="text" name="SearchableText" size="8" placeholder="Pesquisar" />
</form>
</li>
<li><a href="http://saberes.interlegis.leg.br/" title="Saberes - Ambiente de Aprendizagem a Distância" class="globalnav-saberes">Saberes</a></li>
<li><a href="http://colab.interlegis.leg.br/" title="Colab - Comunidades Interlegis" class="globalnav-colab">Colab</a></li>
<li><a href="https://intranet.interlegis.leg.br/" title="Intranet Interlegis" class="globalnav-intranet">Intranet</a></li>
<li><a href="http://www.interlegis.leg.br/" title="Portal Interlegis" class="globalnav-portal">Portal</a></li>
</ul>
{% endblock %}
{% block branding %}
<a class="navbar-brand" href="/">{% trans 'Sistema de Informações Gerenciais do Interlegis' %}</a>
{% endblock %}
{% block nav-global %}
{% if user.is_superuser %}
<li class="dropdown">
<a data-toggle="dropdown" class="dropdown-toggle" href="#">{% trans 'Administração' %} <b class="caret"></b></a>
<ul class="dropdown-menu">
<li><a href="/auth/">{% trans 'Usuários' %} &amp; {% trans 'Grupos' %}</a></li>
<li><a href="/sites/site/">{% trans 'Sites' %}</a></li>
<li><a href="/diagnosticos/">{% trans 'Diagnósticos' %}</a></li>
<li><a href="{% url 'importar-casas' %}">{% trans 'Importar dados de Casas' %}</a></li>
</ul>
</li>
{% endif %}
{% endblock %}
{% block footer %}
{% if not is_popup %}
<div id="footer">
<div class="footernote">
<p>{% trans 'Em caso de dúvida no uso do sistema contate o SPDT no ramal 2587' %}.</p>
<p>{% trans 'É recomendado o uso das informações aqui fornecidas fora do âmbito do Interlegis' %}.</p>
<p>{% trans 'SIGI é um software livre e seus fontes estão disponíveis no' %} <a href="http://colab.interlegis.leg.br/wiki/ProjetoSigi">Colab</a>.</p>
</div>
</div>
{% endif %}
{% endblock %}

98
templates/admin/carrinho.html

@ -1,98 +0,0 @@
{% extends "admin/base_site.html" %}
{% load i18n %}
{% block extrastyle %}
{{ block.super }}
<style>
.botoes{
/*background: url("../../static/admin/img/nav-bg.gif");*/
font-weight: bold;
/*color: red;*/
}
.botoes input{
background: none;
font-weight: bold;
border: none;
color: blue;
}
.botoes li {
background-image: url("../../static/admin/img/nav-bg.gif");
display: inline;
border: 1px solid #CCC;
padding: 5px 10px;
margin: 0px;
}
.botoes a{
}
.botao_excluir input{
color: red;
background: url("../../static/admin/img/icon_deletelink.gif") no-repeat scroll 0 50% transparent
}
</style>
{% endblock %}
{% block title %}{% trans 'Carrinho | SIGI' %}{% endblock %}
{% block content_title %}<h1>{% trans 'Carrinho' %}</h1>{% endblock %}
{% block content %}
<div id="content-main">
{% block mensagem %}
<ul class="messagelist">
{%if carIsEmpty%}
<li class="warning">{% trans 'O carrinho está vazio' %}</li>
{%else%}
<li>{{paginas.paginator.count}} {% trans 'Itens no carrinho' %}.</li>
{%endif%}
</ul>
{% endblock %}
<div id="changelist" class="module">
<form action="{% block action %}#{% endblock %}"
class="changelist-form" method="post">{% csrf_token %}
{%if not carIsEmpty%}
<div class="botoes">
<ul class="botao_excluir">
<li><input class="botao_excluir" type="submit" value=" Excluir do carrinho os itens selecionados" /></li>
<li><a href="excluir_carrinho">{% trans 'Esvaziar carrinho' %}</a></li>
</ul>
</div>
{% endif %}
<div class="result_list">
{% block tabela %}{% endblock %}
</div>
{%if not carIsEmpty%}
<div class="botoes">
<ul class="botao_excluir">
<li><input class="botao_excluir" type="submit" value=" Excluir do carrinho os itens selecionados" /></li>
<li><a href="excluir_carrinho">{% trans 'Esvaziar carrinho' %}</a></li>
</ul>
</div>
{% endif %}
<div class="paginator">
<span class="step-links">
{% if paginas.has_previous %}
<a href="?page={{ paginas.previous_page_number }}">{% trans 'Anterior' %}</a>
{% endif %}
<span class="this-page">
Página {{ paginas.number }} de {{ paginas.paginator.num_pages }}.
</span>
{% if paginas.has_next %}
<a href="?page={{ paginas.next_page_number }}">{% trans 'Próxima' %}</a>
{% endif %}
</span>
<span>{{paginas.paginator.count}} {% trans 'itens' %}</span>
</div>
</form>
{% block botoes %}{% endblock %}
</div>
</div>
{% endblock %}

121
templates/admin/change_list.html

@ -1,121 +0,0 @@
{% extends "admin/base_site.html" %}
{% load i18n admin_urls admin_static admin_list bootstrapped_goodies_tags %}
{% block extrastyle %}
{{ block.super }}
<link rel="stylesheet" type="text/css" href="{% static "admin/css/changelists.css" %}" />
{% if cl.formset %}
<link rel="stylesheet" type="text/css" href="{% static "admin/css/forms.css" %}" />
{% endif %}
{% if cl.formset or action_form %}
{% url 'admin:jsi18n' as jsi18nurl %}
<script type="text/javascript" src="{{ jsi18nurl|default:'../../jsi18n/' }}"></script>
{% endif %}
{{ media.css }}
{% endblock %}
{% block extrahead %}
{{ block.super }}
{{ media.js }}
{% if action_form %}{% if actions_on_top or actions_on_bottom %}
<script type="text/javascript">
(function($) {
$(document).ready(function($) {
$("tr input.action-select").actions();
});
})(django.jQuery);
</script>
{% endif %}{% endif %}
{% endblock %}
{% block bodyclass %}_change-list{% endblock %}
{% block coltype %}flex{% endblock %}
{% block object-tools %}
<ul class="object-tools pull-left nav nav-pills">
{% block object-tools-items %}
{% if has_add_permission %}
<li>
{% url cl.opts|admin_urlname:'add' as add_url %}
<a href="{% add_preserved_filters add_url is_popup %}">
<span class="glyphicon glyphicon-plus"></span> {% blocktrans with cl.opts.verbose_name as name %}Add {{ name }}{% endblocktrans %}
</a>
</li>
{% endif %}
{% endblock %}
</ul>
{% if cl.has_filters %}
<ul class="nav navbar-nav pull-right">
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">{% trans 'Filter' %} <span class="caret"></span></a>
<ul class="dropdown-menu pull-right">
{% for spec in cl.filter_specs %}
{% admin_list_filter cl spec %}
{% endfor %}
</ul>
</li>
</ul>
{% endif %}
{% block search %}{% search_form cl %}{% endblock %}
{% endblock %}
{% block content %}
{% block extra_search %}{% endblock %}
<form class="" id="changelist-form" action="" method="post"{% if cl.formset.is_multipart %} enctype="multipart/form-data"{% endif %}>{% csrf_token %}
{% if cl.formset.errors %}
<div class="alert alert-danger">
<p class="errornote">
{% blocktrans count cl.formset.errors|length as counter %}Please correct the error below.{% plural %}Please correct the errors below.{% endblocktrans %}
</p>
{{ cl.formset.non_form_errors }}
</div>
{% endif %}
{% with app_name=cl.opts.module_name|lower|slugify %}
{% render_with_template_if_exist cl.opts.app_label|lower|add:"/admin_app_"|add:app_name|add:"_description.html" "" %}
{% endwith %}
{% if action_form and actions_on_top and cl.full_result_count %}
<div class='pull-left'>{% admin_actions %}</div>
{% endif %}
<div id="content-main">
<div class="module{% if cl.has_filters %} filtered{% endif %}" id="_changelist">
{% block date_hierarchy %}
{% date_hierarchy cl %}
{% endblock %}
{% if cl.formset %}
<div>{{ cl.formset.management_form }}</div>
{% endif %}
{% block result_list %}
{% result_list cl %}
{% endblock %}
</div>
</div>
{# {% if cl.formset and cl.result_count %} #}
<div class="navbar navbar-default">
<div class="navbar-inner">
<div class="navbar-form pull-left">
{% if action_form and actions_on_bottom and cl.full_result_count %}
{% admin_actions %}
{% endif %}
</div>
<div class="navbar-form pull-right">
<input type="submit" name="_save" class="btn btn-primary default" value="{% trans 'Save' %}"/>
</div>
</div>
</div>
{# {% endif %} #}
{% block pagination %}
{% pagination cl %}
{% endblock %}
</form>
{% endblock %}

64
templates/admin/login.html

@ -1,64 +0,0 @@
{% extends "admin/base_site.html" %}
{% load i18n admin_static %}
{% block extrastyle %}{{ block.super }}<link rel="stylesheet" type="text/css" href="{% static "admin/css/login.css" %}" />{% endblock %}
{% block bodyclass %}login{% endblock %}
{% block menu-principal %}{% endblock %}
{% block content_title %}{% endblock %}
{% block breadcrumbs %}{% endblock %}
{% block container-top %}{% endblock %}
{% block branding %}
<h1 id="site-name">SIGI</h1>
{% endblock %}
{% block content %}
{% if form.errors and not form.non_field_errors and not form.this_is_the_login_form.errors %}
<p class="errornote">
{% if form.errors.items|length == 1 %}{% trans "Please correct the error below." %}{% else %}{% trans "Please correct the errors below." %}{% endif %}
</p>
{% endif %}
{% if form.non_field_errors or form.this_is_the_login_form.errors %}
{% for error in form.non_field_errors|add:form.this_is_the_login_form.errors %}
<p class="errornote">
{{ error }}
</p>
{% endfor %}
{% endif %}
<div id="content-main">
<form action="{{ app_path }}" method="post" id="login-form">{% csrf_token %}
<div class="form-row">
{% if not form.this_is_the_login_form.errors %}{{ form.username.errors }}{% endif %}
<label for="id_username" class="required">{{ form.username.label }}:</label> {{ form.username }}
</div>
<div class="form-row">
{% if not form.this_is_the_login_form.errors %}{{ form.password.errors }}{% endif %}
<label for="id_password" class="required">{% trans 'Password' %}:</label> {{ form.password }}
<input type="hidden" name="this_is_the_login_form" value="1" />
<input type="hidden" name="next" value="{{ next }}" />
</div>
{% url 'admin_password_reset' as password_reset_url %}
{% if password_reset_url %}
<div class="password-reset-link">
<a href="{{ password_reset_url }}">{% trans 'Forgotten your password or username?' %}</a>
</div>
{% endif %}
<div class="submit-row">
<label>&nbsp;</label><input type="submit" value="{% trans 'Log in' %}" />
</div>
</form>
<script type="text/javascript">
document.getElementById('id_username').focus()
</script>
</div>
{% endblock %}
{% block footer %}{% endblock %}

25
templates/admin/search_form.html

@ -1,25 +0,0 @@
{% load i18n admin_static %}
{% if cl.search_fields %}
<form class="navbar-form navbar-right" role="search" id="changelist-search" action="" method="get">
<div class="form-group"><!-- DIV needed for valid HTML -->
<div class="input-group">
<input type="text" class="form-control search-query" placeholder="{% trans 'Search' %}" size="40" name="{{ search_var }}" value="{{ cl.query }}" id="searchbar" />
<span class="input-group-btn">
<button class="btn btn-default" type="submit">
<span class="glyphicon glyphicon-search"></span>
</button>
</span>
</div>
</div>
{% if show_result_count %}
<span class="small quiet">{% blocktrans count counter=cl.result_count %}{{ counter }} result{% plural %}{{ counter }} results{% endblocktrans %} (<a href="?{% if cl.is_popup %}pop=1{% endif %}">{% blocktrans with full_result_count=cl.full_result_count %}{{ full_result_count }} total{% endblocktrans %}</a>)</span>
{% endif %}
{% for pair in cl.params.items %}
{% ifnotequal pair.0 search_var %}<input type="hidden" name="{{ pair.0 }}" value="{{ pair.1 }}"/>{% endifnotequal %}
{% endfor %}
</form>
<script type="text/javascript">document.getElementById("searchbar").focus();</script>
{% endif %}

33
templates/admin/tabs_style.html

@ -1,33 +0,0 @@
{% load static from staticfiles %}
{% load i18n %}
<!--CSS JQuery-->
<link type="text/css" href="{% static 'css/jquery/smoothness/jquery.ui.all.css' %}" rel="stylesheet" />
<!--Scripts JQuery-->
<script type="text/javascript" src="{% static 'js/jquery/jquery-1.4.2.js' %}" ></script>
<script type="text/javascript" src="{% static 'js/jquery/ui/jquery.ui.core.js' %}" ></script>
<script type="text/javascript" src="{% static 'js/jquery/ui/jquery.ui.widget.js' %}" ></script>
<script type="text/javascript" src="{% static 'js/jquery/ui/jquery.ui.tabs.js' %}" ></script>
<script type="text/javascript" src="{% static 'js/jquery/ui/jquery.ui.mouse.js' %}" ></script>
<script type="text/javascript" src="{% static 'js/jquery/ui/jquery.ui.sortable.js' %}" ></script>
<script type="text/javascript">
$(function() {
$( "#tabs" ).tabs({
event: "mouseover"
});
});
</script>
<script>
$(function() {
$( "#sortable" ).sortable();
$( "#sortable" ).disableSelection();
});
</script>
<style>
.ui-tabs-nav {
background-image: url("{% static 'admin/img/nav-bg.gif' %}" );
}
</style>

20
templates/base_change_form.html

@ -1,20 +0,0 @@
{% extends "admin/change_form.html" %}
{% load i18n admin_urls %}
{% block object-tools %}
{% if change %}{% if not is_popup %}
<ul class="nav navbar-nav navbar-left">
{% block object-tools-items %}
<li>
{% url opts|admin_urlname:'history' original.pk|admin_urlquote as history_url %}
<a href="{% add_preserved_filters history_url %}" class="historylink">
<span class="glyphicon glyphicon-book"></span>
{% trans "History" %}
</a>
</li>
{% if has_absolute_url %}<li><a href="{% url 'admin:view_on_site' content_type_id original.pk %}" class="viewsitelink">{% trans "View on site" %}</a></li>{% endif%}
{% endblock %}
</ul>
{% endif %}{% endif %}
{% endblock %}

56
templates/base_mobile.html

@ -1,56 +0,0 @@
{% load static from staticfiles %}
{% load i18n %}
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
{% block titulo %}
<title>{% trans 'SIGI - Diagnósticos' %}</title>
{% endblock titulo %}
{% block media %}
<link rel="stylesheet" href="{% static 'jquery.mobile-1.0.1/jquery.mobile-1.0.1.min.css' %}" />
<script type="text/javascript" src="{% static '/js/jquery/jquery-1.6.4.min.js' %}" ></script>
<script language=javascript>
$(document).bind("mobileinit", function () {
$.mobile.ajaxEnabled = false;
$.mobile.loadingMessage = 'salvando';
});
</script>
<script type="text/javascript" src="{% static 'js/jquery/jquery.maskedinput-1.1.3.min.js' %}" /></script>
<script type="text/javascript" src="{% static 'jquery.mobile-1.0.1/jquery.mobile-1.0.1.min.js' %}" ></script>
<script type="text/javascript" src="{% static 'js/diagnosticos/diagnosticos_categorias_form.js' %}" ></script>
{% endblock media %}
</head>
<body>
<div data-role="page" id="page" class="type-interior">
<div data-role="header" data-position="fixed">
<img id="working" src="{% static 'img/loader.gif' %}" class="ui-btn-right"/>
{% block cabecalho %}{% endblock cabecalho %}
</div> <!-- header -->
<div data-role="content" class="content-primary">
{% block corpo %}{% endblock corpo %}
</div><!-- content -->
<div data-role="footer">
<div data-role="navbar">
<ul>
{% block rodape %}
<li><a href="{% url 'lista_diagnosticos' %}" data-icon="home">{% trans 'Página Inicial' %}</a></li>
{% endblock rodape %}
</ul>
</div>
</div> <!-- footer -->
</div> <!-- page -->
<a id='open-dialog' href="#dialog" data-rel="dialog" data-transition="pop" style='display:none;'></a>
<div data-role="page" id="dialog">
<div data-role="header">
<h1>{% trans 'Ops! Não foi possivel salvar os dados' %}.</h1>
</div>
<div data-role="content" id="text">
{% trans 'Algum erro ocorreu ao salvar os dados do diagnóstico' %}.
{% trans 'Verifique a sua conectividade e/ou entre em contato com a equipe técnica o mais rápido possível' %}.
</div>
</div>
</body>
</html>

108
templates/base_report.html

@ -1,108 +0,0 @@
{% load smart_if %}
{% load static from staticfiles %}
{% load i18n %}
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>{% block title %}{% trans 'Relatório' %}{% endblock title %}</title>
<style type="text/css">
td.logo {
text-align: center;
}
td.header_text p {
margin: 0px;
font-size: 1.4em;
}
td.header_text {
width: 550px;
}
h1 {
font-size: 2em;
text-align: center;
}
h2 {
font-size: 1.7em;
}
h3 {
margin-top: 10px;
margin-bottom: 0px;
}
body {
font-family: "Helvetica, Arial, sans-serif";
font-size: 1.3em;
line-height: 1em;
}
#footer {
width: 100%;
}
#footer table {
border: 0px;
}
.footer-left {
text-align: left;
}
.footer-center {
text-align: center;
}
.footer-right {
text-align: right;
}
div.new_page {
page-break-before: always;
}
div.same_page {
-pdf-keep-with-next: true;
}
@page {
size: {% block pagesize %}{{ pagesize }}{% endblock pagesize %};
margin: 4cm 1cm 1cm 2cm;
font-family: "Helvetica, Arial, sans-serif";
font-size: 2em;
@frame header {
-pdf-frame-content: header;
top: 1cm;
}
@frame footer {
-pdf-frame-content: footer;
bottom: 0cm;
height: 1cm;
margin-left: 2cm;
margin-right: 1cm;
}
}
</style>
{% block extra_head %}
{% endblock %}
</head>
<body>
<div id="header">
<table>
<tr>
<td class="logo"><img src="{% static 'img/logo-senado.jpg' %}" /></td>
<td class="header_text">
<p><strong>{% trans 'SENADO FEDERAL' %}</strong></p>
<p><strong>{% trans 'ILB - PROGRAMA INTERLEGIS' %}</strong></p>
<p>{% block subsecretaria %}{% endblock %}</p>
</td>
<td class="logo"><img src="{% static 'img/logo-interlegis.jpg' %}" /></td>
</tr>
</table>
</div>
{% block report %}
{% endblock %}
<div id="footer">
{%block page_foot%}
<table>
<tr>
<td class="footer-left">{% trans 'Emissão:' %} {% now "d/m/Y H:i:s" %}</td>
<td class="footer-center">&nbsp;</td>
<td class="footer-right">{% trans 'Página:' %} <pdf:pagenumber/> </td>
</tr>
</table>
{%endblock%}
</div>
</body>
</html>

18
templates/change_form_with_report_and_labels.html

@ -1,18 +0,0 @@
{% extends "base_change_form.html" %}
{% load i18n %}
{% block object-tools-items %}
<li><a href="report_complete/">
<span class="glyphicon glyphicon-list-alt"></span>
{% trans 'Relatório' %}
</a></li>
<li><a href="labels/">
<span class="glyphicon glyphicon-th"></span>
{% trans 'Etiqueta' %}
</a></li>
<li><a href="labels_sem_presidente/">
<span class="glyphicon glyphicon-th-large"></span>
{% trans 'Etiqueta sem presidente' %}
</a></li>
{{ block.super }}
{% endblock %}

10
templates/change_list_with_cart.html

@ -1,10 +0,0 @@
{% extends "admin/change_list.html" %}
{% load admin_list i18n reporting_tags %}
{% block object-tools-items %}
<li><a class="btn" href="carrinho/{{query_str}}">
<span class="glyphicon glyphicon-shopping-cart"></span>
{% trans 'Ver Carrinho' %}
</a></li>
{{ block.super }}
{% endblock %}

5
templates/clear_all_filter.html

@ -1,5 +0,0 @@
{% load i18n %}
{% with choices|first as disabled %}
<li class="clear-all-filter{% if disabled %} disabled{% endif %}"><a href="?">{% trans 'Clear All Filters' %}</a></li>
{% endwith %}

36
templates/index.html

@ -1,36 +0,0 @@
{% extends "admin/base_site.html" %}
{% load i18n admin_static %}
{% load static from staticfiles %}
{% block title %}SIGI{% endblock %}
{% block extrahead %}
{{ block.super }}
<link rel="stylesheet" type="text/css" href="{% static 'css/style.css' %}" >
<script type="text/javascript" src="{% static 'admin/js/core.js' %}" ></script>
<script type="text/javascript" src="{% static 'admin/js/jquery.min.js' %}" ></script>
<script type="text/javascript" src="{% static 'admin/js/jquery.init.js' %}" ></script>
<script type="text/javascript" src="{% static 'js/Chart.min.js' %}" ></script>
<script type="text/javascript" src="{% static 'js/dashboard.js' %}"></script>
{% endblock %}
{% block content_title %}
<h1 class="pull-left">{% trans 'Dashboard' %}</h1>
<div class="pull-right"><a href="{% url 'openmap' %}"><img src="{% static 'img/mapicon.png' %}" /> {% trans 'Mapa de atuação do Interlegis' %}</a></div>
{% endblock %}
{% block extrastyle %}{{ block.super }}<link rel="stylesheet" type="text/css" href="{% static "admin/css/dashboard.css" %}" />{% endblock %}
{% block coltype %}colMS{% endblock %}
{% block bodyclass %}dashboard{% endblock %}
{% block breadcrumbs %}{% endblock %}
{% block content %}
<div id="content-main">
{% include "snippets/modules/charts-convenios.html" %}
</div>
{% endblock %}

16
templates/mobile/404.html

@ -1,16 +0,0 @@
{% extends "base_mobile.html" %}
{% load i18n %}
{% block cabecalho %}
<h1>{% trans 'Ocorreu um erro' %}</h1>
{% endblock cabecalho %}
{% block corpo %}
<p>{% trans 'A página que está procurando não existe.' %} </p>
<p>{% trans 'Verifique se o diagnóstico, categoria ou pergunta está cadastrado no sistema.' %}</p>
<a href="{% url 'lista_diagnosticos' %}" data-icon="arrow-l"
data-direction="reverse" data-role="button" data-theme="c" class="ui-btn-left">{% trans 'Voltar' %}</a>
{% endblock corpo %}
{% block rodape %}
{% endblock rodape %}

92
templates/snippets/modules/charts-convenios.html

@ -1,92 +0,0 @@
{% load static from staticfiles %}
{% load i18n %}
<div class="row row-flex row-flex-wrap">
<div id="resumoseit" class="col-md-6" data-source="{% url "home_resumoseit" %}"></div>
<div class="col-md-6">
<div class="panel panel-primary flex-col">
<div class="panel-heading">{% trans 'Sazonalidade da hospedagem de serviços' %}</div>
<div class="panel-body">
<div class="chartcontainer">
<canvas id="chart-area-evolucao" data-source="{% url "home_chartseit" %}" data-legend-id="area-evolucao-legend" data-prevlink-id="area-evolucao-previlink" data-nextlink-id="area-evolucao-nextlink"></canvas>
<div id="area-evolucao-legend"></div>
<div>
<a id="area-evolucao-previlink" href="#" aria-label="{% trans "Retroceder um mês" %}" data-target="chart-area-evolucao">
<span class="glyphicon glyphicon-chevron-left pull-left" aria-hidden="true"></span>
</a>
<a id="area-evolucao-nextlink" href="#" aria-label="{% trans "Avançar um mês" %}" data-target="chart-area-evolucao">
<span class="glyphicon glyphicon-chevron-right pull-right" aria-hidden="true"></span>
</a>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row row-flex row-flex-wrap">
<div id="resumo" class="col-md-6" data-source="{% url "casas-carteira" %}?snippet=resumo&s=sim"></div>
<div class="col-md-6">
<div class="panel panel-primary flex-col">
<div class="panel-heading">{% trans 'Performance da gerência de carteiras' %}</div>
<div class="panel-body">
<ul class="nav nav-pills" role="tablist">
<li role="presentation"><a href="{% url "home_chartperformance" %}" data-target="chart-performance">{% trans "Todo o Interlegis" %}</a></li>
{% for g in gerentes %}
<li role="presentation"><a href="{% url "home_chartperformance" %}?servidor={{ g.pk }}" data-target="chart-performance">{{ g.user.first_name }}</a></li>
{% endfor %}
</ul>
<div class="chartcontainer">
<canvas id="chart-performance" data-source="{% url "home_chartperformance" %}" data-legend-id="chart-performance-all-legend"></canvas>
<div id="chart-performance-all-legend"></div>
</div>
</div>
</div>
</div>
</div>
<div class="row row-flex row-flex-wrap">
<div class="col-md-6" data-source="{% url "home_resumoconvenios" %}"></div>
<div class="col-md-6">
<div class="panel panel-primary flex-col">
<div class="panel-heading">{% trans 'Distribuição de Casas por Gerente' %}</div>
<div class="panel-body">
<div class="chartcontainer">
<canvas id="chart-carteira" data-source="{% url "home_chartcarteira" %}" data-legend-id="chart-carteira-legend"></canvas>
<div id="chart-carteira-legend"></div>
</div>
</div>
</div>
</div>
</div>
{% comment %}
<div class="row row-flex row-flex-wrap">
<div class="col-md-6">
<div class="panel panel-primary flex-col">
<div class="panel-heading">{% trans 'Convênios assinados por projeto' %}</div>
<div class="panel-body">
<div class="chartcontainer">
<div>
<canvas id="chart-area-convenios" width="400" height="400" data-source="{% url "home_chartconvenios" %}" data-legend-id="area-convenios-legend"></canvas>
</div>
<div id="area-convenios-legend"></div>
</div>
</div>
</div>
</div>
<div class="col-md-6">
<div class="panel panel-primary flex-col">
<div class="panel-heading">{% trans 'Processos de convênios por projeto' %}</div>
<div class="panel-body">
<div class="chartcontainer">
<canvas id="chart-area-processos" width="150" height="150" data-source="{% url "home_chartconvenios" %}?q=assinados" data-legend-id="area-processos-legend"></canvas>
<div id="area-processos-legend"></div>
</div>
</div>
</div>
</div>
</div>
{% endcomment %}

69
templates/snippets/modules/resumo_convenios.html

@ -1,69 +0,0 @@
{% load i18n %}
<div class="panel panel-primary flex-col">
<div class="panel-heading">{% trans 'Resumo de informações' %}</div>
<div class="panel-body table-responsive">
<dl class="dl-horizontal">
<dt class="pilllabel">{% trans 'Resumo por região' %}:</dt>
<dd>
<ul class="nav nav-pills">
<li><a href="{% url 'convenios-report_regiao_pdf' 'CO' %}">Centro Oeste</a></li>
<li><a href="{% url 'convenios-report_regiao_pdf' 'NE' %}">Nordeste</a></li>
<li><a href="{% url 'convenios-report_regiao_pdf' 'NO' %}">Norte</a></li>
<li><a href="{% url 'convenios-report_regiao_pdf' 'SD' %}">Sudeste</a></li>
<li><a href="{% url 'convenios-report_regiao_pdf' 'SL' %}">Sul</a></li>
</ul>
</dd>
</dl>
<table class="table table-condensed numeros">
<tr>
{% for item in tabela_resumo_camara.cabecalho_topo %}
<th>{{item}}</th>
{% endfor %}
</tr>
{% for cabecalho,lista in tabela_resumo_camara.lista_zip %}
<tr>
<th>{{cabecalho}}</th>
{% for item in lista %}
<td>{{item}}</td>
{% endfor %}
</tr>
{% endfor %}
</table>
</div>
<div class="panel-footer">
<table class="table table-condensed numeros">
<tr>
<th>{% trans 'Total de câmaras' %}</th>
<td>{{ tabela_resumo_camara.total_camaras }}</td>
</tr>
<tr>
<th>{% trans 'Câmaras sem processo' %}</th>
<td>{{ tabela_resumo_camara.camaras_sem_processo }}</td>
</tr>
<tr>
<th>{% trans 'Casas sem convenio que utilizam algum serviço de hospedagem' %}
<a href="{% url "home_reportsemconvenio" %}?modo=H" target="_blank" aria-label="{% trans "Listar casas" %}" title="{% trans "Listar casas" %}"><span class="glyphicon glyphicon-list-alt" aria-hidden="true"></span></a>
<a href="{% url "home_reportsemconvenio" %}?modo=H&f=csv" aria-label="{% trans "Download csv" %}" title="{% trans "Download csv" %}"><span class="glyphicon glyphicon-download" aria-hidden="true"></span></a>
</th>
<td>{{ tabela_resumo_camara.sem_convenio.hospedagem|length }}</td>
</tr>
<tr>
<th>{% trans 'Casas sem convenio que utilizam somente serviço de registro' %}
<a href="{% url "home_reportsemconvenio" %}?modo=R" target="_blank" aria-label="{% trans "Listar casas" %}" title="{% trans "Listar casas" %}"><span class="glyphicon glyphicon-list-alt" aria-hidden="true"></span></a>
<a href="{% url "home_reportsemconvenio" %}?modo=R&f=csv" aria-label="{% trans "Download csv" %}" title="{% trans "Download csv" %}"><span class="glyphicon glyphicon-download" aria-hidden="true"></span></a>
</th>
<td>{{ tabela_resumo_camara.sem_convenio.registro|length }}</td>
</tr>
<tr>
<th>{% trans 'Casas sem convenio que utilizam algum serviço de registro e/ou hospedagem' %}
<a href="{% url "home_reportsemconvenio" %}" target="_blank" aria-label="{% trans "Listar casas" %}" title="{% trans "Listar casas" %}"><span class="glyphicon glyphicon-list-alt" aria-hidden="true"></span></a>
<a href="{% url "home_reportsemconvenio" %}?f=csv" aria-label="{% trans "Download csv" %}" title="{% trans "Download csv" %}"><span class="glyphicon glyphicon-download" aria-hidden="true"></span></a>
</th>
<td>{{ tabela_resumo_camara.sem_convenio.total|length }}</td>
</tr>
</table>
</div>
</div>

38
templates/snippets/modules/resumo_seit.html

@ -1,38 +0,0 @@
{% load static from staticfiles %}
{% load i18n %}
<div class="panel panel-primary flex-col">
<div class="panel-heading">{% trans 'Serviços hospedados no Interlegis (SEIT)' %}</div>
<div class="panel-body">
<table class="table table-condensed numeros servicos">
<tr>
{% for s in tabela_resumo_seit.titulos %}
<th>{{ s }}</th>
{% endfor %}
</tr>
{% for servico in tabela_resumo_seit.servicos %}
<tr>
<th class="dropdown">
<a id="ddm-{{ servico.nome }}" data-toggle="dropdown" href="#">{{ servico.nome }}</a>
<table class="table table-condensed numeros servicos dropdown-menu" role="menu" aria-labelledby="ddm-{{ servico.nome }}">
{% for mes in servico.novos_por_mes %}
<tr><th>{{ mes.mes }}</th><td>{{ mes.total }}</td></tr>
{% endfor %}
</table>
</th>
<td>{{ servico.total }}</td>
<td>{{ servico.novos_mes_anterior }}</td>
<td>{{ servico.novos_mes_atual }}</td>
</tr>
{% endfor %}
</table>
<div>
<a href="{% url "home_resumoseit" %}?ano={{ tabela_resumo_seit.mes_anterior.year|safe }}&mes={{ tabela_resumo_seit.mes_anterior.month|safe }}" aria-label="{% trans "Retroceder um mês" %}" data-target="resumoseit">
<span class="glyphicon glyphicon-chevron-left pull-left" aria-hidden="true"></span>
</a>
<a href="{% url "home_resumoseit" %}?ano={{ tabela_resumo_seit.proximo_mes.year|safe }}&mes={{ tabela_resumo_seit.proximo_mes.month|safe }}" aria-label="{% trans "Avançar um mês" %}" data-target="resumoseit">
<span class="glyphicon glyphicon-chevron-right pull-right" aria-hidden="true"></span>
</a>
</div>
</div>
</div>
Loading…
Cancel
Save