App-Ordo

 view release on metacpan or  search on metacpan

lib/App/Ordo.pm  view on Meta::CPAN

package App::Ordo;
use strict;
use warnings;
use feature qw(say);
use Moo;
use Exporter 'import';

use JSON qw(encode_json);
use File::Path qw(make_path);
use File::Copy qw(copy);
use File::ShareDir qw(dist_file);
use Term::ANSIColor qw(colored);
use Term::ReadLine::Perl5;
use Term::ReadKey qw(ReadMode ReadKey GetTerminalSize);
use Email::Valid;

use App::Ordo::API;

our @EXPORT_OK = qw(
    $CURRENT_PATH
    extract_command
    epoch_to_tminus
    epoch_to_duration
);

our $VERSION = '0.06';
our $CURRENT_PATH = '/';

has 'api' => (
    is => 'lazy',
    default => sub { App::Ordo::API->new },
);

# ------------------------------------------------------------------
# Session / Auth
# ------------------------------------------------------------------
sub ensure_session {
    my ($self) = @_;

    my $config = $self->api->config;
    my $token  = $config->{token} // '';

    my $res = $self->api->call('login_user', { token => $token });

    if ($res->{success}) {
        $CURRENT_PATH = $res->{path} // '/';
        say colored(["bold green"], "Connected to " . $self->api->config->{api} . " as $res->{email}");
        return $res;
    }

    say colored(["bold yellow"], "No valid token found");
    return $self->prompt_for_token;
}

sub prompt_for_token {
    my $self = shift;
    while (1) {
        print colored(["bold white"], "Enter API token: ");
        chomp(my $token = <STDIN>);
        $token =~ s/^\s+|\s+$//g;

        my $res = $self->api->call('login_user', { token => $token });

        if ($res->{success} && $res->{level} >= 1) {
            my $config = $self->api->config;
            $config->{token} = $token;
            open my $fh, '>', $self->api->config_file or die "Cannot save config: $!";
            print $fh encode_json($config);
            close $fh;
            $CURRENT_PATH = $res->{path} // '/';
            say colored(["bold green"], "Logged in successfully");
            return $res;
        }
        say colored(["bold red"], $res->{message} || "Invalid token");
    }
}

# ------------------------------------------------------------------
# Interactive Shell
# ------------------------------------------------------------------
sub run_interactive {
    my $self = shift;

    $self->ensure_session;

    my $term = Term::ReadLine::Perl5->new('ordo');

    say colored(["bold white"], "\nWelcome to Ordo - the hierarchical job scheduler");
    say "Type 'help' for commands, Ctrl-D to exit.\n";

    while (defined(my $line = $term->readline("ordo:$CURRENT_PATH> "))) {
        $line =~ s/^\s+|\s+$//g;
        next unless $line;
        my @args = extract_command($line);
        App::Ordo::Runner->new(api => $self->api)->run(@args);
    }

    say colored(["bold yellow"], "\nGoodbye!");
}

# ------------------------------------------------------------------
# Command line parsing
# ------------------------------------------------------------------
sub extract_command {
    my ($line) = @_;
    return () unless defined $line;
    my @args;
    my $current = '';
    my $in_quote = '';
    for my $char (split //, $line) {
        if ($in_quote) {
            $current .= $char;
            $in_quote = '' if $char eq $in_quote;
        } elsif ($char eq '"' || $char eq "'") {
            $in_quote = $char;



( run in 1.243 second using v1.01-cache-2.11-cpan-6aa56a78535 )