App-SpreadRevolutionaryDate

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN

 - Configuration file should be opened in UTF-8, pass filehandle to
   AppConfig

0.46 2025-03-20T23:48:51Z
 - Improve splitting of messages according to max_length
 - Fix missing used module
 - Add some images to use with Gemini

0.45 2025-03-20T21:08:22Z
 - Add documentation for Gemini
 - Use locale attribute to build DateTime
 - Add Gemini options in help message
 - Fix PromptUser options in help message
 - Missing mandatory parameters that have a default value should not
   trigger an error
 - Add missing config option for Gemini msgmaker
 - Add configuration sample for Gemini msgmaker config options
 - Use Camel case for configuration section, like msgmaker module name
 - Add tests for Gemini msgmaker config options
 - Add config options for Gemini msgmaker
 - Add Gemini msgmaker

Changes  view on Meta::CPAN

 - Fix errors in USAGE doc

0.11 2019-04-07T14:26:45Z
 - Add German localization of PromptUser msgmaker
 - Add documentation for i18n/l10n
 - Let multivalued options be overridden by command line arguments
 - Add App::SpreadRevolutionaryDate::MsgMaker::RevolutionaryDate::Locale
   role and moosify consuming classes
 - Add localization template
 - Add Italian localization
 - Overload DateTime::Calendar::FrenchRevolutionary to extend defaults
   fr/en locales
 - Add localization with Locale::TextDomain

0.10 2019-03-30T20:59:56Z
 - Add --conf, --version and --help command line parameters
 - Fix and improve doc
 - Add default value when defined for options guessed from Target and
   MsgWriter consuming classes
 - Add wikipedia_link option to revolutionarydate msgmaker
 - Process wikipedia ambiguous links

META.json  view on Meta::CPAN

            "Test::Vars" : "0",
            "strict" : "0",
            "warnings" : "0"
         }
      },
      "runtime" : {
         "requires" : {
            "AppConfig" : "0",
            "Bot::BasicBot" : "0",
            "Class::Load" : "0",
            "DateTime" : "0",
            "DateTime::Calendar::FrenchRevolutionary" : "0",
            "Encode" : "0",
            "File::Basename" : "0",
            "File::HomeDir" : "0",
            "File::ShareDir" : "0",
            "File::Spec" : "0",
            "File::Temp" : "0",
            "File::Type" : "0",
            "Getopt::Long" : "0",
            "IO::Handle" : "0",
            "IO::Prompt::Hooked" : "0",

META.yml  view on Meta::CPAN

  App::SpreadRevolutionaryDate::Target::Mastodon:
    file: lib/App/SpreadRevolutionaryDate/Target/Mastodon.pm
    version: '0.51'
  App::SpreadRevolutionaryDate::Target::Twitter:
    file: lib/App/SpreadRevolutionaryDate/Target/Twitter.pm
    version: '0.51'
requires:
  AppConfig: '0'
  Bot::BasicBot: '0'
  Class::Load: '0'
  DateTime: '0'
  DateTime::Calendar::FrenchRevolutionary: '0'
  Encode: '0'
  File::Basename: '0'
  File::HomeDir: '0'
  File::ShareDir: '0'
  File::Spec: '0'
  File::Temp: '0'
  File::Type: '0'
  Getopt::Long: '0'
  IO::Handle: '0'
  IO::Prompt::Hooked: '0'

Makefile.PL  view on Meta::CPAN

  "EXE_FILES" => [
    "bin/spread-revolutionary-date"
  ],
  "LICENSE" => "gpl",
  "MIN_PERL_VERSION" => "5.014",
  "NAME" => "App::SpreadRevolutionaryDate",
  "PREREQ_PM" => {
    "AppConfig" => 0,
    "Bot::BasicBot" => 0,
    "Class::Load" => 0,
    "DateTime" => 0,
    "DateTime::Calendar::FrenchRevolutionary" => 0,
    "Encode" => 0,
    "File::Basename" => 0,
    "File::HomeDir" => 0,
    "File::ShareDir" => 0,
    "File::Spec" => 0,
    "File::Temp" => 0,
    "File::Type" => 0,
    "Getopt::Long" => 0,
    "IO::Handle" => 0,
    "IO::Prompt::Hooked" => 0,

Makefile.PL  view on Meta::CPAN

  "test" => {
    "TESTS" => "t/*.t"
  }
);


my %FallbackPrereqs = (
  "AppConfig" => 0,
  "Bot::BasicBot" => 0,
  "Class::Load" => 0,
  "DateTime" => 0,
  "DateTime::Calendar::FrenchRevolutionary" => 0,
  "Encode" => 0,
  "File::Basename" => 0,
  "File::HomeDir" => 0,
  "File::ShareDir" => 0,
  "File::Spec" => 0,
  "File::Temp" => 0,
  "File::Type" => 0,
  "FindBin" => 0,
  "Getopt::Long" => 0,
  "IO::Handle" => 0,

README  view on Meta::CPAN

    100 minutes; and minutes into 100 seconds.

    You must have a registered account on each of the targets you want to
    spread the revolutionary date. And you must get credentials for
    spread-revolutionary-date to post on Mastodon, Bluesky and Twitter, and
    also for IA generated messages with Gemini message maker. Finally, you
    have to configure spread-revolutionary-date to use these credentials,
    see "CONFIGURATION" and "COMMAND LINE PARAMETERS" below.

    The revolutionary date and time is computed thanks to the
    DateTime::Calendar::FrenchRevolutionary Perl module, by Jean Forget.

USAGE

      # Just execute the script in your shell
      # to spread current date to configured accounts
      # to Bluesky, Twitter, Mastodon, Freenode and Liberachat:
      $ spread-revolutionary-date
    
      # Or, since this script does nothing but calling
      # the L<App::SpreadRevolutionaryDate> Perl module,

README  view on Meta::CPAN

    App::SpreadRevolutionaryDate::MsgMaker for a comprehensive description
    of this role.

    The name of the message maker should be set as a value of the
    "msgmaker" option.

    Such a message maker class is actually just a wrapper. Usually a
    message maker has to use an existing specific module (which can be a
    Moose class or not) to craft the message.
    App::SpreadRevolutionaryDate::MsgMaker::RevolutionaryDate uses
    DateTime::Calendar::FrenchRevolutionary, while
    App::SpreadRevolutionaryDate::MsgMaker::PromptUser is based on
    IO::Prompt::Hooked and App::SpreadRevolutionaryDate::MsgMaker::Gemini
    just uses LWP to request Gemini server. You may need for example LWP to
    extract the message from a fetched web page or service, or XML::Feed to
    build it from a RSS <https://en.wikipedia.org/wiki/RSS> feed, or DBI to
    retrieve it from a database, or nothing at all to spread a fixed
    message, etc.

    If your new message maker class needs specific parameters (other than
    locale, which comes with App::SpreadRevolutionaryDate::MsgMaker role),

README  view on Meta::CPAN


      The spread message will be Gemini answer, optionally prepended with a
      configured introduction (see bellow), and ending with hashtags
      #IAGenerated #PromptIdentifier.

      Prompts often need to mention informations relative to today, such as
      the FamousBirthday example below, or it could be that you wanna ask
      Gemni for today's weather, or traffic jams occuring the same day of
      the week as today, etc. As a syntactic sugar, you can insert in
      "prompt" option, any variable prefixed with a dollar sign ($) which
      correspond to a method of DateTime module applied to DateTime-now()>
      object, and it will be replaced by the result of this method in the
      prompt sent to Gemini. For example, in the FamousBirthday example
      below, if run on June 21st, the prompt sent to Gemini would be:

        'Which famous people have their birthday on June 21? Give a list of up to 6 people, then after the list give the unformatted URL of the Wikipedia page of only one of them, no comments and no need for an introduction like "Here are some famous...

      You should be careful that such variables are not interpreted by the
      Shell before calling spread-revolutionary-date, specially if
      specified as command line parameters. You can prevent such
      intepretation by the Shell by enclosing the option in single quotes,
      like the examples above.

    "intro"

      You may want that the spread message to start with your own
      introducing words before displaying Gemini answer. You can specify
      this with the "intro" option.

      Likewise, this option use the same syntactic sugar relative to
      methods of DateTime module. For example, the message spread on June
      21st by the FamousBirthday example bellow, would be something like

        Famous people born on June 21 for better or for worse:
        First Name
        Second Name
        Third Name
        Fourth Name
        Fifth Name
        Sixth Name
      

README  view on Meta::CPAN


      prompt   FamousBirthday      = 'Which famous people have their birthday on $month_name $day? Give a list of up to 6 people, then after the list give the unformatted URL of the Wikipedia page of only one of them, no comments and no need for an i...

    The only place where you should be concerned by localization is when
    you define an introduction to be prepended to Gemini answer. Since it
    is a configured static string, it should be written in the desired
    language, like:

      intro    FamousBirthday      = 'FamousBirthday=Berühmte Personen, die am $day $month_name geboren wurden, im Guten wie im Schlechten:'

    Also, if you use some syntactic sugars relative to methods of DateTime
    module that are localizable, like month_name, you should use the
    "locale" option to have it translated in the desired language.

    And now you are ready to spread whatever your like, with just some
    configuration tweaks!

    Be aware that Gemini, like any other AI, has no concept of truth. It
    can only give formally probable answers, based on its training data. So
    do not ask somehing where truth matters… Also, all data you're sending
    to Gemini are assumed to not be private anymore and could be used by

README  view on Meta::CPAN

      msgid "or {abort} to abort"
      msgstr "oder {abort}, um abzubrechen"

    And that's it! As of version 0.11 of spread-revolutionary-date, there
    is only about a dozen of strings to translate, mainly for PromptUser
    message maker. But with the possibility to extend to other message
    makers, you may need more and more strings to be translated.

    Translating days, months and feasts used in the RevolutionaryDate
    message maker do not use the gettext system. Mainly because it uses
    DateTime::Calendar::FrenchRevolutionary which proposes French and
    English translations in dedicated Perl modules.
    spread-revolutionary-date keeps the same way for translating
    expressions used in the French revolutionary calendar, but, thanks to
    Moose::Role
    App::SpreadRevolutionaryDate::MsgMaker::RevolutionaryDate::Locale,
    translatable nominal groups have been isolated from other Perl code.
    Their translations lie in a consuming class in the
    App::SpreadRevolutionaryDate::MsgMaker::RevolutionaryDate::Locale::
    namespace for each translated language. These classes are named after
    the two-letter (ISO 639-1 <https://en.wikipedia.org/wiki/ISO_639-1>) or

README  view on Meta::CPAN

    days. But for consistency reasons, I'd rather group all these
    translations used in the French Revolutionary Calendar in the same
    translation class. Nevertheless, I'm open to find solutions if you
    think it would be easier to translate everything with the gettext
    system.

SEE ALSO

    App::SpreadRevolutionaryDate

    DateTime::Calendar::FrenchRevolutionary

    AppConfig

    App::SpreadRevolutionaryDate::BlueskyLite

    Twitter::API

    Mastodon::Client

    Bot::BasicBot

bin/spread-revolutionary-date  view on Meta::CPAN

=head1 DESCRIPTION

C<spread-revolutionary-date> is a L<Free Software|https://www.gnu.org/philosophy/free-sw.html> that spreads the current date, expressed in the L<French Revolutionary calendar|https://en.wikipedia.org/wiki/French_Republican_calendar>, to various socia...

Moreover, you can easily extend these defaults targets with any desired one, see L</"EXTENDING TO NEW TARGETS">, and even spread something else than the revolutionary date, see L</msgmaker> option and L</"EXTENDING TO NEW MESSAGE MAKERS">.

The French Revolutionary calendar, also called Republican calendar, was introduced during the L<French Revolution|https://en.wikipedia.org/wiki/French_Revolution>, and used from late 1793 to 1805, and also during the L<Paris Commune|https://en.wikipe...

You B<must> have a registered account on each of the targets you want to spread the revolutionary date. And you must get credentials for C<spread-revolutionary-date> to post on C<Mastodon>, C<Bluesky> and C<Twitter>, and also for IA generated message...

The revolutionary date and time is computed thanks to the L<DateTime::Calendar::FrenchRevolutionary> Perl module, by Jean Forget.

=head1 USAGE

  # Just execute the script in your shell
  # to spread current date to configured accounts
  # to Bluesky, Twitter, Mastodon, Freenode and Liberachat:
  $ spread-revolutionary-date

  # Or, since this script does nothing but calling
  # the L<App::SpreadRevolutionaryDate> Perl module,

bin/spread-revolutionary-date  view on Meta::CPAN

Also, we do not plan to extend this feature to C<Twitter> target, since we recommand to not use this social network for political reasons.

Starting from version 0.45, C<Mastodon> and C<Bluesky> classes have a C<max_lenght> attribute (set to 300 for C<Mastodon> and set to 250 for C<Bluesky>), which is used to split a longer message into a thread of multiple posts. Again, we do not plan t...

=head1 EXTENDING TO NEW MESSAGE MAKERS

It is even easier to spread whatever you want instead of the revolutionary date. You should write a new class in the C<App::SpreadRevolutionaryDate::MsgMaker::> namespace (that is: the class should be C<App::SpreadRevolutionaryDate::MsgMaker::MyMsgMa...

The name of the message maker should be set as a value of the L</msgmaker> option.

Such a message maker class is actually just a wrapper. Usually a message maker has to use an existing specific module (which can be a C<Moose> class or not) to craft the message. L<App::SpreadRevolutionaryDate::MsgMaker::RevolutionaryDate> uses L<Dat...

If your new message maker class needs specific parameters (other than C<locale>, which comes with  L<App::SpreadRevolutionaryDate::MsgMaker> role), they should be defined as attributes of this class. Values for such attributes should be set in the L<...

Have a look to L<App::SpreadRevolutionaryDate::MsgMaker::PromptUser> or L<App::SpreadRevolutionaryDate::MsgMaker::Telechat> classes, they show simple examples on how to extend C<spread-revolutionary-date> to a new message maker.

=head2 Gemini message maker

From version 0.45, a new message maker is included which requests I<Gemini> AI. This allows to extend C<spread-revolutionary-date> just by configuring a few options. The most practical way to configure these options is to prepare everything by settin...

This way, you can setup different prompts in your configuration file. Here is an example with 4 different prompts configured:

bin/spread-revolutionary-date  view on Meta::CPAN

=over

=item L</prompt>

This is the option where you can define your prompt. It is advised to test this prompt to have I<Gemini> answer as you wish. For instance, I<Gemini> often start its answers to your prompt by: “Sure, here is ‘what you've asked for’, and you woul...

You can test your prompt with interactive form to I<Gemini> at L<https://gemini.google.com/app> or with C<spread-revolutionary-date> with options C<--test> and C<--targets=Mastodon> for example.

The spread message will be I<Gemini> answer, optionally prepended with a configured introduction (see bellow), and ending with hashtags C<#IAGenerated> C<#PromptIdentifier>.

Prompts often need to mention informations relative to today, such as the C<FamousBirthday> example below, or it could be that you wanna ask I<Gemni> for today's weather, or traffic jams occuring the same day of the week as today, etc. As a syntactic...

  'Which famous people have their birthday on June 21? Give a list of up to 6 people, then after the list give the unformatted URL of the Wikipedia page of only one of them, no comments and no need for an introduction like "Here are some famous peopl...

You should be careful that such variables are not interpreted by the C<Shell> before calling C<spread-revolutionary-date>, specially if specified as command line parameters. You can prevent such intepretation by the C<Shell> by enclosing the option i...

=item L</intro>

You may want that the spread message to start with your own introducing words before displaying I<Gemini> answer. You can specify this with the L</intro> option.

Likewise, this option use the same syntactic sugar relative to methods of L<DateTime> module. For example, the message spread on June 21st by the C<FamousBirthday> example bellow, would be something like

  Famous people born on June 21 for better or for worse:
  First Name
  Second Name
  Third Name
  Fourth Name
  Fifth Name
  Sixth Name

  https://en.wikipedia.org/wiki/Third_Name

bin/spread-revolutionary-date  view on Meta::CPAN

=back

Finally, one word of localization: you don't need it, since I<Gemini> will answer in the language you've used in your prompt. Or you can ask in your prompt to be answered in another language, like:

  prompt   FamousBirthday      = 'Which famous people have their birthday on $month_name $day? Give a list of up to 6 people, then after the list give the unformatted URL of the Wikipedia page of only one of them, no comments and no need for an intro...

The only place where you should be concerned by localization is when you define an introduction to be prepended to I<Gemini> answer. Since it is a configured static string, it should be written in the desired language, like:

  intro    FamousBirthday      = 'FamousBirthday=Berühmte Personen, die am $day $month_name geboren wurden, im Guten wie im Schlechten:'

Also, if you use some syntactic sugars relative to methods of L<DateTime> module that are localizable, like C<month_name>, you should use the L</locale> option to have it translated in the desired language.

And now you are ready to spread whatever your like, with just some configuration tweaks!

Be aware that I<Gemini>, like any other AI, has no concept of truth. It can only give formally probable answers, based on its training data. So do not ask somehing where truth matters… Also, all data you're sending to I<Gemini> are assumed to not b...

=head1 INTERNATIONALIZATION AND LOCALIZATION

Starting from version 0.11, this distribution uses the widespread internationalization and localization system L<gettext|https://en.wikipedia.org/wiki/Gettext>, commonly used for writing multilingual programs. See L<GNU gettext documentation|https://...

Translators can find a portable object template C<po/App-SpreadRevolutionaryDate.pot> which includes all translatable strings used by C<spread-revolutionary-date> (but not translations of days, months, feasts used in the French Revolutionary Calendar...

bin/spread-revolutionary-date  view on Meta::CPAN


 msgstr "Bitte geben Sie die Nachricht zu verbreiten ein"

When the string to be translated includes some words in curly braces, these words are actually named variables and should be left as is in the translation. E.g.:

  msgid "or {abort} to abort"
  msgstr "oder {abort}, um abzubrechen"

And that's it! As of version 0.11 of C<spread-revolutionary-date>, there is only about a dozen of strings to translate, mainly for C<PromptUser> message maker. But with the possibility to extend to other message makers, you may need more and more str...

Translating days, months and feasts used in the C<RevolutionaryDate> message maker do not use the C<gettext> system. Mainly because it uses L<DateTime::Calendar::FrenchRevolutionary> which proposes French and English translations in dedicated Perl mo...

Just copy the French class (from C<lib/App/SpreadRevolutionaryDate/MsgMaker/RevolutionaryDate/Locale/fr.pm> file) into the desired language, change the name of the class and replace every French string. E.g.: the names of the months should be replace...

  has '+months' => (
    default => sub {[
      'Vendémiaire', 'Brumaire',  'Frimaire',
      'Nivôse',      'Pluviôse',  'Ventôse',
      'Germinal',    'Floréal',   'Prairial',
      'Messidor',    'Thermidor', 'Fructidor',
      'jour complémentaire',

bin/spread-revolutionary-date  view on Meta::CPAN

  );

Because of the trick on prefix and suffix for feasts and the needed mapping for wikipedia entries, using the C<gettext> system would be quite difficult. It wouldn't be an issue for translating names of months or days. But for consistency reasons, I'd...

=head1 SEE ALSO

=over

=item L<App::SpreadRevolutionaryDate>

=item L<DateTime::Calendar::FrenchRevolutionary>

=item L<AppConfig>

=item L<App::SpreadRevolutionaryDate::BlueskyLite>

=item L<Twitter::API>

=item L<Mastodon::Client>

=item L<Bot::BasicBot>

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

    $self->targets->{$target}->spread($msg, $self->config->test, $img);
  }
}


no Moose;
__PACKAGE__->meta->make_immutable;

# A module must return a true value. Traditionally, a module returns 1.
# But this module is a revolutionary one, so it discards all old traditions.
# Idea borrowed from Jean Forget's DateTime::Calendar::FrenchRevolutionary.
"Quand le gouvernement viole les droits du peuple,
l'insurrection est pour le peuple le plus sacré
et le plus indispensable des devoirs";

__END__

=pod

=encoding UTF-8

lib/App/SpreadRevolutionaryDate/BlueskyLite.pm  view on Meta::CPAN

#
#   The GNU General Public License, Version 3, June 2007
#
use 5.014;
use utf8;
package App::SpreadRevolutionaryDate::BlueskyLite;
$App::SpreadRevolutionaryDate::BlueskyLite::VERSION = '0.51';
# ABSTRACT: Simple Class to post status to BlueSky.

use LWP::UserAgent;
use DateTime;
use JSON qw(encode_json decode_json);
use URI;
use Encode qw(decode_utf8);
use File::Type;
use File::Basename;

use namespace::autoclean;

sub _fetch_embed_url_card {
  my $self = shift;

lib/App/SpreadRevolutionaryDate/BlueskyLite.pm  view on Meta::CPAN

  my $payload = {
    repo => $self->{did},
    collection => 'app.bsky.feed.post',
    record => {
      text => $text,
      facets => $facets,
      ($embed ?
        (embed => $embed)
        : ()
      ),
      createdAt => DateTime->now->iso8601 . 'Z',
    },
  };

  if ($img) {
    $img = {path => $img} unless ref($img) && ref($img) eq 'HASH' && $img->{path};
    my $ft = File::Type->new();
    my $mime_type = $ft->mime_type($img->{path});

    my $img_alt = $img->{alt} // ucfirst(fileparse($img->{path}, qr/\.[^.]*/));

lib/App/SpreadRevolutionaryDate/BlueskyLite.pm  view on Meta::CPAN

  if ($response->is_success) {
      return decode_json($response->decoded_content);
  } else {
      return $response;
  }
}


# A module must return a true value. Traditionally, a module returns 1.
# But this module is a revolutionary one, so it discards all old traditions.
# Idea borrowed from Jean Forget's DateTime::Calendar::FrenchRevolutionary.
"Quand le gouvernement viole les droits du peuple,
l'insurrection est pour le peuple le plus sacré
et le plus indispensable des devoirs";

__END__

=pod

=encoding UTF-8

lib/App/SpreadRevolutionaryDate/Config.pm  view on Meta::CPAN

USAGE
 exit 0;
}


no Moose;
__PACKAGE__->meta->make_immutable(inline_constructor => 0);

# A module must return a true value. Traditionally, a module returns 1.
# But this module is a revolutionary one, so it discards all old traditions.
# Idea borrowed from Jean Forget's DateTime::Calendar::FrenchRevolutionary.
"Quand le gouvernement viole les droits du peuple,
l'insurrection est pour le peuple le plus sacré
et le plus indispensable des devoirs";

__END__

=pod

=encoding UTF-8

lib/App/SpreadRevolutionaryDate/MsgMaker.pm  view on Meta::CPAN

  is => 'ro',
  isa => 'Str',
  default => 'f',
);

requires 'compute';


# A module must return a true value. Traditionally, a module returns 1.
# But this module is a revolutionary one, so it discards all old traditions.
# Idea borrowed from Jean Forget's DateTime::Calendar::FrenchRevolutionary.
"Quand le gouvernement viole les droits du peuple,
l'insurrection est pour le peuple le plus sacré
et le plus indispensable des devoirs";

__END__

=pod

=encoding UTF-8

lib/App/SpreadRevolutionaryDate/MsgMaker/Gemini.pm  view on Meta::CPAN

#
use 5.014;
use utf8;
package App::SpreadRevolutionaryDate::MsgMaker::Gemini;
$App::SpreadRevolutionaryDate::MsgMaker::Gemini::VERSION = '0.51';
# ABSTRACT: MsgMaker class for L<App::SpreadRevolutionaryDate> to build message with Gemini prompt

use Moose;
with 'App::SpreadRevolutionaryDate::MsgMaker';

use DateTime;
use File::ShareDir ':ALL';
use LWP::UserAgent;
use JSON;

use Locale::TextDomain 'App-SpreadRevolutionaryDate';
use namespace::autoclean;

has 'api_key' => (
  is  => 'ro',
  isa => 'Str',

lib/App/SpreadRevolutionaryDate/MsgMaker/Gemini.pm  view on Meta::CPAN


  return $class->$orig(%args);
};


sub compute {
  my $self = shift;

  my $url = 'https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key= ' . $self->api_key;

  my $today = DateTime->now(locale => $self->locale);
  my $prompt = $self->prompt->{$self->process};
  my @vars = $self->prompt->{$self->process} =~ /\$(\w+)/g;
  foreach my $var (@vars) {
    $prompt =~ s/\$$var/$today->$var/e;
  }

  my $payload = {
    contents => [
      {
        parts => [

lib/App/SpreadRevolutionaryDate/MsgMaker/Gemini.pm  view on Meta::CPAN

  $img->{alt} = $self->img_alt->{$self->process} if $self->img_alt && $self->img_alt->{$self->process};
  return ($msg, $img);
}


no Moose;
__PACKAGE__->meta->make_immutable;

# A module must return a true value. Traditionally, a module returns 1.
# But this module is a revolutionary one, so it discards all old traditions.
# Idea borrowed from Jean Forget's DateTime::Calendar::FrenchRevolutionary.
"Quand le gouvernement viole les droits du peuple,
l'insurrection est pour le peuple le plus sacré
et le plus indispensable des devoirs";

__END__

=pod

=encoding UTF-8

lib/App/SpreadRevolutionaryDate/MsgMaker/PromptUser.pm  view on Meta::CPAN

    return ($msg, undef);
  }
}


no Moose;
__PACKAGE__->meta->make_immutable;

# A module must return a true value. Traditionally, a module returns 1.
# But this module is a revolutionary one, so it discards all old traditions.
# Idea borrowed from Jean Forget's DateTime::Calendar::FrenchRevolutionary.
"Quand le gouvernement viole les droits du peuple,
l'insurrection est pour le peuple le plus sacré
et le plus indispensable des devoirs";

__END__

=pod

=encoding UTF-8

lib/App/SpreadRevolutionaryDate/MsgMaker/RevolutionaryDate.pm  view on Meta::CPAN

  my $self = shift;

  # As of App::SpreadRevolutionaryDate 0.11
  # locale is limited to 'fr', 'en', 'it' or 'es', defaults to 'fr'
  # forced to 'fr' for any other value
  my $revolutionary = $self->acab ?
      App::SpreadRevolutionaryDate::MsgMaker::RevolutionaryDate::Calendar->now->set(hour => 1, minute => 31, second => 20, locale => $self->locale)
    : App::SpreadRevolutionaryDate::MsgMaker::RevolutionaryDate::Calendar->now->set(locale => $self->locale);

  my $feast_long = $revolutionary->feast_long;
  my $today = DateTime->today;
  if ($self->special_birthday_day && $self->special_birthday_month && $self->special_birthday_name && $today->day == $self->special_birthday_day && $today->month == $self->special_birthday_month) {
      $feast_long = $revolutionary->locale->prefixes->[$self->special_birthday_prefix] . $self->special_birthday_name . $revolutionary->locale->suffix;
  }

  my $msg = __x("We are {day_name}, {day} {month} of Revolution year {roman_year} ({year}), {feast_long}, it is {time}!",
      day_name   => $revolutionary->day_name,
      day        => $revolutionary->day,
      month      => $revolutionary->month_name,
      roman_year => $revolutionary->strftime("%EY"),
      year       => $revolutionary->year,

lib/App/SpreadRevolutionaryDate/MsgMaker/RevolutionaryDate.pm  view on Meta::CPAN


  return ($msg, undef);
}


no Moose;
__PACKAGE__->meta->make_immutable;

# A module must return a true value. Traditionally, a module returns 1.
# But this module is a revolutionary one, so it discards all old traditions.
# Idea borrowed from Jean Forget's DateTime::Calendar::FrenchRevolutionary.
"Quand le gouvernement viole les droits du peuple,
l'insurrection est pour le peuple le plus sacré
et le plus indispensable des devoirs";

__END__

=pod

=encoding UTF-8

lib/App/SpreadRevolutionaryDate/MsgMaker/RevolutionaryDate/Calendar.pm  view on Meta::CPAN

# This software is Copyright (c) 2019-2025 by Gérald Sédrati.
#
# This is free software, licensed under:
#
#   The GNU General Public License, Version 3, June 2007
#
use 5.014;
use utf8;
package App::SpreadRevolutionaryDate::MsgMaker::RevolutionaryDate::Calendar;
$App::SpreadRevolutionaryDate::MsgMaker::RevolutionaryDate::Calendar::VERSION = '0.51';
# ABSTRACT: Subclass overloading L<DateTime::Calendar::FrenchRevolutionary> to allow language extension

use Moose;
use MooseX::NonMoose;
extends 'DateTime::Calendar::FrenchRevolutionary';

use Class::Load ':all';
use namespace::autoclean;


sub set {
  my $self = shift;
  my %args = @_;

  my $locale_arg = delete $args{locale};

lib/App/SpreadRevolutionaryDate/MsgMaker/RevolutionaryDate/Calendar.pm  view on Meta::CPAN


  return $self;
}


no Moose;
__PACKAGE__->meta->make_immutable;

# A module must return a true value. Traditionally, a module returns 1.
# But this module is a revolutionary one, so it discards all old traditions.
# Idea borrowed from Jean Forget's DateTime::Calendar::FrenchRevolutionary.
"Quand le gouvernement viole les droits du peuple,
l'insurrection est pour le peuple le plus sacré
et le plus indispensable des devoirs";

__END__

=pod

=encoding UTF-8

=head1 NAME

App::SpreadRevolutionaryDate::MsgMaker::RevolutionaryDate::Calendar - Subclass overloading L<DateTime::Calendar::FrenchRevolutionary> to allow language extension

=head1 VERSION

version 0.51

=head1 METHODS

=head2 set

Overloads L<DateTime::Calendar::FrenchRevolutionary> to allow setting locale, extending 'fr' and 'en'.

=head1 SEE ALSO

=over

=item L<spread-revolutionary-date>

=item L<App::SpreadRevolutionaryDate>

=item L<App::SpreadRevolutionaryDate::Config>

lib/App/SpreadRevolutionaryDate/MsgMaker/RevolutionaryDate/Locale.pm  view on Meta::CPAN

#   The GNU General Public License, Version 3, June 2007
#
use 5.014;
use utf8;
package App::SpreadRevolutionaryDate::MsgMaker::RevolutionaryDate::Locale;
$App::SpreadRevolutionaryDate::MsgMaker::RevolutionaryDate::Locale::VERSION = '0.51';
# ABSTRACT: Role providing interface for localization of revolutionary date built by L<App::SpreadRevolutionaryDate::MsgMaker::RevolutionaryDate>.

use Moose::Role;

use DateTime::Calendar::FrenchRevolutionary;

use Locale::TextDomain 'App-SpreadRevolutionaryDate';
use namespace::autoclean;

has months => (
  is => 'ro',
  isa => 'ArrayRef[Str]',
  required => 1,
);

lib/App/SpreadRevolutionaryDate/MsgMaker/RevolutionaryDate/Locale.pm  view on Meta::CPAN

  my ($self, $month, $entry) = @_;
  $entry = $self->wikipedia_entries->{$month}->{$entry}
      if    exists $self->wikipedia_entries->{$month}
         && exists $self->wikipedia_entries->{$month}->{$entry};
  return $entry;
}


# A module must return a true value. Traditionally, a module returns 1.
# But this module is a revolutionary one, so it discards all old traditions.
# Idea borrowed from Jean Forget's DateTime::Calendar::FrenchRevolutionary.
"Quand le gouvernement viole les droits du peuple,
l'insurrection est pour le peuple le plus sacré
et le plus indispensable des devoirs";

__END__

=pod

=encoding UTF-8

lib/App/SpreadRevolutionaryDate/MsgMaker/RevolutionaryDate/Locale.pm  view on Meta::CPAN

App::SpreadRevolutionaryDate::MsgMaker::RevolutionaryDate::Locale - Role providing interface for localization of revolutionary date built by L<App::SpreadRevolutionaryDate::MsgMaker::RevolutionaryDate>.

=head1 VERSION

version 0.51

=head1 DESCRIPTION

This role defines the localization interface for L<App::SpreadRevolutionaryDate::MsgMaker::RevolutionaryDate>.

It provides some methods copied from L<DateTime::Calendar::FrenchRevolutionary::Locale::fr>.

Any class consuming this role is required to overload every mandatory attribute with a default in the language of that class:

=over

=item months

Default for this attribute should be a sorted array reference of 13 strings, each of them translating the name of each month (C<'Vendémiaire'>, C<'Brumaire'>,  C<'Frimaire'>, C<'Nivôse'>, C<'Pluviôse'>, C<'Ventôse'>, C<'Germinal'>, C<'Floréal'>,...

  has '+months' => (

lib/App/SpreadRevolutionaryDate/MsgMaker/RevolutionaryDate/Locale.pm  view on Meta::CPAN

      },
    }},
  );

=back

=head1 METHODS

=head2 month_name

Returns the name of the month. Takes a L<DateTime::Calendar::FrenchRevolutionary> object as mandatory parameter.

=head2 day_name

Returns the name of the day. Takes a L<DateTime::Calendar::FrenchRevolutionary> object as mandatory parameter.

=head2 feast_short

Returns the feast of the day. Takes a L<DateTime::Calendar::FrenchRevolutionary> object as mandatory parameter.

=head2 feast_long

Returns the feast of the day in long format (I<day of E<lt>xxxE<gt>>). Takes a L<DateTime::Calendar::FrenchRevolutionary> object as mandatory parameter.

=head2 wikipedia_redirect

Returns the wikipedia entry (the end of the wikipedia url) corresponding to the feast of the day. Takes two mandatory parameters: the month as integer from 1 to 13 (13 is used for complementary days, also called "sans-culottides"), and the search ent...

=head1 SEE ALSO

=over

=item L<spread-revolutionary-date>

lib/App/SpreadRevolutionaryDate/MsgMaker/RevolutionaryDate/Locale/en.pm  view on Meta::CPAN

# This software is Copyright (c) 2019-2025 by Gérald Sédrati.
#
# This is free software, licensed under:
#
#   The GNU General Public License, Version 3, June 2007
#
use 5.014;
use utf8;
package App::SpreadRevolutionaryDate::MsgMaker::RevolutionaryDate::Locale::en;
$App::SpreadRevolutionaryDate::MsgMaker::RevolutionaryDate::Locale::en::VERSION = '0.51';
# ABSTRACT: English localization of (part of) L<DateTime::Calendar::FrenchRevolutionary::Locale::en>

use Moose;
with 'App::SpreadRevolutionaryDate::MsgMaker::RevolutionaryDate::Locale';

use Locale::TextDomain 'App-SpreadRevolutionaryDate';
use namespace::autoclean;


has '+months' => (
  default => sub {[

lib/App/SpreadRevolutionaryDate/MsgMaker/RevolutionaryDate/Locale/en.pm  view on Meta::CPAN

    },
  }},
);

no Moose;
__PACKAGE__->meta->make_immutable;


# A module must return a true value. Traditionally, a module returns 1.
# But this module is a revolutionary one, so it discards all old traditions.
# Idea borrowed from Jean Forget's DateTime::Calendar::FrenchRevolutionary.
"Quand le gouvernement viole les droits du peuple,
l'insurrection est pour le peuple le plus sacré
et le plus indispensable des devoirs";

__END__

=pod

=encoding UTF-8

=head1 NAME

App::SpreadRevolutionaryDate::MsgMaker::RevolutionaryDate::Locale::en - English localization of (part of) L<DateTime::Calendar::FrenchRevolutionary::Locale::en>

=head1 VERSION

version 0.51

=head1 DESCRIPTION

This modules copies and fixes some of the English translations of L<DateTime::Calendar::FrenchRevolutionary::Locale::en>, which bases its translation on:

=over

=item [Carlyle]

"The French Revolution: A History", Thomas Carlyle, 1837, Ed. K. J. Fielding and David Sorensen, The World’s Classics, Oxford, New York,  Oxford University Press, 1989.

=item [Taylor]

Alan Taylor's web site: L<http://www.kokogiak.com/frc/default.asp>.

lib/App/SpreadRevolutionaryDate/MsgMaker/RevolutionaryDate/Locale/en.pm  view on Meta::CPAN

Jonathan Badger's French Revolutionary Calendar module written in Ruby

L<https://github.com/jhbadger/FrenchRevCal-ruby>.

=item [Wikipedia]

L<http://en.wikipedia.org/wiki/French_Republican_Calendar>.

=back

When L<DateTime::Calendar::FrenchRevolutionary::Locale::en> leaves some translations as doubtful, they are fixed here based on Wikipedia.

=head1 SEE ALSO

=over

=item L<spread-revolutionary-date>

=item L<App::SpreadRevolutionaryDate>

=item L<App::SpreadRevolutionaryDate::Config>

lib/App/SpreadRevolutionaryDate/MsgMaker/RevolutionaryDate/Locale/es.pm  view on Meta::CPAN

# This software is Copyright (c) 2019-2025 by Gérald Sédrati.
#
# This is free software, licensed under:
#
#   The GNU General Public License, Version 3, June 2007
#
use 5.014;
use utf8;
package App::SpreadRevolutionaryDate::MsgMaker::RevolutionaryDate::Locale::es;
$App::SpreadRevolutionaryDate::MsgMaker::RevolutionaryDate::Locale::es::VERSION = '0.51';
# ABSTRACT: Spanish localization of (part of) L<DateTime::Calendar::FrenchRevolutionary::Locale::fr>

use Moose;
with 'App::SpreadRevolutionaryDate::MsgMaker::RevolutionaryDate::Locale';

use Locale::TextDomain 'App-SpreadRevolutionaryDate';
use namespace::autoclean;


has '+months' => (
  default => sub {[

lib/App/SpreadRevolutionaryDate/MsgMaker/RevolutionaryDate/Locale/es.pm  view on Meta::CPAN

    },
  }},
);

no Moose;
__PACKAGE__->meta->make_immutable;


# A module must return a true value. Traditionally, a module returns 1.
# But this module is a revolutionary one, so it discards all old traditions.
# Idea borrowed from Jean Forget's DateTime::Calendar::FrenchRevolutionary.
"Quand le gouvernement viole les droits du peuple,
l'insurrection est pour le peuple le plus sacré
et le plus indispensable des devoirs";

__END__

=pod

=encoding UTF-8

=head1 NAME

App::SpreadRevolutionaryDate::MsgMaker::RevolutionaryDate::Locale::es - Spanish localization of (part of) L<DateTime::Calendar::FrenchRevolutionary::Locale::fr>

=head1 VERSION

version 0.51

=head1 DESCRIPTION

This modules adds Spanish translations to L<DateTime::Calendar::FrenchRevolutionary>, based on Wikipedia: L<https://es.wikipedia.org/wiki/Calendario_republicano_franc%C3%A9s>.

=head1 SEE ALSO

=over

=item L<spread-revolutionary-date>

=item L<App::SpreadRevolutionaryDate>

=item L<App::SpreadRevolutionaryDate::Config>

lib/App/SpreadRevolutionaryDate/MsgMaker/RevolutionaryDate/Locale/fr.pm  view on Meta::CPAN

# This software is Copyright (c) 2019-2025 by Gérald Sédrati.
#
# This is free software, licensed under:
#
#   The GNU General Public License, Version 3, June 2007
#
use 5.014;
use utf8;
package App::SpreadRevolutionaryDate::MsgMaker::RevolutionaryDate::Locale::fr;
$App::SpreadRevolutionaryDate::MsgMaker::RevolutionaryDate::Locale::fr::VERSION = '0.51';
# ABSTRACT: French localization of (part of) L<DateTime::Calendar::FrenchRevolutionary::Locale::fr>

use Moose;
with 'App::SpreadRevolutionaryDate::MsgMaker::RevolutionaryDate::Locale';

use Locale::TextDomain 'App-SpreadRevolutionaryDate';
use namespace::autoclean;


has '+months' => (
  default => sub {[

lib/App/SpreadRevolutionaryDate/MsgMaker/RevolutionaryDate/Locale/fr.pm  view on Meta::CPAN

    },
  }},
);

no Moose;
__PACKAGE__->meta->make_immutable;


# A module must return a true value. Traditionally, a module returns 1.
# But this module is a revolutionary one, so it discards all old traditions.
# Idea borrowed from Jean Forget's DateTime::Calendar::FrenchRevolutionary.
"Quand le gouvernement viole les droits du peuple,
l'insurrection est pour le peuple le plus sacré
et le plus indispensable des devoirs";

__END__

=pod

=encoding UTF-8

=head1 NAME

App::SpreadRevolutionaryDate::MsgMaker::RevolutionaryDate::Locale::fr - French localization of (part of) L<DateTime::Calendar::FrenchRevolutionary::Locale::fr>

=head1 VERSION

version 0.51

=head1 DESCRIPTION

This modules copies and fixes some of the French translations of L<DateTime::Calendar::FrenchRevolutionary::Locale::fr>.

Sources:

=over

=item [Décret]

"Annuaire ou calendrier pour la seconde année de la République française, annexe du décret du 4 frimaire, an II (24 novembre 1793) sur l'ère, le commencement et l'organisation de l'année et sur les noms des jours et des mois" ; in J. Madival an...

=item [Fabre]

lib/App/SpreadRevolutionaryDate/MsgMaker/RevolutionaryDate/Locale/it.pm  view on Meta::CPAN

# This software is Copyright (c) 2019-2025 by Gérald Sédrati.
#
# This is free software, licensed under:
#
#   The GNU General Public License, Version 3, June 2007
#
use 5.014;
use utf8;
package App::SpreadRevolutionaryDate::MsgMaker::RevolutionaryDate::Locale::it;
$App::SpreadRevolutionaryDate::MsgMaker::RevolutionaryDate::Locale::it::VERSION = '0.51';
# ABSTRACT: Italian localization of (part of) L<DateTime::Calendar::FrenchRevolutionary>

use Moose;
with 'App::SpreadRevolutionaryDate::MsgMaker::RevolutionaryDate::Locale';

use Locale::TextDomain 'App-SpreadRevolutionaryDate';
use namespace::autoclean;


has '+months' => (
  default => sub {[

lib/App/SpreadRevolutionaryDate/MsgMaker/RevolutionaryDate/Locale/it.pm  view on Meta::CPAN

    },
  }},
);

no Moose;
__PACKAGE__->meta->make_immutable;


# A module must return a true value. Traditionally, a module returns 1.
# But this module is a revolutionary one, so it discards all old traditions.
# Idea borrowed from Jean Forget's DateTime::Calendar::FrenchRevolutionary.
"Quand le gouvernement viole les droits du peuple,
l'insurrection est pour le peuple le plus sacré
et le plus indispensable des devoirs";

__END__

=pod

=encoding UTF-8

=head1 NAME

App::SpreadRevolutionaryDate::MsgMaker::RevolutionaryDate::Locale::it - Italian localization of (part of) L<DateTime::Calendar::FrenchRevolutionary>

=head1 VERSION

version 0.51

=head1 DESCRIPTION

This modules adds Italian translations to L<DateTime::Calendar::FrenchRevolutionary>, based on Wikipedia: L<https://it.wikipedia.org/wiki/Calendario_rivoluzionario_francese>.

=head1 SEE ALSO

=over

=item L<spread-revolutionary-date>

=item L<App::SpreadRevolutionaryDate>

=item L<App::SpreadRevolutionaryDate::Config>

lib/App/SpreadRevolutionaryDate/MsgMaker/Telechat.pm  view on Meta::CPAN

#
use 5.014;
use utf8;
package App::SpreadRevolutionaryDate::MsgMaker::Telechat;
$App::SpreadRevolutionaryDate::MsgMaker::Telechat::VERSION = '0.51';
# ABSTRACT: MsgMaker class for L<App::SpreadRevolutionaryDate> to build message with Téléchat date

use Moose;
with 'App::SpreadRevolutionaryDate::MsgMaker';

use DateTime;
use File::ShareDir ':ALL';
use App::SpreadRevolutionaryDate;

use Locale::TextDomain 'App-SpreadRevolutionaryDate';
use namespace::autoclean;

has '+locale' => (
  default => 'fr',
);

lib/App/SpreadRevolutionaryDate/MsgMaker/Telechat.pm  view on Meta::CPAN

      '1227' => ['pyréolophore', 'pyréolophores', 'm'],
      '1228' => ['soubassophone', 'soubassophones', 'm'],
      '1229' => ['vastringue', 'vastringues', 'm'],
      '1230' => ['vocifération sportive', 'vociférations sportives', 'f'],
      '1231' => ['connotation de proximité temporelle', 'connotations de proximité temporelle', 'f'],
    },
  );

  my @telechat_days = ('Lourdi', 'Pardi', 'Morquidi', 'Jourdi', 'Dendrevi', 'Sordi', 'Mitanche');

  my $today = DateTime->now(locale => $self->locale);
  my $day_name = $telechat_days[$today->day_of_week_0];

  my @calendars = sort keys %telechat_calendars;
  my $calendar_key = sprintf("%02d", $today->month).sprintf("%02d", $today->day);
  shift @calendars unless $telechat_calendars{'0tvtime'}->{$calendar_key};
  my $chosen_calendar = @calendars[rand @calendars];
  my $feast = $telechat_calendars{$chosen_calendar}->{$calendar_key};
  my $feast_gender = $feast->[2] eq 'm' ? 'Saint' : 'Sainte';
  my $feast_singular = $feast->[0];
  $feast_singular =~ s/\b(\w)/\U$1/g;

lib/App/SpreadRevolutionaryDate/MsgMaker/Telechat.pm  view on Meta::CPAN


  return ($msg, $img);
}


no Moose;
__PACKAGE__->meta->make_immutable;

# A module must return a true value. Traditionally, a module returns 1.
# But this module is a revolutionary one, so it discards all old traditions.
# Idea borrowed from Jean Forget's DateTime::Calendar::FrenchRevolutionary.
"Quand le gouvernement viole les droits du peuple,
l'insurrection est pour le peuple le plus sacré
et le plus indispensable des devoirs";

__END__

=pod

=encoding UTF-8

lib/App/SpreadRevolutionaryDate/Target.pm  view on Meta::CPAN

    my $str = substr $text, 0, $loc, '';
    push @msgs, $str;
    substr $text, 0, 1, '';
  }
  return @msgs;
}


# A module must return a true value. Traditionally, a module returns 1.
# But this module is a revolutionary one, so it discards all old traditions.
# Idea borrowed from Jean Forget's DateTime::Calendar::FrenchRevolutionary.
"Quand le gouvernement viole les droits du peuple,
l'insurrection est pour le peuple le plus sacré
et le plus indispensable des devoirs";

__END__

=pod

=encoding UTF-8

lib/App/SpreadRevolutionaryDate/Target/Bluesky.pm  view on Meta::CPAN

    }
  }
}


no Moose;
__PACKAGE__->meta->make_immutable;

# A module must return a true value. Traditionally, a module returns 1.
# But this module is a revolutionary one, so it discards all old traditions.
# Idea borrowed from Jean Forget's DateTime::Calendar::FrenchRevolutionary.
"Quand le gouvernement viole les droits du peuple,
l'insurrection est pour le peuple le plus sacré
et le plus indispensable des devoirs";

__END__

=pod

=encoding UTF-8

lib/App/SpreadRevolutionaryDate/Target/Freenode.pm  view on Meta::CPAN

  $self->obj->run;
  POE::Kernel->run();
}


no Moose;
__PACKAGE__->meta->make_immutable;

# A module must return a true value. Traditionally, a module returns 1.
# But this module is a revolutionary one, so it discards all old traditions.
# Idea borrowed from Jean Forget's DateTime::Calendar::FrenchRevolutionary.
"Quand le gouvernement viole les droits du peuple,
l'insurrection est pour le peuple le plus sacré
et le plus indispensable des devoirs";

__END__

=pod

=encoding UTF-8

lib/App/SpreadRevolutionaryDate/Target/Freenode/Bot.pm  view on Meta::CPAN


  return;
}


no Moose;
__PACKAGE__->meta->make_immutable;

# A module must return a true value. Traditionally, a module returns 1.
# But this module is a revolutionary one, so it discards all old traditions.
# Idea borrowed from Jean Forget's DateTime::Calendar::FrenchRevolutionary.
"Quand le gouvernement viole les droits du peuple,
l'insurrection est pour le peuple le plus sacré
et le plus indispensable des devoirs";

__END__

=pod

=encoding UTF-8

lib/App/SpreadRevolutionaryDate/Target/Liberachat.pm  view on Meta::CPAN

  $self->obj->run;
  POE::Kernel->run();
}


no Moose;
__PACKAGE__->meta->make_immutable;

# A module must return a true value. Traditionally, a module returns 1.
# But this module is a revolutionary one, so it discards all old traditions.
# Idea borrowed from Jean Forget's DateTime::Calendar::FrenchRevolutionary.
"Quand le gouvernement viole les droits du peuple,
l'insurrection est pour le peuple le plus sacré
et le plus indispensable des devoirs";

__END__

=pod

=encoding UTF-8

lib/App/SpreadRevolutionaryDate/Target/Liberachat/Bot.pm  view on Meta::CPAN


  return;
}


no Moose;
__PACKAGE__->meta->make_immutable;

# A module must return a true value. Traditionally, a module returns 1.
# But this module is a revolutionary one, so it discards all old traditions.
# Idea borrowed from Jean Forget's DateTime::Calendar::FrenchRevolutionary.
"Quand le gouvernement viole les droits du peuple,
l'insurrection est pour le peuple le plus sacré
et le plus indispensable des devoirs";

__END__

=pod

=encoding UTF-8

lib/App/SpreadRevolutionaryDate/Target/Mastodon.pm  view on Meta::CPAN

    }
  }
}


no Moose;
__PACKAGE__->meta->make_immutable;

# A module must return a true value. Traditionally, a module returns 1.
# But this module is a revolutionary one, so it discards all old traditions.
# Idea borrowed from Jean Forget's DateTime::Calendar::FrenchRevolutionary.
"Quand le gouvernement viole les droits du peuple,
l'insurrection est pour le peuple le plus sacré
et le plus indispensable des devoirs";

__END__

=pod

=encoding UTF-8

lib/App/SpreadRevolutionaryDate/Target/Twitter.pm  view on Meta::CPAN

    $self->obj->post('tweets', {'-to_json' => {"text" => $msg}});
  }
}


no Moose;
__PACKAGE__->meta->make_immutable;

# A module must return a true value. Traditionally, a module returns 1.
# But this module is a revolutionary one, so it discards all old traditions.
# Idea borrowed from Jean Forget's DateTime::Calendar::FrenchRevolutionary.
"Quand le gouvernement viole les droits du peuple,
l'insurrection est pour le peuple le plus sacré
et le plus indispensable des devoirs";

__END__

=pod

=encoding UTF-8



( run in 0.469 second using v1.01-cache-2.11-cpan-05444aca049 )