Software Freedom Law Center

root/trunk/antimatter/tim/Modules/SFLC/TimeTracker/Input/CategoryParser.pm

Revision 53, 5.3 kB (checked in by bkuhn, 10 months ago)
  • Added SFLC's internally developed tim bot released under AGPLv3
Line 
1 # Copyright (C) 2005, 2006   Software Freedom Law Center, Inc.
2 #  Author: Bradley M. Kuhn <bkuhn@softwarefreedom.org>
3 #
4 #  This software gives you freedom; it is licensed to you under version
5 #  3 of the GNU Affero General Public License.
6 #
7 #  This software is distributed WITHOUT ANY WARRANTY, without even the
8 #  implied warranties of MERCHANTABILITY and FITNESS FOR A PARTICULAR
9 #  PURPOSE.  See the GNU Affero General Public License for further
10 #  details.
11 #
12 # You should have received a copy of the GNU Affero General Public
13 # License, version 3 along with this software.  If not, see
14 # <http://www.gnu.org/licenses/>.
15 use strict;
16 use warnings;
17
18 package SFLC::TimeTracker::Input::CategoryParser;
19
20 use base qw( Class::Factory );
21
22 use Carp;
23 use String::Approx 'amatch';
24
25 ###############################################################################
26 sub getDatabase { return SFLC::TimeTracker::Input::getDatabase();}
27 ###############################################################################
28 sub init {
29   my $self = shift;
30   my(%inputVal) = @_;
31   my $userHandle;
32
33   print "keys of inputVal: ", join(", ", keys %inputVal), "\n";
34   print "values of inputVal: ", join(", ", values %inputVal), "\n";
35
36   if (defined $inputVal{userHandle}) {
37     $userHandle = $inputVal{userHandle};
38   } elsif (not defined $inputVal{user}) {
39     croak "cannot instantiate a CategoryParser without user";
40   } else {
41     $userHandle = $self->getDatabase->getUserHandle($inputVal{user});
42     croak "$inputVal{user} does not have a valid userHandle"
43       unless defined $userHandle;
44   }
45
46   $self->{userHandle} = $userHandle;
47   $self->{name} = "Exact";
48   $self->{description} =
49       "Requires an exact match of a time entry category or one of its aliases";
50
51   return $self;
52 }
53 ###############################################################################
54 sub get {
55   my($self, $field) = @_;
56
57   if ($field =~ /^(?:userHandle|categoryID|note|description|categoryCandidate|
58                  description|outputTree|name|categoryDiscard)$/x) {
59     return $self->{$field};
60   } else {
61     confess "$field is not a valid field";
62     return undef;
63   }
64 }
65 ###############################################################################
66 sub userHandle {
67   my($self) = shift;
68   return $self->get('userHandle');
69 }
70 ###############################################################################
71 sub clearFields {
72   my $self = shift;
73   foreach my $field (qw/categoryID note name categoryCandidate
74                  description outputTree categoryDiscard/) {
75     $self->set($field, undef);
76   }
77 }
78 ###############################################################################
79 sub set {
80   my($self, $field, $value) = @_;
81
82   if ($field =~ /^(?:userHandle|categoryID|note|name|categoryCandidate|
83                  description|outputTree|categoryDiscard)$/x) {
84     $self->{$field} = $value;
85   } else {
86     confess "$field is not a valid field";
87     return undef;
88   }
89 }
90 ###############################################################################
91 sub findMinMatch ($$@) {
92   my($self, $given, @candidates) = @_;
93
94   # No choices mean no matches
95   return () if @candidates <= 0;
96   return () if not defined $given or $given =~ /^\s*$/;
97   my $approxVal = 0;
98   my @matches;
99   while (@matches == 0  and ++$approxVal < 100) {
100     (@matches) = amatch($given, ['i', "${approxVal}%"], @candidates);
101   }
102   return @matches;
103 }
104 ###############################################################################
105 sub _doParse ($$) {
106   my ($self, $line) = @_;
107
108   my($note, $categoryID);
109
110   if ($line =~ s/\s+"?no?te?:?\s*"?\s*([^"]+)"?\s*$//) {
111     $note = $1;
112   } elsif ($line =~ s/"([^"]+)"?\s*$//) {
113     $note = $1;
114   }
115
116   if (defined $note) { $note =~ s/^\s+//;   $note =~ s/\s+$//; }
117
118
119   my $categoryCandidate = join("/", split(/\s+/, "\L$line\E"));
120
121   $categoryCandidate =~ s/^\s+//;   $categoryCandidate =~ s/\s+$//;
122   $categoryCandidate =~ s/\/+$//;   $categoryCandidate =~ s!//!/!g;
123   $categoryCandidate =~ s!:!/!g;
124   $categoryCandidate = "/$categoryCandidate" unless $categoryCandidate =~ m%^/%;
125
126   # Do an alias lookup in the database
127   $categoryID = $self->getDatabase()->
128                            categoryAliasLookup($self->{userHandle},
129                                                $categoryCandidate);
130
131   $self->set(note => $note);
132   $self->set(categoryID => $categoryID);
133   $self->set(categoryCandidate => $categoryCandidate);
134   $self->set(categoryDiscard => "");
135
136 #   $self-> new SFLC::TimeTracker::Question::Category(
137 #                                  category => $categoryCandidate,
138 #                                  timeStamp => $timeStamp,
139 #                                  inputString => $self->{currentOriginalLine},
140 #                                  userHandle => $buildData->{userHandle},
141 #             question => "\"$categoryCandidate\" is an unknown category.",
142 #              answers => \@matches);
143
144 }
145
146 __PACKAGE__->add_factory_type( BasicLawyer =>
147              'SFLC::TimeTracker::Input::CategoryParser::Lawyer');
148
149 __PACKAGE__->add_factory_type( AdminAssume =>
150              'SFLC::TimeTracker::Input::CategoryParser::AdminAssume');
151 __PACKAGE__->add_factory_type( Assistant =>
152              'SFLC::TimeTracker::Input::CategoryParser::Assistant');
153 __PACKAGE__->add_factory_type( Press =>
154              'SFLC::TimeTracker::Input::CategoryParser::PR');
155 1;
156 #
157 # Local variables:
158 # compile-command: "perl -I ../../../../Modules -c CategoryParser.pm"
159 # End:
Note: See TracBrowser for help on using the browser.

SFLC Main Page

[frdm] Support SFLC