diff --git a/.gitignore b/.gitignore
index 2129ff5078..8dca4e4871 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,9 +4,9 @@ applets
tmp
logs
courses.dist
-library-directory-tree.json
-library-subject-tree.json
-textbook-tree.json
+*library-directory-tree.json
+*library-subject-tree.json
+*textbook-tree.json
development.yml
*~
!tmp/README
diff --git a/bin/OPL-update b/bin/OPL-update
index 72382f38cd..9425a89527 100755
--- a/bin/OPL-update
+++ b/bin/OPL-update
@@ -21,6 +21,32 @@ use File::Basename;
use Cwd;
use DBI;
+# Command line arguments
+# for some reason the first command line argument is disappearing before it gets here
+
+my $myLib = "OPL" ; # default value
+my $clearAll = 1 ; # default value - drop ALL old tables
+
+if ( ( 0 + @ARGV ) > 0 ) {
+
+ #print join(" , ", @ARGV );
+
+ $myLib = shift;
+
+ print "myLib = $myLib \n";
+
+ my $nextArg = "none";
+ if ( @ARGV ) {
+ $nextArg = shift ;
+ if ( $nextArg eq "noDrop" ) {
+ $clearAll = 0 ;
+ print "Received the noDrop setting.\n";
+ }
+
+ }
+}
+
+
#(maximum varchar length is 255 for mysql version < 5.0.3.
#You can increase path length to 4096 for mysql > 5.0.3)
@@ -56,6 +82,9 @@ my %OPLtables = (
problem => 'OPL_problem',
morelt => 'OPL_morelt',
pgfile_problem => 'OPL_pgfile_problem',
+ cnt_dbsubject => 'Cnt_DBsubject',
+ cnt_dbchapter => 'Cnt_DBchapter',
+ cnt_dbsection => 'Cnt_DBsection',
);
@@ -74,8 +103,34 @@ my %NPLtables = (
problem => 'NPL-problem',
morelt => 'NPL-morelt',
pgfile_problem => 'NPL-pgfile-problem',
+ cnt_dbsubject => 'Cnt_DBsubject',
+ cnt_dbchapter => 'Cnt_DBchapter',
+ cnt_dbsection => 'Cnt_DBsection',
);
+# Which tables to ALWAYS drop and recreate and which can remain
+# 1 = always drop, 0 = conditional on command-line arguments, 2 = NEVER drop
+my %AlwayDropTables = (
+ dbsubject => 0,
+ dbchapter => 0,
+ dbsection => 0,
+ author => 0,
+ path => 0,
+ keyword => 0,
+ textbook => 0,
+ chapter => 0,
+ section => 0,
+ problem => 0,
+ morelt => 0,
+ pgfile => 1,
+ pgfile_keyword => 1,
+ pgfile_problem => 1,
+ cnt_dbsubject => 2,
+ cnt_dbchapter => 2,
+ cnt_dbsection => 2,
+);
+
+
# Get database connection
@@ -96,9 +151,9 @@ my $dbh = DBI->connect(
},
);
-my $libraryRoot = $ce->{problemLibrary}->{root};
+my $libraryRoot = $ce->{problemLibrary}->{$myLib}->{root};
$libraryRoot =~ s|/+$||;
-my $libraryVersion = $ce->{problemLibrary}->{version};
+my $libraryVersion = $ce->{problemLibrary}->{$myLib}->{version};
my $db_storage_engine = $ce->{problemLibrary_db}->{storage_engine};
my $verbose = 0;
@@ -130,14 +185,30 @@ if($libraryVersion eq '2.5') {
print "Library version is $libraryVersion; NPLtables! \n";
}
+
+# Modify table names for per-library tables
+my @special_tables = qw( pgfile pgfile_keyword pgfile_problem );
+my $tmp1; my $tblName;
+foreach $tmp1 ( @special_tables ) {
+ $tblName = $tables{$tmp1};
+ #print "old table name $tblName\n";
+ if ( $libraryVersion eq '2.5') {
+ $tblName =~ s/OPL/${myLib}/;
+ } else {
+ $tblName =~ s/NPL/${myLib}/;
+ }
+ #print "new table name $tblName\n";
+ $tables{$tmp1} = $tblName;
+}
+
@create_tables = (
-[$tables{dbsubject}, '
+["dbsubject",$tables{dbsubject}, '
DBsubject_id int(15) NOT NULL auto_increment,
name varchar(255) NOT NULL,
KEY DBsubject (name),
PRIMARY KEY (DBsubject_id)
'],
-[$tables{dbchapter}, '
+["dbchapter",$tables{dbchapter}, '
DBchapter_id int(15) NOT NULL auto_increment,
name varchar(255) NOT NULL,
DBsubject_id int(15) DEFAULT 0 NOT NULL,
@@ -145,7 +216,7 @@ if($libraryVersion eq '2.5') {
KEY (DBsubject_id),
PRIMARY KEY (DBchapter_id)
'],
-[$tables{dbsection}, '
+["dbsection",$tables{dbsection}, '
DBsection_id int(15) NOT NULL auto_increment,
name varchar(255) NOT NULL,
DBchapter_id int(15) DEFAULT 0 NOT NULL,
@@ -153,7 +224,7 @@ if($libraryVersion eq '2.5') {
KEY (DBchapter_id),
PRIMARY KEY (DBsection_id)
'],
-[$tables{author}, '
+["author",$tables{author}, '
author_id int (15) NOT NULL auto_increment,
institution tinyblob,
lastname varchar (255) NOT NULL,
@@ -162,7 +233,7 @@ if($libraryVersion eq '2.5') {
KEY author (lastname(100), firstname(100)),
PRIMARY KEY (author_id)
'],
-[$tables{path}, '
+["path",$tables{path}, '
path_id int(15) NOT NULL auto_increment,
path varchar(255) NOT NULL,
machine varchar(255),
@@ -170,7 +241,7 @@ if($libraryVersion eq '2.5') {
KEY (path),
PRIMARY KEY (path_id)
'],
-[$tables{pgfile}, '
+["pgfile",$tables{pgfile}, '
pgfile_id int(15) NOT NULL auto_increment,
DBsection_id int(15) NOT NULL,
author_id int(15),
@@ -184,19 +255,19 @@ if($libraryVersion eq '2.5') {
MO TINYINT,
PRIMARY KEY (pgfile_id)
'],
-[$tables{keyword}, '
+["keyword",$tables{keyword}, '
keyword_id int(15) NOT NULL auto_increment,
keyword varchar(256) NOT NULL,
KEY (keyword),
PRIMARY KEY (keyword_id)
'],
-[$tables{pgfile_keyword}, '
+["pgfile_keyword",$tables{pgfile_keyword}, '
pgfile_id int(15) DEFAULT 0 NOT NULL,
keyword_id int(15) DEFAULT 0 NOT NULL,
KEY pgfile_keyword (keyword_id, pgfile_id),
KEY pgfile (pgfile_id)
'],
-[$tables{textbook}, '
+["textbook",$tables{textbook}, '
textbook_id int (15) NOT NULL auto_increment,
title varchar (255) NOT NULL,
edition int (15) DEFAULT 0 NOT NULL,
@@ -206,7 +277,7 @@ if($libraryVersion eq '2.5') {
pubdate varchar (255),
PRIMARY KEY (textbook_id)
'],
-[$tables{chapter}, '
+["chapter",$tables{chapter}, '
chapter_id int (15) NOT NULL auto_increment,
textbook_id int (15),
number int(3),
@@ -216,7 +287,7 @@ if($libraryVersion eq '2.5') {
KEY (number),
PRIMARY KEY (chapter_id)
'],
-[$tables{section}, '
+["section",$tables{section}, '
section_id int(15) NOT NULL auto_increment,
chapter_id int (15),
number int(3),
@@ -226,7 +297,7 @@ if($libraryVersion eq '2.5') {
KEY (number),
PRIMARY KEY section (section_id)
'],
-[$tables{problem}, '
+["problem",$tables{problem}, '
problem_id int(15) NOT NULL auto_increment,
section_id int(15),
number int(4) NOT NULL,
@@ -235,7 +306,7 @@ if($libraryVersion eq '2.5') {
KEY (section_id),
PRIMARY KEY (problem_id)
'],
-[$tables{morelt}, '
+["morelt",$tables{morelt}, '
morelt_id int(15) NOT NULL auto_increment,
name varchar(255) NOT NULL,
DBsection_id int(15),
@@ -243,10 +314,28 @@ if($libraryVersion eq '2.5') {
KEY (name),
PRIMARY KEY (morelt_id)
'],
-[$tables{pgfile_problem}, '
+["pgfile_problem",$tables{pgfile_problem}, '
pgfile_id int(15) DEFAULT 0 NOT NULL,
problem_id int(15) DEFAULT 0 NOT NULL,
PRIMARY KEY (pgfile_id, problem_id)
+'],
+["cnt_dbsubject",$tables{cnt_dbsubject}, '
+ libcode varchar(60) NOT NULL,
+ DBsubject_id int(15) NOT NULL,
+ count int(15) NOT NULL,
+ PRIMARY KEY (libcode,DBsubject_id)
+'],
+["cnt_dbchapter",$tables{cnt_dbchapter}, '
+ libcode varchar(60) NOT NULL,
+ DBchapter_id int(15) NOT NULL,
+ count int(15) NOT NULL,
+ PRIMARY KEY (libcode,DBchapter_id)
+'],
+["cnt_dbsection",$tables{cnt_dbsection}, '
+ libcode varchar(60) NOT NULL,
+ DBsection_id int(15) NOT NULL,
+ count int(15) NOT NULL,
+ PRIMARY KEY (libcode,DBsection_id)
']);
### End of database data
@@ -258,8 +347,25 @@ $dbh->do("DROP TABLE IF EXISTS `NPL-institution`");
$dbh->do("DROP TABLE IF EXISTS `NPL-pgfile-institution`");
for my $tableinfo (@create_tables) {
- my $tabname = $tableinfo->[0];
- my $tabinit = $tableinfo->[1];
+ my $tabCnm = $tableinfo->[0];
+ my $tabname = $tableinfo->[1];
+ my $tabinit = $tableinfo->[2];
+
+# FIXME some tables should NOT be dropped on special libraries
+ if ( $AlwayDropTables{$tabCnm} == 2 ) {
+ print "Not dropping/re-creating $tabname\n";
+ my $query = "CREATE TABLE IF NOT EXISTS `$tabname` ( $tabinit ) ENGINE=$db_storage_engine";
+ $dbh->do($query);
+ next;
+ }
+ if ( $clearAll == 0 ) {
+ # Do not drop and recreate some tables
+ if ( $AlwayDropTables{$tabCnm} == 0 ) {
+ print "Not dropping/re-creating $tabname\n";
+ next;
+ }
+ }
+
my $query = "DROP TABLE IF EXISTS `$tabname`";
$dbh->do($query);
$query = "CREATE TABLE `$tabname` ( $tabinit ) ENGINE=$db_storage_engine";
@@ -431,7 +537,7 @@ if(open(IN, "$libraryRoot/Textbooks")) {
close(IN);
} else {
print "Textbooks file was not found in library $libraryRoot. If the path to the problem library doesn't seem
- correct, make modifications in webwork2/conf/site.conf (\$problemLibrary{root}). If that is correct then
+ correct, make modifications in webwork2/conf/localOverrides.conf (\$problemLibrary{OPL}{root}). If that is correct then
updating from git should download the Textbooks file.\n";
}
#### End of textbooks
@@ -453,7 +559,7 @@ if(open(IN, "$libraryRoot/Taxonomy2")) {
$canopenfile = 1;
} else {
print "Taxonomy file was not found in library $libraryRoot. If the path to the problem library doesn't seem
- correct, make modifications in webwork2/conf/site.conf (\$problemLibrary{root}). If that is correct then
+ correct, make modifications in webwork2/conf/localOverrides.conf (\$problemLibrary{OPL}{root}). If that is correct then
updating from git should download the Taxonomy file.\n";
}
@@ -514,7 +620,12 @@ if($canopenfile) {
#### Save the official taxonomy in json format
my $webwork_htdocs = $ce->{webwork_dir}."/htdocs";
-my $file = "$webwork_htdocs/DATA/tagging-taxonomy.json";
+
+# Get the filename for the taxo_file which is set for THIS library via the
+# settings in conf/defaults.config and/or conf/localOverrides.conf
+my $taxo_file = $ce->{problemLibrary}->{$myLib}->{taxo};
+
+my $file = "$webwork_htdocs/DATA/${taxo_file}";
open(OUTF, ">$file") or die "Cannot open $file";
print OUTF to_json($tagtaxo,{pretty=>1}) or die "Cannot write to $file";
close(OUTF);
@@ -860,33 +971,37 @@ sub pgfiles {
print "\n\n";
-# Now prune away DBsection, etc, which do not appear in any files
-#%my $query = "SELECT chapter_id FROM `$tables{chapter}` WHERE textbook_id = \"$bookid\" AND number = \"$1\"";
-#%my $chapid = $dbh->selectrow_array($query);
+# When allowing multiple libraries, only the FIRST library should do pruning.
+if ( $clearAll == 1 ) {
-#select dbs.DBsection_id from OPL_DBsection dbs;
-#select COUNT(*) from OPL_pgfile where DBsection_id=857;
+ # Now prune away DBsection, etc, which do not appear in any files
+ #%my $query = "SELECT chapter_id FROM `$tables{chapter}` WHERE textbook_id = \"$bookid\" AND number = \"$1\"";
+ #%my $chapid = $dbh->selectrow_array($query);
-my $dbsects = $dbh->selectall_arrayref("SELECT DBsection_id from `$tables{dbsection}`");
-for my $sect (@{$dbsects}) {
+ #select dbs.DBsection_id from OPL_DBsection dbs;
+ #select COUNT(*) from OPL_pgfile where DBsection_id=857;
+
+ my $dbsects = $dbh->selectall_arrayref("SELECT DBsection_id from `$tables{dbsection}`");
+ for my $sect (@{$dbsects}) {
$sect = $sect->[0];
my $srar = $dbh->selectall_arrayref("SELECT * FROM `$tables{pgfile}` WHERE DBsection_id=$sect");
if(scalar(@{$srar})==0) {
$dbh->do("DELETE FROM `$tables{dbsection}` WHERE DBsection_id=$sect");
}
-}
+ }
-my $dbchaps = $dbh->selectall_arrayref("SELECT DBchapter_id from `$tables{dbchapter}`");
-for my $chap (@{$dbchaps}) {
+ my $dbchaps = $dbh->selectall_arrayref("SELECT DBchapter_id from `$tables{dbchapter}`");
+ for my $chap (@{$dbchaps}) {
$chap = $chap->[0];
my $srar = $dbh->selectall_arrayref("SELECT * FROM `$tables{dbsection}` WHERE DBchapter_id=$chap");
if(scalar(@{$srar})==0) {
$dbh->do("DELETE FROM `$tables{dbchapter}` WHERE DBchapter_id=$chap");
}
+ }
}
# Now run the script build-library-tree
-# This is used to create the file library-tree.json which can be used to
+# This is used to create the file ${myLib}-library-tree.json which can be used to
# load in subject-chapter-section information for the OPL
use strict;
@@ -960,16 +1075,20 @@ foreach my $i (0..$#subjects){
push (@subject_tree, $clone);
}
-build_library_directory_tree($ce);
-build_library_subject_tree($ce,$dbh);
-build_library_textbook_tree($ce,$dbh);
+build_library_directory_tree($myLib,$ce);
+build_library_subject_tree($myLib,$ce,$dbh);
+build_library_textbook_tree($myLib,$ce,$dbh);
$dbh->disconnect;
-if ($ce->{problemLibrary}{showLibraryLocalStats} ||
- $ce->{problemLibrary}{showLibraryGlobalStats}) {
- print "\nUpdating Library Statistics.\n";
- do $ENV{WEBWORK_ROOT}.'/bin/update-OPL-statistics';
+if ( $myLib eq "OPL" ) {
+ # Only the "real" OPL has Library statistics
+
+ if ($ce->{problemLibrary}{$myLib}{showLibraryLocalStats} ||
+ $ce->{problemLibrary}{$myLib}{showLibraryGlobalStats}) {
+ print "\nUpdating Library Statistics.\n";
+ do $ENV{WEBWORK_ROOT}.'/bin/update-OPL-statistics';
+ }
}
diff --git a/bin/OPLUtils.pm b/bin/OPLUtils.pm
index 323436ab48..62ceb25650 100644
--- a/bin/OPLUtils.pm
+++ b/bin/OPLUtils.pm
@@ -6,11 +6,13 @@ use base qw(Exporter);
# This file contains the subroutines that build JSON files from the database to help speed up the client side.
#
# The following files are created:
-# 1. $webwork_htdocs/DATA/library-directory-tree.json (the directory structure of the library)
-# 2. $webwork_htdocs/DATA/library-subject-tree.json (the subject/chapter/section struture of the library)
-# 3.
+# 1. $webwork_htdocs/DATA/LIBNAME-library-directory-tree.json (the directory structure of the library)
+# 2. $webwork_htdocs/DATA/LIBNAME-library-subject-tree.json (the subject/chapter/section struture of the library)
+# 3. $webwork_htdocs/DATA/LIBNAME-textbook-tree.json (textbook data)
-# This is used to create the file library-directory-tree.json which can be used to load in
+# The filenames are set via hash values for the current library in conf/defaults.config and/or conf/localOverrides.conf
+
+# This is used to create the file LIBNAME-library-directory-tree.json which can be used to load in
# directory information for the OPL. It writes the file as a JSON of directories to be easily loaded.
use strict;
@@ -25,6 +27,10 @@ use JSON;
our @EXPORT = ();
our @EXPORT_OK = qw(build_library_directory_tree build_library_subject_tree build_library_textbook_tree);
+# what library are we handling, now is first argument of the function
+my $myLib = shift;
+
+
### Data for creating the database tables
@@ -65,16 +71,17 @@ my %NPLtables = (
-
-
sub build_library_directory_tree {
+ # what library are we handling, now is first argument of the function
+ my $myLib = shift;
+
my $ce = shift;
print "Creating the Directory Tree\n";
- my $libraryRoot = $ce->{problemLibrary}->{root};
+ my $libraryRoot = $ce->{problemLibrary}->{$myLib}->{root};
$libraryRoot =~ s|/+$||;
- my $libraryVersion = $ce->{problemLibrary}->{version};
+ my $libraryVersion = $ce->{problemLibrary}->{$myLib}->{version};
my($filename, $directories) = fileparse($libraryRoot);
@@ -82,7 +89,12 @@ sub build_library_directory_tree {
push(@dirArray,buildTree($libraryRoot));
my $webwork_htdocs = $ce->{webwork_dir}."/htdocs";
- my $file = "$webwork_htdocs/DATA/library-directory-tree.json";
+
+ # Determine the proper json file names to use for THIS library via the
+ # settings in conf/defaults.config and/or conf/localOverrides.conf
+ my $jsonFile = $ce->{problemLibrary}->{$myLib}->{tree};
+
+ my $file = "$webwork_htdocs/DATA/${jsonFile}";
# use a variable for the file handle
my $OUTFILE;
@@ -144,15 +156,30 @@ sub buildTree {
sub build_library_subject_tree {
- my ($ce,$dbh) = @_;
+ # what library are we handling, now is first argument of the function
+ my ($myLib,$ce,$dbh) = @_;
- my $libraryRoot = $ce->{problemLibrary}->{root};
+ my $libraryRoot = $ce->{problemLibrary}->{$myLib}->{root};
$libraryRoot =~ s|/+$||;
- my $libraryVersion = $ce->{problemLibrary}->{version};
+ my $libraryVersion = $ce->{problemLibrary}->{$myLib}->{version};
my %tables = ($libraryVersion eq '2.5')? %OPLtables : %NPLtables;
+ # Modify table names for per-library tables
+ my @special_tables = qw( pgfile pgfile_keyword pgfile_problem );
+ my $tmp1; my $tblName;
+ foreach $tmp1 ( @special_tables ) {
+ $tblName = $tables{$tmp1};
+ #print "old table name $tblName\n";
+ if ( $libraryVersion eq '2.5') {
+ $tblName =~ s/OPL/$myLib/;
+ } else {
+ $tblName =~ s/NPL/$myLib/;
+ }
+ #print "new table name $tblName\n";
+ $tables{$tmp1} = $tblName;
+ }
my $selectClause = "select subj.name, ch.name, sect.name, path.path,pg.filename from `$tables{dbsection}` AS sect "
."JOIN `$tables{dbchapter}` AS ch ON ch.DBchapter_id = sect.DBchapter_id "
@@ -272,7 +299,12 @@ sub build_library_subject_tree {
print "\n";
my $webwork_htdocs = $ce->{webwork_dir}."/htdocs";
- my $file = "$webwork_htdocs/DATA/library-subject-tree.json";
+
+ # Determine the proper json file names to use for THIS library via the
+ # settings in conf/defaults.config and/or conf/localOverrides.conf
+ my $jsonFile = $ce->{problemLibrary}->{$myLib}->{subj};
+
+ my $file = "$webwork_htdocs/DATA/${jsonFile}";
# use a variable for the file handle
my $OUTFILE;
@@ -292,15 +324,29 @@ sub build_library_subject_tree {
}
sub build_library_textbook_tree {
+ # what library are we handling, now is first argument of the function
+ my ($myLib,$ce,$dbh) = @_;
- my ($ce,$dbh) = @_;
-
- my $libraryRoot = $ce->{problemLibrary}->{root};
+ my $libraryRoot = $ce->{problemLibrary}->{$myLib}->{root};
$libraryRoot =~ s|/+$||;
- my $libraryVersion = $ce->{problemLibrary}->{version};
+ my $libraryVersion = $ce->{problemLibrary}->{$myLib}->{version};
my %tables = ($libraryVersion eq '2.5')? %OPLtables : %NPLtables;
+ # Modify table names for per-library tables
+ my @special_tables = qw( pgfile pgfile_keyword pgfile_problem );
+ my $tmp1; my $tblName;
+ foreach $tmp1 ( @special_tables ) {
+ $tblName = $tables{$tmp1};
+ #print "old table name $tblName\n";
+ if ( $libraryVersion eq '2.5') {
+ $tblName =~ s/OPL/$myLib/;
+ } else {
+ $tblName =~ s/NPL/$myLib/;
+ }
+ #print "new table name $tblName\n";
+ $tables{$tmp1} = $tblName;
+ }
my $selectClause = "SELECT pg.pgfile_id from `$tables{path}` as path "
."LEFT JOIN `$tables{pgfile}` AS pg ON pg.path_id=path.path_id "
@@ -376,7 +422,12 @@ sub build_library_textbook_tree {
print "\n";
my $webwork_htdocs = $ce->{webwork_dir}."/htdocs";
- my $file = "$webwork_htdocs/DATA/textbook-tree.json";
+
+ # Determine the proper json file names to use for THIS library via the
+ # settings in conf/defaults.config and/or conf/localOverrides.conf
+ my $jsonFile = $ce->{problemLibrary}->{$myLib}->{text};
+
+ my $file = "$webwork_htdocs/DATA/${jsonFile}";
# use a variable for the file handle
my $OUTFILE;
diff --git a/bin/setfilepermissions b/bin/setfilepermissions
index eb9ab9e03c..00854c9d69 100755
--- a/bin/setfilepermissions
+++ b/bin/setfilepermissions
@@ -72,7 +72,7 @@ system("chmod g+w ".$ce->{pg_dir}."/lib/chromatic");
# The server should not be able to write to the OPL (for most sites)
-my $libroot = $ce->{problemLibrary}->{root};
+my $libroot = $ce->{problemLibrary}->{OPL}->{root};
system("chown -R $me $libroot");
system("chmod -R 755 $libroot");
diff --git a/bin/update-OPL-statistics b/bin/update-OPL-statistics
index 528b165f1c..35efd8cdaa 100755
--- a/bin/update-OPL-statistics
+++ b/bin/update-OPL-statistics
@@ -182,7 +182,8 @@ $dbh->commit();
# check to see if the global statistics file exists and if it does, upload it.
-my $global_sql_file = $ce->{problemLibrary}{root}.'/OPL_global_statistics.sql';
+# FIXME - currently hardwired for OPL
+my $global_sql_file = $ce->{problemLibrary}{OPL}{root}.'/OPL_global_statistics.sql';
if (-e $global_sql_file) {
@@ -201,6 +202,9 @@ DROP TABLE IF EXISTS OPL_global_statistics;
EOS
$dbh->commit();
+ # Added NSW
+ $dbh->disconnect();
+
$dbuser = shell_quote($dbuser);
$dbpass = shell_quote($dbpass);
$db = shell_quote($db);
@@ -209,6 +213,8 @@ EOS
`$mysql_command --host=$host --port=$port --user=$dbuser --password=$dbpass $db < $global_sql_file`;
+} else {
+ $dbh->disconnect();
}
1;
diff --git a/conf/defaults.config b/conf/defaults.config
index a442618fcd..bca858df9c 100644
--- a/conf/defaults.config
+++ b/conf/defaults.config
@@ -572,6 +572,10 @@ $maxCourseIdLength = 40;
#
# The problemLibrary configuration data should now be set in localOverrides.conf
+# 2018 - in order to support multiple installed libraries, there are changes to
+# the structure of the configuration settings.
+# the "{OPL}" was added to the path to the records for the main OPL settings.
+
# For configuration instructions, see:
# http://webwork.maa.org/wiki/National_Problem_Library
# The directory containing the natinal problem library files.
@@ -582,8 +586,8 @@ $maxCourseIdLength = 40;
#RE-CONFIGURE problemLibrary values in localOverrides.conf
#################################################
-$problemLibrary{root} ="/opt/webwork/libraries/webwork-open-problem-library/OpenProblemLibrary";
-$problemLibrary{version} ="2.5"; # 2.0 for NPL, 2.5 for OPL
+$problemLibrary{OPL}{root} ="/opt/webwork/libraries/webwork-open-problem-library/OpenProblemLibrary";
+$problemLibrary{OPL}{version} ="2.5"; # 2.0 for NPL, 2.5 for OPL
###########################################################
# Problem Library SQL database connection information
@@ -594,14 +598,16 @@ $problemLibrary_db = {
storage_engine => 'MYISAM',
};
-$problemLibrary{tree} = 'library-directory-tree.json';
+$problemLibrary{OPL}{tree} = 'OPL-library-directory-tree.json';
+$problemLibrary{OPL}{taxo} = 'OPL-tagging-taxonomy.json';
+
# These flags control if statistics on opl problems are shown in the library
# browser. If you want to include local statistics you will need to
# run webwork2/bin/update-OPL-statistics on a regular basis.
-$problemLibrary{showLibraryLocalStats} = 1;
-# This flag controls whether global statistics will0be displayed
-$problemLibrary{showLibraryGlobalStats} = 1;
+$problemLibrary{OPL}{showLibraryLocalStats} = 1;
+# This flag controls whether global statistics will be displayed
+$problemLibrary{OPL}{showLibraryGlobalStats} = 1;
################################################################################
# Logs
diff --git a/conf/localOverrides.conf.dist b/conf/localOverrides.conf.dist
index 16cf72334e..e3db32aa6b 100644
--- a/conf/localOverrides.conf.dist
+++ b/conf/localOverrides.conf.dist
@@ -121,26 +121,130 @@ $webworkFiles{screenSnippets}{setHeader} = "$webworkDirs{conf}/snippets/
# NationalProblemLibrary -- OpenProblemLibrary
################################################################################
+# 2018 - in order to support multiple installed libraries, there are changes to
+# the structure of the configuration settings.
+# the "{OPL}" was added to the path to the records for the main OPL settings.
+
+$problemLibrary{OPL} = { }; # Create an empty hash for the OPL library records
# For configuration instructions, see:
# http://webwork.maa.org/wiki/National_Problem_Library
# The directory containing the natinal problem library files. Set to "" if no problem
# library is installed.
# NationalProblemLibrary (NPL) has been renamed to OpenProblemLibrary (OPL)
-#$problemLibrary{root} = "/opt/webwork/libraries/NationalProblemLibrary";
-#$problemLibrary{version} = "2";
-# uncomment these lines below and comment out the line above if using OPL instead of NPL
+#$problemLibrary{OPL}{root} = "/opt/webwork/libraries/NationalProblemLibrary";
+#$problemLibrary{OPL}{version} = "2";
+# uncomment the 2 lines above and comment the 2 below if using NPL instead of OPL
+
+$problemLibrary{OPL}{root} = "/opt/webwork/libraries/webwork-open-problem-library/OpenProblemLibrary";
+$contribLibrary{OPL}{root} = "/opt/webwork/libraries/webwork-open-problem-library/Contrib";
+$problemLibrary{OPL}{version} = "2.5";
+
+# What is the "displayed" name of this library
+$problemLibrary{OPL}{name} = "Open Problem Library";
+
-$problemLibrary{root} = "/opt/webwork/libraries/webwork-open-problem-library/OpenProblemLibrary";
-$contribLibrary{root} = "/opt/webwork/libraries/webwork-open-problem-library/Contrib";
-$problemLibrary{version} = "2.5";
+# What is the name of the symbolic link from inside course template directories
+# to this library. For the main OPL the value "Library" should be used. Some
+# PG files which load other files have that value hard-coded in.
+$problemLibrary{OPL}{linkname} = "Library"; # Do NOT change this for the OPL
+
+# Used to get internal short name from the "linkname":
+$problemLibrary{LookupTable}{Library} = "OPL";
+
+# JSON files for this library
+$problemLibrary{OPL}{tree} = 'OPL-library-directory-tree.json';
+$problemLibrary{OPL}{taxo} = 'OPL-tagging-taxonomy.json';
+$problemLibrary{OPL}{subj} = 'OPL-library-subject-tree.json';
+$problemLibrary{OPL}{text} = 'OPL-textbook-tree.json';
# These flags control if statistics on opl problems are shown in the library
# browser. If you want to include local statistics you will need to
# run webwork2/bin/update-OPL-statistics on a regular basis.
-$problemLibrary{showLibraryLocalStats} = 1;
+$problemLibrary{OPL}{showLibraryLocalStats} = 1;
# This flag controls whether global statistics will be displayed
-$problemLibrary{showLibraryGlobalStats} = 1;
+$problemLibrary{OPL}{showLibraryGlobalStats} = 1;
+
+# ======================================================
+
+# Sample records for an additional SEARCHABLE library
+
+#$problemLibrary{TSTL1} = { }; # Empty hash for the TSTL1 library records
+
+# Where is the library root directory on the server
+#$problemLibrary{TSTL1}{root} = "/opt/webwork/libraries/tl-01";
+
+# What table version should we use. Should match that of the OTHER libraries
+# so we use the value set for the primary libraries
+#$problemLibrary{TSTL1}{version} = "$problemLibrary{OPL}{version}";
+
+# What is the "displayed" name of this library
+#$problemLibrary{TSTL1}{name} = "Test Library 1";
+
+# What is the name of the symbolic link from inside course template directories
+# to this library.
+# Warning: Do NOT use the value "Library" for anything except the main OPL.
+# Some PG files in the OPL reference/load other problems under the
+# assumption that the OPL is under "Library" so we should NOT put something else there.
+#$problemLibrary{TSTL1}{linkname} = "TestLibrary1"; # Do not call this "Library" that should be reserved for the main OPL only, as linked PG problems in the OPL expect that specific value
+
+# Set the LookupTable values used to get internal short name from the "linkname":
+#$problemLibrary{LookupTable}{TestLibrary1} = "TSTL1";
+
+# JSON files for this library
+#$problemLibrary{TSTL1}{tree} = 'TSTL1-library-directory-tree.json';
+#$problemLibrary{TSTL1}{taxo} = 'TSTL1-tagging-taxonomy.json';
+#$problemLibrary{TSTL1}{subj} = 'TSTL1-library-subject-tree.json';
+#$problemLibrary{TSTL1}{text} = 'TSTL1-textbook-tree.json';
+
+# A present it is assumed that additional libraries will NOT have stats supports,
+# so we disable the following settings.
+#$problemLibrary{TSTL1}{showLibraryLocalStats} = 0;
+#$problemLibrary{TSTL1}{showLibraryGlobalStats} = 0;
+
+# End of sample records for an additional SEARCHABLE library
+
+# ======================================================
+
+# Sample records for an additional SEARCHABLE library
+
+#$problemLibrary{TSTL2} = { }; # Empty hash for the TSTL1 library records
+
+# Where is the library root directory on the server
+#$problemLibrary{TSTL2}{root} = "/opt/webwork/libraries/tl-02";
+
+# What table version should we use. Should match that of the OTHER libraries
+# so we use the value set for the primary libraries
+#$problemLibrary{TSTL2}{version} = "$problemLibrary{OPL}{version}";
+
+# What is the "displayed" name of this library
+#$problemLibrary{TSTL2}{name} = "Test Library 2";
+
+# What is the name of the symbolic link from inside course template directories
+# to this library.
+# Warning: Do NOT use the value "Library" for anything except the main OPL.
+# Some PG files in the OPL reference/load other problems under the
+# assumption that the OPL is under "Library" so we should NOT put something else there.
+#$problemLibrary{TSTL2}{linkname} = "TestLibrary2"; # Do not call this "Library" that should be reserved for the main OPL only, as linked PG problems in the OPL expect that specific value
+
+# Set the LookupTable values used to get internal short name from the "linkname":
+#$problemLibrary{LookupTable}{TestLibrary2} = "TSTL2";
+
+# JSON files for this library
+#$problemLibrary{TSTL2}{tree} = 'TSTL2-library-directory-tree.json';
+#$problemLibrary{TSTL2}{taxo} = 'TSTL2-tagging-taxonomy.json';
+#$problemLibrary{TSTL2}{subj} = 'TSTL2-library-subject-tree.json';
+#$problemLibrary{TSTL2}{text} = 'TSTL2-textbook-tree.json';
+
+# A present it is assumed that additional libraries will NOT have stats supports,
+# so we disable the following settings.
+#$problemLibrary{TSTL2}{showLibraryLocalStats} = 0;
+#$problemLibrary{TSTL2}{showLibraryGlobalStats} = 0;
+
+# End of sample records for an additional SEARCHABLE library
+
+# ======================================================
+
# Additional library buttons can be added to the Library Browser (SetMaker.pm)
# by adding the libraries you want to the following line. For each key=>value
@@ -322,12 +426,12 @@ $pg{options}{periodicRandomizationPeriod} = 5;
################################################################################
$pg{specialPGEnvironmentVars}{DragMath} = 0;
- $pg{specialPGEnvironmentVars}{CAPA_Tools} = "$courseDirs{templates}/Contrib/CAPA/macros/CAPA_Tools/",
- $pg{specialPGEnvironmentVars}{CAPA_MCTools} = "$courseDirs{templates}/Contrib/CAPA/macros/CAPA_MCTools/",
- $pg{specialPGEnvironmentVars}{CAPA_GraphicsDirectory} = "$courseDirs{templates}/Contrib/CAPA/CAPA_Graphics/",
- push @{$pg{directories}{macrosPath}},
- "$courseDirs{templates}/Contrib/CAPA/macros/CAPA_Tools",
- "$courseDirs{templates}/Contrib/CAPA/macros/CAPA_MCTools";
+ #$pg{specialPGEnvironmentVars}{CAPA_Tools} = "$courseDirs{templates}/Contrib/CAPA/macros/CAPA_Tools/",
+ #$pg{specialPGEnvironmentVars}{CAPA_MCTools} = "$courseDirs{templates}/Contrib/CAPA/macros/CAPA_MCTools/",
+ #$pg{specialPGEnvironmentVars}{CAPA_GraphicsDirectory} = "$courseDirs{templates}/Contrib/CAPA/CAPA_Graphics/",
+ #push @{$pg{directories}{macrosPath}},
+ # "$courseDirs{templates}/Contrib/CAPA/macros/CAPA_Tools",
+ # "$courseDirs{templates}/Contrib/CAPA/macros/CAPA_MCTools";
# The link Contrib in the course templates directory should point to ../webwork-open-problem-library/Contrib
diff --git a/conf/site.conf.dist b/conf/site.conf.dist
index 2f479c169b..9e0be2c3bb 100644
--- a/conf/site.conf.dist
+++ b/conf/site.conf.dist
@@ -250,6 +250,9 @@ $mail{tls_allowed} = 0;
#
# The problemLibrary configuration data should now be set in localOverrides.conf
+# 2018 - in order to support multiple installed libraries, there are changes to
+# the structure of the configuration settings.
+
# For configuration instructions, see:
# http://webwork.maa.org/wiki/National_Problem_Library
# The directory containing the Open Problem Library files.
@@ -260,7 +263,7 @@ $mail{tls_allowed} = 0;
#CONFIGURE problemLibrary values in this file. These settings override defaults in default.config
#################################################
-$problemLibrary{root} ="/opt/webwork/libraries/webwork-open-problem-library/OpenProblemLibrary";
+$problemLibrary{OPL}{root} ="/opt/webwork/libraries/webwork-open-problem-library/OpenProblemLibrary";
###########################################################
################################################################################
diff --git a/htdocs/js/apps/SetMaker/setmaker.js b/htdocs/js/apps/SetMaker/setmaker.js
index 47b78150e6..0520103bf7 100644
--- a/htdocs/js/apps/SetMaker/setmaker.js
+++ b/htdocs/js/apps/SetMaker/setmaker.js
@@ -94,20 +94,24 @@ function init_webservice(command) {
}
function lib_update(who, what) {
- var child = { subjects : 'chapters', chapters : 'sections', sections : 'count'};
+ var child = { myLibrary : 'subjects', subjects : 'chapters', chapters : 'sections', sections : 'count'};
nomsg();
var all = 'All ' + capFirstLetter(who);
+ if(who=='myLibrary') { all = 'All Libraries'; }
+
var mydefaultRequestObject = init_webservice('searchLib');
if(mydefaultRequestObject == null) {
// We failed
// console.log("Could not get webservice request object");
return false;
}
+ var myLb = $('[name="library_name"] option:selected').val();
var subj = $('[name="library_subjects"] option:selected').val();
var chap = $('[name="library_chapters"] option:selected').val();
var sect = $('[name="library_sections"] option:selected').val();
+ if(myLb == 'All Libraries'){ myLb = '';};
if(subj == 'All Subjects') { subj = '';};
if(chap == 'All Chapters') { chap = '';};
if(sect == 'All Sections') { sect = '';};
@@ -117,12 +121,16 @@ function lib_update(who, what) {
if(lib_text == 'All Textbooks') { lib_text = '';};
if(lib_textchap == 'All Chapters') { lib_textchap = '';};
if(lib_textsect == 'All Sections') { lib_textsect = '';};
+
+ mydefaultRequestObject.library_name = myLb;
+
mydefaultRequestObject.library_subjects = subj;
mydefaultRequestObject.library_chapters = chap;
mydefaultRequestObject.library_sections = sect;
mydefaultRequestObject.library_textbooks = lib_text;
mydefaultRequestObject.library_textchapter = lib_textchap;
mydefaultRequestObject.library_textsection = lib_textsect;
+
if(who == 'count') {
mydefaultRequestObject.command = 'countDBListings';
// console.log(mydefaultRequestObject);
@@ -131,6 +139,7 @@ function lib_update(who, what) {
data: mydefaultRequestObject,
timeout: 10000, //milliseconds
success: function (data) {
+
if (data.match(/WeBWorK error/)) {
reportWWerror(data);
}
@@ -139,11 +148,21 @@ function lib_update(who, what) {
// console.log(response);
var arr = response.result_data;
arr = arr[0];
- var line = "There are "+ arr +" matching WeBWorK problems"
- if(arr == "1") {
- line = "There is 1 matching WeBWorK problem"
+
+ if(myLb == ''){ myLb = 'All Libraries';};
+
+
+ var line = "There are "+ arr +" matching WeBWorK problems in " + myLb
+ if (arr == "1") {
+ line = "There is 1 matching WeBWorK problem in " + myLb
+ } else if (arr == "0") {
+ line = "There are no matching WeBWorK problem in " + myLb
+
}
$('#library_count_line').html(line);
+
+ if(myLb == 'All Libraries'){ myLb = '';};
+
return true;
},
error: function (data) {
@@ -157,9 +176,35 @@ function lib_update(who, what) {
setselect('library_'+who, [all]);
return lib_update(child[who], 'clear');
}
+ if(who=='subjects' && myLb=='') { return lib_update(who, 'clear'); }
if(who=='chapters' && subj=='') { return lib_update(who, 'clear'); }
if(who=='sections' && chap=='') { return lib_update(who, 'clear'); }
- if(who=='sections') { subcommand = "getSectionListings";}
+
+// if(who=='myLibrary'){ subcommand = "getAllLibraries";}
+
+ if(who=='myLibrary'){
+ subcommand = "getAllLibraries";
+ mydefaultRequestObject.library_name='';
+ mydefaultRequestObject.library_subjects='';
+ mydefaultRequestObject.library_chapters='';
+ mydefaultRequestObject.library_sections='';
+ }
+ if(who=='subjects') {
+ subcommand = "getAllDBsubjects";
+ mydefaultRequestObject.library_subjects='';
+ mydefaultRequestObject.library_chapters='';
+ mydefaultRequestObject.library_sections='';
+ }
+ if(who=='chapters') {
+ subcommand = "getAllDBchapters";
+ mydefaultRequestObject.library_chapters='';
+ mydefaultRequestObject.library_sections='';
+ }
+ if(who=='sections') {
+ subcommand = "getSectionListings";
+ mydefaultRequestObject.library_sections='';
+ }
+
mydefaultRequestObject.command = subcommand;
// console.log(mydefaultRequestObject);
return $.ajax({type:'post',
diff --git a/lib/WeBWorK/ContentGenerator/CourseAdmin.pm b/lib/WeBWorK/ContentGenerator/CourseAdmin.pm
index 118902dae1..f1f9eba8c4 100644
--- a/lib/WeBWorK/ContentGenerator/CourseAdmin.pm
+++ b/lib/WeBWorK/ContentGenerator/CourseAdmin.pm
@@ -3384,8 +3384,8 @@ sub upgrade_notification {
}
}
- die "Couldn't find ".$ce->{problemLibrary}{root}.'. Are you sure $problemLibrary{root} is set correctly in localOverrides.conf?' unless
- chdir($ce->{problemLibrary}{root});
+ die "Couldn't find ".$ce->{problemLibrary}{OPL}{root}.'. Are you sure $problemLibrary{OPL}{root} is set correctly in localOverrides.conf?' unless
+ chdir($ce->{problemLibrary}{OPL}{root});
if ($LibraryRemote && $LibraryBranch) {
# Check if there is an updated version of the OPL available
@@ -3421,11 +3421,11 @@ sub upgrade_notification {
# Check to see if the OPL_update script has been run more recently
# than the last pull of the library.
# this json file is (re)-created every time OPL-update is run.
- my $jsonfile = $ce->{webworkDirs}{htdocs}.'/DATA/'.$ce->{problemLibrary}{tree};
+ my $jsonfile = $ce->{webworkDirs}{htdocs}.'/DATA/'.$ce->{problemLibrary}{OPL}{tree};
# If no json file then the OPL script needs to be run
unless (-e $jsonfile) {
$upgradesAvailable = 1;
- $upgradeMessage .= CGI::Tr(CGI::td($r->maketext('There is no library tree file for the library, you will need to run OPL-update.')));
+ $upgradeMessage .= CGI::Tr(CGI::td($r->maketext('There is no library tree file for the OPL library, you will need to run OPL-update (on the main OPL).')));
# otherwise we need to check to see if the date on the tree file
# is after the date on the last commit in the library
} else {
@@ -3435,7 +3435,7 @@ sub upgrade_notification {
my $lastcommit = `git log -1 --pretty=format:%at`;
if ($lastcommit > $opldate) {
$upgradesAvailable = 1;
- $upgradeMessage .= CGI::Tr(CGI::td($r->maketext('The library index is older than the library, you need to run OPL-update.')));
+ $upgradeMessage .= CGI::Tr(CGI::td($r->maketext('The OPL library index is older than the OPL library, you need to run OPL-update(on the main OPL).')));
}
}
}
diff --git a/lib/WeBWorK/ContentGenerator/Instructor/SetMaker.pm b/lib/WeBWorK/ContentGenerator/Instructor/SetMaker.pm
index 59bdf70598..92a4c5cc3e 100644
--- a/lib/WeBWorK/ContentGenerator/Instructor/SetMaker.pm
+++ b/lib/WeBWorK/ContentGenerator/Instructor/SetMaker.pm
@@ -56,13 +56,14 @@ use constant ALL_SECTIONS => 'All Sections';
use constant ALL_TEXTBOOKS => 'All Textbooks';
use constant LIB2_DATA => {
- 'dbchapter' => {name => 'library_chapters', all => 'All Chapters'},
+ 'dbLibrary' => {name => 'library_name', all => 'All Libraries'},
+ 'dbchapter' => {name => 'library_chapters', all => 'All Chapters'},
'dbsection' => {name => 'library_sections', all =>'All Sections' },
'dbsubject' => {name => 'library_subjects', all => 'All Subjects' },
- 'textbook' => {name => 'library_textbook', all => 'All Textbooks'},
- 'textchapter' => {name => 'library_textchapter', all => 'All Chapters'},
- 'textsection' => {name => 'library_textsection', all => 'All Sections'},
- 'keywords' => {name => 'library_keywords', all => '' },
+ 'textbook' => {name => 'library_textbook', all => 'All Textbooks'},
+ 'textchapter'=> {name => 'library_textchapter', all => 'All Chapters'},
+ 'textsection'=> {name => 'library_textsection', all => 'All Sections'},
+ 'keywords' => {name => 'library_keywords', all => '' },
};
## Flags for operations on files
@@ -122,6 +123,9 @@ sub get_library_sets {
my @pgdirs;
my @dirs = grep {!$ignoredir{$_} and -d "$dir/$_"} @lis;
if ($top == 1) {@dirs = grep {!$problib{$_}} @dirs}
+
+ # FIXME - "Library" is hardwired
+
# Never include Library at the top level
if ($top == 1) {@dirs = grep {$_ ne 'Library'} @dirs}
foreach my $subdir (@dirs) {
@@ -205,6 +209,8 @@ sub getDBextras {
my $r = shift;
my $sourceFileName = shift;
+ # FIXME - "Library" is hardwired
+
if($sourceFileName =~ /^Library/) {
return @{WeBWorK::Utils::ListingDB::getDBextras($r, $sourceFileName)};
}
@@ -472,21 +478,33 @@ sub browse_library_panel {
my $r = $self->r;
my $ce = $r->ce;
- # See if the problem library is installed
- my $libraryRoot = $r->{ce}->{problemLibrary}->{root};
+ # See if the problem library is installed - we check for OPL
+ my $libraryRoot = $r->{ce}->{problemLibrary}->{OPL}->{root};
+
+ my $linkName = $r->{ce}->{problemLibrary}->{OPL}->{linkname};
+
+ # # Debug code below displays the hash data in the HTML output
+ #my $pl1 = $r->{ce}->{problemLibrary};
+ #my $opl1 = $pl1->{OPL};
+ #print CGI::Tr(CGI::td(CGI::div({class=>'ResultsWithError', align=>"center"},
+ # "libraryRoot setting is $libraryRoot and pl1 keys: "
+ # . join(" ",keys( %$pl1))
+ # . "
opl1 keys: "
+ # . join(" ",keys( %$opl1))
+ # )));
unless($libraryRoot) {
print CGI::Tr(CGI::td(CGI::div({class=>'ResultsWithError', align=>"center"},
- "The problem library has not been installed.")));
+ "The OPL problem library has not been installed.")));
return;
}
# Test if the Library directory link exists. If not, try to make it
- unless(-d "$ce->{courseDirs}->{templates}/Library") {
- unless(symlink($libraryRoot, "$ce->{courseDirs}->{templates}/Library")) {
+ unless(-d "$ce->{courseDirs}->{templates}/${linkName}") {
+ unless(symlink($libraryRoot, "$ce->{courseDirs}->{templates}/${linkName}")) {
my $msg = <<"HERE";
-You are missing the directory templates/Library, which is needed
+You are missing the directory templates/${linkName}, which is needed
for the Problem Library to function. It should be a link pointing to
-$libraryRoot, which you set in conf/site.conf.
+$libraryRoot, which you set in conf/localOverrides.conf.
I tried to make the link for you, but that failed. Check the permissions
in your templates directory.
HERE
@@ -495,7 +513,7 @@ HERE
}
# Now check what version we are supposed to use
- my $libraryVersion = $r->{ce}->{problemLibrary}->{version} || 1;
+ my $libraryVersion = $r->{ce}->{problemLibrary}->{OPL}->{version} || 1;
if($libraryVersion == 1) {
return $self->browse_library_panel1;
} elsif($libraryVersion >= 2) {
@@ -555,6 +573,11 @@ sub browse_library_panel2 {
my $r = $self->r;
my $ce = $r->ce;
+ my @libs = WeBWorK::Utils::ListingDB::getAllLibraries($r);
+ unshift @libs, LIB2_DATA->{dbLibrary}{all};
+
+ my %libNames = WeBWorK::Utils::ListingDB::getAllLibrariesNameHash($r);
+
my @subjs = WeBWorK::Utils::ListingDB::getAllDBsubjects($r);
unshift @subjs, LIB2_DATA->{dbsubject}{all};
@@ -565,23 +588,58 @@ sub browse_library_panel2 {
@sects = WeBWorK::Utils::ListingDB::getAllDBsections($r);
unshift @sects, LIB2_DATA->{dbsection}{all};
+ my $libName_selected = $r->param('library_name') || LIB2_DATA->{dbLibrary}{all};
my $subject_selected = $r->param('library_subjects') || LIB2_DATA->{dbsubject}{all};
my $chapter_selected = $r->param('library_chapters') || LIB2_DATA->{dbchapter}{all};
my $section_selected = $r->param('library_sections') || LIB2_DATA->{dbsection}{all};
my $view_problem_line = view_problems_line('lib_view', $r->maketext('View Problems'), $self->r);
- my $count_line = WeBWorK::Utils::ListingDB::countDBListings($r);
+ my $count_line = 0;
+ if ( $libName_selected eq LIB2_DATA->{dbLibrary}{all} ) {
+ # LOOP over all libraries
+ my $ll;
+ my $cc;
+ foreach $ll ( keys( %{$ce->{problemLibrary}} ) ) {
+ # skip "LookupTable"
+ next if ( ($ll eq "LookupTable") || ( $ll eq "" ) ) ;
+ $r->param( 'library_name' => "$ce->{problemLibrary}->{$ll}->{linkname}" );
+
+ # FIXME should check here that this library is installed for this course
+
+ $count_line += WeBWorK::Utils::ListingDB::countDBListings($r);
+ }
+ $r->param( 'library_name' => LIB2_DATA->{dbLibrary}{all} );
+ } else {
+ $count_line = WeBWorK::Utils::ListingDB::countDBListings($r);
+ }
if($count_line==0) {
- $count_line = $r->maketext("There are no matching WeBWorK problems");
+ $count_line = $r->maketext("There are no matching WeBWorK problems in [_1]", $libName_selected);
+ } elsif ( $count_line == 1 ) {
+ $count_line = $r->maketext("There is 1 matching WeBWorK problems in [_1]", $libName_selected);
} else {
- $count_line = $r->maketext("There are [_1] matching WeBWorK problems", $count_line);
+ $count_line = $r->maketext("There are [_1] matching WeBWorK problems in [_2]", $count_line, $libName_selected);
}
print CGI::Tr({},
CGI::td({-class=>"InfoPanel", -align=>"left"},
CGI::hidden(-name=>"library_is_basic", -default=>1,-override=>1),
CGI::start_table({-width=>"100%"}),
+
+ CGI::Tr({},
+ CGI::td([$r->maketext("Library:"),
+ CGI::popup_menu(-name=> 'library_name',
+ -values=>\@libs,
+ -labels=>\%libNames,
+ -default=> $libName_selected,
+ -onchange=>"lib_update('count', 'clear');return true"
+ )]),
+ CGI::td({-colspan=>2, -align=>"left"},
+ CGI::button(-name=>"change_library", -value=>$r->maketext("Get subjects in this library"),
+ -onclick=>"lib_update('subjects', 'get');return true"
+ ))
+ ),
+
CGI::Tr({},
CGI::td([$r->maketext("Subject:"),
CGI::popup_menu(-name=> 'library_subjects',
@@ -609,6 +667,10 @@ sub browse_library_panel2 {
-default=> $section_selected,
-onchange=>"lib_update('count', 'clear');return true"
)]),
+ #CGI::td({-colspan=>2, -align=>"left"},
+ # CGI::button(-name=>"rerun_search", -value=>$r->maketext("Run search again"), # Not needed
+ # -onclick=>"lib_update('count', 'clear');return true"
+ # ))
),
CGI::Tr(CGI::td({-colspan=>3}, $view_problem_line)),
CGI::Tr(CGI::td({-colspan=>3, -align=>"center", -id=>"library_count_line"}, $count_line)),
@@ -623,6 +685,14 @@ sub browse_library_panel2adv {
my $ce = $r->ce;
my $right_button_style = "width: 18ex";
+ my @libs = WeBWorK::Utils::ListingDB::getAllLibraries($r);
+ if(! grep { $_ eq $r->param('library_name') } @libs) {
+ $r->param('library_name', 'Library'); # Fall back value FIXME
+ }
+ unshift @libs, LIB2_DATA->{dbLibrary}{all};
+
+ my %libNames = WeBWorK::Utils::ListingDB::getAllLibrariesNameHash($r);
+
my @subjs = WeBWorK::Utils::ListingDB::getAllDBsubjects($r);
if(! grep { $_ eq $r->param('library_subjects') } @subjs) {
$r->param('library_subjects', '');
@@ -668,7 +738,7 @@ sub browse_library_panel2adv {
unshift @textsecs, LIB2_DATA->{textsection}{all};
my %selected = ();
- for my $j (qw( dbsection dbchapter dbsubject textbook textchapter textsection )) {
+ for my $j (qw( dbLibrary dbsection dbchapter dbsubject textbook textchapter textsection )) {
$selected{$j} = $r->param(LIB2_DATA->{$j}{name}) || LIB2_DATA->{$j}{all};
}
@@ -683,11 +753,31 @@ sub browse_library_panel2adv {
my $view_problem_line = view_problems_line('lib_view', $r->maketext('View Problems'), $self->r);
- my $count_line = WeBWorK::Utils::ListingDB::countDBListings($r);
+ my $libName_selected = $r->param('library_name') || LIB2_DATA->{dbLibrary}{all};
+
+ my $count_line = 0;
+ if ( $libName_selected eq LIB2_DATA->{dbLibrary}{all} ) {
+ # LOOP over all libraries
+ my $ll;
+ foreach $ll ( keys( %{$ce->{problemLibrary}} ) ) {
+ # skip "LookupTable"
+ next if ( ($ll eq "LookupTable") || ( $ll eq "" ) ) ;
+ $r->param( 'library_name' => "$ce->{problemLibrary}->{$ll}->{linkname}" );
+
+ # FIXME should check here that this library is installed for this course
+
+ $count_line += WeBWorK::Utils::ListingDB::countDBListings($r);
+ }
+ $r->param( 'library_name' => LIB2_DATA->{dbLibrary}{all} );
+ } else {
+ $count_line = WeBWorK::Utils::ListingDB::countDBListings($r);
+ }
if($count_line==0) {
- $count_line = "There are no matching WeBWorK problems";
+ $count_line = $r->maketext("There are no matching WeBWorK problems in [_1]", $libName_selected);
+ } elsif ( $count_line == 1 ) {
+ $count_line = $r->maketext("There is 1 matching WeBWorK problems in [_1]", $libName_selected);
} else {
- $count_line = "There are $count_line matching WeBWorK problems";
+ $count_line = $r->maketext("There are [_1] matching WeBWorK problems in [_2]", $count_line, $libName_selected);
}
# Formatting level checkboxes by hand
@@ -713,6 +803,21 @@ sub browse_library_panel2adv {
CGI::start_table({-width=>"100%"}),
# Html done by hand since it is temporary
CGI::Tr(CGI::td({-colspan=>4, -align=>"center"}, $r->maketext('All Selected Constraints Joined by "And"'))),
+
+ CGI::Tr({},
+ CGI::td([$r->maketext("Library:"),
+ CGI::popup_menu(-name=> 'library_name',
+ -values=>\@libs,
+ -labels=>\%libNames,
+ -default=> $selected{dbLibrary},
+ -onchange=>"lib_update('count', 'clear');return true"
+ )]),
+ CGI::td({-colspan=>2, -align=>"left"},
+ CGI::button(-name=>"change_library", -value=>$r->maketext("Get subjects in this library"), # Not needed
+ -onclick=>"lib_update('subjects', 'get');return true"
+ ))
+ ),
+
CGI::Tr({},
CGI::td([$r->maketext("Subject:"),
CGI::popup_menu(-name=> 'library_subjects',
@@ -755,6 +860,10 @@ sub browse_library_panel2adv {
-default=> $selected{textchapter},
-onchange=>"submit();return true"
)]),
+ #CGI::td({-colspan=>2, -align=>"left"},
+ # CGI::button(-name=>"rerun_search", -value=>$r->maketext("Run search again"), # Not needed
+ # -onclick=>"lib_update('count', 'clear');return true"
+ # ))
),
CGI::Tr({},
CGI::td([$r->maketext("Text section:"),
@@ -883,7 +992,7 @@ sub make_top_row {
print CGI::Tr(CGI::td({-class=>"InfoPanel", -align=>"center"},
$r->maketext("Browse").' ',
- CGI::submit(-name=>"browse_npl_library", -value=>$r->maketext("Open Problem Library"), -style=>$these_widths, @dis1),
+ CGI::submit(-name=>"browse_npl_library", -value=>$r->maketext("Searchable Libraries"), -style=>$these_widths, @dis1),
CGI::submit(-name=>"browse_local", -value=>$r->maketext("Local Problems"), -style=>$these_widths, @dis2),
CGI::submit(-name=>"browse_mysets", -value=>$r->maketext("From This Course"), -style=>$these_widths, @dis3),
CGI::submit(-name=>"browse_setdefs", -value=>$r->maketext("Set Definition Files"), -style=>$these_widths, @dis4),
@@ -959,8 +1068,10 @@ sub make_data_row {
my $self = shift;
my $r = $self->r;
my $ce = $r->{ce};
+
my $sourceFileData = shift;
my $sourceFileName = $sourceFileData->{filepath};
+ my $libCode = $sourceFileData->{libCode};
my $pg = shift;
my $isstatic = $sourceFileData->{static};
my $isMO = $sourceFileData->{MO};
@@ -1069,7 +1180,9 @@ sub make_data_row {
# get statistics to display
my $global_problem_stats = '';
- if ($ce->{problemLibrary}{showLibraryGlobalStats}) {
+
+ # use $libCode below
+ if ($ce->{problemLibrary}{$libCode}{showLibraryGlobalStats}) {
my $stats = $self->{library_stats_handler}->getGlobalStats($sourceFileName);
if ($stats->{students_attempted}) {
$global_problem_stats = $self->helpMacro("Global_Usage_Data",$r->maketext('GLOBAL Usage')).': '.
@@ -1083,7 +1196,9 @@ sub make_data_row {
my $local_problem_stats = '';
- if ($ce->{problemLibrary}{showLibraryLocalStats}) {
+
+ # use $libCode below
+ if ($ce->{problemLibrary}{$libCode}{showLibraryLocalStats}) {
my $stats = $self->{library_stats_handler}->getLocalStats($sourceFileName);
if ($stats->{students_attempted}) {
$local_problem_stats = $self->helpMacro("Local_Usage_Data",$r->maketext('LOCAL Usage')).': '.
@@ -1147,8 +1262,21 @@ sub process_search {
# Build a hash of MLT entries keyed by morelt_id
my %mlt = ();
my $mltind;
+
+ # Find library (directory) name and then lookup the code name
+ my $reqLib = $r->param('library_name');
+ my $libCode;
+ my $libSymLink;
+ if ( exists( $r->ce->{problemLibrary}->{LookupTable}->{$reqLib} ) ) {
+ $libCode = $r->ce->{problemLibrary}->{LookupTable}->{$reqLib};
+ $libSymLink = $r->ce->{problemLibrary}->{$libCode}->{linkname};
+ } else {
+ # Fall back to old default
+ $libSymLink = "Library";
+ }
+
for my $indx (0..$#dbsearch) {
- $dbsearch[$indx]->{filepath} = "Library/".$dbsearch[$indx]->{path}."/".$dbsearch[$indx]->{filename};
+ $dbsearch[$indx]->{filepath} = "${libSymLink}/".$dbsearch[$indx]->{path}."/".$dbsearch[$indx]->{filename};
# For debugging
$dbsearch[$indx]->{oindex} = $indx;
if($mltind = $dbsearch[$indx]->{morelt}) {
@@ -1407,10 +1535,41 @@ sub pre_header_initialize {
##### View from the library database
} elsif ($r->param('lib_view')) {
-
+
@pg_files=();
- my @dbsearch = WeBWorK::Utils::ListingDB::getSectionListings($r);
- @pg_files = process_search($r, @dbsearch);
+ my @dbsearch;
+
+ # When "All Libraries" is selected, the value of $r->param('library_name')
+ # is an empty string...
+
+ if ( ( $r->param('library_name') eq "" ) ||
+ ( $r->param('library_name') eq LIB2_DATA->{dbLibrary}{all} ) ) {
+ # search all libraries
+ my @libs = WeBWorK::Utils::ListingDB::getAllLibraries($r);
+
+ # FIXME should check here which libraries are installed for this course
+
+ my $cl;
+ my @tmp1;
+ my $tmpRec;
+
+ foreach $cl ( @libs ) {
+ $r->param( 'library_name' => "$cl" );
+
+ @dbsearch = WeBWorK::Utils::ListingDB::getSectionListings($r);
+ @tmp1 = process_search($r, @dbsearch);
+ #foreach $tmpRec ( @tmp1 ) {
+ # push( @pg_files, $tmpRec );
+ #}
+ push( @pg_files, @tmp1 );
+
+ }
+ $r->param( 'library_name' => LIB2_DATA->{dbLibrary}{all} ); # Set it back
+ } else {
+ # regular, single library search
+ @dbsearch = WeBWorK::Utils::ListingDB::getSectionListings($r);
+ @pg_files = process_search($r, @dbsearch);
+ }
$use_previous_problems=0;
##### View a set from a set*.def
@@ -1585,8 +1744,9 @@ sub pre_header_initialize {
my $library_stats_handler = '';
- if ($ce->{problemLibrary}{showLibraryGlobalStats} ||
- $ce->{problemLibrary}{showLibraryLocalStats} ) {
+# FIXME NSW - need correct library code
+ if ($ce->{problemLibrary}{OPL}{showLibraryGlobalStats} ||
+ $ce->{problemLibrary}{OPL}{showLibraryLocalStats} ) {
$library_stats_handler = WeBWorK::Utils::LibraryStats->new($ce);
}
@@ -1760,14 +1920,20 @@ sub output_JS {
if ($self->r->authz->hasPermissions(scalar($self->r->param('user')), "modify_tags")) {
my $site_url = $ce->{webworkURLs}->{htdocs};
print qq!!;
- if (open(TAXONOMY, $ce->{webworkDirs}{root}.'/htdocs/DATA/tagging-taxonomy.json') ) {
+
+
+ # Determine the proper taxonomy file to use
+ my $tagging_from = "OPL"; # FIXME, should come from settings
+ my $taxofile = $ce->{problemLibrary}->{$tagging_from}->{taxo};
+
+ if (open(TAXONOMY, $ce->{webworkDirs}{root}.'/htdocs/DATA/${taxofile}') ) {
my $taxo = '[]';
$taxo = join("", );
close TAXONOMY;
print qq!\n!;
} else {
print qq!\n!;
- print qq!\n!;
+ print qq!\n!;
}
}
return '';
diff --git a/lib/WeBWorK/ContentGenerator/Instructor/SetMaker2.pm b/lib/WeBWorK/ContentGenerator/Instructor/SetMaker2.pm
index dbe7169fdc..92a5e8c755 100644
--- a/lib/WeBWorK/ContentGenerator/Instructor/SetMaker2.pm
+++ b/lib/WeBWorK/ContentGenerator/Instructor/SetMaker2.pm
@@ -539,11 +539,12 @@ sub browse_library_panel {
my $ce = $r->ce;
# See if the problem library is installed
- my $libraryRoot = $r->{ce}->{problemLibrary}->{root};
+ # FIXME NSW
+ my $libraryRoot = $r->{ce}->{problemLibrary}->{OPL}->{root};
unless($libraryRoot) {
print CGI::div({class=>'ResultsWithError', align=>"center"},
- "The problem library has not been installed.");
+ "The OPL problem library has not been installed.");
return;
}
# Test if the Library directory link exists. If not, try to make it
@@ -551,8 +552,8 @@ sub browse_library_panel {
unless(symlink($libraryRoot, "$ce->{courseDirs}->{templates}/Library")) {
my $msg = <<"HERE";
You are missing the directory templates/Library, which is needed
-for the Problem Library to function. It should be a link pointing to
-$libraryRoot, which you set in conf/site.conf.
+for the Open Problem Library to function. It should be a link pointing to
+$libraryRoot, which you set in conf/localOverrides.conf.
I tried to make the link for you, but that failed. Check the permissions
in your templates directory.
HERE
@@ -561,7 +562,7 @@ HERE
}
# Now check what version we are supposed to use
- my $libraryVersion = $r->{ce}->{problemLibrary}->{version} || 1;
+ my $libraryVersion = $r->{ce}->{problemLibrary}->{OPL}->{version} || 1;
if($libraryVersion == 1) {
return $self->browse_library_panel1;
} elsif($libraryVersion >= 2) {
diff --git a/lib/WeBWorK/ContentGenerator/Instructor/SetMakernojs.pm b/lib/WeBWorK/ContentGenerator/Instructor/SetMakernojs.pm
index 6aef538306..692db0f57c 100644
--- a/lib/WeBWorK/ContentGenerator/Instructor/SetMakernojs.pm
+++ b/lib/WeBWorK/ContentGenerator/Instructor/SetMakernojs.pm
@@ -32,34 +32,36 @@ use warnings;
use WeBWorK::CGI;
use WeBWorK::Debug;
use WeBWorK::Form;
-use WeBWorK::Utils qw(readDirectory max sortByName);
+use WeBWorK::Utils qw(readDirectory max sortByName wwRound x);
use WeBWorK::Utils::Tasks qw(renderProblems);
use File::Find;
require WeBWorK::Utils::ListingDB;
+# we use x to mark strings for maketext
use constant SHOW_HINTS_DEFAULT => 0;
use constant SHOW_SOLUTIONS_DEFAULT => 0;
use constant MAX_SHOW_DEFAULT => 20;
-use constant NO_LOCAL_SET_STRING => 'No sets in this course yet';
-use constant SELECT_SET_STRING => 'Select a Set from this Course';
-use constant SELECT_LOCAL_STRING => 'Select a Problem Collection';
-use constant MY_PROBLEMS => ' My Problems ';
-use constant MAIN_PROBLEMS => ' Unclassified Problems ';
-use constant CREATE_SET_BUTTON => 'Create New Set';
+use constant NO_LOCAL_SET_STRING => x('No sets in this course yet');
+use constant SELECT_SET_STRING => x('Select a Set from this Course');
+use constant SELECT_LOCAL_STRING => x('Select a Problem Collection');
+use constant MY_PROBLEMS => x('My Problems');
+use constant MAIN_PROBLEMS => x('Unclassified Problems');
+use constant CREATE_SET_BUTTON => x('Create New Set');
use constant ALL_CHAPTERS => 'All Chapters';
use constant ALL_SUBJECTS => 'All Subjects';
use constant ALL_SECTIONS => 'All Sections';
use constant ALL_TEXTBOOKS => 'All Textbooks';
use constant LIB2_DATA => {
- 'dbchapter' => {name => 'library_chapters', all => 'All Chapters'},
+ 'dbLibrary' => {name => 'library_name', all => 'All Libraries'},
+ 'dbchapter' => {name => 'library_chapters', all => 'All Chapters'},
'dbsection' => {name => 'library_sections', all =>'All Sections' },
'dbsubject' => {name => 'library_subjects', all => 'All Subjects' },
- 'textbook' => {name => 'library_textbook', all => 'All Textbooks'},
- 'textchapter' => {name => 'library_textchapter', all => 'All Chapters'},
- 'textsection' => {name => 'library_textsection', all => 'All Sections'},
- 'keywords' => {name => 'library_keywords', all => '' },
+ 'textbook' => {name => 'library_textbook', all => 'All Textbooks'},
+ 'textchapter'=> {name => 'library_textchapter', all => 'All Chapters'},
+ 'textsection'=> {name => 'library_textsection', all => 'All Sections'},
+ 'keywords' => {name => 'library_keywords', all => '' },
};
## Flags for operations on files
@@ -407,11 +409,11 @@ sub browse_library_panel {
my $ce = $r->ce;
# See if the problem library is installed
- my $libraryRoot = $r->{ce}->{problemLibrary}->{root};
+ my $libraryRoot = $r->{ce}->{problemLibrary}->{OPL}->{root};
unless($libraryRoot) {
print CGI::Tr(CGI::td(CGI::div({class=>'ResultsWithError', align=>"center"},
- "The problem library has not been installed.")));
+ "The OPL problem library has not been installed.")));
return;
}
# Test if the Library directory link exists. If not, try to make it
@@ -419,8 +421,8 @@ sub browse_library_panel {
unless(symlink($libraryRoot, "$ce->{courseDirs}->{templates}/Library")) {
my $msg = <<"HERE";
You are missing the directory templates/Library, which is needed
-for the Problem Library to function. It should be a link pointing to
-$libraryRoot, which you set in conf/site.conf.
+for the Open Problem Library to function. It should be a link pointing to
+$libraryRoot, which you set in conf/localOverrides.conf.
I tried to make the link for you, but that failed. Check the permissions
in your templates directory.
HERE
@@ -429,7 +431,7 @@ HERE
}
# Now check what version we are supposed to use
- my $libraryVersion = $r->{ce}->{problemLibrary}->{version} || 1;
+ my $libraryVersion = $r->{ce}->{problemLibrary}->{OPL}->{version} || 1;
if($libraryVersion == 1) {
return $self->browse_library_panel1;
} elsif($libraryVersion >= 2) {
diff --git a/lib/WeBWorK/ContentGenerator/Problem.pm b/lib/WeBWorK/ContentGenerator/Problem.pm
index 5b90b14a62..c94ac53842 100644
--- a/lib/WeBWorK/ContentGenerator/Problem.pm
+++ b/lib/WeBWorK/ContentGenerator/Problem.pm
@@ -2183,14 +2183,18 @@ sub output_JS{
# This is for tagging menus (if allowed)
if ($r->authz->hasPermissions($r->param('user'), "modify_tags")) {
- if (open(TAXONOMY, $ce->{webworkDirs}{root}.'/htdocs/DATA/tagging-taxonomy.json') ) {
+ # Determine the proper taxonomy file to use
+ my $tagging_from = "OPL"; # FIXME, should come from settings
+ my $taxofile = $ce->{problemLibrary}->{$tagging_from}->{taxo};
+
+ if (open(TAXONOMY, $ce->{webworkDirs}{root}.'/htdocs/DATA/${taxofile}') ) {
my $taxo = '[]';
$taxo = join("", );
close TAXONOMY;
print qq!\n!;
} else {
print qq!\n!;
- print qq!\n!;
+ print qq!\n!;
}
print CGI::start_script({type=>"text/javascript", src=>"$site_url/js/apps/TagWidget/tagwidget.js"}), CGI::end_script();
}
diff --git a/lib/WeBWorK/Utils/LibraryStats.pm b/lib/WeBWorK/Utils/LibraryStats.pm
index 7ef55e239a..db75fd0ca6 100644
--- a/lib/WeBWorK/Utils/LibraryStats.pm
+++ b/lib/WeBWorK/Utils/LibraryStats.pm
@@ -66,7 +66,12 @@ sub getLocalStats {
unless ($selectstm->execute($source_file)) {
if ($selectstm->errstr =~ /Table .* doesn't exist/) {
- warn "Couldn't find the OPL local statistics table. Did you download the latest OPL and run update-OPL-statistics?"
+ warn "Couldn't find the OPL local statistics table. Did you download the latest OPL and run update-OPL-statistics?";
+
+ # NSW hack - to avoid crash when no statistics
+ return {source_file => $source_file};
+ # END NSW hack
+
}
die $selectstm->errstr;
}
@@ -92,7 +97,12 @@ sub getGlobalStats {
unless ($selectstm->execute($source_file)) {
if ($selectstm->errstr =~ /Table .* doesn't exist/) {
- warn "Couldn't find the OPL global statistics table. Did you download the latest OPL and run update-OPL-statistics?"
+ warn "Couldn't find the OPL global statistics table. Did you download the latest OPL and run update-OPL-statistics?";
+
+ # NSW hack - to avoid crash when no statistics
+ return {source_file => $source_file};
+ # END NSW hack
+
}
die $selectstm->errstr;
}
diff --git a/lib/WeBWorK/Utils/ListingDB.pm b/lib/WeBWorK/Utils/ListingDB.pm
index 987c1e9d9b..9e0edcf473 100644
--- a/lib/WeBWorK/Utils/ListingDB.pm
+++ b/lib/WeBWorK/Utils/ListingDB.pm
@@ -44,7 +44,8 @@ BEGIN
&createListing &updateListing &deleteListing &getAllChapters
&getAllSections &searchListings &getAllListings &getSectionListings
&getAllDBsubjects &getAllDBchapters &getAllDBsections &getDBTextbooks
- &getDBListings &countDBListings &getTables &getDBextras
+ &getDBListings &countDBListings &getTables &getDBextras &getAllLibraries
+ &getAllLibrariesNameHash
);
%EXPORT_TAGS =();
@EXPORT_OK =qw();
@@ -66,6 +67,9 @@ my %OPLtables = (
problem => 'OPL_problem',
morelt => 'OPL_morelt',
pgfile_problem => 'OPL_pgfile_problem',
+ cnt_dbsubject => 'Cnt_DBsubject',
+ cnt_dbchapter => 'Cnt_DBchapter',
+ cnt_dbsection => 'Cnt_DBsection',
);
@@ -84,19 +88,40 @@ my %NPLtables = (
problem => 'NPL-problem',
morelt => 'NPL-morelt',
pgfile_problem => 'NPL-pgfile-problem',
+ cnt_dbsubject => 'Cnt_DBsubject',
+ cnt_dbchapter => 'Cnt_DBchapter',
+ cnt_dbsection => 'Cnt_DBsection',
);
sub getTables {
my $ce = shift;
- my $libraryRoot = $ce->{problemLibrary}->{root};
+ my $myLib = shift; # Library code name (as used in top level of %problemLibrary)
+
my %tables;
- if($ce->{problemLibrary}->{version} == 2.5) {
- %tables = %OPLtables;
- } else {
+ if( $ce->{problemLibrary}->{$myLib}->{version} eq "2" ) {
%tables = %NPLtables;
- }
+ } else {
+ %tables = %OPLtables;
+ }
+
+ # Modify table names for per-library tables
+ my @special_tables = qw( pgfile pgfile_keyword pgfile_problem );
+ my $tmp1; my $tblName;
+ foreach $tmp1 ( @special_tables ) {
+ next if ( $myLib eq "" ); # Skip this
+ $tblName = $tables{$tmp1};
+ #print "old table name $tblName\n";
+ if ( $ce->{problemLibrary}->{$myLib}->{version} eq "2" ) {
+ $tblName =~ s/NPL/${myLib}/;
+ } else {
+ $tblName =~ s/OPL/${myLib}/;
+ }
+ #print "new table name $tblName\n";
+ $tables{$tmp1} = $tblName;
+ }
+
return %tables;
}
@@ -200,12 +225,26 @@ Out put is an array reference: [MO, static]
sub getDBextras {
my $r = shift;
+
+ # Find library (directory) name and then lookup the code name
+ my $reqLib = $r->param('library_name');
+ my $libCode = $r->{ce}->{problemLibrary}->{LookupTable}->{$reqLib};
+
my $path = shift;
- my %tables = getTables($r->ce);
+
+ # Now depends on the $libCode
+ my %tables = getTables($r->ce, $libCode);
+
my $dbh = getDB($r->ce);
my ($mo, $static)=(0,0);
- $path =~ s|^Library/||;
+ # The old code assumed that the path header is "Library/" which
+ # is correct for the main OPL, but not for other libraries.
+ # OLD:
+ # $path =~ s|^Library/||;
+ # NEW:
+ $path =~ s|^${reqLib}/||;
+
my $filename = basename $path;
$path = dirname $path;
my $query = "SELECT pgfile.MO, pgfile.static FROM `$tables{pgfile}` pgfile, `$tables{path}` p WHERE p.path=\"$path\" AND pgfile.path_id=p.path_id AND pgfile.filename=\"$filename\"";
@@ -233,15 +272,23 @@ consistent with the DB subject, chapter, section selected.
sub getDBTextbooks {
my $r = shift;
+
+ # Find library (directory) name and then lookup the code name
+ my $reqLib = $r->param('library_name');
+ my $libCode = $r->{ce}->{problemLibrary}->{LookupTable}->{$reqLib};
+
my $thing = shift || 'textbook';
my $dbh = getDB($r->ce);
- my %tables = getTables($r->ce);
+
+ # Now depends on the $libCode
+ my %tables = getTables($r->ce, $libCode);
+
my $extrawhere = '';
# Handle DB* restrictions
my @search_params=();
my $subj = $r->param('library_subjects') || "";
my $chap = $r->param('library_chapters') || "";
- my $sec = $r->param('library_sections') || "";
+ my $sec = $r->param('library_sections') || "";
if($subj) {
$subj =~ s/'/\\'/g;
$extrawhere .= " AND t.name = ?\n";
@@ -327,6 +374,58 @@ sub getDBTextbooks {
}
}
+=item getAllLibraries($r)
+Returns an array of Library names
+
+$r is the Apache request object
+
+=cut
+
+sub getAllLibraries {
+ my $r = shift;
+
+ my $libLookupTable = $r->{ce}->{problemLibrary}->{LookupTable};
+
+ # The keys are the names used for the symbolic links to the library
+ # the value for a key is the
+
+ my @results = keys( %$libLookupTable );
+
+ # Fixme - reorder ???
+ # Fixme - want a "human" name rather than symbolic link name
+
+ return @results;
+}
+
+=item getAllLibrariesNameHash($r)
+Returns an hash of Library code names to long names
+
+$r is the Apache request object
+
+=cut
+
+sub getAllLibrariesNameHash {
+ my $r = shift;
+
+ my $libLookupTable = $r->{ce}->{problemLibrary}->{LookupTable};
+
+ # The keys are the names used for the symbolic links to the library
+ # the value for a key is the
+
+ my %result;
+
+ my $k;
+ my $code;
+ foreach $k ( keys( %$libLookupTable ) ) {
+ $code = $r->{ce}->{problemLibrary}->{LookupTable}->{$k};
+ $result{$k} = $r->{ce}->{problemLibrary}->{$code}->{name};
+ }
+
+ $result{"All Libraries"} = "All Libraries";
+
+ return %result;
+}
+
=item getAllDBsubjects($r)
Returns an array of DBsubject names
@@ -336,7 +435,14 @@ $r is the Apache request object
sub getAllDBsubjects {
my $r = shift;
- my %tables = getTables($r->ce);
+
+ # Find library (directory) name and then lookup the code name
+ my $reqLib = $r->param('library_name');
+ my $libCode = $r->{ce}->{problemLibrary}->{LookupTable}->{$reqLib};
+
+ # Now depends on the $libCode
+ my %tables = getTables($r->ce, $libCode);
+
my @results=();
my @row;
my $query = "SELECT DISTINCT name, DBsubject_id FROM `$tables{dbsubject}` ORDER BY DBsubject_id";
@@ -347,8 +453,37 @@ sub getAllDBsubjects {
while (@row = $sth->fetchrow_array()) {
push @results, $row[0];
}
- # @results = sortByName(undef, @results);
- return @results;
+
+ # When no current library is set, or "All Libraries" was set and
+ # changed to an empty string - list ALL subjects from ALL libraries.
+ if ( !defined($reqLib) || ( $reqLib eq "" ) ) {
+ #@results = sortByName(undef, @results);
+ return @results;
+ }
+
+ # Get count of problems to determine if the subject should be listed.
+ my $tmp1;
+ my $savedCount;
+ my @nonEmptyResults; # Results which are not empty
+
+ foreach $tmp1 ( @results ) {
+
+ # Set the "param"eter - needs special code when this is a WebworkXMLRPC object
+ my $toSet = 'library_subjects';
+ if ( ref($r) eq "WebworkXMLRPC" ) {
+ $r->setParam($toSet, $tmp1);
+ } else {
+ $r->param($toSet => "$tmp1");
+ }
+
+ $savedCount = countDBListings( $r );
+ #warn "In getAllDBsubjects $tmp1 savedCount = $savedCount";
+ push( @nonEmptyResults, $tmp1) if ( $savedCount > 0 );
+ }
+
+ #@results = sortByName(undef, @results);
+ #return @results;
+ return @nonEmptyResults;
}
@@ -361,7 +496,14 @@ $r is the Apache request object
sub getAllDBchapters {
my $r = shift;
- my %tables = getTables($r->ce);
+
+ # Find library (directory) name and then lookup the code name
+ my $reqLib = $r->param('library_name');
+ my $libCode = $r->{ce}->{problemLibrary}->{LookupTable}->{$reqLib};
+
+ # Now depends on the $libCode
+ my %tables = getTables($r->ce, $libCode);
+
my $subject = $r->param('library_subjects');
return () unless($subject);
my $dbh = getDB($r->ce);
@@ -379,8 +521,36 @@ sub getAllDBchapters {
my $all_chaps_ref = $dbh->selectall_arrayref($query, {},$subject);
my @results = map { $_->[0] } @{$all_chaps_ref};
+
+ # When no current library is set, or "All Libraries" was set and
+ # changed to an empty string - list ALL chapters from ALL libraries.
+ if ( !defined($reqLib) || ( $reqLib eq "" ) ) {
+ #@results = sortByName(undef, @results);
+ return @results;
+ }
+
+ # Get count of problems to determine if the chapter should be listed.
+ my $tmp1;
+ my $savedCount;
+ my @nonEmptyResults; # Results which are not empty
+ foreach $tmp1 ( @results ) {
+
+ # Set the "param"eter - needs special code when this is a WebworkXMLRPC object
+ my $toSet = 'library_chapters';
+ if ( ref($r) eq "WebworkXMLRPC" ) {
+ $r->setParam($toSet, $tmp1);
+ } else {
+ $r->param($toSet => "$tmp1");
+ }
+
+ $savedCount = countDBListings( $r );
+ #warn "In getAllDBchapters $tmp1 savedCount = $savedCount";
+ push( @nonEmptyResults, $tmp1) if ( $savedCount > 0 );
+ }
+
#@results = sortByName(undef, @results);
- return @results;
+ #return @results;
+ return @nonEmptyResults;
}
=item getAllDBsections($r)
@@ -392,7 +562,14 @@ $r is the Apache request object
sub getAllDBsections {
my $r = shift;
- my %tables = getTables($r->ce);
+
+ # Find library (directory) name and then lookup the code name
+ my $reqLib = $r->param('library_name');
+ my $libCode = $r->{ce}->{problemLibrary}->{LookupTable}->{$reqLib};
+
+ # Now depends on the $libCode
+ my %tables = getTables($r->ce, $libCode);
+
my $subject = $r->param('library_subjects');
return () unless($subject);
my $chapter = $r->param('library_chapters');
@@ -414,8 +591,35 @@ sub getAllDBsections {
my $all_sections_ref = $dbh->selectall_arrayref($query, {},$subject, $chapter);
my @results = map { $_->[0] } @{$all_sections_ref};
+
+ # When no current library is set, or "All Libraries" was set and
+ # changed to an empty string - list ALL subjects from ALL libraries.
+ if ( !defined($reqLib) || ( $reqLib eq "" ) ) {
+ #@results = sortByName(undef, @results);
+ return @results;
+ }
+
+ # Get count of problems to determine if the section should be listed.
+ my $tmp1;
+ my $savedCount;
+ my @nonEmptyResults; # Results which are not empty
+ foreach $tmp1 ( @results ) {
+ # Set the "param"eter - needs special code when this is a WebworkXMLRPC object
+ my $toSet = 'library_sections';
+ if ( ref($r) eq "WebworkXMLRPC" ) {
+ $r->setParam($toSet, $tmp1);
+ } else {
+ $r->param($toSet => "$tmp1");
+ }
+
+ $savedCount = countDBListings( $r );
+ #warn "In getAllDBsections $tmp1 savedCount = $savedCount";
+ push( @nonEmptyResults, $tmp1) if ( $savedCount > 0 );
+ }
+
#@results = sortByName(undef, @results);
- return @results;
+ #return @results;
+ return @nonEmptyResults;
}
=item getDBSectionListings($r)
@@ -433,9 +637,48 @@ Here, we search on all known fields out of r
sub getDBListings {
my $r = shift;
+
+ # Find library (directory) name and then lookup the code name
+ my $reqLib = $r->param('library_name');
+ if ( $reqLib eq "" ) {
+ # When called via instructorXMLHandler from JavaScript
+ # there can be a difference between the "param" value and the "hash" value.
+ # and we want the non-empty value
+ $reqLib = $r->{library_name};
+ }
+
+ # Need to handle case of "All Libraries" which should not get passed
+ # into this function, but would cause an error below.
+ if ( $reqLib eq "All Libraries" ) {
+ my $tmp1amcounter = shift; # 0-1 if I am a counter.
+ if ( $tmp1amcounter ) {
+ # If we got here - report 100000 results - to be seen as an unreasonable result
+ return( 100000 );
+ } else {
+ # If we got here - report empty array of results
+ my @tmp1 = (); # no results
+ return @tmp1 ;
+ }
+ }
+ if ( $reqLib eq "" ) {
+ my $tmp1amcounter = shift; # 0-1 if I am a counter.
+ if ( $tmp1amcounter ) {
+ # If we got here - report 1000000 results - to be seen as an unreasonable result
+ return( 1000000 );
+ } else {
+ # If we got here - report empty array of results
+ my @tmp1 = (); # no results
+ return @tmp1 ;
+ }
+ }
+
+ my $libCode = $r->{ce}->{problemLibrary}->{LookupTable}->{$reqLib};
+
+ # Now depends on the $libCode
+ my %tables = getTables($r->ce, $libCode);
+
my $amcounter = shift; # 0-1 if I am a counter.
my $ce = $r->ce;
- my %tables = getTables($ce);
my $subj = $r->param('library_subjects') || "";
my $chap = $r->param('library_chapters') || "";
my $sec = $r->param('library_sections') || "";
@@ -562,21 +805,282 @@ sub getDBListings {
WHERE p.path_id = pgf.path_id AND pgf.pgfile_id= ? ";
my $row = $dbh->selectrow_arrayref($query,{},$pgid);
- push @results, {'path' => $row->[0], 'filename' => $row->[1], 'morelt' => $row->[2], 'pgid'=> $row->[3], 'static' => $row->[4], 'MO' => $row->[5] };
+ push @results, {'path' => $row->[0], 'filename' => $row->[1], 'morelt' => $row->[2], 'pgid'=> $row->[3], 'static' => $row->[4], 'MO' => $row->[5], 'libCode' => "$libCode" };
}
return @results;
}
+# special return codes:
+# -200 = all libraries, do not save data
+# -100 = should not save data
+# -1 = should save count after it is found
+
+sub requestSavedCount {
+ my $r = shift;
+
+ # Find library (directory) name and then lookup the code name
+ my $reqLib = $r->param('library_name');
+ if ( $reqLib eq "" ) {
+ # When called via instructorXMLHandler from JavaScript
+ # there can be a difference between the "param" value and the "hash" value.
+ # and we want the non-empty value
+ $reqLib = $r->{library_name};
+ }
+
+ # Need to handle case of "All Libraries" which should not get passed
+ # into this function, but would cause an error below.
+ if ( ( $reqLib eq "All Libraries" ) || ( $reqLib eq "" ) ) {
+ return( -200 );
+ }
+
+ my $libCode = $r->{ce}->{problemLibrary}->{LookupTable}->{$reqLib};
+
+ # Now depends on the $libCode
+ my %tables = getTables($r->ce, $libCode);
+ my $ce = $r->ce;
+
+ my $keywords = $r->param('library_keywords') || "";
+ if($keywords) {
+ return( -100 ); # No saved counts for this case
+ }
+
+ for my $j (qw( textbook textchapter textsection )) {
+ my $foo = $r->param(LIBRARY_STRUCTURE->{$j}{name}) || '';
+ $foo =~ s/^\s*\d+\.\s*//;
+ if($foo) {
+ return( -100 ); # No saved counts for this case
+ }
+ }
+
+ # Next could be an array, an array reference, or nothing
+ my @levels = $r->param('level');
+ if(scalar(@levels) == 1 and ref($levels[0]) eq 'ARRAY') {
+ @levels = @{$levels[0]};
+ }
+ @levels = grep { defined($_) && m/\S/ } @levels;
+ if(scalar(@levels)) {
+ return( -100 ); # No saved counts for this case
+ }
+
+ my $subj = $r->param('library_subjects') || "";
+ my $chap = $r->param('library_chapters') || "";
+ my $sec = $r->param('library_sections') || "";
+
+ my $dbh = getDB($ce);
+ my $cnt_table = $tables{cnt_dbsubject};
+ my $query;
+
+ my $typewhere = '';
+ my $extrawhere = '';
+ my @select_parameters=();
+
+ if($subj) {
+ $cnt_table = $tables{cnt_dbsubject};
+ $typewhere = "AND dbsj.DBsubject_id = cnt.DBsubject_id ";
+ $extrawhere .= " AND dbsj.name= ? ";
+ push @select_parameters, $subj;
+ }
+ if($chap) {
+ $cnt_table = $tables{cnt_dbchapter};
+ $typewhere = " AND dbc.DBchapter_id = cnt.DBchapter_id ";
+ $extrawhere .= " AND dbc.name= ? ";
+ push @select_parameters, $chap;
+ }
+ if($sec) {
+ $cnt_table = $tables{cnt_dbsection};
+ $typewhere = " AND dbsc.DBsection_id = cnt.DBsection_id ";
+ $extrawhere .= " AND dbsc.name= ? ";
+ push @select_parameters, $sec;
+ }
+ push @select_parameters, $libCode;
+
+ my $query = "SELECT count from `$cnt_table` cnt,
+ `$tables{dbsection}` dbsc,
+ `$tables{dbchapter}` dbc,
+ `$tables{dbsubject}` dbsj
+ WHERE dbsj.DBsubject_id = dbc.DBsubject_id AND
+ dbc.DBchapter_id = dbsc.DBchapter_id
+ $typewhere $extrawhere AND cnt.libcode = ?";
+
+ $query =~ s/\n/ /g;
+ #warn "no text info: ", $query;
+ #warn "params: ", join(" | ",@select_parameters);
+
+ my $sth = $dbh->prepare_cached( $query );
+ if ( !defined($sth) ) {
+ warn "Couldn't prepare statement: " . $dbh->errstr;
+ return(-300);
+ }
+
+ my $rv = $sth->execute(@select_parameters);
+ if ( !defined($rv) ) {
+ warn "Couldn't execute statement: " . $sth->errstr;
+ return(-300);
+ }
+
+ if ($sth->rows == 0) {
+ #warn "No record found";
+ return(-1);
+ }
+ my @data = $sth->fetchrow_array();
+ return( $data[0] );
+}
+
+# Get the id
+sub safe_get_id {
+ my $dbh = shift;
+ my $tablename = shift;
+ my $idname = shift;
+ my $whereclause = shift;
+ my $wherevalues = shift;
+
+ my $query = "SELECT $idname FROM `$tablename` ".$whereclause;
+ my $sth = $dbh->prepare($query);
+ $sth->execute(@$wherevalues);
+ my $idvalue;
+ my @row;
+ unless(@row = $sth->fetchrow_array()) {
+ return -1;
+ }
+ $idvalue = $row[0];
+ return($idvalue);
+}
+
+
+sub saveCount {
+ my $r = shift;
+ my $countToSave = shift; # count found
+
+ # Find library (directory) name and then lookup the code name
+ my $reqLib = $r->param('library_name');
+ if ( $reqLib eq "" ) {
+ # When called via instructorXMLHandler from JavaScript
+ # there can be a difference between the "param" value and the "hash" value.
+ # and we want the non-empty value
+ $reqLib = $r->{library_name};
+ }
+
+ # Need to handle case of "All Libraries" which should not get passed
+ # into this function, but would cause an error below.
+ if ( ( $reqLib eq "All Libraries" ) || ( $reqLib eq "" ) ) {
+ return; # Do not save counts for this case
+ }
+
+ my $libCode = $r->{ce}->{problemLibrary}->{LookupTable}->{$reqLib};
+
+ # Now depends on the $libCode
+ my %tables = getTables($r->ce, $libCode);
+ my $ce = $r->ce;
+
+ my $keywords = $r->param('library_keywords') || "";
+ if($keywords) {
+ return; # Do not save counts for this case
+ }
+
+ for my $j (qw( textbook textchapter textsection )) {
+ my $foo = $r->param(LIBRARY_STRUCTURE->{$j}{name}) || '';
+ $foo =~ s/^\s*\d+\.\s*//;
+ if($foo) {
+ return; # Do not save counts for this case
+ }
+ }
+
+ # Next could be an array, an array reference, or nothing
+ my @levels = $r->param('level');
+ if(scalar(@levels) == 1 and ref($levels[0]) eq 'ARRAY') {
+ @levels = @{$levels[0]};
+ }
+ @levels = grep { defined($_) && m/\S/ } @levels;
+ if(scalar(@levels)) {
+ return; # Do not save counts for this case
+ }
+
+ my $subj = $r->param('library_subjects') || "";
+ my $chap = $r->param('library_chapters') || "";
+ my $sec = $r->param('library_sections') || "";
+
+ my $dbh = getDB($ce);
+ my $cnt_table = $tables{cnt_dbsubject};
+ my $query;
+
+ my @insert_parameters=( "$libCode" ); # Always the first parameter
+
+ my $id_to_use = -1;
+
+ my $new_dbsubj_id;
+ my $new_dbchap_id;
+ my $new_dbsect_id;
+
+ if($subj) {
+ $new_dbsubj_id = safe_get_id($dbh, $tables{dbsubject}, 'DBsubject_id',
+ qq(WHERE name = ?), ["$subj"] );
+ $id_to_use = $new_dbsubj_id;
+ $cnt_table = $tables{cnt_dbsubject};
+ }
+ if($chap) {
+ $new_dbchap_id = safe_get_id($dbh, $tables{dbchapter}, 'DBchapter_id',
+ qq(WHERE name = ? and DBsubject_id = ?), ["$chap", $new_dbsubj_id] );
+ $id_to_use = $new_dbchap_id;
+ $cnt_table = $tables{cnt_dbchapter};
+ }
+ if($sec) {
+ $new_dbsect_id = safe_get_id($dbh, $tables{dbsection}, 'DBsection_id',
+ qq(WHERE name = ? and DBchapter_id = ?), ["$sec", $new_dbchap_id] );
+ $id_to_use = $new_dbsect_id;
+ $cnt_table = $tables{cnt_dbsection};
+ }
+ push( @insert_parameters, $id_to_use, $countToSave );
+
+# my $query = "INSERT INTO `$cnt_table` VALUES (?,?,?)";
+ my $query = "REPLACE INTO `$cnt_table` VALUES (?,?,?)";
+
+ $query =~ s/\n/ /g;
+ #warn "no text info: ", $query;
+ #warn "params: ", join(" | ",@insert_parameters);
+
+ my $sth = $dbh->prepare_cached( $query );
+ if ( !defined($sth) ) {
+ warn "Couldn't prepare statement: " . $dbh->errstr;
+ return;
+ }
+
+ my $rv = $sth->execute(@insert_parameters);
+ if ( !defined($rv) ) {
+ warn "Couldn't execute statement: " . $sth->errstr;
+ return;
+ }
+}
+
sub countDBListings {
- my $r = shift;
- return (getDBListings($r,1));
+ my $r = shift;
+ my $fromSaved = -1;
+ $fromSaved = requestSavedCount($r);
+ if ( $fromSaved >= 0 ) {
+ #warn "fromSaved = $fromSaved";
+ return( $fromSaved );
+ } else {
+ #warn "fromSaved = $fromSaved";
+ my $countedNow = getDBListings($r,1);
+ #warn "countedNow = $countedNow";
+ if ( $fromSaved == -1 ) {
+ saveCount($r, $countedNow);
+ }
+ return( $countedNow );
+ }
}
sub getMLTleader {
my $r = shift;
my $mltid = shift;
- my %tables = getTables($r->ce);
+
+ # Find library (directory) name and then lookup the code name
+ my $reqLib = $r->param('library_name');
+ my $libCode = $r->{ce}->{problemLibrary}->{LookupTable}->{$reqLib};
+
+ # Now depends on the $libCode
+ my %tables = getTables($r->ce, $libCode);
+
my $dbh = getDB($r->ce);
my $query = "SELECT leader FROM `$tables{morelt}` WHERE morelt_id=\"$mltid\"";
my $row = $dbh->selectrow_arrayref($query);
@@ -787,8 +1291,17 @@ sub getMLTleader {
sub getSectionListings {
#print STDERR "ListingDB::getSectionListings(chapter,section)\n";
my $r = shift;
+
+ # Find library (directory) name and then lookup the code name
+ my $reqLib = $r->param('library_name');
+ my $libCode = $r->{ce}->{problemLibrary}->{LookupTable}->{$reqLib};
+
+ # Now depends on the $libCode
+ my %tables = getTables($r->ce, $libCode);
+
+
my $ce = $r->ce;
- my $version = $ce->{problemLibrary}->{version} || 1;
+ my $version = $ce->{problemLibrary}->{$libCode}->{version} || 1;
if($version => 2) { return(getDBListings($r, 0))}
my $subj = $r->param('library_subjects') || "";
my $chap = $r->param('library_chapters') || "";
@@ -818,7 +1331,6 @@ sub getSectionListings {
FROM classify c, pgfiles p
WHERE ? ? c.pgfiles_id = p.pgfiles_id";
my $dbh = getDB($ce);
- my %tables = getTables($ce);
my $sth = $dbh->prepare($query);
$sth->execute($chapstring,$secstring);
@@ -846,13 +1358,25 @@ sub getSectionListings {
# 1 = all ok
#
# not implemented yet
+# currently hacked up to force to "OPL" as it does not get the request object
sub deleteListing {
my $ce = shift;
my $listing_id = shift;
#print STDERR "ListingDB::deleteListing(): listing == '$listing_id'\n";
my $dbh = getDB($ce);
- my %tables = getTables($ce);
+
+# FIXME
+# # Find library (directory) name and then lookup the code name
+# my $reqLib = $r->param('library_name');
+# my $libCode = $r->{ce}->{problemLibrary}->{LookupTable}->{$reqLib};
+#
+# # Now depends on the $libCode
+# my %tables = getTables($r->ce, $libCode);
+
+# FIXME - hack to OPL
+
+ my %tables = getTables($ce, "OPL");
return undef;
}
@@ -904,6 +1428,7 @@ hash has the following format:
Written by Bill Ziemer.
Modified by John Jones.
+Modifed by Nathan Wallach to add support for multiple libraries.
=cut
diff --git a/lib/WebworkWebservice.pm b/lib/WebworkWebservice.pm
index c3e5b71e7c..2cf23add7d 100644
--- a/lib/WebworkWebservice.pm
+++ b/lib/WebworkWebservice.pm
@@ -936,11 +936,11 @@ sub updateSetting {
ce
db
- params
+ param
authz
authen
maketext
-
+ setParam - Added to add an extra param like value
=cut
sub ce {
@@ -959,6 +959,12 @@ sub param { # imitate get behavior of the request object params method
debug("use param $param => $out") if $UNIT_TESTS_ON;
$out;
}
+sub setParam { # add a new param like value
+ my $self =shift;
+ my $param = shift;
+ my $value = shift;
+ $self->{fake_r}->{$param} = $value;
+}
sub authz {
my $self = shift;
debug("use authz ") if $UNIT_TESTS_ON;
diff --git a/lib/WebworkWebservice/LibraryActions.pm b/lib/WebworkWebservice/LibraryActions.pm
index 70f5d767dc..3279274388 100644
--- a/lib/WebworkWebservice/LibraryActions.pm
+++ b/lib/WebworkWebservice/LibraryActions.pm
@@ -284,7 +284,15 @@ sub searchLib { #API for searching the NPL database
if($rh->{library_levels}) {
$self->{level} = [split(//, $rh->{library_levels})];
}
+
+ # The code which supports multiple libraries needs the problemLibrary data
+ # data to be passed on into WeBWorK::Utils::ListingDB when called via
+ # the instructorXMLHandler, so add it here:
+ $self->{ce}->{problemLibrary} = {%{$ce->{problemLibrary}} };
+
+
'getDBTextbooks' eq $subcommand && do {
+ $self->{library_name} = $rh->{library_name};
$self->{library_subjects} = $rh->{library_subjects};
$self->{library_chapters} = $rh->{library_chapters};
$self->{library_sections} = $rh->{library_sections};
@@ -293,23 +301,32 @@ sub searchLib { #API for searching the NPL database
$out->{ra_out} = \@textbooks;
return($out);
};
+ 'getAllLibraries' eq $subcommand && do {
+ my @libraries = WeBWorK::Utils::ListingDB::getAllLibraries($self);
+ $out->{ra_out} = \@libraries;
+ $out->{text} = encode_base64("Libraries loaded.");
+ return($out);
+ };
'getAllDBsubjects' eq $subcommand && do {
+ $self->{library_name} = $rh->{library_name};
my @subjects = WeBWorK::Utils::ListingDB::getAllDBsubjects($self);
$out->{ra_out} = \@subjects;
$out->{text} = encode_base64("Subjects loaded.");
return($out);
};
'getAllDBchapters' eq $subcommand && do {
+ $self->{library_name} = $rh->{library_name};
$self->{library_subjects} = $rh->{library_subjects};
my @chaps = WeBWorK::Utils::ListingDB::getAllDBchapters($self);
$out->{ra_out} = \@chaps;
- $out->{text} = encode_base64("Chapters loaded.");
+ $out->{text} = encode_base64("Chapters loaded.");
return($out);
};
'getDBListings' eq $subcommand && do {
my $templateDir = $self->ce->{courseDirs}->{templates};
+ $self->{library_name} = $rh->{library_name};
$self->{library_subjects} = $rh->{library_subjects};
$self->{library_chapters} = $rh->{library_chapters};
$self->{library_sections} = $rh->{library_sections};
@@ -318,25 +335,39 @@ sub searchLib { #API for searching the NPL database
$self->{library_textchapter} = $rh->{library_textchapter};
$self->{library_textsection} = $rh->{library_textsection};
debug(to_json($rh));
+
my @listings = WeBWorK::Utils::ListingDB::getDBListings($self);
- my @output = map {$templateDir."/Library/".$_->{path}."/".$_->{filename}} @listings;
+
+ # Find library (directory) name and then lookup the code name
+ my $reqLib = $rh->{library_name};
+ my $libCode = $ce->{problemLibrary}->{LookupTable}->{$reqLib};
+ my $linkName = $ce->{problemLibrary}->{$libCode}->{linkname}; # Name of the symbolic link
+
+ # OLD code assumed the directory name "Library" which was for the main OPL
+ #my @output = map {$templateDir."/Library/".$_->{path}."/".$_->{filename}} @listings;
#change the hard coding!!!....just saying
+
+ # NEW:
+ my @output = map {$templateDir."/${linkName}/".$_->{path}."/".$_->{filename}} @listings;
+
$out->{ra_out} = \@output;
return($out);
};
'getSectionListings' eq $subcommand && do {
+ $self->{library_name} = $rh->{library_name};
$self->{library_subjects} = $rh->{library_subjects};
$self->{library_chapters} = $rh->{library_chapters};
$self->{library_sections} = $rh->{library_sections};
my @section_listings = WeBWorK::Utils::ListingDB::getAllDBsections($self);
$out->{ra_out} = \@section_listings;
- $out->{text} = encode_base64("Sections loaded.");
+ $out->{text} = encode_base64("Sections loaded.");
return($out);
};
'countDBListings' eq $subcommand && do {
+ $self->{library_name} = $rh->{library_name};
$self->{library_subjects} = $rh->{library_subjects};
$self->{library_chapters} = $rh->{library_chapters};
$self->{library_sections} = $rh->{library_sections};
@@ -344,8 +375,33 @@ sub searchLib { #API for searching the NPL database
$self->{library_textbook} = $rh->{library_textbook};
$self->{library_textchapter} = $rh->{library_textchapter};
$self->{library_textsection} = $rh->{library_textsection};
- my $count = WeBWorK::Utils::ListingDB::countDBListings($self);
- $out->{text} = encode_base64("Count done.");
+
+ # The code which supports multiple libraries needs the problemLibrary data
+ # to be passed on
+ #$self->{ce}->{problemLibrary} = {%{$ce->{problemLibrary}} };
+
+
+ my $count = 0;
+ if ( ( $rh->{library_name} eq "All Libraries" ) ||
+ # ( !defined( $rh->{library_name} ) ) ||
+ ( $rh->{library_name} eq "" ) ) { # "All Libraries gets changes to "" by JS code
+ my $jjj = $rh->{library_name};
+ # LOOP over all libraries
+ my @libs = keys( %{$ce->{problemLibrary}} );
+ my $ll;
+ $count = "";
+ foreach $ll ( @libs ) {
+ # skip "LookupTable"
+ next if ( ( $ll eq "LookupTable" ) || ( $ll eq "" ) );
+ $self->{library_name} = "$ce->{problemLibrary}->{$ll}->{linkname}";
+
+ $count += WeBWorK::Utils::ListingDB::countDBListings($self);
+ }
+ } else {
+ $count = WeBWorK::Utils::ListingDB::countDBListings($self);
+ }
+
+ $out->{text} = encode_base64("Count done.");
$out->{ra_out} = [$count];
return($out);
};
@@ -392,6 +448,7 @@ sub getProblemDirectories {
my %libraries = %{$self->ce->{courseFiles}->{problibs}};
+ # FIXME - this is for the OPL with the fixed path
my $lib = "Library";
my $source = $ce->{courseDirs}{templates};
my $main = MY_PROBLEMS; my $isTop = 1;