quarta-feira, 25 de abril de 2007

Ubuntu 7.04 - Será desta que a MS se vai sentir?

Para quem não sabe, no dia 19 de Abril foi lançado o Ubuntu 7.04 e este tem muitas novidades.
Dentro delas destaca-se o Gestor de Controladores Restritos. Este gestor permite que se instale os drivers de uma placa gráfica (nVidia e ATI), wireless, etc... com apenas alguns cliques.
A nível de rede sem fios também foi melhorado, temos agora um assistente de redes sem fios (e com fios).
Mais suporte a hardware (isto agora tem a ver com o kernel), mais estável...

Basicamente são estas as mudanças. Já fiz update e está tudo ok :-)

Aconselho que façam o update.

Agora com estas melhorias todas, e sem ter aplicaçoes a comer ram para nos proteger de virus e afins.. será que é desta que a MS se vai sentir com o VISTA (sim, porque o vista é uma desilusão)? Quem sabe é desta que tudo migra para GNU/Linux ao ver a sua potencialidade e o baixo (nulo) preço!

sexta-feira, 13 de abril de 2007

Home Backup Script (Python)

Como prometi, venho aqui colocar uma nova aplicação.
Na altura precisava de algo que me fizesse um backup da homedir e uploadasse para um servidor o backup pus-me ao trabalho de fazer um script que o fizesse.

Consegui chegar à versão 0.3 desse script e comecei a fazer uma 0.4, quem sabe se daqui a uns tempos não continuo a 0.4

Ah e este script até faz logs e utiliza um ficheiro para as configurações :-P

----------------------------------------
from ftplib import FTP
import time, os, sys, ConfigParser

# Home Backup variabels, don't change this
home = os.environ["HOME"]
config = ConfigParser.ConfigParser()
config.read(home + "/homebackup/homebackup.conf")
hostname = config.get("FTP","hostname")
username = config.get("FTP","username")
passwd = config.get("FTP","passwd")
date = time.strftime("%d-%m-%Y-%H%M%S")
user = os.getenv('USER')
bkp = user + "-backup-" + date + ".tar"
log = open(home + "/homebackup/homebackup.log","a")
version = "0.3"

log.write(time.strftime("[%d-%m-%Y %H:%M:%S] ") + "Home Backup Script started.\n")
print "\t\t\tHome Backup Script v" + version + "\t\t\t"
print "Where I will put the backup file?"
print "1. In this directory"
print "2. In a remote machine (You need FTP access)"
option = raw_input("=> ")

def backup():
print "\n" + time.strftime("[%H:%M:%S] ") + "Creating a backup from " + home + " to " + bkp + " ..."
os.system("tar --absolute-names -cf " + bkp + " " + home)
log.write(time.strftime("[%d-%m-%Y %H:%M:%S] ") + "Creating a backup from " + home + " to " + bkp + " ...\n")
print time.strftime("[%H:%M:%S] ") + "Compressing backup ..."
log.write(time.strftime("[%d-%m-%Y %H:%M:%S] ") + "Compressing backup ...\n")
os.system("gzip -9 " + bkp)
log.write(time.strftime("[%d-%m-%Y %H:%M:%S] ") + 'Backup created: ' + bkp + ".gz\n")
print time.strftime("[%H:%M:%S] ") + 'Backup created: ' + bkp + ".gz\n"
log.write(time.strftime("[%d-%m-%Y %H:%M:%S] ") + "Home Backup Script closed.\n\n")
log.close()
def backup_ftp():
print "\n" + time.strftime("[%H:%M:%S] ") + "Creating a backup from " + home + " to " + bkp + " ..."
os.system("tar --absolute-names -cf " + bkp + " " + home)
log.write(time.strftime("[%d-%m-%Y %H:%M:%S] ") + "Creating a backup from " + home + " to " + bkp + " ...\n")
print time.strftime("[%H:%M:%S] ") + "Compressing backup ..."
log.write(time.strftime("[%d-%m-%Y %H:%M:%S] ") + "Compressing backup ...\n")
os.system("gzip -9 " + bkp)
bkpfinal = bkp + ".gz"
log.write(time.strftime("[%d-%m-%Y %H:%M:%S] ") + 'Backup created: ' + bkp + ".gz\n")
print time.strftime("[%H:%M:%S] ") + 'Backup created: ' + bkp + ".gz"
log.write(time.strftime("[%d-%m-%Y %H:%M:%S] ") + "Now I will upload backup to " + hostname + " ...\n")
print time.strftime("[%H:%M:%S] ") + "Now I will upload backup to " + hostname + " ..."
try:
ftp = FTP(hostname)
except:
log.write(time.strftime("[%d-%m-%Y %H:%M:%S] ") + "Invalid hostname.\n")
print time.strftime("[%H:%M:%S] ") + "Invalid hostname."
log.write(time.strftime("[%d-%m-%Y %H:%M:%S] ") + "Upload failed.\n")
print time.strftime("[%H:%M:%S] ") + "Upload failed.\n"
log.write(time.strftime("[%d-%m-%Y %H:%M:%S] ") + "Home Backup Script closed.\n\n")
sys.exit()
try:
ftp.login(username, passwd)
except:
log.write(time.strftime("[%d-%m-%Y %H:%M:%S] ") + "Username or Password invalid.\n")
print time.strftime("[%H:%M:%S] ") + "Username or Password invalid."
log.write(time.strftime("[%d-%m-%Y %H:%M:%S] ") + "Upload failed.\n")
print time.strftime("[%H:%M:%S] ") + "Upload failed.\n"
log.write(time.strftime("[%d-%m-%Y %H:%M:%S] ") + "Home Backup Script closed.\n\n")
sys.exit()
filebkp = open(bkpfinal,'rb')
uploadcmd = "STOR " + bkpfinal
log.write(time.strftime("[%d-%m-%Y %H:%M:%S] ") + "Uploading ...\n")
print time.strftime("[%H:%M:%S] ") + "Uploading ..."
ftp.storbinary(uploadcmd, filebkp)
localsize=os.path.getsize(bkpfinal)
remotesize=ftp.size(bkpfinal)
if localsize != remotesize:
log.write(time.strftime("[%d-%m-%Y %H:%M:%S] ") + "Uploaded file is corrupted.\n")
print time.strftime("[%H:%M:%S] ") + "Uploaded file is corrupted.\n"
log.write(time.strftime("[%d-%m-%Y %H:%M:%S] ") + "Upload failed.\n")
print time.strftime("[%H:%M:%S] ") + "Upload failed.\n"
log.write(time.strftime("[%d-%m-%Y %H:%M:%S] ") + "Home Backup Script closed.\n\n")
elif localsize == remotesize:
log.write(time.strftime("[%d-%m-%Y %H:%M:%S] ") + "Upload completed.\n")
print time.strftime("[%H:%M:%S] ") + "Upload completed.\n"
log.write(time.strftime("[%d-%m-%Y %H:%M:%S] ") + "Home Backup Script closed.\n\n")
filebkp.close()
ftp.quit()
log.close()

if option == "1":
backup()
elif option == "2":
backup_ftp()
elif option != "1":
print "Unknown option."
elif option != "2":
print "Unknown option."
Download completo pode ser feito aqui: http://hydrus.homeunix.net/~amg/homebackup/homebackup-0.3.tar.gz

quinta-feira, 12 de abril de 2007

Desculpem o tempo sem posts

Olá irmãos,
Para os que lêem (provavelmente ninguém ou quase ninguém) o meu blog, desculpem estar sem fazer posts uns tempinhos... é que tive várias coisas para fazer e esqueci-me disto. Esta fim de semana prometo que ponho uma nova aplicação.
By the way, ando a voltar para Python :-P por isso daqui a uns tempos novas aplicações de 2007 (já não faço aplicações em Python desde 2006, eheheh).

Bem, é isso.

Cumprimentos a todos(as)!

quinta-feira, 5 de abril de 2007

Voltei ao Loonix!

Olá irmãos, estou de volta ao Loonix.
Após uns tempos sem este a "doença" voltou. Sou de novo o paranóico que era antigamente. Viva ao Loonix!
Vim para Ubuntu porque agora tenho um laptop (sim, eu com laptop, linux lá e redes wireless é um perigo-- risos). Pus esta distribuição para não perder muito tempo com configurações e por ser mais indicada para portáteis. Para além disso tenho um sticker do Ubuntu na parte de trás do portátil para quando alguém me vir na rua com o portátil dizer: Uhh grande geek!
Deixando de mimos, eu como tenho uma placa gráfica de 128mb e 1gb de ram coloquei o Beryl+AIGLX para ver como ficava... e está mesmo excelente. O VISTA comia-me 50% de RAM (50% de 1gb = 500mb), o portátil aquecia um bocado e o disco rigido fazia um apito muito baixo e agudo. Agora com Ubuntu aqui já é outra coisa :-P
Uma das dificuldades que tive foi a resolução... como é Widescreen e a placa é Intel deu logo barraca. Mas felizmente no Feisty Fawn este problema já vem resolvido.
Para resolver este problema utilizei o 915resolution (podem ver o meu tutorial aqui: http://www.tux-linux.net/view.php?IDART=331).
Não tenho postado ultimamente porque tenho andado a ver LOST (hay, ja estou quase a apanhar a ABC e depois ver os lançamentos semanais).
Tenho andando também a ler a Revista Portuguesa de Linux (http://www.revista-linux.com/), lançada bimestralmente (de dois em dois meses) e que aceitam tutoriais por parte dos leitores. Para não falar que é distribuída livremente (em PDF, nice, estamos a salvar o ambiente, um problema que me preocupa seriamente).
Estou quase de volta à escola, mas são só mais 2 meses sensivelmente e depois tenho férias de verão :-)))
Provavlemente este fim-de-semana ainda coloco mais alguma aplicação minha e explicar como procedi para a sua elaboração.

Cumprimentos geekianos a todos os geeks(as)

sábado, 24 de março de 2007

Gerador de PINS (Python)

Olá irmãos,

Hoje vou postar aqui sobre este script que fiz na altura para me gerar um PIN do cartão de multibanco, esta foi uma das aplicações em que pensei enquanto ia dormir, e aí levantei-me da cama e vim programar.

Tive apenas duas dificuldades: - Gerar valores aleatórios e fazer com que os números tivessem zeros antes (ex: 0001, 0199, 0012).

Primeiro comecei por ir ao Google e o Python já tem uma biblioteca que o faz (chamada random), bastou fazer um

Import random

para a poder utilizar.

A ideia geral para o script funcionar foi ele primeiro gerar os números de 0000 ate 9999, escrever num ficheiro. Após escrito ele irá abrir novamente o ficheiro para apenas leitura e aí com a biblioteca random pegar num valor aleatório, por exemplo: 6273.

Acima falei de um problema que tive, que foi nos zeros. Andei em vários sítios à procura de como o fazer (pois 000 como inteiro ficava apenas 0). É aí que me vem a ideia: Bem, se não preciso de inteiros, porque não utilizar estes valores como string? Aí já não haveria problemas, e assim o fiz.

Mas agora levanta-se outra questão: - Quando é que o script vai saber em que altura será 000 ou 0 ou 00? É aí que atribuo a três variáveis vários zeros como string:

val1 = '000'

val2 = '00'

val3 = '0'

Após esta atribuição é altura de indicar ao script quando usar o val1, val2 e val3. Para isto recorri ao while, visto enquanto x (variável contador que irá de 0 até 9999) for menor que 10 terá o val1 (três zeros), menor que 100 terá val2, e menor que 1000 terá val3.

while x < 10:

    ficheiro = open('gerado.txt','a')

    ficheiro.write(str(val1) + str(x) + " ")

    ficheiro.close()

    x = x + 1

    

while x < 100:

    ficheiro = open('gerado.txt','a')

    ficheiro.write(str(val2) + str(x) + " ")

    ficheiro.close()

    x = x + 1


 

while x < 1000:

    ficheiro = open('gerado.txt','a')

    ficheiro.write(str(val3) + str(x) + " ")

    ficheiro.close()

    x = x + 1

    

while x < 10000:

    ficheiro = open('gerado.txt','a')

    ficheiro.write(str(x) + " ")

    ficheiro.close()

    x = x + 1

Se repararem na altura de escrever no ficheiro existe um str(val1) + str(x), e isto porquê? Bem, segundo se aprende no início da programação apenas se pode fazer operações com dados do mesmo tipo (inteiro com inteiro, string com string), e como x é um dado do tipo inteiro, tenho de na altura o "converter" para string para o poder utilizar com a respectiva string (val1, val2, val3).

Temos os dados escritos no ficheiro gerado.txt, agora teremos de o abrir novamente como leitura. Após abrirmos como leitura teremos de separar os seus dados numa lista, para isto recorri ao split()

gerado = ficheiro.read().split()

Agora já temos uma variável (gerado) com os valores gerados (0000 ate 9999) todos separados como lista.

Falta escolher um valor aleatório para aparecer no ecrã, para resolver isto usei o random.sample(), passando como argumento a string com o conteúdo (gerado) e quantos valores queria (1). Após escolher o valor aleatório é armazenado numa variável (gerados) e é mostrado no ecrã o valor:

gerados = random.sample(gerado, 1)

print "PIN: " + str(gerados).strip("[' ']")

Recorri ao strip() para remover o [' '] que iria aparecer nos números gerados, visto estar a trabalhar com uma lista.

Aqui se segue o código completo:

#!/usr/bin/env python


 

# Mon Oct 23 22:46:00 2006 AZOST

# Gerador de PINS

# (c) 2006 - Alexandre Garcia <alexmgarcia@tux-linux.net>


 

import random

ficheiro = open('gerado.txt','w')

ficheiro.close()

val1 = '000'

val2 = '00'

val3 = '0'

x = 0


 

while x < 10:

    ficheiro = open('gerado.txt','a')

    ficheiro.write(str(val1) + str(x) + " ")

    ficheiro.close()

    x = x + 1

    

while x < 100:

    ficheiro = open('gerado.txt','a')

    ficheiro.write(str(val2) + str(x) + " ")

    ficheiro.close()

    x = x + 1


 

while x < 1000:

    ficheiro = open('gerado.txt','a')

    ficheiro.write(str(val3) + str(x) + " ")

    ficheiro.close()

    x = x + 1

    

while x < 10000:

    ficheiro = open('gerado.txt','a')

    ficheiro.write(str(x) + " ")

    ficheiro.close()

    x = x + 1


 

ficheiro = open('gerado.txt','r')

gerado = ficheiro.read().split()

gerados = random.sample(gerado, 1)

print "PIN: " + str(gerados).strip("[' ']")

ficheiro.close()

sexta-feira, 23 de março de 2007

Conversor de Binário para Decimal (Pascal)

Sim, Pascal! Há gente que se questiona: Ainda dão isso?

Pois é, esta linguagem do século passado e ultrapassada a nível de "novidades" ainda é utilizada no ensino para apresentar programação aos novos alunos e ambientá-los com bases de programação.

Eu, felizmente (ou infelizmente?) estou a dar Pascal em Bases de Programação e acho-o simples e bom para aprender a programar.

Este foi um trabalho de casa que foi pedido, mas penso que era para utilizar operações com strings, só que faço as coisas sempre por outro método e utilizei foi o método tradicional de converter de binário para decimal: 010 = 0 * 2 ^ 0 + 1 * 2 ^ 1 + 0 * 2 ^ 2 = 2

O código é estranho, até usei uns ifs que não sei porquê, mas resolveram os problemas que tinha (caso o ultimo numero fosse 0 acrescentava um valor: 010 ficava 3, 0100 ficava 5, mas já 011 ficava 3 e 0101 ficava 5):

Program bin_dec;

function expoente(x,y:longint):longint;

var

z,n:longint;

begin

n := x;

for z := 2 to y do

n := n * x;

expoente := n;

end;

var

num, aux, multi, digito, valor, soma:longint;

exp:integer;

begin

write('Num (bin): ');

readln(num);

multi := 10;

aux := num;

exp := 0;

soma := 0;

while (aux <> 0) do

begin

digito := aux mod 10;

aux := aux div 10;

multi := multi * 10;

if (exp = 0) and (digito = 1) then

begin

soma := 1;

exp := 1;

end

else

begin

valor := expoente(2,exp);

exp := exp + 1;

soma := soma + digito * valor;

end;

end;

writeln(num,'(bin) = ',soma,'(dec)');

readln;

end.

Gerador de Galeria em HTML (Python)

Este vai ser o meu primeiro post sobre aplicações escritas por mim.

O que é que então isto faz?

É um script que na altura em que usava Linux fiz em Python para gerar uma galeria de fotos em html a partir de um directório com fotos, pois precisava de o fazer porque tinha um directório com várias fotos e "colocar" uma foto de cada vez em código html é trabalhoso, por isso aproveitei uma biblioteca de Python e pus mãos à obra.

A minha primeira dificuldade foi certamente criar uma thumbnail da imagem em questão, por isso dei uma visita ao Google (http://www.google.pt) e rapidamente encontrei o que queria: Python Imaging Library (http://www.pythonware.com/products/pil/). É óbvio que não sabia como trabalhar com este, então disse a mim mesmo: RTFM, fi-lo e em questão de minutos já sabia minimamente o que queria.

Primeiro de tudo tive que indicar que imagem abrir, para isto atribuí a uma variável o resultado de

Image.open(imagem)


 

Em que imagem será uma variável com o caminho da foto/ficheiro.

Também declarei outra variável: THUMBSIZE, em que atribuí a esta a largura e altura da thumbnail (230x153), mais propriamente o valor 230,153. Após isto utilizei a função

Thumbnail

da biblioteca PIL (Python Imaging Library) para a criar, que tem a seguinte sintaxe:

Img (esta foi uma variável criada por mim em que terá como valor o resultado de image.open(imagem) – img.thumbnail(THUMBSIZE)


 

OK. Já tenho a thumbnail da imagem, agora tenho que a salvar… mas há um problema: Imaginemos que o utilizador do script já o correu anteriormente, mas agora acrescentou mais imagens, só que as thumbnails das imagens já existentes encontram-se no directório… como fazer para não criar uma thumbnail de uma thumbnail?

É simples, basta utilizar um if para verificar se as primeiras 5 letras da variável imagem são constituídas pela palavra thumb

If imagem[0:5] != "thumb":

Após esta verificação, caso o resultado seja Verdadeiro e não Falso, o script vai executar o que vem a seguir a esta condição:

Img.save('thumb.' + str(imagem), "JPEG")

Ou seja, o ficheiro ficará: thumb.Foto1.JPG note-se aqui o uso da função str() para converter o valor de imagem para uma string (cadeia de caracteres alfanuméricos). Basicamente a função save do PIL é para salvar num ficheiro as alterações feitas à imagem.

E pronto, temos o problema de criar as thumbnails resolvido.

Aqui abaixo segue-se o código completo do script.

#!/usr/bin/env python


 

# Alto Circuito Galeria

# Por Alexandre Garcia (c) 2006

# Wed, 06 Dec 2006


 

import os, time, string, Image, glob


 

THUMBSIZE = 230, 153

PATH = "/home/amg/AC_fotos/" # Alterar para o directorio das fotos

HTML = PATH + "index.html"

TITLE = "Alto Circuito Lan Party I - Fotos" # Alterar para o titulo do site

ficheiro = open(HTML,"w")


 

def converter():

    os.chdir(PATH)

for imagem in glob.glob("*.JPG"):

img = Image.open(imagem)

img.thumbnail(THUMBSIZE)

        if imagem[0:5] != "thumb":

    img.save('thumb.' + str(imagem), "JPEG")


 

def gerar():

    os.chdir(PATH)

    imgthumb = glob.glob("thumb.*")

    ficheiro.write("<html><head><title>" + TITLE + "</title></head><body><font size=\"4\"><b><center>" + TITLE + "</b></font><br><br>")

    for thumb in imgthumb:

        thumb = '<a href=\"' + str(thumb).strip('thumb.') + '\">' + '<img src=\"' + thumb + '\">' + '</img>' + '</a>' + ' '

        ficheiro.write(thumb)

    ficheiro.write("<br><br><font size=\"2\">Actualizado em " + time.strftime("%d-%m-%Y %H:%M:%S") + "<br>Galeria Alto Circuito - Script feito por <a href=\"mailto:alexmgarcia@tux-linux.net\" style=\"text-decoration:none\"><b>Alexandre Garcia</b></a> (c) 2006</font></center></body></html>")

    ficheiro.close()


 

converter()

gerar()


 

Haja saúde para todos!