relaton-isbn 1.20.1 → 2.0.0.pre.alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d961c0cec51c29aa88f6fad4ef2d58983639702fcba31cd8cf055f45c076e2e6
4
- data.tar.gz: 31f1d75ae435ce9a8ffca0f4f5717a2091bdf80ff85c8e4546530945c48d1c17
3
+ metadata.gz: 8d47310ca1f6271c5591fff0ec1024f005fde6924145a82fb0a802f000d705fd
4
+ data.tar.gz: c2bb8987f28c0d7a3f7bed4b2b02738bb3e929f43c38762c152387620609140a
5
5
  SHA512:
6
- metadata.gz: 6e611b4a3b4c3daefa5711f460eb56bee5c386036f48b5b9a3e32f37179e2b72ca99497edfe2d1306769af3c3d308460ab3c15a0ed8e5530b3b5a38b6f0a8276
7
- data.tar.gz: d6a3067ef1bb1da1e8a1754d0de441aa3ea2a9334a24d11b831c86e583313070da550f52e23ff4e3a62b1857fe96ddb867ab29e15b435a0405bd7363a260bfed
6
+ metadata.gz: 8568adf632314066c5ecb1e93efce0767a07abc112b9dfd7dcf1d1618151b69901ce772a479101881c5405fde6ec1c22f609b872d731e81cb6b6c931052f12b9
7
+ data.tar.gz: '0148ab38709f2868769f8b51da950f257dcc5d43952b0515ef1c8044f695359bdd6ca63c1215c5f72bf87a479ae7f40f7d0e45577ab0794d6094d955f1c73989'
@@ -0,0 +1,7 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(gem list:*)"
5
+ ]
6
+ }
7
+ }
data/.rubocop.yml CHANGED
@@ -7,6 +7,6 @@ require: rubocop-rails
7
7
  inherit_from:
8
8
  - https://raw.githubusercontent.com/riboseinc/oss-guides/master/ci/rubocop.yml
9
9
  AllCops:
10
- TargetRubyVersion: 3.1
10
+ TargetRubyVersion: 3.2
11
11
  Rails:
12
12
  Enabled: false
data/CLAUDE.md ADDED
@@ -0,0 +1,45 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## What this gem does
6
+
7
+ Retrieves bibliographic items from the OpenLibrary API by ISBN (10 or 13 digit) and returns `Relaton::Bib::ItemData` objects. Part of the Relaton family of gems.
8
+
9
+ ## Commands
10
+
11
+ ```sh
12
+ bundle exec rspec # run all tests
13
+ bundle exec rspec spec/relaton/isbn/parser_spec.rb # run single spec file
14
+ bundle exec rubocop # lint
15
+ bin/console # IRB with gem loaded
16
+ ```
17
+
18
+ ## Architecture
19
+
20
+ Request flow: `OpenLibrary.get(code)` → `Isbn.new(code).parse` (validates/normalizes ISBN) → `OpenLibrary.request_api(isbn)` (HTTP to openlibrary.org) → `Parser.parse(json)` (builds `ItemData`)
21
+
22
+ Key modules under `Relaton::Isbn`:
23
+ - **OpenLibrary** — API client, main entry point via `.get`
24
+ - **Isbn** — ISBN-10/13 validation and conversion (always normalizes to ISBN-13)
25
+ - **Parser** — Transforms OpenLibrary JSON into `Relaton::Bib::ItemData` with titles, contributors, dates, etc.
26
+ - **Processor** — Integration hook for relaton-core framework (`from_xml`, `from_yaml`, `get`)
27
+ - **Util** — Logging via `Relaton::Bib::Util`
28
+
29
+ ## Data model (relaton-bib 2.0)
30
+
31
+ Uses `Relaton::Bib::` namespace (not the old `RelatonBib::`). Key classes: `ItemData`, `Title`, `Docidentifier` (uses `.content` not `.id`), `Uri`, `Contributor`, `Person`, `Organization`, `Date` (uses `at:` not `on:`), `Place`.
32
+
33
+ `Parser#parse` returns `Bib::ItemData` (not `Bibitem`) — `ItemData` is the plain data class; `Bibitem`/`Item` are lutaml-model serializers that wrap it.
34
+
35
+ ## Testing
36
+
37
+ - **VCR** records HTTP interactions in `spec/vcr_cassettes/` (re-records every 7 days)
38
+ - **WebMock** disables real HTTP by default
39
+ - **SimpleCov** tracks coverage
40
+ - Fixtures in `spec/fixtures/`
41
+
42
+ ## Style
43
+
44
+ - RuboCop with Ribose OSS style guide, target Ruby 3.1
45
+ - `rubocop-rails` is required but Rails cops are disabled (not a Rails app)
data/README.adoc CHANGED
@@ -1,4 +1,4 @@
1
- = Relaton-ISBN: retrieves bibliographic items using OpenLibrary API
1
+ = Relaton::ISBN: retrieves bibliographic items using OpenLibrary API
2
2
 
3
3
  image:https://img.shields.io/gem/v/relaton-isbn.svg["Gem Version", link="https://rubygems.org/gems/relaton-isbn"]
4
4
  image:https://github.com/relaton/relaton-isbn/workflows/macos/badge.svg["Build Status (macOS)", link="https://github.com/relaton/relaton-isbn/actions?workflow=macos"]
@@ -8,11 +8,11 @@ image:https://codeclimate.com/github/relaton/relaton-isbn/badges/gpa.svg["Code C
8
8
  image:https://img.shields.io/github/issues-pr-raw/relaton/relaton-isbn.svg["Pull Requests", link="https://github.com/relaton/relaton-isbn/pulls"]
9
9
  image:https://img.shields.io/github/commits-since/relaton/relaton-isbn/latest.svg["Commits since latest",link="https://github.com/relaton/relaton-isbn/releases"]
10
10
 
11
- RelatonIsbn is a Ruby gem that implements the
11
+ Relaton::Isbn is a Ruby gem that implements the
12
12
  https://github.com/metanorma/metanorma-model-iso#iso-bibliographic-item[IsoBibliographicItem model].
13
13
 
14
14
  You can use it to retrieve metadata of Standards from https://openlibrary.org, and
15
- access such metadata through the `BibliographicItem` object.
15
+ access such metadata through the `Bibitem` object.
16
16
 
17
17
  == Installation
18
18
 
@@ -41,25 +41,25 @@ $ gem install relaton-isbn
41
41
 
42
42
  === Retrieving bibliographic items using OpenLibrary API
43
43
 
44
- To retrieve bibliographic items, use `RelatonIsbn::OpenLibrary.get` method with ISBN-10 or ISBN-13 as an argument. Allowed prefixes are `ISBN`, `isbn:`. Prefix and hyphens are optional. The method returns `RelatonBib::BibliographicItem` object.
44
+ To retrieve bibliographic items, use `Relaton::Isbn::OpenLibrary.get` method with ISBN-10 or ISBN-13 as an argument. Allowed prefixes are `ISBN`, `isbn:`. Prefix and hyphens are optional. The method returns `Relaton::Bib::Bibitem` object.
45
45
 
46
46
  [source,ruby]
47
47
  ----
48
- require 'relaton_isbn'
48
+ require 'relaton/isbn'
49
49
  => true
50
50
 
51
51
  # get document by ISBN-13
52
- > ibitem = RelatonIsbn::OpenLibrary.get "ISBN 978-0-12-064481-0"
53
- [relaton-isbn] (ISBN 9780120644810) Fetching from OpenLibrary ...
54
- [relaton-isbn] (ISBN 9780120644810) Found: `9780120644810`
55
- => #<RelatonBib::BibliographicItem:0x0000000113889258
52
+ bibitem = Relaton::Isbn::OpenLibrary.get "ISBN 978-0-12-064481-0"
53
+ [relaton-isbn] INFO: (ISBN 978-0-12-064481-0) Fetching from OpenLibrary ...
54
+ [relaton-isbn] INFO: (ISBN 978-0-12-064481-0) Found: `9780120644810`
55
+ => #<Relaton::Bib::Bibitem:0x0000000127ed25d8
56
56
  ...
57
57
 
58
58
  # get document by ISBN-10
59
- > RelatonIsbn::OpenLibrary.get "isbn:0120644819"
60
- [relaton-isbn] (isbn:0120644819) Fetching from OpenLibrary ...
61
- [relaton-isbn] (isbn:0120644819) Found: `9780120644810`
62
- => #<RelatonBib::BibliographicItem:0x00000001098ac960
59
+ Relaton::Isbn::OpenLibrary.get "isbn:0120644819"
60
+ [relaton-isbn] INFO: (isbn:0120644819) Fetching from OpenLibrary ...
61
+ [relaton-isbn] INFO: (isbn:0120644819) Found: `9780120644810`
62
+ => #<Relaton::Bib::Bibitem:0x0000000127f11698
63
63
  ...
64
64
  ----
65
65
 
@@ -67,60 +67,39 @@ require 'relaton_isbn'
67
67
  [source,ruby]
68
68
  ----
69
69
  # serialize to XML
70
- > puts bibitem.to_xml
71
- <bibitem id="9780120644810" schema-version="v1.2.7">
72
- <title type="main" format="text/plain">Graphics gems II</title>
73
- <uri type="src">http://openlibrary.org/books/OL21119585M/Graphics_gems_II</uri>
74
- <docidentifier type="ISBN" primary="true">9780120644810</docidentifier>
75
- <date type="published">
76
- <on>1991</on>
77
- </date>
78
- <contributor>
79
- <role type="author"/>
80
- <person>
81
- <name>
82
- <completename>James Arvo</completename>
83
- </name>
84
- </person>
85
- </contributor>
86
- <contributor>
87
- <role type="publisher"/>
88
- <organization>
89
- <name>AP Professional</name>
90
- </organization>
91
- </contributor>
92
- <place>
93
- <city>Boston</city>
94
- </place>
95
- <place>
96
- <city>London</city>
97
- </place>
98
- </bibitem>
70
+ bibitem.to_xml
71
+ => "<bibitem id="9780120644810" schema-version="v1.4.1">
72
+ <fetched>2026-03-04</fetched>
73
+ <title type="main">Graphics gems II</title>
74
+ <uri type="src">http://openlibrary.org/books/OL21119585M/Graphics_gems_II</uri>
75
+ <docidentifier type="ISBN" primary="true">9780120644810</docidentifier>
76
+ ...
77
+ </bibitem>"
99
78
 
100
79
  # serialize to bibdata XML
101
- > puts bibitem.to_xml bibdata: true
102
- <bibdata schema-version="v1.2.7">
103
- <title type="main" format="text/plain">Graphics gems II</title>
104
- ...
80
+ bibitem.to_xml bibdata: true
81
+ => "<bibdata schema-version="v1.4.1">
82
+ <fetched>2026-03-04</fetched>
83
+ <title type="main">Graphics gems II</title>
84
+ <uri type="src">http://openlibrary.org/books/OL21119585M/Graphics_gems_II</uri>
85
+ <docidentifier type="ISBN" primary="true">9780120644810</docidentifier>
86
+ ...
87
+ <ext>
88
+ <flavor>isbn</flavor>
89
+ </ext>
90
+ </bibdata>"
105
91
 
106
92
  # serialize to hash
107
- > bibitem.to_hash
108
- => {"schema-version"=>"v1.2.7",
109
- "id"=>"9780120644810",
110
- "title"=>[{"content"=>"Graphics gems II", "format"=>"text/plain", "type"=>"main"}],
111
- "link"=>[{"content"=>"http://openlibrary.org/books/OL21119585M/Graphics_gems_II", "type"=>"src"}],
112
- "docid"=>[{"id"=>"9780120644810", "type"=>"ISBN", "primary"=>true}],
113
- "date"=>[{"type"=>"published", "value"=>"1991"}],
114
- "contributor"=>
115
- [{"person"=>{"name"=>{"completename"=>{"content"=>"James Arvo"}}, "url"=>"http://openlibrary.org/authors/OL2646519A/James_Arvo"}, "role"=>[{"type"=>"author"}]},
116
- {"organization"=>{"name"=>[{"content"=>"AP Professional"}]}, "role"=>[{"type"=>"publisher"}]}],
117
- "revdate"=>"1991",
118
- "place"=>[{"city"=>"Boston"}, {"city"=>"London"}]}
93
+ puts bibitem.to_yaml
94
+ => "---
95
+ id: '9780120644810'
96
+ schema_version: v1.4.1
97
+ ..."
119
98
  ----
120
99
 
121
100
  === Logging
122
101
 
123
- RelatonIsbn uses the relaton-logger gem for logging. By default, it logs to STDOUT. To change the log levels and add other loggers, read the https://github.com/relaton/relaton-logger#usage[relaton-logger] documentation.
102
+ Relaton::Isbn uses the relaton-logger gem for logging. By default, it logs to STDOUT. To change the log levels and add other loggers, read the https://github.com/relaton/relaton-logger#usage[relaton-logger] documentation.
124
103
 
125
104
  == Development
126
105
 
@@ -0,0 +1,61 @@
1
+ module Relaton
2
+ module Isbn
3
+ class Isbn
4
+ #
5
+ # Create ISBN object.
6
+ #
7
+ # @param [String] isbn ISBN 13 number
8
+ #
9
+ def initialize(isbn)
10
+ @isbn = isbn&.delete("-")&.sub(/^ISBN[\s:]/i, "")
11
+ end
12
+
13
+ def parse
14
+ convert_to13
15
+ end
16
+
17
+ def check?
18
+ case @isbn
19
+ when /^\d{9}[\dX]$/i then check10?
20
+ when /^\d{13}$/ then check13?
21
+ else false
22
+ end
23
+ end
24
+
25
+ def check10?
26
+ @isbn[9] == calc_check_digit10
27
+ end
28
+
29
+ def check13?
30
+ @isbn[12] == calc_check_digit13
31
+ end
32
+
33
+ def calc_check_digit10
34
+ sum = 0
35
+ @isbn[..-2].chars.each_with_index do |c, i|
36
+ sum += c.to_i * (10 - i)
37
+ end
38
+ chk = (11 - sum % 11) % 11
39
+ chk == 10 ? "X" : chk.to_s
40
+ end
41
+
42
+ def calc_check_digit13
43
+ sum = 0
44
+ @isbn[..-2].chars.each_with_index do |c, i|
45
+ sum += c.to_i * (i.even? ? 1 : 3)
46
+ end
47
+ ((10 - sum % 10) % 10).to_s
48
+ end
49
+
50
+ def convert_to13
51
+ return unless check?
52
+
53
+ return @isbn if @isbn.size == 13
54
+
55
+ @isbn = "978#{@isbn}"
56
+ @isbn[12] = calc_check_digit13
57
+ @isbn
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,43 @@
1
+ module Relaton
2
+ module Isbn
3
+ #
4
+ # Search ISBN in Openlibrary.
5
+ #
6
+ module OpenLibrary
7
+ extend self
8
+
9
+ ENDPOINT = "http://openlibrary.org/api/volumes/brief/isbn/".freeze
10
+
11
+ def get(ref, _date = nil, _opts = {}) # rubocop:disable Metrics/MethodLength
12
+ Util.info "Fetching from OpenLibrary ...", key: ref
13
+
14
+ isbn = Isbn.new(ref).parse
15
+ unless isbn
16
+ Util.info "Incorrect ISBN.", key: ref
17
+ return
18
+ end
19
+
20
+ resp = request_api isbn
21
+ unless resp
22
+ Util.info "Not found.", key: ref
23
+ return
24
+ end
25
+
26
+ bib = Parser.parse resp
27
+ Util.info "Found: `#{bib.docidentifier.first.content}`", key: ref
28
+ bib
29
+ end
30
+
31
+ def request_api(isbn)
32
+ uri = URI "#{ENDPOINT}#{isbn}.json"
33
+ response = Net::HTTP.get_response uri
34
+ return unless response.is_a? Net::HTTPSuccess
35
+
36
+ data = JSON.parse response.body
37
+ return unless data["records"]&.any?
38
+
39
+ data["records"].first.last
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,88 @@
1
+ module Relaton
2
+ module Isbn
3
+ #
4
+ # OpenLibrary document parser.
5
+ #
6
+ class Parser
7
+ ATTRS = %i[fetched title docidentifier source contributor date place ext].freeze
8
+
9
+ def initialize(doc)
10
+ @doc = doc
11
+ end
12
+
13
+ def self.parse(doc)
14
+ new(doc).parse
15
+ end
16
+
17
+ def parse
18
+ args = ATTRS.each_with_object({}) { |a, h| h[a] = send(a) }
19
+ Bib::ItemData.new(**args)
20
+ end
21
+
22
+ private
23
+
24
+ def fetched = Date.today.to_s
25
+
26
+ def title
27
+ t = [Bib::Title.new(content: @doc["data"]["title"], type: "main")]
28
+ if @doc["data"]["subtitle"]
29
+ t << Bib::Title.new(content: @doc["data"]["subtitle"], type: "subtitle")
30
+ end
31
+ t
32
+ end
33
+
34
+ def docidentifier
35
+ isbn = @doc["details"]["bib_key"].split(":").last
36
+ [Bib::Docidentifier.new(content: isbn, type: "ISBN", primary: true)]
37
+ end
38
+
39
+ def source
40
+ [Bib::Uri.new(content: @doc["recordURL"], type: "src")]
41
+ end
42
+
43
+ def contributor
44
+ create_authors + creaate_publishers
45
+ end
46
+
47
+ def create_authors
48
+ @doc["data"]["authors"].map do |a|
49
+ name = Bib::FullName.new(
50
+ completename: Bib::LocalizedString.new(content: a["name"]),
51
+ )
52
+ person = Bib::Person.new(
53
+ name: name,
54
+ uri: a["url"] ? [Bib::Uri.new(content: a["url"])] : [],
55
+ )
56
+ Bib::Contributor.new(
57
+ person: person,
58
+ role: [Bib::Contributor::Role.new(type: "author")],
59
+ )
60
+ end
61
+ end
62
+
63
+ def creaate_publishers
64
+ @doc["data"]["publishers"].map do |p|
65
+ org = Bib::Organization.new(
66
+ name: [Bib::TypedLocalizedString.new(content: p["name"])],
67
+ )
68
+ Bib::Contributor.new(
69
+ organization: org,
70
+ role: [Bib::Contributor::Role.new(type: "publisher")],
71
+ )
72
+ end
73
+ end
74
+
75
+ def date
76
+ @doc["publishDates"].map { Bib::Date.new type: "published", at: _1 }
77
+ end
78
+
79
+ def place
80
+ @doc["data"]["publish_places"]&.map { Bib::Place.new city: _1["name"] }
81
+ end
82
+
83
+ def ext
84
+ Bib::Ext.new(flavor: "isbn")
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,48 @@
1
+ require "relaton/core/processor"
2
+
3
+ module Relaton
4
+ module Isbn
5
+ class Processor < Relaton::Core::Processor
6
+ attr_reader :idtype
7
+
8
+ def initialize # rubocop:disable Lint/MissingSuper
9
+ @short = :relaton_isbn
10
+ @prefix = "ISBN"
11
+ @defaultprefix = /^ISBN\s/
12
+ @idtype = "ISBN"
13
+ @datasets = %w[]
14
+ end
15
+
16
+ # @param code [String]
17
+ # @param date [String, nil] year
18
+ # @param opts [Hash]
19
+ # @return [Relaton::Bib::Bibitem]
20
+ def get(code, date, opts)
21
+ require_relative "../isbn"
22
+ ::Relaton::Isbn::OpenLibrary.get(code, date, opts)
23
+ end
24
+
25
+ #
26
+ # @param xml [String]
27
+ # @return [Relaton::Bib::Bibitem]
28
+ def from_xml(xml)
29
+ require_relative "../isbn"
30
+ ::Relaton::Bib::Bibitem.from_xml xml
31
+ end
32
+
33
+ # @param hash [Hash]
34
+ # @return [Relaton::Bib::Bibitem]
35
+ def from_yaml(hash)
36
+ require_relative "../isbn"
37
+ ::Relaton::Bib::Bibitem.from_hash hash
38
+ end
39
+
40
+ # Returns hash of XML grammar
41
+ # @return [String]
42
+ def grammar_hash
43
+ require_relative "../isbn"
44
+ @grammar_hash ||= ::Relaton::Isbn.grammar_hash
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,8 @@
1
+ module Relaton
2
+ module Isbn
3
+ module Util
4
+ extend Relaton::Bib::Util
5
+ PROGNAME = "relaton-isbn".freeze
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,5 @@
1
+ module Relaton
2
+ module Isbn
3
+ VERSION = "2.0.0-alpha.1".freeze
4
+ end
5
+ end
@@ -0,0 +1,19 @@
1
+ require "net/http"
2
+ require "relaton/bib"
3
+ require_relative "isbn/version"
4
+ require_relative "isbn/util"
5
+ require_relative "isbn/isbn"
6
+ require_relative "isbn/parser"
7
+ require_relative "isbn/open_library"
8
+
9
+ module Relaton
10
+ module Isbn
11
+ module_function
12
+
13
+ # Returns hash of XML reammar
14
+ # @return [String]
15
+ def grammar_hash
16
+ Digest::MD5.hexdigest Relaton::Isbn::VERSION + Relaton::Bib::VERSION # grammars
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,6 @@
1
+ module Relaton
2
+ module Isbn
3
+ VERSION: String
4
+ # See the writing guide of rbs: https://github.com/ruby/rbs#guides
5
+ end
6
+ end
metadata CHANGED
@@ -1,30 +1,57 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: relaton-isbn
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.20.1
4
+ version: 2.0.0.pre.alpha.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
- autorequire:
9
8
  bindir: exe
10
9
  cert_chain: []
11
- date: 2025-04-24 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: isoics
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: 0.1.0
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - "~>"
24
+ - !ruby/object:Gem::Version
25
+ version: 0.1.0
13
26
  - !ruby/object:Gem::Dependency
14
27
  name: relaton-bib
15
28
  requirement: !ruby/object:Gem::Requirement
16
29
  requirements:
17
30
  - - "~>"
18
31
  - !ruby/object:Gem::Version
19
- version: 1.20.0
32
+ version: 2.0.0.pre.alpha.4
20
33
  type: :runtime
21
34
  prerelease: false
22
35
  version_requirements: !ruby/object:Gem::Requirement
23
36
  requirements:
24
37
  - - "~>"
25
38
  - !ruby/object:Gem::Version
26
- version: 1.20.0
27
- description: 'RelatonIsbn: retrieve publications by ISBN for bibliographic use using
39
+ version: 2.0.0.pre.alpha.4
40
+ - !ruby/object:Gem::Dependency
41
+ name: relaton-core
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: 0.0.9
47
+ type: :runtime
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: 0.0.9
54
+ description: 'Relaton::Isbn: retrieve publications by ISBN for bibliographic use using
28
55
  the BibliographicItem model'
29
56
  email:
30
57
  - open.source@ribose.com
@@ -32,26 +59,27 @@ executables: []
32
59
  extensions: []
33
60
  extra_rdoc_files: []
34
61
  files:
62
+ - ".claude/settings.local.json"
35
63
  - ".rspec"
36
64
  - ".rubocop.yml"
65
+ - CLAUDE.md
37
66
  - LICENSE.txt
38
67
  - README.adoc
39
68
  - Rakefile
40
- - lib/relaton_isbn.rb
41
- - lib/relaton_isbn/isbn.rb
42
- - lib/relaton_isbn/open_library.rb
43
- - lib/relaton_isbn/parser.rb
44
- - lib/relaton_isbn/processor.rb
45
- - lib/relaton_isbn/util.rb
46
- - lib/relaton_isbn/version.rb
47
- - sig/relaton_isbn.rbs
69
+ - lib/relaton/isbn.rb
70
+ - lib/relaton/isbn/isbn.rb
71
+ - lib/relaton/isbn/open_library.rb
72
+ - lib/relaton/isbn/parser.rb
73
+ - lib/relaton/isbn/processor.rb
74
+ - lib/relaton/isbn/util.rb
75
+ - lib/relaton/isbn/version.rb
76
+ - sig/relaton/isbn.rbs
48
77
  homepage: https://github.com/relaton/relaton-isbn
49
78
  licenses:
50
79
  - MIT
51
80
  metadata:
52
81
  homepage_uri: https://github.com/relaton/relaton-isbn
53
82
  source_code_uri: https://github.com/relaton/relaton-isbn
54
- post_install_message:
55
83
  rdoc_options: []
56
84
  require_paths:
57
85
  - lib
@@ -59,16 +87,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
59
87
  requirements:
60
88
  - - ">="
61
89
  - !ruby/object:Gem::Version
62
- version: 3.1.0
90
+ version: 3.2.0
63
91
  required_rubygems_version: !ruby/object:Gem::Requirement
64
92
  requirements:
65
93
  - - ">="
66
94
  - !ruby/object:Gem::Version
67
95
  version: '0'
68
96
  requirements: []
69
- rubygems_version: 3.5.22
70
- signing_key:
97
+ rubygems_version: 3.6.9
71
98
  specification_version: 4
72
- summary: 'RelatonIsbn: retrieve publications by ISBN for bibliographic use using the
73
- BibliographicItem model'
99
+ summary: 'Relaton::Isbn: retrieve publications by ISBN for bibliographic use using
100
+ the BibliographicItem model'
74
101
  test_files: []
@@ -1,59 +0,0 @@
1
- module RelatonIsbn
2
- class Isbn
3
- #
4
- # Create ISBN object.
5
- #
6
- # @param [String] isbn ISBN 13 number
7
- #
8
- def initialize(isbn)
9
- @isbn = isbn&.delete("-")&.sub(/^ISBN[\s:]/i, "")
10
- end
11
-
12
- def parse
13
- convert_to13
14
- end
15
-
16
- def check?
17
- case @isbn
18
- when /^\d{9}[\dX]$/i then check10?
19
- when /^\d{13}$/ then check13?
20
- else false
21
- end
22
- end
23
-
24
- def check10?
25
- @isbn[9] == calc_check_digit10
26
- end
27
-
28
- def check13?
29
- @isbn[12] == calc_check_digit13
30
- end
31
-
32
- def calc_check_digit10
33
- sum = 0
34
- @isbn[..-2].chars.each_with_index do |c, i|
35
- sum += c.to_i * (10 - i)
36
- end
37
- chk = (11 - sum % 11) % 11
38
- chk == 10 ? "X" : chk.to_s
39
- end
40
-
41
- def calc_check_digit13
42
- sum = 0
43
- @isbn[..-2].chars.each_with_index do |c, i|
44
- sum += c.to_i * (i.even? ? 1 : 3)
45
- end
46
- ((10 - sum % 10) % 10).to_s
47
- end
48
-
49
- def convert_to13
50
- return unless check?
51
-
52
- return @isbn if @isbn.size == 13
53
-
54
- @isbn = "978#{@isbn}"
55
- @isbn[12] = calc_check_digit13
56
- @isbn
57
- end
58
- end
59
- end
@@ -1,41 +0,0 @@
1
- module RelatonIsbn
2
- #
3
- # Search ISBN in Openlibrary.
4
- #
5
- module OpenLibrary
6
- extend self
7
-
8
- ENDPOINT = "http://openlibrary.org/api/volumes/brief/isbn/".freeze
9
-
10
- def get(ref, _date = nil, _opts = {}) # rubocop:disable Metrics/MethodLength
11
- Util.info "Fetching from OpenLibrary ...", key: ref
12
-
13
- isbn = Isbn.new(ref).parse
14
- unless isbn
15
- Util.info "Incorrect ISBN.", key: ref
16
- return
17
- end
18
-
19
- resp = request_api isbn
20
- unless resp
21
- Util.info "Not found.", key: ref
22
- return
23
- end
24
-
25
- bib = Parser.parse resp
26
- Util.info "Found: `#{bib.docidentifier.first.id}`", key: ref
27
- bib
28
- end
29
-
30
- def request_api(isbn)
31
- uri = URI "#{ENDPOINT}#{isbn}.json"
32
- response = Net::HTTP.get_response uri
33
- return unless response.is_a? Net::HTTPSuccess
34
-
35
- data = JSON.parse response.body
36
- return unless data["records"]&.any?
37
-
38
- data["records"].first.last
39
- end
40
- end
41
- end
@@ -1,69 +0,0 @@
1
- module RelatonIsbn
2
- #
3
- # OpenLibrary document parser.
4
- #
5
- class Parser
6
- ATTRS = %i[fetched title docid link contributor date place].freeze
7
-
8
- def initialize(doc)
9
- @doc = doc
10
- end
11
-
12
- def self.parse(doc)
13
- new(doc).parse
14
- end
15
-
16
- def parse
17
- args = ATTRS.each_with_object({}) { |a, h| h[a] = send(a) }
18
- RelatonBib::BibliographicItem.new(**args)
19
- end
20
-
21
- private
22
-
23
- def fetched = Date.today.to_s
24
-
25
- def title
26
- t = [RelatonBib::TypedTitleString.new(content: @doc["data"]["title"], type: "main")]
27
- if @doc["data"]["subtitle"]
28
- t << RelatonBib::TypedTitleString.new(content: @doc["data"]["subtitle"], type: "subtitle")
29
- end
30
- t
31
- end
32
-
33
- def docid
34
- isbn = @doc["details"]["bib_key"].split(":").last
35
- [RelatonBib::DocumentIdentifier.new(id: isbn, type: "ISBN", primary: true)]
36
- end
37
-
38
- def link
39
- [RelatonBib::TypedUri.new(content: @doc["recordURL"], type: "src")]
40
- end
41
-
42
- def contributor
43
- create_authors + creaate_publishers
44
- end
45
-
46
- def create_authors
47
- @doc["data"]["authors"].map do |a|
48
- name = RelatonBib::FullName.new completename: RelatonBib::LocalizedString.new(a["name"])
49
- entity = RelatonBib::Person.new name: name, url: a["url"]
50
- RelatonBib::ContributionInfo.new entity: entity, role: [{ type: "author" }]
51
- end
52
- end
53
-
54
- def creaate_publishers
55
- @doc["data"]["publishers"].map do |p|
56
- entity = RelatonBib::Organization.new name: RelatonBib::LocalizedString.new(p["name"])
57
- RelatonBib::ContributionInfo.new entity: entity, role: [{ type: "publisher" }]
58
- end
59
- end
60
-
61
- def date
62
- @doc["publishDates"].map { RelatonBib::BibliographicDate.new type: "published", on: _1 }
63
- end
64
-
65
- def place
66
- @doc["data"]["publish_places"]&.map { RelatonBib::Place.new city: _1["name"] }
67
- end
68
- end
69
- end
@@ -1,58 +0,0 @@
1
- require "relaton/processor"
2
-
3
- module RelatonIsbn
4
- class Processor < Relaton::Processor
5
- attr_reader :idtype
6
-
7
- def initialize # rubocop:disable Lint/MissingSuper
8
- @short = :relaton_isbn
9
- @prefix = "ISBN"
10
- @defaultprefix = /^ISBN\s/
11
- @idtype = "ISBN"
12
- @datasets = %w[]
13
- end
14
-
15
- # @param code [String]
16
- # @param date [String, nil] year
17
- # @param opts [Hash]
18
- # @return [RelatonBib::BibliographicItem]
19
- def get(code, date, opts)
20
- ::RelatonIsbn::OpenLibrary.get(code, date, opts)
21
- end
22
-
23
- #
24
- # @param [String] source source name (bipm-data-outcomes, bipm-si-brochure,
25
- # rawdata-bipm-metrologia)
26
- # @param [Hash] opts
27
- # @option opts [String] :output directory to output documents
28
- # @option opts [String] :format
29
- #
30
- # def fetch_data(source, opts)
31
- # DataFetcher.fetch(source, **opts)
32
- # end
33
-
34
- # @param xml [String]
35
- # @return [RelatonBib::BibliographicItem]
36
- def from_xml(xml)
37
- ::RelatonBib::XMLParser.from_xml xml
38
- end
39
-
40
- # @param hash [Hash]
41
- # @return [RelatonBib::BibliographicItem]
42
- def hash_to_bib(hash)
43
- ::RelatonBib::BibliographicItem.from_hash hash
44
- end
45
-
46
- # Returns hash of XML grammar
47
- # @return [String]
48
- def grammar_hash
49
- @grammar_hash ||= ::RelatonIsbn.grammar_hash
50
- end
51
-
52
- #
53
- # Remove index file
54
- #
55
- # def remove_index_file
56
- # end
57
- end
58
- end
@@ -1,6 +0,0 @@
1
- module RelatonIsbn
2
- module Util
3
- extend RelatonBib::Util
4
- PROGNAME = "relaton-isbn".freeze
5
- end
6
- end
@@ -1,3 +0,0 @@
1
- module RelatonIsbn
2
- VERSION = "1.20.1".freeze
3
- end
data/lib/relaton_isbn.rb DELETED
@@ -1,17 +0,0 @@
1
- require "net/http"
2
- require "relaton_bib"
3
- require_relative "relaton_isbn/version"
4
- require_relative "relaton_isbn/util"
5
- require_relative "relaton_isbn/isbn"
6
- require_relative "relaton_isbn/parser"
7
- require_relative "relaton_isbn/open_library"
8
-
9
- module RelatonIsbn
10
- module_function
11
-
12
- # Returns hash of XML reammar
13
- # @return [String]
14
- def grammar_hash
15
- Digest::MD5.hexdigest RelatonIsbn::VERSION + RelatonBib::VERSION # grammars
16
- end
17
- end
data/sig/relaton_isbn.rbs DELETED
@@ -1,4 +0,0 @@
1
- module RelatonIsbn
2
- VERSION: String
3
- # See the writing guide of rbs: https://github.com/ruby/rbs#guides
4
- end