Bugzilla – Attachment 31873 Details for
Bug 11876
Add a diff view to staged MARC records
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 11876 [Follow-up] Add a diff view to staged MARC Records
Bug-11876-Follow-up-Add-a-diff-view-to-staged-MARC.patch (text/plain), 16.67 KB, created by
Jonathan Druart
on 2014-09-25 12:02:17 UTC
(
hide
)
Description:
Bug 11876 [Follow-up] Add a diff view to staged MARC Records
Filename:
MIME Type:
Creator:
Jonathan Druart
Created:
2014-09-25 12:02:17 UTC
Size:
16.67 KB
patch
obsolete
>From 2956c6d76c0c892c6f93c30e2b0bbe8e4c480736 Mon Sep 17 00:00:00 2001 >From: Owen Leonard <oleonard@myacpl.org> >Date: Thu, 14 Aug 2014 14:52:34 -0400 >Subject: [PATCH] Bug 11876 [Follow-up] Add a diff view to staged MARC Records > >This follow up makes some corrections to the previously added files and >adds some functionality to the diff: A Javascript diff plugin highlights >the differences between the records in the two columns. > >Corrections made: Converted tab indentation to spaces, corrected GPL >statement. > >File organization: Moved showdiffmarc.pl and .tt to /tools/ to match the >location of the page with which it functions, >tools/manage-marc-import.pl. Corrected permissions on showdiffmarc.pl >accordingly. > >Updates to the template: Added standard includes inclucing header menu >and breadcrumbs; converted custom layout to YUI Grid standard. > >To test, follow the test plan previously defined: > >- Stage a MARC record batch which contains at least one record match for > something already in your catalog. >- Locate the staged MARC record batch in Tools -> Manage staged records > and click to view the contents. >- Find the record which matched an existing record and click the "View" > link in the Diff column. >- The compare screen should include the header menu and breadcrumbs. The > differences between your staged file and the existing record should be > higlighted. >- You should be able to return to the MARC batch you were previously > viewing by following the link in the breadcrumbs or the link at the > bottom of the page. >- Confirm that the "About" page includes information about the new > JavaScript plugin on the Licenses tab. > >Signed-off-by: Nick Clemens <nick@quecheelibrary.org> > >Signed-off-by: Jonathan Druart <jonathan.druart@biblibre.com> >--- > koha-tmpl/intranet-tmpl/lib/jsdiff/jsdiff.js | 160 +++++++++++++++++++++ > koha-tmpl/intranet-tmpl/lib/jsdiff/jsdiff.min.js | 10 ++ > koha-tmpl/intranet-tmpl/prog/en/modules/about.tt | 3 + > .../prog/en/modules/tools/showdiffmarc.tt | 89 ++++++------ > tools/batch_records_ajax.pl | 2 +- > tools/showdiffmarc.pl | 10 +- > 6 files changed, 227 insertions(+), 47 deletions(-) > create mode 100644 koha-tmpl/intranet-tmpl/lib/jsdiff/jsdiff.js > create mode 100644 koha-tmpl/intranet-tmpl/lib/jsdiff/jsdiff.min.js > >diff --git a/koha-tmpl/intranet-tmpl/lib/jsdiff/jsdiff.js b/koha-tmpl/intranet-tmpl/lib/jsdiff/jsdiff.js >new file mode 100644 >index 0000000..3e3cc47 >--- /dev/null >+++ b/koha-tmpl/intranet-tmpl/lib/jsdiff/jsdiff.js >@@ -0,0 +1,160 @@ >+/* >+ * Javascript Diff Algorithm >+ * By John Resig (http://ejohn.org/) >+ * Modified by Chu Alan "sprite" >+ * >+ * Released under the MIT license. >+ * >+ * More Info: >+ * http://ejohn.org/projects/javascript-diff-algorithm/ >+ */ >+ >+function escape(s) { >+ var n = s; >+ n = n.replace(/&/g, "&"); >+ n = n.replace(/</g, "<"); >+ n = n.replace(/>/g, ">"); >+ n = n.replace(/"/g, """); >+ >+ return n; >+} >+ >+function diffString( o, n ) { >+ o = o.replace(/\s+$/, ''); >+ n = n.replace(/\s+$/, ''); >+ >+ var out = diff(o == "" ? [] : o.split(/\s+/), n == "" ? [] : n.split(/\s+/) ); >+ var str = ""; >+ >+ var oSpace = o.match(/\s+/g); >+ if (oSpace == null) { >+ oSpace = ["\n"]; >+ } else { >+ oSpace.push("\n"); >+ } >+ var nSpace = n.match(/\s+/g); >+ if (nSpace == null) { >+ nSpace = ["\n"]; >+ } else { >+ nSpace.push("\n"); >+ } >+ >+ if (out.n.length == 0) { >+ for (var i = 0; i < out.o.length; i++) { >+ str += '<del>' + escape(out.o[i]) + oSpace[i] + "</del>"; >+ } >+ } else { >+ if (out.n[0].text == null) { >+ for (n = 0; n < out.o.length && out.o[n].text == null; n++) { >+ str += '<del>' + escape(out.o[n]) + oSpace[n] + "</del>"; >+ } >+ } >+ >+ for ( var i = 0; i < out.n.length; i++ ) { >+ if (out.n[i].text == null) { >+ str += '<ins>' + escape(out.n[i]) + nSpace[i] + "</ins>"; >+ } else { >+ var pre = ""; >+ >+ for (n = out.n[i].row + 1; n < out.o.length && out.o[n].text == null; n++ ) { >+ pre += '<del>' + escape(out.o[n]) + oSpace[n] + "</del>"; >+ } >+ str += " " + out.n[i].text + nSpace[i] + pre; >+ } >+ } >+ } >+ >+ return str; >+} >+ >+function randomColor() { >+ return "rgb(" + (Math.random() * 100) + "%, " + >+ (Math.random() * 100) + "%, " + >+ (Math.random() * 100) + "%)"; >+} >+function diffString2( o, n ) { >+ o = o.replace(/\s+$/, ''); >+ n = n.replace(/\s+$/, ''); >+ >+ var out = diff(o == "" ? [] : o.split(/\s+/), n == "" ? [] : n.split(/\s+/) ); >+ >+ var oSpace = o.match(/\s+/g); >+ if (oSpace == null) { >+ oSpace = ["\n"]; >+ } else { >+ oSpace.push("\n"); >+ } >+ var nSpace = n.match(/\s+/g); >+ if (nSpace == null) { >+ nSpace = ["\n"]; >+ } else { >+ nSpace.push("\n"); >+ } >+ >+ var os = ""; >+ var colors = new Array(); >+ for (var i = 0; i < out.o.length; i++) { >+ colors[i] = randomColor(); >+ >+ if (out.o[i].text != null) { >+ os += '<span style="background-color: ' +colors[i]+ '">' + >+ escape(out.o[i].text) + oSpace[i] + "</span>"; >+ } else { >+ os += "<del>" + escape(out.o[i]) + oSpace[i] + "</del>"; >+ } >+ } >+ >+ var ns = ""; >+ for (var i = 0; i < out.n.length; i++) { >+ if (out.n[i].text != null) { >+ ns += '<span style="background-color: ' +colors[out.n[i].row]+ '">' + >+ escape(out.n[i].text) + nSpace[i] + "</span>"; >+ } else { >+ ns += "<ins>" + escape(out.n[i]) + nSpace[i] + "</ins>"; >+ } >+ } >+ >+ return { o : os , n : ns }; >+} >+ >+function diff( o, n ) { >+ var ns = new Object(); >+ var os = new Object(); >+ >+ for ( var i = 0; i < n.length; i++ ) { >+ if ( ns[ n[i] ] == null ) >+ ns[ n[i] ] = { rows: new Array(), o: null }; >+ ns[ n[i] ].rows.push( i ); >+ } >+ >+ for ( var i = 0; i < o.length; i++ ) { >+ if ( os[ o[i] ] == null ) >+ os[ o[i] ] = { rows: new Array(), n: null }; >+ os[ o[i] ].rows.push( i ); >+ } >+ >+ for ( var i in ns ) { >+ if ( ns[i].rows.length == 1 && typeof(os[i]) != "undefined" && os[i].rows.length == 1 ) { >+ n[ ns[i].rows[0] ] = { text: n[ ns[i].rows[0] ], row: os[i].rows[0] }; >+ o[ os[i].rows[0] ] = { text: o[ os[i].rows[0] ], row: ns[i].rows[0] }; >+ } >+ } >+ >+ for ( var i = 0; i < n.length - 1; i++ ) { >+ if ( n[i].text != null && n[i+1].text == null && n[i].row + 1 < o.length && o[ n[i].row + 1 ].text == null && >+ n[i+1] == o[ n[i].row + 1 ] ) { >+ n[i+1] = { text: n[i+1], row: n[i].row + 1 }; >+ o[n[i].row+1] = { text: o[n[i].row+1], row: i + 1 }; >+ } >+ } >+ >+ for ( var i = n.length - 1; i > 0; i-- ) { >+ if ( n[i].text != null && n[i-1].text == null && n[i].row > 0 && o[ n[i].row - 1 ].text == null && >+ n[i-1] == o[ n[i].row - 1 ] ) { >+ n[i-1] = { text: n[i-1], row: n[i].row - 1 }; >+ o[n[i].row-1] = { text: o[n[i].row-1], row: i - 1 }; >+ } >+ } >+ >+ return { o: o, n: n }; >+} >diff --git a/koha-tmpl/intranet-tmpl/lib/jsdiff/jsdiff.min.js b/koha-tmpl/intranet-tmpl/lib/jsdiff/jsdiff.min.js >new file mode 100644 >index 0000000..9420f1a >--- /dev/null >+++ b/koha-tmpl/intranet-tmpl/lib/jsdiff/jsdiff.min.js >@@ -0,0 +1,10 @@ >+/* >+ * Javascript Diff Algorithm >+ * By John Resig (http://ejohn.org/) >+ * Modified by Chu Alan "sprite" >+ * >+ * Released under the MIT license. >+ * >+ * More Info: >+ * http://ejohn.org/projects/javascript-diff-algorithm/ >+ */function escape(a){var b=a;return b=b.replace(/&/g,"&"),b=b.replace(/</g,"<"),b=b.replace(/>/g,">"),b=b.replace(/"/g,"""),b}function diffString(a,b){a=a.replace(/\s+$/,""),b=b.replace(/\s+$/,"");var c=diff(a==""?[]:a.split(/\s+/),b==""?[]:b.split(/\s+/)),d="",e=a.match(/\s+/g);e==null?e=["\n"]:e.push("\n");var f=b.match(/\s+/g);f==null?f=["\n"]:f.push("\n");if(c.n.length==0)for(var g=0;g<c.o.length;g++)d+="<del>"+escape(c.o[g])+e[g]+"</del>";else{if(c.n[0].text==null)for(b=0;b<c.o.length&&c.o[b].text==null;b++)d+="<del>"+escape(c.o[b])+e[b]+"</del>";for(var g=0;g<c.n.length;g++)if(c.n[g].text==null)d+="<ins>"+escape(c.n[g])+f[g]+"</ins>";else{var h="";for(b=c.n[g].row+1;b<c.o.length&&c.o[b].text==null;b++)h+="<del>"+escape(c.o[b])+e[b]+"</del>";d+=" "+c.n[g].text+f[g]+h}}return d}function randomColor(){return"rgb("+Math.random()*100+"%, "+Math.random()*100+"%, "+Math.random()*100+"%)"}function diffString2(a,b){a=a.replace(/\s+$/,""),b=b.replace(/\s+$/,"");var c=diff(a==""?[]:a.split(/\s+/),b==""?[]:b.split(/\s+/)),d=a.match(/\s+/g);d==null?d=["\n"]:d.push("\n");var e=b.match(/\s+/g);e==null?e=["\n"]:e.push("\n");var f="",g=new Array;for(var h=0;h<c.o.length;h++)g[h]=randomColor(),c.o[h].text!=null?f+='<span style="background-color: '+g[h]+'">'+escape(c.o[h].text)+d[h]+"</span>":f+="<del>"+escape(c.o[h])+d[h]+"</del>";var i="";for(var h=0;h<c.n.length;h++)c.n[h].text!=null?i+='<span style="background-color: '+g[c.n[h].row]+'">'+escape(c.n[h].text)+e[h]+"</span>":i+="<ins>"+escape(c.n[h])+e[h]+"</ins>";return{o:f,n:i}}function diff(a,b){var c=new Object,d=new Object;for(var e=0;e<b.length;e++)c[b[e]]==null&&(c[b[e]]={rows:new Array,o:null}),c[b[e]].rows.push(e);for(var e=0;e<a.length;e++)d[a[e]]==null&&(d[a[e]]={rows:new Array,n:null}),d[a[e]].rows.push(e);for(var e in c)c[e].rows.length==1&&typeof d[e]!="undefined"&&d[e].rows.length==1&&(b[c[e].rows[0]]={text:b[c[e].rows[0]],row:d[e].rows[0]},a[d[e].rows[0]]={text:a[d[e].rows[0]],row:c[e].rows[0]});for(var e=0;e<b.length-1;e++)b[e].text!=null&&b[e+1].text==null&&b[e].row+1<a.length&&a[b[e].row+1].text==null&&b[e+1]==a[b[e].row+1]&&(b[e+1]={text:b[e+1],row:b[e].row+1},a[b[e].row+1]={text:a[b[e].row+1],row:e+1});for(var e=b.length-1;e>0;e--)b[e].text!=null&&b[e-1].text==null&&b[e].row>0&&a[b[e].row-1].text==null&&b[e-1]==a[b[e].row-1]&&(b[e-1]={text:b[e-1],row:b[e].row-1},a[b[e].row-1]={text:a[b[e].row-1],row:e-1});return{o:a,n:b}}; >\ No newline at end of file >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/about.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/about.tt >index 0f01f8c..43938ce 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/about.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/about.tt >@@ -607,6 +607,9 @@ > <h2>jQuery Colvis plugin</h2> > <p>The <a href="http://datatables.net/extensions/colvis/">controls for column visiblity in DataTables</a> > by Allan Jardine is licensed under the BSD 3 and GPL v2 license.</p> >+ >+ <h2>Javascript Diff Algorithm</h2> >+ <p>The <a href="http://ejohn.org/projects/javascript-diff-algorithm/">Javascript Diff Algorithm</a> plugin by John Resig is licensed under the <a href="http://opensource.org/licenses/mit-license.php">MIT License</a>.</p> > </div> > > <div id="translations"> >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/showdiffmarc.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/showdiffmarc.tt >index 2d33c84..93edb39 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/showdiffmarc.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/showdiffmarc.tt >@@ -1,50 +1,55 @@ > [% INCLUDE 'doc-head-open.inc' %] >-<title>Koha -- Cataloging: MARC Import</title> >- >-<style> >-div#main { >- width: 100%; >- margin: 10px auto; >-} >- >-div.col1, >-div.col2 { >- float: left; >- width: 46%; >- margin-left: 3%; >- >-} >- >-pre { >- padding: 10px; >- overflow: scroll; >-} >+<title>Koha › Tools › Manage staged MARC records › Compare matched records</title> >+[% INCLUDE 'doc-head-close.inc' %] >+<script type="text/javascript" src="[% interface %]/lib/jsdiff/jsdiff.min.js"></script> >+<script type="text/javascript"> >+ $(document).ready(function(){ >+ var diff1 = $("#col1 pre").text(); >+ var diff2 = $("#col2 pre").text(); >+ var diffs = diffString(diff1,diff2); >+ $("#col1 pre,#col2 pre").html(diffs); >+ }); >+</script> >+<style type="text/css"> >+ ins { background-color: #e6ffe6; } >+ del { background-color: #ffe6e6; } >+ #col1 ins, #col2 del { display: none; } >+ pre { padding: 10px; overflow: scroll; } > </style> >+</head> >+<body id="tools_compare-marc-import" class="tools"> > >-[% INCLUDE 'doc-head-close.inc' %] >+[% INCLUDE 'header.inc' %] > >-</head> >-<body> >+<div id="breadcrumbs"> >+ <a href="/cgi-bin/koha/mainpage.pl">Home</a> › <a href="/cgi-bin/koha/tools/tools-home.pl">Tools</a> › <a href="/cgi-bin/koha/tools/manage-marc-import.pl">Manage staged MARC records</a> › <a href="/cgi-bin/koha/tools/manage-marc-import.pl?import_batch_id=[% batchid %]">Batch [% batchid %]</a> › Compare matched records >+</div> > >-<div id="main"> >- <div class="col1"> >- <h2>Original</h2> >- [% IF ( ERROR_FORMATTED1 ) %] >- <p>The biblionumber <em>[% BIBLIONUMBER %]</em> doesn't match to any record.</p> >- [% ELSE %] >- <h1>[% BIBLIOTITLE %]</h1> >- <pre>[% MARC_FORMATTED1 %]</pre> >- [% END %] >+<div id="doc3"> >+ <div class="yui-g"> >+ <div id="col1" class="yui-u first"> >+ <h1>Original</h1> >+ [% IF ( ERROR_FORMATTED1 ) %] >+ <div class="dialog alert"> >+ <p>The biblionumber <em>[% BIBLIONUMBER %]</em> doesn't match any existing record.</p> >+ </div> >+ [% ELSE %] >+ <h2>[% BIBLIOTITLE %]</h2> >+ <pre>[% MARC_FORMATTED1 %]</pre> >+ [% END %] >+ </div> >+ <div id="col2" class="yui-u"> >+ <h1>Imported</h1> >+ [% IF ( ERROR_FORMATTED2 ) %] >+ <div class="dialog alert"> >+ <p>The import id number <em>[% IMPORTID %]</em> doesn't match any existing record.</p> >+ </div> >+ [% ELSE %] >+ <h2>[% IMPORTTITLE %]</h2> >+ <pre>[% MARC_FORMATTED2 %] </pre> >+ [% END %] >+ </div> > </div> >- <div class="col2"> >- <h2>Imported</h2> >- [% IF ( ERROR_FORMATTED2 ) %] >- <p>The importid <em>[% IMPORTID %]</em> doesn't match to any record.</p> >- [% ELSE %] >- <h1>[% IMPORTTITLE %]</h1> >- <pre>[% MARC_FORMATTED2 %] </pre> >- [% END %] >- </div> >-</div> > >+<p><a href="/cgi-bin/koha/tools/manage-marc-import.pl?import_batch_id=[% batchid %]">Return to staged MARC batch [% batchid %]</a></p> > [% INCLUDE 'intranet-bottom.inc' %] >diff --git a/tools/batch_records_ajax.pl b/tools/batch_records_ajax.pl >index 57d7bc0..e3dec83 100755 >--- a/tools/batch_records_ajax.pl >+++ b/tools/batch_records_ajax.pl >@@ -107,7 +107,7 @@ foreach my $record (@$records) { > || q{}, > score => $#$match > -1 ? $match->[0]->{'score'} : 0, > match_id => $match_id, >- diff_url => $match_id ? "/cgi-bin/koha/tools/showdiffmarc.pl?importid=$record->{import_record_id}&id=$match_id" : undef >+ diff_url => $match_id ? "/cgi-bin/koha/tools/showdiffmarc.pl?batchid=$import_batch_id&importid=$record->{import_record_id}&id=$match_id" : undef > }; > } > >diff --git a/tools/showdiffmarc.pl b/tools/showdiffmarc.pl >index e0e0f7c..3b12795 100755 >--- a/tools/showdiffmarc.pl >+++ b/tools/showdiffmarc.pl >@@ -8,7 +8,7 @@ > # > # Koha is free software; you can redistribute it and/or modify it under the > # terms of the GNU General Public License as published by the Free Software >-# Foundation; either version 2 of the License, or (at your option) any later >+# Foundation; either version 3 of the License, or (at your option) any later > # version. > # > # Koha is distributed in the hope that it will be useful, but WITHOUT ANY >@@ -40,6 +40,7 @@ use XML::LibXML; > my $input = new CGI; > my $biblionumber = $input->param('id'); > my $importid = $input->param('importid'); >+my $batchid = $input->param('batchid'); > > > if ( $biblionumber and $importid ) { >@@ -56,7 +57,7 @@ if ( $biblionumber and $importid ) { > query => $input, > type => "intranet", > authnotrequired => 0, >- flagsrequired => { catalogue => 1 }, >+ flagsrequired => { tools => 'manage_staged_marc' }, > debug => 1, > } > ); >@@ -82,7 +83,7 @@ if ( $biblionumber and $importid ) { > } > > >- $template->param( SCRIPT_NAME => $ENV{'SCRIPT_NAME'}, >+ $template->param( SCRIPT_NAME => $ENV{'SCRIPT_NAME'}, > BIBLIONUMBER => $biblionumber, > IMPORTID => $importid, > BIBLIOTITLE => $biblioTitle, >@@ -90,7 +91,8 @@ if ( $biblionumber and $importid ) { > MARC_FORMATTED1 => $formatted1, > MARC_FORMATTED2 => $formatted2, > ERROR_FORMATTED1 => $errorFormatted1, >- ERROR_FORMATTED2 => $errorFormatted2 >+ ERROR_FORMATTED2 => $errorFormatted2, >+ batchid => $batchid > ); > > output_html_with_http_headers $input, $cookie, $template->output; >-- >2.1.0
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 11876
:
25743
|
30590
|
30591
|
30787
|
30797
|
30798
|
30799
|
30800
|
31835
|
31847
|
31871
|
31872
|
31873
|
31874
|
32987
|
32995
|
33052
|
33053
|
33054
|
33055
|
33056