jeanmichel . 123
Mon, 22 May 2006 13:29:34 -0700
Selon Bruno Coudoin <[EMAIL PROTECTED]>: > > http://gcompris.net/incoming/friki-0.1.tgz > > J'ai mis en place un mécanisme d'auto-détection de clé USB à minima. > C'est à dire que ca marche mais c'est pas implémenté propre jusqu'au > bout. Pour que ca marche, il faut avoir dbus et hal sur la machine > (Testé sur mandriva 2006 qui contient dbus 0.23).
Pour ma part (debian testing), ça ne semble pas marcher avec:
ii dbus 0.61-5 simple
interprocess messaging system
ii hal 0.5.7-1 Hardware
Abstraction Layer
ii gnome-volume-manager 1.5.15-1 GNOME daemon
to auto-mount and manage media
> Si vous n'avez pas dbus, pas de problème, appuyez sur refresh lorsque la
> clé est insérez et montée.
> Par défaut, je pointe suppose que la clé est montée sur "/mnt/removable"
Justement, sur ma machine, le nom du point de montage dépend du label associé au
système de fichier contenu sur la clef (un peu comme sous windows).
Ce qui revien à dire que cette chaine ne devrait peu être pas être constante...
> Si ce n'est pas le cas, changer:
> MOUNT_POINT="/mnt/removable"
>
> Et voila, les remarques sont les bienvenues.
J'ai essayé de détecter automatiquement le point de montage ajouté
automatiquement, mais je n'arrive pas à modifier une variable globale.
Le fichier modifié est disponible ci-joint.
extrait des modifs faites:
# Set here where your system does mount usb keys
WELLKNOWN_MOUNT_POINTS = [ ]
REMOVABLE_MOUNT_POINTS = [ ]
MOUNT_POINT="/mnt/removable"
def mount_points_list ():
output = os.popen("/bin/df -m " )
fs = output.readlines()
del fs[0]
dmp = map ( re.compile( '[\s\n]*' ).split, fs)
mp = map ( lambda x: x[5] , dmp)
print "mps:" + str(mp)
return mp
#initialisation des points de monatges biens connus:
WELLKNOWN_MOUNT_POINTS = mount_points_list ()
def mount_points_detector ():
c = mount_points_list ()
#x = MOUNT_CHECK
for i in WELLKNOWN_MOUNT_POINTS:
if not i in c :
WELLKNOWN_MOUNT_POINTS.remove(i)
for i in REMOVABLE_MOUNT_POINTS:
if not i in c :
REMOVABLE_MOUNT_POINTS.remove(i)
for i in c:
if not i in WELLKNOWN_MOUNT_POINTS :
if not i in REMOVABLE_MOUNT_POINTS :
REMOVABLE_MOUNT_POINTS.append(i)
if len ( REMOVABLE_MOUNT_POINTS) > 0:
MOUNT_POINT = REMOVABLE_MOUNT_POINTS[0]
MOUNT_CHECK = REMOVABLE_MOUNT_POINTS[0]
#x = MOUNT_CHECK
print "mount point set to " + MOUNT_POINT
print "wk:" + str(WELLKNOWN_MOUNT_POINTS)
print "rem:" +str(REMOVABLE_MOUNT_POINTS)
#return MOUNT_CHECK
#return x
def run_df(self):
# Reset categories
for categ_item in self.selections:
self.set_category_status(categ_item, STATUS_UNSELECTED)
#MOUNT_CHECK =
mount_points_detector ()
output = os.popen("/bin/df -ml %s" % (MOUNT_CHECK,))
try:
...
Par ailleurs, il me semble qu'il manque un bouton, pour démonter la clef, mais
je ne suis pas arrivé jusqu'à cette étape.
bonne chance...
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# friki - A USB KEY Filler
#
# Very convenient and user friendly tool to create a kiosk dedicated to
# filling USB Key with Free content.
#
# Copyright (C) 2006 Bruno Coudoin
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
import pygtk
import gtk
import os
import time
import gobject
import gnomecanvas
import shutil
import re
try:
import dbus
with_dbus = True
except:
with_dbus = False
pass
#
# START OF USER CONFIGURATION
# ---------------------------
#
# SET THE CONTENT TO PROVIDE HERE
# Categorie we provide (name, image, rootdir, size)
#
categories = [
[ "Rock", "/home/bruno/mp3/Sick Side Project - MoonCity Cheats -- Jamendo - MP3 VBR 192k - 2006.04.03 [www.jamendo.com]/", 200 ],
[ "Rap", "/home/bruno/mp3/Silence - L'autre endroit -- Jamendo - MP3 VBR 192k - 2006.01.09 [www.jamendo.com]/", 200 ],
[ "Electro", "/home/bruno/mp3/Trent - Avant l'orage -- Jamendo - MP3 VBR 192k - 2005.10.30 [www.jamendo.com]/", 200 ],
[ "Techno", "/home/bruno/mp3/Xcyril - Styles Divers -- Jamendo - MP3 VBR 192k - 2006.01.11 [www.jamendo.com]/", 200 ],
[ "Le film Elephant Dream", "/home/bruno/mp3/Elephants_Dream_1024.avi", 426 ],
[ "Logiciel Libre", "/home/bruno/mp3/Rafiralfiro - Transe Lucide -- Jamendo - MP3 VBR 192k - 2006.01.12 [www.jamendo.com]", 200 ],
]
# Set to True is you want to test on your hard drive.
# By default, the /tmp/friki directory will be used instead of the USB Key
DEBUG=False
# Set here where your system does mount usb keys
WELLKNOWN_MOUNT_POINTS = [ ]
REMOVABLE_MOUNT_POINTS = [ ]
MOUNT_POINT="/mnt/removable"
#
# END OF USER CONFIGURATION
# -------------------------
#
VERSION=0.1
# Usually, MOUNT_CHECK is the same as mountpoint. To find out, run a df and look at
# the last field on the line matching MOUNT_POINT
# It is usefull to change it to
MOUNT_CHECK=MOUNT_POINT
# Override the values for debugging
if(DEBUG):
MOUNT_POINT="/tmp/friki"
MOUNT_CHECK="/"
if(not os.path.isdir(MOUNT_POINT)):
os.mkdir(MOUNT_POINT)
# Background image
IMAGE_DIR=""
BACKGROUND_FILE="background.png"
LOGO_FILE="toulibre-logo.png"
LOGO_X=580.0
LOGO_Y=530.0
SELECTION_X = 240
SELECTION_Y = 60
STATUS_UNSELECTED = 0
STATUS_SELECTED = 1
STATUS_UNAVAILABLE = 2
STATUS_COPIED = 3
def mount_points_list ():
output = os.popen("/bin/df -m " )
fs = output.readlines()
del fs[0]
dmp = map ( re.compile( '[\s\n]*' ).split, fs)
mp = map ( lambda x: x[5] , dmp)
print "mps:" + str(mp)
return mp
#initialisation des points de monatges biens connus:
WELLKNOWN_MOUNT_POINTS = mount_points_list ()
def mount_points_detector ():
c = mount_points_list ()
#x = MOUNT_CHECK
for i in WELLKNOWN_MOUNT_POINTS:
if not i in c :
WELLKNOWN_MOUNT_POINTS.remove(i)
for i in REMOVABLE_MOUNT_POINTS:
if not i in c :
REMOVABLE_MOUNT_POINTS.remove(i)
for i in c:
if not i in WELLKNOWN_MOUNT_POINTS :
if not i in REMOVABLE_MOUNT_POINTS :
REMOVABLE_MOUNT_POINTS.append(i)
if len ( REMOVABLE_MOUNT_POINTS) > 0:
MOUNT_POINT = REMOVABLE_MOUNT_POINTS[0]
MOUNT_CHECK = REMOVABLE_MOUNT_POINTS[0]
#x = MOUNT_CHECK
print "mount point set to " + MOUNT_POINT
print "wk:" + str(WELLKNOWN_MOUNT_POINTS)
print "rem:" +str(REMOVABLE_MOUNT_POINTS)
#return MOUNT_CHECK
#return x
class Friki:
width = 800
height = 600
def set_category_status(self, item, state):
if(state == STATUS_UNSELECTED):
item.set(pixbuf=gtk.gdk.pixbuf_new_from_file("category_back.png"))
elif(state == STATUS_SELECTED):
item.set(pixbuf=gtk.gdk.pixbuf_new_from_file("category_back_selected.png"))
elif(state == STATUS_UNAVAILABLE):
item.set(pixbuf=gtk.gdk.pixbuf_new_from_file("category_back_disabled.png"))
elif(state == STATUS_COPIED):
item.set(pixbuf=gtk.gdk.pixbuf_new_from_file("category_back_copied.png"))
item.set_data('state', state)
# Event on categories
def categorie_event(self, item, event, size):
if(self.space == 0):
return
state = item.get_data('state')
if(state == STATUS_UNAVAILABLE or state == STATUS_COPIED):
return
if event.type == gtk.gdk.ENTER_NOTIFY:
item.set(pixbuf=gtk.gdk.pixbuf_new_from_file("category_back_highlight.png"))
elif event.type == gtk.gdk.LEAVE_NOTIFY:
self.set_category_status(item, state)
if event.type == gtk.gdk.BUTTON_PRESS:
if event.button == 1:
if(state == STATUS_UNSELECTED):
self.space = self.space - size
self.set_category_status(item, STATUS_SELECTED)
elif(state == STATUS_SELECTED):
self.space = self.space + size
self.set_category_status(item, STATUS_UNSELECTED)
else:
return True
self.display_status('Tu as %s Mega Octet de place disponible' % (self.space,))
# Disable checkboxes where there is not enough space left
for categ_item in self.selections:
state = categ_item.get_data('state')
size = categ_item.get_data('size')
if(state == STATUS_UNSELECTED and self.space - size < 0):
self.set_category_status(categ_item, STATUS_UNAVAILABLE)
elif(state == STATUS_UNAVAILABLE and self.space - size > 0):
self.set_category_status(categ_item, STATUS_UNSELECTED)
return True
return False
def add_selection(self, rootitem, y, name, dir, size):
back = gtk.gdk.pixbuf_new_from_file("category_back.png")
item = rootitem.add(
gnomecanvas.CanvasPixbuf,
pixbuf = back,
x = SELECTION_X,
y = y
)
item.set_data('state', STATUS_UNSELECTED)
item.set_data('size', size)
item.set_data('name', name)
item.set_data('dir', dir)
item.connect("event", self.categorie_event, size)
rootitem.add(
gnomecanvas.CanvasText,
x = SELECTION_X + back.get_width()/2,
y = y + 17,
font = "Sans 14",
text = name,
fill_color = "white",
justification = gtk.JUSTIFY_CENTER
)
rootitem.add(
gnomecanvas.CanvasText,
x = SELECTION_X + back.get_width() - 30,
y = y + 25,
font = "Sans 10",
text = "(%dMO)" %(size,),
fill_color = "white",
justification = gtk.JUSTIFY_CENTER
)
self.selections.append(item)
# This is a callback function. The data arguments are ignored
# in this example. More on callbacks below.
def copy(self, widget, data=None):
error = False
for categ_item in self.selections:
state = categ_item.get_data('state')
if(state == STATUS_SELECTED):
name = categ_item.get_data('name')
srcdir = categ_item.get_data('dir')
self.display_status("Copie '%s' en cours" %(name,))
if(os.path.isdir(srcdir)):
try:
shutil.copytree(srcdir, "%s/%s" %(MOUNT_POINT, name,))
self.set_category_status(categ_item, STATUS_COPIED)
except (IOError, os.error), why:
print("Erreur de copie 'srcdir ''%s'" %(srcdir, why))
self.display_status("Erreur: '%s'" %(why,))
error = True
break
else:
# Regular file
try:
shutil.copy(srcdir, MOUNT_POINT)
self.set_category_status(categ_item, STATUS_COPIED)
except (IOError, os.error), why:
print("Erreur de copie '%s' '%s'" %(srcdir, why))
self.display_status("Erreur: '%s'" %(why,))
error = True
break
if(not error):
self.display_status("La copie est terminée")
def delete_event(self, widget, event, data=None):
# If you return FALSE in the "delete_event" signal handler,
# GTK will emit the "destroy" signal. Returning TRUE means
# you don't want the window to be destroyed.
# This is useful for popping up 'are you sure you want to quit?'
# type dialogs.
print "delete event occurred"
# Change FALSE to TRUE and the main window will not be destroyed
# with a "delete_event".
return False
def display_status(self, text):
self.label.set(text=text)
# Make sure to refresh the UI, even when we are doing copy
while gtk.events_pending():
gtk.main_iteration(False)
def destroy(self, widget, data=None):
print "destroy signal occurred"
gtk.main_quit()
def __init__(self):
self.added_callback = 0
self.space = 0
self.selections = []
# create a new window
window = gtk.Window(gtk.WINDOW_TOPLEVEL)
window.set_default_size(800,600)
window.set_title("Libère tes oreilles, libère ton ordinateur ")
window.connect("delete_event", self.delete_event)
window.connect("destroy", self.destroy)
# Sets the border width of the window.
window.set_border_width(0)
# Create VBox to hold canvas and buttons.
vbox = gtk.VBox()
window.add(vbox)
# The canvas
self.canvas = gnomecanvas.Canvas()
self.canvas.set_size_request(self.width, self.height)
self.canvas.set_scroll_region(0,0, self.width, self.height)
vbox.pack_start(self.canvas)
# Create our rootitem. We put each canvas item in it so at the end we
# only have to kill it. The canvas deletes all the items it contains
# automaticaly.
self.rootitem = self.canvas.root().add(
gnomecanvas.CanvasGroup,
x=0.0,
y=0.0
)
self.rootitem.add(
gnomecanvas.CanvasPixbuf,
pixbuf = gtk.gdk.pixbuf_new_from_file(BACKGROUND_FILE),
x=0.0,
y=0.0
)
self.rootitem.add(
gnomecanvas.CanvasPixbuf,
pixbuf = gtk.gdk.pixbuf_new_from_file(LOGO_FILE),
x=LOGO_X,
y=LOGO_Y
)
y = 120.0
step = 400.0 / len(categories)
for categorie in categories:
self.add_selection(self.rootitem, y, categorie[0], categorie[1], categorie[2])
y = y + step
# Display the version of friki
self.rootitem.add(
gnomecanvas.CanvasText,
x = 50,
y = self.height-20,
font = "Sans 10",
text = "Version %s" %(VERSION,),
fill_color = "white",
justification=gtk.JUSTIFY_CENTER
)
self.label = self.rootitem.add(
gnomecanvas.CanvasText,
x = self.width/2,
y = self.height-30,
font = "Sans 16",
text = "Inserez votre cle usb",
fill_color = "white",
justification=gtk.JUSTIFY_CENTER
)
# Main button box
bbox = gtk.VButtonBox()
bbox.set_border_width(5)
bbox.set_layout(gtk.BUTTONBOX_SPREAD)
bbox.set_spacing(3)
self.rootitem.add(
gnomecanvas.CanvasWidget,
widget=bbox,
x=20.0,
y=480.0,
width=760.0,
height= 100.0,
anchor=gtk.ANCHOR_NW,
size_pixels=False)
# The bottom buttons
hbox = gtk.HButtonBox()
bbox.add(hbox)
hbox.set_border_width(5)
hbox.set_layout(gtk.BUTTONBOX_SPREAD)
hbox.set_spacing(3)
# Bottom buttons
button = gtk.Button(stock='gtk-refresh')
button.connect("clicked", self.run_df_cb, None)
hbox.add(button)
self.button_ok = gtk.Button(stock='gtk-ok')
hbox.add(self.button_ok)
self.button_ok.connect("clicked", self.copy, None)
self.button_ok.set_sensitive(False)
# The final step is to display this newly created widget.
window.show_all()
def device_added_callback(self, udi, a, b, c, d):
print "=================================================="
print 'Device with udi %s was added (%s, %s, %s, %s)' % (udi, a, b, c, d)
self.added_callback = self.added_callback + 1
if(self.added_callback<6):
self.display_status('Montage en cours étape %d' %(self.added_callback,))
return
self.display_status('Je calcule la place disponible')
gobject.timeout_add(2000, self.run_df)
def run_df_cb(self, widget, data=None):
self.run_df()
def run_df(self):
# Reset categories
for categ_item in self.selections:
self.set_category_status(categ_item, STATUS_UNSELECTED)
#MOUNT_CHECK =
mount_points_detector ()
output = os.popen("/bin/df -ml %s" % (MOUNT_CHECK,))
try:
line = output.readlines()[1]
except:
# If there is not this line, then there is no answer from df
self.display_status('Je ne trouve pas le point de montage %s' % (MOUNT_CHECK,))
return
print line
print line.split()
print line.split()[5]
print line.split()[3]
if(line.split()[5] == MOUNT_CHECK):
self.space = int(line.split()[3])
# Activate the copy
self.display_status('Tu as %d Mega Octet de place disponible' % (self.space,))
self.button_ok.set_sensitive(True)
def device_removed_callback(self, udi, a, b, c, d):
print "=================================================="
print 'Device with udi %s was removed (%s, %s, %s, %s)' % (udi, a, b, c, d)
self.added_callback = 0
self.size = 0
self.button_ok.set_sensitive(False)
self.display_status('Insere ta cle usb')
def device_capability_callback(self, udi, capability, b, c, d):
print "=================================================="
print 'Device with udi %s added capability %s' % (udi, capability)
def main(self):
# Init DBUS
print with_dbus
if(with_dbus):
bus = dbus.SystemBus()
connection = bus.get_connection()
bus.add_signal_receiver(self.device_added_callback,
'DeviceAdded',
'org.freedesktop.Hal.Manager',
'org.freedesktop.Hal',
'/org/freedesktop/Hal/Manager')
bus.add_signal_receiver(self.device_removed_callback,
'DeviceRemoved',
'org.freedesktop.Hal.Manager',
'org.freedesktop.Hal',
'/org/freedesktop/Hal/Manager')
bus.add_signal_receiver(self.device_capability_callback,
'DeviceAdded',
'org.freedesktop.Hal.Manager',
'org.freedesktop.Hal',
'/org/freedesktop/Hal/Manager')
# Start the main loop
gtk.main()
#
# MAIN
# ----
#
friki = Friki()
friki.main()
_______________________________________________ Toulouse-ll mailing list Toulouse-ll@toulibre.org http://lolut.utbm.info/cgi-bin/mailman/listinfo/toulouse-ll