Изба говорильня + автомаунт + хэндлер

Written by

in

Наконец-то выкроил врем избавиться от старого костыля и приспособить новый.

В общем ТЗ: проговаривать качественным сепстраловским синтезом что за флешку мы воткнули, автомаунтить ее (кеды 4е маунтят по нажатию значек в нотификаторе/долфине только, да и не везде у меня кеды стоят, fvwm еще местами)

Реализация. От юзера запускаем питоновский скрипт, надыбанный на лоре во времена древние, предварительно его маленько дополнив. Сырцы этого извращения под катом.

Вышел примерно такой быдлокод:

notify.py

#!/usr/bin/python
# -*- coding: utf-8 -*-
###########################################################################
#  Event Commenter + automount via hal  + bash handlers                   # 
# ------------------------------                                          #
# copyright : © 2008 radiofun; © 2009 Necromant                           #
# jabber    : radiofun@jabber.ru                                          #
# jabber    : aifiltr0@invyl.ath.cx                                       #
#                                                                         #
###########################################################################
#                                                                         #
#   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.                                   #
#                                                                         #
###########################################################################

import gobject
import threading
import math
import dbus
import dbus.mainloop.glib
import os

class EventCommenter():#threading.Thread):
    def __init__(self):
        #threading.Thread.__init__(self)
        self.__bus = dbus.SystemBus()
        self.__hm = self.__bus.get_object('org.freedesktop.Hal','/org/freedesktop/Hal/Manager')
        self.__hm.connect_to_signal('DeviceAdded', self.deviceAdded)
        self.__hm.connect_to_signal('DeviceRemoved', self.deviceRemoved)
	self.handler_script = "/home/aifiltr0/.config/notifier/storage_handler.sh"
	
        self.__connectedDevices = dict();
      
    def deviceAdded(self, devID):
        device = dbus.Interface(self.__bus.get_object("org.freedesktop.Hal", devID),
                                "org.freedesktop.Hal.Device")
        message = self.__prepareComment(device)
        if len(message) > 0:
            self.__connectedDevices[devID]=message;
            self.__say(message);
            os.system(self.exec_line)

    def deviceRemoved(self, devID):
        if devID in self.__connectedDevices:
            message = self.__connectedDevices.pop(devID)
            message += ", disconnected."
            #self.__say(message);

    #prepare device comment!
    def __prepareComment(self, device):
        message = ""
        if device.PropertyExists('info.capabilities'):
            isCD = device.QueryCapability('volume.disc')
            #if "volume"
            if device.QueryCapability('volume') and not isCD:
                size =self.__getHumanReadableSize(device.GetProperty('volume.size'))
                label = device.GetProperty('volume.label')
                if len(label) < 1:
                    label = device.GetProperty('volume.fsversion')
                message += "Volume connected: label is " + label + ", Total size "+ size
		#device.Mount(label,"rw");
		uuid = device.GetProperty('volume.uuid')
		uuid = uuid.replace("-","_")
                vol = self.__bus.get_object('org.freedesktop.Hal', '/org/freedesktop/Hal/devices/volume_uuid_' + uuid)
                vol.Mount("", device.GetProperty('volume.fstype'), '', dbus_interface="org.freedesktop.Hal.Device.Volume")
		mpoint = device.GetProperty('volume.mount_point')
		self.exec_line = self.handler_script + " " + mpoint + " " + label + " " +uuid
		print mpoint
            # if CD or dvd
            if isCD:
                label = ""
                if device.GetProperty('volume.disc.has_audio'):
                    label += " audio "
                if device.GetProperty('volume.disc.is_blank'):
                    label += " empty "
                label += device.GetProperty('volume.disc.type') + " "
                label += device.GetProperty('volume.label')
                message += label + " disk"
            #if storage
            elif device.QueryCapability('storage'):
                message += 'Device connection detected: '
                message += self.__getDeviceName(device) + " storage"
            #это должно быть саммы последним!            
	    elif (device.PropertyExists('linux.subsystem')
                    and (device.GetProperty('linux.subsystem') == 'usb')) :
                category = device.GetProperty('info.category')
                devName = self.__getDeviceName(device)
                message += devName + " " + category
        return message

    # in uint64!
    def __getHumanReadableSize(self, size):
        dim = int(math.log(size, 1024))
        result = {
            0 : lambda x: str(x) + ' bytes',
            1 : lambda x: str(int(x/1024+0.5)) + ' kilobytes',
            2 : lambda x: str(int(x/1.048576e6+0.5)) + ' megabytes',
            3 : lambda x: str(int(x/1.073741824e9+0.5)) + ' gigabytes'
            }[dim](size)
        return result

    def __getDeviceName(self, device):
        result = ""
        if device.PropertyExists('info.vendor'):
            result = device.GetProperty('info.vendor') + " "
        if device.PropertyExists('info.product'):
            result += device.GetProperty('info.product')
        else:
            result += "unknown"
        return result

    def __say(self, text):
        #pipe = os.popen('espeak -vmb/mb-fr4-en -s 150 -a 100','w')
	pipe = os.popen('lsay \'' + text+ '\'','w')
        print text
        #pipe.write(text)
        pipe.close()

    def __del__ (self):
        self.__bus.close()


dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)

ec = EventCommenter()

mainloop = gobject.MainLoop()
mainloop.run()


pipe = os.popen('lsay \'' + text+ '\'','w') - это команда синтеза. У меня работает свой кавайный враппер на сях вокруг сепстраловского синтеза, который мало того что в альзу пишет, но еще и выдает амплитуду на светодиоды подрубленные к LPT через особый светодиодный интерфейс, написанный месяцем ранее со скуки. Ничего не мешает использовать espeak, но качество синтеза там как из толчка.

self.handler_script = "/home/aifiltr0/.config/notifier/storage_handler.sh" - рекомендую поменять, у Вас он в другом месте лежать могет. Это башевский хендлер, который и выполняет грязную работу. Можно было и на питоне все оставить, да вот я с ним не особо дружу, да и не хочется особо изучать его, так что лучше пусть на баше скрипты вызывает, он мне как-то ближе да и лучше он для задач типа "скопируй", "снеси".

Ему кидаем 3 аргумента: точку монтирования носителя, лейбл носителя и ууид, чтобы оно смогло узнать с чем мы работаем и вести себя адекватно.  Вот так выглядит мой баш хендлер:

#!/bin/bash
MPOINT=$1
LABEL=$2
UUID=$3
export MPOINT
export LABEL
export UUID
cd /home/aifiltr0/.config/notifier/stg_handlers.d
for file in `ls`; do
. $file
done;

Ну а в stg_handlers.d индивидуальные хендлеры типа снесика мне с vfat флешки троян, пропарсив autorun.inf (компы с виндой в общедоступном месте с интернетом в инсте - зло!), фотки там скопирни и так далее.

Выглядит это со стороны примерно так:

Comments

4 responses to “Изба говорильня + автомаунт + хэндлер”

  1. ffsdmad Avatar

    Интересно, а кто же всё таки генерирует звук?

  2. Necromant Avatar
    Necromant

    цепстраловский проприетарный синтез. Увы, но единственное неблевотное что есть. новая версия поделия – см свежий пост.

  3. ffsdmad Avatar

    дак выкладывал бы пруф на эту проприетарщину
    и ещё, рутуб для гиковидео фу, я столько лет не видел рекламы прокладок, а ты всё испортил

  4. Necromant Avatar
    Necromant

    http://cepstral.com – если не изменяет память. Синтез тамошний. А рутуб потом вырежу, как не поленюсь сюда флеш плеер прикрутить. А планах вообще с вордпресса переехать на самописную цмську на сях.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.