Older blog entries for ebf (starting at number 38)

19 Oct 2010 (updated 25 Oct 2010 at 23:12 UTC) »

HOWTO: Delete all of your tweets in a few steps

@AlineMary and I decided to change our course with Twitter. Our profiles used to be private, restricted to a few known acquaintances. For personal reasons, we decided to use Twitter in a different way, more public and focused on our projects.

But (always a but) we wouldn’t like to lose our followers or to stop following the interesting people we already followed, so deleting and recreating our accounts was out of league. Manually deleting all tweets, well, was too nightmarish (I had ~ 9800 tweets and @AlineMary ~ 600).

I Googled several mass delete services and found a handful – some, well recommended. There was only one minor problem: none of them worked ;)

Always witty and wise, @AlineMary told me: “You used to be a programmer, right?”. Point taken, my dear :-D .

After googling for some simple-to-use APIs (with OAuth support), I found Jeff Miller’s - “Twitter from the command line in Python using OAuth”, in which he demonstrated the very easy-to-use Tweepy library.

After a quick grok at the documentation, and following Jeff’s footsteps, I managed to assemble a very bare-bones app to mass delete all Tweets. Best of all: It worked :)

So, let’s proceed to the HowTo. You will need to follow Jeff’s steps for the OAuth authentication first:

Step 1: Download Tweepy

Tweepy is an awesome Twitter library for Python. Much of this post is based on information I found in the Tweepy documentation.

Download Tweepy from GitHub and install it on your system.

Step 2: Register a new client app with Twitter

Navigate to http://twitter.com/oauth_clients and click on Register a new application. You might have to log in to the Twitter site first, if you’re not already.

Fill in the registration fields as follows:

When finished on the registration page, click Save.

Next page:

Keep this browser window open. We’ll need the information in the next step.

Step 3: Connect the app to your Twitter account

Next, the app needs to be authorized to connect to your account so it can send tweets under your name.

We’ll create a one-off utility script to do this. Save the following Python code as a script on your local system.

#!/usr/bin/env python

import tweepy

CONSUMER_KEY = 'paste your Consumer Key here'
CONSUMER_SECRET = 'paste your Consumer Secret here'

auth = tweepy.OAuthHandler(CONSUMER_KEY, CONSUMER_SECRET)
auth_url = auth.get_authorization_url()
print 'Please authorize: ' + auth_url
verifier = raw_input('PIN: ').strip()
auth.get_access_token(verifier)
print "ACCESS_KEY = '%s'" % auth.access_token.key
print "ACCESS_SECRET = '%s'" % auth.access_token.secret

Paste the Consumer Key and Consumer Secret from the end of step 2 into this script, replacing the CONSUMER_KEY and CONSUMER_SECRET constants. Then save and run on your system.

You should see a prompt like this:

Please authorize: <URL>
PIN:

Open that URL in your browser. You should see the standard OAuth Twitter connection screen:

Click Allow.

Twitter will then provide you with a PIN code that authenticates the connection between the client app and your Twitter account.

Enter this PIN into the prompt from the Python registration script:

PIN: 2781961

The script will then print out another key/secret pair:

ACCESS_KEY = '124242RCyi3g0cZ4r5BWL047rsh0S0yv5VxAGwTKCOsHAb'
ACCESS_SECRET = 'kaTXiC489qo8y6haTBSlwOqR1syG83tzPG2StdQ'

But the values will be different each time.

Keep this information on your screen because we’ll need it in the next step.

Ok! Thanks Jeff :) . Now, to the destructive part of this post. Muahuahua*.

We will create a very simple Python script that will iterate over your tweets and… well, delete them :)

#!/usr/bin/env python
import sys
import tweepy
import time

CONSUMER_KEY = 'xxxxxxxx'
CONSUMER_SECRET = 'xxxxxxxx'
ACCESS_KEY = 'xxxxxxxxx'
ACCESS_SECRET = 'xxxxxxxxxxxx'

auth = tweepy.OAuthHandler(CONSUMER_KEY, CONSUMER_SECRET)
auth.set_access_token(ACCESS_KEY, ACCESS_SECRET)
api = tweepy.API(auth)

pag  = 1
status  = []

while (1):
	try:
		status  = api.user_timeline(page=pag)
		for update in status:
			print update.id
			print update.text
			api.destroy_status(update.id)
			print "--"
			pag  = pag + 1
	except:
		print "Failure... sleeping for 10 minutes."
		time.sleep(600) # Sleep for 10 minutes and try again.

And that’s it. Execute this Python script (don’t forget to fill your Keys and Secrets, the one you got with Jeff’s steps) and… wait. This app takes a long time to run (mine is still running). But it works 100% :)

Doubts? Comment!

* Sheldon Cooper. :)
19 Oct 2010 (updated 25 Oct 2010 at 23:12 UTC) »

Como apagar seus tweets em poucos passos.

Eu e a @AlineMary decidimos mudar o rumo no Twitter. Antes, tínhamos um perfil privado, restrito a alguns conhecidos. Por motivos pessoais, resolvemos que vamos utilizar o Twitter de forma mais publica e mais voltada a nossos projetos.

Só um porém: não gostaríamos de perder nossos seguidores e aqueles os quais seguíamos, portanto deletar e recriar a conta era algo impraticável. Deletar manualmente os tweets, também (eu tinha ~ 9800 tweets e ela ~ 600).

Procurei vários serviços de mass delete na web e achamos alguns muito bem recomendados. O problema é que eles simplesmente não funcionaram :)

Sempre unida de uma sabedoria cativante, @AlineMary falou: “Você não é um programador?”. Point taken, my dear :)

Após efetuar algumas buscas na web por uma API simples de usar (e com suporte a OAuth), achei o artigo do Jeff Miller – “Twitter from the command line in Python using OAuth”, o qual demonstrava o uso muito simples da API Tweepy.

Dando uma olhada rápida na documentação e seguindo o exemplo do Jeff, montei um programa bem bare bones para remoção em massa dos tweets. E não é que deu certo? :)

Vamos aos passos. Iniciamente você terá de seguir as etapas do post do Jeff para efetuar a autenticação OAuth no Twitter.

Step 1: Download Tweepy

Tweepy is an awesome Twitter library for Python. Much of this post is based on information I found in the Tweepy documentation.

Download Tweepy from GitHub and install it on your system.

Step 2: Register a new client app with Twitter

Navigate to http://twitter.com/oauth_clients and click on Register a new application. You might have to log in to the Twitter site first, if you’re not already.

Fill in the registration fields as follows:

When finished on the registration page, click Save.

Next page:

Keep this browser window open. We’ll need the information in the next step.

Step 3: Connect the app to your Twitter account

Next, the app needs to be authorized to connect to your account so it can send tweets under your name.

We’ll create a one-off utility script to do this. Save the following Python code as a script on your local system.

#!/usr/bin/env python

import tweepy

CONSUMER_KEY = 'paste your Consumer Key here'
CONSUMER_SECRET = 'paste your Consumer Secret here'

auth = tweepy.OAuthHandler(CONSUMER_KEY, CONSUMER_SECRET)
auth_url = auth.get_authorization_url()
print 'Please authorize: ' + auth_url
verifier = raw_input('PIN: ').strip()
auth.get_access_token(verifier)
print "ACCESS_KEY = '%s'" % auth.access_token.key
print "ACCESS_SECRET = '%s'" % auth.access_token.secret

Paste the Consumer Key and Consumer Secret from the end of step 2 into this script, replacing the CONSUMER_KEY and CONSUMER_SECRET constants. Then save and run on your system.

You should see a prompt like this:

Please authorize: <URL>
PIN:

Open that URL in your browser. You should see the standard OAuth Twitter connection screen:

Click Allow.

Twitter will then provide you with a PIN code that authenticates the connection between the client app and your Twitter account.

Enter this PIN into the prompt from the Python registration script:

PIN: 2781961

The script will then print out another key/secret pair:

ACCESS_KEY = '124242RCyi3g0cZ4r5BWL047rsh0S0yv5VxAGwTKCOsHAb'
ACCESS_SECRET = 'kaTXiC489qo8y6haTBSlwOqR1syG83tzPG2StdQ'

But the values will be different each time.

Keep this information on your screen because we’ll need it in the next step.

Ok! Obrigado Jeff :) Agora, vamos a parte destruidora do Post. Muahuahua*.

Vamos criar um script simples que vai iterar pelos posts já efetuados pelo seu usuário e… bem, deletá-los :)

#!/usr/bin/env python
import sys
import tweepy
import time

CONSUMER_KEY = 'xxxxxxxx'
CONSUMER_SECRET = 'xxxxxxxx'
ACCESS_KEY = 'xxxxxxxxx'
ACCESS_SECRET = 'xxxxxxxxxxxx'

auth = tweepy.OAuthHandler(CONSUMER_KEY, CONSUMER_SECRET)
auth.set_access_token(ACCESS_KEY, ACCESS_SECRET)
api = tweepy.API(auth)

pag  = 1
status  = []

while (1):
	try:
		status  = api.user_timeline(page=pag)
		for update in status:
			print update.id
			print update.text
			api.destroy_status(update.id)
			print "--"
			pag  = pag + 1
	except:
		print "Failure... sleeping for 10 minutes."
		time.sleep(600) # Sleep for 10 minutes and try again.

E é isso. Execute esse script Python informando as Keys e Secrets obtidas em cima com o Jeff e… aguarde. O script demora um bocado (o meu ainda está rodando). Mas funciona 100% :)

Dúvidas? Comment!

* Frase atribuída a Sheldon Cooper. :)
16 Oct 2010 (updated 25 Oct 2010 at 23:12 UTC) »

Notes on GridFS and MongoDB

Today we made several tests with MongoDB’s GridFS. And, as simple as it is, we had a hard time trying to find detailed documentation and samples on C++ of this monster (on a good way ;) ).

After brushing some bits, groking headers and a very thorough analysis of the C++ driver source code, we got a simple code snippet that stores an arbitrary file on GridFS, and changes its metadata. This is the sample that worked – if you have any suggestions, please comment! :)

Enjoy!

<br />
...<br />
#include "mongo/client/dbclient.h"<br />
#include "mongo/client/gridfs.h"</p>
<p>using namespace mongo;</p>
<p>...<br />
// The file's full path<br />
m_NomeArquivo = ...;<br />
QFileInfo   info(m_NomeArquivo);</p>
<p>...<br />
DBClientConnection  c;<br />
// local connection to MongoDB.<br />
c.connect("localhost");</p>
<p>// Here we "map" GridFS with the prefix we desire<br />
GridFS      gfs     = GridFS(c, "gridfs", "myfiles");<br />
BSONObj  ret    = gfs.storeFile(m_NomeArquivo.toStdString(), info.fileName().toStdString());<br />
BSONObjBuilder  b;<br />
b.appendElements(ret);<br />
// Here we can add any additional information we want<br />
b.append("fileInserted", "0001");<br />
BSONObj o   = b.obj();</p>
<p>// And now we update the document on MongoDB.<br />
c.update("gridfs.myfiles.files", BSON("filename" << retorno.getField("filename")), o, false, false);<br />
16 Oct 2010 (updated 25 Oct 2010 at 23:12 UTC) »

Notas sobre GridFS e MongoDB

Durante o dia de hoje efetuamos vários testes com o GridFS do MongoDB. E, por mais simples que seja, achar documentação e exemplos desse monstro em C++ foi bem complicado.

Depois de escovar bits, analisar headers e analisar o código fonte do driver C++ do MongoDB, chegamos a um exemplo simples de armazenamento de arquivos genéricos no GridFS, alterando o Metadata do arquivo em questão. Esse é o exemplo que deu certo – se tiver alguma sugestão, comment! :)

Aproveitem!

...
#include "mongo/client/dbclient.h"
#include "mongo/client/gridfs.h"

using namespace mongo;

...
// pega o caminho completo do arquivo a ser salvo
m_NomeArquivo = ...;
QFileInfo   info(m_NomeArquivo);

...
DBClientConnection  c;
// conexão com o MongoDB, local.
c.connect("localhost");

// Mapeamos o GridFS com o prefixo que queremos
GridFS      gfs     = GridFS(c, "gridfs", "arquivos");
BSONObj  retorno    = gfs.storeFile(m_NomeArquivo.toStdString(), info.fileName().toStdString());
BSONObjBuilder  b;
b.appendElements(retorno);
// Aqui incluímos qualquer informação que quisermos
b.append("arquivoInserido", "0001");
BSONObj o   = b.obj();

// E atualizamos o registro do metadata no MongoDB
c.update("gridfs.arquivos.files", BSON("filename" << retorno.getField("filename")), o, false, false);
14 Oct 2010 (updated 16 Oct 2010 at 00:13 UTC) »

Back to subversion…

Almost a month ago, I started an experiment here at A&D. We use Subversion (svn) for 5 years already and never thought about switching to something else. But reading so much on the web about git, I decided that we should test it and feel the advantages in person.

As everyone around me knows, my tests usually involve a “deep dive” inside the solution. :) So, we migrated all of our code repository from svn to git. My conclusion: git is great! A formidable tool that helps the developer rethink the work cicle.

But (always a but!), its distributed nature has caused some problems for us, mainly when someone (err, me!) forgets to issue a git push. That’s why we are starting a painfully migration back to subversion.

This does mean we are stopping using git, right? Wrong. With git-svn, we can have the best from both worlds, using git for a local management, and svn for our main repository.

Oh… I really recommend Redmine. I think it’s much better than Trac for project coordination.

Syndicated 2010-10-14 14:25:05 (Updated 2010-10-16 00:09:53) from #include "ebf.h"

De volta a subversão…

A mais ou menos 30 dias iniciei um experimento aqui na A&D. Utilizamos o Subversion (svn) a quase 5 anos e nunca tínhamos pensado em trocar. Mas com tanto burburinho na internet sobre o git, decidi testar a solução e ver quais eram as vantagens.

Como todos que me conhecem, meus testes normalmente envolvem usar totalmente a solução “testada”. :) Migramos todos nossos projetos para git. Minha conclusão: o git é fenomenal. Realmente uma ferramenta que ajuda o programador a repensar seu ciclo de trabalho.

Porém, sua natureza distribuída causou alguns problemas para gente, principalmente quando alguém (leia-se eu) esquecia de dar um git push. Por isso vamos começar uma dolorosa migração de volta para o subversion.

Isso significa que vamos parar de usar o git, certo? Errado. Com o git-svn vamos ter o melhor dos dois mundos, usando o git para um gerenciamento “local” e o svn para o repositório central.

Ah… recomendo muito o Redmine. Muito melhor que o Trac para organização de projetos.

Syndicated 2010-10-14 13:21:17 (Updated 2010-10-14 13:21:18) from #include "ebf.h"

Hello world!

Welcome to WordPress. This is your first post. Edit or delete it, then start blogging!

Syndicated 2010-09-09 00:51:39 from #include

And we are back…

Antiga marca Maximus

Antiga marca Maximus

Depois de alguns meses ausente (7 para ser exato), voltei ao meu blog. Estive mais atuante no Twitter ultimamente, mas acho que agora passou :)

Nos últimos meses estive completamente imerso nas novidades que a A&D (ex-Soluções, agora Tecnologia) lançou na Exposec 2009. O Maximus 4.0 está sendo um grande marco para a empresa e simboliza uma mudança tecnológica que vai ecoar por um bom tempo no futuro da A&D.

A primeira grande mudança da linha Maximus é sua marca. Antigamente representado pela “estrela”, agora ela é representada pelo “escudo”:

A nova marca nasceu do desejo de revigorar o nome e a identidade da linha Maximus, trazendo visualmente, a nova direção que estamos traçando. Antigamente, algo voltado apenas a segurança eletrônica e detecção, a linha agora seguirá novos direcionamentos. E o que mostramos na Exposec é só o primeiro passo.

Nova Marca Maximus

Nova Marca Maximus

Outra grande diferenças da versão 4.0 para a série 3.X foi o revamp do Maximus Client. A primeira vista tem-se a impressão de uma mudança cosmética, mas é puro engano. Todo o Maximus Client foi redesenvolvido utilizando novas técnicas e frameworks, não sendo aproveitado nenhum código da versão antiga. Some isso com uma interface matadora criada por um dos maiores especialistas em GUI design do mundo, o meu grande amigo Everaldo Coelho e teremos um software não só mais robusto, como mais fácil de usar e extremamente agradável aos olhos:

Interface Mx4 (Mac)

Interface Mx4 (Mac)

E as novidades não param por aí. Pretendo continuar mostrando mais nos próximos dias. Qualquer coisa, estou a disposição.

Abraço!

Eduardo.

Syndicated 2009-05-18 16:26:42 from #include

Uma breve discussão sobre tempo perdido…

Eu gosto muito do John Hodgman (não só por causa da Apple, mas por causa do Daily Show). Ele fez uma apresentação na TED muito boa… assistam! Muito inspiradora.

Abraço!

Eduardo.

Syndicated 2008-10-24 22:09:35 from #include

24 Oct 2008 (updated 25 May 2009 at 14:14 UTC) »

Mais um final de ano!

PS: Estou com esse Post pronto a quase 1 mês… mesmo assim, lá vai!

Depois de 4 meses sumido deste weblog, venho aqui desejar a todos os amigos, familiares, clientes e distribuidores um grande obrigado!

A um ano atrás (mais ou menos) eu estava muito contente. O projeto que começamos em 2001 (na verdade começou muito antes, porém…) estava crescendo muito acima das expectativas e previsões. Sinceramente não acreditava que 2007 seria ainda melhor. E foi.

  • Estamos 12x maiores do que éramos em 2006.
  • Começamos 2007 com 5 distribuidores. Continuamos com o mesmo número, porém vários foram substituídos e a qualidade e dedicação dos atuais superaram qualquer previsão minha. Principalmente por se tratarem de distribuidores de equipamentos, e não de software.
  • Final de 2006: Maximus versão 3.1. Final de 2007: Maximus versão 3.5. Tivemos mais de 140 atualizações, sendo quase 35 novas funcionalidades no sistema. E …
  • 2006: Promessa da nova Intranet. 2007: Nova Intranet já é passado :)
  • A carteira de clientes aumentou muito esse ano. Queria pelo menos dobrar a de 2006. Conseguimos aumentá-la em 4x.
  • Nosso corpo técnico aumentou ainda mais. Continuamos investindo bastante na capacitação de escala internacional de nossos técnicos.
  • E eu achava que estava interoperável em 2006… caramba. Hoje já temos suporte a GPRS/IP de mais 4 marcas, suportamos mais 6 receptoras (inclusive diretamente por IP) e quase 10 novas soluções de monitoramento de imagem. É mole? :)
  • Ganhamos o prêmio TOP GUS 2007.
  • Terminei 2007 com 1 computador. Hoje estou com um Notebook Core2 Duo Intel e uma workstation Core2 Quad Intel, totalizando 6 processadores só pra mim ;) hehehe….
  • Nossa sede literalmente está dobrando de tamanho!

No lado pessoal, comecei a estudar algo que sempre quis: Aviação. Pretendo, em 2008, concluir o curso de Piloto Privado e em 2009, Piloto Comercial. Não pretendo seguir carreira, mas sempre quis pilotar um avião “de fato”. Nos simuladores (principalmente X-Plane e o FSX) estou quase lá. Quero ver no avião de verdade…

Um forte abraço e que venha 2008!

Syndicated 2008-01-16 14:45:36 (Updated 2009-05-24 19:31:13) from #include

29 older entries...

New Advogato Features

New HTML Parser: The long-awaited libxml2 based HTML parser code is live. It needs further work but already handles most markup better than the original parser.

Keep up with the latest Advogato features by reading the Advogato status blog.

If you're a C programmer with some spare time, take a look at the mod_virgule project page and help us with one of the tasks on the ToDo list!