From Code to Community: Sponsoring The Perl and Raku Conference 2025 Learn more

use strict;
our $VERSION = '0.02';
sub load {
my $class = shift;
my $section = shift;
if ( !defined $section ) {
die 'section is required';
}
my $config = _load_and_verify();
if ( !exists $config->{$section} ) {
die "$section section was not found in the config";
}
return $config->{$section};
}
sub _get_conf_dir {
my $name = 'toot';
my $dir;
if ( $ENV{HOME} && -d "$ENV{HOME}/.config/$name" ) {
$dir = "$ENV{HOME}/.config";
}
elsif ( -d "/etc/$name" ) {
$dir = '/etc';
}
else {
die "error: unable to find config directory\n";
}
return "$dir/$name";
}
sub _load_and_verify {
my $rc = _get_conf_dir() . '/config.ini';
unless ( -e $rc && -r $rc ) {
die "error: $rc does not exist or cannot be read\n";
}
my $config = Config::Tiny->read($rc);
unless ( defined $config->{'default'} ) {
die "default section in $rc is not defined\n";
}
foreach my $section ( keys %$config ) {
foreach my $key (qw{ instance username client_id client_secret access_token }) {
unless ( defined $config->{$section}{$key} ) {
die "$key key for $section section in $rc is not defined\n";
}
}
}
return $config;
}
1;
__END__
=pod
=head1 NAME
App::Toot::Config - load and verify the config
=head1 SYNOPSIS
use App::Toot::Config;
my $config = App::Toot::Config->load( 'section name' );
=head1 DESCRIPTION
C<App::Toot::Config> loads settings for L<App::Toot>.
=head1 SUBROUTINES
=head2 load( 'section name' )
Reads, verifies, and returns the config.
=head3 ARGUMENTS
The defined section name is required and dies if not found in the loaded config.
=head3 RETURNS
Returns a hashref of the loaded config for the defined section name.
=head1 CONFIGURATION
To post to Mastodon, you need to provide the account's oauth credentials in the file C<config.ini>.
An example is provided as part of this distribution. The user running the L<toot> script, for example through cron, will need access to the configuration file.
To set up the configuration file, copy C<config.ini.example> into one of the following locations:
=over
=item C<$ENV{HOME}/.config/toot/config.ini>
=item C</etc/toot/config.ini>
=back
After creating the file, edit and update the values in the C<default> section to match the account's oauth credentials.
[default]
instance = mastodon.social
username = youruser
client_id = OKE98_kdno_NOTAREALCLIENTID
client_secret = mkjklnv_NOTAREALCLIENTSECRET
access_token = jo83_NOTAREALACCESSTOKEN
B<NOTE:> If the C<$ENV{HOME}/.config/toot/> directory exists, C<config.ini> will be loaded from there regardless of a config file in C</etc/toot/>.
=head2 Required keys
The following keys are required for each section:
=over
=item instance
The Mastodon server name the account belongs to.
=item username
The account name for the Mastodon server defined in C<instance>.
=item client_id
The C<client_id> as provided for the C<username> on the C<instance>.
=item client_secret
The C<client_secret> as provided for the C<username> on the C<instance>.
=item access_token
The C<access_token> as provided for the C<username> on the C<instance>.
=back
=head2 Additional accounts
Multiple accounts can be configured with different sections after the C<default> section.
[default]
instance = mastodon.social
username = youruser
client_id = OKE98_kdno_NOTAREALCLIENTID
client_secret = mkjklnv_NOTAREALCLIENTSECRET
access_token = jo83_NOTAREALACCESSTOKEN
[development]
instance = botsin.space
username = yourdeveluser
client_id = Ijjkn_STILLNOTAREALCLIENTID
client_secret = u7hhd_STILLNOTAREALCLIENTSECRET
access_token = D873_SKILLNOTAREALACCESSTOKEN
The section name, C<development> in the example above, can be named anything as long as it's unique with the other section names.
=head1 COPYRIGHT AND LICENSE
Copyright (c) 2023 Blaine Motsinger under the MIT license.
=head1 AUTHOR
Blaine Motsinger C<blaine@renderorange.com>
=cut