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.
Files changed (51) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.md +33 -0
  3. data/README.adoc +1265 -0
  4. data/Rakefile +8 -0
  5. data/exe/w3c_api +6 -0
  6. data/lib/w3c_api/cli.rb +41 -0
  7. data/lib/w3c_api/client.rb +320 -0
  8. data/lib/w3c_api/commands/affiliation.rb +48 -0
  9. data/lib/w3c_api/commands/ecosystem.rb +57 -0
  10. data/lib/w3c_api/commands/group.rb +87 -0
  11. data/lib/w3c_api/commands/output_formatter.rb +18 -0
  12. data/lib/w3c_api/commands/participation.rb +34 -0
  13. data/lib/w3c_api/commands/series.rb +40 -0
  14. data/lib/w3c_api/commands/specification.rb +68 -0
  15. data/lib/w3c_api/commands/translation.rb +31 -0
  16. data/lib/w3c_api/commands/user.rb +77 -0
  17. data/lib/w3c_api/models/affiliation.rb +86 -0
  18. data/lib/w3c_api/models/affiliations.rb +33 -0
  19. data/lib/w3c_api/models/base.rb +39 -0
  20. data/lib/w3c_api/models/call_for_translation.rb +59 -0
  21. data/lib/w3c_api/models/call_for_translation_ref.rb +15 -0
  22. data/lib/w3c_api/models/charter.rb +110 -0
  23. data/lib/w3c_api/models/charters.rb +17 -0
  24. data/lib/w3c_api/models/collection_base.rb +79 -0
  25. data/lib/w3c_api/models/connected_account.rb +54 -0
  26. data/lib/w3c_api/models/delegate_enumerable.rb +54 -0
  27. data/lib/w3c_api/models/ecosystem.rb +72 -0
  28. data/lib/w3c_api/models/ecosystems.rb +33 -0
  29. data/lib/w3c_api/models/extension.rb +12 -0
  30. data/lib/w3c_api/models/group.rb +173 -0
  31. data/lib/w3c_api/models/groups.rb +38 -0
  32. data/lib/w3c_api/models/join_emails.rb +12 -0
  33. data/lib/w3c_api/models/link.rb +17 -0
  34. data/lib/w3c_api/models/participation.rb +109 -0
  35. data/lib/w3c_api/models/participations.rb +17 -0
  36. data/lib/w3c_api/models/serie.rb +88 -0
  37. data/lib/w3c_api/models/series.rb +41 -0
  38. data/lib/w3c_api/models/series_collection.rb +17 -0
  39. data/lib/w3c_api/models/spec_version.rb +96 -0
  40. data/lib/w3c_api/models/spec_version_ref.rb +18 -0
  41. data/lib/w3c_api/models/spec_versions.rb +17 -0
  42. data/lib/w3c_api/models/specification.rb +79 -0
  43. data/lib/w3c_api/models/specifications.rb +17 -0
  44. data/lib/w3c_api/models/translation.rb +162 -0
  45. data/lib/w3c_api/models/translations.rb +40 -0
  46. data/lib/w3c_api/models/user.rb +178 -0
  47. data/lib/w3c_api/models/users.rb +44 -0
  48. data/lib/w3c_api/models.rb +15 -0
  49. data/lib/w3c_api/version.rb +5 -0
  50. data/lib/w3c_api.rb +9 -0
  51. metadata +166 -0
@@ -0,0 +1,96 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'base'
4
+ require_relative 'link'
5
+
6
+ # Example spec version response format:
7
+ # {
8
+ # "date": "2023-09-21"
9
+ # "status": "REC"
10
+ # "rec_track": true
11
+ # "editor-draft": "https://w3c.github.io/example-draft/"
12
+ # "uri": "https://www.w3.org/TR/2023/REC-example-20230921/"
13
+ # "title": "Example Specification"
14
+ # "shortlink": "https://www.w3.org/TR/example/"
15
+ # "process-rules": "2021"
16
+ # "_links": {
17
+ # "self": {
18
+ # "href": "https://api.w3.org/specifications/example/versions/20230921"
19
+ # },
20
+ # "specification": {
21
+ # "href": "https://api.w3.org/specifications/example"
22
+ # }
23
+ # }
24
+ # }
25
+
26
+ module W3cApi
27
+ module Models
28
+ class SpecVersionLinks < Lutaml::Model::Serializable
29
+ attribute :self, Link
30
+ attribute :specification, Link
31
+ end
32
+
33
+ class SpecVersion < Base
34
+ attribute :status, :string
35
+ attribute :rec_track, :boolean
36
+ attribute :editor_draft, :string
37
+ attribute :uri, :string, pattern: %r{https://www\.w3\.org/.*}
38
+ attribute :date, :date_time # Date-time format
39
+ attribute :last_call_feedback_due, :date_time # Date-time format
40
+ attribute :pr_reviews_date, :date_time # Date-time format
41
+ attribute :implementation_feedback_due, :date_time # Date-time format
42
+ attribute :per_reviews_due, :date_time # Date-time format
43
+ attribute :informative, :boolean
44
+ attribute :title, :string
45
+ attribute :href, :string
46
+ attribute :shortlink, :string, pattern: %r{https://www\.w3\.org/.*}
47
+ attribute :translation, :string
48
+ attribute :errata, :string
49
+ attribute :process_rules, :string
50
+ attribute :_links, SpecVersionLinks
51
+
52
+ # Return the specification this version belongs to
53
+ def specification(client = nil)
54
+ return nil unless client && _links&.specification
55
+
56
+ spec_href = _links.specification.href
57
+ spec_shortname = spec_href.split('/').last
58
+
59
+ client.specification(spec_shortname)
60
+ end
61
+
62
+ # Check if this spec version is a Recommendation
63
+ def recommendation?
64
+ status == 'REC'
65
+ end
66
+
67
+ # Check if this spec version is a Working Draft
68
+ def working_draft?
69
+ status == 'WD'
70
+ end
71
+
72
+ # Check if this spec version is a Candidate Recommendation
73
+ def candidate_recommendation?
74
+ status == 'CR'
75
+ end
76
+
77
+ def self.from_response(response)
78
+ transformed_response = transform_keys(response)
79
+
80
+ spec_version = new
81
+ transformed_response.each do |key, value|
82
+ case key
83
+ when :_links
84
+ links = value.each_with_object({}) do |(link_name, link_data), acc|
85
+ acc[link_name] = Link.new(href: link_data[:href], title: link_data[:title])
86
+ end
87
+ spec_version._links = SpecVersionLinks.new(links)
88
+ else
89
+ spec_version.send("#{key}=", value) if spec_version.respond_to?("#{key}=")
90
+ end
91
+ end
92
+ spec_version
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'lutaml/model'
4
+
5
+ module W3cApi
6
+ module Models
7
+ class SpecVersionRef < Lutaml::Model::Serializable
8
+ attribute :status, :string
9
+ attribute :rec_track, :boolean
10
+ attribute :editor_draft, :string
11
+ attribute :uri, :string
12
+ attribute :date, :string
13
+ attribute :title, :string
14
+ attribute :shortlink, :string
15
+ attribute :process_rules, :string
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'lutaml/model'
4
+ require_relative 'spec_version'
5
+ require_relative 'delegate_enumerable'
6
+ require_relative 'collection_base'
7
+
8
+ module W3cApi
9
+ module Models
10
+ class SpecVersions < CollectionBase
11
+ attribute :spec_versions, SpecVersion, collection: true
12
+
13
+ delegate_enumerable :spec_versions
14
+ collection_instance_class SpecVersion, :spec_versions
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'base'
4
+ require_relative 'link'
5
+
6
+ # {
7
+ # "shortlink"=>"https://www.w3.org/TR/PNG/",
8
+ # "description"=>"<p>This document describes PNG (Portable Network Graphics), an extensible file format for the lossless, portable, well-compressed storage of raster images. PNG provides a patent-free replacement for GIF and can also replace many common uses of TIFF. Indexed-color, grayscale, and truecolor images are supported, plus an optional alpha channel. Sample depths range from 1 to 16 bits.</p>\r\n<p>PNG is designed to work well in online viewing applications, such as the World Wide Web, so it is fully streamable with a progressive display option. PNG is robust, providing both full file integrity checking and simple detection of common transmission errors. Also, PNG can store gamma and chromaticity data for improved color matching on heterogeneous platforms.</p>\r\n<p>This specification defines an Internet Media Type image/png.</p>",
9
+ # "title"=>"Portable Network Graphics (PNG) Specification (Second Edition)",
10
+ # "shortname"=>"png-2",
11
+ # "editor-draft"=>"https://w3c.github.io/png/",
12
+ # "_links"=>{
13
+ # "self"=>{
14
+ # "href"=>"https://api.w3.org/specifications/png-2"
15
+ # },
16
+ # "version-history"=>{
17
+ # "href"=>"https://api.w3.org/specifications/png-2/versions"
18
+ # },
19
+ # "first-version"=>{
20
+ # "href"=>"https://api.w3.org/specifications/png-2/versions/20030520",
21
+ # "title"=>"Proposed Recommendation"
22
+ # },
23
+ # "latest-version"=>{
24
+ # "href"=>"https://api.w3.org/specifications/png-2/versions/20031110",
25
+ # "title"=>"Recommendation"
26
+ # },
27
+ # "series"=>{
28
+ # "href"=>"https://api.w3.org/specification-series/png"
29
+ # }
30
+ # }
31
+ # }
32
+
33
+ module W3cApi
34
+ module Models
35
+ class SpecificationLinks < Lutaml::Model::Serializable
36
+ attribute :self, Link
37
+ attribute :version_history, Link
38
+ attribute :first_version, Link
39
+ attribute :latest_version, Link
40
+ attribute :series, Link
41
+ end
42
+
43
+ class Specification < Base
44
+ attribute :shortlink, :string
45
+ attribute :description, :string
46
+ attribute :title, :string
47
+ attribute :href, :string
48
+ attribute :shortname, :string
49
+ attribute :editor_draft, :string
50
+ attribute :series_version, :string
51
+ attribute :_links, SpecificationLinks
52
+
53
+ # Return versions of this specification
54
+ def versions(client = nil)
55
+ return nil unless client && shortname
56
+
57
+ client.specification_versions(shortname)
58
+ end
59
+
60
+ def self.from_response(response)
61
+ transformed_response = transform_keys(response)
62
+
63
+ spec = new
64
+ transformed_response.each do |key, value|
65
+ case key
66
+ when :_links
67
+ links = value.each_with_object({}) do |(link_name, link_data), acc|
68
+ acc[link_name] = Link.new(href: link_data[:href], title: link_data[:title])
69
+ end
70
+ spec._links = SpecificationLinks.new(links)
71
+ else
72
+ spec.send("#{key}=", value) if spec.respond_to?("#{key}=")
73
+ end
74
+ end
75
+ spec
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'lutaml/model'
4
+ require_relative 'specification'
5
+ require_relative 'delegate_enumerable'
6
+ require_relative 'collection_base'
7
+
8
+ module W3cApi
9
+ module Models
10
+ class Specifications < CollectionBase
11
+ attribute :specifications, Specification, collection: true
12
+
13
+ delegate_enumerable :specifications
14
+ collection_instance_class Specification, :specifications
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,162 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'base'
4
+ require_relative 'call_for_translation_ref'
5
+ require_relative 'link'
6
+ require_relative 'user'
7
+
8
+ # {
9
+ # "states"=>[
10
+ # "review"
11
+ # ],
12
+ # "uri"=>"https://github.com/w3c/wai-video-standards-and-benefits/blob/master/index.fr.md",
13
+ # "title"=>"Vidéo : introduction à l’accessibilité web et aux standards du W3C",
14
+ # "language"=>"fr",
15
+ # "translators"=>[
16
+ # {
17
+ # "id"=>40757,
18
+ # "name"=>"Stéphane Deschamps",
19
+ # "given"=>"Stéphane",
20
+ # "family"=>"Deschamps",
21
+ # "work-title"=>"Mr.",
22
+ # "biography"=>"I love accessibility and standards. Don't we all.",
23
+ # "country-code"=>"FR",
24
+ # "city"=>"Arcueil Cedex",
25
+ # "connected-accounts"=>[], #<<<< TODO THIS IS NOT DONE
26
+ # "discr"=>"user",
27
+ # "_links"=>{
28
+ # "self"=>{
29
+ # "href"=>"https://api.w3.org/users/56nw1z8a5uo0sscsgk4kso8g0004008"
30
+ # },
31
+ # "affiliations"=>{
32
+ # "href"=>"https://api.w3.org/users/56nw1z8a5uo0sscsgk4kso8g0004008/affiliations"
33
+ # },
34
+ # "groups"=>{
35
+ # "href"=>"https://api.w3.org/users/56nw1z8a5uo0sscsgk4kso8g0004008/groups"
36
+ # },
37
+ # "specifications"=>{
38
+ # "href"=>"https://api.w3.org/users/56nw1z8a5uo0sscsgk4kso8g0004008/specifications"
39
+ # },
40
+ # "photos"=>[
41
+ # {
42
+ # "href"=>"https://www.w3.org/thumbnails/360/avatar-images/56nw1z8a5uo0sscsgk4kso8g0004008.webp?x-version=1",
43
+ # "name"=>"large"
44
+ # },
45
+ # {
46
+ # "href"=>"https://www.w3.org/thumbnails/100/avatar-images/56nw1z8a5uo0sscsgk4kso8g0004008.webp?x-version=1",
47
+ # "name"=>"thumbnail"
48
+ # },
49
+ # {
50
+ # "href"=>"https://www.w3.org/thumbnails/48/avatar-images/56nw1z8a5uo0sscsgk4kso8g0004008.webp?x-version=1",
51
+ # "name"=>"tiny"
52
+ # }
53
+ # ],
54
+ # "participations"=>{
55
+ # "href"=>"https://api.w3.org/users/56nw1z8a5uo0sscsgk4kso8g0004008/participations"
56
+ # },
57
+ # "chair_of_groups"=>{
58
+ # "href"=>"https://api.w3.org/users/56nw1z8a5uo0sscsgk4kso8g0004008/chair-of-groups"
59
+ # },
60
+ # "team_contact_of_groups"=>{
61
+ # "href"=>"https://api.w3.org/users/56nw1z8a5uo0sscsgk4kso8g0004008/team-contact-of-groups"
62
+ # }
63
+ # }
64
+ # }
65
+ # ],
66
+ # "authorized"=>false,
67
+ # "call-for-translation"=>{
68
+ # "uri"=>"https://www.w3.org/WAI/videos/standards-and-benefits/",
69
+ # "title"=>"Video Introduction to Web Accessibility and W3C Standards",
70
+ # "_links"=>{
71
+ # "self"=>{
72
+ # "href"=>"https://api.w3.org/callsfortranslation/5"
73
+ # },
74
+ # "translations"=>{
75
+ # "href"=>"https://api.w3.org/callsfortranslation/5/translations"
76
+ # }
77
+ # }
78
+ # },
79
+ # "comments"=>"Needs updating. Requested on 22 Feb 2019.",
80
+ # "_links"=>{
81
+ # "self"=>{
82
+ # "href"=>"https://api.w3.org/translations/2"
83
+ # }
84
+ # }
85
+ # }
86
+
87
+ module W3cApi
88
+ module Models
89
+ class TranslationLinks < Lutaml::Model::Serializable
90
+ attribute :self, Link
91
+ end
92
+
93
+ class Translation < Base
94
+ attribute :uri, :string
95
+ attribute :title, :string
96
+ attribute :href, :string
97
+ attribute :language, :string
98
+ attribute :published, :string # Date-time format
99
+ attribute :updated, :string # Date-time format
100
+ attribute :authorized, :boolean
101
+ attribute :lto_name, :string
102
+ attribute :call_for_translation, CallForTranslationRef
103
+ attribute :comments, :string
104
+ attribute :states, :string, collection: true
105
+ attribute :translators, User, collection: true
106
+ attribute :_links, TranslationLinks
107
+
108
+ # Parse date strings to Date objects
109
+ def published_date
110
+ Date.parse(published) if published
111
+ rescue Date::Error
112
+ nil
113
+ end
114
+
115
+ def updated_date
116
+ Date.parse(updated) if updated
117
+ rescue Date::Error
118
+ nil
119
+ end
120
+
121
+ # Get the call for translation as a CallForTranslation object
122
+ def call_for_translation_object
123
+ return nil unless call_for_translation
124
+
125
+ Models::CallForTranslation.new(call_for_translation)
126
+ end
127
+
128
+ # Get the specification version associated with this translation
129
+ def specification_version(client = nil)
130
+ return nil unless call_for_translation&.spec_version
131
+
132
+ call_for_translation.spec_version
133
+ end
134
+
135
+ def self.from_response(response)
136
+ transformed_response = transform_keys(response)
137
+
138
+ translation = new
139
+ transformed_response.each do |key, value|
140
+ case key
141
+ when :_links
142
+ links = value.each_with_object({}) do |(link_name, link_data), acc|
143
+ acc[link_name] = Link.new(href: link_data[:href], title: link_data[:title])
144
+ end
145
+ translation._links = TranslationLinks.new(links)
146
+ when :call_for_translation
147
+ translation.call_for_translation = CallForTranslationRef.new(value)
148
+ when :translators
149
+ # Handle translators as User objects if present
150
+ if value.is_a?(Array)
151
+ users = value.map { |user_data| User.from_response(user_data) }
152
+ translation.translators = users
153
+ end
154
+ else
155
+ translation.send("#{key}=", value) if translation.respond_to?("#{key}=")
156
+ end
157
+ end
158
+ translation
159
+ end
160
+ end
161
+ end
162
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'lutaml/model'
4
+ require_relative 'translation'
5
+ require_relative 'delegate_enumerable'
6
+ require_relative 'collection_base'
7
+
8
+ # {
9
+ # "page"=>1,
10
+ # "limit"=>100,
11
+ # "pages"=>7,
12
+ # "total"=>631,
13
+ # "_links"=>{
14
+ # "translations"=>[
15
+ # {
16
+ # "href"=>"https://api.w3.org/translations/2",
17
+ # "title"=>"Vidéo : introduction à l’accessibilité web et aux standards du W3C",
18
+ # "language"=>"fr"
19
+ # },
20
+ # {
21
+ # "href"=>"https://api.w3.org/translations/3",
22
+ # "title"=>"Vídeo de Introducción a la Accesibilidad Web y Estándares del W3C",
23
+ # "language"=>"es"
24
+ # },
25
+ # {
26
+ # "href"=>"https://api.w3.org/translations/4",
27
+ # "title"=>"Video-introductie over Web-toegankelijkheid en W3C-standaarden",
28
+ # "language"=>"nl"
29
+ # },
30
+
31
+ module W3cApi
32
+ module Models
33
+ class Translations < CollectionBase
34
+ attribute :translations, Translation, collection: true
35
+
36
+ delegate_enumerable :translations
37
+ collection_instance_class Translation, :translations
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,178 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'base'
4
+ require_relative 'connected_account'
5
+ require_relative 'link'
6
+
7
+ # {
8
+ # "id"=>58291,
9
+ # "name"=>"David Grogan",
10
+ # "given"=>"David",
11
+ # "family"=>"Grogan",
12
+ # "work-title"=>"Software Engineer",
13
+ # "connected-accounts"=>[
14
+ # {
15
+ # "created"=>"2019-07-18T21:28:31+00:00",
16
+ # "updated"=>"2021-01-21T10:49:57+00:00",
17
+ # "service"=>"github",
18
+ # "identifier"=>"1801875",
19
+ # "nickname"=>"davidsgrogan",
20
+ # "profile-picture"=>"https://avatars.githubusercontent.com/u/1801875?v=4",
21
+ # "href"=>"https://github.com/davidsgrogan",
22
+ # "_links"=>{
23
+ # "user"=>{
24
+ # "href"=>"https://api.w3.org/users/c2yerd5euz48gcw08s44oww8g4oo8w8"
25
+ # }
26
+ # }
27
+ # }
28
+ # ],
29
+ # "discr"=>"user",
30
+ # "_links"=>{
31
+ # "self"=>{
32
+ # "href"=>"https://api.w3.org/users/c2yerd5euz48gcw08s44oww8g4oo8w8"
33
+ # },
34
+ # "affiliations"=>{
35
+ # "href"=>"https://api.w3.org/users/c2yerd5euz48gcw08s44oww8g4oo8w8/affiliations"
36
+ # },
37
+ # "groups"=>{
38
+ # "href"=>"https://api.w3.org/users/c2yerd5euz48gcw08s44oww8g4oo8w8/groups"
39
+ # },
40
+ # "specifications"=>{
41
+ # "href"=>"https://api.w3.org/users/c2yerd5euz48gcw08s44oww8g4oo8w8/specifications"
42
+ # },
43
+ # "participations"=>{
44
+ # "href"=>"https://api.w3.org/users/c2yerd5euz48gcw08s44oww8g4oo8w8/participations"
45
+ # },
46
+ # "chair_of_groups"=>{
47
+ # "href"=>"https://api.w3.org/users/c2yerd5euz48gcw08s44oww8g4oo8w8/chair-of-groups"
48
+ # },
49
+ # "team_contact_of_groups"=>{
50
+ # "href"=>"https://api.w3.org/users/c2yerd5euz48gcw08s44oww8g4oo8w8/team-contact-of-groups"
51
+ # }
52
+ # }
53
+ # }
54
+
55
+ # {
56
+ # "id": 40757,
57
+ # "name": "Stéphane Deschamps",
58
+ # "given": "Stéphane",
59
+ # "family": "Deschamps",
60
+ # "work_title": "Mr.",
61
+ # "discr": "user",
62
+ # "biography": "I love accessibility and standards. Don't we all.",
63
+ # "country_code": "FR",
64
+ # "city": "Arcueil Cedex",
65
+ # "_links": {
66
+ # "self": {
67
+ # "href": "https://api.w3.org/users/56nw1z8a5uo0sscsgk4kso8g0004008"
68
+ # },
69
+ # "affiliations": {
70
+ # "href": "https://api.w3.org/users/56nw1z8a5uo0sscsgk4kso8g0004008/affiliations"
71
+ # },
72
+ # "groups": {
73
+ # "href": "https://api.w3.org/users/56nw1z8a5uo0sscsgk4kso8g0004008/groups"
74
+ # },
75
+ # "specifications": {
76
+ # "href": "https://api.w3.org/users/56nw1z8a5uo0sscsgk4kso8g0004008/specifications"
77
+ # },
78
+ # "participations": {
79
+ # "href": "https://api.w3.org/users/56nw1z8a5uo0sscsgk4kso8g0004008/participations"
80
+ # },
81
+ # "chair_of_groups": {
82
+ # "href": "https://api.w3.org/users/56nw1z8a5uo0sscsgk4kso8g0004008/chair-of-groups"
83
+ # },
84
+ # "team_contact_of_groups": {
85
+ # "href": "https://api.w3.org/users/56nw1z8a5uo0sscsgk4kso8g0004008/team-contact-of-groups"
86
+ # }
87
+ # }
88
+ # }
89
+
90
+ module W3cApi
91
+ module Models
92
+ class UserPhoto < Lutaml::Model::Serializable
93
+ attribute :href, :string
94
+ attribute :name, :string
95
+ end
96
+
97
+ class UserLinks < Lutaml::Model::Serializable
98
+ attribute :self, Link
99
+ attribute :affiliations, Link
100
+ attribute :groups, Link
101
+ attribute :specifications, Link
102
+ attribute :participations, Link
103
+ attribute :chair_of_groups, Link
104
+ attribute :team_contact_of_groups, Link
105
+ end
106
+
107
+ class User < Base
108
+ attribute :id, :integer
109
+ attribute :href, :string
110
+ attribute :title, :string
111
+ attribute :name, :string
112
+ attribute :email, :string
113
+ attribute :given, :string
114
+ attribute :family, :string
115
+ attribute :work_title, :string
116
+ attribute :discr, :string
117
+ attribute :biography, :string
118
+ attribute :phone, :string
119
+ attribute :country_code, :string
120
+ attribute :country_division, :string
121
+ attribute :city, :string
122
+ attribute :connected_accounts, ConnectedAccount, collection: true
123
+ attribute :_links, UserLinks
124
+
125
+ # Return groups this user is a member of
126
+ def groups(client = nil)
127
+ return nil unless client && _links&.groups
128
+
129
+ client.user_groups(id)
130
+ end
131
+
132
+ # Return specifications this user has contributed to
133
+ def specifications(client = nil)
134
+ return nil unless client && _links&.specifications
135
+
136
+ client.user_specifications(id)
137
+ end
138
+
139
+ def self.from_response(response)
140
+ transformed_response = transform_keys(response)
141
+
142
+ user = new
143
+ transformed_response.each do |key, value|
144
+ case key
145
+ when :connected_accounts
146
+ user.connected_accounts = value.map do |account|
147
+ ConnectedAccount.from_response(account)
148
+ end
149
+ when :_links
150
+ links_data = {}
151
+
152
+ # Handle all standard links
153
+ value.each do |link_name, link_data|
154
+ next if link_name == :photos
155
+
156
+ # Handle photos array separately
157
+
158
+ links_data[link_name] = Link.new(href: link_data[:href], title: link_data[:title])
159
+ end
160
+
161
+ # Handle photos if present
162
+ if value[:photos]
163
+ photos = value[:photos].map do |photo|
164
+ UserPhoto.new(href: photo[:href], name: photo[:name])
165
+ end
166
+ links_data[:photos] = photos
167
+ end
168
+
169
+ user._links = UserLinks.new(links_data)
170
+ else
171
+ user.send("#{key}=", value) if user.respond_to?("#{key}=")
172
+ end
173
+ end
174
+ user
175
+ end
176
+ end
177
+ end
178
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'lutaml/model'
4
+ require_relative 'user'
5
+ require_relative 'delegate_enumerable'
6
+ require_relative 'collection_base'
7
+
8
+ # {
9
+ # "page"=>1,
10
+ # "limit"=>100,
11
+ # "pages"=>8,
12
+ # "total"=>709,
13
+ # "_links"=>{
14
+ # "up"=>{
15
+ # "href"=>"https://api.w3.org/affiliations/35662"
16
+ # },
17
+ # "participants"=>[
18
+ # {
19
+ # "href"=>"https://api.w3.org/users/p3dte6mpoj4sgw888w8kw4w4skwosck",
20
+ # "title"=>"Tab Atkins Jr."
21
+ # },
22
+ # {
23
+ # "href"=>"https://api.w3.org/users/l88ca27n2b4sk00cogosk0skw4s8osc",
24
+ # "title"=>"Chris Wilson"
25
+ # },
26
+ # {
27
+ # "href"=>"https://api.w3.org/users/kjqsxbe6kioko4s88s4wocws848kgw8",
28
+ # "title"=>"David Baron"
29
+ # },
30
+ # {
31
+ # "href"=>"https://api.w3.org/users/t9qq83owlzkck404w0o44so8owc00gg",
32
+ # "title"=>"Rune Lillesveen"
33
+ # },
34
+
35
+ module W3cApi
36
+ module Models
37
+ class Users < CollectionBase
38
+ attribute :users, User, collection: true
39
+
40
+ delegate_enumerable :users
41
+ collection_instance_class User, :users
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,15 @@
1
+ module W3cApi
2
+ module Models
3
+ end
4
+ end
5
+
6
+ require_relative 'models/specifications'
7
+ require_relative 'models/spec_versions'
8
+ require_relative 'models/users'
9
+ require_relative 'models/charters'
10
+ require_relative 'models/translations'
11
+ require_relative 'models/series_collection'
12
+ require_relative 'models/affiliations'
13
+ require_relative 'models/participations'
14
+ require_relative 'models/groups'
15
+ require_relative 'models/ecosystems'
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module W3cApi
4
+ VERSION = "0.1.0"
5
+ end