Simplest way to show user messages from an irc channel in a terminal - Servers Administration, Networking, & Virtualization
buttcake
I'm big on lurking and I'm thinking of using either ii or sic with tail while finding a way to get rid of non-user messages.
How would you guys go about it ?
z3bra
sic wont help you much, I'd rather go with ii + 'grep -v' pipeline
josuah
I really like ii and sic. What you can do is either an existing wrapper, or do your own out of existing components or from scratch.

I see 4 pieces for an ii or sic wrapper (may also apply for other tools as well):

-> Something to manage connection:
- type the commands by hand,
- a script that start all connections at once
- an interface (cli / tui...) that start and stop servers on demand
- do you want to handle disconnections

-> Something to manage the multiple channels
- for sic, this is a built-in feature (through multiplexing)
- for ii: do you want an interface that prompt a channel to join
- do you want to handle automatic joining

- > Something to handle the user input
- REPL-style client ? Read a line, send it to the channel, restart
- Keybindings of any kind to control the above ?
- Prevent input and output to be mixed: two different windows (tmux, window manager) or a single one...

... if you use "tail -f &" to display the messages and "while read line" to read the input, you will have an issue of the incoming message being printed at current cursor position: where you are currently writing. To avoid this, you can use 9term or acme, both provided in plan9port.

-> And then the goodies: pimp and rice the output: sed and awk are your friends.

I have this simple script that takes a channel directory as argument and read input from user.

You can bring line editing and separated input / outut with rlwrap, and calling your small-ish script like that:

Code:
stty -echo  # Do not print what I just wrote on screen, ii does it already

rlwrap ii-client  # open the client without raw input output but with line editing

stty sane  # reset the terminal

You can use it directly with sic: "$ rlwrap sic".
josuah
You can bring logs to sic with tee: "$ sic ... | tee -a <channel-name>" which will append logs to the file "<channel-name>".

And you can bring output multiplexing to ii with tail: "$ cd $IRC_DIR; tail -f */out */*/out". Then you will have messages from all channels, and you switch channel, the path to the channel will be displayed:

Code:
==> irc.freenode.net/#something/out <==
2017-05-22 23:24 <josuah> this is some channel
2017-05-22 23:25 <dude> oh, is it?

==> unix.chat/#unix/out <==
2017-05-22 23:26 <josuah> now THIS is a channel
2017-05-22 23:27 <dude> now I believe you

==> irc.freenode.net/#something/out <==
2017-05-22 23:29 <josuah> dude: are you 'dude' from #unix@unix.chat?

This is a standard tail feature. :)
josuah
And then come the fun part (4th piece): ricing ii output. What I like is that all consecutive messages from a single person get grouped, and that a newline gets added whenever the speaker change:

Sample output:

Code:
---------------------------------- 2017-05-20 ----------------------------------

23:38     person  I write a message
23:39             then another one, and it is added below, without repeating
                  the nick name.  And if it is too long, it gets wrapped,
                  without repeating the date

23:44       dude  I am another person, empty line gets added above.

23:46        -!-  someone(~user@somewhere) has joined #unix
23:48             other-dude(~user@somewhere.else) has joined #unix

23:56       dude  whoops!
23:57             close to a new day!

---------------------------------- 2017-05-20 ----------------------------------

00:01       dude  Yup! The day is over.  Long life to the day!

The source of the ii wrapper: it takes input from stdin and spat it out as it comes:
Code:
# http://tools.suckless.org/ii

awk '

BEGIN {
    WIDTH = 80 - 17;
}

{
    last = date;
    date = $1;
}

date != last {
    printf("----------------------------------");
    printf(" %s ", date);
    printf("----------------------------------\n")
}

{
    if ($3 ~ "<.*>" || $3 ~ "-!-") {
        sub("<", "", $3);
        sub(">", "", $3);

        if (nick != $3) {
            printf("\n");
            printf("%s %10s  ", $2, $3);
            nick = $3;
        } else {
            printf("%s %10s  ", $2, "");
        }

        sub("[^ ]* [^ ]* [^ ]* ", "");

    } else {
        printf("%s %10s  ", $2, "");
        sub("[^ ]* [^ ]* ", "");
    }

    sub("^\001ACTION ", "~~ ");
    sub("\001$", " ~~");

    for (offset = 0; length($0) > 0; offset = 18) {
        row = substr($0, 1, WIDTH);

        if (length(row) >= WIDTH)
            sub(" [^ ]*$", "", row);

        $0 = substr($0, length(row) + 1);
        sub(" *", "");

        printf("%" offset "s%s\n", "", row);
    }
}'
josuah
Well, this was not exactly what you asked for, sorry. But this looked like the beginning on an ii/sic thread, so I jumped in the train.

Code:
# http://tools.suckless.org/ii

awk '

BEGIN {
    WIDTH = 80 - 17;
}
$3 ~ "-!-" {
    next;
}

{
    last = date;
    date = $1;
}

date != last {
    printf("----------------------------------");
    printf(" %s ", date);
    printf("----------------------------------\n")
}

{
    if ($3 ~ "<.*>") {
        sub("<", "", $3);
        sub(">", "", $3);

        if (nick != $3) {
            printf("\n");
            printf("%s %10s  ", $2, $3);
            nick = $3;
        } else {
            printf("%s %10s  ", $2, "");
        }

        sub("[^ ]* [^ ]* [^ ]* ", "");

    } else {
        printf("%s %10s  ", $2, "");
        sub("[^ ]* [^ ]* ", "");
    }

    sub("^\001ACTION ", "~~ ");
    sub("\001$", " ~~");

    for (offset = 0; length($0) > 0; offset = 18) {
        row = substr($0, 1, WIDTH);

        if (length(row) >= WIDTH)
            sub(" [^ ]*$", "", row);

        $0 = substr($0, length(row) + 1);
        sub(" *", "");

        printf("%" offset "s%s\n", "", row);
    }
}'

This does the same, but without non-user messages.
buttcake
I've had a lot to do these days but I feel bad for not saying something after this abundance of information. Thank you.
For what it's worth what I was trying to do was really really simple, something like:

$ thinggy
(quietly connect to channel #x on network y with some some random info)
(starts displaying only user messages with a history limit of say, something like 60)

I don't need user input or managing multiple channels, I just wanted it as simple technologically as possible to he point where I was considering writing my own pseudo irc client because I don't really need much functionality. I know this is stupid since there are already a lot of tools out there but it's an itch I want to scratch.
josuah
buttcake: I write too much... :-P

You can give this a try:

Code:
ii -s irc.freenode.net &
sleep 3 && printf '/j #%s\n' "$2" > "$HOME/irc/$1/in"
sleep 1 && cd "$HOME/$1/#$2" && less out

Let call it iic or anything. Then you can do "iic unix.chat unix"

This open the output buffer in less. Thn to make it scrolling as message come, press 'F'. To write a message, press 'Ctrl + C' then '!echo message > in', then 'F' again.




Members  |  Stats  |  Night Mode