From dafb86376968beaa8ac1d3f37dd1bf7b5b99ff09 Mon Sep 17 00:00:00 2001 From: Axel Amghar Date: Thu, 23 May 2019 11:48:01 +0200 Subject: [PATCH] Bug 22639: Elasticsearch ability to export mappings and facets settings With this patch you can download search fields , biblios and authorities table in search engine configuration Test plan: - apply the patch - make sure you have "elasticsearch" as value for the syspref "SearchEngine" - go to search engine configuration in the admin page - in the search fields part, you have a button "Download ... table" - download in (.csv), (.tab), (.ods) - verify that you have the same table in your file than in the search fields table - make the same test for bibliographic records and authorities - Then add some mappings and dowload, your new file has to be modified Signed-off-by: Michal Denar --- admin/searchengine/elasticsearch/mappings.pl | 166 +++++++++++++++++++++ .../admin/searchengine/elasticsearch/mappings.tt | 88 ++++++++++- 2 files changed, 249 insertions(+), 5 deletions(-) diff --git a/admin/searchengine/elasticsearch/mappings.pl b/admin/searchengine/elasticsearch/mappings.pl index f91399aa9d..86df22c909 100755 --- a/admin/searchengine/elasticsearch/mappings.pl +++ b/admin/searchengine/elasticsearch/mappings.pl @@ -21,12 +21,16 @@ use Scalar::Util qw(looks_like_number); use List::Util qw( first ); use C4::Koha; use C4::Output; +use C4::Context; use C4::Auth; +use Text::CSV::Encoded; +use C4::Reports::Guided; use Koha::SearchEngine::Elasticsearch; use Koha::SearchEngine::Elasticsearch::Indexer; use Koha::SearchMarcMaps; use Koha::SearchFields; +use Koha::Util::OpenDocument; use Try::Tiny; @@ -151,6 +155,158 @@ elsif( $op eq 'reset_confirmed' ) { elsif( $op eq 'reset_confirm' ) { $template->param( reset_confirm => 1 ); } +elsif ($op eq 'download'){ + my $format = $input->param("format"); + my $table = $input->param("table"); + my ($type, $content, $reportfilename, $csv, $ods_fh, $ods_filepath, $ods_content); + my $i = 0; + + if ($format eq "tab"){ + $type = 'application/octet-stream'; + + } elsif ($format eq "csv"){ + $type = 'application/csv'; + my $delimiter = C4::Context->preference('delimiter') || ','; + $delimiter = "\t" if ($delimiter eq 'tabulation'); + $csv = Text::CSV::Encoded->new({ encoding_out => 'UTF-8', sep_char => $delimiter}); + $csv or die "Text::CSV::Encoded->new({binary => 1}) FAILED: " . Text::CSV::Encoded->error_diag(); + + } elsif ($format eq "ods"){ + $type = 'application/vnd.oasis.opendocument.spreadsheet'; + $ods_fh = File::Temp->new( UNLINK => 0 ); + $ods_filepath = $ods_fh->filename; + } + + if ($table eq "search_fields"){ + $reportfilename = "search_fields_table"; + my @search_field_names = $input->multi_param("search_field_name"); + my @search_fileds_labels = $input->multi_param("search_field_label"); + my @search_fileds_types = $input->multi_param("search_field_type"); + my @search_field_weights = $input->multi_param("search_field_weight"); + + if ($format eq 'tab') { + my @header_row = ("Name\t\t\t","Label\t\t\t","Type","Weight"); + $content .= join("\t\t", @header_row) . "\n"; + $content = Encode::decode('UTF-8', $content); + + foreach my $search_field_name (@search_field_names){ + my @row; + $search_field_name .= ' ' while (length($search_field_name)< 25); + $search_fileds_labels[$i] .= ' ' while (length($search_fileds_labels[$i])< 25); + @row = ($search_field_name, $search_fileds_labels[$i], $search_fileds_types[$i], $search_field_weights[$i]); + $content .= join("\t\t", @row) . "\n"; + $i++; + } + } else { + my @header_row = ("Name","Label","Type","Weight"); + + if ( $format eq 'csv' ) { + if ($csv->combine(@header_row)) { + $content .= Encode::decode('UTF-8', $csv->string()) . "\n"; + foreach my $search_field_name (@search_field_names){ + my @row; + @row = ($search_field_name,$search_fileds_labels[$i],$search_fileds_types[$i],$search_field_weights[$i]); + if ($csv->combine(@row)) { + $content .= $csv->string() . "\n"; + } + $i++; + } + } + } elsif ( $format eq 'ods' ) { + my @headers = @header_row; + push @$ods_content, \@headers; + + foreach my $search_field_name (@search_field_names){ + my @content_row; + push @content_row, Encode::encode( 'UTF8', $search_field_name ), Encode::encode( 'UTF8', $search_fileds_labels[$i] ) , $search_fileds_types[$i],$search_field_weights[$i]; + push @$ods_content, \@content_row; + $i++; + } + generate_ods($ods_filepath, $ods_content); + binmode(STDOUT); + open $ods_fh, '<', $ods_filepath; + $content .= $_ while <$ods_fh>; + unlink $ods_filepath; + } + } + } else { + my (@search_field_names, @sort, @facet, @suggestible, @marc_field); + if ($table eq "biblios"){ + $reportfilename = "biblios_table"; + @search_field_names = $input->multi_param("search_field_names_biblios"); + @sort = $input->multi_param("sort_biblios"); + @facet = $input->multi_param("facet_biblios"); + @suggestible = $input->multi_param("suggestible_biblios"); + @marc_field = $input->multi_param("marc_field_biblios"); + + } elsif ($table eq "authorities"){ + $reportfilename = "authorities_table"; + @search_field_names = $input->multi_param("search_field_names_authorities"); + @sort = $input->multi_param("sort_authorities"); + @facet = $input->multi_param("facet_authorities"); + @suggestible = $input->multi_param("suggestible_authorities"); + @marc_field = $input->multi_param("marc_field_authorities"); + } + if ($format eq "tab"){ + my @header_row = ("Search field\t\t","Sortable","Facetable","Suggestible","Mapping"); + $content .= join("\t", @header_row) . "\n"; + $content = Encode::decode('UTF-8', $content); + + foreach my $search_field_name (@search_field_names){ + my @row; + $search_field_name .= ' ' while (length($search_field_name)< 20); + @row = ($search_field_name,$sort[$i],$facet[$i],$suggestible[$i],$marc_field[$i]); + $content .= join("\t\t", @row) . "\n"; + $i++; + } + } else { + my @header_row = ("Search field","Sortable","Facetable","Suggestible","Mapping "); + if ( $format eq 'csv' ) { + if ($csv->combine(@header_row)) { + $content .= Encode::decode('UTF-8', $csv->string()) . "\n"; + foreach my $search_field_name (@search_field_names){ + my @row; + @row = ($search_field_name,$sort[$i],$facet[$i],$suggestible[$i],$marc_field[$i]); + if ($csv->combine(@row)) { + $content .= $csv->string() . "\n"; + } + $i++; + } + } + } elsif ( $format eq 'ods' ) { + my @headers = @header_row; + push @$ods_content, \@headers; + + foreach my $search_field_name (@search_field_names){ + my @content_row; + push @content_row, Encode::encode( 'UTF8', $search_field_name ), $sort[$i] , $facet[$i], $suggestible[$i], Encode::encode( 'UTF8', $marc_field[$i] ); + push @$ods_content, \@content_row; + $i++; + } + generate_ods($ods_filepath, $ods_content); + binmode(STDOUT); + open $ods_fh, '<', $ods_filepath; + $content .= $_ while <$ods_fh>; + unlink $ods_filepath; + } + } + } + + if ($format eq "tab"){ + $reportfilename .= ".tab"; + } elsif ($format eq "csv"){ + $reportfilename .= ".csv"; + } elsif ($format eq "ods"){ + $reportfilename .= ".ods"; + } + + print $input->header( + -type => $type, + -attachment=> $reportfilename + ); + print $content; + exit; +} my @indexes; @@ -215,11 +371,21 @@ while ( my $search_field = $search_fields->next ) { push @all_search_fields, $search_field_unblessed; } +my @extensions = ("csv","tab","ods"); +my @formats_and_extensions =("Semicolon separated test (.csv)","Tab separated text (.tab)","Open Document Spreadsheet (.ods)"); +my @formats; +my $j = 0; +foreach my $extension (@extensions){ + push (@formats , { extension => $extension, format_and_extension =>$formats_and_extensions[$j] }); + $j++; +} + $template->param( indexes => \@indexes, all_search_fields => \@all_search_fields, facetable_fields => \@facetable_fields, messages => \@messages, + formats => \@formats, ); output_html_with_http_headers $input, $cookie, $template->output; diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/searchengine/elasticsearch/mappings.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/searchengine/elasticsearch/mappings.tt index 33df1fbd8a..8b8eaf3227 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/searchengine/elasticsearch/mappings.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/searchengine/elasticsearch/mappings.tt @@ -26,6 +26,18 @@ return new_line; } + function create_input(value, name){ + $("#save_or_reset").append('' ); + } + + function create_submit(format, table_name){ + $(".remove").remove(); + create_input("download","op"); + create_input(format,"format"); + create_input(table_name,"table"); + $("#save_or_reset").submit(); + } + $(document).ready(function() { $("#tabs").tabs(); $('.delete').click(function() { @@ -56,12 +68,40 @@ $("#facet_biblios > table").tableDnD( { onDragClass: "dragClass", } ); + + $("#edit").click(function () { + $(".remove").remove(); + create_input("edit","op"); + $("#save_or_reset").submit(); + }); + $("#reset_confirm").click(function () { + $(".remove").remove(); + create_input("reset_confirm","op"); + $("#save_or_reset").submit(); + }); + + [% FOREACH format IN formats %] + $("#link_[% format.extension | html %]").click( function () { + create_submit("[% format.extension | html %]","search_fields"); + }); + + [% FOREACH index IN indexes %] + $("#link_[% index.index_name | html %]_[% format.extension | html %]").click( function () { + create_submit("[% format.extension | html %]","[% index.index_name | html %]"); + }); + [% END %] + [% END %] }); @@ -142,7 +182,7 @@ a.add, a.delete { [% END %] -
+
+
+ + + +
+ + +

+

+ @@ -222,8 +276,31 @@ a.add, a.delete {
+ [% FOREACH index IN indexes %]
+
+ + + +
+ + +

+

+ + [% FOREACH mappings IN index.mappings %] + + + + + + [% END %] + @@ -389,12 +466,13 @@ a.add, a.delete { [% END %] -

- - -

+ +

+ + +

-- 2.11.0