Arquivo mensais:outubro 2005

Mudança de Servidor

ATENÇÃO: Este conteúdo foi publicado há 12 anos. Eu talvez nem concorde mais com ele. Se é um post sobre tecnologia, talvez não faça mais sentido. Mantenho neste blog o que escrevo desde os 14 anos por motivos históricos. Leia levando isso em conta.

Eu já conhecia a Dreamhost há algum tempo. Já cliquei algumas vezes no link da página do Bruno Torres, que me levava pra esse servidor “louco” que dá quase 5gb de espaço, 120gb de banda e o preço é igual o da GlobalHosts (aquela que eu usava até mês passado), mas depois de me confrontar com a taxa de setup (US$ 50!) tinha resolvido que não precisava de tudo isso (pô, o servidor tem o dobro de espaço em disco que a Nerdhost tinha de banda) e não valia a pena.

Mas acontece que hoje, procurando por servidores de hospedagem com SSH, encontro um post de semana passada do Danilo Medeiros, no DigitalMinds com justamente o que eu sonhava: DreamHost sem taxa de setup. O negócio é bom pra ele e pra mim: Ele ganha US$ 47,00 por eu ter me cadastrado pelo site dele e eu ganho os outros US$ 50,00 (na Dreamhost, quando alguém se cadastra, o cara que sugeriu o site a ele ganha US$ 97,00!). Mas pra mim é melhor, porque finalmente eu tenho um servidor confiável (conheço vários usuários felizes), barato e tem bem mais recursos até do que eu precisava.

Nessa semana aconteceram muitas coisas… Vou começar falando do Ubuntu. A distribuição, com fama de simples, impressionou até a minha mãe!

Pra mim, ele não é nada demais. Não acho mais simples do que Kurumin (que também é baseado em Debian, é em português e tem um monte de ícones mágicos pra facilitar ainda mais a vida) ou do que o Debian BR-CDD (esse segundo tem até o design da instalação e usa o Gnome, exatamente igual a ele, e é em português!). Acho que só pode ser por causa do seu significado “humanity to others” ou por ser bonitinho e a gente poder pedir gratuitamente CDs pelo site. Mas independente dessa questão, o que importa é que tá todo mundo gostando do Ubuntu.

Meu irmão menor, de 11 anos, instalou o sistema quase sozinho no desktop de casa. O único problema que ele teve foi o de configuração de rede (ele não sabia que IP colocar) e o particionamento, em que eu tive que dar uma pequena ajuda, mas acho que na próxima ele já vai conseguir fazer sozinho.

Além disso, levei uns cds pro Colégio e estamos com projeto de instalar em seis computadores: os três da biblioteca (uso apenas da internet por alunos) e os três da sala dos professores (uso apenas do Word). A reação da maioria das pessoas (já instalamos em dois computadores) foi muito legal. Só que anotei algumas dificuldades pra talvez até modificar em futuras versões do Ubuntu ou pra caso alguém quiser criar uma distribuição fácil se lembrar… Hehehe… :)

  • Configuração da Rede – Meu irmão não soube o que colocar no IP para se conectar a nossa rede local… Acho que faltou naquela tela uma pergunta “Você quer configurar a rede agora?”
  • Particionamento do Disco – Isso sempre é difícil para os usuários leigos. Não sei como podia ser mais simples, mas sei que a maioria das pessoas desiste de instalar nessa parte…
  • Configuração do Fuso Horário – Esse era um problema que eu realmente não esperava. Porém, até professores do Colégio tiveram dificuldade com a escolha de fuso horário… Acho que deve ficar mais claro na instalação, como fica na maioria dos formulários na internet. GMT -2 : São Paulo, Brasília, etc. ao invés de Leste, Oeste, outro.
  • Menu do Gnome – As três pessoas que tiveram o primeiro contato com sua nova máquina com Ubuntu clicaram no ícone de “Mostrar área de trabalho”. Não seria mais sensato para o Gnome colocar o menu de aplicações embaixo para quem está vindo do sistema corporativo da Microsoft se acostumar de forma mais leve?
  • NumLock – Todo mundo tá acostumado com o NumLock ligado por padrão.
  • Pacotes pt-BR – O Ubuntu pergunta na instalação se queremos baixar os pacotes. Porém, considerando que eu uso ADSL PPPoE e não pude configurar minha internet durante a instalação, como faço pra instalar os pacotes brasileiros depois? Deveria ter um ícone pra isso no menu depois…
  • Conectar ADSL – Pô… A instalação tudo bem, mas depois eu ter que entrar no console e digitar pppoeconf pra configurar o ADSL (porque obviamente já usei outros Linuxes e conhecia o rp-pppoe) é difícil, né? Que tipo de usuário leigo consegue conectar-se ao seu serviço PPPoE num Ubuntu?

Alguns dos problemas acima são específicos do Ubuntu; outros dos GNU/Linux em geral. Algumas coisas são questão de preferência, mas será que não seria importante deixar o GNU/Linux mais fácil até nesses pontos (bem específicos) para os usuários acostumados com o Windows?

Por essa e por outras, disse acima que preferia o Kurumin, mas de qualquer maneira, o Ubuntu tá muito legal e o povo tá começando a usar aqui… O software livre, até pra fins educativos, é muito legal. Agora estou baixando o Edubuntu pra ver se não dá pra instalar nos computadores do Laboratório de Informática do Colégio… :D

Outro fato dessa semana foi o final do JEI2005. Salesiano campeão-geral novamente, com a ajuda do voleibol juvenil masculino… :D

E para finalizar, talvez o mais importante dos fatos: a mudança do sistema de blog do meu site. Estou agora utilizando o WordPress. É meio estranho alguém que estava fazendo um sistema de blogs semana retrasada passar a usar um outro sistema, né? Mas é que eu desisti de fazer o Semantic Blog, porque o projeto tava meio parado (o Gustavo e o Hélio são muito ocupados) e recebi finalmente meu invite no WordPress.com, onde testei o sistema e gostei bastante. Um recurso legal é que tem vários plugins. Estou para instalar o plugin do GeSHi e já instalei o plugin do LaTeX Render. Realmente recomendo… :)

[update] Agora instalei também o plugin do GeSHi! [/update]

Compras e Blog

ATENÇÃO: Este conteúdo foi publicado há 12 anos. Eu talvez nem concorde mais com ele. Se é um post sobre tecnologia, talvez não faça mais sentido. Mantenho neste blog o que escrevo desde os 14 anos por motivos históricos. Leia levando isso em conta.

Hoje, no Linuxmall, comprei um pequeno livro chamado Invasão de Redes: Ataques e Defesas e foi escrito por Tiago José Pereira Nogueira. Nunca vi nada desse cara, ninguém me recomendou esse livro e não conheço ninguém que já tenha lido ou comentado alguma coisa sobre ele. É um livro que parece ser novo e me deu vontade de comprar porque sempre quis saber trabalhar com redes no C. Ele aborda tópicos interessantes, como sockets e conexões, port scanners, DDoS, entre outras coisas. Só tô explicando pra vocês não pensarem que eu comprei porque decidi virar um cracker maligno invasor de redes… :lol: Aproveitei o frete pra comprar também um novo adesivo pro laptop, um Tux grande (de 11x13cm – eu medi antes pra ver se ficava legal no laptop) que custou R$ 2,00. A compra deve chegar quinta-feira. A propósito, alguém já ouviu falar de E-Sedex? Parece ser legal… Barato e rápido! Pedi essa compra com ele pra testar. Faz tanto tempo que não compro na internet que eu fico por fora dessas novidades!

Vou aproveitar o post pra postar os códigos que eu estou fazendo pra interpretação de BBCodes e estatísticas do blog que eu, o Hélio e o Gustavo começamos a desenvolver semana passada e queremos acabar até no máximo o final de novembro (pretendemos acabar perto do dia 15/11).

Expressões Regulares

< ?php
/* A parte de regex de códigos precisa do GeSHi Highlighter. Includando-o... */
include("geshi.php");
 
/* Essa classe serve para ser usada com "extends", ela sozinha "não é nada". */
class Regex {
 
    /* Função que interpreta emoticons */
    function Emoticons() {
        $origem=Array(":)", ":(", ":D", ":P", ":O", ":S", ":lol:", ":blink:");
        $destino=Array("feliz.gif", "triste.gif", "sorriso.gif", "lingua.gif", "espantado.gif", "confuso.gif", "riso.gif", "confuso.gif");
        // EM DESENVOLVIMENTO!
    }
 
    /* Função que interpreta BBCodes...
     * Totalmente desenvolvida por mim. (nem parece de tão linda, né?) */
    function InterpretaBBCodes() {
        /* Vamos começar pelos [codes], porque só o que tá fora deles deve ser
           interpretado depois. */
 
        preg_match_all("/[code language=([a-z]+)](.*)[/code]/sU", $this->texto, $matches_com_linguagens);
        preg_match_all("/[code](.*)[/code]/sU", $this->texto, $matches_sem_linguagens);
 
        /* - A parte dos códigos é $matches_com_linguagens[$i][2] e $matches_sem_linguages[$i][1].
               - A parte que diz em que linguagem os códigos $matches_com_linguagens[$i][2] foi escrita
              é $matches_com_linguagens[$i][1].
           - Para facilitar os códigos abaixo, vou trocar matches_com_linguagens para mcl e
           matches_sem_linguagens para msl. Só não fiz em cima pra quem tá de fora entender o que
           eu tô fazendo nessa parte do código. ;)
        */
 
        $mcl=$matches_com_linguagens;
        $msl=$matches_sem_linguagens;
 
        $con=0;
        for ($i=0; $i<sizeof ($mcl[0]); $i++) {
            $g=new GeSHi($mcl[2][$i], $mcl[1][$i], "./geshi/");
            $geshi_mcl[$i]=$g->parse_code();
            $mcl_md5[$i]=md5(time()*$con++);
            $this->texto=str_replace($mcl[0][$i], $mcl_md5[$i], $this->texto);
        }
        for ($i=0; $i</sizeof><sizeof ($msl[0]); $i++) {
            /* Aqui, vocês vão perguntar: "Por que passar no GeSHi, se não sei highlightear essa linguagem?
               A resposta é que o GeSHi não só highlighta, mas formata o código de forma que ele fique
               legível (por exemplo, troca < por &lt. */
            $g=new GeSHi($msl[1][$i], "", "./geshi/");
            $geshi_msl[$i]=$g->parse_code();
            $msl_md5[$i]=md5(time()*$con++);
            $this->texto=str_replace($msl[0][$i], $msl_md5[$i], $this->texto);
        }
 
        /* Beleza, agora precisamos sempre lembrar de não highlightear o que estiver entre <pre>.
           E também não podemos deixar nada fora dos padrões XHTML Strict. */
 
        $this->texto=str_replace("&", "&amp;", $this->texto);
        $this->texto=str_replace("< ", "&lt;", $this->texto);
        $this->texto=str_replace(">", "&gt;", $this->texto);
        $this->texto=str_replace(""", "&quot;", $this->texto);
 
        // Aqui tá o meu "nl2br" semântico! =)
        $this->texto="<p>".$this->texto."</p>";
        $this->texto=preg_replace("/nnn*/", "<p>", $this->texto);
            /* </p><p></p> vazios não são semânticos. Mas estive pensando depois de fazer isso e acho que
                algumas pessoas podem querer dar um grande espaço entre os <p>, por isso estou
                pensando em fazer uma ER que a cada n a mais de dois n's adicione 10px ao
                margin-bottom do último </p><p>. O que vocês acham? */
        $this->texto=preg_replace("/n/", "<br />n", $this->texto);
        $this->texto=preg_replace("/< /p></p><p>/", "</p>n<p>", $this->texto);
 
        // Formatação básica (negrito, itálico, sublinhado, cores, cabeçalhos)
           $this->texto=preg_replace("/[b](.*)[/b]/sU", "<strong>\1</strong>", $this->texto);
        $this->texto=preg_replace("/[i](.*)[/i]/sU", "<em>\1</em>", $this->texto);
        $this->texto=preg_replace("/[u](.*)[/u]/sU", "<span style="text-decoration:underline;">\1</span>", $this->texto);
        $this->texto=preg_replace("/[color=([^]]+)](.*)[/color]/sU", "<span style="color:\1;">\2</span>", $this->texto);
        $this->texto=preg_replace("/[h([1-6])](.*)[/h\1]/sU", "<h \1>\2< /h\1>n", $this->texto);
 
        // Citações
        $this->texto=preg_replace("/[quote](.*)[/quote]/sU", "<q>\1</q>n", $this->texto);
        $this->texto=preg_replace("/[quote=([^]]+)](.*)[/quote]/sU", "<q>\2</q>n<cite>\1</cite>", $this->texto);
 
        // URLs
        $this->texto=preg_replace("/([^"/=]])(www.[^[:blank:]"< ]+)/", "\1<a href="http://\2">\2", $this->texto);
        $this->texto=preg_replace("/([^"=]])(http://[^[:blank:]"< ]+)/", "\1<a href="\2">\2", $this->texto);
 
        $this->texto=preg_replace("/[url]([^"]*)[/url]/sU", "<a href="\1">\1</a>", $this->texto);
        $this->texto=preg_replace("/[url=([^[:blank:]"]+)[[:blank:]]+title=([^]"]+)](.*)[/url]/sU", "<a href="\1" title="\2">\3</a>", $this->texto);
        $this->texto=preg_replace("/[url=([^]"]+)](.*)[/url]/sU", "<a href="\1">\2</a>", $this->texto);
 
 
        preg_match_all("/<a href="([^"]+)">/U", $this->texto, $matches);
 
        for ($i=0; $i<count ($matches[0]); $i++) {
            $parse=parse_url($matches[1][$i]);
            $dominio=$parse["host"];
            $this->texto=str_replace($matches[0][$i], "<a href="".$matches[1][$i]."" title="Link Externo: $dominio">", $this->texto);
        }
 
        // Imagens    
        $this->texto=preg_replace("/[img=([^]]+)]([^"]*)[/img]/U", "<img src="\2" alt="\1" />", $this->texto);
        $this->texto=preg_replace("/[img]([^"]*)[/img]/U", "<img src="\1" alt="Imagem: \2" />", $this->texto);
 
        // Listas
        $this->texto=preg_replace("/[list](.*)[/list]/sU", "<ul>\1</ul>", $this->texto);
        $this->texto=preg_replace("/[li](.*)[/li]/sU", "<li><p>\1</p></li>", $this->texto);
 
        // Limpando besteiras... Alguém tem alguma idéia melhor do que esse FOR feio?
        for ($count=0; $count&lt;10; $count++) {
            $this->texto=preg_replace("/<br />< /li>/", "", $this->texto);
            $this->texto=preg_replace("/<ul><br />/", "</ul><ul>", $this->texto);
            $this->texto=preg_replace("/< (/?)li><br />/", "< \1li>",  $this->texto);
            $this->texto=preg_replace("/<q><br />/", "</q><q>", $this->texto);
            $this->texto=preg_replace("/< /q><br />/", "</q>", $this->texto);
        }
 
        // Emoticons
        // $this->Emoticons();
 
        /* Lembram que o código tinha sido transformado em md5s com o tempo, pros
           bbcodes não entrarem em ação dentro deles? Então vamos transformar de
           volta em códigos agora... */
 
        for ($i=0; $i<sizeof ($mcl[0]); $i++) {
            $this->texto=str_replace($mcl_md5[$i], $geshi_mcl[$i], $this->texto);
        }
 
        for ($i=0; $i</sizeof><sizeof ($msl[0]); $i++) {
            $this->texto=str_replace($msl_md5[$i], $geshi_msl[$i], $this->texto);
        }
 
        // Limpando as besteiras que não precisam ser repetidas (e coloquei depois dos codes porque
        // aqui corrijo o negócio com os <pre>s.
        $this->texto=preg_replace("/<p>[[:blank:]]*<pre>(.*)< /pre>[[:blank:]]*< /p>/sU", "<\/pre><pre>\1<\/pre>", $this->texto);
        $this->texto=preg_replace("/</p><p>[[:blank:]]*<ul>(.*)< /ul>[[:blank:]]*< /p>/sU", "</ul><ul>\1</ul>", $this->texto);
        $this->texto=preg_replace("/</p><p>[[:blank:]]*<h (.)>(.*)< /h\1>[[:blank:]]*< /p>/sU", "</h><h \1>\2</h>", $this->texto);
        $this->texto=preg_replace("/< ([^>]+)>[[:blank:]]?< /\1>/", "", $this->texto);
 
        // E pra finalizar, o mais mala de todos... =)
        $this->texto.="n";
    }
}
?>

Tá bem comentado e queria pedir pra quem puder, dar uma testada com ele (coloquem uns BBCodes errados e coisas que vocês acham que eu não iria prever). Aí embaixo então a parte das estatísticas, para as quais estou usando um pouco do código do Shortstat. Ela tá assim por enquanto:

Estatísticas

< ?php
class Estatisticas {
    var $ip, $pais, $codigopais, $referer, $url, $dominio, $res, $useragent, $navegador, $versaonavegador, $plataforma, $unixtime;
 
    /* Função que descobre o IP real do visitante
     * Copiada de: www.foo.com.br
     */
    function IpReal() {
        if (getenv("HTTP_CLIENT_IP") && strcasecmp(getenv("HTTP_CLIENT_IP"), "desconhecido")) {
            $ip=getenv("HTTP_CLIENT_IP");
        } else if (getenv("HTTP_X_FORWARDED_FOR") && strcasecmp(getenv("HTTP_X_FORWARDED_FOR"), "desconhecido")) {
            $ip=getenv("HTTP_X_FORWARDED_FOR");
        } else if (getenv("REMOTE_ADDR") && strcasecmp(getenv("REMOTE_ADDR"), "desconhecido")) {
            $ip=getenv("REMOTE_ADDR");
        } else if (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], "desconhecido")) {
            $ip=$_SERVER['REMOTE_ADDR'];
        } else {
            $ip="desconhecido";
        }
 
        return $ip;
    }
 
    /* Função para descobrir navegador, sistema operacional, etc. com base no User Agent.
     * "SI_parseUserAgent()" do Shortstat, levemente modificada.
     */
    function ParseUserAgent($ua) {
        $plataforma="Desconhecida";
        $navegador="Desconhecido";
        $versao="";
 
        if (eregi("Win", $ua)) {
            $plataforma="Windows";
        } else if (eregi("Mac", $ua)) {
            $plataforma="Macintosh";
        } else if (eregi("Linux", $ua)) {
            $plataforma="Linux";
        } else if (eregi("W3C", $ua)) {
            $plataforma="W3C Validator";
            $navegador="W3C Validator";
            $versao="-";
        } else if (eregi("Googlebot", $ua)) {
            $plataforma="Googlebot";
        } else if (eregi("msnbot", $ua)) {
            $plataforma="MSNBot";
        } else if (eregi("Cynthia", $ua)) {
            $plataforma="Cynthia";
            $navegador="Cynthia";
            $versao="0";
        }
 
        if (eregi("Mozilla/4", $ua)&&!eregi("compatible", $ua)) {
            $navegador="Netscape";
            eregi('Mozilla/([[:digit:].]+)', $ua, $b);
            $versao=$b[1];
        }
        if (eregi("Mozilla/5", $ua)||eregi("Gecko", $ua)) {
            $navegador="Mozilla";
            eregi('rv(:| )([[:digit:].]+)', $ua, $b);
            $versao=$b[2];
        }
        if (eregi("Safari", $ua)) {
            $navegador="Safari";
            $plataforma="Macintosh";
            eregi('Safari/([[:digit:].]+)', $ua, $b);
            $versao=$b[1];
        }
        if (eregi("iCab", $ua)) {
            $navegador="iCab";
            eregi('iCab/([[:digit:].]+)', $ua, $b);
            $versao=$b[1];
        }
        if (eregi("Firefox", $ua)) {
            $navegador="Firefox";
            eregi('Firefox/([[:digit:].]+)', $ua, $b);
            $versao=$b[1];
        }
        if (eregi("Firebird", $ua)) {
            $navegador="Firebird";
            eregi('Firebird/([[:digit:].]+)', $ua, $b);
            $versao=$b[1];
        }
        if (eregi("Phoenix", $ua)) {
            $navegador="Phoenix";
            eregi('Phoenix/([[:digit:].]+)', $ua, $b);
            $versao=$b[1];
        }
        if (eregi("Camino", $ua)) {
            $navegador="Camino";
            eregi('Camino/([[:digit:].]+)', $ua, $b);
            $versao=$b[1];
        }
        if (eregi("Chimera", $ua)) {
            $navegador="Chimera";
            eregi('Chimera/([[:digit:].]+)', $ua, $b);
            $versao=$b[1];
        }
        if (eregi("Netscape", $ua)) {
            $navegador="Netscape";
            eregi('Netscape[0-9]?/([[:digit:].]+)', $ua, $b);
            $versao=$b[1];
        }
        if (eregi("MSIE", $ua)) {
            $navegador="Internet Explorer";
            eregi('MSIE ([[:digit:].]+)', $ua, $b);
            $versao=$b[1];
        }
        if (eregi("Opera", $ua)) {
            $navegador="Opera";
            eregi('Opera( |/)([[:digit:].]+)', $ua, $b);
            $versao=$b[2];
        }
        if (eregi("OmniWeb", $ua)) {
            $navegador="OmniWeb";
            eregi('OmniWeb/([[:digit:].]+)', $ua, $b);
            $versao=$b[1];
        }
        if (eregi("Konqueror", $ua)) {
            $navegador="Konqueror";
            $plataforma="Linux";
            eregi('Konqueror/([[:digit:].]+', $ua, $b);
            $versao=$b[1];
        }
        if (eregi('Crawl', $ua) || eregi('bot', $ua) || eregi('slurp', $ua) || eregi('spider', $ua)) {
            $navegador="Crawler/Search Engine";
            $versao="-";
        }
        if (eregi('Lynx', $ua)) {
            $navegador="Lynx";
            eregi('Lynx/([[:digit:].]+)', $ua, $b);
            $versao=$b[1];
            $plataforma="Linux";
        }
        if (eregi('Links', $ua)) {
            $navegador="Links";
            eregi('(([[:digit:].]+)', $ua, $b);
            $versao=$b[1];
        }
 
        $array=Array($navegador, $versao, $plataforma);
        return $array;
    }
 
    /* Função para determinar o país do visitante
     * "SI_determineCountry()", do Shortstat, bem modificada por mim.
     */
    function DeterminarPais($ip) {
        global $BASE;
        $ip=sprintf("%u", ip2long($ip));
 
        $db=new $BASE['TYPE'];
        $db->Conecta();
        $db->Query("SELECT nome, codigo FROM ".$BASE['TABELA_PAISES']." WHERE ip_from < = $ip AND ip_to >= $ip");
        $array=$db->FetchRow();
 
        $db->Desconecta();
 
        /* Agora um monte de linhas por causa da incompetência do PHP 5.0.5... Hehehe... */
        $tmp1=preg_replace("/([A-ZxC0-xDF])/e", "chr(ord('\1')+32)", $array[0]);
        $tmp2=ucwords($tmp1);
        $array[0]=trim($tmp2);
 
        return $array;
    }
 
    /* Função para "increase stats"
     * O arquivo "inc.stats.php" do Shortstat, bem modificado por mim.
     */
    function IncStats() {
        global $BASE;
        $this->ip=$this->IpReal();
        list($this->pais, $this->codigopais)=$this->DeterminarPais($this->ip);
        $this->referer=$_SERVER["HTTP_REFERER"];
        $this->url=parse_url($this->referer);
        $this->dominio=eregi_replace("^www", "", $this->url["host"]);
        $this->resource=$_SERVER["REQUEST_URI"];
        $this->useragent=$_SERVER["HTTP_USER_AGENT"];
        list($this->navegador, $this->versaonavegador, $this->plataforma)=ParseUserAgent($this->useragent);
        $this->unixtime=time();
 
        $db=new $BASE['TYPE'];
        $db->Conecta();
        $db->Query("INSERT INTO ".$BASE['TABELA_ESTATISTICAS']." (ip, pais, codigopais, dominio,
        referer, resource, useragent, plataforma, navegador, versao, unixtime) VALUES ('{$this->ip}',
        '{$this->pais}', '{$this->codigopais}', '{$this->dominio}', '{$this->referer}', '{$this->resource}',
        '{$this->useragent}', '{$this->plataforma}', '{$this->navegador}', '{$this->versaonavegador}',
        '{$this->unixtime}')");
        $db->Desconecta();
    }
}
?>

Bom… Esses dois códigos estão em desenvolvimento ainda, mas acho que com o tempo vão melhorando. Tem umas coisas na parte de Regex que eu queria tornar mais simples mas ainda não descobri como! :blink: Quem quiser sugerir, sinta-se a vontade.

Expressões Regulares no C

ATENÇÃO: Este conteúdo foi publicado há 12 anos. Eu talvez nem concorde mais com ele. Se é um post sobre tecnologia, talvez não faça mais sentido. Mantenho neste blog o que escrevo desde os 14 anos por motivos históricos. Leia levando isso em conta.

Sem querer, visitando a página do cara que desenvolve as Funções ZZ com o Aurélio, o Thobias, acabei descobrindo que o C possue uma biblioteca para expressões regulares! Não sei porquê, mas sempre pensei que o C não tivesse esse suporte e nunca parei pra investigar…

Agora descobri que o C tem uma biblioteca chamada regex.h com quatro funções simples para ERs:

       int regcomp(regex_t *preg, const char *regex, int cflags);
       int regexec(const regex_t *preg, const char *string, size_t nmatch, regmatch_t pmatch[], int eflags);
       size_t regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size);
       void regfree(regex_t *preg)

Não vou aumentar muito esse assunto, mas deixar aqui o link do artigo do Thobias: thobias.org/doc/er_c.html.

A propósito… A página dele é muito legal! Você se sente usando Linux modo-texto… :lol:

E já que falei sobre ERs e Funções ZZ, vou por último falar de um patch que eu fiz pra função ZZCalcula dar as respostas em notação científica e com precisão maior, o que é extremamente importante para eu não precisar ficar contando zeros no novo grupo de estudo de física (que fiz com o prof. Valdir, o Ivo e o John) onde estamos estudando principaplmente astronomia e ter respostas precisas. O patch está disponível aqui e serve para a última versão das ZZ (5.9): Patch para Funções ZZ 5.9, para ZZCalcula resolver as operações com notações científicas e precisão mais alta. Para quem já modificou muito seu arquivo das funções, ou não gosta de patches, publiquei também no meu servidor somente o código inteiro da nova função ZZCalcula com esse recurso: zzcalcula.txt

Hmmm… Eu resolvi começar a floodar mais aqui no blog, isso é, usar a idéia de assuntos diferentes em posts diferentes… Espero que ninguém que recebe e-mails sempre que eu publico uma coisa nova se estresse muito; mas se tiver chato eu dou um jeito de fazer um cron (meu novo servidor tem suporte a cronjobs! E já que eu nunca usei, seria muito legal aprender…) ;)

O Poder do Ajax

ATENÇÃO: Este conteúdo foi publicado há 12 anos. Eu talvez nem concorde mais com ele. Se é um post sobre tecnologia, talvez não faça mais sentido. Mantenho neste blog o que escrevo desde os 14 anos por motivos históricos. Leia levando isso em conta.

Ontem, pela primeira vez, desenvolvi um sistema em Ajax. Já vinha estudando há pouco mais de uma semana e hoje temos votação do Grêmio Estudantil no Colégio, e achei interessante fazer usando Ajax, e aproveitar algumas coisas como:

  • Todos usam Mozilla Firefox.
  • O servidor fica do lado dos computadores… É rede, não internet!

… para abusar de Ajax, já que eu podia fazer uma coisa que buscasse bastante no servidor e que só funcionasse no Gecko. O resultado ficou bem legal. Embora eu não tenha conseguido fazer um trechinho do script sem um IFRAME que atuliza sem parar, todo o esquema foi feito com JavaScript e aprendi umas coisas bem legais. Além disso, o formuláro ficou muito bonito, posicionado e desenvolvido em CSS. Os botões de radio estão com a propriedade display:none e os labels estão com opacity:0.5; Quando eu clico neles (onclick), eles deixam todos os outros com opacity:0.5 e se dão opacity:1. Quando o visitante clica no submit do formulário, o XmlHttp IMEDIATAMENTE pega os dados do servidor e joga na tela. Ficou uma coisa muito massa. E ainda aproveitei pra usar PNGs transparentes!

Não vou colocar o código aqui agora, ainda queria ajustar algumas coisas porque ontem fiz na pressa, mas confiram um screenshot! (o SS mais legal seria o do “Voto Confirmado”, quando um div com fundo PNG alpha aparece em cima de tudo, mas eu fiz um sistema de segurança para só quem tá dentro do Lab. de Informática poder votar – testando IPs – e agora estou em casa).

Screenshot da Votação do Grêmio

Ajax é muito power. Desenvolvendo com ele dá pra fazer umas coisas que antes eu nem imaginava… Agora tô estudando bastante JavaScript, porque com a parte de servidor/PHP não há problemas, mas nunca estudei muito o lado client-side (estudei tableless, mas não DOM/JavaScript!). Já li dois artigos do Elcio, do Tableless.com.br: Um sobre DHTML Crossbrowser e outro que é o conhecido Ajax para quem só ouviu falar. Agora estou acabando o segundo artigo dele sobre Ajax, Ajax: Encarando o Mundo Real. O bom é que a sintaxe das coisas no JavaScript são bem parecidas com as do PHP…


Tenho lido umas coisas desse cara e tô achando muito bom. Sugiro que quem goste de software livre ou quem quer aprender mais sobre ele, leia os artigos também. :)

Troca de Servidor e “Semantic Blog”

ATENÇÃO: Este conteúdo foi publicado há 12 anos. Eu talvez nem concorde mais com ele. Se é um post sobre tecnologia, talvez não faça mais sentido. Mantenho neste blog o que escrevo desde os 14 anos por motivos históricos. Leia levando isso em conta.

Em primeiro lugar, quero pedir desculpa a quem entrou no meu site hoje e teve algum problema. Acontece que acabo de trocar de servidor. Depois de ver uma propaganda no Tableless.com.br, acessei o site da NerdHost e gostei dos preços e da qualidade do serviço. Por causa desses fatos e por eles estarem incentivando os padrões web (dão um mês gratuito pra quem desenvolve em tableless), fechei o contrato com eles no dia em que eu vi. :) Esse servidor usa CPanel, que eu acho bem melhor que o painel de controle da Metaweb e tem vantagens como um SSH que funciona SCP (acreditem! O da Metaweb não funcionava!), subdomínios ilimitados, PHP 5, MySql 4… Foi uma excelente troca! :D E ainda peguei o plano mais barato (limpei o servidor, consegui deixá-lo com 60mb), que custa R$ 5,67 (incrível a precisão do valor… hehehe).

Em segundo lugar: Eu, o Hélio e o Gustavo começamos a desenvolver um sistema de blog, em cima de classes, bastante parecido com o meu mas mais simples que tem como objetivo ser leve e possuir apenas o que é necessário. Ele já vai vir com um Shortstat bem modificado pra dar várias estatísticas (tipo, comentários por visitante, umas paradas assim) e com o GeSHi Highlighter. Os posts vão usar BBCodes e o blog vai ser baseado em templates. Resolvemos dar o nome “Semantic Blog”. Gostou? Deixe um comentário pra eu saber! Não gostou? Deixe um comentário também! :p Hehehe… Se você tiver qualquer sugestão de recurso interessante que ele deve ter, também fique a vontade para postar um comentário!