meibo 0.27.0 → 0.28.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 (100) hide show
  1. checksums.yaml +4 -4
  2. data/.envrc +4 -0
  3. data/.rubocop.yml +14 -2
  4. data/.rubocop_todo.yml +0 -7
  5. data/Gemfile.lock +157 -56
  6. data/README.md +14 -3
  7. data/flake.lock +188 -0
  8. data/flake.nix +55 -0
  9. data/gemset.nix +658 -0
  10. data/lib/meibo/academic_session.rb +21 -21
  11. data/lib/meibo/classroom.rb +47 -34
  12. data/lib/meibo/classroom_set.rb +5 -1
  13. data/lib/meibo/converter.rb +16 -18
  14. data/lib/meibo/course.rb +34 -21
  15. data/lib/meibo/course_set.rb +5 -1
  16. data/lib/meibo/data_model.rb +46 -36
  17. data/lib/meibo/data_set.rb +8 -10
  18. data/lib/meibo/demographic.rb +36 -36
  19. data/lib/meibo/enrollment.rb +22 -22
  20. data/lib/meibo/enrollment_set.rb +9 -2
  21. data/lib/meibo/eportal/v3/classroom.rb +11 -0
  22. data/lib/meibo/eportal/v3/course.rb +11 -0
  23. data/lib/meibo/eportal/v3/enrollment.rb +11 -0
  24. data/lib/meibo/eportal/v3/organization.rb +11 -0
  25. data/lib/meibo/eportal/v3/user.rb +16 -0
  26. data/lib/meibo/eportal/v3/user_profile.rb +11 -0
  27. data/lib/meibo/eportal/v3.rb +30 -0
  28. data/lib/meibo/eportal/v4/user.rb +37 -0
  29. data/lib/meibo/eportal/v4.rb +16 -0
  30. data/lib/meibo/eportal.rb +6 -0
  31. data/lib/meibo/errors.rb +27 -5
  32. data/lib/meibo/factory_bot/academic_session.rb +1 -1
  33. data/lib/meibo/factory_bot/classroom.rb +1 -1
  34. data/lib/meibo/factory_bot/course.rb +1 -1
  35. data/lib/meibo/factory_bot/demographic.rb +1 -1
  36. data/lib/meibo/factory_bot/enrollment.rb +1 -1
  37. data/lib/meibo/factory_bot/manifest.rb +0 -21
  38. data/lib/meibo/factory_bot/organization.rb +1 -1
  39. data/lib/meibo/factory_bot/role.rb +2 -4
  40. data/lib/meibo/factory_bot/user.rb +7 -7
  41. data/lib/meibo/factory_bot/user_profile.rb +1 -1
  42. data/lib/meibo/japan_k12_schools_profile/v1/enrollment.rb +16 -0
  43. data/lib/meibo/japan_k12_schools_profile/v1.rb +20 -0
  44. data/lib/meibo/japan_k12_schools_profile.rb +6 -0
  45. data/lib/meibo/japan_profile/v1_1/academic_session.rb +29 -0
  46. data/lib/meibo/japan_profile/v1_1/classroom.rb +27 -0
  47. data/lib/meibo/japan_profile/v1_1/course.rb +16 -0
  48. data/lib/meibo/japan_profile/v1_1/demographic.rb +11 -0
  49. data/lib/meibo/japan_profile/v1_1/enrollment.rb +47 -0
  50. data/lib/meibo/japan_profile/v1_1/organization.rb +16 -0
  51. data/lib/meibo/japan_profile/v1_1/organization_set.rb +23 -0
  52. data/lib/meibo/japan_profile/v1_1/user.rb +39 -0
  53. data/lib/meibo/japan_profile/v1_1/user_set.rb +17 -0
  54. data/lib/meibo/japan_profile/v1_1.rb +35 -0
  55. data/lib/meibo/japan_profile/v1_1_1.rb +9 -0
  56. data/lib/meibo/japan_profile/v1_2/user.rb +42 -0
  57. data/lib/meibo/japan_profile/v1_2.rb +20 -0
  58. data/lib/meibo/japan_profile.rb +6 -0
  59. data/lib/meibo/manifest.rb +41 -46
  60. data/lib/meibo/oneroster/v1_2/user.rb +43 -0
  61. data/lib/meibo/oneroster/v1_2.rb +62 -0
  62. data/lib/meibo/oneroster/v1_2_1.rb +22 -0
  63. data/lib/meibo/oneroster.rb +6 -0
  64. data/lib/meibo/organization.rb +17 -17
  65. data/lib/meibo/processing_mode.rb +53 -0
  66. data/lib/meibo/profile.rb +8 -4
  67. data/lib/meibo/profiles.rb +12 -120
  68. data/lib/meibo/pse_interoperability_standard/v5.rb +9 -0
  69. data/lib/meibo/pse_interoperability_standard/v6/enrollment.rb +11 -0
  70. data/lib/meibo/pse_interoperability_standard/v6.rb +18 -0
  71. data/lib/meibo/pse_interoperability_standard.rb +6 -0
  72. data/lib/meibo/reader.rb +24 -36
  73. data/lib/meibo/role.rb +24 -24
  74. data/lib/meibo/roster.rb +46 -47
  75. data/lib/meibo/user.rb +35 -35
  76. data/lib/meibo/user_profile.rb +20 -20
  77. data/lib/meibo/user_set.rb +1 -1
  78. data/lib/meibo/version.rb +1 -1
  79. data/lib/meibo.rb +10 -2
  80. data/meibo.gemspec +1 -1
  81. metadata +45 -28
  82. data/lib/meibo/eportal_v3/classroom.rb +0 -15
  83. data/lib/meibo/eportal_v3/course.rb +0 -15
  84. data/lib/meibo/eportal_v3/enrollment.rb +0 -15
  85. data/lib/meibo/eportal_v3/organization.rb +0 -15
  86. data/lib/meibo/eportal_v3/user.rb +0 -16
  87. data/lib/meibo/eportal_v3/user_profile.rb +0 -15
  88. data/lib/meibo/japan_profile/academic_session.rb +0 -29
  89. data/lib/meibo/japan_profile/classroom.rb +0 -24
  90. data/lib/meibo/japan_profile/course.rb +0 -18
  91. data/lib/meibo/japan_profile/demographic.rb +0 -15
  92. data/lib/meibo/japan_profile/enrollment.rb +0 -40
  93. data/lib/meibo/japan_profile/organization.rb +0 -20
  94. data/lib/meibo/japan_profile/organization_set.rb +0 -17
  95. data/lib/meibo/japan_profile/role_jp_m0.rb +0 -26
  96. data/lib/meibo/japan_profile/user.rb +0 -45
  97. data/lib/meibo/japan_profile/user_m0.rb +0 -12
  98. data/lib/meibo/japan_profile/user_set.rb +0 -14
  99. data/lib/meibo/manifest/processing_mode.rb +0 -41
  100. data/lib/meibo/user_m0.rb +0 -47
data/lib/meibo/reader.rb CHANGED
@@ -60,46 +60,46 @@ module Meibo
60
60
  each_user_profile.to_a
61
61
  end
62
62
 
63
- def each_academic_session(&block)
64
- read_data(:file_academic_sessions, &block)
63
+ def each_academic_session(&)
64
+ read_data(:file_academic_sessions, &)
65
65
  end
66
66
 
67
- def each_class(&block)
68
- read_data(:file_classes, &block)
67
+ def each_class(&)
68
+ read_data(:file_classes, &)
69
69
  end
70
70
 
71
- def each_course(&block)
72
- read_data(:file_courses, &block)
71
+ def each_course(&)
72
+ read_data(:file_courses, &)
73
73
  end
74
74
 
75
- def each_demographic(&block)
76
- read_data(:file_demographics, &block)
75
+ def each_demographic(&)
76
+ read_data(:file_demographics, &)
77
77
  end
78
78
 
79
- def each_enrollment(&block)
80
- read_data(:file_enrollments, &block)
79
+ def each_enrollment(&)
80
+ read_data(:file_enrollments, &)
81
81
  end
82
82
 
83
- def each_organization(&block)
84
- read_data(:file_orgs, &block)
83
+ def each_organization(&)
84
+ read_data(:file_orgs, &)
85
85
  end
86
86
 
87
- def each_role(&block)
88
- read_data(:file_roles, &block)
87
+ def each_role(&)
88
+ read_data(:file_roles, &)
89
89
  end
90
90
 
91
- def each_user_profile(&block)
92
- read_data(:file_user_profiles, &block)
91
+ def each_user_profile(&)
92
+ read_data(:file_user_profiles, &)
93
93
  end
94
94
 
95
- def each_user(&block)
96
- read_data(:file_users, &block)
95
+ def each_user(&)
96
+ read_data(:file_users, &)
97
97
  end
98
98
 
99
99
  def manifest
100
100
  @manifest ||= begin
101
101
  filename = Meibo::Manifest.filename
102
- raise CsvFileNotFoundError, "#{filename} not found" unless file_entry?(filename)
102
+ raise CsvFileNotFoundError.new("#{filename} not found", filename: filename) unless file_entry?(filename)
103
103
 
104
104
  csv = @zipfile.read(filename)
105
105
  Meibo::Manifest.parse(csv)
@@ -107,20 +107,8 @@ module Meibo
107
107
  end
108
108
 
109
109
  def load_bulk_files
110
- bulk_file_attributes = manifest.file_attributes(processing_mode: Meibo::Manifest::PROCESSING_MODES[:bulk])
111
- {
112
- file_academic_sessions: :academic_sessions,
113
- file_classes: :classes,
114
- file_courses: :courses,
115
- file_demographics: :demographics,
116
- file_enrollments: :enrollments,
117
- file_orgs: :organizations,
118
- file_roles: :roles,
119
- file_users: :users,
120
- file_user_profiles: :user_profiles
121
- }.filter_map do |file_attribute, data_method|
122
- [data_method, public_send(data_method).to_a] if bulk_file_attributes.include?(file_attribute)
123
- end.to_h
110
+ bulk_file_attributes = manifest.file_attributes(processing_mode: ProcessingMode.bulk)
111
+ bulk_file_attributes.to_h { |file_attribute| [file_attribute, read_data(file_attribute)&.to_a] }.compact
124
112
  end
125
113
 
126
114
  def file_entry?(filename)
@@ -131,12 +119,12 @@ module Meibo
131
119
 
132
120
  private
133
121
 
134
- def read_data(file_attribute, &block)
122
+ def read_data(file_attribute, &)
135
123
  filename = Manifest.filename_for(file_attribute)
136
- raise CsvFileNotFoundError, "#{filename} not found" unless file_entry?(filename)
124
+ raise CsvFileNotFoundError.new("#{filename} not found", filename: filename) unless file_entry?(filename)
137
125
 
138
126
  csv = @zipfile.read(filename)
139
- profile.data_model_for(file_attribute).parse(csv, &block)
127
+ profile.data_model_for(file_attribute)&.parse(csv, &)
140
128
  end
141
129
  end
142
130
  end
data/lib/meibo/role.rb CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  module Meibo
4
4
  class Role
5
+ include DataModel
6
+
5
7
  TYPES = {
6
8
  primary: "primary",
7
9
  secondary: "secondary"
@@ -22,30 +24,28 @@ module Meibo
22
24
  teacher: "teacher"
23
25
  }.freeze
24
26
 
25
- DataModel.define(
26
- self,
27
- attribute_name_to_header_field_map: {
28
- sourced_id: "sourcedId",
29
- status: "status",
30
- date_last_modified: "dateLastModified",
31
- user_sourced_id: "userSourcedId",
32
- role_type: "roleType",
33
- role: "role",
34
- begin_date: "beginDate",
35
- end_date: "endDate",
36
- org_sourced_id: "orgSourcedId",
37
- user_profile_sourced_id: "userProfileSourcedId"
38
- }.freeze,
39
- converters: {
40
- date: %i[begin_date end_date].freeze,
41
- datetime: [:date_last_modified].freeze,
42
- required: %i[sourced_id user_sourced_id role_type role org_sourced_id].freeze,
43
- enum: {
44
- role: [*ROLES.values, ENUM_EXT_PATTERN].freeze,
45
- role_type: TYPES.values.freeze
46
- }.freeze,
47
- status: [:status].freeze
48
- }.freeze
27
+ define_attributes(
28
+ sourced_id: "sourcedId",
29
+ status: "status",
30
+ date_last_modified: "dateLastModified",
31
+ user_sourced_id: "userSourcedId",
32
+ role_type: "roleType",
33
+ role: "role",
34
+ begin_date: "beginDate",
35
+ end_date: "endDate",
36
+ org_sourced_id: "orgSourcedId",
37
+ user_profile_sourced_id: "userProfileSourcedId"
38
+ )
39
+
40
+ define_converters(
41
+ date: %i[begin_date end_date],
42
+ datetime: [:date_last_modified],
43
+ required: %i[sourced_id user_sourced_id role_type role org_sourced_id],
44
+ enum: {
45
+ role: [*ROLES.values, ENUM_EXT_PATTERN],
46
+ role_type: TYPES.values
47
+ },
48
+ status: [:status]
49
49
  )
50
50
 
51
51
  def initialize(sourced_id:, user_sourced_id:, role_type:, role:, org_sourced_id:, status: nil, date_last_modified: nil,
data/lib/meibo/roster.rb CHANGED
@@ -6,6 +6,20 @@ require "csv"
6
6
  module Meibo
7
7
  class Roster
8
8
  class << self
9
+ def file_attribute_name_to_data_attribute_name(file_attribute)
10
+ {
11
+ file_academic_sessions: :academic_sessions,
12
+ file_classes: :classes,
13
+ file_courses: :courses,
14
+ file_demographics: :demographics,
15
+ file_enrollments: :enrollments,
16
+ file_orgs: :organizations,
17
+ file_roles: :roles,
18
+ file_user_profiles: :user_profiles,
19
+ file_users: :users
20
+ }[file_attribute]
21
+ end
22
+
9
23
  def from_file(file_path, profile: Meibo.current_profile)
10
24
  Reader.open(file_path, profile: profile) do |reader|
11
25
  return read_data(reader, profile)
@@ -18,9 +32,9 @@ module Meibo
18
32
  end
19
33
  end
20
34
 
21
- def open(io_or_path, **opts)
35
+ def open(io_or_path, **)
22
36
  m = io_or_path.is_a?(IO) ? :from_buffer : :from_file
23
- roster = public_send(m, io_or_path, **opts)
37
+ roster = public_send(m, io_or_path, **)
24
38
  return roster unless block_given?
25
39
 
26
40
  Meibo.with_roster(roster) { yield roster }
@@ -32,20 +46,19 @@ module Meibo
32
46
  begin
33
47
  manifest = reader.manifest
34
48
  rescue CsvFileNotFoundError
35
- raise NotSupportedError, "OneRoster 1.0\u306F\u30B5\u30DD\u30FC\u30C8\u3057\u3066\u3044\u307E\u305B\u3093"
49
+ raise NotSupportedError, "OneRoster 1.0はサポートしていません"
36
50
  rescue StandardError
37
51
  raise NotSupportedError, "#{Meibo::Manifest.filename}の読み込みに失敗しました"
38
52
  end
39
53
 
40
- validate_manifest_version(manifest.manifest_version)
41
- validate_oneroster_version(manifest.oneroster_version)
54
+ validate_manifest_version(profile, manifest.manifest_version)
55
+ validate_oneroster_version(profile, manifest.oneroster_version)
42
56
  validate_supported_processing_mode(manifest)
43
- processing_modes = Meibo::Manifest::PROCESSING_MODES
44
- validate_absent_files(reader, manifest.filenames(processing_mode: processing_modes[:absent]))
45
- validate_bulk_files(reader, manifest.filenames(processing_mode: processing_modes[:bulk]))
57
+ validate_absent_files(reader, manifest.filenames(processing_mode: ProcessingMode.absent))
58
+ validate_bulk_files(reader, manifest.filenames(processing_mode: ProcessingMode.bulk))
46
59
 
47
- new(manifest_properties: manifest.to_h, profile: profile,
48
- **reader.load_bulk_files).tap(&:check_semantically_consistent)
60
+ data_attributes = reader.load_bulk_files.transform_keys { |file_attribute| file_attribute_name_to_data_attribute_name(file_attribute) }
61
+ new(manifest_properties: manifest.to_h, profile: profile, **data_attributes).tap(&:check_semantically_consistent)
49
62
  end
50
63
 
51
64
  def validate_absent_files(reader, absent_filenames)
@@ -64,22 +77,22 @@ module Meibo
64
77
  end
65
78
  end
66
79
 
67
- def validate_manifest_version(manifest_version)
68
- return if manifest_version == Meibo::Manifest::MANIFEST_VERSION
80
+ def validate_manifest_version(profile, manifest_version)
81
+ return if manifest_version == profile.manifest_version
69
82
 
70
83
  raise NotSupportedError, "manifest.version: #{manifest_version}はサポートしていません"
71
84
  end
72
85
 
73
- def validate_oneroster_version(oneroster_version)
74
- return if oneroster_version == Meibo::Manifest::ONEROSTER_VERSION
86
+ def validate_oneroster_version(profile, oneroster_version)
87
+ return if oneroster_version == profile.oneroster_version
75
88
 
76
89
  raise NotSupportedError, "oneroster.version: #{oneroster_version}はサポートしていません"
77
90
  end
78
91
 
79
92
  def validate_supported_processing_mode(manifest)
80
- return if manifest.file_attributes(processing_mode: Meibo::Manifest::PROCESSING_MODES[:delta]).empty?
93
+ return if manifest.file_attributes(processing_mode: ProcessingMode.delta).empty?
81
94
 
82
- raise NotSupportedError, "DELTA\u306F\u30B5\u30DD\u30FC\u30C8\u3057\u3066\u3044\u307E\u305B\u3093"
95
+ raise NotSupportedError, "DELTAはサポートしていません"
83
96
  end
84
97
  end
85
98
 
@@ -90,15 +103,15 @@ module Meibo
90
103
  courses: [], demographics: [], enrollments: [], organizations: [], roles: [], user_profiles: [], users: [])
91
104
  @profile = profile
92
105
  @manifest_properties = manifest_properties
93
- @academic_sessions = profile.data_set_for(:academic_sessions).new(academic_sessions, roster: self)
94
- @classes = profile.data_set_for(:classes).new(classes, roster: self)
95
- @courses = profile.data_set_for(:courses).new(courses, roster: self)
96
- @demographics = profile.data_set_for(:demographics).new(demographics, roster: self)
97
- @enrollments = profile.data_set_for(:enrollments).new(enrollments, roster: self)
98
- @organizations = profile.data_set_for(:orgs).new(organizations, roster: self)
99
- @roles = profile.data_set_for(:roles).new(roles, roster: self)
100
- @user_profiles = profile.data_set_for(:user_profiles).new(user_profiles, roster: self)
101
- @users = profile.data_set_for(:users).new(users, roster: self)
106
+ @academic_sessions = profile.data_set_for(:file_academic_sessions).new(academic_sessions, roster: self)
107
+ @classes = profile.data_set_for(:file_classes).new(classes, roster: self)
108
+ @courses = profile.data_set_for(:file_courses).new(courses, roster: self)
109
+ @demographics = profile.data_set_for(:file_demographics).new(demographics, roster: self)
110
+ @enrollments = profile.data_set_for(:file_enrollments).new(enrollments, roster: self)
111
+ @organizations = profile.data_set_for(:file_orgs).new(organizations, roster: self)
112
+ @roles = profile.data_set_for(:file_roles).new(roles, roster: self)
113
+ @user_profiles = profile.data_set_for(:file_user_profiles).new(user_profiles, roster: self)
114
+ @users = profile.data_set_for(:file_users).new(users, roster: self)
102
115
  end
103
116
 
104
117
  def builder
@@ -119,8 +132,8 @@ module Meibo
119
132
  ].each(&:check_semantically_consistent)
120
133
  end
121
134
 
122
- def write_to_buffer(io)
123
- Zip::File.open_buffer(io) do |zipfile|
135
+ def write_to_buffer(io, create: true)
136
+ Zip::File.open_buffer(io, create:) do |zipfile|
124
137
  write(zipfile)
125
138
  end
126
139
  end
@@ -135,8 +148,8 @@ module Meibo
135
148
 
136
149
  def write(zipfile)
137
150
  manifest = build_manifest
138
- zipfile.get_output_stream(::Meibo::Manifest.filename) do |f|
139
- f.puts ::Meibo::Manifest.header_fields.to_csv
151
+ zipfile.get_output_stream(Manifest.filename) do |f|
152
+ f.puts Manifest.header_fields.to_csv
140
153
  manifest.to_a.each do |row|
141
154
  f.puts row.to_csv
142
155
  end
@@ -156,24 +169,10 @@ module Meibo
156
169
  end
157
170
  end
158
171
 
159
- def build_manifest
160
- new_manifest_properties = file_properties.merge(manifest_properties)
161
- Meibo::Manifest.build_from_default(**new_manifest_properties)
162
- end
172
+ def build_manifest = Manifest.new(**profile.manifest_properties, **manifest_properties, **file_properties)
163
173
 
164
174
  def data_for(file_attribute)
165
- data_method = {
166
- file_academic_sessions: :academic_sessions,
167
- file_classes: :classes,
168
- file_courses: :courses,
169
- file_demographics: :demographics,
170
- file_enrollments: :enrollments,
171
- file_orgs: :organizations,
172
- file_roles: :roles,
173
- file_user_profiles: :user_profiles,
174
- file_users: :users
175
- }[file_attribute]
176
- public_send(data_method)
175
+ public_send(self.class.file_attribute_name_to_data_attribute_name(file_attribute))
177
176
  end
178
177
 
179
178
  def file_properties
@@ -192,9 +191,9 @@ module Meibo
192
191
 
193
192
  def procesing_mode(data)
194
193
  if data.empty?
195
- Meibo::Manifest::PROCESSING_MODES[:absent]
194
+ ProcessingMode.absent
196
195
  else
197
- Meibo::Manifest::PROCESSING_MODES[:bulk]
196
+ ProcessingMode.bulk
198
197
  end
199
198
  end
200
199
  end
data/lib/meibo/user.rb CHANGED
@@ -2,42 +2,42 @@
2
2
 
3
3
  module Meibo
4
4
  class User
5
- USER_ID_FORMAT_REGEXP = /\A\{[^:}]+:[^}]+\}\z/.freeze
5
+ include DataModel
6
6
 
7
- DataModel.define(
8
- self,
9
- attribute_name_to_header_field_map: {
10
- sourced_id: "sourcedId",
11
- status: "status",
12
- date_last_modified: "dateLastModified",
13
- enabled_user: "enabledUser",
14
- username: "username",
15
- user_ids: "userIds",
16
- given_name: "givenName",
17
- family_name: "familyName",
18
- middle_name: "middleName",
19
- identifier: "identifier",
20
- email: "email",
21
- sms: "sms",
22
- phone: "phone",
23
- agent_sourced_ids: "agentSourcedIds",
24
- grades: "grades",
25
- password: "password",
26
- user_master_identifier: "userMasterIdentifier",
27
- preferred_given_name: "preferredGivenName",
28
- preferred_middle_name: "preferredMiddleName",
29
- preferred_family_name: "preferredFamilyName",
30
- primary_org_sourced_id: "primaryOrgSourcedId",
31
- pronouns: "pronouns"
32
- }.freeze,
33
- converters: {
34
- boolean: [:enabled_user].freeze,
35
- datetime: [:date_last_modified].freeze,
36
- list: %i[user_ids agent_sourced_ids grades].freeze,
37
- required: %i[sourced_id enabled_user username given_name family_name].freeze,
38
- status: [:status].freeze,
39
- user_ids: [:user_ids].freeze
40
- }.freeze
7
+ USER_ID_FORMAT_REGEXP = /\A\{[^:}]+:[^}]+\}\z/
8
+
9
+ define_attributes(
10
+ sourced_id: "sourcedId",
11
+ status: "status",
12
+ date_last_modified: "dateLastModified",
13
+ enabled_user: "enabledUser",
14
+ username: "username",
15
+ user_ids: "userIds",
16
+ given_name: "givenName",
17
+ family_name: "familyName",
18
+ middle_name: "middleName",
19
+ identifier: "identifier",
20
+ email: "email",
21
+ sms: "sms",
22
+ phone: "phone",
23
+ agent_sourced_ids: "agentSourcedIds",
24
+ grades: "grades",
25
+ password: "password",
26
+ user_master_identifier: "userMasterIdentifier",
27
+ preferred_given_name: "preferredGivenName",
28
+ preferred_middle_name: "preferredMiddleName",
29
+ preferred_family_name: "preferredFamilyName",
30
+ primary_org_sourced_id: "primaryOrgSourcedId",
31
+ pronouns: "pronouns"
32
+ )
33
+
34
+ define_converters(
35
+ boolean: [:enabled_user],
36
+ datetime: [:date_last_modified],
37
+ list: %i[user_ids agent_sourced_ids grades],
38
+ required: %i[sourced_id enabled_user username given_name family_name],
39
+ status: [:status],
40
+ user_ids: [:user_ids]
41
41
  )
42
42
 
43
43
  def initialize(sourced_id:, username:, given_name:, family_name:, status: nil, date_last_modified: nil,
@@ -2,26 +2,26 @@
2
2
 
3
3
  module Meibo
4
4
  class UserProfile
5
- DataModel.define(
6
- self,
7
- attribute_name_to_header_field_map: {
8
- sourced_id: "sourcedId",
9
- status: "status",
10
- date_last_modified: "dateLastModified",
11
- user_sourced_id: "userSourcedId",
12
- profile_type: "profileType",
13
- vendor_id: "vendorId",
14
- application_id: "applicationId",
15
- description: "description",
16
- credential_type: "credentialType",
17
- username: "username",
18
- password: "password"
19
- },
20
- converters: {
21
- datetime: [:date_last_modified],
22
- required: %i[sourced_id user_sourced_id profile_type vendor_id credential_type username],
23
- status: [:status]
24
- }
5
+ include DataModel
6
+
7
+ define_attributes(
8
+ sourced_id: "sourcedId",
9
+ status: "status",
10
+ date_last_modified: "dateLastModified",
11
+ user_sourced_id: "userSourcedId",
12
+ profile_type: "profileType",
13
+ vendor_id: "vendorId",
14
+ application_id: "applicationId",
15
+ description: "description",
16
+ credential_type: "credentialType",
17
+ username: "username",
18
+ password: "password"
19
+ )
20
+
21
+ define_converters(
22
+ datetime: [:date_last_modified],
23
+ required: %i[sourced_id user_sourced_id profile_type vendor_id credential_type username],
24
+ status: [:status]
25
25
  )
26
26
 
27
27
  def initialize(sourced_id:, user_sourced_id:, profile_type:, vendor_id:, credential_type:, username:, status: nil, date_last_modified: nil,
@@ -5,7 +5,7 @@ module Meibo
5
5
  def check_semantically_consistent
6
6
  super
7
7
 
8
- raise Error, "userMasterIdentifier\u304C\u91CD\u8907\u3057\u3066\u3044\u307E\u3059" if @data.filter_map(&:user_master_identifier).tally.values.any? { |v| v > 1 }
8
+ raise Error, "userMasterIdentifierが重複しています" if @data.filter_map(&:user_master_identifier).tally.values.any? { |v| v > 1 }
9
9
 
10
10
  each do |user|
11
11
  roster.organizations.find(user.primary_org_sourced_id) if user.primary_org_sourced_id
data/lib/meibo/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Meibo
4
- VERSION = "0.27.0"
4
+ VERSION = "0.28.0"
5
5
  end
data/lib/meibo.rb CHANGED
@@ -4,6 +4,14 @@ require "zeitwerk"
4
4
  loader = Zeitwerk::Loader.for_gem
5
5
  loader.ignore("#{__dir__}/meibo/errors.rb")
6
6
  loader.ignore("#{__dir__}/meibo/factory_bot")
7
+ loader.inflector.inflect(
8
+ "oneroster" => "OneRoster",
9
+ "pse_interoperability_standard" => "PSEInteroperabilityStandard",
10
+ "v1_1_1" => "V1_1_1",
11
+ "v1_1" => "V1_1",
12
+ "v1_2_1" => "V1_2_1",
13
+ "v1_2" => "V1_2"
14
+ )
7
15
  loader.setup
8
16
 
9
17
  require_relative "meibo/version"
@@ -11,7 +19,7 @@ require_relative "meibo/errors"
11
19
 
12
20
  module Meibo
13
21
  CSV_ENCODING = "UTF-8"
14
- ENUM_EXT_PATTERN = /\Aext:[a-zA-Z0-9.\-_]+\z/.freeze
22
+ ENUM_EXT_PATTERN = /\Aext:[a-zA-Z0-9.\-_]+\z/
15
23
 
16
24
  class << self
17
25
  attr_accessor :default_profile
@@ -50,4 +58,4 @@ end
50
58
 
51
59
  loader.eager_load
52
60
 
53
- Meibo.default_profile = Meibo::Profiles["v1.2"]
61
+ Meibo.default_profile = Meibo::Profiles["IMS OneRoster: CSV Binding Final Release v1.2.1"]
data/meibo.gemspec CHANGED
@@ -11,7 +11,7 @@ Gem::Specification.new do |spec|
11
11
  spec.summary = "Meibo is a ruby library for OneRoster CSV Binding Japan Profile."
12
12
  spec.homepage = "https://github.com/hanachin/meibo"
13
13
  spec.license = "MIT"
14
- spec.required_ruby_version = ">= 2.7.0"
14
+ spec.required_ruby_version = ">= 3.4.0"
15
15
 
16
16
  spec.metadata["allowed_push_host"] = "https://rubygems.org/"
17
17