relaton-xsf 1.20.0 → 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 +4 -4
- data/.rubocop.yml +1 -1
- data/CLAUDE.md +58 -0
- data/README.adoc +36 -28
- data/lib/relaton/xsf/bibdata.rb +7 -0
- data/lib/relaton/xsf/bibitem.rb +7 -0
- data/lib/relaton/xsf/bibliography.rb +24 -0
- data/lib/relaton/xsf/data_fetcher.rb +56 -0
- data/lib/relaton/xsf/hit.rb +17 -0
- data/lib/relaton/xsf/hit_collection.rb +24 -0
- data/lib/relaton/xsf/item.rb +7 -0
- data/lib/relaton/xsf/processor.rb +50 -0
- data/lib/relaton/xsf/util.rb +9 -0
- data/lib/relaton/xsf/version.rb +7 -0
- data/lib/relaton/xsf.rb +29 -0
- metadata +35 -24
- data/lib/relaton_xsf/bibliographic_item.rb +0 -4
- data/lib/relaton_xsf/bibliography.rb +0 -22
- data/lib/relaton_xsf/bibxml_parser.rb +0 -12
- data/lib/relaton_xsf/data_fetcher.rb +0 -57
- data/lib/relaton_xsf/hash_converter.rb +0 -11
- data/lib/relaton_xsf/hit.rb +0 -15
- data/lib/relaton_xsf/hit_collection.rb +0 -19
- data/lib/relaton_xsf/processor.rb +0 -61
- data/lib/relaton_xsf/util.rb +0 -6
- data/lib/relaton_xsf/version.rb +0 -5
- data/lib/relaton_xsf/xml_parser.rb +0 -14
- data/lib/relaton_xsf.rb +0 -20
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f37b079bdc2af9ac10f413caecc791b69360a948628e0bdbf11a19e32648f53b
|
|
4
|
+
data.tar.gz: c2d4606232e12b41bd8b6673f0ae67ff101b37487ecb1e36247ed0521f66d8bc
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4f35da54cefed765b7b810959bbbb44ae982b89eed78516f17822090f6ac00a7767ab8dbb3707de3553e7d92e7fa034441a930eec7db0fc9a887e1cb4bb29f55
|
|
7
|
+
data.tar.gz: 32607532cadab4c5be0a4d391502e5c2b0621ae1c4f3787ab95d4096de2ff5d91a181cf62f7cd88a8de90372a0ae221651398448f4790ce75f23f12db2ec1576
|
data/.rubocop.yml
CHANGED
data/CLAUDE.md
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
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 is relaton-xsf?
|
|
6
|
+
|
|
7
|
+
A Ruby gem for bibliographic retrieval of XMPP XEP (XMPP Extension Protocol) specifications. Part of the Relaton family of gems. Fetches data from https://xmpp.org/extensions/refs/ and the relaton-data-xsf GitHub repository.
|
|
8
|
+
|
|
9
|
+
## Commands
|
|
10
|
+
|
|
11
|
+
- `bundle exec rspec` — run all tests
|
|
12
|
+
- `bundle exec rspec spec/relaton/xsf/processor_spec.rb` — run a single spec file
|
|
13
|
+
- `bundle exec rubocop` — lint
|
|
14
|
+
- `bundle exec rubocop -a` — lint with auto-fix
|
|
15
|
+
- `bin/console` — interactive console with gem loaded
|
|
16
|
+
|
|
17
|
+
## Architecture
|
|
18
|
+
|
|
19
|
+
Namespace: `Relaton::Xsf` (under `lib/relaton/xsf/`). Branch `lutaml-integration` uses the new nested namespace (not the old `RelatonXsf`).
|
|
20
|
+
|
|
21
|
+
Key classes and their base classes from relaton-core:
|
|
22
|
+
|
|
23
|
+
| Class | Base | Role |
|
|
24
|
+
|---|---|---|
|
|
25
|
+
| `Processor` | `Relaton::Core::Processor` | Plugin entry point for relaton registry |
|
|
26
|
+
| `Bibliography` | Module (extends self) | Search & get interface (`search`, `get`) |
|
|
27
|
+
| `HitCollection` | `Relaton::Core::HitCollection` | Collection of search results |
|
|
28
|
+
| `Hit` | `Relaton::Core::Hit` | Single result; lazy-loads YAML from GitHub |
|
|
29
|
+
| `DataFetcher` | `Relaton::Core::DataFetcher` | Crawls xmpp.org, parses BibXML, saves docs |
|
|
30
|
+
| `Item` / `Bibitem` / `Bibdata` | `Relaton::Bib::Item` | Bibliographic item models (lutaml-model based) |
|
|
31
|
+
|
|
32
|
+
Data flow: `Processor#get` → `Bibliography.get` → `HitCollection.search` → `Hit#item` → fetches YAML → `Relaton::Bib::Item.from_yaml`
|
|
33
|
+
|
|
34
|
+
DataFetcher flow: Crawls `https://xmpp.org/extensions/refs/`, parses each XML ref via `Relaton::Bib::Converter::BibXml.to_item`, sets `ext.flavor = "xsf"`, saves to disk.
|
|
35
|
+
|
|
36
|
+
Constants: `INDEXFILE = "index-v1"`, `GHDATA_URL` points to relaton-data-xsf `data-v2` branch.
|
|
37
|
+
|
|
38
|
+
## Testing
|
|
39
|
+
|
|
40
|
+
- RSpec with VCR cassettes (`spec/vcr_cassettes/`) for HTTP interactions
|
|
41
|
+
- WebMock disables all external network connections
|
|
42
|
+
- Fixtures in `spec/fixtures/` (item.yaml, bibdata.xml, bibitem.xml)
|
|
43
|
+
- Round-trip tests verify YAML→Item→YAML and XML→Item→XML fidelity
|
|
44
|
+
- `DataFetcher` is lazily required — specs that test it must `require "relaton/xsf/data_fetcher"` explicitly
|
|
45
|
+
- Same for `Processor` — `require "relaton/xsf/processor"`
|
|
46
|
+
|
|
47
|
+
## Key dependencies
|
|
48
|
+
|
|
49
|
+
- `relaton-core` — abstract base classes (Processor, HitCollection, Hit, DataFetcher)
|
|
50
|
+
- `relaton-bib` — bibliographic models, XML/YAML serialization (lutaml-model based)
|
|
51
|
+
- `relaton-index` — index management for quick document lookups
|
|
52
|
+
- `mechanize` — HTTP fetching and HTML parsing
|
|
53
|
+
|
|
54
|
+
## Style
|
|
55
|
+
|
|
56
|
+
- RuboCop with relaton shared config (inherits from riboseinc/oss-guides)
|
|
57
|
+
- Target Ruby version: 3.1
|
|
58
|
+
- Logging via `Relaton::Xsf::Util` (extends `Relaton::Bib::Util`, PROGNAME = "relaton-xsf")
|
data/README.adoc
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
= Relaton
|
|
1
|
+
= Relaton::XSF: bibliographic retrieval of XMPP XEP specifications
|
|
2
2
|
|
|
3
3
|
image:https://img.shields.io/gem/v/relaton-xsf.svg["Gem Version", link="https://rubygems.org/gems/relaton-xsf"]
|
|
4
4
|
image:https://github.com/relaton/relaton-xsf/workflows/macos/badge.svg["Build Status (macOS)", link="https://github.com/relaton/relaton-xsf/actions?workflow=macos"]
|
|
@@ -42,14 +42,14 @@ Or install it yourself as:
|
|
|
42
42
|
|
|
43
43
|
[source,ruby]
|
|
44
44
|
----
|
|
45
|
-
require '
|
|
45
|
+
require 'relaton/xsf'
|
|
46
46
|
=> true
|
|
47
47
|
|
|
48
|
-
hit_collection =
|
|
49
|
-
=> <
|
|
48
|
+
hit_collection = Relaton::Xsf::Bibliography.search("XEP 0001")
|
|
49
|
+
=> <Relaton::Xsf::HitCollection:0x000000000013c0 @ref=XEP 0001 @fetched=false>
|
|
50
50
|
|
|
51
|
-
item = hit_collection[0].
|
|
52
|
-
=> #<
|
|
51
|
+
item = hit_collection[0].item
|
|
52
|
+
=> #<Relaton::Bib::ItemData:0x0000000124d510b8
|
|
53
53
|
...
|
|
54
54
|
----
|
|
55
55
|
|
|
@@ -57,9 +57,12 @@ item = hit_collection[0].fetch
|
|
|
57
57
|
[source,ruby]
|
|
58
58
|
----
|
|
59
59
|
item.to_xml
|
|
60
|
-
=> "<bibitem id="XEP0001" type="standard" schema-version="v1.
|
|
61
|
-
<fetched>
|
|
62
|
-
<title
|
|
60
|
+
=> "<bibitem id="XEP0001" type="standard" schema-version="v1.4.1">
|
|
61
|
+
<fetched>2026-03-04</fetched>
|
|
62
|
+
<title language="en" script="Latn">XMPP Extension Protocols</title>
|
|
63
|
+
<uri type="src">http://xmpp.org/extensions/xep-0001.html</uri>
|
|
64
|
+
<uri type="HTML">http://xmpp.org/extensions/xep-0001.html</uri>
|
|
65
|
+
<docidentifier type="XEP" primary="true">XEP 0001</docidentifier>
|
|
63
66
|
...
|
|
64
67
|
<bibitem>"
|
|
65
68
|
----
|
|
@@ -67,12 +70,16 @@ With argument `bibdata: true` it outputs XML wrapped by `bibdata` element and ad
|
|
|
67
70
|
[source,ruby]
|
|
68
71
|
----
|
|
69
72
|
item.to_xml bibdata: true
|
|
70
|
-
=> "<bibdata type="standard" schema-version="v1.
|
|
71
|
-
<fetched>
|
|
72
|
-
<title
|
|
73
|
+
=> "<bibdata type="standard" schema-version="v1.4.1">
|
|
74
|
+
<fetched>2026-03-04</fetched>
|
|
75
|
+
<title language="en" script="Latn">XMPP Extension Protocols</title>
|
|
76
|
+
<uri type="src">http://xmpp.org/extensions/xep-0001.html</uri>
|
|
77
|
+
<uri type="HTML">http://xmpp.org/extensions/xep-0001.html</uri>
|
|
78
|
+
<docidentifier type="XEP" primary="true">XEP 0001</docidentifier>
|
|
73
79
|
...
|
|
74
80
|
<ext>
|
|
75
81
|
<doctype>rfc</doctype>
|
|
82
|
+
<flavor>xsf</flavor>
|
|
76
83
|
</ext>
|
|
77
84
|
</bibdata>"
|
|
78
85
|
----
|
|
@@ -80,35 +87,34 @@ item.to_xml bibdata: true
|
|
|
80
87
|
=== Get document by reference
|
|
81
88
|
[source,ruby]
|
|
82
89
|
----
|
|
83
|
-
item =
|
|
84
|
-
[relaton-xsf] (XEP 0001) Fetching from Relaton repository ...
|
|
85
|
-
[relaton-xsf] (XEP 0001) Found `XEP 0001`
|
|
86
|
-
=> #<
|
|
90
|
+
item = Relaton::Xsf::Bibliography.get "XEP 0001"
|
|
91
|
+
[relaton-xsf] INFO: (XEP 0001) Fetching from Relaton repository ...
|
|
92
|
+
[relaton-xsf] INFO: (XEP 0001) Found: `XEP 0001`
|
|
93
|
+
=> #<Relaton::Bib::ItemData:0x0000000125036f58
|
|
87
94
|
...
|
|
88
95
|
|
|
89
|
-
item.docidentifier.first.
|
|
96
|
+
item.docidentifier.first.content
|
|
90
97
|
=> "XEP 0001"
|
|
91
98
|
----
|
|
92
99
|
|
|
93
|
-
=== Typed links
|
|
100
|
+
=== Typed source links
|
|
94
101
|
|
|
95
|
-
XSF publications have `src` type link.
|
|
102
|
+
XSF publications have `src` type source link.
|
|
96
103
|
|
|
97
104
|
[source,ruby]
|
|
98
105
|
----
|
|
99
|
-
item.
|
|
100
|
-
=>
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
@type="src">]
|
|
106
|
+
item.source[0].type
|
|
107
|
+
=> "src"
|
|
108
|
+
|
|
109
|
+
item.source[0].content
|
|
110
|
+
=> "http://xmpp.org/extensions/xep-0001.html"
|
|
105
111
|
----
|
|
106
112
|
|
|
107
113
|
=== Fetch data
|
|
108
114
|
|
|
109
115
|
This gem uses the https://xmpp.org/extensions/refs/ dataset as a data source.
|
|
110
116
|
|
|
111
|
-
The method `
|
|
117
|
+
The method `Relaton::Xsf::DataFetcher.fetch(output: "data", format: "yaml")` fetches all the documents from the dataset and saves them to the `./data` folder in YAML format.
|
|
112
118
|
Arguments:
|
|
113
119
|
|
|
114
120
|
- `output` - folder to save documents (default './data').
|
|
@@ -116,7 +122,9 @@ Arguments:
|
|
|
116
122
|
|
|
117
123
|
[source,ruby]
|
|
118
124
|
----
|
|
119
|
-
|
|
125
|
+
require 'relaton/xsf/data_fetcher'
|
|
126
|
+
|
|
127
|
+
Relaton::Xsf::DataFetcher.fetch
|
|
120
128
|
Started at: 2021-09-01 18:01:01 +0200
|
|
121
129
|
Stopped at: 2021-09-01 18:01:43 +0200
|
|
122
130
|
Done in: 42 sec.
|
|
@@ -125,7 +133,7 @@ Done in: 42 sec.
|
|
|
125
133
|
|
|
126
134
|
=== Logging
|
|
127
135
|
|
|
128
|
-
|
|
136
|
+
Relaton::Xsf 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.
|
|
129
137
|
|
|
130
138
|
== Development
|
|
131
139
|
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module Relaton
|
|
2
|
+
module Xsf
|
|
3
|
+
module Bibliography
|
|
4
|
+
extend self
|
|
5
|
+
|
|
6
|
+
def search(ref)
|
|
7
|
+
HitCollection.new(ref).search
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def get(code, _year = nil, _opts = {})
|
|
11
|
+
Util.info "Fetching from Relaton repository ...", key: code
|
|
12
|
+
result = search(code)
|
|
13
|
+
if result.empty?
|
|
14
|
+
Util.info "Not found.", key: code
|
|
15
|
+
return
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
bib = result.first.item
|
|
19
|
+
Util.info "Found: `#{bib.docidentifier.first.content}`", key: code
|
|
20
|
+
bib
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
require "relaton/core"
|
|
2
|
+
|
|
3
|
+
module Relaton
|
|
4
|
+
module Xsf
|
|
5
|
+
class DataFetcher < Relaton::Core::DataFetcher
|
|
6
|
+
def index
|
|
7
|
+
@index ||= Relaton::Index.find_or_create :xsf, file: "#{INDEXFILE}.yaml"
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def fetch(_source = nil)
|
|
11
|
+
agent = Mechanize.new
|
|
12
|
+
resp = agent.get "https://xmpp.org/extensions/refs/"
|
|
13
|
+
resp.xpath("//a[contains(@href, 'XEP-')]").each do |link|
|
|
14
|
+
doc = agent.get link[:href]
|
|
15
|
+
bib = Relaton::Bib::Converter::BibXml.to_item doc.body
|
|
16
|
+
save_doc bib
|
|
17
|
+
rescue StandardError => e
|
|
18
|
+
Util.warn "Failed to parse #{link[:href]}: #{e.message}"
|
|
19
|
+
end
|
|
20
|
+
index.save
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def save_doc(bib)
|
|
24
|
+
return unless bib
|
|
25
|
+
|
|
26
|
+
bib.ext ||= Relaton::Bib::Ext.new
|
|
27
|
+
bib.ext.flavor = "xsf"
|
|
28
|
+
|
|
29
|
+
docid = bib.docidentifier.detect(&:primary) || bib.docidentifier.first
|
|
30
|
+
id = docid&.content
|
|
31
|
+
return unless id
|
|
32
|
+
|
|
33
|
+
file = output_file id
|
|
34
|
+
if @files.include? file
|
|
35
|
+
Util.warn "File #{file} already exists"
|
|
36
|
+
else
|
|
37
|
+
@files << file
|
|
38
|
+
end
|
|
39
|
+
File.write file, serialize(bib), encoding: "UTF-8"
|
|
40
|
+
index.add_or_update id, file
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def to_yaml(bib)
|
|
44
|
+
bib.to_yaml
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def to_xml(bib)
|
|
48
|
+
bib.to_xml bibdata: true
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def to_bibxml(bib)
|
|
52
|
+
bib.to_rfcxml
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module Relaton
|
|
2
|
+
module Xsf
|
|
3
|
+
class Hit < Relaton::Core::Hit
|
|
4
|
+
def item
|
|
5
|
+
return @doc if @doc
|
|
6
|
+
|
|
7
|
+
agent = Mechanize.new
|
|
8
|
+
resp = agent.get hit[:url]
|
|
9
|
+
hash = YAML.safe_load resp.body
|
|
10
|
+
hash["fetched"] = Date.today.to_s
|
|
11
|
+
@doc = Relaton::Bib::Item.from_yaml hash.to_yaml
|
|
12
|
+
rescue StandardError => e
|
|
13
|
+
raise Relaton::RequestError, e.message
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module Relaton
|
|
2
|
+
module Xsf
|
|
3
|
+
class HitCollection < Relaton::Core::HitCollection
|
|
4
|
+
GHDATA_URL = "https://raw.githubusercontent.com/relaton/relaton-data-xsf/data-v2/".freeze
|
|
5
|
+
|
|
6
|
+
def search
|
|
7
|
+
@array = index.search(ref).sort_by { |hit| hit[:id] }.map do |row|
|
|
8
|
+
Hit.new url: "#{GHDATA_URL}#{row[:file]}"
|
|
9
|
+
end
|
|
10
|
+
self
|
|
11
|
+
rescue StandardError => e
|
|
12
|
+
raise Relaton::RequestError, e.message
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def index
|
|
16
|
+
@index ||= Relaton::Index.find_or_create(
|
|
17
|
+
:xsf,
|
|
18
|
+
url: "#{GHDATA_URL}#{INDEXFILE}.zip",
|
|
19
|
+
file: "#{INDEXFILE}.yaml",
|
|
20
|
+
)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
require "relaton/core/processor"
|
|
3
|
+
|
|
4
|
+
module Relaton
|
|
5
|
+
module Xsf
|
|
6
|
+
class Processor < Relaton::Core::Processor
|
|
7
|
+
attr_reader :idtype
|
|
8
|
+
|
|
9
|
+
def initialize # rubocop:disable Lint/MissingSuper
|
|
10
|
+
@short = :relaton_xsf
|
|
11
|
+
@prefix = "XEP"
|
|
12
|
+
@defaultprefix = %r{^XEP\s}
|
|
13
|
+
@idtype = "XEP"
|
|
14
|
+
@datasets = %w[xep-xmpp]
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def get(code, date, opts)
|
|
18
|
+
require_relative "../xsf"
|
|
19
|
+
Relaton::Xsf::Bibliography.get(code, date, opts)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def fetch_data(_source, opts)
|
|
23
|
+
require_relative "data_fetcher"
|
|
24
|
+
Relaton::Xsf::DataFetcher.fetch(**opts)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def from_xml(xml)
|
|
28
|
+
require_relative "../xsf"
|
|
29
|
+
Relaton::Bib::Item.from_xml(xml)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def from_yaml(yaml)
|
|
33
|
+
require_relative "../xsf"
|
|
34
|
+
Relaton::Bib::Item.from_yaml(yaml)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def grammar_hash
|
|
38
|
+
require_relative "../xsf"
|
|
39
|
+
Relaton::Xsf.grammar_hash
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def remove_index_file
|
|
43
|
+
require_relative "../xsf"
|
|
44
|
+
Relaton::Index.find_or_create(
|
|
45
|
+
:xsf, url: true, file: "#{INDEXFILE}.yaml"
|
|
46
|
+
).remove_file
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
data/lib/relaton/xsf.rb
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "mechanize"
|
|
4
|
+
require "relaton/index"
|
|
5
|
+
require "relaton/bib"
|
|
6
|
+
require_relative "xsf/version"
|
|
7
|
+
require_relative "xsf/util"
|
|
8
|
+
require_relative "xsf/item"
|
|
9
|
+
require_relative "xsf/bibitem"
|
|
10
|
+
require_relative "xsf/bibdata"
|
|
11
|
+
require_relative "xsf/hit"
|
|
12
|
+
require_relative "xsf/hit_collection"
|
|
13
|
+
require_relative "xsf/bibliography"
|
|
14
|
+
|
|
15
|
+
module Relaton
|
|
16
|
+
module Xsf
|
|
17
|
+
INDEXFILE = "index-v1"
|
|
18
|
+
|
|
19
|
+
class Error < StandardError; end
|
|
20
|
+
|
|
21
|
+
# Your code goes here...
|
|
22
|
+
def self.grammar_hash
|
|
23
|
+
# gem_path = File.expand_path "..", __dir__
|
|
24
|
+
# grammars_path = File.join gem_path, "grammars", "*"
|
|
25
|
+
# grammars = Dir[grammars_path].sort.map { |gp| File.read gp }.join
|
|
26
|
+
Digest::MD5.hexdigest Relaton::Bib::VERSION # grammars
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: relaton-xsf
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
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:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: mechanize
|
|
@@ -30,14 +29,28 @@ dependencies:
|
|
|
30
29
|
requirements:
|
|
31
30
|
- - "~>"
|
|
32
31
|
- !ruby/object:Gem::Version
|
|
33
|
-
version:
|
|
32
|
+
version: 2.0.0.pre.alpha.4
|
|
34
33
|
type: :runtime
|
|
35
34
|
prerelease: false
|
|
36
35
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
36
|
requirements:
|
|
38
37
|
- - "~>"
|
|
39
38
|
- !ruby/object:Gem::Version
|
|
40
|
-
version:
|
|
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
|
|
41
54
|
- !ruby/object:Gem::Dependency
|
|
42
55
|
name: relaton-index
|
|
43
56
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -52,8 +65,8 @@ dependencies:
|
|
|
52
65
|
- - "~>"
|
|
53
66
|
- !ruby/object:Gem::Version
|
|
54
67
|
version: 0.2.0
|
|
55
|
-
description: '
|
|
56
|
-
model'
|
|
68
|
+
description: 'Relaton::Xsf: retrieve ISO Standards for bibliographic use using the
|
|
69
|
+
IsoBibliographicItem model'
|
|
57
70
|
email:
|
|
58
71
|
- open.source@ribose.com
|
|
59
72
|
executables: []
|
|
@@ -62,29 +75,28 @@ extra_rdoc_files: []
|
|
|
62
75
|
files:
|
|
63
76
|
- ".rspec"
|
|
64
77
|
- ".rubocop.yml"
|
|
78
|
+
- CLAUDE.md
|
|
65
79
|
- Gemfile
|
|
66
80
|
- LICENSE.txt
|
|
67
81
|
- README.adoc
|
|
68
82
|
- Rakefile
|
|
69
|
-
- lib/
|
|
70
|
-
- lib/
|
|
71
|
-
- lib/
|
|
72
|
-
- lib/
|
|
73
|
-
- lib/
|
|
74
|
-
- lib/
|
|
75
|
-
- lib/
|
|
76
|
-
- lib/
|
|
77
|
-
- lib/
|
|
78
|
-
- lib/
|
|
79
|
-
- lib/
|
|
80
|
-
- lib/relaton_xsf/xml_parser.rb
|
|
83
|
+
- lib/relaton/xsf.rb
|
|
84
|
+
- lib/relaton/xsf/bibdata.rb
|
|
85
|
+
- lib/relaton/xsf/bibitem.rb
|
|
86
|
+
- lib/relaton/xsf/bibliography.rb
|
|
87
|
+
- lib/relaton/xsf/data_fetcher.rb
|
|
88
|
+
- lib/relaton/xsf/hit.rb
|
|
89
|
+
- lib/relaton/xsf/hit_collection.rb
|
|
90
|
+
- lib/relaton/xsf/item.rb
|
|
91
|
+
- lib/relaton/xsf/processor.rb
|
|
92
|
+
- lib/relaton/xsf/util.rb
|
|
93
|
+
- lib/relaton/xsf/version.rb
|
|
81
94
|
- sig/relaton_xsf.rbs
|
|
82
95
|
homepage: https://github.com/relaton/relaton-xsf
|
|
83
96
|
licenses:
|
|
84
97
|
- BSD-2-Clause
|
|
85
98
|
metadata:
|
|
86
99
|
homepage_uri: https://github.com/relaton/relaton-xsf
|
|
87
|
-
post_install_message:
|
|
88
100
|
rdoc_options: []
|
|
89
101
|
require_paths:
|
|
90
102
|
- lib
|
|
@@ -92,16 +104,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
92
104
|
requirements:
|
|
93
105
|
- - ">="
|
|
94
106
|
- !ruby/object:Gem::Version
|
|
95
|
-
version: 2.
|
|
107
|
+
version: 3.2.0
|
|
96
108
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
97
109
|
requirements:
|
|
98
110
|
- - ">="
|
|
99
111
|
- !ruby/object:Gem::Version
|
|
100
112
|
version: '0'
|
|
101
113
|
requirements: []
|
|
102
|
-
rubygems_version: 3.
|
|
103
|
-
signing_key:
|
|
114
|
+
rubygems_version: 3.6.9
|
|
104
115
|
specification_version: 4
|
|
105
|
-
summary: '
|
|
116
|
+
summary: 'Relaton::Xsf: retrieve ISO Standards for bibliographic use using the IsoBibliographicItem
|
|
106
117
|
model'
|
|
107
118
|
test_files: []
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
module RelatonXsf
|
|
2
|
-
module Bibliography
|
|
3
|
-
extend self
|
|
4
|
-
|
|
5
|
-
def search(ref)
|
|
6
|
-
HitCollection.new(ref).search
|
|
7
|
-
end
|
|
8
|
-
|
|
9
|
-
def get(code, _year = nil, _opts = {})
|
|
10
|
-
Util.info "Fetching from Relaton repository ...", key: code
|
|
11
|
-
result = search(code)
|
|
12
|
-
if result.empty?
|
|
13
|
-
Util.info "Not found.", key: code
|
|
14
|
-
return
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
bib = result.first.fetch
|
|
18
|
-
Util.info "Found: `#{bib.docidentifier.first.id}`", key: code
|
|
19
|
-
bib
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
end
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
module RelatonXsf
|
|
2
|
-
class DataFetcher
|
|
3
|
-
# @param output [String]
|
|
4
|
-
# @param format [String]
|
|
5
|
-
def initialize(output, format)
|
|
6
|
-
@output = output
|
|
7
|
-
@format = format
|
|
8
|
-
@ext = format.sub(/^bib/, "")
|
|
9
|
-
@files = []
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
def self.fetch(output: "data", format: "yaml")
|
|
13
|
-
warn "fetching data to #{output} in #{format} format"
|
|
14
|
-
t1 = Time.now
|
|
15
|
-
warn "start at #{t1}"
|
|
16
|
-
FileUtils.mkdir_p output
|
|
17
|
-
new(output, format).fetch
|
|
18
|
-
t2 = Time.now
|
|
19
|
-
t = t2 - t1
|
|
20
|
-
warn "finished at #{t2} (#{t.round} seconds)"
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
def index
|
|
24
|
-
@index ||= Relaton::Index.find_or_create :xsf, file: "index-v1.yaml"
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
def fetch
|
|
28
|
-
agent = Mechanize.new
|
|
29
|
-
resp = agent.get "https://xmpp.org/extensions/refs/"
|
|
30
|
-
resp.xpath("//a[contains(@href, 'XEP-')]").each do |link|
|
|
31
|
-
doc = agent.get link[:href]
|
|
32
|
-
bib = BibXMLParser.parse doc.body
|
|
33
|
-
write_doc bib
|
|
34
|
-
end
|
|
35
|
-
index.save
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
def write_doc(bib)
|
|
39
|
-
id = bib.docidentifier.find(&:primary).id
|
|
40
|
-
file = File.join @output, "#{id.gsub(' ', '-').downcase}.#{@ext}"
|
|
41
|
-
if @files.include? file
|
|
42
|
-
Util.warn "#{file} already exists"
|
|
43
|
-
end
|
|
44
|
-
File.write file, serialize(bib), encoding: "UTF-8"
|
|
45
|
-
@files << file
|
|
46
|
-
index.add_or_update id, file
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
def serialize(bib)
|
|
50
|
-
case @format
|
|
51
|
-
when "yaml" then bib.to_hash.to_yaml
|
|
52
|
-
when "xml" then bib.to_xml bibdata: true
|
|
53
|
-
else bib.send "to_#{@format}"
|
|
54
|
-
end
|
|
55
|
-
end
|
|
56
|
-
end
|
|
57
|
-
end
|
data/lib/relaton_xsf/hit.rb
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
module RelatonXsf
|
|
2
|
-
class Hit < RelatonBib::Hit
|
|
3
|
-
def fetch
|
|
4
|
-
return @doc if @doc
|
|
5
|
-
|
|
6
|
-
agent = Mechanize.new
|
|
7
|
-
resp = agent.get hit[:url]
|
|
8
|
-
hash = YAML.safe_load resp.body
|
|
9
|
-
hash["fetched"] = Date.today.to_s
|
|
10
|
-
@doc = BibliographicItem.from_hash hash
|
|
11
|
-
rescue StandardError => e
|
|
12
|
-
raise RelatonBib::RequestError, e.message
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
end
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
module RelatonXsf
|
|
2
|
-
class HitCollection < RelatonBib::HitCollection
|
|
3
|
-
INDEX_FILE = "index-v1.yaml".freeze
|
|
4
|
-
GHDATA_URL = "https://raw.githubusercontent.com/relaton/relaton-data-xsf/main/".freeze
|
|
5
|
-
|
|
6
|
-
def search
|
|
7
|
-
@array = index.search(text).sort_by { |hit| hit[:id] }.map do |row|
|
|
8
|
-
Hit.new url: "#{GHDATA_URL}#{row[:file]}"
|
|
9
|
-
end
|
|
10
|
-
self
|
|
11
|
-
rescue StandardError => e
|
|
12
|
-
raise RelatonBib::RequestError, e.message
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def index
|
|
16
|
-
@index ||= Relaton::Index.find_or_create :xsf, url: "#{GHDATA_URL}index-v1.zip", file: INDEX_FILE
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
end
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
require "relaton/processor"
|
|
2
|
-
|
|
3
|
-
module RelatonXsf
|
|
4
|
-
class Processor < Relaton::Processor
|
|
5
|
-
attr_reader :idtype
|
|
6
|
-
|
|
7
|
-
def initialize # rubocop:disable Lint/MissingSuper
|
|
8
|
-
@short = :relaton_xsf
|
|
9
|
-
@prefix = "XEP"
|
|
10
|
-
@defaultprefix = %r{^XEP\s}
|
|
11
|
-
@idtype = "XEP"
|
|
12
|
-
@datasets = %w[xep-xmpp]
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
# @param code [String]
|
|
16
|
-
# @param date [String, nil] year
|
|
17
|
-
# @param opts [Hash]
|
|
18
|
-
# @return [RelatonXsf::BibliographicItem]
|
|
19
|
-
def get(code, date, opts)
|
|
20
|
-
::RelatonXsf::Bibliography.get(code, date, opts)
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
#
|
|
24
|
-
# Fetch all the documents from http://xml2rfc.tools.ietf.org/public/rfc/bibxml-3gpp-new/
|
|
25
|
-
#
|
|
26
|
-
# @param [String] source source name
|
|
27
|
-
# @param [Hash] opts
|
|
28
|
-
# @option opts [String] :output directory to output documents
|
|
29
|
-
# @option opts [String] :format
|
|
30
|
-
#
|
|
31
|
-
def fetch_data(_source, opts)
|
|
32
|
-
::RelatonXsf::DataFetcher.fetch(**opts)
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
# @param xml [String]
|
|
36
|
-
# @return [RelatonXsf::BibliographicItem]
|
|
37
|
-
def from_xml(xml)
|
|
38
|
-
::RelatonXsf::XMLParser.from_xml xml
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
# @param hash [Hash]
|
|
42
|
-
# @return [RelatonXsf::BibliographicItem]
|
|
43
|
-
def hash_to_bib(hash)
|
|
44
|
-
item_hash = ::RelatonXsf::HashConverter.hash_to_bib(hash)
|
|
45
|
-
::RelatonXsf::BibliographicItem.new(**item_hash)
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
# Returns hash of XML grammar
|
|
49
|
-
# @return [String]
|
|
50
|
-
def grammar_hash
|
|
51
|
-
@grammar_hash ||= ::RelatonBib.grammar_hash
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
#
|
|
55
|
-
# Remove index file
|
|
56
|
-
#
|
|
57
|
-
def remove_index_file
|
|
58
|
-
Relaton::Index.find_or_create(:xsf, url: true, file: HitCollection::INDEX_FILE).remove_file
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
end
|
data/lib/relaton_xsf/util.rb
DELETED
data/lib/relaton_xsf/version.rb
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
module RelatonXsf
|
|
2
|
-
class XMLParser < RelatonBib::XMLParser
|
|
3
|
-
#
|
|
4
|
-
# Create bibliographic item
|
|
5
|
-
#
|
|
6
|
-
# @param item_hash [Hash] bibliographic item hash
|
|
7
|
-
#
|
|
8
|
-
# @return [RelatonXsf::BibliographicItem] bibliographic item
|
|
9
|
-
#
|
|
10
|
-
def self.bib_item(item_hash)
|
|
11
|
-
BibliographicItem.new(**item_hash)
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
end
|
data/lib/relaton_xsf.rb
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "mechanize"
|
|
4
|
-
require "relaton/index"
|
|
5
|
-
require "relaton_bib"
|
|
6
|
-
require_relative "relaton_xsf/version"
|
|
7
|
-
require_relative "relaton_xsf/util"
|
|
8
|
-
require_relative "relaton_xsf/bibliographic_item"
|
|
9
|
-
require_relative "relaton_xsf/bibliography"
|
|
10
|
-
require_relative "relaton_xsf/hit_collection"
|
|
11
|
-
require_relative "relaton_xsf/hit"
|
|
12
|
-
require_relative "relaton_xsf/xml_parser"
|
|
13
|
-
require_relative "relaton_xsf/bibxml_parser"
|
|
14
|
-
require_relative "relaton_xsf/hash_converter"
|
|
15
|
-
require_relative "relaton_xsf/data_fetcher"
|
|
16
|
-
|
|
17
|
-
module RelatonXsf
|
|
18
|
-
class Error < StandardError; end
|
|
19
|
-
# Your code goes here...
|
|
20
|
-
end
|