File:  [Coherent Logic Development] / ChivanetModcon / modcon
Revision 1.3: download - view: text, annotated - select for diffs
Fri Jan 31 15:39:06 2025 UTC (2 months ago) by snw
Branches: MAIN
CVS tags: HEAD
Minor fixes

#!/usr/bin/env perl

#
# ChivaNet Moderator Console
#  Copyright (C) 2025 Coherent Logic Development LLC
#
# $Id: modcon,v 1.3 2025/01/31 15:39:06 snw Exp $
#
# Author: Serena Willis <snw@coherent-logic.com>
#
# Licensed AGPL-3.0
#
# $Log: modcon,v $
# Revision 1.3  2025/01/31 15:39:06  snw
# Minor fixes
#
# Revision 1.2  2025/01/31 13:38:51  snw
# Initial basic functions working
#
# Revision 1.1.1.1  2025/01/30 19:16:06  snw
# Initial commit
#
#

use REST::Client;
use JSON;
use Getopt::Long;
use Data::Dumper;
use Term::ReadKey;

my $rasurl = '';
my $apikey = '';
my $online = 0;
my $modcon_version = '0.0.1';
my $cnclient = '';
my $rasclient = '';
my $wchar = '';
my $hchar = '';
my $wpixels = '';
my $hpixels = '';
my $account = '';

sub list_sso_users {
    $cnclient->GET("/chivanet/users");
    my $ct = 0;
    
    my $json = $cnclient->responseContent();
    my $hashref = decode_json($json);

    if($hashref->{ok} == 1) {
        my $arrayref = $hashref->{users};
        my @users = sort(@{$arrayref});
        
        foreach my $user (@users) {
            print "$user\n";
            $ct = $ct + 1;

            if($ct > $hchar - 2) {
                print "ENTER to continue, Q to quit...";
                my $resp = <STDIN>;
                chomp($resp);
                if($resp eq "Q") {
                    return;
                }
                elsif($resp eq "q") {
                    return;
                }
                $ct = 0;
            }
        }
    }
    else {
        print "RPC error\n";
    }
}

sub list_ras_users {

}

sub select_sso_user {
    my($id) = @_;

    $cnclient->GET("/chivanet/validate_user?id=$id");
    my $json = $cnclient->responseContent();
    my $hashref = decode_json($json);
    
    if($hashref->{exists} == 1) {

        $cnclient->GET("/chivanet/user?id=$id");
        my $json = $cnclient->responseContent();
        $account = decode_json($json);
        
        return $id;
    }
    else {
        print ">>> invalid SSO user $id [$hashref->{error}]\n";
        return "---";
    }            
}

sub select_ras_user {
    my($id) = @_;

    $cnclient->GET("/chivanet/validate_sn?id=$id");
    my $json = $cnclient->responseContent();
    my $hashref = decode_json($json);

    if($hashref->{exists} == 1) {
        return $id;
    }
    else {
        print ">>> invalid RAS screen name $id\n";
        return "---";
    }
}

sub trace_ras_sn {
    my($user) = @_;
    
    $cnclient->GET("/chivanet/trace_sn?id=$user");
    my $json = $cnclient->responseContent();
    my $hashref = decode_json($json);
    my $record = $hashref->{account};
    my $result = $record->{id};
    
    print "RAS screen name $user belongs to SSO account $result; switching to SSO mode\n";
    return $result;   
}

sub list_ras_sessions {
    $cnclient->GET("/chivanet/ras_sessions");
    my $json = $cnclient->responseContent();
    my $hashref = decode_json($json);
    my $sessions = $hashref->{sessions};
    my $arrayref = $sessions->{sessions};
    my $ct = 0;
    
    foreach my $session (@{$arrayref}) {
        print "$session->{screen_name}\n";

        $ct = $ct + 1;

        if($ct > $hchar - 2) {
            print "ENTER to continue, Q to quit...";
            my $resp = <STDIN>;
            chomp($resp);
            if($resp eq "Q") {
                return;
            }
            elsif($resp eq "q") {
                return;
            }
            $ct = 0;
        }
    }
    
    print "$sessions->{count} current sessions\n";    
}

sub list_ras_screennames {
    my($id) = @_;
    
    $cnclient->GET("/chivanet/ras_screen_names?id=$id");

    my $json = $cnclient->responseContent();
    my $hashref = decode_json($json);
    my $arrayref = $hashref->{screen_names};
    my $ct = 0;
    my $total = 0;

    print "\n";
    
    foreach my $sn (@{$arrayref}) {
        my $name = "$sn->{screen_name}\n";
        chomp($name);

        my $bot = '';
        my $public = '';
        
        if($sn->{bot_sn} eq 1) {
            $bot = "bot";
        }
        else {
            $bot = "human";
        }

        if($sn->{public_sn} eq 1) {
            $public = "public";
        }
        else {
            $public = "unlisted";
        }

        print "$name:  $public $bot; created $sn->{create_ts}\n";
        
        $ct = $ct + 1;
        $total = $total + 1;
        
        if($ct > $hchar - 2) {
            print "ENTER to continue, Q to quit...";
            my $resp = <STDIN>;
            chomp($resp);
            if($resp eq "Q") {
                return;
            }
            elsif($resp eq "q") {
                return;
            }
            $ct = 0;
        }
    }

    print "\nSSO user $id has $total screen names\n\n";

}

sub print_sso_user {
    my $act = $account->{account};

    print "\n";
    print "Username          :  $act->{id}\n";
    print "Real Name         :  $act->{last_name}, $act->{first_name}\n";
    print "Display Name      :  $act->{display_name}\n";
    print "Pronouns          :  $act->{pronouns}\n";
    print "Profile Image     :  https://chivanet.org$act->{profile_photo}\n";        
    print "E-Mail Address    :  $act->{email}\n";
    print "Permission Level  :  $act->{perm_level}\n";
    print "Created           :  $act->{create_ts}\n";
    print "Banned            :  $act->{mod_banned}\n\n";
}

sub print_ras_user {
    my($id) = @_;

    $cnclient->GET("/chivanet/sn_status?id=$id");
    my $json = $cnclient->responseContent();
    my $hashref = decode_json($json);
    my $status = $hashref->{status};
    my $online = "offline";
    
    if($status->{online} == 1) {        
        $online = "online";        
    }
    
    print "\n";


    if($online eq "online") {
        my $sess = $status->{session};
        my $service = 'AIM';
        
        if($sess->{is_icq} == 1) {
            $service = 'ICQ';
        }

        if($sess->{idle_seconds} > 0) {
            $online = "idle";
        }
        
        print "Screen Name       :  $id [$online]\n";
        print "Service           :  $service\n";
        if($online eq "online") {
            print "Time Online (secs):  $sess->{online_seconds}\n";
        }
        else {
            print "Time Idle (secs)  :  $sess->{idle_seconds}\n";
        }
        print "Away Message      :  $sess->{away_message}\n\n";
    }
    else {
        print "Screen Name       :  $id [$online]\n\n";
    }
    
#    print Dumper($status);
    
}

sub send_im {
    my($user, $msgbody) = @_;

    print "sending message \"$msgbody\" to $user...";   
    
    my $msg = "<font color=red><strong>[ChivaNet Support]:</strong></font> $msgbody";
    
    $cnclient->GET("/chivanet/send_im?from=ChivaNet&to=$user&message=$msg");
    my $json = $cnclient->responseContent();
    my $hashref = decode_json($json);
    
    if($hashref->{status} == 1) {
        print "[OK]\n";
    }
    else {
        print "[FAIL]\n";
    }
}

sub prompt {
    
    my $rawcmd = '';
    my $mode = '---';
    my $user = '---';

    while (1) {
        print "MODCON [$mode/$user]> ";
        my $line = <STDIN>;
        chomp($line);
        $rawcmd = $line;
        
        my @cmd = split(' ', $rawcmd);
        
        if ($cmd[0] eq "quit") {
            return;
        }
        elsif ($cmd[0] eq "mode") {
            if($cmd[1] eq "sso") {
                $mode = "SSO";
                $user = "---";
                $account = '';
            }
            elsif ($cmd[1] eq "ras") {
                $mode = "RAS";
                $user = "---";
                $account = '';
            }
            else {
                print "?\n";
            }
        }
        elsif ($cmd[0] eq "select") {
            if($cmd[1] eq "user") {
                if($mode eq "SSO") {
                    $user = select_sso_user($cmd[2]);                    
                    chomp($user);
                    print_sso_user;
                }
                elsif($mode eq "RAS") {
                    $user = select_ras_user($cmd[2]);
                    chomp($user);
                    print_ras_user $user;
                }
                else {
                    print "?\n";
                }
            }            
            else {
                print "?\n";
            }
        }
        elsif ($cmd[0] eq "im") {
            if($mode eq "RAS") {
                if($user ne "---") {
                    my @msga = @cmd[1..$#cmd];
                    my $msgbody = join(' ', @msga);                    
                    send_im($user, $msgbody);
                }
                else {
                    print "?\n";
                }
            }
            else {
                print "?\n";
            }
        }    
        elsif ($cmd[0] eq "trace") {
            if($mode eq "RAS") {
                if($user ne "---") {                    
                    my $id = trace_ras_sn($user);
                    $mode = "SSO";
                    $user = select_sso_user($id);
                    print_sso_user;
                }
                else {
                    print "?\n";
                }
            }
            else {
                print "?\n";
            }
        }
        elsif ($cmd[0] eq "field") {
            if($user ne "---") {
                my $act = $account->{account};
                print "$user\-\>$cmd[1]:  $act->{$cmd[1]}\n";
            }
            else {
                print "?\n";
            }
        }
        elsif ($cmd[0] eq "describe") {
            if($user ne "---") {
                if($mode eq "SSO") {
                    print_sso_user;
                }
                elsif($mode eq "RAS") {
                    print_ras_user($user);
                }                                
            }
            else {
                print "?\n";
            }
        }
        elsif ($cmd[0] eq "list") {
            if($cmd[1] eq "users") {
                if($mode eq "SSO") {
                    list_sso_users();
                }
                elsif($mode eq "RAS") {
                    list_ras_users();
                }
            }
            elsif($cmd[1] eq "sessions") {
                if($mode eq "RAS") {
                    list_ras_sessions();
                }
                else {
                    print "?\n";
                }
            }
            elsif($cmd[1] eq "sn") {
                if($mode eq "SSO") {
                    if($user ne "---") {
                        list_ras_screennames $user;
                    }
                    else {
                        print "?\n";
                    }
                }
                else {
                    print "?\n";
                }
            }
            else {
                print "?\n";
            }
        }
        else {
            print "?\n"
        }
    }

}

sub main {  
    GetOptions("rasurl=s" => \$rasurl,               
               "apikey=s" => \$apikey)
        or die("error in command line arguments");

    ($wchar, $hchar, $wpixels, $hpixels) = GetTerminalSize();
    
    $cnclient = REST::Client->new({
        host => 'https://chivanet.org/rest/api',
        timeout => 10});

    $cnclient->addHeader('Authorization', "Apikey $apikey");

    $rasclient = REST::Client->new({
        host => $rasurl,
        timeout => 10});    
    
    print "ChivaNet MODCON $modcon_version\n";
    print " Copyright (C) 2025 Coherent Logic Development LLC\n\n";
    
    prompt();
    print "Goodbye.\n"
}

main();

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>