Наконец-то выкроил врем избавиться от старого костыля и приспособить новый.
В общем ТЗ: проговаривать качественным сепстраловским синтезом что за флешку мы воткнули, автомаунтить ее (кеды 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 (компы с виндой в общедоступном месте с интернетом в инсте - зло!), фотки там скопирни и так далее.
Выглядит это со стороны примерно так:
Leave a Reply