--- /dev/null
+<ng-template #dialogContent>
+ <div class="modal-header bg-info">
+ <h4 class="modal-title">
+ <span i18n>MARC Record Lint Results</span>
+ </h4>
+ <button type="button" class="close"
+ i18n-aria-label aria-label="Close" (click)="close()">
+ <span aria-hidden="true">×</span>
+ </button>
+ </div>
+ <div class="modal-body">
+ <div class="row p-2" *ngIf="warnings.length === 0">
+ <span i18n>No warnings!</span>
+ </div>
+ <div class="row p-2" *ngIf="warnings.length > 0">
+ <ul>
+ <li *ngFor="let warning of warnings">
+ {{warning}}
+ </li>
+ </ul>
+ </div>
+ </div>
+ <div class="modal-footer">
+ <ng-container *ngIf="!chargeResponse">
+ <button type="button" class="btn btn-warning"
+ (click)="close()" i18n>Close</button>
+ </ng-container>
+ </div>
+</ng-template>
--- /dev/null
+import {Component, OnInit, Input, ViewChild} from '@angular/core';
+import {DialogComponent} from '@eg/share/dialog/dialog.component';
+import {NgbModal} from '@ng-bootstrap/ng-bootstrap';
+
+/**
+ * Dialog for merging authority records.
+ */
+
+@Component({
+ selector: 'eg-marc-record-lint-dialog',
+ templateUrl: 'lint-dialog.component.html'
+})
+
+export class MarcRecordLintDialogComponent
+ extends DialogComponent implements OnInit {
+
+ // lint warnings
+ @Input() warnings: any[] = [];
+
+ constructor(
+ private modal: NgbModal // required for passing to parent
+ ) {
+ super(modal); // required for subclassing
+ }
+}
import {MarcEditorDialogComponent} from './editor-dialog.component';
import {PhysCharDialogComponent} from './phys-char-dialog.component';
import {HoldingsModule} from '@eg/staff/share/holdings/holdings.module';
+import {MarcRecordLintDialogComponent} from './lint-dialog.component';
@NgModule({
declarations: [
EditableContentComponent,
MarcEditorDialogComponent,
PhysCharDialogComponent,
- AuthorityLinkingDialogComponent
+ AuthorityLinkingDialogComponent,
+ MarcRecordLintDialogComponent
],
imports: [
StaffCommonModule,
</ng-container>
</ng-template>
+
+<eg-marc-record-lint-dialog #lintDialog></eg-marc-record-lint-dialog>
+
<ng-container *ngIf="dataLoaded">
<div class="mt-3 text-monospace"
(contextmenu)="$event.preventDefault()">
<div><button class="btn btn-outline-dark"
(click)="showHelp = !showHelp" i18n>Help</button></div>
<ng-container *ngIf="context.recordType === 'biblio'">
- <div class="mt-2"><button class="btn btn-outline-dark"
- (click)="validate()" i18n>Validate</button></div>
+ <div class="mt-2">
+ <button class="btn btn-outline-dark"
+ (click)="validate()" i18n>Validate</button>
+ <button class="btn btn-outline-dark ml-2"
+ (click)="lint()" i18n>Lint</button>
+ </div>
</ng-container>
<div class="mt-2">
<button type="button" class="btn btn-outline-info"
import {MarcEditContext} from './editor-context';
import {AuthorityLinkingDialogComponent} from './authority-linking-dialog.component';
import {PhysCharDialogComponent} from './phys-char-dialog.component';
+import {MarcRecordLintDialogComponent} from './lint-dialog.component';
/**
@ViewChild('physCharDialog', {static: false})
physCharDialog: PhysCharDialogComponent;
+ @ViewChild('lintDialog', {static: false})
+ lintDialog: MarcRecordLintDialogComponent;
+
constructor(
private idl: IdlService,
private net: NetService,
});
}
+ lint() {
+ const xml = this.record.toXml();
+ this.net.request('open-ils.cat',
+ 'open-ils.cat.biblio.record.lint', xml)
+ .subscribe(warnings => {
+ this.lintDialog.warnings = warnings;
+ this.lintDialog.open({size: 'lg'});
+ });
+ }
+
isControlledBibTag(tag: string): boolean {
return this.controlledBibTags && this.controlledBibTags.includes(tag);
}
use OpenSRF::Utils::Logger qw($logger);
use OpenSRF::AppSession;
+use MARC::File::XML (BinaryEncoding => 'utf8', RecordFormat => 'USMARC');
+use MARC::Record;
+use MARC::Lint;
+use MARC::Errorchecks;
+
my $U = "OpenILS::Application::AppUtils";
my $conf;
my %marctemplates;
}
}
+__PACKAGE__->register_method(
+ method => "lint_marc_bib",
+ api_name => "open-ils.cat.biblio.record.lint",
+ argc => 1,
+ signature => {
+ desc => 'Return a list of warnings about a bibliograhpic MARC record',
+ params => [
+ {desc => 'MARC record (as MARCXML)', type => 'string'},
+ ]
+ },
+ return => {desc => 'List of warnings about the MARC record', type => 'object' }
+);
+
+sub lint_marc_bib {
+ my ($self, $client, $marc) = @_;
+
+open F, '>', '/tmp/f';
+print F $marc;
+close F;
+ my $rec;
+ eval {
+ $rec = MARC::Record->new_from_xml($marc);
+ };
+ if ($@) {
+ return [ 'Record cannot be parsed at all (and crashed MARC::Record)' ];
+ };
+ unless (defined $rec) {
+ return [ 'Record cannot be parsed at all' ];
+ }
+
+ my @errors = ();
+ eval {
+ @errors = @{MARC::Errorchecks::check_all_subs($rec)};
+ };
+ if ($@) {
+ return [ 'Record could not be parsed by MARC::Errorchecks' ];
+ }
+
+ my $lint = MARC::Lint->new;
+ $lint->check_record($rec);
+ my @warnings = $lint->warnings;
+
+ return [ sort (@warnings, @errors) ];
+}
+
1;
# vi:et:ts=4:sw=4