diff --git a/etc/cron/atualiza_data_uso.py b/etc/cron/atualiza_data_uso.py
new file mode 100644
index 0000000..4663a0a
--- /dev/null
+++ b/etc/cron/atualiza_data_uso.py
@@ -0,0 +1,30 @@
+# -*- coding: utf-8 -*-
+# Atualiza a data de último uso dos serviços SEIT realizados pelas Casas Legislativas
+# Colocar no CRON - basta executar uma vez por dia
+#
+
+import sys
+from django.core.management import setup_environ
+
+# Produção
+sys.path.insert(0, '/var/interlegis/sigi')
+sys.path.insert(0, '/var/interlegis/sigi/sigi')
+
+# Dev
+import os
+BASE_DIR = os.path.abspath(os.path.dirname(__file__) + '../..')
+PROJECT_DIR = BASE_DIR + '/sigi'
+print BASE_DIR, PROJECT_DIR
+sys.path.insert(0, BASE_DIR)
+sys.path.insert(0, PROJECT_DIR)
+
+# Faça!
+from sigi import settings
+setup_environ(settings)
+
+from sigi.apps.servicos.models import Servico
+
+queryset = Servico.objects.exclude(url="").exclude(tipo_servico__string_pesquisa="")
+for obj in queryset:
+ obj.atualiza_data_uso()
+ print obj.url, obj.data_ultimo_uso, obj.erro_atualizacao
\ No newline at end of file
diff --git a/sigi/apps/casas/models.py b/sigi/apps/casas/models.py
index 13f658b..71ef475 100644
--- a/sigi/apps/casas/models.py
+++ b/sigi/apps/casas/models.py
@@ -6,7 +6,7 @@ from sigi.apps.utils import SearchField
from datetime import datetime
import random
from unicodedata import normalize
-from apps.contatos.models import Municipio
+from sigi.apps.contatos.models import Municipio
class TipoCasaLegislativa(models.Model):
""" Modelo para representar o tipo da Casa Legislativa
diff --git a/sigi/apps/servicos/admin.py b/sigi/apps/servicos/admin.py
index 8bb32f6..d890558 100644
--- a/sigi/apps/servicos/admin.py
+++ b/sigi/apps/servicos/admin.py
@@ -48,7 +48,9 @@ class TipoServicoAdmin(admin.ModelAdmin):
class ServicoAdmin(admin.ModelAdmin):
form = ServicoFormAdmin
- list_display = ('casa_legislativa','getUf', 'tipo_servico', 'hospedagem_interlegis', 'data_ativacao', 'data_desativacao', 'getUrl')
+ actions = ['calcular_data_uso',]
+ list_display = ('casa_legislativa','getUf', 'tipo_servico', 'hospedagem_interlegis', 'data_ativacao', 'data_desativacao',
+ 'getUrl', 'data_ultimo_uso', 'erro_atualizacao')
fieldsets = (( None, {
'fields': ('casa_legislativa', 'data_ativacao',)
}),
@@ -62,10 +64,9 @@ class ServicoAdmin(admin.ModelAdmin):
'fields': ('data_alteracao', 'data_desativacao', 'motivo_desativacao',)
}))
readonly_fields = ('casa_legislativa', 'data_ativacao', 'data_alteracao')
- list_filter = ('tipo_servico', 'hospedagem_interlegis', 'casa_legislativa')
+ list_filter = ('tipo_servico', 'hospedagem_interlegis', 'data_ultimo_uso', 'casa_legislativa', )
list_display_links = []
ordering = ('casa_legislativa__municipio__uf', 'casa_legislativa', 'tipo_servico',)
- actions = None
inlines = (LogServicoInline,)
def getUf(self, obj):
@@ -77,8 +78,22 @@ class ServicoAdmin(admin.ModelAdmin):
return u'%s' % (obj.url, obj.url)
getUrl.short_description = 'Url'
getUrl.allow_tags = True
-
+ def calcular_data_uso(self, request, queryset):
+ for servico in queryset:
+ servico.atualiza_data_uso()
+ self.message_user(request, "Atualização concluída. Os sites que não responderam foram deixados com a data em branco" )
+ return HttpResponseRedirect('.')
+ calcular_data_uso.short_description = u"Atualizar a data do último uso do(s) serviço(s)"
+
+ def get_actions(self, request):
+ from django.utils.datastructures import SortedDict
+ actions = [self.get_action(action) for action in self.actions]
+ actions = filter(None, actions)
+ actions.sort(lambda a,b: cmp(a[2].lower(), b[2].lower()))
+ actions = SortedDict([ (name, (func, name, desc)) for func, name, desc in actions ])
+ return actions
+
def lookup_allowed(self, lookup, value):
return super(ServicoAdmin, self).lookup_allowed(lookup, value) or \
lookup in ['casa_legislativa__municipio__uf__codigo_ibge__exact']
diff --git a/sigi/apps/servicos/models.py b/sigi/apps/servicos/models.py
index a4d7ba0..83c4718 100644
--- a/sigi/apps/servicos/models.py
+++ b/sigi/apps/servicos/models.py
@@ -6,14 +6,16 @@ from django.core.mail import send_mail
from sigi.settings import DEFAULT_FROM_EMAIL
class TipoServico(models.Model):
- email_help = '''Use:
+ email_help = u'''Use:
{url} para incluir a URL do serviço,
{senha} para incluir a senha inicial do serviço'''
- nome = models.CharField('Nome', max_length=60)
- sigla = models.CharField('Sigla', max_length='12')
- template_email_ativa = models.TextField('Template de email de ativação', help_text = email_help, blank=True)
- template_email_altera = models.TextField('Template de email de alteração', help_text = email_help, blank=True)
- template_email_desativa = models.TextField('Template de email de desativação', help_text = email_help + '
{motivo} para incluir o motivo da desativação do serviço', blank=True)
+ nome = models.CharField(u'Nome', max_length=60)
+ sigla = models.CharField(u'Sigla', max_length='12')
+ string_pesquisa = models.CharField(u'String de pesquisa', blank=True, max_length=200,
+ help_text=u'Sufixo para pesquisa RSS para averiguar a data da última atualização do serviço')
+ template_email_ativa = models.TextField(u'Template de email de ativação', help_text = email_help, blank=True)
+ template_email_altera = models.TextField(u'Template de email de alteração', help_text = email_help, blank=True)
+ template_email_desativa = models.TextField(u'Template de email de desativação', help_text = email_help + u'
{motivo} para incluir o motivo da desativação do serviço', blank=True)
@property
def qtde_casas_atendidas(self):
@@ -21,29 +23,81 @@ class TipoServico(models.Model):
return self.servico_set.filter(data_desativacao=None).count()
class Meta:
- verbose_name = 'Tipo de serviço'
- verbose_name_plural = 'Tipos de serviço'
+ verbose_name = u'Tipo de serviço'
+ verbose_name_plural = u'Tipos de serviço'
def __unicode__(self):
return self.nome;
class Servico(models.Model):
- casa_legislativa = models.ForeignKey(CasaLegislativa, verbose_name='Casa legislativa')
- tipo_servico = models.ForeignKey(TipoServico, verbose_name='Tipo de serviço')
- contato_tecnico = models.ForeignKey(Funcionario, verbose_name='Contato técnico', related_name='contato_tecnico')
- contato_administrativo = models.ForeignKey(Funcionario, verbose_name='Contato administrativo', related_name='contato_administrativo')
- url = models.URLField('URL do serviço', verify_exists=False, blank=True)
- hospedagem_interlegis = models.BooleanField('Hospedagem no Interlegis?')
- nome_servidor = models.CharField('Hospedado em', max_length=60, blank=True, help_text='Se hospedado no Interlegis, informe o nome do servidor.
Senão, informe o nome do provedor de serviços.')
- porta_servico = models.PositiveSmallIntegerField('Porta de serviço (instância)', blank=True, null=True)
- senha_inicial = models.CharField('Senha inicial', max_length=33, blank=True)
- data_ativacao = models.DateField('Data de ativação', default=date.today)
- data_alteracao = models.DateField('Data da última alteração', blank=True, null=True, auto_now=True)
- data_desativacao = models.DateField('Data de desativação', blank=True, null=True)
- motivo_desativacao = models.TextField('Motivo da desativação', blank=True)
+ casa_legislativa = models.ForeignKey(CasaLegislativa, verbose_name=u'Casa legislativa')
+ tipo_servico = models.ForeignKey(TipoServico, verbose_name=u'Tipo de serviço')
+ contato_tecnico = models.ForeignKey(Funcionario, verbose_name=u'Contato técnico', related_name='contato_tecnico')
+ contato_administrativo = models.ForeignKey(Funcionario, verbose_name=u'Contato administrativo', related_name='contato_administrativo')
+ url = models.URLField(u'URL do serviço', verify_exists=False, blank=True)
+ hospedagem_interlegis = models.BooleanField(u'Hospedagem no Interlegis?')
+ nome_servidor = models.CharField(u'Hospedado em', max_length=60, blank=True,
+ help_text=u'Se hospedado no Interlegis, informe o nome do servidor.
Senão, informe o nome do provedor de serviços.')
+ porta_servico = models.PositiveSmallIntegerField(u'Porta de serviço (instância)', blank=True, null=True)
+ senha_inicial = models.CharField(u'Senha inicial', max_length=33, blank=True)
+ data_ativacao = models.DateField(u'Data de ativação', default=date.today)
+ data_alteracao = models.DateField(u'Data da última alteração', blank=True, null=True, auto_now=True)
+ data_desativacao = models.DateField(u'Data de desativação', blank=True, null=True)
+ motivo_desativacao = models.TextField(u'Motivo da desativação', blank=True)
+ data_ultimo_uso = models.DateField(u'Data da última utilização', blank=True, null=True,
+ help_text=u'Data em que o serviço foi utilizado pela Casa Legislativa pela última vez
NÃO É ATUALIZADO AUTOMATICAMENTE!')
+ erro_atualizacao = models.CharField(u"Erro na atualização", blank=True, max_length=200,
+ help_text=u"Erro ocorrido na última tentativa de atualizar a data de último acesso")
casa_legislativa.casa_uf_filter = True
+ def atualiza_data_uso(self):
+ def reset(erro=u""):
+ if self.data_ultimo_uso is None and not erro:
+ return
+ self.data_ultimo_uso = None
+ self.erro_atualizacao = erro
+ self.save()
+ return
+
+ if self.tipo_servico.string_pesquisa == "":
+ reset()
+ return
+
+ url = self.url
+
+ if not url:
+ reset()
+ return
+
+ if url[-1] != '/':
+ url += '/'
+ url += self.tipo_servico.string_pesquisa
+
+ import urllib2
+ from xml.dom.minidom import parseString
+
+ try:
+ try: # Tentar conxão sem proxy
+ req = urllib2.urlopen(url=url, timeout=5)
+ except: # Tentar com proxy
+ proxy = urllib2.ProxyHandler()
+ opener = urllib2.build_opener(proxy)
+ req = opener.open(fullurl=url, timeout=5)
+
+ rss = req.read()
+ xml = parseString(rss)
+ items = xml.getElementsByTagName('item')
+ first_item = items[0]
+ date_list = first_item.getElementsByTagName('dc:date')
+ date_item = date_list[0]
+ date_text = date_item.firstChild.nodeValue
+ self.data_ultimo_uso = date_text[:10] # Apenas YYYY-MM-DD
+ self.erro_atualizacao = ""
+ self.save()
+ except Exception as e:
+ reset(erro=e.message)
+
def __unicode__(self):
return "%s (%s)" % (self.tipo_servico.nome, 'ativo' if self.data_desativacao is None else 'Desativado')