use
5.014;
$App::SpreadRevolutionaryDate::Config::VERSION
=
'0.40'
;
BEGIN {
unless
(
$ENV
{PERL_UNICODE} &&
$ENV
{PERL_UNICODE} =~ /A/) {
@ARGV
=
map
{ decode_utf8(
$_
, 1) }
@ARGV
;
}
}
sub
new {
my
(
$class
,
$filename
) =
@_
;
my
@orig_argv
=
@ARGV
;
my
$config_first
= Getopt::Long::Parser->new;
$config_first
->configure(
'pass_through'
);
if
(
$filename
) {
$config_first
->getoptions(
"version|v"
=>
sub
{
say
$App::SpreadRevolutionaryDate::Config::VERSION
;
exit
0; },
"help|h|?"
=> \
&usage
);
}
else
{
$config_first
->getoptions(
"version|v"
=>
sub
{
say
$App::SpreadRevolutionaryDate::Config::VERSION
;
exit
0; },
"help|h|?"
=> \
&usage
,
"conf|c=s"
=> \
$filename
);
}
my
$file_start
;
$file_start
=
tell
$filename
if
$filename
&&
ref
(
$filename
);
my
$config_targets
= AppConfig::new(
$class
, {
CREATE
=> 1,
ERROR
=>
sub
{}},
'conf'
=> {
ARGCOUNT
=> ARGCOUNT_ONE,
ALIAS
=>
'c'
},
'version'
=> {
ARGCOUNT
=> ARGCOUNT_NONE,
ALIAS
=>
'v'
},
'help'
=> {
ARGCOUNT
=> ARGCOUNT_NONE,
ALIAS
=>
'h|?'
},
'targets'
=> {
ARGCOUNT
=> ARGCOUNT_LIST,
ALIAS
=>
'tg'
},
'msgmaker'
=> {
ARGCOUNT
=> ARGCOUNT_ONE,
ALIAS
=>
'mm'
},
'test'
=> {
ARGCOUNT
=> ARGCOUNT_NONE,
ALIAS
=>
'no|n'
},
'locale'
=> {
ARGCOUNT
=> ARGCOUNT_ONE,
ALIAS
=>
'l'
},
'acab'
=> {
ARGCOUNT
=> ARGCOUNT_NONE,
ALIAS
=>
'a'
},
'bluesky'
=> {
ARGCOUNT
=> ARGCOUNT_NONE,
ALIAS
=>
'b'
},
'twitter'
=> {
ARGCOUNT
=> ARGCOUNT_NONE,
ALIAS
=>
't'
},
'mastodon'
=> {
ARGCOUNT
=> ARGCOUNT_NONE,
ALIAS
=>
'm'
},
'freenode'
=> {
ARGCOUNT
=> ARGCOUNT_NONE,
ALIAS
=>
'f'
},
'liberachat'
=> {
ARGCOUNT
=> ARGCOUNT_NONE,
ALIAS
=>
'lt'
});
$config_targets
->parse_file(
$filename
);
@ARGV
=
@orig_argv
;
$config_targets
->parse_command_line;
my
@targets
= @{
$config_targets
->targets};
my
%potential_targets
=
$config_targets
->varlist(
"."
);
foreach
my
$potential_target
(
keys
%potential_targets
) {
next
unless
$potential_targets
{
$potential_target
};
next
if
$potential_target
=~ /_/;
if
(
$potential_target
!~ /^(?:acab|test|locale|targets|msgmaker|conf|version|help)$/) {
push
@targets
,
$potential_target
;
}
}
if
(!
$config_targets
->bluesky && !
$config_targets
->twitter && !
$config_targets
->mastodon && !
$config_targets
->freenode && !
$config_targets
->liberachat && !
scalar
(
@targets
)) {
push
@targets
,
'bluesky'
,
'twitter'
,
'mastodon'
,
'freenode'
,
'liberachat'
;
$config_targets
->targets(
@targets
);
$config_targets
->bluesky(1);
$config_targets
->twitter(1);
$config_targets
->mastodon(1);
$config_targets
->freenode(1);
$config_targets
->liberachat(1);
}
my
%target_attributes
;
foreach
my
$target
(
@targets
) {
my
$target_class
=
'App::SpreadRevolutionaryDate::Target::'
.
ucfirst
(
lc
(
$target
));
my
$target_meta
;
try_load_class(
$target_class
)
or
die
"Cannot found target class $target_class for target $target\n"
;
load_class(
$target_class
);
eval
{
$target_meta
=
$target_class
->meta; };
die
"Cannot found target meta class $target_class for target $target: $@\n"
if
$@;
foreach
my
$target_meta_attribute
(
$target_meta
->get_all_attributes) {
next
if
$target_meta_attribute
->name eq
'obj'
;
my
$target_meta_attribute_type
=
$target_meta_attribute
->type_constraint;
my
$target_meta_attribute_argcount
=
$target_meta_attribute_type
=~ /ArrayRef/ ? ARGCOUNT_LIST :
$target_meta_attribute_type
=~ /HashRef/ ? ARGCOUNT_HASH :
$target_meta_attribute_type
=~ /Bool/ ? ARGCOUNT_NONE : ARGCOUNT_ONE;
$target_attributes
{
lc
(
$target
) .
'_'
.
$target_meta_attribute
->name} = {
ARGCOUNT
=>
$target_meta_attribute_argcount
};
$target_attributes
{
lc
(
$target
)} = {
ARGCOUNT
=> ARGCOUNT_NONE };
if
(
$target_meta_attribute
->has_default) {
$target_attributes
{
lc
(
$target
) .
'_'
.
$target_meta_attribute
->name}{DEFAULT} =
$target_meta_attribute
->
default
;
}
}
}
my
%msgmaker_attributes
;
my
$msgmaker
=
$config_targets
->msgmaker ||
'RevolutionaryDate'
;
my
$msgmaker_class
=
'App::SpreadRevolutionaryDate::MsgMaker::'
.
$msgmaker
;
my
$msgmaker_meta
;
try_load_class(
$msgmaker_class
)
or
die
"Cannot found msgmaker class $msgmaker_class for msgmaker $msgmaker\n"
;
load_class(
$msgmaker_class
);
eval
{
$msgmaker_meta
=
$msgmaker_class
->meta; };
die
"Cannot found msgmaker meta class $msgmaker_class for msgmaker $msgmaker: $@\n"
if
$@;
foreach
my
$msgmaker_meta_attribute
(
$msgmaker_meta
->get_all_attributes) {
next
if
$msgmaker_meta_attribute
->name eq
'locale'
;
my
$msgmaker_meta_attribute_type
=
$msgmaker_meta_attribute
->type_constraint;
my
$msgmaker_meta_attribute_argcount
=
$msgmaker_meta_attribute_type
=~ /ArrayRef/ ? ARGCOUNT_LIST :
$msgmaker_meta_attribute_type
=~ /HashRef/ ? ARGCOUNT_HASH :
$msgmaker_meta_attribute_type
=~ /Bool/ ? ARGCOUNT_NONE : ARGCOUNT_ONE;
$msgmaker_attributes
{
lc
(
$msgmaker
) .
'_'
.
$msgmaker_meta_attribute
->name} = {
ARGCOUNT
=>
$msgmaker_meta_attribute_argcount
};
$msgmaker_attributes
{
lc
(
$msgmaker
)} = {
ARGCOUNT
=> ARGCOUNT_NONE };
if
(
$msgmaker_meta_attribute
->has_default) {
$msgmaker_attributes
{
lc
(
$msgmaker
) .
'_'
.
$msgmaker_meta_attribute
->name}{DEFAULT} =
$msgmaker_meta_attribute
->
default
;
}
}
my
$self
= AppConfig::new(
$class
,
%target_attributes
,
%msgmaker_attributes
,
'conf'
=> {
ARGCOUNT
=> ARGCOUNT_ONE,
ALIAS
=>
'c'
},
'version'
=> {
ARGCOUNT
=> ARGCOUNT_NONE,
ALIAS
=>
'v'
},
'help'
=> {
ARGCOUNT
=> ARGCOUNT_NONE,
ALIAS
=>
'h|?'
},
'targets'
=> {
ARGCOUNT
=> ARGCOUNT_LIST,
ALIAS
=>
'tg'
},
'msgmaker'
=> {
ARGCOUNT
=> ARGCOUNT_ONE,
ALIAS
=>
'mm'
,
default
=>
'RevolutionaryDate'
},
'test'
=> {
ARGCOUNT
=> ARGCOUNT_NONE,
ALIAS
=>
'no|n'
},
'locale'
=> {
ARGCOUNT
=> ARGCOUNT_ONE,
ALIAS
=>
'l'
,
default
=>
'fr'
},
'acab'
=> {
ARGCOUNT
=> ARGCOUNT_NONE,
ALIAS
=>
'a'
},
'bluesky'
=> {
ARGCOUNT
=> ARGCOUNT_NONE,
ALIAS
=>
'b'
},
'twitter'
=> {
ARGCOUNT
=> ARGCOUNT_NONE,
ALIAS
=>
't'
},
'mastodon'
=> {
ARGCOUNT
=> ARGCOUNT_NONE,
ALIAS
=>
'm'
},
'freenode'
=> {
ARGCOUNT
=> ARGCOUNT_NONE,
ALIAS
=>
'f'
},
'liberachat'
=> {
ARGCOUNT
=> ARGCOUNT_NONE,
ALIAS
=>
'lt'
},
'bluesky_identifier'
=> {
ARGCOUNT
=> ARGCOUNT_ONE,
ALIAS
=>
'bi'
},
'bluesky_password'
=> {
ARGCOUNT
=> ARGCOUNT_ONE,
ALIAS
=>
'bp'
},
'twitter_consumer_key'
=> {
ARGCOUNT
=> ARGCOUNT_ONE,
ALIAS
=>
'tck'
},
'twitter_consumer_secret'
=> {
ARGCOUNT
=> ARGCOUNT_ONE,
ALIAS
=>
'tcs'
},
'twitter_access_token'
=> {
ARGCOUNT
=> ARGCOUNT_ONE,
ALIAS
=>
'tat'
},
'twitter_access_token_secret'
=> {
ARGCOUNT
=> ARGCOUNT_ONE,
ALIAS
=>
'tats'
},
'twitter_api'
=> {
ARGCOUNT
=> ARGCOUNT_ONE,
ALIAS
=>
'tapi'
},
'mastodon_instance'
=> {
ARGCOUNT
=> ARGCOUNT_ONE,
ALIAS
=>
'mi'
},
'mastodon_client_id'
=> {
ARGCOUNT
=> ARGCOUNT_ONE,
ALIAS
=>
'mci'
},
'mastodon_client_secret'
=> {
ARGCOUNT
=> ARGCOUNT_ONE,
ALIAS
=>
'mcs'
},
'mastodon_access_token'
=> {
ARGCOUNT
=> ARGCOUNT_ONE,
ALIAS
=>
'mat'
},
'freenode_nickname'
=> {
ARGCOUNT
=> ARGCOUNT_ONE,
ALIAS
=>
'fn'
},
'freenode_password'
=> {
ARGCOUNT
=> ARGCOUNT_ONE,
ALIAS
=>
'fp'
},
'freenode_test_channels'
=> {
ARGCOUNT
=> ARGCOUNT_LIST,
ALIAS
=>
'ftc'
},
'freenode_channels'
=> {
ARGCOUNT
=> ARGCOUNT_LIST,
ALIAS
=>
'fc'
},
'liberachat_nickname'
=> {
ARGCOUNT
=> ARGCOUNT_ONE,
ALIAS
=>
'ln'
},
'liberachat_password'
=> {
ARGCOUNT
=> ARGCOUNT_ONE,
ALIAS
=>
'lp'
},
'liberachat_test_channels'
=> {
ARGCOUNT
=> ARGCOUNT_LIST,
ALIAS
=>
'ltc'
},
'liberachat_channels'
=> {
ARGCOUNT
=> ARGCOUNT_LIST,
ALIAS
=>
'lc'
},
'revolutionarydate_acab'
=> {
ARGCOUNT
=> ARGCOUNT_NONE,
ALIAS
=>
'ra'
},
'promptuser_default'
=> {
ARGCOUNT
=> ARGCOUNT_ONE,
ALIAS
=>
'pud'
},
);
seek
$filename
,
$file_start
, 0
if
$file_start
;
$self
->parse_file(
$filename
);
my
%args_list_backup
;
my
%args_list
=
$config_targets
->varlist(
"."
);
foreach
my
$arg_list
(
keys
%args_list
) {
next
unless
$self
->_argcount(
$arg_list
) == ARGCOUNT_LIST;
push
@{
$args_list_backup
{
$arg_list
}}, @{
$self
->
$arg_list
};
$self
->_default(
$arg_list
);
}
@ARGV
=
@orig_argv
;
$self
->parse_command_line;
foreach
my
$arg_list
(
keys
%args_list_backup
) {
unless
(
scalar
@{
$self
->
$arg_list
}) {
$self
->
$arg_list
(
$_
)
foreach
(@{
$args_list_backup
{
$arg_list
}});
}
}
@targets
= @{
$self
->targets};
my
%confvars
=
$self
->varlist(
"."
);
foreach
my
$potential_target
(
keys
%confvars
) {
next
unless
$confvars
{
$potential_target
};
next
if
$potential_target
=~ /_/;
if
(
$potential_target
!~ /^(?:acab|test|locale|targets|msgmaker|conf|version|help)$/) {
push
@targets
,
$potential_target
;
$self
->targets(
$potential_target
);
}
}
if
(!
$self
->bluesky && !
$self
->twitter && !
$self
->mastodon && !
$self
->freenode && !
$self
->liberachat && !
scalar
(
@targets
)) {
push
@targets
,
'bluesky'
,
'twitter'
,
'mastodon'
,
'freenode'
,
'liberachat'
;
map
{
$self
->targets(
$_
); }
@targets
;
$self
->bluesky(1);
$self
->twitter(1);
$self
->mastodon(1);
$self
->freenode(1);
$self
->liberachat(1);
}
foreach
my
$target
(
@targets
) {
$self
->check_target_mandatory_options(
$target
);
}
return
$self
;
}
sub
parse_file {
my
(
$self
,
$filename
) =
@_
;
foreach
my
$default_path
(
File::HomeDir->my_home .
'/.config/spread-revolutionary-date/spread-revolutionary-date.conf'
,
File::HomeDir->my_home .
'/.spread-revolutionary-date.conf'
) {
$filename
=
$default_path
if
(!
$filename
&& -f
$default_path
)
}
$self
->file(
$filename
);
}
sub
parse_command_line {
my
$self
=
shift
;
$self
->args;
}
sub
check_target_mandatory_options {
my
(
$self
,
$target
) =
@_
;
my
$target_class
=
'App::SpreadRevolutionaryDate::Target::'
.
ucfirst
(
lc
(
$target
));
my
$target_meta
;
try_load_class(
$target_class
)
or
die
"Cannot found target class $target_class for target $target\n"
;
load_class(
$target_class
);
eval
{
$target_meta
=
$target_class
->meta; };
die
"Cannot found target meta class $target_class for target $target: $@\n"
if
$@;
foreach
my
$target_meta_attribute
(
$target_meta
->get_all_attributes) {
next
if
$target_meta_attribute
->name eq
'obj'
;
next
unless
$target_meta_attribute
->is_required;
my
$target_mandatory_option
=
$target
.
'_'
.
$target_meta_attribute
->name;
die
"Cannot spread to $target, mandatory configuraton parameter "
.
$target_meta_attribute
->name .
" missing\n"
unless
!!
$self
->
$target_mandatory_option
;
}
}
sub
get_target_arguments {
my
(
$self
,
$target
) =
@_
;
$target
=
lc
(
$target
);
my
%target_args
=
$self
->varlist(
"^${target}_"
, 1);
foreach
my
$arg
(
keys
%target_args
) {
if
(
$arg
=~ /^test_(.+)$/ &&
$target_args
{$1}) {
$target_args
{$1} =
delete
$target_args
{
$arg
}
if
$self
->test;
}
}
return
%target_args
;
}
sub
get_msgmaker_arguments {
my
(
$self
,
$msgmaker
) =
@_
;
$msgmaker
=
lc
(
$msgmaker
);
my
%msgmaker_args
=
$self
->varlist(
"^${msgmaker}_"
, 1);
$msgmaker_args
{acab} =
$self
->acab
if
$msgmaker
eq
'revolutionarydate'
&& !
$msgmaker_args
{acab}
&&
$self
->acab;
if
(
$msgmaker
eq
'promptuser'
) {
if
(
$msgmaker_args
{
default
} &&
$msgmaker_args
{
default
} ne App::SpreadRevolutionaryDate::MsgMaker::PromptUser->meta->get_attribute(
'default'
)->
default
) {
$ENV
{PERL_MM_USE_DEFAULT} = 1
}
}
return
%msgmaker_args
;
}
sub
usage {
print
<<
"USAGE"
;
Usage: $0 <OPTIONS>
with
<OPTIONS>:
--conf|-c <file>: path to configuration file (
default
: ~/.config/spread-revolutionary-date/spread-revolutionary-date.conf or ~/.spread-revolutionary-date.conf)'
--version|-v':
print
out version
--help|-h|-?':
print
out this help
--targets|-tg <target_1> [--targets|-tg <target_2> […--targets|-tg <target_n>]]': define targets (
default
: bluesky, twitter, mastodon, freenode, liberachat)
--msgmaker|-mm <MsgMakerClass>: define message maker (
default
: RevolutionaryDate)
--locale|-l <fr|en|it|es>: define locale (
default
: fr
for
msgmaker=RevolutionaryDate, en otherwise)
--test|--
no
|-n:
do
not spread, just
print
out message or spread to test channels
for
Freenode or Liberachat
--bluesky_identifier|-bi <key>: define Bluesky identifier
--bluesky_password|-bp <key>: define Bluesky password
--twitter_consumer_key|-tck <key>: define Twitter consumer key
--twitter_consumer_secret|-tcs <secret>: define Twitter consumer secret
--twitter_access_token|-tat <token>: define Twitter access token
--twitter_access_token_secret|tats <token_secret>: define Twitter access token secret
--mastodon_instance|-mi <instance>: define Mastodon instance
--mastodon_client_id|-mci <id>: define Mastodon client id
--mastodon_client_secret|-mcs <secret>: define Mastodon client secret
--mastodon_access_token|-mat <token>: define Mastodon access token
--freenode_nickname|-fn <nick>: define Freenode nickname
--freenode_password|-fp <passwd>: define Freenode password
--freenode_test_channels|-ftc <channel_1> [--freenode_test_channels|-ftc <channel_2> […--freenode_test_channels|-ftc <channel_n>]]: define Freenode channels
--freenode_channels|-fc <channel_1> [--freenode_channels|-fc <channel_2> […--freenode_channels|-fc <channel_n>]]: define Freenode test channels
--liberachat_nickname|-ln <nick>: define Liberachat nickname
--liberachat_password|-lp <passwd>: define Liberachat password
--liberachat_test_channels|-ltc <channel_1> [--liberachat_test_channels|-ltc <channel_2> […--liberachat_test_channels|-ltc <channel_n>]]: define Liberachat channels
--liberachat_channels|-
lc
<channel_1> [--liberachat_channels|-
lc
<channel_2> […--liberachat_channels|-
lc
<channel_n>]]: define Liberachat test channels
--revolutionarydate_acab | -ra: pretend it is 01:31:20 (
default
: false)
--promptuser_default|-pud <msg>: define
default
message
when
--msgmaker=PromptUser (
default
:
'Goodbye old world, hello revolutionary worlds'
)
USAGE
exit
0;
}
no
Moose;
__PACKAGE__->meta->make_immutable(
inline_constructor
=> 0);
"Quand le gouvernement viole les droits du peuple,
l'insurrection est pour le peuple le plus sacré
et le plus indispensable des devoirs";
Hide Show 104 lines of Pod