Skip to content

Commit ccd33bf

Browse files
committed
improve the search and add a "no results"
add ww-update script to call OPL-update and build-search-json.pl
1 parent 9e73176 commit ccd33bf

File tree

7 files changed

+140
-61
lines changed

7 files changed

+140
-61
lines changed

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ htdocs/themes/*
3636
DATA/*
3737
!DATA/uploads
3838
DATA/uploads/*
39-
!htdocs/DATA/search.json
4039
!*README*
4140

4241
docker-compose.yml

bin/dev_scripts/build-search-db.pl renamed to bin/build-search-json.pl

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,21 +49,24 @@ =head1 DESCRIPTION
4949
# These are the default sample problem directory and JSON file.
5050
my $sample_prob_dir = "tutorial/sample-problems";
5151
my $json_file = "htdocs/DATA/search.json";
52-
my $verbose = 0;
52+
my ($verbose, $show_warnings) = (1, 0);
5353

5454
GetOptions(
5555
'p|pg-root=s' => \$pg_root,
5656
'f|json-file=s' => \$json_file,
5757
's|sample-prob-dir=s' => \$sample_prob_dir,
5858
'b|build=s' => \$build,
59+
'w|show-warnings' => \$show_warnings,
5960
'v|verbose+' => \$verbose
6061
);
6162

6263
die "The build options must be one of (all, macros, samples). The value $build is not valid."
6364
if ((grep { $_ eq $build } qw/all macros samples/) != 1);
6465

6566
my $ww_root = $ENV{WW_ROOT};
66-
$ww_root = Mojo::File->new(curfile->dirname, "..", "..")->realpath unless defined($ww_root);
67+
$ww_root = Mojo::File->curfile->dirname->dirname->realpath unless defined($ww_root);
68+
69+
say $ww_root;
6770

6871
die "ww_root: $ww_root is not a directory" unless -d $ww_root;
6972

@@ -99,7 +102,7 @@ =head1 DESCRIPTION
99102
my @files;
100103
my $index = 1; # set an index for each file.
101104

102-
sub processFile {
105+
sub processPGfile {
103106
return unless $_ =~ /\.pg$/;
104107
say "Processing $_" if $verbose;
105108
my $filename = $_;
@@ -192,11 +195,11 @@ sub extractPODNode {
192195
my ($filename, $root, $title) = @_;
193196
my @index = grep { ref($root->[$_]) eq 'ARRAY' && $root->[$_][2] =~ /$title/ } 0 .. scalar(@$root) - 1;
194197
if (@index == 0) {
195-
warn "In $filename: The section named $title is not found in the POD.";
198+
warn "In $filename: The section named $title is not found in the POD." if $show_warnings;
196199
return;
197200
}
198201
if (@index > 1) {
199-
warn "In $filename: There are more than one section named $title in the POD.";
202+
warn "In $filename: There are more than one section named $title in the POD." if $show_warnings;
200203
return;
201204
}
202205
# start at index 2 and extract all text
@@ -225,9 +228,12 @@ sub parseHead2 {
225228
# process a macro file's POD
226229
sub processMacro {
227230
return unless $_ =~ /\.pl$/;
228-
say "Processing $_" if $verbose;
229231
my $file = Mojo::File->new($File::Find::name);
230-
return if $file->dirname =~ /deprecated/;
232+
if ($file->dirname =~ /deprecated/) {
233+
say "Skipping $_. This is deprecated." if $verbose;
234+
return;
235+
}
236+
say "Processing $_" if $verbose;
231237

232238
my $parser = Pod::Simple::SimpleTree->new();
233239
my $root = $parser->parse_file("$file")->root;
@@ -245,7 +251,7 @@ sub processMacro {
245251
}
246252

247253
# Process the sample problems in $sample_prob_dir.
248-
find({ wanted => \&processFile }, "$sample_prob_dir") if (grep { $build eq $_ } qw/all samples/);
254+
find({ wanted => \&processPGfile }, "$sample_prob_dir") if (grep { $build eq $_ } qw/all samples/);
249255

250256
# Process the POD within the macros dir.
251257
find({ wanted => \&processMacro }, "$pg_root/macros") if (grep { $build eq $_ } qw/all macros/);

bin/download-OPL-metadata-release.pl

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,12 @@ BEGIN
8080
die "The directory $libraryDirectory does not exist or is not writable."
8181
if (!-d $libraryDirectory || !-w $libraryDirectory);
8282

83+
warn $ENV{OPL_GIT_REPOSITORY};
84+
85+
my $git_repo = $ENV{OPL_GIT_REPOSITORY} // 'origin';
86+
8387
# Checkout the release tag in the library clone if it hasn't already been done.
84-
`$ce->{externalPrograms}{git} -C $libraryDirectory fetch --tags origin`;
88+
`$ce->{externalPrograms}{git} -C $libraryDirectory fetch --tags $git_repo`;
8589
`$ce->{externalPrograms}{git} -C $libraryDirectory show-ref refs/heads/$releaseTag -q`;
8690
if ($?) {
8791
say "Switching OPL clone in $libraryDirectory to new branch of release tag $releaseTag.";

bin/update-ww.pl

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
#!/usr/bin/env perl
2+
3+
=head1 NAME
4+
5+
update-ww.pl -- run all needed scripts when webwork is updated.
6+
7+
=head1 SYNOPSIS
8+
9+
update-ww.pl [options]
10+
11+
Options:
12+
-a|--all Run both OPL-update and build-search-json.pl
13+
14+
-b|--build-sample-probs Run the build-search-json.pl script with the 'all' flag.
15+
The other options are 'samples' and 'macros' if not all
16+
are desired.
17+
-o|--opl-update Run the OPL-update script. By default the upload-opl-statistics
18+
part of the script is not run. See the upload-opl-stats flags
19+
to change this.
20+
-s|--sample-probs Run the sample-probs part of the script.
21+
22+
-v|--verbose Setting this flag provides details as the script runs.
23+
24+
=cut
25+
26+
use strict;
27+
use warnings;
28+
use feature 'say';
29+
30+
use Mojo::File;
31+
use Getopt::Long qw(:config bundling);
32+
33+
# BEGIN {
34+
# use Env qw(WEBWORK_ROOT);
35+
# }
36+
37+
my $ww_root = Mojo::File->curfile->dirname->dirname->realpath;
38+
39+
my $build = 'all';
40+
my $git_repo = 'origin';
41+
my $all = 1;
42+
my ($verbose, $opl_update, $sample_probs, $upload_opl_stats) = (0, 0, 0, 0);
43+
44+
GetOptions(
45+
'a|all' => \$all,
46+
'b|build-sample-probs=s' => \$build,
47+
'o|opl-update' => \$opl_update,
48+
'g|git-opl-repository=s' => \$git_repo,
49+
's|sample-probs' => \$sample_probs,
50+
'u|upload-opl-stats' => \$upload_opl_stats,
51+
'v|verbose+' => \$verbose
52+
);
53+
54+
my $v = $verbose ? '-v' : '';
55+
if ($all || $sample_probs) {
56+
say 'Rebuilding the sample problem and macro POD file.';
57+
my $search_output = `perl $ww_root/bin/build-search-json.pl $v -b $build`;
58+
say $search_output if $verbose;
59+
}
60+
61+
if ($all || $opl_update) {
62+
say 'Running the OPL-update script.';
63+
$ENV{SKIP_UPLOAD_OPL_STATISTICS} = 1 unless $upload_opl_stats;
64+
$ENV{OPL_GIT_REPOSITORY} = $git_repo;
65+
say "Running the OPL upate script" if $verbose;
66+
my $opl_output = `perl $ww_root/bin/OPL-update`;
67+
say $opl_output if $verbose;
68+
}
69+
70+
1;

htdocs/DATA/search.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

htdocs/js/SampleProblemViewer/search.js

Lines changed: 33 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -3,36 +3,6 @@
33
about every page to be searched (macro POD and sample problems).
44
*/
55
(() => {
6-
// ChatGPT generated throttle function similar to Lodash.
7-
function throttle(func, wait) {
8-
let lastCallTime = 0;
9-
let timeout = null;
10-
let lastArgs, lastContext;
11-
12-
return function throttled(...args) {
13-
const now = Date.now();
14-
const remaining = wait - (now - lastCallTime);
15-
16-
lastArgs = args;
17-
lastContext = this;
18-
19-
if (remaining <= 0 || remaining > wait) {
20-
if (timeout) {
21-
clearTimeout(timeout);
22-
timeout = null;
23-
}
24-
lastCallTime = now;
25-
func.apply(lastContext, lastArgs);
26-
} else if (!timeout) {
27-
timeout = setTimeout(() => {
28-
lastCallTime = Date.now();
29-
timeout = null;
30-
func.apply(lastContext, lastArgs);
31-
}, remaining);
32-
}
33-
};
34-
}
35-
366
const miniSearch = new MiniSearch({ fields: ['terms', 'filename', 'name', 'description', 'methods'] });
377
let pages;
388
// This is the data from sample-problems/macros POD.
@@ -51,32 +21,47 @@
5121
resultList.innerHTML = '';
5222
});
5323

54-
const search = throttle(() => {
55-
const results = miniSearch.search(searchBox.value);
24+
const search = () => {
25+
const results = miniSearch.search(searchBox.value, { prefix: true });
5626
const ids = results.map((p) => p.id);
5727

28+
const includeMacros = document.getElementById('includeMacros').checked;
29+
const includeSP = document.getElementById('includeSP').checked;
30+
5831
resultList.innerHTML = '';
32+
5933
ids.forEach((id) => {
60-
const item = document.createElement('div');
61-
item.classList.add('card');
6234
const p = pages[id - 1];
63-
const file = p.filename.replace('.pg', '');
64-
const path = p.type == 'sample problem' ? 'sampleproblems' : p.type == 'macro' ? 'pod' : '';
35+
if ((p.type == 'sample problem' && includeSP) || (p.type == 'macro' && includeMacros)) {
36+
const item = document.createElement('div');
37+
item.classList.add('card');
38+
39+
const file = p.filename.replace('.pg', '');
40+
const path = p.type == 'sample problem' ? 'sampleproblems' : p.type == 'macro' ? 'pod' : '';
6541

66-
// This is the search results for each page.
67-
item.innerHTML = `
68-
<div class="card-body">
69-
<h5 class="card-title">
70-
<a href=\"/webwork2/${path}/${p.dir}/${file}\">${p.name}</a>
71-
(${p.type})
72-
</h5>
73-
<p class="card-text">${p.description}</p>
74-
</div>
75-
`;
42+
// This is the search results for each page.
7643

77-
resultList.appendChild(item);
44+
item.innerHTML = `
45+
<div class="card-body">
46+
<h5 class="card-title">
47+
<a href=\"/webwork2/${path}/${p.dir}/${file}\">${p.name}</a>
48+
(${p.type})
49+
</h5>
50+
<p class="card-text">${p.description}</p>
51+
</div>
52+
`;
53+
54+
resultList.appendChild(item);
55+
}
7856
});
79-
}, 250);
57+
// If there are no results, say so
58+
if (resultList.children.length == 0) {
59+
const item = document.createElement('div');
60+
item.classList.add('alert', 'alert-info');
61+
item.innerHTML = 'No results found';
62+
resultList.append(item);
63+
}
64+
};
8065

8166
searchBox.addEventListener('keypress', search);
8267
})();

templates/ContentGenerator/SampleProblemViewer.html.ep

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@
2424
<body>
2525
<div class="container-fluid p-3">
2626
<div class="row">
27-
<div class="col-5">
27+
<div class="col-4">
2828
<h1><%= title %></h1>
2929
</div>
30-
<div class="col-6 offset-md-1">
30+
<div class="col-5 offset-md-1">
3131
<div class="input-group mb-3">
3232
<span class="input-group-text" id="basic-addon1">
3333
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-search" viewBox="0 0 16 16">
@@ -38,8 +38,23 @@
3838
<button class="btn btn-outline-secondary" type="button" id="clearSearchButton">Clear</button>
3939
</div>
4040
</div>
41+
<div class="col-2">
42+
<div class="form-check">
43+
<input class="form-check-input" type="checkbox" value="" id="includeMacros" checked>
44+
<label class="form-check-label" for="includeMacros">
45+
Include Macros
46+
</label>
47+
</div>
48+
<div class="form-check">
49+
<input class="form-check-input" type="checkbox" value="" id="includeSP" checked>
50+
<label class="form-check-label" for="includeSP">
51+
Include Sample Problems
52+
</label>
53+
</div>
54+
</div>
4155
</div>
4256

57+
4358
<div class="container">
4459
<div class="row">
4560
<div class="col-5 mt-3">

0 commit comments

Comments
 (0)