File Coverage

blib/lib/MARC/Convert/Wikidata.pm
Criterion Covered Total %
statement 44 71 61.9
branch 4 18 22.2
condition 2 12 16.6
subroutine 10 14 71.4
pod 4 4 100.0
total 64 119 53.7


line stmt bran cond sub pod time code
1             package MARC::Convert::Wikidata;
2              
3 3     3   144646 use strict;
  3         35  
  3         84  
4 3     3   28 use warnings;
  3         5  
  3         103  
5              
6 3     3   915 use Class::Utils qw(set_params);
  3         27738  
  3         84  
7 3     3   136 use Error::Pure qw(err);
  3         10  
  3         123  
8 3     3   1349 use MARC::Convert::Wikidata::Item::AudioBook;
  3         8  
  3         124  
9 3     3   1500 use MARC::Convert::Wikidata::Item::BookEdition;
  3         8  
  3         80  
10 3     3   1261 use MARC::Convert::Wikidata::Item::Periodical;
  3         7  
  3         111  
11 3     3   1351 use MARC::Convert::Wikidata::Transform;
  3         12  
  3         125  
12 3     3   22 use Scalar::Util qw(blessed);
  3         8  
  3         1982  
13              
14             our $VERSION = 0.02;
15              
16             # Constructor.
17             sub new {
18 3     3 1 23761 my ($class, @params) = @_;
19              
20             # Create object.
21 3         9 my $self = bless {}, $class;
22              
23             # Cover callback.
24 3         10 $self->{'callback_cover'} = undef;
25              
26             # Lang callback.
27 3         8 $self->{'callback_lang'} = undef;
28              
29             # People callback.
30 3         7 $self->{'callback_people'} = undef;
31              
32             # Place of publication Wikidata lookup callback.
33 3         7 $self->{'callback_publisher_place'} = undef;
34              
35             # Publisher Wikidata lookup callback.
36 3         7 $self->{'callback_publisher_name'} = undef;
37              
38             # Book series Wikidata lookup callback.
39 3         7 $self->{'callback_series'} = undef;
40              
41             # Retrieved date.
42 3         4 $self->{'date_retrieved'} = undef;
43              
44             # MARC::Record object.
45 3         9 $self->{'marc_record'} = undef;
46              
47             # Process parameters.
48 3         14 set_params($self, @params);
49              
50 3 100       41 if (! defined $self->{'marc_record'}) {
51 1         4 err "Parameter 'marc_record' is required.";
52             }
53 2 100 66     25 if (! blessed($self->{'marc_record'})
54             || ! $self->{'marc_record'}->isa('MARC::Record')) {
55              
56 1         4 err "Parameter 'marc_record' must be a MARC::Record object.";
57             }
58              
59             $self->{'_transform_object'} = MARC::Convert::Wikidata::Transform->new(
60 1         11 'marc_record' => $self->{'marc_record'},
61             )->object;
62              
63 1         55 return $self;
64             }
65              
66             sub object {
67 0     0 1   my $self = shift;
68              
69 0           return $self->{'_transform_object'};
70             }
71              
72             sub type {
73 0     0 1   my $self = shift;
74              
75 0           my $leader = $self->{'marc_record'}->leader;
76             # XXX Use MARC::Leader if exist.
77 0           my $leader_hr = $self->_leader($leader);
78              
79             # Language material
80 0 0 0       if ($leader_hr->{'type_of_record'} eq 'a' && $leader_hr->{'bibliographic_level'} eq 'm') {
    0 0        
    0 0        
    0          
81 0           return 'monograph';
82              
83             # XXX Notated music
84             } elsif ($leader_hr->{'type_of_record'} eq 'c' && $leader_hr->{'bibliographic_level'} eq 'm') {
85 0           return 'monograph';
86              
87             # Nonmusical sound recording
88             } elsif ($leader_hr->{'type_of_record'} eq 'i' && $leader_hr->{'bibliographic_level'} eq 'm') {
89 0           return 'audiobook';
90              
91             # Serial
92             } elsif ($leader_hr->{'bibliographic_level'} eq 's') {
93 0           return 'periodical';
94             } else {
95 0           err "Unsupported item with leader '$leader'.";
96             }
97             }
98              
99             sub wikidata {
100 0     0 1   my $self = shift;
101              
102             # Parameters.
103             my %params = (
104             'callback_cover' => $self->{'callback_cover'},
105             'callback_lang' => $self->{'callback_lang'},,
106             'callback_publisher_place' => $self->{'callback_publisher_place'},,
107             'callback_people' => $self->{'callback_people'},
108             'callback_publisher_name' => $self->{'callback_publisher_name'},
109             'callback_series' => $self->{'callback_series'},
110             'marc_record' => $self->{'marc_record'},
111 0           'transform_object' => $self->{'_transform_object'},
112             );
113              
114 0           my $wikidata;
115 0           my $marc_type = $self->type;
116 0 0         if ($marc_type eq 'monograph') {
    0          
    0          
117 0           $wikidata = MARC::Convert::Wikidata::Item::BookEdition->new(
118             %params,
119             )->wikidata;
120             } elsif ($marc_type eq 'audiobook') {
121 0           $wikidata = MARC::Convert::Wikidata::Item::AudioBook->new(
122             %params,
123             )->wikidata;
124             } elsif ($marc_type eq 'periodical') {
125 0           $wikidata = MARC::Convert::Wikidata::Item::Periodical->new(
126             %params,
127             )->wikidata;
128             } else {
129 0           err "Item '$marc_type' doesn't supported.";
130             }
131              
132 0           return $wikidata;
133             }
134              
135             sub _leader {
136 0     0     my ($self, $leader) = @_;
137              
138             # Example '03691nam a2200685 aa4500'
139 0           my $length = substr $leader, 0, 5;
140 0           my $record_status = substr $leader, 5, 1;
141 0           my $type_of_record = substr $leader, 6, 1;
142 0           my $bibliographic_level = substr $leader, 7, 1;
143              
144             return {
145 0           'length' => $length,
146             'record_status' => $record_status,
147             'type_of_record' => $type_of_record,
148             'bibliographic_level' => $bibliographic_level,
149             }
150             }
151              
152             1;
153              
154             __END__
155              
156             =pod
157              
158             =encoding utf8
159              
160             =head1 NAME
161              
162             MARC::Convert::Wikidata - Conversion class between MARC file to Wikibase::Datatype item.
163              
164             =head1 SYNOPSIS
165              
166             use MARC::Convert::Wikidata;
167              
168             my $obj = MARC::Convert::Wikidata->new(%params);
169             my $object = $obj->object;
170             my $type = $obj->type;
171             my $wikidata = $obj->wikidata;
172              
173             =head1 DESCRIPTION
174              
175             Original intent of this class was conversion from MARC records in National Library of the
176             Czech Republic to Wikidata. The conversion is not simple, this mean that many
177             things are concrete for this concrete national library.
178              
179             =head1 METHODS
180              
181             =head2 C<new>
182              
183             my $obj = MARC::Convert::Wikidata->new(%params);
184              
185             Constructor.
186              
187             =over 8
188              
189             =item * C<callback_cover>
190              
191             Cover callback
192              
193             Default value is undef.
194              
195             =item * C<callback_lang>
196              
197             Language callback.
198              
199             Default value is undef.
200              
201             =item * C<callback_people>
202              
203             People callback.
204              
205             Default value is undef.
206              
207             =item * C<callback_publisher_place>
208              
209             Place of publication Wikidata lookup callback.
210              
211             Default value is undef.
212              
213             =item * C<callback_publisher_name>
214              
215             Publisher Wikidata lookup callback.
216              
217             Default value is undef.
218              
219             =item * C<callback_series>
220              
221             Book series Wikidata lookup callback.
222              
223             Default value is undef.
224              
225             =item * C<date_retrieved>
226              
227             Retrieved date.
228              
229             Default value is undef.
230              
231             =item * C<marc_record>
232              
233             MARC::Record object.
234              
235             It's required.
236              
237             =back
238              
239             Returns instance of object.
240              
241             =head2 C<object>
242              
243             my $object = $obj->object;
244              
245             Get data object created from MARC record.
246              
247             Returns MARC::Convert::Wikidata::Object instance.
248              
249             =head2 C<type>
250              
251             my $type = $obj->type;
252              
253             Process MARC record and detect which record type is.
254             Supported values are: monograph, audiobook and periodical.
255              
256             Returns string.
257              
258             =head2 C<wikidata>
259              
260             my $wikidata = $obj->wikidata;
261              
262             Process conversion from MARC record to Wikibase::Datatype::Item which is
263             possible to load to Wikidata.
264              
265             Returns Wikibase::Datatype instance.
266              
267             =head1 ERRORS
268              
269             new():
270             From Class::Utils::set_params():
271             Unknown parameter '%s'.
272             Parameter 'marc_record' is required.
273             Parameter 'marc_record' must be a MARC::Record object.
274              
275             type():
276             Unsupported item with leader '%s'.
277              
278             wikidata():
279             Item '%s' doesn't supported.
280             Unsupported item with leader '%s'.
281              
282             =head1 EXAMPLE
283              
284             =for comment filename=marc_to_wikidata_print.pl
285              
286             use strict;
287             use warnings;
288              
289             use File::Temp ();
290             use MARC::Convert::Wikidata;
291             use MARC::File::XML;
292             use MARC::Record;
293             use Unicode::UTF8 qw(decode_utf8 encode_utf8);
294             use Wikibase::Datatype::Print::Item;
295              
296             my $marc_xml = decode_utf8(<<'END');
297             <?xml version="1.0" encoding="UTF-8"?>
298             <collection
299             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
300             xsi:schemaLocation="http://www.loc.gov/MARC21/slim http://www.loc.gov/standards/marcxml/schema/MARC21slim.xsd"
301             xmlns="http://www.loc.gov/MARC21/slim">
302             <record>
303             <leader>01177nam a2200349 i 4500</leader>
304             <controlfield tag="001">nkc20193102359</controlfield>
305             <controlfield tag="003">CZ PrNK</controlfield>
306             <controlfield tag="005">20190813103856.0</controlfield>
307             <controlfield tag="007">ta</controlfield>
308             <controlfield tag="008">190612s1917 xr af b 000 f cze </controlfield>
309             <datafield tag="015" ind1=" " ind2=" ">
310             <subfield code="a">cnb003102359</subfield>
311             </datafield>
312             <datafield tag="020" ind1=" " ind2=" ">
313             <subfield code="q">(Vázáno)</subfield>
314             </datafield>
315             <datafield tag="040" ind1=" " ind2=" ">
316             <subfield code="a">ABA001</subfield>
317             <subfield code="b">cze</subfield>
318             <subfield code="e">rda</subfield>
319             </datafield>
320             <datafield tag="072" ind1=" " ind2="7">
321             <subfield code="a">821.162.3-3</subfield>
322             <subfield code="x">Česká próza</subfield>
323             <subfield code="2">Konspekt</subfield>
324             <subfield code="9">25</subfield>
325             </datafield>
326             <datafield tag="072" ind1=" " ind2="7">
327             <subfield code="a">821-93</subfield>
328             <subfield code="x">Literatura pro děti a mládež (beletrie)</subfield>
329             <subfield code="2">Konspekt</subfield>
330             <subfield code="9">26</subfield>
331             </datafield>
332             <datafield tag="080" ind1=" " ind2=" ">
333             <subfield code="a">821.162.3-34</subfield>
334             <subfield code="2">MRF</subfield>
335             </datafield>
336             <datafield tag="080" ind1=" " ind2=" ">
337             <subfield code="a">821-93</subfield>
338             <subfield code="2">MRF</subfield>
339             </datafield>
340             <datafield tag="080" ind1=" " ind2=" ">
341             <subfield code="a">(0:82-34)</subfield>
342             <subfield code="2">MRF</subfield>
343             </datafield>
344             <datafield tag="100" ind1="1" ind2=" ">
345             <subfield code="a">Karafiát, Jan,</subfield>
346             <subfield code="d">1846-1929</subfield>
347             <subfield code="7">jk01052941</subfield>
348             <subfield code="4">aut</subfield>
349             </datafield>
350             <datafield tag="245" ind1="1" ind2="0">
351             <subfield code="a">Broučci :</subfield>
352             <subfield code="b">pro malé i veliké děti /</subfield>
353             <subfield code="c">Jan Karafiát</subfield>
354             </datafield>
355             <datafield tag="250" ind1=" " ind2=" ">
356             <subfield code="a">IV. vydání</subfield>
357             </datafield>
358             <datafield tag="264" ind1=" " ind2="1">
359             <subfield code="a">V Praze :</subfield>
360             <subfield code="b">Alois Hynek,</subfield>
361             <subfield code="c">[1917?]</subfield>
362             </datafield>
363             <datafield tag="300" ind1=" " ind2=" ">
364             <subfield code="a">85 stran, 5 nečíslovaných listů obrazových příloh :</subfield>
365             <subfield code="b">ilustrace (některé barevné) ;</subfield>
366             <subfield code="c">24 cm</subfield>
367             </datafield>
368             <datafield tag="336" ind1=" " ind2=" ">
369             <subfield code="a">text</subfield>
370             <subfield code="b">txt</subfield>
371             <subfield code="2">rdacontent</subfield>
372             </datafield>
373             <datafield tag="337" ind1=" " ind2=" ">
374             <subfield code="a">bez média</subfield>
375             <subfield code="b">n</subfield>
376             <subfield code="2">rdamedia</subfield>
377             </datafield>
378             <datafield tag="338" ind1=" " ind2=" ">
379             <subfield code="a">svazek</subfield>
380             <subfield code="b">nc</subfield>
381             <subfield code="2">rdacarrier</subfield>
382             </datafield>
383             <datafield tag="655" ind1=" " ind2="7">
384             <subfield code="a">české pohádky</subfield>
385             <subfield code="7">fd133970</subfield>
386             <subfield code="2">czenas</subfield>
387             </datafield>
388             <datafield tag="655" ind1=" " ind2="7">
389             <subfield code="a">publikace pro děti</subfield>
390             <subfield code="7">fd133156</subfield>
391             <subfield code="2">czenas</subfield>
392             </datafield>
393             <datafield tag="655" ind1=" " ind2="9">
394             <subfield code="a">Czech fairy tales</subfield>
395             <subfield code="2">eczenas</subfield>
396             </datafield>
397             <datafield tag="655" ind1=" " ind2="9">
398             <subfield code="a">children's literature</subfield>
399             <subfield code="2">eczenas</subfield>
400             </datafield>
401             <datafield tag="910" ind1=" " ind2=" ">
402             <subfield code="a">ABA001</subfield>
403             </datafield>
404             <datafield tag="998" ind1=" " ind2=" ">
405             <subfield code="a">003102359</subfield>
406             </datafield>
407             </record>
408             </collection>
409             END
410             my $marc_record = MARC::Record->new_from_xml($marc_xml, 'UTF-8');
411              
412             # Object.
413             my $obj = MARC::Convert::Wikidata->new(
414             'marc_record' => $marc_record,
415             );
416              
417             # Convert MARC record to Wikibase object.
418             my $item = $obj->wikidata;
419              
420             # Print out.
421             print encode_utf8(scalar Wikibase::Datatype::Print::Item::print($item));
422              
423             # Output like:
424             # TODO Add callbacks.
425             # No callback method for translation of people in 'authors' method.
426             # No callback method for translation of language.
427             # Label: Broučci: pro malé i veliké děti (en)
428             # Description: 1917 Czech book edition (en)
429             # Statements:
430             # P31: Q3331189 (normal)
431             # P3184: cnb003102359 (normal)
432             # References:
433             # {
434             # P248: Q86914821
435             # P3184: cnb003102359
436             # P813: 26 May 2023 (Q1985727)
437             # }
438             # P393: 4 (normal)
439             # References:
440             # {
441             # P248: Q86914821
442             # P3184: cnb003102359
443             # P813: 26 May 2023 (Q1985727)
444             # }
445             # P1104: 85 (normal)
446             # References:
447             # {
448             # P248: Q86914821
449             # P3184: cnb003102359
450             # P813: 26 May 2023 (Q1985727)
451             # }
452             # P577: 1917 (Q1985727) (normal)
453             # References:
454             # {
455             # P248: Q86914821
456             # P3184: cnb003102359
457             # P813: 26 May 2023 (Q1985727)
458             # }
459             # P1680: pro malé i veliké děti (cs) (normal)
460             # References:
461             # {
462             # P248: Q86914821
463             # P3184: cnb003102359
464             # P813: 26 May 2023 (Q1985727)
465             # }
466             # P1476: Broučci (cs) (normal)
467             # References:
468             # {
469             # P248: Q86914821
470             # P3184: cnb003102359
471             # P813: 26 May 2023 (Q1985727)
472             # }
473              
474             =head1 DEPENDENCIES
475              
476             L<Class::Utils>,
477             L<Error::Pure>,
478             L<MARC::Convert::Wikidata::Item::AudioBook>,
479             L<MARC::Convert::Wikidata::Item::BookEdition>,
480             L<MARC::Convert::Wikidata::Item::Periodical>,
481             L<MARC::Convert::Wikidata::Transform>,
482             L<Scalar::Util>.
483              
484             =head1 SEE ALSO
485              
486             =over
487              
488             =item L<MARC::Record>
489              
490             Perl extension for handling MARC records
491              
492             =item L<Wikibase::Datatype::Item>
493              
494             Wikibase item datatype.
495              
496             =back
497              
498             =head1 REPOSITORY
499              
500             L<https://github.com/michal-josef-spacek/MARC-Convert-Wikidata>
501              
502             =head1 AUTHOR
503              
504             Michal Josef Špaček L<mailto:skim@cpan.org>
505              
506             L<http://skim.cz>
507              
508             =head1 LICENSE AND COPYRIGHT
509              
510             © 2021-2023 Michal Josef Špaček
511              
512             BSD 2-Clause License
513              
514             =head1 VERSION
515              
516             0.02
517              
518             =cut