]> git.somenet.org - irc/bugbot.git/blob - BotModules/List.bm
GITOLITE.txt
[irc/bugbot.git] / BotModules / List.bm
1 # -*- Mode: perl; tab-width: 4; indent-tabs-mode: nil; -*-
2 ################################
3 # List Module                  #
4 ################################
5
6 package BotModules::List;
7 use vars qw(@ISA);
8 @ISA = qw(BotModules);
9 1;
10
11 # XXX Wipe entire list command
12
13 # RegisterConfig - Called when initialised, should call registerVariables
14 sub RegisterConfig {
15     my $self = shift;
16     $self->SUPER::RegisterConfig(@_);
17     $self->registerVariables(
18       # [ name, save?, settable? ]
19         ['lists', 1, 1, {}], # user => 'list name|item 1|item 2||list name|item1|item 2'
20         ['preferredLineLength', 1, 1, 80], # the usual
21         ['maxItemsInChannel', 1, 1, 20], # max number of items to print in the channel (above this and direct messages are used)
22     );
23 }
24
25 sub Help {
26     my $self = shift;
27     my ($event) = @_;
28     return {
29             '' => 'A personal list tracker. Store your lists here. You must be authenticated to use this (see \'newuser\'). Use the \'add\' command to add items to a list.',
30             'add' => 'Add an item to a personal list. List names shouldn\'t contain the word \'to\' otherwise things will be too ambiguous. Syntax: \'add <thing to add> to <list name> list\', e.g. \'add bug 5693 to critical bug list\'.',
31             'remove' => 'Remove an item from a personal list. Syntax: \'remove <thing to add> from <list name> list\', e.g. \'remove bug 5693 from critical bug list\'.',
32             'list' => 'List the items in your list. Syntax: \'list items in <name of list> list\', e.g. \'list items in critical bug list\' or just \'critical bug list\'.',
33             'lists' => 'Tells you what lists you have set up.',
34     };
35 }
36
37 sub Told {
38     my $self = shift;
39     my ($event, $message) = @_;
40     if ($message =~ /^\s*add\s+(\S(?:.*\S)?)\s+to\s+(?:my\s+)?(\S(?:.*\S)?)\s+list[\s!.]*$/osi and $message !~ /\|/o and $event->{'userName'}) {
41         $self->AddItem($event, $1, $2);
42     } elsif ($message =~ /^\s*remove\s+(\S(?:.*\S)?)\s+from\s+(?:my\s+)?(\S(?:.*\S)?)\s+list[\s!.]*$/osi and $message !~ /\|/o and $event->{'userName'}) {
43         $self->RemoveItem($event, $1, $2);
44     } elsif ($message =~ /^\s*   (?:examine \s+                      |
45                                     list \s+ items \s+ in \s+        |
46                                     what (?:\s+is|'s) \s+ (?:in\s+)? )
47                                  (?: my \s+ | the \s+ )?
48                                  ( \S (?:.*\S)? )
49                                 \s+ list [\s!?.]* $/osix
50              and $message !~ /\|/o and $event->{'userName'}) {
51         $self->ListItems($event, $1);
52     } elsif ($message =~ /^\s*lists[?\s.!]*$/osi and $event->{'userName'}) {
53         $self->ListLists($event, $1);
54     } else {
55         return $self->SUPER::Told(@_);
56     }
57     return 0; # dealt with it...
58 }
59
60 sub Baffled {
61     my $self = shift;
62     my ($event, $message) = @_;
63     if ($message =~ /^\s*(\S(?:.*\S)?)\s+list[\s!?.]*$/osi and $message !~ /\|/o and $event->{'userName'}) {
64         $self->ListItems($event, $1);
65     } else {
66         return $self->SUPER::Baffled(@_);
67     }
68     return 0; # dealt with it...
69 }
70
71 sub Heard {
72     my $self = shift;
73     my ($event, $message) = @_;
74     if ($message =~ /^\s*add\s+(\S(?:.*\S)?)\s+to\s+(?:my\s+)?(\S(?:.*\S)?)\s+list[\s!.]*$/osi and $message !~ /\|/o and $event->{'userName'}) {
75         $self->AddItem($event, $1, $2);
76     } elsif ($message =~ /^\s*remove\s+(\S(?:.*\S)?)\s+from\s+(?:my\s+)?(\S(?:.*\S)?)\s+list[\s!.]*$/osi and $message !~ /\|/o and $event->{'userName'}) {
77         $self->RemoveItem($event, $1, $2);
78     } else {
79         return $self->SUPER::Told(@_);
80     }
81     return 0; # dealt with it...
82 }
83
84 sub AddItem {
85     my $self = shift;
86     my ($event, $what, $list) = @_;
87     my @lists = split(/\|\|/o, $self->{'lists'}->{$event->{'userName'}});
88     local $" = '\', \'';
89     my %lists;
90     foreach my $sublist (@lists) {
91         my @items = split(/\|/o, $sublist);
92         $lists{shift @items} = \@items;
93     }
94     push(@{$lists{lc $list}}, $what);
95     local $" = '|';
96     my $compoundLists = '';
97     foreach my $list (keys(%lists)) {
98         if ($compoundLists ne '') {
99             $compoundLists .= '||';
100         }
101         $compoundLists .= "$list|@{$lists{$list}}";
102     }
103     $self->{'lists'}->{$event->{'userName'}} = $compoundLists;
104     $self->saveConfig();
105     $self->say($event, "$event->{'from'}: stored '$what' in '$list' list");
106 }
107
108 sub RemoveItem {
109     my $self = shift;
110     my ($event, $what, $list) = @_;
111     my @lists = split(/\|\|/o, $self->{'lists'}->{$event->{'userName'}});
112     local $" = '\', \'';
113     my %lists;
114     my $removed = 0;
115     foreach my $sublist (@lists) {
116         my @items = split(/\|/o, $sublist);
117         if (lc $list eq $items[0]) {
118             my $listName = shift @items;
119             foreach my $item (@items) {
120                 if (lc $what ne lc $item) {
121                     push(@{$lists{$listName}}, $item);
122                 } else {
123                     $removed++;
124                 }
125             }
126         } else {
127             $lists{shift @items} = \@items;
128         }
129     }
130     local $" = '|';
131     my $compoundLists = '';
132     foreach my $list (keys(%lists)) {
133         if ($compoundLists ne '') {
134             $compoundLists .= '||';
135         }
136         $compoundLists .= "$list|@{$lists{$list}}";
137     }
138     $self->{'lists'}->{$event->{'userName'}} = $compoundLists;
139     $self->saveConfig();
140     if ($removed) {
141         $self->say($event, "$event->{'from'}: removed '$what' from '$list' list");
142     } else {
143         $self->say($event, "$event->{'from'}: could not find '$what' in '$list' list");
144     }
145 }
146
147 sub ListItems {
148     my $self = shift;
149     my ($event, $list) = @_;
150     my @lists = split(/\|\|/o, $self->{'lists'}->{$event->{'userName'}});
151     my %lists;
152     foreach my $list (@lists) {
153         my @items = split(/\|/o, $list);
154         $lists{lc shift @items} = \@items;
155     }
156     if (defined(@{$lists{lc $list}})) {
157         my $size = scalar(@{$lists{lc $list}});
158         if ($size > $self->{'maxItemsInChannel'}) {
159             $self->channelSay($event, "$event->{'from'}: Your $list list contains $size items, which I am /msg'ing you.");
160             $self->directSay($event, $self->prettyPrint($self->{'preferredLineLength'}, "Your $list list contains: ", '', ', ', @{$lists{lc $list}}));
161         } else {
162             $self->say($event, $self->prettyPrint($self->{'preferredLineLength'}, "Your $list list contains: ", $event->{'channel'} eq '' ? '' : "$event->{'from'}: ", ', ', @{$lists{lc $list}}));
163         }
164     } else {
165         $self->say($event, "You don't have a $list list, sorry.");
166     }
167 }
168
169 sub ListLists {
170     my $self = shift;
171     my ($event) = @_;
172     my @lists = split(/\|\|/o, $self->{'lists'}->{$event->{'userName'}});
173     my @listNames;
174     foreach my $list (@lists) {
175         my @items = split(/\|/o, $list);
176         push(@listNames, $items[0]);
177     }
178     $self->say($event, $self->prettyPrint($self->{'preferredLineLength'}, "Your lists are: ", $event->{'channel'} eq '' ? '' : "$event->{'from'}: ", ', ', @listNames));
179 }