Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

implement some prettyping-inspired display alongside textual data. #3

Closed
wants to merge 17 commits into
from

Conversation

Projects
None yet
4 participants
Contributor

anarcat commented Dec 4, 2013

this is a first stab at porting "prettyping.sh" into noping. the idea is to show a histogram of the ping history.

it is a little rough for now:

  • it should fallback when the terminal is not unicode-capable
  • the scaling logic is not fully automatic, which will degenerate (ie. all red or all green) in cases where the latency is close to 255 ms or 1ms with little stddev

this requires switching to the ncursesw library and other unicode ncurses hackery described in this post:

http://newsgroups.derkeiler.com/Archive/Rec/rec.games.roguelike.development/2010-09/msg00050.html

pretty ping is a awk/bash script, MIT-licensed, available here:

https://bitbucket.org/denilsonsa/small_scripts/src/tip/prettyping.sh

anarcat added some commits Dec 3, 2013

implement some prettyping-inspired display instead of textual
this is a first stab at porting "prettyping.sh" into noping. the idea
is to show a histogram of ping times instead of numerical values. with
some work, we could actually show both, but this focuses on
implementing the hard part (the histogram) properly.

it is very rudimentary for now:

 * the math may be wrong for the size of the bar, I was mostly in a
   rush to make unicode work and have something pretty quickly.

 * all hosts are on the same line: each should have its own line

 * the histogram should be displayed in a separate window

 * it should use background colors as well

 * it should fallback when the terminal is not unicode-capable

 * the scaling logic is fully automatic, which necessarily gives weird
   results at first

this requires switching to the ncursesw library and other unicode
ncurses hackery described in this post:

http://newsgroups.derkeiler.com/Archive/Rec/rec.games.roguelike.development/2010-09/msg00050.html

pretty ping is a awk/bash script, MIT-licensed, available here:

https://bitbucket.org/denilsonsa/small_scripts/src/tip/prettyping.sh
cleanup safety checks
make sure that if we go beyond the max ratio, we just mark it as one
rework scaling algorithm so it covers the whole range
i did this after some stress testing, now it covers the whole range on input
Contributor

anarcat commented Dec 4, 2013

Note that prettyping falls back to regular ASCII characters (_.oO) if unicode is disabled (on the commandline).

Now the questions are:

  1. how do we detect a unicode-capable terminal?
  2. if we can't, how do we disable/enable that feature? another noping binary? nopingu?
  3. what characters do we use in the fallback? _.oO is cute, but I am sure it could be improved with ncurses and ASCII escape codes...

For example, the following program:

#include <ncurses.h>
int main(void)
        {
        int counter;
        initscr();
        attron(A_UNDERLINE);
        mvprintw(0,7,"Progress bar testing\n\n");
        attroff(A_UNDERLINE);
        for (counter=115; counter >= 111; counter--)
          {
            addch(counter | A_ALTCHARSET);
          }
        refresh();
        getch();
        endwin();
        return 0;
        }

... outputs:

       Progress bar testing

⎽⎼─⎻⎺

It renders better on the terminal than here - it progresses actually quite nicely in 5 steps. Not bad!

More information:

Owner

octo commented Dec 4, 2013

  1. I've sent an email to my favorite terminal expert and CC'ed you. nl_langinfo(3) looks promising.
  2. I guess a command line argument would be best. People and / or distributions who want to have a different command can use aliases and stuff, though I doubt that this will be priority.
  3. I don't have a strong preference. I like you suggestions, both, the cute and the liney one ;) Code page 437 also has some suitable characters, although not as many as Unicode. No idea how portable / universal that would be.

Thanks again and best regards,
—octo

Contributor

anarcat commented Dec 4, 2013

Awesome, let's see what's the magic incantation then we can finish this. :) If you have pointers on how to name the commandline option, it would be appreciated. prettyping uses --unicode, but I feel we should assume unicode and have a flag to turn it off if necessary. so --nounicode / -n?

Owner

octo commented Dec 5, 2013

We're not using getopt_long for portability at the moment. I think a convention is to use upper case and lower case for boolean options, though not consistently: ssh -X enables X forwarding, -x disables it. ssh -t forces (enables) a TTY, -T prevents (disables) one … I'd prefer -u to mean "(force) use Unicode", -U to mean "disable Unicode" and neither to mean "automatically figure it out". Does that sound like a plan?

Contributor

anarcat commented Dec 5, 2013

sounds like a plan to me! now if we could only figure out how to auto-detect now ;)

Refactor the graph printing into its own function.
This makes it much easier and cleaner to add a second, non-Unicode
implementation and possibly even a non-color version.
Owner

octo commented Dec 5, 2013

Also, I just pushed an update to the ab/prettyping branch of my repository which does some refactoring of the code into its own function. I'd be great if you could merge or pick that into the PR.

Thanks :)
—octo

Contributor

anarcat commented Dec 6, 2013

About unicode detection, what do we have?

  • stackexchange suggests locale charmap which returns UTF-8 here

  • rosettacode suggests (basically) grepping LANG for utf (case insensitive)

  • ncurses mailing list says you need to import the user's locale (LC_ALL) and deal with it from there

  • POSIX seems to say we should use:

    #include <langinfo.h>
    char const *codeset = nl_langinfo (CODESET);
    

    then i guess we need to grep for utf there?

It's unclear what are the expectations (of ncurses?) here - do we expect a "unicode" or "utf-8" terminal? And if the locale is set, that's one thing, but it doesn't mean the terminal supports it.

But I guess we could assume that if the locale is set to unicode and the terminal doesn't support it, that's some serious foot-shooting from the user and failure is expected. That is my expectation is a unicode user anyways so far.

Contributor

anarcat commented Dec 6, 2013

Another note - from what I understand, ncurses itself relies on nl_getinfo() to detect the locale to display (say) unicode or borders properly. (I base this on the claim done by python.)

I am not sure what that means, but there you go. :)

Contributor

anarcat commented Dec 6, 2013

I added the refactoring in - one thing though: it seems now the code runs only if has_colors() - however, we could still display a (more limited) progressbar without colors, so I feel we should push that check further down the stack...

Contributor

anarcat commented Dec 6, 2013

Here's the unicode-detection code in ncurses:

/*
 * Check if we are running in a UTF-8 locale.
 */
NCURSES_EXPORT(int)
_nc_unicode_locale(void)
{
    int result = 0;
#if defined(__MINGW32__) && USE_WIDEC_SUPPORT
    result = 1;
#elif HAVE_LANGINFO_CODESET
    char *env = nl_langinfo(CODESET);
    result = !strcmp(env, "UTF-8");
    T(("_nc_unicode_locale(%s) ->%d", env, result));
#else
    char *env = _nc_get_locale();
    if (env != 0) {
    if (strstr(env, ".UTF-8") != 0) {
        result = 1;
        T(("_nc_unicode_locale(%s) ->%d", env, result));
    }
    }
#endif
    return result;
}

This function is used as such:

    sp->_screen_unicode = _nc_unicode_locale();

Maybe we can use that? the screen object doesn't seem accessible unfortunately...

autodetect unicode, and fallback to ACS scancodes on failure
this is fairly ugly - we use a hidden ncurses function to detect
unicode (but at least we don't reimplement it), then we mess around
with the character arrays to display the rights symbols

i am not sure i like this, but i prefer to braindump than to stall, so
let's move forward.
Contributor

anarcat commented Dec 6, 2013

alright, that commit (5901ec3) adds some crude autodetection magic (based on that hidden ncurses function, _nc_unicode_locale) and messes around with my rotten C brain to display the right thing.

we're just missing a commandline option now and we're good, although a second pair of eyes on that ugly mess I just pushed should be applied.

obligatory screenshot:

unset $LANG or $LC_ALL (or whatever env | grep -i utf tells you to) to test.

anarcat added some commits Dec 6, 2013

move unicode detection to a separate function
this will ease transition to a commandline option override
add commandline flag for forcing or disabling unicode
note that "forcing" may not work: ncurses still expects your locale to
be correct, so maybe the force flag should also explicitely set a utf8
locale?
Contributor

anarcat commented Dec 6, 2013

done for the night. :)

Florian Forster added some commits Dec 6, 2013

Contributor

anarcat commented Jan 21, 2014

Alright, so we now have a commandline option, proper toolchain hooks, everything seems to be in order and I use this in production on a daily basis. In fact, I have had this code (65e6e0f, to be more precise) running for over 7 days straight over 6 targets now, so I'd say it works well. :)

Can we merge this in already? The debian package already picked it up as well: http://packages.qa.debian.org/libo/liboping/news/20131226T164825Z.html :)

Contributor

anarcat commented Mar 6, 2014

ping?

Contributor

anarcat commented Mar 19, 2014

ping

@schweikert schweikert referenced this pull request in schweikert/fping May 27, 2014

Open

ncurses / "prettyping" feature #63

Contributor

anarcat commented Jun 4, 2014

can we get this show on the road? this is working now, i have ran the code in a test to multiple hosts until i rebooted my workstation, about a week ago - so basically 4 months, without a crash.

Contributor

anarcat commented Aug 7, 2014

ping

Any updates on this?

Owner

octo commented Sep 25, 2014

Sorry for losing track of this :\ I've just merged this to the master branch (4710e54) and will create a new liboping version soon now :)

Best regards,
—octo

@octo octo closed this Sep 25, 2014

Contributor

anarcat commented Sep 25, 2014

alas! thank you very much for this!

@anarcat anarcat deleted the anarcat:prettyping branch Sep 25, 2014

In case someone looks at this pull request someday in the future and finds broken links to prettyping, it is because it has a new homepage: https://github.com/denilsonsa/prettyping and http://denilsonsa.github.io/prettyping/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment