SSH üzerinden sesli bildirim


13

Konversation IRC istemcisinden terminal tabanlı IRSSI'ya geçtim. IRSSI'yı GNU ekran + SSH kullanarak uzak bir makinede başlatıyorum. Yeni mesajlarla ilgili herhangi bir sesli bildirim almıyorum, bu da yeni mesajlar için IRSSI'ya arada bir bakmam gerektiği anlamına geliyor.

Bu gerçekten üretken değil, bu yüzden /usr/share/sounds/KDE-Im-Irc-Event.oggherhangi bir etkinlik varsa makinemde bir ses (tercihen sinir bozucu bip sesi değil) çalan bir uygulama / komut dosyası arıyorum . Belirli kanallar için bildirimi devre dışı bırakabilirsem harika olur.

Veya, bu mümkün değilse, bir tür bildirim yoluyla libnotifyGNOME ve KDE için kullanılabilir hale getirir.

Yanıtlar:


10

Libnotify'ı sevmedim, bu yüzden Python'da bir UDP sunucusu ve irssi için bir istemci uygulaması oluşturdum. Bu yanıtın düzeltme 1'deki orijinal gereksinimler için geçerli olduğunu ve metin bildirimi olmadığını unutmayın.

müşteri

Bu sürüm size yönelik çeşitli mesajlara tepki verir. Herhangi bir kanaldaki mesajlardan haberdar olmak istiyorsanız #, #'message public'satırın başını kaldırın . Bazı hız sınırlamaları uygulanır, bildirimler arasında en az 1,3 saniye gecikme olur.

##
## Put me in ~/.irssi/scripts, and then execute the following in irssi:
##
##       /load perl
##       /script load notifyudp
##

use strict;
use Irssi;
use IO::Socket;
use vars qw($VERSION %IRSSI);
use Time::HiRes qw(time);

$VERSION = "0.3.20140930";
%IRSSI = (
    authors     => 'Lekensteyn',
    contact     => 'lekensteyn@gmail.com',
    name        => 'notifyudp.pl',
    description => 'Send a UDP signal to a remote machine',
    license     => 'GPLv3+'
);

Irssi::settings_add_str('notifyudp', 'notifyudp_ip_addr', '');
# port 0 = disabled
Irssi::settings_add_int('notifyudp', 'notifyudp_port', 0);
Irssi::settings_add_bool('notifyudp', 'notifyudp_auto_start', 0);

my $sock;

sub notify_load {
    if ($sock) {
        Irssi::print('NotifyUDP: Already connected.');
        return;
    }
    my $ip = Irssi::settings_get_str('notifyudp_ip_addr');
    my $port = Irssi::settings_get_int('notifyudp_port');
    if (!$port || !$ip) {
        Irssi::print('NotifyUDP: No port or host set, /set notifyudp for more information..');
        return;
    }
    if ($port < 1024 || $port > 65535) {
        Irssi::print('NotifyUDP: Invalid port, must be 1024 <= port <= 65535, resetting and ignoring.');
        Irssi::settings_set_int('notifyudp_port', 0);
        return;
    }
    $sock = new IO::Socket::INET(
        PeerAddr => $ip,
        PeerPort => $port,
        Proto => 'udp',
        Timeout => 1
    );
    Irssi::print("NotifyUDP: IP $ip will be notified on port $port.");
}

my $last_time = 0;
sub notify {
    if ($sock) {
        my $now = time;
        my $notify_delay = 1.3;
        if (abs($now - $last_time) > $notify_delay) {
            $last_time = $now;
            $sock->send("M");
        }
    }
}
sub notify_if_hilighted {
    my ($dest, $text, $stripped) = @_;
    if ($dest->{level} & MSGLEVEL_HILIGHT) {
        notify();
    }
}

sub notify_stop {
    if ($sock) {
        Irssi::print("NotifyUDP: Stopping.");
        $sock->send("S");
        $sock = undef;
    } else {
        Irssi::print("NotifyUDP: not active.");
    }
}

sub cmd_notifyudp {
    my ($cmd) = @_;
    if ($cmd eq 'start') {
        notify_load();
    } elsif ($cmd eq 'stop') {
        notify_stop();
    } elsif ($cmd eq 'ping') {
        notify();
    } else {
        Irssi::print('NotifyUDP: Usage: /notifyudp [start|stop|ping]');
    }
}

Irssi::command_bind('notifyudp', 'cmd_notifyudp');

my @signals = (
# Uncomment the following to get notifs for every (channel) message
#'message public',
'message private',
'dcc request',

'message irc notice', # NickServ responses and such

# whenever the server dies
'server connected',
'server connect failed',
'server disconnected',

'message invite',
'message topic',
'message dcc',
'ctcp msg',
'ctcp reply',
);
Irssi::signal_add('print text', 'notify_if_hilighted');
foreach (@signals) {
    Irssi::signal_add($_, 'notify');
}

if (Irssi::settings_get_bool('notifyudp_auto_start')) {
    Irssi::print('NotifyUDP: automatic connection with the sound server is enabled.');
    notify_load();
} else {
    Irssi::print('NotifyUDP: automatic connection with the sound server is disabled.');
}

Sunucu

Başladığımda bir UDP paket "M", bu oynar alırsa, tüm adresleri port 3533. dinler /usr/share/sounds/KDE-Im-Irc-Event.oggkullanarak paplay( "PulseAudio'nun oyun"). Alma Ssırasında sunucudan çıkar. Açık kaynak olduğundan, bunu kaldırmakta özgürsünüz.

#!/usr/bin/env python
# udpsoundserver.py

"""Listen on a UDP port and play a sound when 'M' is received

Starts the server listening on UDP port PORT (3533 by default) on address HOST
(by default all addresses). Valid commands are:
M - play Music
S - Stop the server
"""
try:
    import socketserver
except ImportError:
    import SocketServer as socketserver
from os import system,getpid
import threading
import sys

# leave it empty to listen on all addresses
HOST = ""
PORT = 3533


class UDPSvr(socketserver.BaseRequestHandler):
    def handle(self):
        data = self.request[0]
        if sys.version >= '3':
            data = str(data, "ISO-8859-1")
        data = data.strip()
        if data == "M":
            ding.dong()
        elif data == "S":
            ding.die()

class Worker(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
        self.daemon = True
    def run(self):
        server.serve_forever();

class Handler(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
        self.daemon = True
        self.play = False
        self.must_die = False

    def run(self):
        self.event = threading.Event()
        while True:
            self.event.wait(1.)
            if self.event.isSet():
                if self.play:
                    print("Playing...")
                    system("paplay /usr/share/sounds/KDE-Im-Irc-Event.ogg")
                # no else if to allow shutdown signals 
                if self.must_die:
                    print("Shutting down...")
                    server.shutdown()
                    break
                self.play = False
                self.event.clear()

    def dong(self):
        self.play = True
        self.event.set()

    def die(self):
        self.must_die = True
        self.event.set()

def ca(num, x):
    print("Caught SIGINT, shutting down...")
    ding.die()

import signal
if __name__ == "__main__":
    print("My PID is: " + str(getpid()))

    if len(sys.argv) > 1:
        HOST = sys.argv[1]
    if len(sys.argv) > 2:
        PORT = int(sys.argv[2])

    print("Host: " + HOST)
    print("Port: " + str(PORT))
    server = socketserver.UDPServer((HOST, PORT), UDPSvr)

    ding = Handler()
    signal.signal(signal.SIGINT, ca)
    worker = Worker()
    ding.start()
    worker.start()
    # might not be the cleanest, but it allows Ctrl + C
    while ding.isAlive():
        ding.join(3600)

Uzak sunucuyu başlatma sırası şu hale gelir:

screen -dm path/to/udpsoundserver.py
ssh -R 5355:localhost:5355

Giriş yaptıktan sonra çalıştırıyorum:

screen -t irssi irssi

Daha sonra tekrar bağlanmanız gerekirse:

screen -r irssi

Başladıktan sonra irssi, ana bilgisayarı ve bağlantı noktasını ayarlamanız gerekir:

/set notifyudp_ip_addr 127.0.0.1
/set notifyudp_port 5355

Başlangıçta otomatik olarak bağlanmasını sağlamak için:

/set notifyudp_auto_start 1

İlk kez, henüz otomatik başlatılmadığı için UDP'ye Bildir'i manuel olarak başlatmanız gerekir:

/notifyudp start

Bildirimi test etmek için:

/notifyudp ping

Yapmak:

  • ses sunucusunun bağlantı kesildiğinde durmasını sağlayın
  • kanal atlamaya izin ver

Metin göstergesinin bir gereklilik olmadığını söylediniz - kelime öbeği güzel olacağını ima etti, ancak tercih edilen seçenek değildi. Düzenleme için özür dilerim ve isterseniz geri alabilirsiniz.
jrg

Sorun değil, alternatiflere sahip olmak güzel. Benim çözümüm birlikte söylediğim gibi, bu yüzden cevabınız denemeye değer olabilir.
Lekensteyn

7

Bunu libnotify ile yapıyorum. Bulduğum bu yaştan önce.

Bir şampiyon gibi çalışır. Bunu linux üzerinde libnotify ile kullanıyordum (ve hala bir linux makinesindeyken yapıyorum) ama çoğu zaman şimdi bir macbook'tayım, bu yüzden mac üzerinde libnotify yerine growl kullanıyorum.

# todo: grap topic changes

use strict;
use vars qw($VERSION %IRSSI);

use Irssi;
$VERSION = '0.0.3';
%IRSSI = (
    authors     => 'Thorsten Leemhuis',
    contact     => 'fedora@leemhuis.info',
    name        => 'fnotify',
    description => 'Write a notification to a file that shows who is talking to you in which channel.',
    url         => 'http://www.leemhuis.info/files/fnotify/',
    license     => 'GNU General Public License',
    changed     => '$Date: 2007-01-13 12:00:00 +0100 (Sat, 13 Jan 2007) $'
);

#--------------------------------------------------------------------
# In parts based on knotify.pl 0.1.1 by Hugo Haas
# http://larve.net/people/hugo/2005/01/knotify.pl
# which is based on osd.pl 0.3.3 by Jeroen Coekaerts, Koenraad Heijlen
# http://www.irssi.org/scripts/scripts/osd.pl
#
# Other parts based on notify.pl from Luke Macken
# http://fedora.feedjack.org/user/918/
#
#--------------------------------------------------------------------

#--------------------------------------------------------------------
# Private message parsing
#--------------------------------------------------------------------

sub priv_msg {
    my ($server,$msg,$nick,$address,$target) = @_;
    filewrite($nick." " .$msg );
}

#--------------------------------------------------------------------
# Printing hilight's
#--------------------------------------------------------------------

sub hilight {
    my ($dest, $text, $stripped) = @_;
    if ($dest->{level} & MSGLEVEL_HILIGHT) {
    filewrite($dest->{target}. " " .$stripped );
    }
}

#--------------------------------------------------------------------
# The actual printing
#--------------------------------------------------------------------

sub filewrite {
    my ($text) = @_;
    # FIXME: there is probably a better way to get the irssi-dir...
        open(FILE,">>$ENV{HOME}/.irssi/fnotify");
    print FILE $text . "\n";
        close (FILE);
}

#--------------------------------------------------------------------
# Irssi::signal_add_last / Irssi::command_bind
#--------------------------------------------------------------------

Irssi::signal_add_last("message private", "priv_msg");
Irssi::signal_add_last("print text", "hilight");

#- end

Yüklemek irssiiçin aşağıdakileri çalıştırın:

/load perl

/script load fnotify

Ardından, yönlendirilmesini sağlamalıyız libnotify. Bunu yapmak için aşağıdakileri kabuk komut dosyası olarak kaydedin ve oturum açtığınızda çalıştırın:

# yes, we need a way to flush the file on disconnect; i don't know one
# yes, that's flush is not atomic (but good enough for me)
ssh remote.system.somewhere "tail -n 10 .irssi/fnotify ; : > .irssi/fnotify ; tail -f .irssi/fnotify " | sed -u 's/[<@&]//g' | while read heading message  do  notify-send -i gtk-dialog-info -t 300000 -- "${heading}" "${message}"; done # the sed -u 's/[<@&]//g' is needed as those characters might confuse  notify-send (FIXME: is that a bug or a feature?)

Topal GROWLer. ;) Bir bakacağım.
jrg

Bunu daha sonra kontrol edeceğim, bu QI'yi gönderdikten bir gün sonra birlikte kullandığım bir perl ve python betiğini hackledi.
Lekensteyn
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.