Questa applicazione è stata creata da me per puro scopo didattico. Dovevo imparare ad utilizzare il bluetooth in Python e ho finito per creare questa simpatica applicazione.
Descrizione:
Una volta selezionato un file presente sul vostro cellulare, BT Flooder tenterà di inviarlo a tutte le periferiche bluetooth che sono nei paragi, tenendo una conta delle vittime che accettano il vostro file.
L’applicazione può essere utile per inviare un’immagine, magari un vostro sticker o una foto che volete condividere con tutti, oppure una semplice nota testo contenente un messaggio, un indirizzo di un sito internet, o qualsiasi cosa vi venga in mente.
L’applicazione supporta inoltre un filtro che permette di esonerare determinate periferiche dall’assillante invito a ricevere un file, e una funzione di logging, tramite la quale potrete conoscere, al termine dell’esecuzione, tutte le periferiche che hanno accettato il vostro file.
BT Flooder è stato scritto in Python, quindi necessita (ovviamente) che l’interprete sia installato sul vostro cellulare. Oltre a questo l’applicazione fa uso del modulo esterno LightBlue, necessario per cercare periferiche bluetooth silenziosamente. Il file di installazione è scaricabile a questo indirizzo, e va installato nella memoria interna, non sulla memory card.
- Download BT Flooder (versione .sis) -
- Download BT Flooder (versione .py) -
- Download modulo LightBlue -
Aggiornamento – 24/08/2009
Ho aggiornato l’applicazione perché presentava un bug nella codifica UTF-8. Non era infatti possibile selezionare periferiche e file con caratteri non-ASCII.
Segue il codice sorgente dell’applicazione.
import os
import e32
import sys
import socket
import appuifw
import globalui
import graphics
try:
import lightblue
except:
appuifw.note(u'Modulo lightblue non trovato.', 'error')
if appuifw.query(u'Scaricare il modulo richiesto?', 'query'):
url = 'http://lightblue.sourceforge.net/#downloads'
browser = 'BrowserNG.exe'
e32.start_exe(browser, ' "4 %s"' % url, 1)
sys.exit()
#Variabili
log_file = u'C:\\bt_flooder_log.txt'
log_ok = False
accept = 0 #Persone che accettano
attemp = 0 #Tentativi di invio
filtro = [] #Filtro di MAC
devices = () #Periferiche
obj = u'Nessuno' #File selezionato
file_ok = False
status = u'Flooder in pausa.' #Stato flooder
#Draw
PAD = 5 #Padding
TXT = (0, 0, 0) #Colore testo
VAL = (255, 0, 0) #Colore valore
STATUS = (0, 200, 0) #Colore stato applicazione
ABOUT = (180, 180, 180) #Colore about
BACKGROUND = (240, 255, 255)
MRG = 25 #Margin
FONT_T = (None, 20)
FONT_V = (None, 20, 1)
def draw(r=None):
"""Disegna la schermata di stato"""
global devices, status, attemp
img.clear(BACKGROUND)
#File oggetto
img.text((PAD, MRG), u'File:', fill = TXT, font = FONT_T)
X = img.measure_text(u'File: ', font = FONT_T)[1]
img.text((PAD + X, MRG), u'%s' % obj[obj.rfind('\\')+1:], fill = VAL, font = FONT_V)
#Log attivo/disattivo
img.text((PAD, MRG * 2), u'Log:', fill = TXT, font = FONT_T)
X = img.measure_text(u'Log: ', font = FONT_T)[1]
img.text((PAD + X, MRG * 2), (log_ok and u'Attivato' or u'Disattivato'), fill = VAL, font = FONT_V)
#Vittime che accettano
img.text((PAD, MRG * 3), u'Vittime:', fill = TXT, font = FONT_T)
X = img.measure_text(u'Vittime: ', font = FONT_T)[1]
img.text((PAD + X, MRG * 3), u'%d' % accept, fill = VAL, font = FONT_V)
#Tentativi di invio file
img.text((PAD, MRG * 4), u'Tentativi invio:', fill = TXT, font = FONT_T)
X = img.measure_text(u'Tentativi invio: ', font = FONT_T)[1]
img.text((PAD + X, MRG * 4), u'%d' % attemp, fill = VAL, font = FONT_V)
#Periferiche bluetooth nei paragi
img.text((PAD, MRG * 5), u'Periferiche BT:', fill = TXT, font = FONT_T)
X = img.measure_text(u'Periferiche BT: ', font = FONT_T)[1]
img.text((PAD + X, MRG * 5), u'%d' % len(devices), fill = VAL, font = FONT_V)
#Stato applicazione
img.text((PAD, MRG * 6), status, fill = STATUS, font = FONT_V)
#About
img.text((PAD, MRG * 7 + 20), u'Created by Ale152', fill = ABOUT, font = FONT_T)
img.text((PAD, MRG * 8 + 20), u'www.Wirgilio.it', fill = ABOUT, font = FONT_T)
c.blit(img)
#Canvas
c = appuifw.Canvas(redraw_callback = draw)
img = graphics.Image.new(c.size)
appuifw.app.body = c
def list(path):
"""Lista una directory e restituisce un file selezionato"""
#Torna indietro
if path.endswith('\\..'):
#Mostra dischi
if path in ['C:\\\\..', 'E:\\\\..']:
files = ['C:', 'E:']
path = ''
#Mostra directory precedente
else:
path = path[:path.rfind('\\\\..')] #Elimino il \\.. dal path
path = path[:path.rfind('\\')] #Elimino l'ultima dir dal path
#Listo la dir
files = os.listdir(path)
files.sort()
files[0:0] = ['\\..']
#Lista directory
elif path:
files = os.listdir(path)
files.sort()
files[0:0] = ['\\..']
ufiles = [i.decode('utf-8') for i in files] #appuifw richiede unicode
try:
selected = files[appuifw.selection_list(ufiles, 1)] #1 abilita ricerca
except:
#Nessun file selezionato
pass
#Se hai selezionato E: non deve restituire \E: !
return path and path+'\\'+selected or selected
def select_file():
"""Seleziona un file da inviare alle vittime"""
global log_ok, file_ok, obj
appuifw.note(u'Selezionare un file da inviare alle vittime.')
file_ok = False #File non selezionato
path = 'C:\\\\..' #Torna indietro ai dischi
temp = list(path)
while not file_ok:
temp = list(temp)
#Se è un file, restituisce l'indirizzo
#Se è una cartella, la lista
if os.path.isfile(temp):
file_ok = True
obj = temp.decode('utf-8')
appuifw.note(u'File selezionato.', 'conf')
draw()
if log_ok:
log.write('%s> file = %s\n' % (strftime('%H:%M:%S'), obj))
def logging():
"""Attiva o disattiva il file di log"""
global log_ok, log, strftime
log_ok = globalui.global_query(u'Salvare un file di log?')
if log_ok:
log = file(log_file, 'a')
from time import strftime
log.write('\n\nSession starts on %s\n' % strftime('%H:%M:%S'))
appuifw.note(log_file+' creato.', 'conf')
#Chiede di attivare il logging all'avvio dell'applicazione
logging()
#*****************
# Filtro #
#*****************
def filter(action):
"""Gestisce il filtro periferiche. Le periferiche nel filtro non verranno
infastidite dal flooder"""
global filtro
#Aggiungi periferica
if action == 'add':
try:
mac = socket.bt_obex_discover()[0]
if mac:
filtro.append(mac)
appuifw.note(u'Periferica aggiunta.', 'conf')
else:
appuifw.note(u'Periferica non raggiungibile!', 'error')
except:
appuifw.note(u'Periferica non raggiungibile!', 'error')
#Mostra periferiche
elif action == 'show':
if filtro:
ufiltro = [i.decode('utf-8') for i in filtro]
appuifw.selection_list(ufiltro)
else:
appuifw.note(u'Nessuna periferica nel filtro!', 'error')
#Elimina periferiche
elif action == 'del':
if filtro:
ufiltro = [i.decode('utf-8') for i in filtro]
delete = appuifw.selection_list(ufiltro)
filtro.remove(filtro[delete])
appuifw.note(u'Periferica rimossa.', 'conf')
else:
appuifw.note(u'Nessuna periferica nel filtro!', 'error')
#About
def about():
appuifw.query(u'BT Flooder created by Ale152.', 'query')
appuifw.query(u'www.wirgilio.it', 'query')
#*****************
# Applicazione #
#*****************
def app(oper):
global log_ok, file_ok, run, accept, obj, devices, status, attemp
##
## Run
##
if oper == 'run':
run = True
#Seleziona un file come oggetto
if not file_ok:
select_file()
while run:
#Cerco periferiche nei paragi
status = u'Cerco periferiche...'
draw()
try:
devices = lightblue.finddevices()
if log_ok:
log.write('%s> %d devices found!\n' %
(strftime('%H:%M:%S'), len(devices)))
except SymbianError:
appuifw.note(u'Bluetooth disattivato!', 'error')
app('stop')
break
#Cerco i servizi offerti
for device in devices:
try: #Supporta obex?
status = 'Verifico '+device[1]+'...'
draw()
#obex = (mac, {'srv':chan})
obex = socket.bt_obex_discover(device[0])
if obex and obex[0] not in filtro:
status = device[1]+' supporta OBEX!'
draw()
canale = obex[1].items()[0][1]
indirizzo = obex[0]
if log_ok:
log.write('%s> trying to send "%s" to %s (%s)...' %
(strftime('%H:%M:%S'), obj, indirizzo, str(device[1])))
status = u'Provo ad inviare il file...'
attemp += 1
draw()
try: #Provo ad inviare il file
socket.bt_obex_send_file(indirizzo, canale, obj)
accept += 1
status = u'File inviato!'
draw()
e32.ao_sleep(1)
if log_ok:
log.write(' file sent! (%d)\n' % accept)
except:
if log_ok:
log.write(' file refused!\n')
status = u'File rifiutato
'
draw()
except: #Non supporta obex.
status = device[1]+' non supportato.'
draw()
e32.ao_sleep(0.01)
##
## Stop
##
elif oper == 'stop':
run = False
status = u'Flooder in pausa.'
draw()
##
## Quit
##
elif oper == 'quit':
run = False
#Chiude il log se aperto
if log_ok:
log.write('%s> victims = %d' % (strftime('%H:%M:%S'), accept))
log.write('\nSession ends on %s\n\n' % strftime('%H:%M:%S'))
log.close()
lock.signal()
appuifw.app.set_exit()
#Appuifw
appuifw.app.title = u'BT Flooder'
appuifw.app.exit_key_handler = lambda: app('quit')
appuifw.app.menu = [(u'Flooder', ((u'Avvia', lambda: app('run')),
(u'Arresta', lambda: app('stop')),
(u'Seleziona file', select_file))
),
(u'Filtro periferiche', ((u'Mostra', lambda: filter('show')),
(u'Aggiungi', lambda: filter('add')),
(u'Elimina', lambda: filter('del'))
)),
(u'File log', logging),
(u'About', about),
(u'Esci', lambda: app('quit'))]
lock = e32.Ao_lock()
lock.wait()
Ciao,molto interessante..
volevo chiederti se è possibile effettuare qualcosa del genere su maemo5..in particolare sul n900
grazie mille!
@staky07
Certo che è possibile! Su Maemo puoi fare praticamente ogni cosa che faresti sul computer
Il problema però è che il codice è completamente diverso.
Questo script è scritto per utilizzare librerie e funzioni di Symbian, bisognerebbe modificare tutto con le relative funzioni di Python per Maemo.
Purtroppo, non avendo un N900, non ho idea di quali siano le modifiche da fare…
Esiste un emulatore su pc per virtualizzare Maemo..

http://netrudy.wordpress.com/2010/01/20/sviluppo-pymaemo-da-virtual-machine/
se vuoi dargli un occhiatina magari..
grazie ancora..cmq..