helio.loureiro.eng.br
  • Home
  • Unix
  • Linux
  • Blog
  • Python
  • Programação
  • Tudo
  • Suécia
  1. You are here:  
  2. Home
  3. Python

Os artigos mais lidos de 2024

  • linux-br.org num ritmo mais lento
  • Criando um serviço de relay de DNS-over-HTTPS
  • Minha palestra sobre a história do Unix na IX BSD Day
  • Pedal forte de 2023 em dados do Google
  • Linux vs GNU/Linux

Usando python pra capturar a webcam

Details
Written by: Helio Loureiro
Category: Python
Published: September 07, 2013
Hits: 14787

Dia desses eu redescobri as imagens da minha webcam.  Tirei vários screenshots usando o aplicativo cheese, desde que minha mais nova nasceu. E nem lembrava disso.

Consegui criar uma videozinho com elas, o que foi bem legal, mostrando o crescimento dela (e minha barba ficando cada vez mais branca).

 

A idéia inicial era gerar um gif animado, mas o mesmo ficou em 85 MB de tamanho.  E sem som.

Então resolvi fazer 2 coisas:

  • Um script pra ficar pegando imagens da webcam sem precisar de um aplicativo gráfico.
  • Gerar via linha de comando o gif animado.

A captura do screenshot, eu consegui fazer utilizando pygame.  O módulo já inclui vários binding pra realizar ações como capturar da webcam e salvar a imagem.  O script ficou assim:

#! /usr/bin/python -u

"""
Not only Obamas _is_ watching you...
Based in: http://stackoverflow.com/questions/15870619/python-webcam-http-streaming-and-image-capture
"""

SAVEDIR = "/home/helio/Pictures/Webcam"

import pygame, sys
import pygame.camera
import time, random

pygame.init()
pygame.camera.init()
cam = pygame.camera.Camera("/dev/video0", (640,480))

while True:
   print "Taking a shot:",
   cam.start()
   image = cam.get_image()
   cam.stop()
   
   timestamp = time.strftime("%Y-%m-%d_%H%M%S", time.localtime())
   filename = "%s/%s.jpg" % (SAVEDIR, timestamp)
   print "saving into %s" % filename
   
   pygame.image.save(image, filename)
   time.sleep(random.randrange(10) * 60)

Chamei de obamawatch.py em homenagem à espionagem da NSA nas nossas vidas, e que o presidente Obama não fez esforço nenhum pra diminuir ou mesmo evitar.  É um script super intrusivo, pois tira fotos de tempos em tempos, podendo pegar situações que... humm... não o faça se sentir muito orgulhoso.  Então é bom rodar de vez em quando.  

Pra juntar as imagens JPEG geradas em um GIF animado, usei o imagemagick com o mogrify.  Com o mogrify, na verdade, eu diminui as imagens pra 320x240 pixels, pra diminuir o tamanho.  Então usei o imagemagick pra gera o GIF.

mogrify -resize 320x240 *jpg

gm convert -delay 20 2013-09-07_1* animated-2013-09-07.gif

Com isso consegui o resultado abaixo.  Bem divertido. 

 

 

IOError: [Errno 10] No child processes

Details
Written by: Helio Loureiro
Category: Python
Published: August 07, 2013
Hits: 9628

Às vezes eu escrevo programas.  Entre esse programas, alguns são daemons.
Que erro maldito!

Além da confusão com demônios, o que são daemons?

Daemons são os programas que rodam em background no sistema, não precisando de um terminal (console) anexado.  E qualquer tipo de programa pode ser um daemon, pra qualquer finalidade.

Em geral daemons seguem as seguintes regras pra se tornarem daemons:

  1. Mudar pro diretório raiz ("/").
  2. Realizar um fork().
  3. Finalizar o processo pai, ficando somente o filho, criado no fork().
  4. Realizar outro fork().
  5. Finalizar o primeiro processo filho, deixando somente o segundo, criado no segundo fork().

O segundo fork() é feito para garantir que o programa, através do segundo processo filho, seja "herdado" pelo processo init do sistema.

Em Python, sempre incluo uma função como essa:

   def Daemonize(self):
      """
      Fork to became a daemon.
      """
      
      if not self.isDaemon:
         try:
            self.run()
         except KeyboardInterrupt:
            sys.exit(0)
         return
      
      os.chdir("/")
      pid = os.fork()
      
      if (pid > 0):
         sys.exit(os.EX_OK)
      else:
         pid = os.fork()
         
         if (pid > 0):
            sys.exit(os.EX_OK)
         else:
            self.run()

Esse é parte de um método, mas poderia ser uma função.  A idéia é usar o getopt() para verificar as opções passadas e entrar no modo de daemon ou não, dependendo da opção passada, que modifica a variável booleana self.isDaemon.

Mas um dos meus programs começou a apresentar o seguinte erro:

helio@goosfraba:~$ connect_TSP.py ccn
IP already setup... skipping root access
Running as daemon
daemonized...
close failed in file object destructor:
IOError: [Errno 10] No child processes
Error in sys.excepthook:
Traceback (most recent call last):
  File "/usr/lib/python2.7/dist-packages/apport_python_hook.py", line 66, in apport_excepthook
    from apport.fileutils import likely_packaged, get_recent_crashes
RuntimeError: sys.meta_path must be a list of import hooks

Original exception was:
IOError: [Errno 10] No child processes

Inicialmente achei que era problema no "apport" com meu programa, que usa python-expect.  Mesmo com tal erro, o programa funcionava perfeitamente em background, como daemon.  Várias fontes na Internet, principalmente no Launchpad, o sistema de bug report do Ubuntu, várias pessoas reclamavam de tal erro como sendo problema do apport.

Após muito buscar a origem do problema, não no Ubuntu, mas no python, descobri que alguns file descriptors estavam causando esse erro, por continuarem abertos quando ocorria o fork().  Corrigi da seguinte forma:

   def Daemonize(self):
      """
      Fork to became a daemon.
      """
      
      if not self.isDaemon:
         try:
            self.run()
         except KeyboardInterrupt:
            sys.exit(0)
         return
      
      os.chdir("/")
      pid = os.fork()
      
      if (pid > 0):
         os.close(sys.stdin.fileno())
         os.close(sys.stout.fileno())
         os.close(sys.stderr.fileno())
         sys.exit(os.EX_OK)
      else:
         pid = os.fork()
         
         if (pid > 0):
            os.close(sys.stdin.fileno())
            os.close(sys.stdout.fileno())
            os.close(sys.stderr.fileno())
            sys.exit(os.EX_OK)
         else:
            self.run()

então bastou fechar os descritores de arquivo do STDIN, STDOU e STDERR pra ter certeza que o daemon não sairia com o erro acima.

Happy hacking :-)

PyCon Brasil 2013

Details
Written by: Helio Loureiro
Category: Python
Published: August 06, 2013
Hits: 8288

Esse enviei 2 apresentações pra Python Brasil.  Uma falando sobre python-twitter (e como faço pra enviar os #FF de sexta-feira) e outra pra falar sobre python em telecomunicações.

Não tenho nada escrito ainda, e vou aguardar a confirmação do trabalho pra começar.  Se der certo, estarei em Brasília no início de outubro :-)

Adicionando controle automático de acesso ao wifi

Details
Written by: Helio Loureiro
Category: Python
Published: September 22, 2012
Hits: 10651

Fonte: http://www.tiagodoria.ig.com.br/2007/08/28/edelman-prepara-estudo-inedito-sobre-blog-no-brasil/Para quem tem filho adolescente, sabe que as traquitanas tecnológicas tornaram a vida um inferno quando o assunto é estudar.  Controlar o acesso ao computador é fácil, criando regras de bloqueio após certos horários estabelecidos, ou mesmo permissão e filtragem de acessos à sites baseados em URL e squid.

Mas com a chegadas dos dispositivos móveis, como telefones Android e tablets, a coisa não ficou tão fácil.

Restou a opção de bloquear o acesso pelo MAC address nos horários de estudo (que em geral são transformados em horários de soneca durante a tarde ou televisão).

Então fiz um pequeno script em python que bloqueia os MACs já cadastrados, tanto do tablet quanto do smartphone, e libera nos horários em que o computador desktop também está liberado.  Com certeza isso não resolve o problema, mas com adolescentes, em geral, quase nada resolve.

O programa funciona com meu roteador wifi, um WR3G01, que comprei no Dealextreme (mais informações aqui).  É um roteador wireless que se diz compatível com DD-WRT, mas que pra isso exige soldar os contatos da conexão serial na placa e carregar o firmware por tftp (era mais fácil dizer que não suporta então).

 

O programa segue:


#! /usr/bin/python
import re, urllib2
from base64 import encodestring
from sys import argv

MACS = [ "94:63:AA:BB:CC:DD", "74:E1:AA:BB:CC:DD" ]
login = "admin"
password = "admin"
server = "192.168.0.1"
port = 80
URI = "/apply.cgi"

TAG =""
for mac in MACS:
  mac = re.sub(":",'%3A', mac)
  TAG += mac + '%3B'

def Usage():
  print "Use: %s {block|allow}" % argv[0]
  exit(1)


if (len(argv) < 2):
  Usage()
elif (not re.search("allow|block",argv[1])):
  Usage()
  
msg_body = "submit_button=wlan_access&" + \
  "change_action=&" + \
  "action=Apply&" + \
  "AccessControlList0=" + TAG + "&"

if (argv[1] == "allow"):
  msg_body += "AccessPolicy0=0&"
elif (argv[1] == "block"):
  msg_body += "AccessPolicy0=2&"
msg_body += "mac=&mac=&mac=&mac=&mac=&mac=&"
if (argv[1] == "allow"):
  msg_body += "selectMAC=1"
elif (argv[1] == "block"):
  msg_body += " selectMAC=3"

http_pass = encodestring(login + ":" + password)
url = "http://" + server + ":" + str(port) + URI

my_headers = {
  'User-Agent' : 'Python Client/1.0/1.0',
  'Authorization' : 'Basic ' + http_pass,
  'Content-Type' : 'application/x-www-form-urlencoded'
}

req = urllib2.Request(
  url,
  headers = my_headers,
  data = msg_body
)

print "Sending: %s" % argv[1]
resp = urllib2.urlopen(req)

Python em telecom em 7 minutos

Details
Written by: Helio Loureiro
Category: Python
Published: May 29, 2012
Hits: 7798

Essa é uma apresentação que fiz na iMasters em abril último, no evento 7Masters sobre python. 

Não é um curso de python, nem nada próximo disso, mas apenas uma visão de que telecom é na verdade um grande TI, com aplicações que todos nós já conhecemos bem.

7_minutes_python_telecom.swf

 

Era uma apresentação que deveria levar 7 minutos.  Gastei 20.

UPDATE: 2021-12-23 troquei o arquivo embedded de flash pra um gif animado uma vez que nenhum browser sério ainda suporta swf.

 

  1. UnicodeEncodeError: 'ascii' codec can't encode character
  2. Limpando os SPAMs do eri.cx
  3. Enviando IP por mail com Python
  4. Escrevendo uma aplicação com python-twitter (parte 3 - final)

Page 6 of 9

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

Estatísticas

  • Users 2
  • Articles 457
  • Articles View Hits 3240867

Imagem aleatória