w3c_api 0.1.0
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 +7 -0
- data/LICENSE.md +33 -0
- data/README.adoc +1265 -0
- data/Rakefile +8 -0
- data/exe/w3c_api +6 -0
- data/lib/w3c_api/cli.rb +41 -0
- data/lib/w3c_api/client.rb +320 -0
- data/lib/w3c_api/commands/affiliation.rb +48 -0
- data/lib/w3c_api/commands/ecosystem.rb +57 -0
- data/lib/w3c_api/commands/group.rb +87 -0
- data/lib/w3c_api/commands/output_formatter.rb +18 -0
- data/lib/w3c_api/commands/participation.rb +34 -0
- data/lib/w3c_api/commands/series.rb +40 -0
- data/lib/w3c_api/commands/specification.rb +68 -0
- data/lib/w3c_api/commands/translation.rb +31 -0
- data/lib/w3c_api/commands/user.rb +77 -0
- data/lib/w3c_api/models/affiliation.rb +86 -0
- data/lib/w3c_api/models/affiliations.rb +33 -0
- data/lib/w3c_api/models/base.rb +39 -0
- data/lib/w3c_api/models/call_for_translation.rb +59 -0
- data/lib/w3c_api/models/call_for_translation_ref.rb +15 -0
- data/lib/w3c_api/models/charter.rb +110 -0
- data/lib/w3c_api/models/charters.rb +17 -0
- data/lib/w3c_api/models/collection_base.rb +79 -0
- data/lib/w3c_api/models/connected_account.rb +54 -0
- data/lib/w3c_api/models/delegate_enumerable.rb +54 -0
- data/lib/w3c_api/models/ecosystem.rb +72 -0
- data/lib/w3c_api/models/ecosystems.rb +33 -0
- data/lib/w3c_api/models/extension.rb +12 -0
- data/lib/w3c_api/models/group.rb +173 -0
- data/lib/w3c_api/models/groups.rb +38 -0
- data/lib/w3c_api/models/join_emails.rb +12 -0
- data/lib/w3c_api/models/link.rb +17 -0
- data/lib/w3c_api/models/participation.rb +109 -0
- data/lib/w3c_api/models/participations.rb +17 -0
- data/lib/w3c_api/models/serie.rb +88 -0
- data/lib/w3c_api/models/series.rb +41 -0
- data/lib/w3c_api/models/series_collection.rb +17 -0
- data/lib/w3c_api/models/spec_version.rb +96 -0
- data/lib/w3c_api/models/spec_version_ref.rb +18 -0
- data/lib/w3c_api/models/spec_versions.rb +17 -0
- data/lib/w3c_api/models/specification.rb +79 -0
- data/lib/w3c_api/models/specifications.rb +17 -0
- data/lib/w3c_api/models/translation.rb +162 -0
- data/lib/w3c_api/models/translations.rb +40 -0
- data/lib/w3c_api/models/user.rb +178 -0
- data/lib/w3c_api/models/users.rb +44 -0
- data/lib/w3c_api/models.rb +15 -0
- data/lib/w3c_api/version.rb +5 -0
- data/lib/w3c_api.rb +9 -0
- metadata +166 -0
@@ -0,0 +1,68 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'thor'
|
4
|
+
require_relative 'output_formatter'
|
5
|
+
require_relative '../client'
|
6
|
+
|
7
|
+
module W3cApi
|
8
|
+
module Commands
|
9
|
+
# Thor CLI command for specification operations
|
10
|
+
class Specification < Thor
|
11
|
+
include OutputFormatter
|
12
|
+
|
13
|
+
desc 'fetch [OPTIONS]', 'Fetch specifications'
|
14
|
+
option :shortname, type: :string, desc: 'Filter by shortname'
|
15
|
+
option :version, type: :string, desc: 'Specific version of the specification'
|
16
|
+
option :status, type: :string, desc: 'Filter by status'
|
17
|
+
option :format, type: :string, default: 'yaml', enum: %w[json yaml], desc: 'Output format'
|
18
|
+
def fetch
|
19
|
+
client = W3cApi::Client.new
|
20
|
+
|
21
|
+
specifications = if options[:shortname] && options[:version]
|
22
|
+
# Single specification version
|
23
|
+
client.specification_version(options[:shortname], options[:version])
|
24
|
+
elsif options[:shortname]
|
25
|
+
# Single specification
|
26
|
+
client.specification(options[:shortname])
|
27
|
+
elsif options[:status]
|
28
|
+
# Specifications by status
|
29
|
+
client.specifications_by_status(options[:status])
|
30
|
+
else
|
31
|
+
# All specifications
|
32
|
+
client.specifications
|
33
|
+
end
|
34
|
+
|
35
|
+
output_results(specifications, options[:format])
|
36
|
+
end
|
37
|
+
|
38
|
+
desc 'versions', 'Fetch versions of a specification'
|
39
|
+
option :shortname, type: :string, required: true, desc: 'Specification shortname'
|
40
|
+
option :format, type: :string, default: 'yaml', enum: %w[json yaml], desc: 'Output format'
|
41
|
+
def versions
|
42
|
+
client = W3cApi::Client.new
|
43
|
+
versions = client.specification_versions(options[:shortname])
|
44
|
+
output_results(versions, options[:format])
|
45
|
+
end
|
46
|
+
|
47
|
+
desc 'supersedes', 'Fetch specifications that this specification supersedes'
|
48
|
+
option :shortname, type: :string, required: true, desc: 'Specification shortname'
|
49
|
+
option :format, type: :string, default: 'yaml', enum: %w[json yaml], desc: 'Output format'
|
50
|
+
def supersedes
|
51
|
+
# We need to add client.specification_supersedes method in the client
|
52
|
+
client = W3cApi::Client.new
|
53
|
+
specifications = client.specification_supersedes(options[:shortname])
|
54
|
+
output_results(specifications, options[:format])
|
55
|
+
end
|
56
|
+
|
57
|
+
desc 'superseded-by', 'Fetch specifications that supersede this specification'
|
58
|
+
option :shortname, type: :string, required: true, desc: 'Specification shortname'
|
59
|
+
option :format, type: :string, default: 'yaml', enum: %w[json yaml], desc: 'Output format'
|
60
|
+
def superseded_by
|
61
|
+
# We need to add client.specification_superseded_by method in the client
|
62
|
+
client = W3cApi::Client.new
|
63
|
+
specifications = client.specification_superseded_by(options[:shortname])
|
64
|
+
output_results(specifications, options[:format])
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'thor'
|
4
|
+
require_relative 'output_formatter'
|
5
|
+
require_relative '../client'
|
6
|
+
|
7
|
+
module W3cApi
|
8
|
+
module Commands
|
9
|
+
# Thor CLI command for translation operations
|
10
|
+
class Translation < Thor
|
11
|
+
include OutputFormatter
|
12
|
+
|
13
|
+
desc 'fetch [OPTIONS]', 'Fetch a translation by ID'
|
14
|
+
option :id, type: :string, desc: 'Translation ID'
|
15
|
+
option :format, type: :string, default: 'yaml', enum: %w[json yaml], desc: 'Output format'
|
16
|
+
def fetch
|
17
|
+
client = W3cApi::Client.new
|
18
|
+
|
19
|
+
translations = if options[:id]
|
20
|
+
# Single specification version
|
21
|
+
client.translation(options[:id])
|
22
|
+
else
|
23
|
+
# All translations
|
24
|
+
client.translations
|
25
|
+
end
|
26
|
+
|
27
|
+
output_results(translations, options[:format])
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'thor'
|
4
|
+
require_relative 'output_formatter'
|
5
|
+
require_relative '../client'
|
6
|
+
|
7
|
+
module W3cApi
|
8
|
+
module Commands
|
9
|
+
# Thor CLI command for user operations
|
10
|
+
class User < Thor
|
11
|
+
include OutputFormatter
|
12
|
+
|
13
|
+
desc 'fetch [OPTIONS]', 'Fetch a user by ID'
|
14
|
+
option :id, type: :string, required: true, desc: 'User ID (required)'
|
15
|
+
option :format, type: :string, default: 'yaml', enum: %w[json yaml], desc: 'Output format'
|
16
|
+
def fetch
|
17
|
+
client = W3cApi::Client.new
|
18
|
+
user = client.user(options[:id])
|
19
|
+
output_results(user, options[:format])
|
20
|
+
end
|
21
|
+
|
22
|
+
desc 'groups', 'Fetch groups a user is a member of'
|
23
|
+
option :id, type: :string, required: true, desc: 'User ID'
|
24
|
+
option :format, type: :string, default: 'yaml', enum: %w[json yaml], desc: 'Output format'
|
25
|
+
def groups
|
26
|
+
client = W3cApi::Client.new
|
27
|
+
groups = client.user_groups(options[:id])
|
28
|
+
output_results(groups, options[:format])
|
29
|
+
end
|
30
|
+
|
31
|
+
desc 'specifications', 'Fetch specifications a user has contributed to'
|
32
|
+
option :id, type: :string, required: true, desc: 'User ID (string or numeric)'
|
33
|
+
option :format, type: :string, default: 'yaml', enum: %w[json yaml], desc: 'Output format'
|
34
|
+
def specifications
|
35
|
+
client = W3cApi::Client.new
|
36
|
+
specifications = client.user_specifications(options[:id])
|
37
|
+
output_results(specifications, options[:format])
|
38
|
+
end
|
39
|
+
|
40
|
+
desc 'affiliations', 'Fetch affiliations of a user'
|
41
|
+
option :id, type: :string, required: true, desc: 'User ID (string or numeric)'
|
42
|
+
option :format, type: :string, default: 'yaml', enum: %w[json yaml], desc: 'Output format'
|
43
|
+
def affiliations
|
44
|
+
client = W3cApi::Client.new
|
45
|
+
affiliations = client.user_affiliations(options[:id])
|
46
|
+
output_results(affiliations, options[:format])
|
47
|
+
end
|
48
|
+
|
49
|
+
desc 'participations', 'Fetch participations of a user'
|
50
|
+
option :id, type: :string, required: true, desc: 'User ID (string or numeric)'
|
51
|
+
option :format, type: :string, default: 'yaml', enum: %w[json yaml], desc: 'Output format'
|
52
|
+
def participations
|
53
|
+
client = W3cApi::Client.new
|
54
|
+
participations = client.user_participations(options[:id])
|
55
|
+
output_results(participations, options[:format])
|
56
|
+
end
|
57
|
+
|
58
|
+
desc 'chair-of-groups', 'Fetch groups a user chairs'
|
59
|
+
option :id, type: :string, required: true, desc: 'User ID (string or numeric)'
|
60
|
+
option :format, type: :string, default: 'yaml', enum: %w[json yaml], desc: 'Output format'
|
61
|
+
def chair_of_groups
|
62
|
+
client = W3cApi::Client.new
|
63
|
+
groups = client.user_chair_of_groups(options[:id])
|
64
|
+
output_results(groups, options[:format])
|
65
|
+
end
|
66
|
+
|
67
|
+
desc 'team-contact-of-groups', 'Fetch groups a user is a team contact of'
|
68
|
+
option :id, type: :string, required: true, desc: 'User ID (string or numeric)'
|
69
|
+
option :format, type: :string, default: 'yaml', enum: %w[json yaml], desc: 'Output format'
|
70
|
+
def team_contact_of_groups
|
71
|
+
client = W3cApi::Client.new
|
72
|
+
groups = client.user_team_contact_of_groups(options[:id])
|
73
|
+
output_results(groups, options[:format])
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'base'
|
4
|
+
require_relative 'link'
|
5
|
+
|
6
|
+
# Example affiliation response:
|
7
|
+
# {
|
8
|
+
# "id"=>48830,
|
9
|
+
# "name"=>"Postmedia",
|
10
|
+
# "discr"=>"organization",
|
11
|
+
# "is-member"=>false,
|
12
|
+
# "is-member-association"=>false,
|
13
|
+
# "is-partner-member"=>false,
|
14
|
+
# "_links"=>{
|
15
|
+
# "self"=>{
|
16
|
+
# "href"=>"https://api.w3.org/affiliations/48830"
|
17
|
+
# },
|
18
|
+
# "participants"=>{
|
19
|
+
# "href"=>"https://api.w3.org/affiliations/48830/participants"
|
20
|
+
# },
|
21
|
+
# "participations"=>{
|
22
|
+
# "href"=>"https://api.w3.org/affiliations/48830/participations"
|
23
|
+
# }
|
24
|
+
# }
|
25
|
+
# }
|
26
|
+
|
27
|
+
# Fetch index response:
|
28
|
+
# {
|
29
|
+
# "href"=>"https://api.w3.org/affiliations/1001",
|
30
|
+
# "title"=>"Framkom (Forskningsaktiebolaget Medie-och Kommunikationsteknik)"
|
31
|
+
# },
|
32
|
+
|
33
|
+
|
34
|
+
module W3cApi
|
35
|
+
module Models
|
36
|
+
class AffiliationLinks < Lutaml::Model::Serializable
|
37
|
+
attribute :self, Link
|
38
|
+
attribute :participants, Link
|
39
|
+
attribute :participations, Link
|
40
|
+
end
|
41
|
+
|
42
|
+
class Affiliation < Base
|
43
|
+
attribute :id, :integer
|
44
|
+
attribute :name, :string
|
45
|
+
attribute :href, :string
|
46
|
+
attribute :title, :string
|
47
|
+
attribute :descr, :string
|
48
|
+
attribute :is_member, :boolean
|
49
|
+
attribute :is_member_association, :boolean
|
50
|
+
attribute :is_partner_member, :boolean
|
51
|
+
attribute :_links, AffiliationLinks
|
52
|
+
|
53
|
+
# Get participants of this affiliation
|
54
|
+
def participants(client = nil)
|
55
|
+
return nil unless client && _links&.participants
|
56
|
+
|
57
|
+
client.affiliation_participants(id)
|
58
|
+
end
|
59
|
+
|
60
|
+
# Get participations of this affiliation
|
61
|
+
def participations(client = nil)
|
62
|
+
return nil unless client && _links&.participations
|
63
|
+
|
64
|
+
client.affiliation_participations(id)
|
65
|
+
end
|
66
|
+
|
67
|
+
def self.from_response(response)
|
68
|
+
transformed_response = transform_keys(response)
|
69
|
+
|
70
|
+
affiliation = new
|
71
|
+
transformed_response.each do |key, value|
|
72
|
+
case key
|
73
|
+
when :_links
|
74
|
+
links = value.each_with_object({}) do |(link_name, link_data), acc|
|
75
|
+
acc[link_name] = Link.new(href: link_data[:href], title: link_data[:title])
|
76
|
+
end
|
77
|
+
affiliation._links = AffiliationLinks.new(links)
|
78
|
+
else
|
79
|
+
affiliation.send("#{key}=", value) if affiliation.respond_to?("#{key}=")
|
80
|
+
end
|
81
|
+
end
|
82
|
+
affiliation
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'lutaml/model'
|
4
|
+
require_relative 'affiliation'
|
5
|
+
require_relative 'delegate_enumerable'
|
6
|
+
require_relative 'collection_base'
|
7
|
+
|
8
|
+
# {
|
9
|
+
# "page"=>1,
|
10
|
+
# "limit"=>1000,
|
11
|
+
# "pages"=>16,
|
12
|
+
# "total"=>15918,
|
13
|
+
# "_links"=>{
|
14
|
+
# "affiliations"=>[
|
15
|
+
# {
|
16
|
+
# "href"=>"https://api.w3.org/affiliations/1001",
|
17
|
+
# "title"=>"Framkom (Forskningsaktiebolaget Medie-och Kommunikationsteknik)"
|
18
|
+
# },
|
19
|
+
# {
|
20
|
+
# "href"=>"https://api.w3.org/affiliations/1003",
|
21
|
+
# "title"=>"BackWeb Technologies, Inc."
|
22
|
+
# },
|
23
|
+
|
24
|
+
module W3cApi
|
25
|
+
module Models
|
26
|
+
class Affiliations < CollectionBase
|
27
|
+
attribute :affiliations, Affiliation, collection: true
|
28
|
+
|
29
|
+
delegate_enumerable :affiliations
|
30
|
+
collection_instance_class Affiliation, :affiliations
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'lutaml/model'
|
4
|
+
require 'json'
|
5
|
+
require 'yaml'
|
6
|
+
|
7
|
+
module W3cApi
|
8
|
+
module Models
|
9
|
+
class Base < Lutaml::Model::Serializable
|
10
|
+
# Common methods for all W3C API models
|
11
|
+
|
12
|
+
# Create a model instance from a JSON hash
|
13
|
+
def self.from_response(data)
|
14
|
+
# Convert keys with hyphens to snake_case for Ruby
|
15
|
+
transformed_data = transform_keys(data)
|
16
|
+
|
17
|
+
# Create model instance
|
18
|
+
new(transformed_data)
|
19
|
+
end
|
20
|
+
|
21
|
+
# Utility function to transform kebab-case to snake_case
|
22
|
+
def self.transform_keys(data)
|
23
|
+
case data
|
24
|
+
when Hash
|
25
|
+
result = {}
|
26
|
+
data.each do |key, value|
|
27
|
+
snake_key = key.to_s.tr('-', '_').to_sym
|
28
|
+
result[snake_key] = transform_keys(value)
|
29
|
+
end
|
30
|
+
result
|
31
|
+
when Array
|
32
|
+
data.map { |item| transform_keys(item) }
|
33
|
+
else
|
34
|
+
data
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'base'
|
4
|
+
require_relative 'link'
|
5
|
+
require_relative 'spec_version_ref'
|
6
|
+
|
7
|
+
# {
|
8
|
+
# "uri": "https://www.w3.org/WAI/videos/standards-and-benefits/"
|
9
|
+
# "title": "Video Introduction to Web Accessibility and W3C Standards"
|
10
|
+
# "_links": {
|
11
|
+
# "self": {
|
12
|
+
# "href": "https://api.w3.org/callsfortranslation/5"
|
13
|
+
# }
|
14
|
+
# "translations": {
|
15
|
+
# "href": "https://api.w3.org/callsfortranslation/5/translations"
|
16
|
+
# }
|
17
|
+
# }
|
18
|
+
# }
|
19
|
+
|
20
|
+
module W3cApi
|
21
|
+
module Models
|
22
|
+
class CallForTranslationLinks < Lutaml::Model::Serializable
|
23
|
+
attribute :self, Link
|
24
|
+
attribute :translations, Link
|
25
|
+
end
|
26
|
+
|
27
|
+
class CallForTranslation < Base
|
28
|
+
attribute :uri, :string
|
29
|
+
attribute :title, :string
|
30
|
+
attribute :spec_version, SpecVersionRef
|
31
|
+
attribute :_links, CallForTranslationLinks
|
32
|
+
|
33
|
+
# Get translations for this call for translation
|
34
|
+
def translations(client = nil)
|
35
|
+
return nil unless client && _links&.translations
|
36
|
+
|
37
|
+
client.call_for_translation_translations(uri)
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.from_response(response)
|
41
|
+
transformed_response = transform_keys(response)
|
42
|
+
|
43
|
+
cft = new
|
44
|
+
transformed_response.each do |key, value|
|
45
|
+
case key
|
46
|
+
when :_links
|
47
|
+
links = value.each_with_object({}) do |(link_name, link_data), acc|
|
48
|
+
acc[link_name] = Link.new(href: link_data[:href], title: link_data[:title])
|
49
|
+
end
|
50
|
+
cft._links = CallForTranslationLinks.new(links)
|
51
|
+
else
|
52
|
+
cft.send("#{key}=", value) if cft.respond_to?("#{key}=")
|
53
|
+
end
|
54
|
+
end
|
55
|
+
cft
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'lutaml/model'
|
4
|
+
require_relative 'spec_version_ref'
|
5
|
+
|
6
|
+
module W3cApi
|
7
|
+
module Models
|
8
|
+
class CallForTranslationRef < Lutaml::Model::Serializable
|
9
|
+
attribute :uri, :string
|
10
|
+
attribute :title, :string
|
11
|
+
attribute :comments, :string
|
12
|
+
attribute :spec_version, SpecVersionRef
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'base'
|
4
|
+
require_relative 'extension'
|
5
|
+
require_relative 'link'
|
6
|
+
|
7
|
+
# Example charter response format - specific fields may vary by group:
|
8
|
+
# {
|
9
|
+
# "end": "2025-10-31"
|
10
|
+
# "title": "Accessibility Guidelines Working Group Charter"
|
11
|
+
# "start": "1997-10-06"
|
12
|
+
# "initial_end": "1999-10-06"
|
13
|
+
# "uri": "https://www.w3.org/2022/05/accessibility-guidelines-wg-charter.html"
|
14
|
+
# "cfp_uri": "https://lists.w3.org/Archives/Member/w3c-ac-members/..."
|
15
|
+
# "extensions": [...]
|
16
|
+
# "required_new_commitments": false
|
17
|
+
# "patent_policy": "pre-2020"
|
18
|
+
# "_links": {
|
19
|
+
# "self": {
|
20
|
+
# "href": "https://api.w3.org/groups/wg/ag/charters/492"
|
21
|
+
# },
|
22
|
+
# "group": {
|
23
|
+
# "href": "https://api.w3.org/groups/wg/ag"
|
24
|
+
# }
|
25
|
+
# }
|
26
|
+
# }
|
27
|
+
|
28
|
+
module W3cApi
|
29
|
+
module Models
|
30
|
+
class CharterLinks < Lutaml::Model::Serializable
|
31
|
+
attribute :self, Link
|
32
|
+
attribute :group, Link
|
33
|
+
end
|
34
|
+
|
35
|
+
class Charter < Base
|
36
|
+
attribute :end, :string # Date-time format
|
37
|
+
attribute :href, :string
|
38
|
+
attribute :title, :string
|
39
|
+
attribute :start, :string # Date-time format
|
40
|
+
attribute :initial_end, :string # Date-time format
|
41
|
+
attribute :uri, :string, pattern: %r{https?://www\.w3\.org.*}
|
42
|
+
attribute :cfp_uri, :string, pattern: %r{https://lists\.w3\.org/Archives/Member/w3c-ac-members/.*}
|
43
|
+
attribute :extensions, Extension, collection: true
|
44
|
+
attribute :required_new_commitments, :boolean
|
45
|
+
attribute :patent_policy, :string
|
46
|
+
attribute :_links, CharterLinks
|
47
|
+
|
48
|
+
# Return the group this charter belongs to
|
49
|
+
def group(client = nil)
|
50
|
+
return nil unless client && _links&.group
|
51
|
+
|
52
|
+
group_href = _links.group.href
|
53
|
+
group_id = group_href.split('/').last
|
54
|
+
|
55
|
+
client.group(group_id)
|
56
|
+
end
|
57
|
+
|
58
|
+
# Parse date strings to Date objects
|
59
|
+
def end_date
|
60
|
+
Date.parse(self.end) if self.end
|
61
|
+
rescue Date::Error
|
62
|
+
nil
|
63
|
+
end
|
64
|
+
|
65
|
+
def start_date
|
66
|
+
Date.parse(start) if start
|
67
|
+
rescue Date::Error
|
68
|
+
nil
|
69
|
+
end
|
70
|
+
|
71
|
+
def initial_end_date
|
72
|
+
Date.parse(initial_end) if initial_end
|
73
|
+
rescue Date::Error
|
74
|
+
nil
|
75
|
+
end
|
76
|
+
|
77
|
+
# Check if this charter is active
|
78
|
+
def active?
|
79
|
+
start_date &&
|
80
|
+
(end_date.nil? || end_date >= Date.today) &&
|
81
|
+
start_date <= Date.today
|
82
|
+
rescue Date::Error
|
83
|
+
false
|
84
|
+
end
|
85
|
+
|
86
|
+
# Check if this charter has been extended
|
87
|
+
def extended?
|
88
|
+
!extensions.nil? && !extensions.empty?
|
89
|
+
end
|
90
|
+
|
91
|
+
def self.from_response(response)
|
92
|
+
transformed_response = transform_keys(response)
|
93
|
+
|
94
|
+
charter = new
|
95
|
+
transformed_response.each do |key, value|
|
96
|
+
case key
|
97
|
+
when :_links
|
98
|
+
links = value.each_with_object({}) do |(link_name, link_data), acc|
|
99
|
+
acc[link_name] = Link.new(href: link_data[:href], title: link_data[:title])
|
100
|
+
end
|
101
|
+
charter._links = CharterLinks.new(links)
|
102
|
+
else
|
103
|
+
charter.send("#{key}=", value) if charter.respond_to?("#{key}=")
|
104
|
+
end
|
105
|
+
end
|
106
|
+
charter
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'lutaml/model'
|
4
|
+
require_relative 'charter'
|
5
|
+
require_relative 'delegate_enumerable'
|
6
|
+
require_relative 'collection_base'
|
7
|
+
|
8
|
+
module W3cApi
|
9
|
+
module Models
|
10
|
+
class Charters < CollectionBase
|
11
|
+
attribute :charters, Charter, collection: true
|
12
|
+
|
13
|
+
delegate_enumerable :charters
|
14
|
+
collection_instance_class Charter, :charters
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'lutaml/model'
|
4
|
+
require 'json'
|
5
|
+
require 'yaml'
|
6
|
+
|
7
|
+
module W3cApi
|
8
|
+
module Models
|
9
|
+
class CollectionBase < Lutaml::Model::Serializable
|
10
|
+
# Common methods for all W3C API model collections
|
11
|
+
extend DelegateEnumerable
|
12
|
+
|
13
|
+
def self.collection_instance_class(klass, attribute)
|
14
|
+
@collection_instance_class ||= klass
|
15
|
+
@collection_attribute = attribute
|
16
|
+
end
|
17
|
+
|
18
|
+
# Create a model instance from a hash response
|
19
|
+
def self.from_response(data)
|
20
|
+
return new({ @collection_attribute => [] }) if data.nil?
|
21
|
+
|
22
|
+
# Handle the case where data is expected to have 'items' key
|
23
|
+
if data.is_a?(Hash)
|
24
|
+
return new({ @collection_attribute => [] }) unless data.key?(:items) || data.key?('items')
|
25
|
+
|
26
|
+
items_key = data.key?(:items) ? :items : 'items'
|
27
|
+
items = data[items_key] || []
|
28
|
+
|
29
|
+
# Set pagination metadata
|
30
|
+
result = new
|
31
|
+
data.each do |key, value|
|
32
|
+
next if key == items_key
|
33
|
+
|
34
|
+
result.send("#{key}=", value) if result.respond_to?("#{key}=")
|
35
|
+
end
|
36
|
+
|
37
|
+
# Process items array
|
38
|
+
transformed_items = items.map do |item|
|
39
|
+
@collection_instance_class.new(transform_keys(item))
|
40
|
+
end
|
41
|
+
|
42
|
+
result.send("#{@collection_attribute}=", transformed_items)
|
43
|
+
return result
|
44
|
+
|
45
|
+
# Handle case where response is a hash but doesn't contain 'items'
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
# Handle case where data is directly the items array
|
50
|
+
if data.is_a?(Array)
|
51
|
+
transformed_data = data.map do |item|
|
52
|
+
@collection_instance_class.new(transform_keys(item))
|
53
|
+
end
|
54
|
+
return new({ @collection_attribute => transformed_data })
|
55
|
+
end
|
56
|
+
|
57
|
+
# For backward compatibility, try to create a model instance anyway
|
58
|
+
new({ @collection_attribute => [] })
|
59
|
+
end
|
60
|
+
|
61
|
+
# Utility function to transform kebab-case to snake_case
|
62
|
+
def self.transform_keys(data)
|
63
|
+
case data
|
64
|
+
when Hash
|
65
|
+
result = {}
|
66
|
+
data.each do |key, value|
|
67
|
+
snake_key = key.to_s.tr('-', '_').to_sym
|
68
|
+
result[snake_key] = transform_keys(value)
|
69
|
+
end
|
70
|
+
result
|
71
|
+
when Array
|
72
|
+
data.map { |item| transform_keys(item) }
|
73
|
+
else
|
74
|
+
data
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'lutaml/model'
|
4
|
+
|
5
|
+
# {
|
6
|
+
# "created"=>"2019-07-18T21:28:31+00:00",
|
7
|
+
# "updated"=>"2021-01-21T10:49:57+00:00",
|
8
|
+
# "service"=>"github",
|
9
|
+
# "identifier"=>"1801875",
|
10
|
+
# "nickname"=>"davidsgrogan",
|
11
|
+
# "profile-picture"=>"https://avatars.githubusercontent.com/u/1801875?v=4",
|
12
|
+
# "href"=>"https://github.com/davidsgrogan",
|
13
|
+
# "_links"=>{
|
14
|
+
# "user"=>{
|
15
|
+
# "href"=>"https://api.w3.org/users/c2yerd5euz48gcw08s44oww8g4oo8w8"
|
16
|
+
# }
|
17
|
+
# }
|
18
|
+
# }
|
19
|
+
|
20
|
+
module W3cApi
|
21
|
+
module Models
|
22
|
+
class ConnectedAccountLinks < Lutaml::Model::Serializable
|
23
|
+
attribute :user, Link
|
24
|
+
end
|
25
|
+
|
26
|
+
class ConnectedAccount < Base
|
27
|
+
attribute :created, :date_time
|
28
|
+
attribute :updated, :date_time
|
29
|
+
attribute :service, :string
|
30
|
+
attribute :identifier, :string
|
31
|
+
attribute :nickname, :string
|
32
|
+
attribute :profile_picture, :string
|
33
|
+
attribute :href, :string
|
34
|
+
attribute :_links, ConnectedAccountLinks
|
35
|
+
|
36
|
+
def self.from_response(response)
|
37
|
+
transformed_response = transform_keys(response)
|
38
|
+
account = new
|
39
|
+
transformed_response.each do |key, value|
|
40
|
+
case key
|
41
|
+
when :_links
|
42
|
+
links = value.each_with_object({}) do |(link_name, link_data), acc|
|
43
|
+
acc[link_name] = Link.new(href: link_data[:href], title: link_data[:title])
|
44
|
+
end
|
45
|
+
account._links = ConnectedAccountLinks.new(links)
|
46
|
+
else
|
47
|
+
account.send("#{key}=", value) if account.respond_to?("#{key}=")
|
48
|
+
end
|
49
|
+
end
|
50
|
+
account
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|