App-FirefoxMultiAccountContainersUtils

 view release on metacpan or  search on metacpan

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

    my %args = @_;

    my $code = $args{code};
    unless (ref $code eq 'CODE') {
        $code = "no strict; no warnings; package main; sub { $code }";
        $code = eval $code; ## no critic: BuiltinFunctions::ProhibitStringyEval
        return [400, "Cannot compile string code: $@"] if $@;
    }

    my $res;
    $res = _get_containers_json(\%args, 'backup');
    return $res unless $res->[0] == 200;

    my $path = $res->[2]{path};
    my $json = $res->[2]{content};
    my $new_identities = [];
    for my $identity (@{ $json->{identities} }) {
        local $_ = $identity;
        my $code_res = $code->($identity);
        if (!$code_res) {
            next;
        } elsif (ref $code_res ne 'HASH') {
            log_fatal "Code does not return a hashref: %s", $code_res;
            die;
        } else {
            push @$new_identities, $code_res;
        }
    }
    $json->{identities} = $new_identities;

    if ($args{-dry_run}) {
        # convert boolean object to 1/0 for display
        for (@{ $json->{identities} }) { $_->{public} = $_->{public} ? 1:0 }

        return [200, "OK (dry-run)", $json->{identities}];
    }

    log_info "Writing $path ...";
    File::Slurper::write_text($path, JSON::MaybeXS::encode_json($json));
    [200];
}

$SPEC{firefox_mua_add_container} = {
    v => 1.1,
    summary => "Add a new Firefox Multi-Account container",
    description => <<'MARKDOWN',

This utility will copy the last container record, change the name to the one you
specify, and add it to the list of containers. You can also set some other
attributes.

MARKDOWN
    args => {
        %argspec0_profile,
        name => {
            summary => 'Name for the new container',
            schema => ['str*', min_len=>1],
            pos => 1,
        },
        color => {
            schema => ['str*', match=>qr/\A\w+\z/], # XXX currently not validated for valid values
        },
        icon => {
            schema => ['str*', match=>qr/\A\w+\z/], # XXX currently not validated for valid values
        },
    },
    features => {
        dry_run => 1,
    },
};
sub firefox_mua_add_container {
    require App::FirefoxUtils;
    require File::Copy;
    require File::Slurper;
    require Firefox::Util::Profile;
    require JSON::MaybeXS;

    my %args = @_;
    defined(my $name = $args{name}) or return [400, "Please specify name for new container"];

    my $res;
    $res = _get_containers_json(\%args, 'backup');
    return $res unless $res->[0] == 200;

    my $path = $res->[2]{path};
    my $json = $res->[2]{content};

    # we currently need one existing identity
    @{ $json->{identities} } or return [412, "I need at least one existing identity"];
    my $new_identity = { %{$json->{identities}[-1]} };
    $new_identity->{name} = $name;

    # check that name does not already exist
    for my $identity (@{ $json->{identities} }) {
        return [409, "Identity with name '$name' already exists"] if $identity->{name} eq $name;
    }

    # set other attributes
    if (defined $args{icon}) {
        $new_identity->{icon} = $args{icon};
    }
    if (defined $args{color}) {
        $new_identity->{color} = $args{color};
    }

    # set user context id to the greatest
    {
        my $max_context_id = 0;
        for my $identity (@{ $json->{identities} }) {
            $max_context_id = $identity->{userContextId}
                if $max_context_id < $identity->{userContextId}
                && $identity->{userContextId} < 4294967295;
        }
        $new_identity->{userContextId} = $max_context_id;
    }

    # add the new container
    push @{ $json->{identities} }, $new_identity;

    if ($args{-dry_run}) {
        # convert boolean object to 1/0 for display
        for (@{ $json->{identities} }) { $_->{public} = $_->{public} ? 1:0 }

        return [200, "OK (dry-run)", $json->{identities}[-1]];



( run in 1.725 second using v1.01-cache-2.11-cpan-140bd7fdf52 )