relaton-3gpp 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/bin/console +1 -1
- data/grammars/basicdoc.rng +1517 -651
- data/grammars/biblio-standoc.rng +100 -20
- data/grammars/biblio.rng +959 -356
- data/grammars/relaton-3gpp.rng +3 -1
- data/lib/relaton/3gpp/bibdata.rb +8 -0
- data/lib/relaton/3gpp/bibitem.rb +8 -0
- data/lib/relaton/3gpp/bibliography.rb +51 -0
- data/lib/relaton/3gpp/data_fetcher.rb +225 -0
- data/lib/relaton/3gpp/doctype.rb +9 -0
- data/lib/relaton/3gpp/ext.rb +34 -0
- data/lib/relaton/3gpp/item.rb +12 -0
- data/lib/relaton/3gpp/item_data.rb +23 -0
- data/lib/relaton/3gpp/parser.rb +304 -0
- data/lib/relaton/3gpp/processor.rb +60 -0
- data/lib/relaton/3gpp/release.rb +33 -0
- data/lib/relaton/3gpp/util.rb +8 -0
- data/lib/relaton/3gpp/version.rb +7 -0
- data/lib/relaton/3gpp.rb +23 -0
- data/relaton_3gpp.gemspec +7 -6
- metadata +36 -20
- data/lib/relaton_3gpp/bibliographic_item.rb +0 -98
- data/lib/relaton_3gpp/bibliography.rb +0 -50
- data/lib/relaton_3gpp/data_fetcher.rb +0 -283
- data/lib/relaton_3gpp/document_type.rb +0 -18
- data/lib/relaton_3gpp/hash_converter.rb +0 -31
- data/lib/relaton_3gpp/parser.rb +0 -273
- data/lib/relaton_3gpp/processor.rb +0 -61
- data/lib/relaton_3gpp/release.rb +0 -70
- data/lib/relaton_3gpp/util.rb +0 -6
- data/lib/relaton_3gpp/version.rb +0 -5
- data/lib/relaton_3gpp/xml_parser.rb +0 -62
- data/lib/relaton_3gpp.rb +0 -28
data/grammars/relaton-3gpp.rng
CHANGED
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Relaton
|
4
|
+
module ThreeGpp
|
5
|
+
# Methods for search IANA standards.
|
6
|
+
module Bibliography
|
7
|
+
# SOURCE = "http://xml2rfc.tools.ietf.org/public/rfc/bibxml-3gpp-new/"
|
8
|
+
SOURCE = "https://raw.githubusercontent.com/relaton/relaton-data-3gpp/refs/heads/data-v2/"
|
9
|
+
INDEX_FILE = "index-v1.yaml"
|
10
|
+
|
11
|
+
# @param text [String]
|
12
|
+
# @return [RelatonBib::BibliographicItem]
|
13
|
+
def search(text) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
14
|
+
index = Relaton::Index.find_or_create "3GPP", url: "#{SOURCE}index-v1.zip", file: INDEX_FILE
|
15
|
+
row = index.search(text.sub(/^3GPP\s/, "")).min_by { |r| r[:id] }
|
16
|
+
return unless row
|
17
|
+
|
18
|
+
# file = text.sub(/^3GPP\s/, "").gsub(/[\s,:\/]/, "_").squeeze("_").upcase
|
19
|
+
url = "#{SOURCE}#{row[:file]}"
|
20
|
+
resp = Net::HTTP.get_response URI(url)
|
21
|
+
return unless resp.code == "200"
|
22
|
+
|
23
|
+
item = Item.from_yaml(resp.body)
|
24
|
+
item.fetched = Date.today.to_s
|
25
|
+
item
|
26
|
+
rescue SocketError, Timeout::Error, Errno::EINVAL, Errno::ECONNRESET,
|
27
|
+
EOFError, Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError,
|
28
|
+
Net::ProtocolError, Errno::ETIMEDOUT => e
|
29
|
+
raise Relaton::RequestError, e.message
|
30
|
+
end
|
31
|
+
|
32
|
+
# @param ref [String] the W3C standard Code to look up
|
33
|
+
# @param year [String, NilClass] not used
|
34
|
+
# @param opts [Hash] options
|
35
|
+
# @return [RelatonBib::BibliographicItem]
|
36
|
+
def get(ref, _year = nil, _opts = {})
|
37
|
+
Util.info "Fetching from Relaton repository ...", key: ref
|
38
|
+
result = search(ref)
|
39
|
+
unless result
|
40
|
+
Util.info "Not found.", key: ref
|
41
|
+
return
|
42
|
+
end
|
43
|
+
|
44
|
+
Util.info "Found: `#{result.docidentifier[0].content}`", key: ref
|
45
|
+
result
|
46
|
+
end
|
47
|
+
|
48
|
+
extend Bibliography
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,225 @@
|
|
1
|
+
require "fileutils"
|
2
|
+
require "net/ftp"
|
3
|
+
require_relative "../3gpp"
|
4
|
+
require_relative "parser"
|
5
|
+
|
6
|
+
module Relaton
|
7
|
+
module ThreeGpp
|
8
|
+
class DataFetcher < Core::DataFetcher
|
9
|
+
CURRENT = "current.yaml".freeze
|
10
|
+
|
11
|
+
def index
|
12
|
+
@index ||= Relaton::Index.find_or_create "3gpp", file: Bibliography::INDEX_FILE
|
13
|
+
end
|
14
|
+
|
15
|
+
#
|
16
|
+
# Parse documents
|
17
|
+
#
|
18
|
+
# @param [String] source source of documents, status-smg-3gpp for updare or status-smg-3gpp-force for renewal
|
19
|
+
#
|
20
|
+
def fetch(source) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
21
|
+
renewal = source == "status-smg-3GPP-force"
|
22
|
+
file = get_file renewal
|
23
|
+
return unless file && File.exist?(file) && File.size(file) > 20_000_000
|
24
|
+
|
25
|
+
if renewal
|
26
|
+
FileUtils.rm_f Dir.glob(File.join(@output, "/*")) # if renewal && dbs["2001-04-25_schedule"].any?
|
27
|
+
index.remove_all # if renewal
|
28
|
+
end
|
29
|
+
CSV.open(file, "r:bom|utf-8", headers: true).each do |row|
|
30
|
+
save_doc Parser.parse(row)
|
31
|
+
end
|
32
|
+
File.write CURRENT, @current.to_yaml, encoding: "UTF-8"
|
33
|
+
index.save
|
34
|
+
end
|
35
|
+
|
36
|
+
#
|
37
|
+
# Get file from FTP. If file does not exist or changed, return nil
|
38
|
+
#
|
39
|
+
# @param [Boolean] renewal force to update all documents
|
40
|
+
#
|
41
|
+
# @return [String, nil] file name
|
42
|
+
#
|
43
|
+
def get_file(renewal) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
44
|
+
@current = YAML.load_file CURRENT if File.exist? CURRENT
|
45
|
+
@current ||= {}
|
46
|
+
n = 0
|
47
|
+
begin
|
48
|
+
ftp = Net::FTP.new("www.3gpp.org")
|
49
|
+
ftp.resume = true
|
50
|
+
ftp.login
|
51
|
+
ftp.chdir "/Information/Databases/"
|
52
|
+
file_path = ftp.list("*.csv").first
|
53
|
+
return unless file_path
|
54
|
+
|
55
|
+
d, t, _, file = file_path.split
|
56
|
+
dt = DateTime.strptime("#{d} #{t}", "%m-%d-%y %I:%M%p")
|
57
|
+
if !renewal && file == @current["file"] && !@current["date"].empty? && dt == DateTime.parse(@current["date"])
|
58
|
+
return
|
59
|
+
end
|
60
|
+
|
61
|
+
tmp_file = File.join Dir.tmpdir, "3gpp.csv"
|
62
|
+
ftp.get(file, tmp_file)
|
63
|
+
rescue Net::ReadTimeout => e
|
64
|
+
n += 1
|
65
|
+
retry if n < 5
|
66
|
+
raise e
|
67
|
+
end
|
68
|
+
@current["file"] = file
|
69
|
+
@current["date"] = dt.to_s
|
70
|
+
tmp_file
|
71
|
+
end
|
72
|
+
|
73
|
+
#
|
74
|
+
# Save document to file
|
75
|
+
#
|
76
|
+
# @param [RelatonW3c::W3cBibliographicItem, nil] bib bibliographic item
|
77
|
+
#
|
78
|
+
def save_doc(bib) # rubocop:disable Metrics/MethodLength
|
79
|
+
return unless bib
|
80
|
+
|
81
|
+
bib1 = bib
|
82
|
+
file = output_file(bib1.docnumber)
|
83
|
+
if @files.include? file
|
84
|
+
bib1 = merge_duplication bib1, file
|
85
|
+
Util.warn "File #{file} already exists. Document: #{bib.docnumber}" if bib1.nil?
|
86
|
+
else
|
87
|
+
@files << file
|
88
|
+
index.add_or_update bib1.docnumber, file
|
89
|
+
end
|
90
|
+
File.write file, serialize(bib1), encoding: "UTF-8" unless bib1.nil?
|
91
|
+
end
|
92
|
+
|
93
|
+
#
|
94
|
+
# Merge duplication
|
95
|
+
#
|
96
|
+
# @param [Relaton3gpp::BibliographicItem] bib new bibliographic item
|
97
|
+
# @param [String] file file name of existing bibliographic item
|
98
|
+
#
|
99
|
+
# @return [Relaton3gpp::BibliographicItem, nil] merged bibliographic item or nil if no merge has been done
|
100
|
+
#
|
101
|
+
def merge_duplication(bib, file)
|
102
|
+
hash = YAML.load_file file
|
103
|
+
existed = Item.from_hash hash
|
104
|
+
changed = update_source bib, existed
|
105
|
+
bib1, bib2, chng = transposed_relation bib, existed
|
106
|
+
changed ||= chng
|
107
|
+
chng = add_contributor(bib1, bib2)
|
108
|
+
changed ||= chng
|
109
|
+
bib1 if changed
|
110
|
+
end
|
111
|
+
|
112
|
+
#
|
113
|
+
# Update link in case one of bibliographic items has no link
|
114
|
+
#
|
115
|
+
# @param [Relaton3gpp::BibliographicItem] bib1
|
116
|
+
# @param [Relaton3gpp::BibliographicItem] bib2
|
117
|
+
#
|
118
|
+
# @return [Boolean] true if link has been updated
|
119
|
+
#
|
120
|
+
def update_source(bib1, bib2)
|
121
|
+
if bib1.source.any? && bib2.source.empty?
|
122
|
+
bib2.source = bib1.source
|
123
|
+
true
|
124
|
+
elsif bib1.source.empty? && bib2.source.any?
|
125
|
+
bib1.source = bib2.source
|
126
|
+
true
|
127
|
+
else false
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
#
|
132
|
+
# If one of bibliographic items has date gereater than anotherm=, make it relation
|
133
|
+
#
|
134
|
+
# @param [Relaton3gpp::BibliographicItem] bib new bibliographic item
|
135
|
+
# @param [Relaton3gpp::BibliographicItem] existed existing bibliographic item
|
136
|
+
#
|
137
|
+
# @return [Array<Relaton3gpp::BibliographicItem, Boolean>] main bibliographic item,
|
138
|
+
# related bibliographic item, true if relation has been added
|
139
|
+
#
|
140
|
+
def transposed_relation(bib, existed) # rubocop:disable Metrics/CyclomaticComplexity
|
141
|
+
return [bib, existed, false] if bib.date.none? && existed.date.none? ||
|
142
|
+
bib.date.any? && existed.date.none?
|
143
|
+
return [existed, bib, true] if bib.date.none? && existed.date.any?
|
144
|
+
|
145
|
+
check_transposed_date bib, existed
|
146
|
+
end
|
147
|
+
|
148
|
+
#
|
149
|
+
# Check if date of one bibliographic item is transposed to another
|
150
|
+
#
|
151
|
+
# @param [Relaton3gpp::BibliographicItem] bib new bibliographic item
|
152
|
+
# @param [Relaton3gpp::BibliographicItem] existed existing bibliographic item
|
153
|
+
#
|
154
|
+
# @return [Array<Relaton3gpp::BibliographicItem, Boolean>] main bibliographic item,
|
155
|
+
# related bibliographic item, true if relation has been added
|
156
|
+
#
|
157
|
+
def check_transposed_date(bib, existed)
|
158
|
+
if bib.date[0].at < existed.date[0].at
|
159
|
+
add_transposed_relation bib, existed
|
160
|
+
[bib, existed, true]
|
161
|
+
elsif bib.date[0].at > existed.date[0].at
|
162
|
+
add_transposed_relation existed, bib
|
163
|
+
[existed, bib, true]
|
164
|
+
else [bib, existed, false]
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
#
|
169
|
+
# Add transposed relation
|
170
|
+
#
|
171
|
+
# @param [Relaton3gpp::BibliographicItem] bib1 the main bibliographic item
|
172
|
+
# @param [Relaton3gpp::BibliographicItem] bib2 the transposed bibliographic item
|
173
|
+
#
|
174
|
+
# @return [Relaton3gpp::BibliographicItem]
|
175
|
+
#
|
176
|
+
def add_transposed_relation(bib1, bib2)
|
177
|
+
bib2.relation.each { |r| bib1.relation << r }
|
178
|
+
bib2.instance_variable_set :@relation, []
|
179
|
+
desc = Bib::LocalizedMarkedUpString.new content: "equivalent"
|
180
|
+
rel = Bib::Relation.new(type: "adoptedAs", bibitem: bib2, description: desc)
|
181
|
+
bib1.relation << rel
|
182
|
+
end
|
183
|
+
|
184
|
+
def add_contributor(bib1, bib2) # rubocop:disable Metrics/MethodLength,Metrics/AbcSize
|
185
|
+
changed = false
|
186
|
+
|
187
|
+
bib2.contributor.each do |bc|
|
188
|
+
next unless bc.person
|
189
|
+
|
190
|
+
existed = bib1.contributor.find { |ic| ic.person&.name == bc.person.name }
|
191
|
+
if existed
|
192
|
+
chng = add_affiliation existed, bc.person.affiliation
|
193
|
+
changed ||= chng
|
194
|
+
else
|
195
|
+
bib1.contributor << bc
|
196
|
+
changed = true
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
changed
|
201
|
+
end
|
202
|
+
|
203
|
+
def add_affiliation(contrib, affiliation)
|
204
|
+
changed = false
|
205
|
+
|
206
|
+
affiliation.each do |a|
|
207
|
+
unless contrib.person.affiliation.include? a
|
208
|
+
contrib.person.affiliation << a
|
209
|
+
changed = true
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
changed
|
214
|
+
end
|
215
|
+
|
216
|
+
def to_xml(bib)
|
217
|
+
Bibdata.to_xml(bib)
|
218
|
+
end
|
219
|
+
|
220
|
+
def to_yaml(bib)
|
221
|
+
Item.to_yaml(bib)
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require_relative "doctype"
|
2
|
+
require_relative "release"
|
3
|
+
|
4
|
+
module Relaton
|
5
|
+
module ThreeGpp
|
6
|
+
class Ext < Lutaml::Model::Serializable
|
7
|
+
attribute :schema_version, method: :get_schema_version
|
8
|
+
attribute :doctype, Doctype
|
9
|
+
attribute :subdoctype, :string, values: %w[spec release]
|
10
|
+
attribute :editorialgroup, Relaton::Bib::EditorialGroup
|
11
|
+
attribute :ics, Relaton::Bib::ICS, collection: true
|
12
|
+
attribute :radiotechnology, :string, values: %w[2G 3G LTE 5G]
|
13
|
+
attribute :common_ims_spec, :boolean
|
14
|
+
attribute :internal, :boolean
|
15
|
+
attribute :release, Release
|
16
|
+
|
17
|
+
def get_schema_version
|
18
|
+
Relaton.schema_versions["relaton-model-3gpp"]
|
19
|
+
end
|
20
|
+
|
21
|
+
xml do
|
22
|
+
map_attribute "schema-version", to: :schema_version
|
23
|
+
map_element "doctype", to: :doctype
|
24
|
+
map_element "subdoctype", to: :subdoctype
|
25
|
+
map_element "editorialgroup", to: :editorialgroup
|
26
|
+
map_element "ics", to: :ics
|
27
|
+
map_element "radiotechnology", to: :radiotechnology
|
28
|
+
map_element "common-ims-spec", to: :common_ims_spec
|
29
|
+
map_element "internal", to: :internal
|
30
|
+
map_element "release", to: :release
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Relaton
|
2
|
+
module ThreeGpp
|
3
|
+
class ItemData < Relaton::Bib::ItemData
|
4
|
+
def to_xml(bibdata: false, **opts)
|
5
|
+
add_notes opts[:note] do
|
6
|
+
bibdata ? Bibdata.to_xml(self) : Bibitem.to_xml(self)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def to_yaml(**opts)
|
11
|
+
add_notes opts[:note] do
|
12
|
+
Item.to_yaml(self)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_json(**opts)
|
17
|
+
add_notes opts[:note] do
|
18
|
+
Item.to_json(self)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,304 @@
|
|
1
|
+
require "csv"
|
2
|
+
|
3
|
+
module Relaton
|
4
|
+
module ThreeGpp
|
5
|
+
class Parser
|
6
|
+
# DOCTYPES = { "TS" => "Technical Specification", "TR" => "Technical Report" }.freeze
|
7
|
+
|
8
|
+
#
|
9
|
+
# Document parser initalization
|
10
|
+
#
|
11
|
+
# @param [CSV::Row] row CSV row
|
12
|
+
#
|
13
|
+
def initialize(row)
|
14
|
+
@row = row
|
15
|
+
end
|
16
|
+
|
17
|
+
#
|
18
|
+
# Initialize document parser and run it
|
19
|
+
#
|
20
|
+
# @param [CSV:Row] row CSV row
|
21
|
+
#
|
22
|
+
# @return [RelatonBib:BibliographicItem, nil] bibliographic item
|
23
|
+
#
|
24
|
+
def self.parse(row)
|
25
|
+
new(row).parse
|
26
|
+
end
|
27
|
+
|
28
|
+
#
|
29
|
+
# Parse document
|
30
|
+
#
|
31
|
+
# @return [Relaton3gpp:BibliographicItem, nil] bibliographic item
|
32
|
+
#
|
33
|
+
def parse # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
34
|
+
ItemData.new(
|
35
|
+
id: parse_id,
|
36
|
+
type: "standard",
|
37
|
+
language: ["en"],
|
38
|
+
script: ["Latn"],
|
39
|
+
title: parse_title,
|
40
|
+
source: parse_source,
|
41
|
+
# abstract: parse_abstract,
|
42
|
+
docidentifier: parse_docid,
|
43
|
+
docnumber: number,
|
44
|
+
date: parse_date,
|
45
|
+
version: parse_version,
|
46
|
+
contributor: parse_contributor,
|
47
|
+
place: parse_place,
|
48
|
+
ext: parse_ext,
|
49
|
+
# biblionote: parse_note,
|
50
|
+
# docstatus: parse_status,
|
51
|
+
# common_ims_spec: @spec[:ComIMS] == "1",
|
52
|
+
# internal: @spec[:"For publication"] == "0",
|
53
|
+
)
|
54
|
+
end
|
55
|
+
|
56
|
+
def parse_id
|
57
|
+
number.gsub(/[\s:\/]/, "-").squeeze("-").upcase
|
58
|
+
end
|
59
|
+
|
60
|
+
#
|
61
|
+
# Parse title
|
62
|
+
#
|
63
|
+
# @return [RelatonBib::TypedTitleStringCollection] title
|
64
|
+
#
|
65
|
+
def parse_title
|
66
|
+
[Bib::Title.new(content: @row["Title"], type: "main")]
|
67
|
+
# RelatonBib::TypedTitleStringCollection.new [t]
|
68
|
+
end
|
69
|
+
|
70
|
+
#
|
71
|
+
# Parse link
|
72
|
+
#
|
73
|
+
# @return [Array<RelatonBib::TypedUri>] link
|
74
|
+
#
|
75
|
+
def parse_source
|
76
|
+
return [] unless @row["Link"]
|
77
|
+
|
78
|
+
[Bib::Uri.new(type: "src", content: @row["Link"])]
|
79
|
+
end
|
80
|
+
|
81
|
+
#
|
82
|
+
# Parse abstract
|
83
|
+
#
|
84
|
+
# @return [Array<RelatonBib::FormattedString>]
|
85
|
+
#
|
86
|
+
# def parse_abstract
|
87
|
+
# return [] unless @spec[:description]
|
88
|
+
|
89
|
+
# [RelatonBib::FormattedString.new(content: @spec[:description])]
|
90
|
+
# end
|
91
|
+
|
92
|
+
#
|
93
|
+
# Parse docidentifier
|
94
|
+
#
|
95
|
+
# @return [Arra<RelatonBib::DocumentIdentifier>] docidentifier
|
96
|
+
#
|
97
|
+
def parse_docid
|
98
|
+
[Bib::Docidentifier.new(type: "3GPP", content: "3GPP #{number}", primary: true)]
|
99
|
+
end
|
100
|
+
|
101
|
+
#
|
102
|
+
# Generate number
|
103
|
+
#
|
104
|
+
# @return [String] number
|
105
|
+
#
|
106
|
+
def number
|
107
|
+
num = "#{doctype_abbr} #{@row[0]}"
|
108
|
+
num += ":#{release}" if release
|
109
|
+
"#{num}/#{version}"
|
110
|
+
end
|
111
|
+
|
112
|
+
def version
|
113
|
+
@row["Version"]
|
114
|
+
end
|
115
|
+
|
116
|
+
def parse_version
|
117
|
+
[Bib::Version.new(draft: version)]
|
118
|
+
end
|
119
|
+
|
120
|
+
def doctype_abbr
|
121
|
+
@row["Is TS"] == "1" ? "TS" : "TR"
|
122
|
+
end
|
123
|
+
|
124
|
+
def release
|
125
|
+
@release ||= case @row["WPM Code 2G"]
|
126
|
+
when /Release_(\d+)/ then "REL-#{$1}"
|
127
|
+
when /PH(\d+)/ then "Ph#{$1}"
|
128
|
+
else @row["Release"]
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
#
|
133
|
+
# Version
|
134
|
+
#
|
135
|
+
# @return [String] version
|
136
|
+
#
|
137
|
+
# def version
|
138
|
+
# "#{@row[:MAJOR_VERSION_NB]}.#{@row[:TECHNICAL_VERSION_NB]}.#{@row[:EDITORIAL_VERSION_NB]}"
|
139
|
+
# end
|
140
|
+
|
141
|
+
#
|
142
|
+
# Parse date
|
143
|
+
#
|
144
|
+
# @return [Array<RelatonBib::BibliographicDate>] date
|
145
|
+
#
|
146
|
+
def parse_date
|
147
|
+
dates = []
|
148
|
+
if @row["Date"]
|
149
|
+
on = Date.parse(@row["Date"]).to_s
|
150
|
+
dates << Bib::Date.new(type: "published", at: on)
|
151
|
+
end
|
152
|
+
dates
|
153
|
+
end
|
154
|
+
|
155
|
+
#
|
156
|
+
# Parse note
|
157
|
+
#
|
158
|
+
# @return [RelatonBib::BiblioNoteCollection] notes
|
159
|
+
#
|
160
|
+
# def parse_note
|
161
|
+
# n = []
|
162
|
+
# if @specrel && @specrel[:remarks] && @specrel[:remarks] != "."
|
163
|
+
# n << RelatonBib::BiblioNote.new(type: "remark", content: @specrel[:remarks])
|
164
|
+
# end
|
165
|
+
# if @row[:comment] && @row[:comment] != "."
|
166
|
+
# n << RelatonBib::BiblioNote.new(type: "comment", content: @row[:comment])
|
167
|
+
# end
|
168
|
+
# RelatonBib::BiblioNoteCollection.new n
|
169
|
+
# end
|
170
|
+
|
171
|
+
#
|
172
|
+
# Prase status
|
173
|
+
#
|
174
|
+
# @return [RelatnoBib::DocumentStatus, nil] status
|
175
|
+
#
|
176
|
+
# def parse_status
|
177
|
+
# if @specrel && @specrel[:withdrawn] == "1"
|
178
|
+
# RelatonBib::DocumentStatus.new stage: "withdrawn"
|
179
|
+
# elsif @spec[:"For publication"] == "1"
|
180
|
+
# RelatonBib::DocumentStatus.new stage: "published"
|
181
|
+
# end
|
182
|
+
# end
|
183
|
+
|
184
|
+
#
|
185
|
+
# Create contributors
|
186
|
+
#
|
187
|
+
# @return [Array<RelatonBib::ContributionInfo>] contributor
|
188
|
+
#
|
189
|
+
def parse_contributor # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
190
|
+
name = Bib::TypedLocalizedString.new(content: "3rd Generation Partnership Project")
|
191
|
+
abbrev = Bib::LocalizedString.new content: "3GPP"
|
192
|
+
org = Bib::Organization.new(name: [name], abbreviation: abbrev, address: [address])
|
193
|
+
contribs = [Bib::Contributor.new(organization: org, role: contributor_role)]
|
194
|
+
return contribs unless @row["Last Name"] && @row["Last Name"] != "Vacant"
|
195
|
+
|
196
|
+
role = Bib::Contributor::Role.new type: "author"
|
197
|
+
contribs << Bib::Contributor.new(person: person, role: [role])
|
198
|
+
end
|
199
|
+
|
200
|
+
def address
|
201
|
+
Bib::Address.new(
|
202
|
+
street: ["c/o ETSI 650, route des Lucioles", "3GPP Mobile Competence Centre"],
|
203
|
+
postcode: "06921", city: "Sophia Antipolis Cedex", country: "France"
|
204
|
+
)
|
205
|
+
end
|
206
|
+
|
207
|
+
def contributor_role
|
208
|
+
[Bib::Contributor::Role.new(type: "author"), Bib::Contributor::Role.new(type: "publisher")]
|
209
|
+
end
|
210
|
+
|
211
|
+
def person
|
212
|
+
surname = Bib::LocalizedString.new content: @row["Last Name"], language: "en", script: "Latn"
|
213
|
+
forename = Bib::FullNameType::Forename.new content: @row["First Name"], language: "en", script: "Latn"
|
214
|
+
name = Bib::FullName.new(surname: surname, forename: [forename])
|
215
|
+
Bib::Person.new(name: name, affiliation: affiliation)
|
216
|
+
end
|
217
|
+
|
218
|
+
def affiliation
|
219
|
+
return [] if @row["Organisation"].nil? || @row["Organisation"].empty?
|
220
|
+
|
221
|
+
name = Bib::TypedLocalizedString.new(content: @row["Organisation"])
|
222
|
+
org = Bib::Organization.new(name: [name])
|
223
|
+
[Bib::Affiliation.new(organization: org)]
|
224
|
+
end
|
225
|
+
|
226
|
+
def parse_place
|
227
|
+
[Bib::Place.new(formatted_place: "Sophia Antipolis Cedex, France")]
|
228
|
+
end
|
229
|
+
|
230
|
+
def parse_ext
|
231
|
+
Ext.new(
|
232
|
+
doctype: parse_doctype,
|
233
|
+
editorialgroup: parse_editorialgroup,
|
234
|
+
radiotechnology: parse_radiotechnology,
|
235
|
+
release: parse_release,
|
236
|
+
)
|
237
|
+
end
|
238
|
+
|
239
|
+
def parse_doctype
|
240
|
+
# type = DOCTYPES[doctype_abbr]
|
241
|
+
# Doctype.new(abbreviation: doctype_abbr, content: type)
|
242
|
+
Doctype.new(content: doctype_abbr) # 3GPP grammar alloves only TS and TR content
|
243
|
+
end
|
244
|
+
|
245
|
+
#
|
246
|
+
# Parse editorialgroup
|
247
|
+
#
|
248
|
+
# @return [RelatonBib::EditorialGroup] editorialgroups
|
249
|
+
#
|
250
|
+
def parse_editorialgroup # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
251
|
+
eg = []
|
252
|
+
prime = @row["Responsible Primary"]
|
253
|
+
eg << create_workgroup(prime, "prime") unless prime.nil? || prime.empty?
|
254
|
+
|
255
|
+
@row["Responsible Secondary"].strip.split(", ").each do |wg|
|
256
|
+
eg << create_workgroup(wg, "other")
|
257
|
+
end
|
258
|
+
Bib::EditorialGroup.new technical_committee: eg
|
259
|
+
end
|
260
|
+
|
261
|
+
def create_workgroup(name, type)
|
262
|
+
Bib::WorkGroup.new(content: name, type: type)
|
263
|
+
end
|
264
|
+
|
265
|
+
#
|
266
|
+
# Parse radio technology
|
267
|
+
#
|
268
|
+
# @return [String] radio technology
|
269
|
+
#
|
270
|
+
def parse_radiotechnology
|
271
|
+
case @row["WPM Code 3G"]
|
272
|
+
when /5G/ then "5G"
|
273
|
+
when /4G/ then "LTE"
|
274
|
+
when /3G/ then "3G"
|
275
|
+
else @row["WPM Code 2G"] && "2G"
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
#
|
280
|
+
# Parse release
|
281
|
+
#
|
282
|
+
# @return [Relaton3gpp::Release, nil] release
|
283
|
+
#
|
284
|
+
def parse_release # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
285
|
+
project_start = Date.parse(@row["Project Start"]) if @row["Project Start"]
|
286
|
+
project_end = Date.parse(@row["Project End"]) if @row["Project End"]
|
287
|
+
Release.new(
|
288
|
+
# version2g: @rel[:version_2g],
|
289
|
+
# version3g: @rel[:version_3g],
|
290
|
+
# defunct: @rel[:defunct] == "1",
|
291
|
+
wpm_code_2g: @row["WPM Code 2G"],
|
292
|
+
wpm_code_3g: @row["WPM Code 3G"],
|
293
|
+
# freeze_meeting: @rel[:"freeze meeting"],
|
294
|
+
freeze_stage1_meeting: @row["Stage 1 Freeze"],
|
295
|
+
freeze_stage2_meeting: @row["Stage 2 Freeze"],
|
296
|
+
freeze_stage3_meeting: @row["Stage 3 Freeze"],
|
297
|
+
close_meeting: @row["Close Meeting"],
|
298
|
+
project_start: project_start,
|
299
|
+
project_end: project_end,
|
300
|
+
)
|
301
|
+
end
|
302
|
+
end
|
303
|
+
end
|
304
|
+
end
|