- move translations to a separate file
authorAndreas Scherbaum <andreas@scherbaum.biz>
Wed, 8 Aug 2012 23:23:36 +0000 (01:23 +0200)
committerAndreas Scherbaum <andreas@scherbaum.biz>
Wed, 8 Aug 2012 23:23:36 +0000 (01:23 +0200)
config.pm
docbot.conf
docbot.pl
docbot.translations [new file with mode: 0644]
todo.txt

index 88cf6465eae495eb50b02bc15cdd012d0d68a747..fcabf640b07ba1dd3f1f6d4c932eef84e73e422c 100755 (executable)
--- a/config.pm
+++ b/config.pm
@@ -36,6 +36,53 @@ use Data::Dumper;
 use YAML::XS qw (/./);
 
 
+# from Hash::Merge, modified
+my ( $GLOBAL );
+$GLOBAL = {};
+bless $GLOBAL;
+$GLOBAL->{'behaviors'} = {
+    'LEFT_PRECEDENT' => {
+        'SCALAR' => {
+            'SCALAR' => sub { $_[0] },
+            'ARRAY'  => sub { $_[0] },
+            'HASH'   => sub { $_[0] },
+        },
+        'ARRAY' => {
+            'SCALAR' => sub { [ @{ $_[0] }, $_[1] ] },
+            'ARRAY'  => sub { [ @{ $_[0] }, @{ $_[1] } ] },
+            'HASH'   => sub { [ @{ $_[0] }, values %{ $_[1] } ] },
+        },
+        'HASH' => {
+            'SCALAR' => sub { $_[0] },
+            'ARRAY'  => sub { $_[0] },
+            'HASH'   => sub { _merge_hashes( $_[0], $_[1] ) },
+        },
+    },
+
+    'RIGHT_PRECEDENT' => {
+        'SCALAR' => {
+            'SCALAR' => sub { $_[1] },
+            'ARRAY'  => sub { [ $_[0], @{ $_[1] } ] },
+            'HASH'   => sub { $_[1] },
+        },
+        'ARRAY' => {
+            'SCALAR' => sub { $_[1] },
+            'ARRAY'  => sub { [ @{ $_[0] }, @{ $_[1] } ] },
+            'HASH'   => sub { $_[1] },
+        },
+        'HASH' => {
+            'SCALAR' => sub { $_[1] },
+            'ARRAY'  => sub { [ values %{ $_[0] }, @{ $_[1] } ] },
+            'HASH'   => sub { _merge_hashes( $_[0], $_[1] ) },
+        },
+    },
+};
+$GLOBAL->{'behavior'} = 'LEFT_PRECEDENT';
+$GLOBAL->{'matrix'}   = $GLOBAL->{behaviors}{ $GLOBAL->{'behavior'} };
+
+
+
+
 # new()
 #
 # constructor
@@ -110,6 +157,110 @@ sub read_config {
 }
 
 
+# read_additional_config()
+#
+# read in a additional config file
+#
+# parameter:
+#  - self
+#  - config filename
+# return:
+#  none
+sub read_additional_config {
+    my $self = shift;
+    my $config_file = shift;
+
+    # test if config file exists
+    if (!-f $config_file) {
+        die "could not find config file: $config_file\n";
+    }
+
+    my $config = LoadFile($config_file);
+
+    my $orig = $self->{config};
+    my $new = $config;
+    my %combined = %{ _merge_hashes( $orig, $new ) };
+
+    # store config
+    $self->{config} = \%combined;
+
+    return;
+}
+
+
+# from Hash::Merge, modified
+#
+# merge_hashes()
+#
+# merge two hashes
+#
+# parameter:
+#  - hash pointer 1
+#  - hash pointer 2
+# return:
+#  - combined hash
+sub merge_hashes {
+    my ( $left, $right ) = @_;
+
+    # For the general use of this module, we want to create duplicates
+    # of all data that is merged.  This behavior can be shut off, but
+    # can create havoc if references are used heavily.
+
+    my $lefttype =
+        ref $left eq 'HASH'  ? 'HASH'
+      : ref $left eq 'ARRAY' ? 'ARRAY'
+      :                        'SCALAR';
+
+    my $righttype =
+        ref $right eq 'HASH'  ? 'HASH'
+      : ref $right eq 'ARRAY' ? 'ARRAY'
+      :                         'SCALAR';
+
+    return $GLOBAL->{'matrix'}->{$lefttype}{$righttype}->( $left, $right );
+}
+
+
+# This does a straight merge of hashes, delegating the merge-specific
+# work to 'merge_hashes'
+
+# from Hash::Merge, modified
+#
+# _merge_hashes()
+#
+# worker function to merge two hashes
+#
+# parameter:
+#  - hash pointer 1
+#  - hash pointer 2
+# return:
+#  - combined hash
+sub _merge_hashes {
+    my ( $left, $right ) = ( shift, shift );
+    if ( ref $left ne 'HASH' || ref $right ne 'HASH' ) {
+        print STDERR "Arguments for _merge_hashes must be hash references\n";
+        exit();
+    }
+
+    my %newhash;
+    foreach my $leftkey ( keys %$left ) {
+        if ( exists $right->{$leftkey} ) {
+            $newhash{$leftkey} = merge_hashes( $left->{$leftkey}, $right->{$leftkey} );
+        }
+        else {
+            $newhash{$leftkey} = $left->{$leftkey};
+        }
+    }
+
+    foreach my $rightkey ( keys %$right ) {
+        if ( !exists $left->{$rightkey} ) {
+            $newhash{$rightkey} = $right->{$rightkey};
+        }
+    }
+
+    return \%newhash;
+}
+
+
 # reread_config()
 #
 # reread an already readed configfile
index 0d684d3a44465714ee315bb3ec73050bca241583..c716513f6fe8c3ab1ff4a4ec5c14fd8b2904ca5d 100644 (file)
@@ -55,72 +55,4 @@ search:
   maxwrap: 2
   searchsite: 'http://pg-docbot.de/search/?q='
 translations:
-  de:
-    learn: 'lerne|lernen'
-    forget: 'vergesse|vergessen'
-    config: 'konfiguriere'
-    help: 'hilfe'
-    search: 'suche'
-    say: 'sage'
-    key: 'Schlüsselwort'
-    successfully_added_1_keyword: 'Ein Schlüsselwort hinzugefügt'
-    successfully_added_1_url: 'Eine URL hinzugefügt'
-    successfully_added_x_keyword: '% Schlüsselwörter hinzugefügt'
-    successfully_added_x_url: 'X URLs hinzugefügt'
-    successfully_deleted_1_keyword: 'Ein Schlüsselwort gelöscht'
-    successfully_deleted_1_url: 'Eine URL gelöscht'
-    successfully_deleted_x_keyword: '% Schlüsselwörter gelöscht'
-    successfully_deleted_x_url: '% URLs gelöscht'
-    url_not_found: 'URL nicht gefunden'
-    urls_not_found: 'URLs nicht gefunden'
-    keyword_not_found: 'Schlüsselwort nicht gefunden'
-    keywords_not_found: 'Schlüsselwörter nicht gefunden'
-    nothing_found: 'Nichts gefunden'
-    additional_information_at: 'Weitere Informationen unter'
-    you_are_not_authorized: 'Sie sind nicht authorisiert'
-    access_denied: 'Zugriff verweigert'
-    invalid_search: 'Ungültige Suche'
-    database_error: 'Datenbankfehler'
-    more_results_at: 'Mehr Ergebnisse unter'
-    more_result: 'weiteres Ergebnis'
-    more_results: 'weitere Ergebnisse'
-    error_wallchan_command_parameter: 'Der "wallchan" Befehl erfordert einen Parameter'
-    error_url_command_parameter: 'Der "url" Befehl erfordert einen Parameter'
-    error_key_command_parameter: 'Der "key" Befehl erfordert einen Parameter'
-    wallchan_command_message: 'Nachricht vom Operator'
-    error_say_command_parameter: 'Der "say" Befehl erfordert zwei Parameter'
-    error_say_not_joined: 'Der Bot ist nicht in diesem Channel'
-    error_join_command_parameter: 'Der "join" Befehl erfordert zwei Parameter'
-    error_join_already_joined: 'Der Bot ist bereits in diesem Channel'
-    error_leave_command_parameter: 'Der "leave" Befehl erfordert einen Parameter'
-    error_leave_not_joined: 'Der Bot ist nicht in diesem Channel'
-    help_general_line_1: 'Allgemeine Hilfe'
-    help_general_line_2: 'Starte eine Suche mit zwei Fragezeichen, danach der Suchbegriff'
-    help_general_line_3: 'Die folgenden Befehle stehen außerdem zur Verfügung'
-    help_general_line_say: 'Nutze: ?sage #channel Nachricht'
-    help_general_line_lost: 'Nutze: ?lost'
-    help_general_line_url: 'Nutze: ?url <URL>'
-    help_general_line_key: 'Nutze: ?key <Schlüsselwort>'
-    help_general_line_quit: 'Nutze: ?quit'
-    lost_only_in_commandchannel: 'Der "lost" Befehl ist nur im Adminchannel erlaubt'
-    url_only_in_commandchannel: 'Der "url" Befehl ist nur im Adminchannel erlaubt'
-    key_only_in_commandchannel: 'Der "key" Befehl ist nur im Adminchannel erlaubt'
-    search_bad_parameters: 'Falsche Parameter'
-    search_no_new_keywords: 'Alle Schlüsselwörter existieren bereits in der Datenbank'
-    search_add_1_keyword: '1 Schlüsselwort erfolgreich hinzugefügt'
-    search_add_n_keywords: '%1 Schlüsselwörter erfolgreich hinzugefügt'
-    search_add_url_1_keyword: 'URL mit 1 Schlüsselwort erfolgreich hinzugefügt'
-    search_add_url_n_keywords: 'URL mit %1 Schlüsselwörtern erfolgreich hinzugefügt'
-    forget_nothing_to_forget: 'Nichts zu vergessen'
-    forget_forgot_1_url: '1 URL vergessen'
-    forget_forgot_n_urls: '%1 URLs vergessen'
-    forget_forgot_1_key: '1 Schlüsselwort vergessen'
-    forget_forgot_n_keys: '%1 Schlüsselwörter vergessen'
-  fr:
-    learn: 'apprendre'
-    forget: 'oublier'
-    help: 'aide'
-  es:
-    learn: 'aprender'
-    forget: 'olvidar'
-    help: 'ayuda'
+  file: 'docbot.translations'
index 444af1c0b512e35285c1daa720998751e986845b..9ed88191b3abcb3dfa305bf27271eb1a3b5d6991 100755 (executable)
--- a/docbot.pl
+++ b/docbot.pl
@@ -23,7 +23,7 @@
 # - add the command to is_valid_command(), is_valid_operator_command() and/or is_valid_admin_command()
 # - add help for the command in handle_command_help()
 # - add the command to the command list in handle_command_help()
-# - add any required translation to docbot.conf
+# - add any required translation to docbot.translations
 
 
 
@@ -94,15 +94,17 @@ $main::help = 0;
 $main::debug = 0;
 $main::debug_traffic = 0;
 $main::config_file = "";
+$main::translations_file = "";
 # parse options
-my $args_init_string = "help h d debug D c=s config=s l=s logfile=s";
+my $args_init_string = "help h d debug D c=s config=s l=s logfile=s t=s translations=s";
 unless (
     GetOptions(
-        'help|h|?'     =>  \$main::help,
-        'debug|d'      =>  \$main::debug,
-        'debug-irc|D'  =>  \$main::debug_traffic,
-        'config|c=s'   =>  \$main::config_file,
-        'logfile|l=s'  =>  \$main::logfile,
+        'help|h|?'          =>  \$main::help,
+        'debug|d'           =>  \$main::debug,
+        'debug-irc|D'       =>  \$main::debug_traffic,
+        'config|c=s'        =>  \$main::config_file,
+        'logfile|l=s'       =>  \$main::logfile,
+        'translations|t=s'  =>  \$main::translations_file,
     )
 ) {
     # There were some errors with parsing command line options - show help.
@@ -130,11 +132,12 @@ if ($main::help == 1) {
   $0 [options]
 
 The following options are available:
-  -h --help       This help
-  -d --debug      Enable debug messages
-  -D --debug-irc  Enable IRC traffic debugging
-  -c --config     Config file (required)
-  -l --logfile    Logfile
+  -h --help          This help
+  -d --debug         Enable debug messages
+  -D --debug-irc     Enable IRC traffic debugging
+  -c --config        Config file (required)
+  -l --logfile       Logfile
+  -t --translations  Translations
 
 _END_OF_HELP_
     exit(0);
@@ -151,6 +154,9 @@ if (length($main::config_file) > 0) {
 }
 
 
+init_translations();
+read_translations($main::translations_file);
+
 init_database();
 init_sessions();
 
@@ -412,6 +418,53 @@ sub read_config {
 }
 
 
+# init_translations()
+#
+# init translations
+#
+# parameter:
+#  none
+# return:
+#  none
+sub init_translations {
+
+    if (length($main::translations_file) == 0) {
+        # translations not a commandline parameter
+        # read filename from configuration
+        my $translations_file = config_get_key2('translations', 'file');
+        if (defined($translations_file) and -f $translations_file) {
+            $main::translations_file = $translations_file;
+        } elsif (defined($translations_file)) {
+            print_msg("translations file (" . $translations_file . ") from configuration not found", ERROR);
+            exit(1);
+        }
+    } elsif (!-f $main::translations_file) {
+        print_msg("translations file (" . $main::translations_file . ") from commandline not found", ERROR);
+        exit(1);
+    }
+}
+
+
+# read_translations()
+#
+# read translations
+#
+# parameter:
+#  - translations file name
+# return:
+#  none
+sub read_translations {
+    my $translations_file = shift;
+
+    if (length($translations_file) > 0 and -f $translations_file) {
+        print_msg("Read configuration file: $translations_file", DEBUG);
+        $main::config->read_additional_config($translations_file);
+    } else {
+        print_msg("No translations file available", DEBUG);
+    }
+}
+
+
 # config_get_key1()
 #
 # read configuration value
@@ -1241,7 +1294,7 @@ sub find_command {
         # try to translate the command
         # find the channel language
         my $channel_language = config_get_key3('channels', $channel, 'language');
-        # not defined channel language triggers a full search across all languages
+        # undefined channel language triggers a full search across all languages
         # this is just fine
 
         my $translation = find_translation($channel_language, $command);
diff --git a/docbot.translations b/docbot.translations
new file mode 100644 (file)
index 0000000..57f7b41
--- /dev/null
@@ -0,0 +1,71 @@
+---
+translations:
+  de:
+    learn: 'lerne|lernen'
+    forget: 'vergesse|vergessen'
+    config: 'konfiguriere'
+    help: 'hilfe'
+    search: 'suche'
+    say: 'sage'
+    key: 'Schlüsselwort'
+    successfully_added_1_keyword: 'Ein Schlüsselwort hinzugefügt'
+    successfully_added_1_url: 'Eine URL hinzugefügt'
+    successfully_added_x_keyword: '% Schlüsselwörter hinzugefügt'
+    successfully_added_x_url: 'X URLs hinzugefügt'
+    successfully_deleted_1_keyword: 'Ein Schlüsselwort gelöscht'
+    successfully_deleted_1_url: 'Eine URL gelöscht'
+    successfully_deleted_x_keyword: '% Schlüsselwörter gelöscht'
+    successfully_deleted_x_url: '% URLs gelöscht'
+    url_not_found: 'URL nicht gefunden'
+    urls_not_found: 'URLs nicht gefunden'
+    keyword_not_found: 'Schlüsselwort nicht gefunden'
+    keywords_not_found: 'Schlüsselwörter nicht gefunden'
+    nothing_found: 'Nichts gefunden'
+    additional_information_at: 'Weitere Informationen unter'
+    you_are_not_authorized: 'Sie sind nicht authorisiert'
+    access_denied: 'Zugriff verweigert'
+    invalid_search: 'Ungültige Suche'
+    database_error: 'Datenbankfehler'
+    more_results_at: 'Mehr Ergebnisse unter'
+    more_result: 'weiteres Ergebnis'
+    more_results: 'weitere Ergebnisse'
+    error_wallchan_command_parameter: 'Der "wallchan" Befehl erfordert einen Parameter'
+    error_url_command_parameter: 'Der "url" Befehl erfordert einen Parameter'
+    error_key_command_parameter: 'Der "key" Befehl erfordert einen Parameter'
+    wallchan_command_message: 'Nachricht vom Operator'
+    error_say_command_parameter: 'Der "say" Befehl erfordert zwei Parameter'
+    error_say_not_joined: 'Der Bot ist nicht in diesem Channel'
+    error_join_command_parameter: 'Der "join" Befehl erfordert zwei Parameter'
+    error_join_already_joined: 'Der Bot ist bereits in diesem Channel'
+    error_leave_command_parameter: 'Der "leave" Befehl erfordert einen Parameter'
+    error_leave_not_joined: 'Der Bot ist nicht in diesem Channel'
+    help_general_line_1: 'Allgemeine Hilfe'
+    help_general_line_2: 'Starte eine Suche mit zwei Fragezeichen, danach der Suchbegriff'
+    help_general_line_3: 'Die folgenden Befehle stehen außerdem zur Verfügung'
+    help_general_line_say: 'Nutze: ?sage #channel Nachricht'
+    help_general_line_lost: 'Nutze: ?lost'
+    help_general_line_url: 'Nutze: ?url <URL>'
+    help_general_line_key: 'Nutze: ?key <Schlüsselwort>'
+    help_general_line_quit: 'Nutze: ?quit'
+    lost_only_in_commandchannel: 'Der "lost" Befehl ist nur im Adminchannel erlaubt'
+    url_only_in_commandchannel: 'Der "url" Befehl ist nur im Adminchannel erlaubt'
+    key_only_in_commandchannel: 'Der "key" Befehl ist nur im Adminchannel erlaubt'
+    search_bad_parameters: 'Falsche Parameter'
+    search_no_new_keywords: 'Alle Schlüsselwörter existieren bereits in der Datenbank'
+    search_add_1_keyword: '1 Schlüsselwort erfolgreich hinzugefügt'
+    search_add_n_keywords: '%1 Schlüsselwörter erfolgreich hinzugefügt'
+    search_add_url_1_keyword: 'URL mit 1 Schlüsselwort erfolgreich hinzugefügt'
+    search_add_url_n_keywords: 'URL mit %1 Schlüsselwörtern erfolgreich hinzugefügt'
+    forget_nothing_to_forget: 'Nichts zu vergessen'
+    forget_forgot_1_url: '1 URL vergessen'
+    forget_forgot_n_urls: '%1 URLs vergessen'
+    forget_forgot_1_key: '1 Schlüsselwort vergessen'
+    forget_forgot_n_keys: '%1 Schlüsselwörter vergessen'
+  fr:
+    learn: 'apprendre'
+    forget: 'oublier'
+    help: 'aide'
+  es:
+    learn: 'aprender'
+    forget: 'olvidar'
+    help: 'ayuda'
index b0a027e661ee28a07cf9ae3a9dc5cfedb78ee2b4..50d9d90c50cef46419154cabd65d96b759f23360 100644 (file)
--- a/todo.txt
+++ b/todo.txt
@@ -21,4 +21,4 @@
 - nickserv handling (passwords)
 - implement --help OK
 - verify existence of required tables at startup OK
-- move translations to a separate file
+- move translations to a separate file OK