@ -1,5 +1,6 @@
# -*- coding: utf-8 -*-
import csv
from datetime import datetime
import json as simplejson # XXX trocar isso por simplesmente import json e refatorar o codigo
import os
import time
@ -64,6 +65,9 @@ def dashboard(request):
return render_to_response ( ' metas/dashboard.html ' , extra_context , context_instance = RequestContext ( request ) )
def openmap ( request ) :
reptype = request . GET . get ( ' reptype ' , None )
if reptype is None :
context = {
' tipos_orgao ' : TipoOrgao . objects . filter ( legislativo = True ) ,
' tipos_servico ' : TipoServico . objects . all ( ) ,
@ -71,9 +75,81 @@ def openmap(request):
' gerentes ' : Servidor . objects . exclude ( casas_que_gerencia = None ) ,
' regioes ' : [ ( s , n , UnidadeFederativa . objects . filter ( regiao = s ) )
for s , n in UnidadeFederativa . REGIAO_CHOICES ] ,
}
return render ( request , ' metas/openmap.html ' , context )
else :
tipos_orgao = request . GET . getlist ( ' tipo_orgao ' , [ ] )
tipos_servico = request . GET . getlist ( ' tipo_servico ' , [ ] )
tipos_convenio = request . GET . getlist ( ' tipo_convenio ' , [ ] )
gerentes = request . GET . getlist ( ' gerente ' , [ ] )
ufs = request . GET . getlist ( ' uf ' , [ ] )
casas = openmapdata ( request )
context = {
' tipos_orgao ' : TipoOrgao . objects . filter ( legislativo = True ,
sigla__in = tipos_orgao ) ,
' tipos_servico ' : TipoServico . objects . filter (
sigla__in = tipos_servico
) ,
' tipos_convenio ' : Projeto . objects . filter ( sigla__in = tipos_convenio ) ,
' gerentes ' : Servidor . objects . exclude (
casas_que_gerencia = None ) . filter ( id__in = gerentes ) ,
' ufs ' : UnidadeFederativa . objects . filter ( sigla__in = ufs ) ,
' casas ' : casas
}
if reptype == " lista " :
return render_to_pdf ( " metas/lista_casas.html " , context )
else :
fieldnames = [ ' cnpj ' , ' nome ' , ' uf ' , ' regiao ' , ' endereco ' , ' bairro ' ,
' cep ' , ' ult_alt_endereco ' , ' presidente ' ,
' ult_atualizacao_presidente ' , ' telefone_presidente ' ,
' email_presidente ' , ' telefones ' , ' emails ' , ' contatos ' ,
' convenios ' , ' servicos ' ]
response = HttpResponse ( content_type = ' text/csv ' )
writer = csv . DictWriter ( response , fieldnames = fieldnames )
writer . writeheader ( )
for casa in casas :
row = {
' cnpj ' : casa . cnpj . encode ( ' utf8 ' ) ,
' nome ' : casa . nome . encode ( ' utf8 ' ) ,
' uf ' : casa . municipio . uf . nome . encode ( ' utf8 ' ) ,
' regiao ' :
casa . municipio . uf . get_regiao_display ( ) . encode ( ' utf8 ' ) ,
' endereco ' : casa . logradouro . encode ( ' utf8 ' ) ,
' bairro ' : casa . bairro . encode ( ' utf8 ' ) ,
' cep ' : casa . cep . encode ( ' utf8 ' ) ,
' ult_alt_endereco ' : ( casa . ult_alt_endereco . strftime (
" %d / % m/ % Y " ) . encode ( ' utf8 ' )
if casa . ult_alt_endereco else " " ) ,
' telefones ' : u " , " . join ( casa . telefones . values_list ( ' numero ' ,
flat = True )
) . encode ( ' utf8 ' ) ,
' emails ' : u " , " . join ( [ casa . email ] + list (
casa . funcionario_set . values_list ( ' email ' , flat = True ) )
) . encode ( ' utf8 ' ) ,
' contatos ' : u " , " . join ( casa . funcionario_set . values_list (
' nome ' , flat = True ) ) . encode ( ' utf8 ' ) ,
' convenios ' : u " , " . join ( [ c . __unicode__ ( ) for c in
casa . convenio_set . all ( ) ]
) . encode ( ' utf8 ' ) ,
' servicos ' : u " , " . join ( [ u " {tipo} ( {url} ) " . format (
tipo = s . tipo_servico . nome , url = s . url )
for s in casa . servico_set . all ( ) ]
) . encode ( ' utf8 ' )
}
if casa . presidente :
row [ ' presidente ' ] = casa . presidente . nome . encode ( ' utf8 ' )
row [ ' ult_atualizacao_presidente ' ] = (
casa . presidente . ult_alteracao . strftime ( " %d / % m/ % Y " )
if casa . presidente . ult_alteracao else " " )
row [ ' telefone_presidente ' ] = casa . presidente . nota . encode (
' utf8 ' ) if casa . presidente . nota else " "
row [ ' email_presidente ' ] = casa . presidente . email . encode (
' utf8 ' )
writer . writerow ( row )
return response
def openmapdata ( request ) :
tipos_orgao = request . GET . getlist ( ' tipo_orgao ' , None )
@ -112,381 +188,46 @@ def openmapdata(request):
else :
dados = dados . filter ( gerentes_interlegis__id__in = gerentes )
dados = dados . distinct ( " nome " )
if not reptype :
dados = dados . distinct ( " nome " )
dados = dados . values_list ( " id " , " nome " , " municipio__latitude " ,
" municipio__longitude " )
return JsonResponse ( list ( dados ) , safe = False )
else :
return JsonResponse ( { ' result ' : ' todo-feature ' } )
dados = dados . order_by (
' municipio__uf__regiao ' ,
' municipio__uf__nome ' ,
' nome '
) . distinct (
' municipio__uf__regiao ' ,
' municipio__uf__nome ' ,
' nome '
) . prefetch_related (
' servico_set ' ,
' convenio_set ' ,
' municipio__uf ' ,
' gerentes_interlegis '
)
return dados
def openmapdetail ( request , orgao_id ) :
orgao = get_object_or_404 ( Orgao , id = orgao_id )
return render ( request , " metas/openmapdetail.html " , { ' orgao ' : orgao } )
def mapa ( request ) :
"""
Mostra o mapa com filtros carregados com valores default
"""
projetos = Projeto . objects . all ( )
filters = (
# NAME, HEADING,
# [(value, label, checked) ...]
( " seit " , _ ( u ' Por Serviços SEIT ' ) ,
[ ( x . sigla , x . sigla , x . nome , True )
for x in TipoServico . objects . all ( ) ] ) ,
( " convenios " , _ ( u ' Por Casas conveniadas ' ) ,
[ ( x . sigla ,
' convenio_ ' + x . sigla ,
_ ( u ' ao {projeto} ' ) . format ( projeto = x . sigla ) ,
x . sigla == ' PML ' ) for x in projetos ] ) ,
( " equipadas " , _ ( u ' Por Casas equipadas ' ) ,
[ ( x . sigla ,
' equip_ ' + x . sigla ,
_ ( u ' pelo {projeto} ' ) . format ( projeto = x . sigla ) ,
False ) for x in projetos ] ) ,
( " diagnosticos " , _ ( u ' Por Diagnósticos ' ) ,
[ ( ' A ' , ' diagnostico_A ' , ' Em andamento ' , False ) ,
( ' P ' , ' diagnostico_P ' , ' Publicados ' , True ) ] ) ,
( " regioes " , _ ( u ' Por região ' ) ,
[ ( x [ 0 ] , x [ 0 ] , x [ 1 ] , True )
for x in UnidadeFederativa . REGIAO_CHOICES ] ) ,
( " estados " , _ ( u ' Por Estado ' ) ,
[ ( x . sigla , x . sigla , x . nome , False )
for x in UnidadeFederativa . objects . all ( ) ] ) ,
( " gerente " , _ ( u ' Por gerente de relacionamento ' ) ,
[ ( " " , ' gerente_ ' , _ ( u " Sem gerente " ) , False ) ] +
[ ( g . id , ' gerente_ {0} ' . format ( g . id ) ,
_ ( u " {firstname} {lastname} " ) . format (
firstname = g . nome_completo . split ( ) [ 0 ] ,
lastname = g . nome_completo . split ( ) [ - 1 ] )
, False ) for g in Servidor . objects . exclude (
casas_que_gerencia = None ) . order_by ( ' nome_completo ' ) ] ) ,
)
return render ( request , ' metas/mapa.html ' , { ' filters ' : filters } )
@cache_page ( 1800 ) # Cache de 30min
def map_data ( request ) :
"""
Retorna json com todos os dados dos municípios que têm relação com o Interlegis
Tenta ler esse json do arquivo JSON_FILE_NAME . Se não encontrar , chama a rotina
gera_map_data_file ( ) .
"""
try :
file = open ( JSON_FILE_NAME , ' r ' )
json = file . read ( )
except :
json = gera_map_data_file ( )
return HttpResponse ( json , content_type = ' application/json ' )
def map_search ( request ) :
response = { ' result ' : ' NOT_FOUND ' }
if ' q ' in request . GET :
q = request . GET . get ( ' q ' )
if len ( q . split ( ' , ' ) ) > 1 :
municipio , uf = [ s . strip ( ) for s in q . split ( ' , ' ) ]
casas = Orgao . objects . filter ( search_text__icontains = to_ascii ( municipio ) , municipio__uf__sigla__iexact = uf )
else :
casas = Orgao . objects . filter ( search_text__icontains = to_ascii ( q ) )
if casas . count ( ) > 0 :
response = { ' result ' : ' FOUND ' , ' ids ' : [ c . pk for c in casas ] }
return HttpResponse ( simplejson . dumps ( response ) , content_type = ' application/json ' )
@cache_page ( 86400 ) # Cache de um dia (24 horas = 86400 segundos)
def map_sum ( request ) :
# Filtrar Casas de acordo com os parâmetros
param = get_params ( request )
casas = filtrar_casas ( * * param )
# Montar registros de totalização
tot_servicos = SortedDict ( )
tot_projetos = SortedDict ( )
tot_diagnosticos = SortedDict ( )
for ts in TipoServico . objects . all ( ) :
tot_servicos [ ts . sigla ] = 0
for pr in Projeto . objects . all ( ) :
tot_projetos [ pr . sigla ] = 0
tot_convenios = tot_projetos . copy ( )
tot_equipadas = tot_projetos . copy ( )
tot_diagnosticos [ ' A ' ] = 0
tot_diagnosticos [ ' P ' ] = 0
# Montar as linhas do array de resultados com as regiões e os estados
result = { }
for uf in UnidadeFederativa . objects . filter ( Q ( regiao__in = param [ ' regioes ' ] ) | Q ( sigla__in = param [ ' estados ' ] ) ) . order_by ( ' regiao ' , ' nome ' ) :
if uf . regiao not in result :
result [ uf . regiao ] = { ' nome ' : uf . get_regiao_display ( ) , ' ufs ' : { } , ' servicos ' : tot_servicos . copy ( ) ,
' convenios ' : tot_projetos . copy ( ) , ' equipadas ' : tot_projetos . copy ( ) ,
' diagnosticos ' : tot_diagnosticos . copy ( ) }
result [ uf . regiao ] [ ' ufs ' ] [ uf . codigo_ibge ] = { ' nome ' : uf . nome , ' servicos ' : tot_servicos . copy ( ) ,
' convenios ' : tot_projetos . copy ( ) , ' equipadas ' : tot_projetos . copy ( ) ,
' diagnosticos ' : tot_diagnosticos . copy ( ) }
# Processar as casas filtradas
for casa in casas . distinct ( ) :
uf = casa . municipio . uf
for s in casa . servico_set . all ( ) :
tot_servicos [ s . tipo_servico . sigla ] + = 1
result [ uf . regiao ] [ ' servicos ' ] [ s . tipo_servico . sigla ] + = 1
result [ uf . regiao ] [ ' ufs ' ] [ uf . codigo_ibge ] [ ' servicos ' ] [ s . tipo_servico . sigla ] + = 1
for c in casa . convenio_set . all ( ) :
tot_convenios [ c . projeto . sigla ] + = 1
result [ uf . regiao ] [ ' convenios ' ] [ c . projeto . sigla ] + = 1
result [ uf . regiao ] [ ' ufs ' ] [ uf . codigo_ibge ] [ ' convenios ' ] [ c . projeto . sigla ] + = 1
if ( c . equipada and c . data_termo_aceite is not None ) :
tot_equipadas [ c . projeto . sigla ] + = 1
result [ uf . regiao ] [ ' equipadas ' ] [ c . projeto . sigla ] + = 1
result [ uf . regiao ] [ ' ufs ' ] [ uf . codigo_ibge ] [ ' equipadas ' ] [ c . projeto . sigla ] + = 1
for d in casa . diagnostico_set . all ( ) :
if d . publicado :
tot_diagnosticos [ ' P ' ] + = 1
result [ uf . regiao ] [ ' diagnosticos ' ] [ ' P ' ] + = 1
result [ uf . regiao ] [ ' ufs ' ] [ uf . codigo_ibge ] [ ' diagnosticos ' ] [ ' P ' ] + = 1
else :
tot_diagnosticos [ ' A ' ] + = 1
result [ uf . regiao ] [ ' diagnosticos ' ] [ ' A ' ] + = 1
result [ uf . regiao ] [ ' ufs ' ] [ uf . codigo_ibge ] [ ' diagnosticos ' ] [ ' A ' ] + = 1
extra_context = {
' pagesize ' : ' a4 landscape ' ,
' servicos ' : TipoServico . objects . all ( ) ,
' projetos ' : Projeto . objects . all ( ) ,
' result ' : result ,
' tot_servicos ' : tot_servicos ,
' tot_convenios ' : tot_convenios ,
' tot_equipadas ' : tot_equipadas ,
' tot_diagnosticos ' : tot_diagnosticos ,
}
return render_to_pdf ( ' metas/map_sum.html ' , extra_context )
@cache_page ( 86400 ) # Cache de um dia (24 horas = 86400 segundos)
def map_list ( request ) :
# Filtrar Casas de acordo com os parâmetros
param = get_params ( request )
formato = request . GET . get ( ' fmt ' , ' pdf ' )
casas = filtrar_casas ( * * param )
casas = casas . order_by ( ' municipio__uf__regiao ' , ' municipio__uf__nome ' , ' nome ' ) . distinct ( )
if formato == ' csv ' :
response = HttpResponse ( content_type = ' text/csv ' )
response [ ' Content-Disposition ' ] = ' attachment; filename= " maplist.csv " '
writer = csv . writer ( response )
srv = { x [ 0 ] : x [ 1 ] for x in TipoServico . objects . values_list ( ' id ' , ' nome ' ) }
cnv = { x [ 0 ] : x [ 1 ] for x in Projeto . objects . values_list ( ' id ' , ' sigla ' ) }
def openmapsearch ( request ) :
q = request . GET . get ( ' q ' , ' ' )
if len ( q ) < 3 :
return JsonResponse ( { ' result ' : ' unsearchable ' } )
head = [ s . encode ( ' utf-8 ' ) for s in
[ u ' código IBGE ' , u ' nome da casa ' , u ' município ' , u ' UF ' , u ' região ' , ] +
[ x for x in srv . values ( ) ] +
reduce ( lambda x , y : x + y ,
[ [ ' conveniada ao %s ' % x , ' equipada por %s ' % x ] for x in cnv . values ( ) ] ) ]
writer . writerow ( head )
for casa in casas :
row = [ casa . municipio . codigo_ibge ,
casa . nome . encode ( ' utf-8 ' ) ,
casa . municipio . nome . encode ( ' utf-8 ' ) ,
casa . municipio . uf . sigla . encode ( ' utf-8 ' ) ,
casa . municipio . uf . get_regiao_display ( ) . encode ( ' utf-8 ' ) , ]
for id in srv . keys ( ) :
try :
sv = casa . servico_set . get ( tipo_servico__id = id )
row + = [ sv . data_ativacao , ]
except :
row + = [ None , ]
for id in cnv . keys ( ) :
try :
cv = casa . convenio_set . get ( projeto__id = id )
row + = [ cv . data_retorno_assinatura , cv . data_termo_aceite if cv . equipada else None , ]
except :
row + = [ None , None , ]
writer . writerow ( row )
return response
return render_to_pdf ( ' metas/map_list.html ' , { ' casas ' : casas } )
#----------------------------------------------------------------------------------------------------
# Funções auxiliares - não são views
#----------------------------------------------------------------------------------------------------
def get_params ( request ) :
''' Pegar parâmetros da pesquisa '''
return {
' seit ' : request . GET . getlist ( ' seit ' ) ,
' convenios ' : request . GET . getlist ( ' convenios ' ) ,
' equipadas ' : request . GET . getlist ( ' equipadas ' ) ,
' diagnosticos ' : request . GET . getlist ( ' diagnosticos ' ) ,
' regioes ' : request . GET . getlist ( ' regioes ' ) ,
' estados ' : request . GET . getlist ( ' estados ' ) ,
' gerentes ' : request . GET . getlist ( ' gerente ' ) ,
}
def filtrar_casas ( seit , convenios , equipadas , regioes , estados , diagnosticos ,
gerentes ) :
''' Filtrar Casas que atendem aos parâmetros de pesquisa '''
qServico = Q ( servico__tipo_servico__sigla__in = seit )
qConvenio = Q ( convenio__projeto__sigla__in = convenios )
qEquipada = Q ( convenio__projeto__sigla__in = equipadas ,
convenio__equipada = True )
qRegiao = Q ( municipio__uf__regiao__in = regioes )
qEstado = Q ( municipio__uf__sigla__in = estados )
if gerentes :
qGerente = Q ( gerentes_interlegis__id__in = gerentes )
else :
qGerente = Q ( )
if diagnosticos :
qDiagnostico = Q ( diagnostico__publicado__in = [ p == ' P '
for p in diagnosticos ] )
else :
qDiagnostico = Q ( )
casas = Orgao . objects . filter ( qRegiao | qEstado ) . filter ( qGerente )
if seit or convenios or equipadas or diagnosticos :
casas = casas . filter ( qServico | qConvenio | qEquipada | qDiagnostico )
else :
casas = casas . filter ( Q ( servico = None ) & Q ( convenio = None ) &
Q ( diagnostico = None ) )
return casas
def gera_map_data_file ( cronjob = False ) :
''' Criar um arquivo json em {settings.MEDIA_ROOT} /apps/metas/ com o nome de map_data.json
Este arquivo será consumido pela view de dados de mapa .
Retorna os dados json caso cronjob seja falso .
Caso cronjob seja True , retorna log de tempo gasto na geração ou a mensagem do erro
que impediu a gravação do arquivo .
'''
start = time . time ( )
casas = { }
for c in Orgao . objects . prefetch_related ( ' servico_set ' , ' convenio_set ' , ' diagnostico_set ' ) . all ( ) . distinct ( ) :
# if c.servico_set.count() == 0 and c.convenio_set.count() == 0 and c.diagnostico_set.count() == 0:
# continue
# # Salta essa casa, pois ela não tem nada com o Interlegis
if c . pk not in casas :
summary = parliament_summary ( c )
summary [ ' info ' ] = " <br/> " . join ( summary [ ' info ' ] )
casas [ c . pk ] = summary
json_data = simplejson . dumps ( casas )
try :
file = open ( JSON_FILE_NAME , ' w ' )
file . write ( json_data )
file . close ( )
except Exception as e : # A gravação não foi bem sucedida ...
if cronjob : # ... o chamador deseja a mensagem de erro
return str ( e )
else :
pass # ... ou os dados poderão ser usados de qualquer forma
if cronjob :
return _ ( u " Arquivo %(filename)s gerado em %(seconds)d segundos " ) % dict (
filename = JSON_FILE_NAME ,
seconds = time . time ( ) - start )
return json_data
def parliament_summary ( parliament ) :
summary = {
' nome ' : parliament . nome + ' , ' + parliament . municipio . uf . sigla ,
' thumb ' : thumbnail_url ( parliament . foto , ' small ' ) ,
' foto ' : ( parliament . foto . url if parliament . foto else ' ' ) ,
' lat ' : str ( parliament . municipio . latitude ) ,
' lng ' : str ( parliament . municipio . longitude ) ,
' estado ' : parliament . municipio . uf . sigla ,
' regiao ' : parliament . municipio . uf . regiao ,
' gerentes ' : [ str ( g . id ) for g in parliament . gerentes_interlegis . all ( ) ] ,
' diagnosticos ' : [ ] ,
' seit ' : [ ] ,
' convenios ' : [ ] ,
' equipadas ' : [ ] ,
' info ' : [ ]
}
if parliament . gerentes_interlegis . exists ( ) :
summary [ ' info ' ] . append ( _ ( u " Gerentes Interlegis: {lista} " ) . format (
lista = parliament . lista_gerentes ( fmt = ' lista ' ) ) )
for sv in parliament . servico_set . filter ( data_desativacao = None ) :
summary [ ' info ' ] . append (
_ ( u " {name} ativado em {date} " ) . format (
name = sv . tipo_servico . nome ,
date = sv . data_ativacao . strftime ( ' %d / % m/ % Y ' ) if sv . data_ativacao
else _ ( u ' <sem data de ativação> ' ) ) +
( u " <a href= ' {0} ' target= ' _blank ' ><img src= ' {1} img/link.gif ' "
u " alt= ' link ' ></a> " ) . format ( sv . url , STATIC_URL ) )
summary [ ' seit ' ] . append ( sv . tipo_servico . sigla )
for cv in parliament . convenio_set . all ( ) :
if ( ( cv . data_retorno_assinatura is None ) and
( cv . equipada and cv . data_termo_aceite is not None ) ) :
summary [ ' info ' ] . append (
_ ( u " Equipada em {date} pelo {project} " ) . format (
date = cv . data_termo_aceite . strftime ( ' %d / % m/ % Y ' ) ,
project = cv . projeto . sigla ) )
summary [ ' equipadas ' ] . append ( cv . projeto . sigla )
elif cv . data_retorno_assinatura is None :
summary [ ' info ' ] . append (
_ ( u " Adesão ao projeto {project} , em {date} " ) . format (
project = cv . projeto . sigla , date = cv . data_adesao ) )
summary [ ' convenios ' ] . append ( cv . projeto . sigla )
if ( ( cv . data_retorno_assinatura is not None ) and not
( cv . equipada and cv . data_termo_aceite is not None ) ) :
summary [ ' info ' ] . append (
_ ( u " Conveniada ao %(project)s em %(date)s " ) . format (
project = cv . projeto . sigla ,
date = cv . data_retorno_assinatura . strftime ( ' %d / % m/ % Y ' ) ) )
summary [ ' convenios ' ] . append ( cv . projeto . sigla )
if ( ( cv . data_retorno_assinatura is not None ) and
( cv . equipada and cv . data_termo_aceite is not None ) ) :
summary [ ' info ' ] . append (
_ ( u " Conveniada ao {project} em {date} e equipada em "
u " {equipped_date} " ) . format (
project = cv . projeto . sigla ,
date = cv . data_retorno_assinatura . strftime ( ' %d / % m/ % Y ' ) ,
equipped_date = cv . data_termo_aceite . strftime ( ' %d / % m/ % Y ' ) ) )
summary [ ' equipadas ' ] . append ( cv . projeto . sigla )
summary [ ' convenios ' ] . append ( cv . projeto . sigla )
for dg in parliament . diagnostico_set . all ( ) :
summary [ ' diagnosticos ' ] . append ( ' P ' if dg . publicado else ' A ' )
summary [ ' info ' ] . append (
_ ( u " Diagnosticada no período de {initial_date} "
u " a {final_date} " ) . format (
initial_date = dg . data_visita_inicio . strftime ( ' %d / % m/ % Y ' )
if dg . data_visita_inicio is not None
else _ ( u " <sem data de início> " ) ,
final_date = dg . data_visita_fim . strftime ( ' %d / % m/ % Y ' )
if dg . data_visita_fim
else _ ( u " <sem data de término> " ) ) )
return summary
dados = Orgao . objects . filter (
tipo__legislativo = True ,
search_text__icontains = to_ascii ( q )
) [ : 10 ]
dados = dados . values ( " id " , " nome " , " municipio__latitude " ,
" municipio__longitude " )
dados = [ { ' id ' : d [ ' id ' ] ,
' label ' : d [ ' nome ' ] ,
' lat ' : d [ ' municipio__latitude ' ] ,
' lng ' : d [ ' municipio__longitude ' ] } for d in dados ]
return JsonResponse ( list ( dados ) , safe = False )