- add "?user", "?learnuser" and "?forgetuser" command
authorAndreas Scherbaum <andreas@scherbaum.biz>
Sun, 14 Apr 2013 18:33:31 +0000 (20:33 +0200)
committerAndreas Scherbaum <andreas@scherbaum.biz>
Sun, 14 Apr 2013 18:33:31 +0000 (20:33 +0200)
docbot.pl
docbot.translations
sql/changes-2013-04-14.sql [new file with mode: 0644]

index fc3384d2389249d452b9775955d9f24d939644ee..8f3f1ec55bc8a8d6013715430ca7019a787d4710 100755 (executable)
--- a/docbot.pl
+++ b/docbot.pl
@@ -358,29 +358,32 @@ sub init_statistics {
 
     $main::statistics{'docbot_start'} = time();
 
-    $main::statistics{'command_counter_search'}   = 0;
-    $main::statistics{'command_counter_help'}     = 0;
-    $main::statistics{'command_counter_info'}     = 0;
-    $main::statistics{'command_counter_learn'}    = 0;
-    $main::statistics{'command_counter_forget'}   = 0;
-    $main::statistics{'command_counter_config'}   = 0;
-    $main::statistics{'command_counter_status'}   = 0;
-    $main::statistics{'command_counter_wallchan'} = 0;
-    $main::statistics{'command_counter_say'}      = 0;
-    $main::statistics{'command_counter_join'}     = 0;
-    $main::statistics{'command_counter_leave'}    = 0;
-    $main::statistics{'command_counter_lost'}     = 0;
-    $main::statistics{'command_counter_url'}      = 0;
-    $main::statistics{'command_counter_key'}      = 0;
-    $main::statistics{'command_counter_grant'}    = 0;
-    $main::statistics{'command_counter_revoke'}   = 0;
-
-    $main::statistics{'command_access_denied'}    = 0;
-
-    $main::statistics{'database_connects'}        = 0;
-    $main::statistics{'database_queries'}         = 0;
-
-    $main::statistics{'connects'}                 = 0;
+    $main::statistics{'command_counter_search'}     = 0;
+    $main::statistics{'command_counter_help'}       = 0;
+    $main::statistics{'command_counter_info'}       = 0;
+    $main::statistics{'command_counter_learn'}      = 0;
+    $main::statistics{'command_counter_forget'}     = 0;
+    $main::statistics{'command_counter_config'}     = 0;
+    $main::statistics{'command_counter_status'}     = 0;
+    $main::statistics{'command_counter_wallchan'}   = 0;
+    $main::statistics{'command_counter_say'}        = 0;
+    $main::statistics{'command_counter_join'}       = 0;
+    $main::statistics{'command_counter_leave'}      = 0;
+    $main::statistics{'command_counter_lost'}       = 0;
+    $main::statistics{'command_counter_url'}        = 0;
+    $main::statistics{'command_counter_key'}        = 0;
+    $main::statistics{'command_counter_grant'}      = 0;
+    $main::statistics{'command_counter_revoke'}     = 0;
+    $main::statistics{'command_counter_user'}       = 0;
+    $main::statistics{'command_counter_learnuser'}  = 0;
+    $main::statistics{'command_counter_forgetuser'} = 0;
+
+    $main::statistics{'command_access_denied'}      = 0;
+
+    $main::statistics{'database_connects'}          = 0;
+    $main::statistics{'database_queries'}           = 0;
+
+    $main::statistics{'connects'}                   = 0;
 }
 
 
@@ -1330,6 +1333,8 @@ sub is_valid_command {
         return 1;
     } elsif ($command eq 'search') {
         return 1;
+    } elsif ($command eq 'user') {
+        return 1;
     }
 
     return 0;
@@ -1355,6 +1360,10 @@ sub is_valid_operator_command {
         return 1;
     } elsif ($command eq 'key') {
         return 1;
+    } elsif ($command eq 'learnuser') {
+        return 1;
+    } elsif ($command eq 'forgetuser') {
+        return 1;
     }
 
     return 0;
@@ -1974,6 +1983,15 @@ sub handle_command {
         when('revoke') {
             return handle_command_revoke($command, $string, $mode, $kernel, $heap, $who, $nick, $where, $msg, $sender, $irc, $channel);
         }
+        when('user') {
+            return handle_command_user($command, $string, $mode, $kernel, $heap, $who, $nick, $where, $msg, $sender, $irc, $channel);
+        }
+        when('learnuser') {
+            return handle_command_learnuser($command, $string, $mode, $kernel, $heap, $who, $nick, $where, $msg, $sender, $irc, $channel);
+        }
+        when('forgetuser') {
+            return handle_command_forgetuser($command, $string, $mode, $kernel, $heap, $who, $nick, $where, $msg, $sender, $irc, $channel);
+        }
     }
 
     return '';
@@ -2099,6 +2117,293 @@ sub handle_command_grant {
 }
 
 
+# handle_command_user()
+#
+# command handler for the 'user' command
+#
+# parameter:
+#  - the command (lower case)
+#  - the parameter string (may be empty)
+#  - the command mode (admin/operator/user)
+#  - POE kernel
+#  - POE heap
+#  - the full who of the message sender, including the nick name
+#  - the nick name of the message sender
+#  - the full origin of the message
+#  - the message itself
+#  - POE sender
+#  - session irc handle
+#  - the channel name
+# return:
+#  - text to send back to the sender
+sub handle_command_user {
+    my $command = shift;
+    my $string  = shift;
+    my $mode    = shift;
+    my $kernel  = shift;
+    my $heap    = shift;
+    my $who     = shift;
+    my $nick    = shift;
+    my $where   = shift;
+    my $msg     = shift;
+    my $sender  = shift;
+    my $irc     = shift;
+    my $channel = shift;
+
+
+    if (length($string) < 1) {
+        my $answer = 'The "user" command requires one';
+           $answer = translate_text_for_channel($channel, 'error_user_command_parameter', $answer);
+        return $answer;
+    }
+
+    # remove spaces at beginning and end
+    $string =~ s/^[\s\t]+//gs;
+    $string =~ s/[\s\t]+$//gs;
+
+    my ($msg_nick, $msg_url);
+    if ($string =~ /^([^\s]+)$/) {
+        $msg_nick = $string;
+        $msg_url = '';
+    } else {
+        my $answer = 'The "user" command requires one parameters';
+           $answer = translate_text_for_channel($channel, 'error_user_command_parameter', $answer);
+        return $answer;
+    }
+
+
+    print_msg("user search: '$msg_nick', by $nick", DEBUG);
+    send_to_commandchannel("user search: '$msg_nick', by $nick");
+
+    $main::statistics{'command_counter_user'}++;
+
+
+    my $query = "SELECT u_nick, u_url FROM docbot_user WHERE LOWER(u_nick) = LOWER(?::TEXT)";
+    my $st    = $main::db->query($query, $msg_nick);
+    if (!defined($st)) {
+        my $answer = "Database error";
+           $answer = translate_text_for_channel($channel, 'database_error', $answer);
+        return $answer;
+    }
+    my $rows = $st->rows;
+
+
+    if ($rows == 0) {
+        my $answer = "Nick not in database";
+           $answer = translate_text_for_channel($channel, 'error_user_user_not_in_database', $answer);
+        return $answer;
+    }
+    my $row = $st->fetchrow_hashref;
+    if (length($row->{'u_url'}) == 0) {
+        my $answer = "Nick not in database";
+           $answer = translate_text_for_channel($channel, 'error_user_user_not_in_database', $answer);
+        return $answer;
+    }
+
+    return $msg_nick . ': ' . $row->{'u_url'};
+}
+
+
+# handle_command_learnuser()
+#
+# command handler for the 'learnuser' command
+#
+# parameter:
+#  - the command (lower case)
+#  - the parameter string (may be empty)
+#  - the command mode (admin/operator/user)
+#  - POE kernel
+#  - POE heap
+#  - the full who of the message sender, including the nick name
+#  - the nick name of the message sender
+#  - the full origin of the message
+#  - the message itself
+#  - POE sender
+#  - session irc handle
+#  - the channel name
+# return:
+#  - text to send back to the sender
+sub handle_command_learnuser {
+    my $command = shift;
+    my $string  = shift;
+    my $mode    = shift;
+    my $kernel  = shift;
+    my $heap    = shift;
+    my $who     = shift;
+    my $nick    = shift;
+    my $where   = shift;
+    my $msg     = shift;
+    my $sender  = shift;
+    my $irc     = shift;
+    my $channel = shift;
+
+
+    if (length($string) < 1) {
+        my $answer = 'The "learnuser" command requires two parameters';
+           $answer = translate_text_for_channel($channel, 'error_learnuser_command_parameter', $answer);
+        return $answer;
+    }
+
+    # remove spaces at beginning and end
+    $string =~ s/^[\s\t]+//gs;
+    $string =~ s/[\s\t]+$//gs;
+
+    my ($msg_nick, $msg_url);
+    if ($string =~ /^([^\s]+)\s+(http.+)$/) {
+        $msg_nick = $1;
+        $msg_url = $2;
+    } else {
+        my $answer = 'The "learnuser" command requires two parameters';
+           $answer = translate_text_for_channel($channel, 'error_learnuser_command_parameter', $answer);
+        return $answer;
+    }
+
+
+    print_msg("user learn: '$msg_nick/$msg_url', by $nick", DEBUG);
+    send_to_commandchannel("user learn: '$msg_nick/$msg_url', by $nick");
+
+    $main::statistics{'command_counter_learnuser'}++;
+
+
+    my $query = "SELECT u_nick, u_url FROM docbot_user WHERE LOWER(u_nick) = LOWER(?::TEXT)";
+    my $st    = $main::db->query($query, $msg_nick);
+    if (!defined($st)) {
+        my $answer = "Database error";
+           $answer = translate_text_for_channel($channel, 'database_error', $answer);
+        return $answer;
+    }
+    my $rows = $st->rows;
+
+
+    if ($msg_url =~ /^http:\/\/wiki\.postgresql\.org\//) {
+        my $answer = "Wiki links must begin with https";
+           $answer = translate_text_for_channel($channel, 'error_learnuser_wiki_links_https', $answer);
+        return $answer;
+    }
+    if ($msg_url !~ /^https:\/\/wiki\.postgresql\.org\/wiki\/User:[a-zA-Z0-9\+\-]+$/) {
+        my $answer = "Only links to the PostgreSQL wiki are allowed as user links";
+           $answer = translate_text_for_channel($channel, 'error_learnuser_wiki_links', $answer);
+        return $answer;
+    }
+
+    if ($rows == 0) {
+        # user not yet in database
+        $query = "INSERT INTO docbot_user (u_nick, u_role, u_reason, u_url) VALUES (LOWER(?::TEXT), 'user', 'Added for url', '')";
+        $st    = $main::db->query($query, $msg_nick);
+        if (!defined($st)) {
+            my $answer = "Database error";
+               $answer = translate_text_for_channel($channel, 'database_error', $answer);
+            return $answer;
+        }
+        my $answer = "User added";
+           $answer = translate_text_for_channel($channel, 'error_learnuser_user_added', $answer);
+        return $answer;
+    } else {
+        # user already in database, update link
+        my $row = $st->fetchrow_hashref;
+        $query = "UPDATE docbot_user SET u_url = ?::TEXT WHERE LOWER(u_nick) = LOWER(?::TEXT)";
+        $st    = $main::db->query($query, $msg_url, $msg_nick);
+        if (!defined($st)) {
+            my $answer = "Database error";
+               $answer = translate_text_for_channel($channel, 'database_error', $answer);
+            return $answer;
+        }
+        my $answer = "User changed";
+           $answer = translate_text_for_channel($channel, 'error_learnuser_user_canged', $answer);
+        return $answer;
+    }
+}
+
+
+# handle_command_forgetuser()
+#
+# command handler for the 'forgetuser' command
+#
+# parameter:
+#  - the command (lower case)
+#  - the parameter string (may be empty)
+#  - the command mode (admin/operator/user)
+#  - POE kernel
+#  - POE heap
+#  - the full who of the message sender, including the nick name
+#  - the nick name of the message sender
+#  - the full origin of the message
+#  - the message itself
+#  - POE sender
+#  - session irc handle
+#  - the channel name
+# return:
+#  - text to send back to the sender
+sub handle_command_forgetuser {
+    my $command = shift;
+    my $string  = shift;
+    my $mode    = shift;
+    my $kernel  = shift;
+    my $heap    = shift;
+    my $who     = shift;
+    my $nick    = shift;
+    my $where   = shift;
+    my $msg     = shift;
+    my $sender  = shift;
+    my $irc     = shift;
+    my $channel = shift;
+
+
+    if (length($string) < 1) {
+        my $answer = 'The "forgetuser" command requires one parameter';
+           $answer = translate_text_for_channel($channel, 'error_forgetuser_command_parameter', $answer);
+        return $answer;
+    }
+
+    # remove spaces at beginning and end
+    $string =~ s/^[\s\t]+//gs;
+    $string =~ s/[\s\t]+$//gs;
+
+    my ($msg_nick, $msg_url);
+    if ($string =~ /^([^\s]+)$/) {
+        $msg_nick = $1;
+    } else {
+        my $answer = 'The "forgetuser" command requires one parameter';
+           $answer = translate_text_for_channel($channel, 'error_forgetuser_command_parameter', $answer);
+        return $answer;
+    }
+
+
+    print_msg("user forget: '$msg_nick', by $nick", DEBUG);
+    send_to_commandchannel("user forget: '$msg_nick', by $nick");
+
+    $main::statistics{'command_counter_forgetuser'}++;
+
+
+    my $query = "SELECT u_nick, u_url FROM docbot_user WHERE LOWER(u_nick) = LOWER(?::TEXT)";
+    my $st    = $main::db->query($query, $msg_nick);
+    if (!defined($st)) {
+        my $answer = "Database error";
+           $answer = translate_text_for_channel($channel, 'database_error', $answer);
+        return $answer;
+    }
+    my $rows = $st->rows;
+
+
+    if ($rows == 0) {
+        my $answer = "User not in database";
+           $answer = translate_text_for_channel($channel, 'error_forgetuser_not_in_database', $answer);
+        return $answer;
+    }
+
+    $query = "UPDATE docbot_user SET u_url = '' WHERE LOWER(u_nick) = LOWER(?::TEXT)";
+    $st    = $main::db->query($query, $msg_nick);
+    if (!defined($st)) {
+        my $answer = "Database error";
+           $answer = translate_text_for_channel($channel, 'database_error', $answer);
+        return $answer;
+    }
+    my $answer = "User changed";
+       $answer = translate_text_for_channel($channel, 'error_forgetuser_user_canged', $answer);
+    return $answer;
+}
+
+
 # handle_command_revoke()
 #
 # command handler for the 'revoke' command
@@ -2299,22 +2604,25 @@ sub handle_command_status {
     $irc->yield( privmsg => $channel, 'Joined channels: ' . join(", ", @channels) );
     $irc->yield( privmsg => $channel, 'Number of IRC (re)connects: ' . $main::statistics{'connects'} );
     my @commands = ();
-    push(@commands, 'search: ' .   $main::statistics{'command_counter_search'});
-    push(@commands, 'help: ' .     $main::statistics{'command_counter_help'});
-    push(@commands, 'info: ' .     $main::statistics{'command_counter_info'});
-    push(@commands, 'learn: ' .    $main::statistics{'command_counter_learn'});
-    push(@commands, 'forget: ' .   $main::statistics{'command_counter_forget'});
-    push(@commands, 'config: ' .   $main::statistics{'command_counter_config'});
-    push(@commands, 'wallchan: ' . $main::statistics{'command_counter_wallchan'});
-    push(@commands, 'say: ' .      $main::statistics{'command_counter_say'});
-    push(@commands, 'join: ' .     $main::statistics{'command_counter_join'});
-    push(@commands, 'leave: ' .    $main::statistics{'command_counter_leave'});
-    push(@commands, 'status: ' .   $main::statistics{'command_counter_status'});
-    push(@commands, 'lost: ' .     $main::statistics{'command_counter_lost'});
-    push(@commands, 'url: ' .      $main::statistics{'command_counter_url'});
-    push(@commands, 'key: ' .      $main::statistics{'command_counter_key'});
-    push(@commands, 'grant: ' .    $main::statistics{'command_counter_grant'});
-    push(@commands, 'revoke: ' .   $main::statistics{'command_counter_revoke'});
+    push(@commands, 'search: '      . $main::statistics{'command_counter_search'});
+    push(@commands, 'help: '        . $main::statistics{'command_counter_help'});
+    push(@commands, 'info: '        . $main::statistics{'command_counter_info'});
+    push(@commands, 'learn: '       . $main::statistics{'command_counter_learn'});
+    push(@commands, 'forget: '      . $main::statistics{'command_counter_forget'});
+    push(@commands, 'config: '      . $main::statistics{'command_counter_config'});
+    push(@commands, 'wallchan: '    . $main::statistics{'command_counter_wallchan'});
+    push(@commands, 'say: '         . $main::statistics{'command_counter_say'});
+    push(@commands, 'join: '        . $main::statistics{'command_counter_join'});
+    push(@commands, 'leave: '       . $main::statistics{'command_counter_leave'});
+    push(@commands, 'status: '      . $main::statistics{'command_counter_status'});
+    push(@commands, 'lost: '        . $main::statistics{'command_counter_lost'});
+    push(@commands, 'url: '         . $main::statistics{'command_counter_url'});
+    push(@commands, 'key: '         . $main::statistics{'command_counter_key'});
+    push(@commands, 'grant: '       . $main::statistics{'command_counter_grant'});
+    push(@commands, 'revoke: '      . $main::statistics{'command_counter_revoke'});
+    push(@commands, 'user: '        . $main::statistics{'command_counter_user'});
+    push(@commands, 'user learn: '  . $main::statistics{'command_counter_learnuser'});
+    push(@commands, 'user forget: ' . $main::statistics{'command_counter_forgetuser'});
     # don't bother to add 'quit' statistic here
     $irc->yield( privmsg => $channel, 'Number of executed IRC commands: ' . join(", ", @commands) );
     $irc->yield( privmsg => $channel, 'Number of denied IRC requests: ' . $main::statistics{'command_access_denied'} );
@@ -3267,7 +3575,7 @@ sub handle_command_help {
         # translate message
         $answer = translate_text_for_channel($replyto, 'help_general_line_3', $answer);
         $answer .= ': ';
-        $answer .= 'search, help, info, learn, forget, config, status, say, wallchan, lost, url, key, join, leave, quit';
+        $answer .= 'search, help, info, learn, forget, config, status, say, wallchan, lost, url, key, join, leave, quit, user, learnuser, forgetuser';
         $irc->yield( privmsg => $replyto, $answer );
     }
 
@@ -3332,6 +3640,24 @@ sub handle_command_help {
         $irc->yield( privmsg => $replyto, $answer );
     }
 
+    if ($string eq 'user') {
+        my $answer = "Use ?user [learn|forget] <nick> [url]";
+           $answer = translate_text_for_channel($replyto, 'help_general_line_user', $answer);
+        $irc->yield( privmsg => $replyto, $answer );
+    }
+
+    if ($string eq 'learnuser') {
+        my $answer = "Use ?learnuser <nick> url";
+           $answer = translate_text_for_channel($replyto, 'help_general_line_learnuser', $answer);
+        $irc->yield( privmsg => $replyto, $answer );
+    }
+
+    if ($string eq 'forgetuser') {
+        my $answer = "Use ?forgetuser <nick>";
+           $answer = translate_text_for_channel($replyto, 'help_general_line_forgetuser', $answer);
+        $irc->yield( privmsg => $replyto, $answer );
+    }
+
     return '';
 }
 
index e4790797e109160d7f5466be42bdca359f321840..7d3a75de762cc860e6f7bd5336b3e6f0ef396086 100644 (file)
@@ -38,7 +38,7 @@ translations:
     error_grant_command_parameter: 'Der "grant" Befehl erfordert zwei Parameter'
     error_grant_second_parameter: 'Der zweite Parameter muss "op" oder "admin" sein'
     error_grant_user_has_level: 'Dieser Benutzer ist bereits mit diesem Level in der Datenbank eingetragen'
-    error_grant_user_added: 'Benutzer addiert'
+    error_grant_user_added: 'Benutzer hinzugefügt'
     error_grant_user_canged: 'Benutzer geändert'
     error_revoke_command_parameter: 'Der "revoke" Befehl erfordert einen Parameter'
     error_revoke_user_not_in_db: 'Benutzer nicht in Datenbank'
@@ -48,6 +48,17 @@ translations:
     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'
+    error_user_command_parameter: 'Der "user" Befehl erfordert einen Parameter'
+    error_learnuser_command_parameter: 'Der "learnuser" Befehl erfordert zwei Parameter'
+    error_forgetuser_command_parameter: 'Der "forgetuser" Befehl erfordert einen Parameter'
+    error_user_user_not_in_database: 'Dieser Nick ist nicht in der Datenbank'
+    error_learnuser_wiki_links_https: 'Wiki Links müssen mit https anfangen'
+    error_learnuser_wiki_links: 'Nur Links zum PostgreSQL Wiki sind erlaubt'
+    error_learnuser_user_added: 'Benutzer hinzugefügt'
+    error_user_user_canged: 'Benutzer geändert'
+    error_learnuser_user_canged: 'Benutzer geändert'
+    error_forgetuser_user_canged: 'Benutzer geändert'
+    error_forgetuser_not_in_database: 'Benutzer nicht in der Datenbank'
     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'
@@ -60,6 +71,9 @@ translations:
     help_general_line_leave: 'Nutze: ?leave'
     help_general_line_grant: 'Nutze: ?grant <Nick> <op/admin>'
     help_general_line_revoke: 'Nutze: ?revoke <Nick>'
+    help_general_line_user: 'Nutze: ?user <nick>'
+    help_general_line_learnuser: 'Nutze: ?learnuser <nick> url'
+    help_general_line_forgetuser: 'Nutze: ?forgetuser <nick>'
     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'
diff --git a/sql/changes-2013-04-14.sql b/sql/changes-2013-04-14.sql
new file mode 100644 (file)
index 0000000..17256ec
--- /dev/null
@@ -0,0 +1,4 @@
+BEGIN;
+ALTER TABLE docbot_user
+  ADD COLUMN u_url TEXT NOT NULL DEFAULT '';
+COMMIT;