Arquivo da categoria: PlanetaSIG

Novo fornecedor de alojamento

Espero que este seja o meu último post sobre alojamento de sites por muitos e bons anos!

Concluí a transferência do domínio viasig.com (blog e planetasig) para um novo fornecedor.  Já relatei aqui a razão que me levou a mudar da Esoterica para outro fornecedor e não desejo voltar a ter problemas deste género…

Mas acabou por ser uma experiência positiva porque acabei por ficar melhor servido. Se não vejamos as condições do novo serviço:

Preço Anual 29,40€
Espaço em disco 1 GB
Tráfego Ilimitado
Domínios 1
Subdomínios Ilimitados
PHP 4 e 5
Python 2.4.3
Tomcat/JSP ok
Ruby ok
MySQL 5.0
PostgreSQL 8.1
Tarefas Agendadas Cron
Acesso Shell JailedShell

Por um preço muito semelhante consigo mais 3 características a que não tinha acesso e que fazem uma grande diferença:

  1. Tarefas agendadas para controlar facilmente o refrescamento das entradas no Planeta SIG;
  2. Acesso Shell para perceber os problemas com os scripts do Planeta SIG (Planet Venus);
  3. e ainda… PostgreSQL!!

Na verdade o meu novo fornecedor – Lefatech – não inclui o acesso à shell de raíz neste pack. Mas bastou-me solicitar, justificando a necessidade, e o acesso foi configurado na hora. Em contraste, quando pedi à Esoterica para criar uma tarefa agendada informaram-me que teria de fazer um upgrade para um plano que custa 108€/ano!

Com este novo alojamento ainda ganho o suporte a PostgreSQL o que poderá ser útil se surgir a oportunidade de criar algum site com mapas dinâmicos. Faltará o módulo PostGIS, mas também faltava o módulo mod_python ao Apache, e foi compilado e configurado pelo suporte técnico em poucos dias. Por isso pode ser que se consiga o PostGIS se for necessário!

A transferência para o novo servidor ficou activada hoje, sem que eu notasse qualquer anomalia. Aproveitei para actualizar o WordPress para a última versão (2.8.6). Se algum leitor notar algum problema por favor avise-me usando os comentários.

A propósito, o WP ganhou o prémio de melhor CMS Open Source de 2009!

Pequeno problema com feeds do Planeta SIG

Enquanto tentava resolver o problema de executar python para refrescar os artigos no Planeta SIG, parece que acabei por baralhar os feeds, entre o Planeta SIG e o meu próprio blog… penso ter tudo resolvido, e ficam aqui as minhas desculpas pelo lapso.

Em breve mudarei o domíno viasig.com para uma nova empresa de hosting para garantir que este tipo de problemas sejam mais fáceis de resolver!!

Resolvido o problema do Planeta SIG

O Planeta SIG deixou de ser actualizado por uns dias. Penso que agora a situação está normalizada. Por agora será actualizado 4h em 4h, e posteriormente pretendo voltar à actualização em intervalos de 1h.

Nunca me tinha defrontado com problemas no relacionamento com a empresa que me fornece o hosting, ou seja, o serviço onde alojo o Planeta SIG.

O serviço funcionou praticamente de forma automática durante quase 1 ano. E um destes dias o site desapareceu completamente… a Esoterica suspendeu o domínio. Ao consultar a minha conta de email pessoal lá estava um email enviado há 5 horas dizendo que havia um problema com o meu domínio, e que estava a comprometer a estabilidade do servidor, onde outros utilizadores teriam os seus sites.

Naturalmente que um só cliente não pode prejudicar tantos outros. E a suspensão não me parece assim tão mal dadas as circunstâncias. O que é lamentável é a forma como o processo de re-activar o Planeta SIG foi executado… levando a uma paragem de 1 semana. Sucedeu que decidiram bloquear algumas das funções necessárias à actualização do Planeta SIG, e por mais que tentasse foi-me impossível executar o script de actualização. O software que uso é o mais utilizado em todo o mundo, sendo a base de outros planetas como o Planet WordPress, o Planet Ubuntu, ou o “nosso” Planet Geospatial. Portanto, não será propriamente software malicioso…

Neste momento, consigo já executar o script. E espero que a situação se mantenha assim.

Qual foi o problema?

O que aconteceu foi um bug no processo de actualização do site. Como não tenho acesso às capacidades de agendamento de tarefas do servidor, usei um serviço que de 1  em 1 h chamava o script de actualização.

Tudo corria muito bem. Mas a dada altura, algo mudou no servidor, e o script começou a devolver erros de timeout. O erro de timeout não impedia que o script concluísse as tarefas de actualização e por isso no Planeta SIG tudo parecia normal. O problema foi que ao receber o erro de timeout, o tal serviço que devia executar o script 1h/1h passou a fazê-lo a cada minuto! Ou seja, o servidor foi inundado de pedidos para executar o meu script de actualização! Oops.

Bom, a solução foi resolver este bug. E a partir daqui ignorar os erros de timeout. E garantir que só se executa o script de actualização no intervalo estabelecido de 1h.

Só que nesta altura a Esoterica começou a dificultar as coisas, apertando as restrições de segurança ao ponto de não conseguir executar o script de actualização. E isto arrastou-se por 1 semana.

Decisões, decisões

O poder negocial dos clientes é realmente muito pequeno frente às empresas que fornecem o alojamento de sites, e a facilidade com que estas podem abusar da sua posição é preocupante, mesmo que nem se apercebam que a atitude que estão a tomar pode ser violenta para o cliente e destruir um projecto.

A hipótese de mudar de fornecedor de alojamento foi a primeira ideia que me ocorreu e tenho já seleccionadas as alternativas que me pareceram melhores. Mas… há sempre a probabilidade do problema voltar a acontecer.

A hipótese de passar a usar um PC em casa como servidor web é por isso muito atractiva, pela independência que oferece. Alguém sabe quanto custará, em electricidade, manter um PC ligado o ano inteiro? E o custo de ter um endereço IP fixo?

Para o custo de electricidade encontrei referências a preços de 2008:

Um PC que consome 200w em tarifa bi-horária, 30 dias por mês, 12 meses por ano, pagou em 2008 13,35€ por mês, num total anual de 160€.

A somar ainda o custo de ter um IP fixo (que não qual é)…

Comparando com o custo de 20€/ano para ter um serviço de hospedagem, a opção caseira é um tudo-nada mais caro.

Conclusão e Futuro

Em resultado destas dificuldades, e por ter a sempre incerteza sobre se o serviço de actualização não voltará a provocar um problema destes, comecei a desenvolver um PlanetaSIG em PHP, baseado na excelente biblioteca SimplePie. Mas o tempo é curto e não sei quando terminarei. A outra coisa a fazer é encontrar um serviço de hospedagem que permita a utilização de tarefas agendadas a um preço baixo. Se alguém souber de um, estou muitíssimo interessado!

Até breve.

PlanetaSIG com extractos de posts com 500 caracteres

A pedido de um dos autores, a partir de hoje, o PlanetaSIG tem a capacidade de mostrar apenas os primeiros N caracteres de cada post. A configuração proposta é mostrar 500 caracteres, permitindo aos leitores do agregador decidir se lhe interessa visitar o blog original para ler o post completo.

O agregador tem funcionado inspirado no PlanetGS e como tal mostra numa única página os posts de forma integral, dos blogs que agrega.

Pessoalmente, leio o PlanetaSIG bem como outros planetas e blogs com o Google Desktop, usando a sidebar onde vejo os títulos dos itens a serem refrescados. Ao clicar num item, é aberto directamente o blog original, sem passar pelo PlanetaSIG (ou outro agregador).

Acontece que o PlanetaSIG pode ser consultado directamente, visitando a página. E nesse caso é bem possível que esse visitante já não irá visitar os blogs originais, reduzindo o tráfego desses blogs. E compreendo perfeitamente os autores que querem evitar esta situação (e mesmo que não concordasse agiria da mesma forma – o autor é soberano).

Com esta nova possibilidade espero resolver a questão de forma simpática para todos.

Portanto, quem tem o seu blog agregado no PlanetaSIG e que assim deseje pode enviar-me um email e eu configurarei o seu feed para mostrar apenas um extracto dos posts. O modo default para quem não se manifestar continuará a ser mostrar os posts integrais, mantendo um pouco a mesma lógica dos planetas mais globais como o PlanetGS e o PlanetOSGeo.

Aproveito para pedir sugestões para blogs que possam ser incluídos no PlanetaSIG!!

Detalhes técnicos

O PlanetaSIG é gerado pelo software Venus, escrito em Python. O Venus não permite de raíz configurar o n.º de caracteres a mostrar em cada post, nem permite usar o sumário ou excerpto incluído nos feeds, em vez de mostrar o conteúdo. Já antes tinha tentado configurar o Venus para fazer esse efeito mas sem sucesso.

Mas o Venus tem a capacidade de aplicar filtros a cada feed RSS, e de forma independente. Ou seja, podemos aplicar um filtro a um feed, e outro filtro diferente noutro feed, e até ter outros feeds sem filtro algum.

Um filtro é um pequeno script escrito em Python (também pode ser um xslt), que vai ser executado para cada item dentro de um feed, podendo transformá-lo da maneira como o programador quiser. Por exemplo, podem retirar-se todas as referências a imagens, ou substituir tags <h1> por <h3> ou outro qualquer, aplicar classes css a determinados tags, etc.

O que acabei por fazer foi criar um filtro que pega no <content> de cada post e o substitui por apenas os primeiros N caracteres do original. Este filtro pode ainda substituir o <content> por outro tag qualquer – por exemplo, copiar o sumário para o content. Como o Venus só consegue mostrar o <content>, passa a mostrar o sumário sem saber…

O código do novo filtro foi baseado num filtro que vem já incluído no Venus – excerpt.py. Fica aqui o código para referência futura.

Até breve.

Cria um novo elemento ou substitui um existente,
com o texto de outro elemento, truncado com X caracteres.
Baseado no filtro excerpt.py e alterado por Duarte Carreira em 16/Julho/2009.

Parameters:
  width:  maximum number of characters in the excerpt.  Default: 500
  omit:   whitespace delimited list of html tags to remove.  Default: none
  target: name of element created.  Default: content
  source: name of element to get data from. Default: summary
  replace: yes to delete duplicate target. Default: yes

Example to test:
python tests/reconstitute.py http://localhost/feedorig.xml
--filters "planetaSIG.py?width=500&source=content&target=content&replace=yes">tes
te3.xml

Notes:
* if you want to avoid duplicate entries use replace=yes.
* Venus does not expose summary in the feeds to tmpl templates. With this filter,
   you cant replace the text inside content with the text from summary. This is
   what the default values do.
* if 'img' is in the list of tags to be omitted <img> tags are replaced with
   hypertext links associated with the value of the 'alt' attribute.  If there
   is no alt attribute value, <img> is used instead.  If the parent element
   of the img tag is already an <a> tag, no additional hypertext links are
   added.
"""

import sys, xml.dom.minidom, textwrap
from xml.dom import Node, minidom

atomNS = 'http://www.w3.org/2005/Atom'
planetNS = 'http://planet.intertwingly.net/'

args = dict(zip([name.lstrip('-') for name in sys.argv[1::2]], sys.argv[2::2]))

wrapper = textwrap.TextWrapper(width=int(args.get('width','500')))
omit = args.get('omit', '').split()
target = args.get('target', 'content')
original = args.get('source', 'summary')
replace = args.get('replace','yes')

class copy:
    """ recursively copy a source to a target, up to a given width """

    def __init__(self, dom, source, target):
        self.dom = dom
        self.full = False
        self.text = []
        self.textlen = 0
        self.copyChildren(source, target)

    def copyChildren(self, source, target):
        """ copy child nodes of a source to the target """
        for child in source.childNodes:
            if child.nodeType == Node.ELEMENT_NODE:
                 self.copyElement(child, target)
            elif child.nodeType == Node.TEXT_NODE:
                 self.copyText(child.data, target)
            if self.full: break

    def copyElement(self, source, target):
        """ copy source element to the target """

        # check the omit list
        if source.nodeName in omit:
            if source.nodeName == 'img':
               return self.elideImage(source, target)
            return self.copyChildren(source, target)

        # copy element, attributes, and children
        child = self.dom.createElementNS(source.namespaceURI, source.nodeName)
        target.appendChild(child)
        for i in range(0, source.attributes.length):
            attr = source.attributes.item(i)
            child.setAttributeNS(attr.namespaceURI, attr.name, attr.value)
        self.copyChildren(source, child)

    def elideImage(self, source, target):
        """ copy an elided form of the image element to the target """
        alt = source.getAttribute('alt') or '<img>'
        src = source.getAttribute('src')

        if target.nodeName == 'a' or not src:
            self.copyText(alt, target)
        else:
            child = self.dom.createElement('a')
            child.setAttribute('href', src)
            self.copyText(alt, child)
            target.appendChild(child)

    def copyText(self, source, target):
        """ copy text to the target, until the point where it would wrap """
        if not source.isspace() and source.strip():
            self.text.append(source.strip())
        lines = wrapper.wrap(' '.join(self.text))
        if len(lines) == 1:
            target.appendChild(self.dom.createTextNode(source))
            self.textlen = len(lines[0])
        elif lines:
            excerpt = source[:len(lines[0])-self.textlen] + u' \u2026'
            target.appendChild(dom.createTextNode(excerpt))
            self.full = True

# select summary or content element
dom = minidom.parse(sys.stdin)

#source = dom.getElementsByTagNameNS(atomNS, 'summary')
#if not source:
#    source = dom.getElementsByTagNameNS(atomNS, 'content')
source = dom.getElementsByTagNameNS(atomNS, original)

# if present, recursively copy it to a planet:excerpt element
if source:
    fonteelem = source[0]
    if target.startswith('planet:'):
        dom.documentElement.setAttribute('xmlns:planet', planetNS)
    if target.startswith('atom:'): target = target.split(':',1)[1]
    excerpt = dom.createElementNS(planetNS, target)
    source[0].parentNode.appendChild(excerpt)
    copy(dom, source[0], excerpt)
    #source[0].parentNode.replaceChild(excerpt, source[0])
    #if source[0].nodeName == excerpt.nodeName:
    #  source[0].parentNode.removeChild(source[0])

#apagar o original
if replace == 'yes':
    source = dom.getElementsByTagName(target)
    fonteelem = source[0]
    if len(source)>1:
        source[0].parentNode.removeChild(source[0])

# print out results
print dom.toxml('utf-8')