Support tags for individual tips
[grml-tips.git] / grml-tips
1 #!/usr/bin/perl
2 # Filename:      grml-tips
3 # Purpose:       query a signature file for a specific keyword and display results
4 # Authors:       grml-team (grml.org), (c) Michael Prokop <mika@grml.org>, (c) Alexander Wirt <formorer@grml.org>
5 # Bug-Reports:   see http://grml.org/bugs/
6 # License:       This file is licensed under the GPL v2.
7 ################################################################################
8
9 use strict;
10 use Pod::Usage;
11
12 use feature 'say';
13 use Term::ReadKey;
14 use Time::HiRes;
15 use LWP::UserAgent;
16 use Getopt::Long;
17
18 =head1 NAME
19
20 B<grml-tips> - query a signature file for a specific keyword and display results
21
22 =head1 SYNOPSIS
23
24 B<grml-tips> [OPTION] I<searchpattern|tag>
25
26 =head1 DESCRIPTION
27
28 This manual page documents briefly the B<grml-tips> command.
29
30 =head1 OPTIONS
31
32 =over 8
33
34 =item B<--help>
35
36 Print this help and exit.
37
38 =item B<--tagsonly>
39
40 Match on tags only instead of the whole tip 
41
42 =back
43
44 =head1 EXAMPLES
45
46 =over 8
47
48 =item B<grml-tips> I<ntfs>
49
50 Query grml-tips file for tips / hints including keyword  "ntfs".
51
52 =item B<grml-tips> I<.>
53
54 Display all available B<grml-tips> at once.
55
56 =back
57
58 =head1 FILES
59
60 /usr/share/grml-tips/grml_tips
61
62 Signature file containing the tips.
63
64 =head1 SEE ALSO
65
66 L<grml(1)>
67
68 =head1 AUTHOR
69
70 grml-tips was written by Alexander Wirt <formorer@grml.org>
71
72 =cut
73
74 my $grml_tips = '/usr/share/grml-tips/grml_tips';
75
76 my $help;
77 my $tagsonly;
78
79 my $result = GetOptions (
80     "help" => \$help,
81     "tagsonly" => \$tagsonly
82 );
83
84 my $pattern   = shift;
85
86 #help if pattern is missing;
87 pod2usage(
88     {   -message => 'No search pattern provided',
89         -exitval => -1,
90     }
91 ) unless $pattern;
92
93 #help if help is wanted
94 pod2usage() if $help;
95
96 my @tips;
97
98 if ( !open( my $fh, '<', "$grml_tips" ) ) {
99     say STDERR "Error: File \"$grml_tips\" not found.";
100     say STDERR "Exiting.";
101     exit -1;
102 }
103 else {
104     my $tip = '';
105
106     my $tips_found = 0;
107     while ( my $line = <$fh> ) {
108         if ( $line !~ /^-- $/ ) {
109             $tip .= $line;
110         }
111         else {
112             my $header = "Grml Tip Number $tips_found\n";
113             my $line = "-" x ( length($header) - 1 ) . "\n\n";
114
115             $tips_found++;
116             if ($tagsonly) {
117                 #extract tags from tip
118                 my ($tag) = $tip =~ /^Tags: (.*)$/m;
119                 my @tags = split(/[, ]+/, $tag);
120                 if (grep(/^$pattern$/i, @tags) ) {
121                     push @tips, $header . $line . $tip . "\n";
122                 }
123                 $tip = '';
124             } else {
125                 if ( $tip =~ /$pattern/mi ) {
126                     push @tips, $header . $line . $tip . "\n";
127                     $tip = '';
128                 }
129                 else {
130                     $tip = '';
131                 }
132             }
133         }
134     }
135     close($fh);
136 }
137
138 if (@tips) {
139     if ( !open( my $fh, '|-', 'less -FRX' ) ) {
140         say @tips;
141     }
142     else {
143         say $fh @tips;
144     }
145 }
146 else {
147     say "Sorry, could not find a tip for '$pattern'. :-(\n\n",
148         "Do you want to submit the keyword '$pattern' to grml's keyword database?\n",
149         "The grml team will write tips for the most requested and useful keywords.\n",
150         "To use and contribute to this feature you'll need a working networking connection.\n",
151         "No personal data will be transmitted to the database.\n\n",
152         "Send \"$pattern\" to grml's keyword database? [y|N] ";
153
154     ReadMode 4;    # Turn off controls keys
155     my $x;
156     while ( not defined( $x = ReadKey(-1) ) ) {
157         Time::HiRes::sleep(0.5);
158     }
159     ReadMode 0;    # Reset tty mode before exiting
160     print "\n\n";
161     if ( $x =~ /(y|j)/i ) {
162         my $version;
163         if ( -f '/etc/grml_version' ) {
164             open( my $fh, '<', '/etc/grml_version' )
165                 or die "Could not open /etc/grml_version: $!";
166             $version = <$fh>;
167             chomp $version;
168             close($fh);
169         }
170         elsif ( -f '/etc/debian_version' ) {
171             open( my $fh, '<', '/etc/debian_version' )
172                 or die "Could not open /etc/debian_version: $!";
173             $version = <$fh>;
174             chomp $version;
175             close($fh);
176         }
177         else {
178             $version = 'unknown';
179         }
180         my $ua = new LWP::UserAgent;
181         $ua->agent("grml-tips 0.0 ");    # set the HTTP 'browser' type
182         my $res = $ua->post(
183             'http://deb.grml.org/~formorer/submissions/keyword.cgi',
184             [   'version' => $version,
185                 'keyword' => $pattern
186             ],
187         );
188         if ( $res->is_success ) {
189             my $content = $res->decoded_content;
190             if ( $content =~ /Submission received/ ) {
191                 say
192                     "Keyword '$pattern' has been submitted to grml's keyword database.\nThanks.";
193             }
194             else {
195                 say "Your pattern could not be submitted.\n",
196                     "Please file a bug against grml-tips at ",
197                     "http://bts.grml.org/\n",
198                     "Thanks!";
199             }
200         }
201         else {
202             print "Could not submitt '$pattern': " . $res->status_line . "\n";
203         }
204
205     }
206     else {
207         print
208             "'$pattern' has not been sent to grml's keyword database as requested.\n";
209         print
210             "If you want to submit a tip please mail it to tips\@grml.org - thank you!\n";
211     }
212 }
213
214 ## END OF FILE #################################################################