Thông báo âm thanh qua SSH


12

Tôi vừa chuyển từ máy khách IRC của Konversation sang IRSSI dựa trên thiết bị đầu cuối. Tôi đang bắt đầu IRSSI trên một máy từ xa bằng màn hình GNU + SSH. Tôi không nhận được bất kỳ thông báo âm thanh nào về các tin nhắn mới, điều đó có nghĩa là tôi sẽ kiểm tra IRSSI một lần trong một thời gian cho các tin nhắn mới.

Điều đó không thực sự hiệu quả, vì vậy tôi đang tìm kiếm một ứng dụng / tập lệnh phát âm thanh (tốt nhất /usr/share/sounds/KDE-Im-Irc-Event.oggvà không phải là tiếng bíp khó chịu) trên máy của tôi nếu có bất kỳ hoạt động nào. Sẽ thật tuyệt nếu tôi có thể tắt thông báo cho một số kênh nhất định.

Hoặc, nếu điều đó là không thể, một số loại thông báo thông qua libnotify, do đó làm cho nó có sẵn cho Gnome và KDE.

Câu trả lời:


9

Tôi không thích libnotify, vì vậy tôi đã tạo một máy chủ UDP bằng Python và một ứng dụng khách cho irssi. Lưu ý rằng câu trả lời này áp dụng cho các yêu cầu ban đầu trong phiên bản 1 , nó không có thông báo văn bản.

Khách hàng

Phiên bản này phản ứng với các tin nhắn khác nhau hướng vào bạn. Nếu bạn muốn được thông báo về các tin nhắn trong bất kỳ kênh nào, hãy xóa phần đầu #trong #'message public'dòng. Một số giới hạn tốc độ được thực hiện, sẽ có ít nhất 1,3 giây chậm trễ giữa các thông báo.

##
## 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.');
}

Người phục vụ

Khi bắt đầu, nó lắng nghe trên tất cả các địa chỉ, cổng 3533. Nếu nhận được gói UDP "M", nó sẽ phát /usr/share/sounds/KDE-Im-Irc-Event.oggbằng cách sử dụng paplay("PulseAudio play"). Khi nhận S, nó thoát khỏi máy chủ. Vì nó là nguồn mở, bạn có thể loại bỏ điều này.

#!/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)

Trình tự khởi động máy chủ từ xa trở thành:

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

Sau khi đăng nhập, tôi chạy:

screen -t irssi irssi

Nếu bạn cần kết nối lại sau:

screen -r irssi

Sau khi bắt đầu irssi, bạn cần đặt máy chủ và cổng:

/set notifyudp_ip_addr 127.0.0.1
/set notifyudp_port 5355

Để làm cho nó kết nối tự động khi khởi động:

/set notifyudp_auto_start 1

Lần đầu tiên, bạn cần bắt đầu Thông báo UDP theo cách thủ công vì nó chưa tự động bắt đầu:

/notifyudp start

Để kiểm tra thông báo:

/notifyudp ping

Làm:

  • làm cho máy chủ âm thanh dừng lại khi ngắt kết nối
  • cho phép bỏ qua các kênh

Bạn nói rằng chỉ báo văn bản không phải là một yêu cầu - cụm từ ngụ ý rằng nó sẽ tốt, nhưng không phải là tùy chọn ưa thích. Tôi xin lỗi vì đã chỉnh sửa và bạn có thể khôi phục lại nếu muốn.
năm11

Không có vấn đề, thật tốt khi có những lựa chọn thay thế. Giải pháp của tôi là như tôi đã nói đã hack cùng nhau, vì vậy câu trả lời của bạn có thể đáng để thử.
Lekensteyn

7

Tôi làm điều này với libnotify. Tôi tìm thấy điều này từ lâu.

Nó hoạt động như một nhà vô địch. Tôi đã từng sử dụng nó với libnotify trên linux (và vẫn làm khi tôi sử dụng máy linux) nhưng hiện tại tôi đang sử dụng macbook, vì vậy tôi sử dụng tiếng gầm để thay thế cho libnotify trên mac.

# 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

Để tải nó vào irssi, hãy chạy như sau:

/load perl

/script load fnotify

Sau đó, chúng ta cần phải chuyển nó đến libnotify. Để làm điều đó, hãy lưu đoạn dưới đây dưới dạng tập lệnh shell và chạy nó khi đăng nhập:

# 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?)

LOW GROWLer. ;) Tôi sẽ xem qua một chút.
JRG

Tôi sẽ kiểm tra điều này sau, một ngày sau khi đăng QI này đã hack một tập lệnh perl và python mà tôi đã sử dụng sau đó.
Lekensteyn
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.