toulouse-ll  

Re: [Toulibre] Kiosque de copie sur clé usb

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