Skip to content

Commit 6aa2a1d

Browse files
committed
Add search facility
1 parent f88b7ce commit 6aa2a1d

File tree

7 files changed

+277
-9
lines changed

7 files changed

+277
-9
lines changed

ADBOS/DB.pm

+44-3
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ use ADBOS::Schema;
88
use ADBOS::Parse;
99
use DateTime::Format::Strptime;
1010
use String::Random;
11+
use Apache::Solr ();
12+
use Apache::Solr::Document ();
13+
use ADBOS::Config;
14+
15+
my $config = simple_config;
1116

1217
=pod
1318
@@ -305,9 +310,39 @@ sub sigtypeSearch($)
305310
$sigtype;
306311
}
307312

313+
sub opdefIndex($)
314+
{ my ($self, $opdefs_id) = @_;
315+
my $url = $config->{solrurl};
316+
my $solr = Apache::Solr->new(server => $url);
317+
318+
my @fields = qw(type number_serial number_year erg_code parent_equip defective_unit
319+
line5 defect repair_int assistance assistance_port matdem remarks);
320+
# First we need to create a new hash with *all* the data in: if we are updating
321+
# an OPDEF and the old data is unchanged and therefore not in the SITREP, then
322+
# it will otherwise be removed from Solr.
323+
my $opdef_rs = $self->sch->resultset('Opdef');
324+
my $opdef = $opdef_rs->find($opdefs_id);
325+
my $indexdata;
326+
foreach my $field (@fields)
327+
{
328+
$indexdata->{$field} = $opdef->$field // '';
329+
}
330+
$indexdata->{id} = $opdefs_id;
331+
$indexdata->{category} = $opdef->category->name; # Convert to string from ID
332+
$indexdata->{ship} = $opdef->ship->name; # Convert to string from ID
333+
$indexdata->{modified} = $opdef->modified->strftime('%FT%TZ');
334+
my $doc = Apache::Solr::Document->new( fields => $indexdata );
335+
my @signals = $opdef->signals->all;
336+
foreach my $sig (@signals)
337+
{
338+
$doc->addField(signal => $sig->content);
339+
}
340+
my $results = $solr->addDocument($doc);
341+
$results or die $results->errors;
342+
}
343+
308344
sub opdefStore($$)
309345
{ my ($self, $opdefin, $ships_id) = @_;
310-
311346
return if !$ships_id;
312347
my $opdefs_id;
313348
my %newdata;
@@ -316,12 +351,14 @@ sub opdefStore($$)
316351
line5 defect repair_int assistance assistance_port matdem remarks);
317352
@newdata{@fields} = undef;
318353
@newdata{ keys %newdata } = @$opdefin{ keys %newdata };
354+
319355
my $defrep = $opdefin->{opdef} eq 'DEFREP' ? 1 : 0;
320356
$newdata{defrep} = 1 if $defrep;
321357

322-
# Get the ID of the category
358+
# Convert category string to database ID number
359+
my $catname = $opdefin->{category};
323360
my $category_rs = $self->sch->resultset('Category');
324-
my $c = $category_rs->find($opdefin->{category}, { key => 'name' });
361+
my $c = $category_rs->find($catname, { key => 'name' });
325362
$newdata{category} = $c->id if $c;
326363

327364
my $opdef_rs = $self->sch->resultset('Opdef');
@@ -409,6 +446,7 @@ sub opdefStore($$)
409446
$opdef->update({ cancelled => 1 }) if $opdefin->{format} eq 'CANCEL';
410447
}
411448
}
449+
412450
$opdefs_id;
413451
}
414452

@@ -441,6 +479,9 @@ sub signalStore($$;$$$)
441479
my $opdef = $opdef_rs->find($opdefs_id) if $opdefs_id;
442480
$opdef->update({ modified => \'UTC_TIMESTAMP()', modified_sigtype => $ss }) if $opdef;
443481

482+
# Store the OPDEF in Solr for search.
483+
$self->opdefIndex($opdefs_id);
484+
444485
$id;
445486
}
446487

ADBOS/Display.pm

+111
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ use ADBOS::Parse;
1010
use ADBOS::Config;
1111
use ADBOS::Email;
1212
use Email::Valid;
13+
use Apache::Solr ();
14+
use Apache::Solr::Document ();
1315

1416
my $config = simple_config;
1517
my $db = ADBOS::DB->new($config);
@@ -47,6 +49,115 @@ sub login($;$)
4749
$self->_standard_template('login.html', $vars);
4850
}
4951

52+
sub search($$)
53+
{ my ($self, $user) = @_;
54+
my $q = $self->{qry};
55+
56+
my $url = $config->{solrurl};
57+
my $solr = Apache::Solr->new(server => $url);
58+
59+
my $file = 'search.html';
60+
61+
my @searchq; my @uq;
62+
if ($q->param('type'))
63+
{
64+
push @searchq, {field => 'type', value => uc $q->param('type')};
65+
}
66+
if ($q->param('ship'))
67+
{
68+
push @searchq, {field => 'ship', value => uc $q->param('ship')};
69+
}
70+
if ($q->param('number_year'))
71+
{
72+
push @searchq, {field => 'number_year', value => $q->param('number_year')};
73+
}
74+
if ($q->param('number_serial'))
75+
{
76+
push @searchq, {field => 'number_serial', value => $q->param('number_serial')};
77+
}
78+
if ($q->param('category'))
79+
{
80+
push @searchq, {field => 'category', value => uc $q->param('category')};
81+
}
82+
if ($q->param('defective_unit'))
83+
{
84+
push @searchq, {field => 'defective_unit', value => $q->param('defective_unit')};
85+
}
86+
if ($q->param('line5'))
87+
{
88+
push @searchq, {field => 'line5', value => $q->param('line5')};
89+
}
90+
if ($q->param('assistance_port'))
91+
{
92+
push @searchq, {field => 'assistance_port', value => $q->param('assistance_port')};
93+
}
94+
if ($q->param('remarks'))
95+
{
96+
push @searchq, {field => 'remarks', value => $q->param('remarks')};
97+
}
98+
if ($q->param('assistance'))
99+
{
100+
push @searchq, {field => 'assistance', value => $q->param('assistance')};
101+
}
102+
if ($q->param('repair_int'))
103+
{
104+
push @searchq, {field => 'repair_int', value => $q->param('repair_int')};
105+
}
106+
if ($q->param('defect'))
107+
{
108+
push @searchq, {field => 'defect', value => $q->param('defect')};
109+
}
110+
if ($q->param('parent_equip'))
111+
{
112+
push @searchq, {field => 'parent_equip', value => $q->param('parent_equip')};
113+
}
114+
if ($q->param('erg_code'))
115+
{
116+
push @searchq, {field => 'erg_code', value => $q->param('erg_code')};
117+
}
118+
if($q->param('signal'))
119+
{
120+
push @searchq, {field => 'signal', value => $q->param('signal')};
121+
}
122+
123+
unless (@searchq)
124+
{
125+
my $vars = {
126+
user => $user,
127+
title => 'OPDEF Search'
128+
};
129+
$self->_standard_template($file, $vars);
130+
}
131+
132+
my $searchq = join ' AND ', map { $_->{field}.":(".$_->{value}.")"} @searchq;
133+
my $uriq = join '&', map { $_->{field}."=".$_->{value}} @searchq;
134+
my $sort = $q->param('sort') eq 'date' ? 'modified' : 'score';
135+
my $results = $solr->select(q => "{!q.op=AND}$searchq", sort => "$sort desc", hl => {fl=>'signal'});
136+
my @opdefs;
137+
while(my $doc = $results->nextSelected)
138+
{
139+
my $hldoc = $results->highlighted($doc);
140+
my $opdef;
141+
$opdef->{id} = $doc->_id;
142+
$opdef->{line5} = $doc->_line5;
143+
$opdef->{type} = $doc->_type;
144+
$opdef->{number_serial} = $doc->_number_serial;
145+
$opdef->{number_year} = $doc->_number_year;
146+
$opdef->{ship} = $doc->_ship;
147+
$opdef->{modified} = $doc->_modified;
148+
$opdef->{highlight} = $hldoc->_signal;
149+
push @opdefs, $opdef;
150+
}
151+
152+
my $vars = { opdefs => \@opdefs,
153+
user => $user,
154+
title => 'OPDEF Search',
155+
uriq => $uriq,
156+
};
157+
158+
$self->_standard_template($file, $vars);
159+
}
160+
50161
sub summary($$)
51162
{ my ($self, $user) = @_;
52163

index.pl

+5-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,11 @@
3636
$guest = $display->syops($auth);
3737
}
3838

39-
if ($req->unparsed_uri =~ m!^/+summary/?!gi)
39+
if ($req->unparsed_uri =~ m!^/+search/?!gi)
40+
{
41+
$display->search($user);
42+
}
43+
elsif ($req->unparsed_uri =~ m!^/+summary/?!gi)
4044
{
4145
$display->summary($user);
4246
}

indexopdefs.pl

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#!/usr/bin/perl
2+
3+
use strict;
4+
use warnings;
5+
6+
use lib "/var/www/opdef.andybev.com";
7+
8+
use ADBOS::DB;
9+
use ADBOS::Config;
10+
11+
my $config = simple_config;
12+
my $db = ADBOS::DB->new($config);
13+
14+
my $sch = $db->sch;
15+
$sch->storage->debug(0);
16+
17+
my $opdef_rs = $sch->resultset('Opdef');
18+
19+
my @opdefs = $opdef_rs->search->all;
20+
21+
foreach my $opdef (@opdefs)
22+
{
23+
$db->opdefIndex($opdef->id);
24+
}
25+

style.css

+1-5
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@ DIV.banner {
5050

5151
DIV.username {
5252
float: left;
53-
padding-left: 300px;
5453
position:absolute;
5554
bottom:0;
5655
right:0;
@@ -186,7 +185,7 @@ textarea.formstyle {
186185
label.formstyle {
187186
vertical-align: middle;
188187
display: inline-block;
189-
width: 100px;
188+
width: 200px;
190189
}
191190

192191
textarea.comments{
@@ -227,9 +226,6 @@ td.bottom{
227226
}
228227

229228
#menu {
230-
position: absolute;
231-
bottom:0;
232-
height: 100%;
233229
}
234230

235231
#menu ul {

templates/header.html

+6
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,12 @@
2626
[% END %]
2727
</ul>
2828
</div>
29+
<div style="float:left">
30+
<form action="/search">
31+
<input type="text" name="signal">
32+
<input type="submit" name="submit" value="Quick search">
33+
</form>
34+
</div>
2935
<div class="username">
3036
[% IF user %]
3137
Logged in as <a href="/myaccount">[% user.username %]</a>

templates/search.html

+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
[% INCLUDE header.html %]
2+
3+
[% IF opdefs.defined %]
4+
<h2>Search results</h2>
5+
<p>
6+
<a href="/search?[% uriq %]&sort=score">Sort by relevance</a> | <a href="/search?[% uriq %]&sort=date">Sort by date</a> | <a href="/search">Advanced search</a>
7+
</p>
8+
<div>
9+
[% IF opdefs.size %]
10+
[% FOR opdef IN opdefs %]
11+
<p><a href="/opdef/[% opdef.id %]">[% opdef.ship %] [% opdef.type %] [% opdef.number_serial %]-[% opdef.number_year %] ([% opdef.line5 %])</a><br>
12+
[% opdef.highlight %] [% opdef.modified %]</p>
13+
[% END %]
14+
[% ELSE %]
15+
<p>No results</p>
16+
[% END %]
17+
</div>
18+
[% ELSE %]
19+
<p>To perform a single character wildcard search use the "?" symbol. To perform a multiple character wildcard search use the "*" symbol.</p>
20+
<form method="GET" action="/search">
21+
<div class="form_row">
22+
<label class="formstyle" for="type">Type:</label>
23+
<input class="formstyle" id="type" type="textbox" name="type">
24+
</div>
25+
<div class="form_row">
26+
<label class="formstyle" for="ship">Ship:</label>
27+
<input class="formstyle" id="ship" type="textbox" name="ship">
28+
</div>
29+
<div class="form_row">
30+
<label class="formstyle" for="number_year">Year:</label>
31+
<input class="formstyle" id="number_year" type="textbox" name="number_year">
32+
</div>
33+
<div class="form_row">
34+
<label class="formstyle" for="number_serial">Serial:</label>
35+
<input class="formstyle" id="number_serial" type="textbox" name="number_serial">
36+
</div>
37+
<div class="form_row">
38+
<label class="formstyle" for="category">Category:</label>
39+
<input class="formstyle" id="category" type="textbox" name="category">
40+
</div>
41+
<div class="form_row">
42+
<label class="formstyle" for="erg_code">ERG code:</label>
43+
<input class="formstyle" id="erg_code" type="textbox" name="erg_code">
44+
</div>
45+
<div class="form_row">
46+
<label class="formstyle" for="parent_equip">Parent equipment:</label>
47+
<input class="formstyle" id="parent_equip" type="textbox" name="parent_equip">
48+
</div>
49+
<div class="form_row">
50+
<label class="formstyle" for="defective_unit">Defective unit:</label>
51+
<input class="formstyle" id="defective_unit" type="textbox" name="defective_unit">
52+
</div>
53+
<div class="form_row">
54+
<label class="formstyle" for="line5">Line 5:</label>
55+
<input class="formstyle" id="line5" type="textbox" name="line5">
56+
</div>
57+
<div class="form_row">
58+
<label class="formstyle" for="defect">Defect:</label>
59+
<input class="formstyle" id="defect" type="textbox" name="defect">
60+
</div>
61+
<div class="form_row">
62+
<label class="formstyle" for="repair_int">Repair intentions:</label>
63+
<input class="formstyle" id="repair_int" type="textbox" name="repair_int">
64+
</div>
65+
<div class="form_row">
66+
<label class="formstyle" for="assistance">Assistance:</label>
67+
<input class="formstyle" id="assistance" type="textbox" name="assistance">
68+
</div>
69+
<div class="form_row">
70+
<label class="formstyle" for="assistance_port">Assistance port:</label>
71+
<input class="formstyle" id="assistance_port" type="textbox" name="assistance_port">
72+
</div>
73+
<div class="form_row">
74+
<label class="formstyle" for="remarks">Remarks:</label>
75+
<input class="formstyle" id="remarks" type="textbox" name="remarks">
76+
</div>
77+
<div class="form_row">
78+
<label class="formstyle" for="signal">Signal text:</label>
79+
<input class="formstyle" id="signal" type="textbox" name="signal">
80+
<input class="submit tall" type="submit" value="Search" name="search">
81+
</div>
82+
</form>
83+
[% END %]
84+
85+
[% INCLUDE footer.html %]

0 commit comments

Comments
 (0)