CallBackery

 view release on metacpan or  search on metacpan

lib/CallBackery/GuiPlugin/Abstract.pm  view on Meta::CPAN

package CallBackery::GuiPlugin::Abstract;
use strict;
use warnings;
use Carp qw(carp croak);
use Storable qw(dclone);
use Data::Dumper;
use Mojo::Template;
use Mojo::Util qw(monkey_patch);
use CallBackery::Exception qw(mkerror);
use autodie;
use Scalar::Util 'blessed';
use IPC::Open3;
use POSIX qw<F_SETFD F_GETFD FD_CLOEXEC>;
use Time::HiRes qw(usleep);
use Mojo::JSON qw(encode_json decode_json true false);
use Mojo::File;
use Scalar::Util 'weaken';
# disable warnings below, otherwise testing will give warnings
eval { local $^W=0; require "sys/ioctl.ph" };

=head1 NAME

CallBackery::GuiPlugin::Abstract - GuiPlugin base class

=head1 SYNOPSIS

 use Mojo::Base 'CallBackery::GuiPlugin::Abstract';

=head1 DESCRIPTION

The abstract base class for callbackery gui classes.

=cut

use Mojo::Base -base, -signatures, -async_await;


=head1 ATTRIBUTES

=head2 config

The Plugin instance specific config section from the master config file.

=cut

has 'config';

=head2 name

The PLUGIN instance 'name' as specified in the C<*** PLUGIN:... ***> section.

=cut

has 'name';

=head2 user

The current user object

=cut

has 'user';


has 'dbHandle' => sub ($self) {
    $self->user->db;
};

    
=head2 tabName

What should the tab holding this plugin be called

=cut

has tabName => sub {
    return shift->config->{'tab-name'};

lib/CallBackery/GuiPlugin/Abstract.pm  view on Meta::CPAN


=head2 renderTemplate(template,destination)

Render the given template and write the result into the given
file. These templates support the L<Mojo::Template> language enhanced
by the command C<L('Plugin::key')> which looks up values from the
config database. The convention is that each plugin writes data in
it's own namespace.

If the destination already exists, the method compares the current
content with the new one. It will only update the file if the content
differs.

The method returns 0 when there was no change and 1 when a new version
of the file was written.

These additional commands are available to the templates.

=over

=item *

slurp(file)

=back

=cut

has cfgHash => sub {
    my $self = shift;
    return $self->app->config->cfgHash;
}, weak => 1;

has template => sub {
    my $self = shift;
    my $mt = Mojo::Template->new();
    $self->dbHandle;   
    my $dbLookup = sub { $self->getConfigValue(@_) // ''};
 
    # don't use L, use dbLookup instead
    monkey_patch $mt->namespace,
        L => $dbLookup;

    monkey_patch $mt->namespace,
        dbLookup => $dbLookup;

    monkey_patch $mt->namespace,
        app => sub { $self->app };

    monkey_patch $mt->namespace,
        slurp => sub {
            my $filename = shift;
            return Mojo::File->new($filename)->slurp;
        };
    monkey_patch $mt->namespace,
        cfgHash => sub { $self->cfgHash };

    monkey_patch $mt->namespace,
        pluginCfg => sub { my $instance = shift;
            my $cfg = $self->cfgHash->{PLUGIN}{prototype}{$instance}->config;
            weaken $cfg;
            return $cfg;
        };
    return $mt;
};


has homeDir => sub {
    [getpwuid $>]->[7];
};

sub renderTemplate{
    my $self = shift;
    my $template = shift;
    my $destination = Mojo::File->new(shift);
    $self->log->debug('['.$self->name.'] processing template '.$template);
    my $newData = $self->template->render($self->app->home->rel_file('templates/system/'.$template)->slurp);
    if (-r $destination){
        my $oldData = Mojo::File->new($destination)->slurp;
        if ($newData eq $oldData){
            return 0
        }
    }
    my $dir = $destination->dirname;
    if (not -d $dir){
        Mojo::File->new($dir)->make_path({mode => 755});
    }

    $self->log->debug('['.$self->name."] writing $destination\n$newData");
    eval {
        local $SIG{__DIE__};
        $destination->spew($newData);
    };
    if ($@){
        if (blessed $@ and $@->isa('autodie::exception')){
            $self->log->error('['.$self->name."] writing $template -> $destination: ".$@->errno);
        }
        else {
            die $@;
        }
    }
    if ($self->controller and $self->controller->can('runEventActions')){
        $self->controller->runEventActions('changeConfig');
    }
    return 1;
}

=head2 getConfigValue(key)

Read a config value from the database.

=cut

sub getConfigValue {
    my $self = shift;
    my $key = shift;
    my $value = $self->dbHandle->getConfigValue($key);
    return undef if not defined $value;
    my $ret = eval { decode_json($value) };
    # warn "GET $key -> ".Dumper($ret);
    if ($@){



( run in 0.702 second using v1.01-cache-2.11-cpan-39bf76dae61 )