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.
- checksums.yaml +4 -4
- data/.envrc +4 -0
- data/.rubocop.yml +14 -2
- data/.rubocop_todo.yml +0 -7
- data/Gemfile.lock +157 -56
- data/README.md +14 -3
- data/flake.lock +188 -0
- data/flake.nix +55 -0
- data/gemset.nix +658 -0
- data/lib/meibo/academic_session.rb +21 -21
- data/lib/meibo/classroom.rb +47 -34
- data/lib/meibo/classroom_set.rb +5 -1
- data/lib/meibo/converter.rb +16 -18
- data/lib/meibo/course.rb +34 -21
- data/lib/meibo/course_set.rb +5 -1
- data/lib/meibo/data_model.rb +46 -36
- data/lib/meibo/data_set.rb +8 -10
- data/lib/meibo/demographic.rb +36 -36
- data/lib/meibo/enrollment.rb +22 -22
- data/lib/meibo/enrollment_set.rb +9 -2
- data/lib/meibo/eportal/v3/classroom.rb +11 -0
- data/lib/meibo/eportal/v3/course.rb +11 -0
- data/lib/meibo/eportal/v3/enrollment.rb +11 -0
- data/lib/meibo/eportal/v3/organization.rb +11 -0
- data/lib/meibo/eportal/v3/user.rb +16 -0
- data/lib/meibo/eportal/v3/user_profile.rb +11 -0
- data/lib/meibo/eportal/v3.rb +30 -0
- data/lib/meibo/eportal/v4/user.rb +37 -0
- data/lib/meibo/eportal/v4.rb +16 -0
- data/lib/meibo/eportal.rb +6 -0
- data/lib/meibo/errors.rb +27 -5
- data/lib/meibo/factory_bot/academic_session.rb +1 -1
- data/lib/meibo/factory_bot/classroom.rb +1 -1
- data/lib/meibo/factory_bot/course.rb +1 -1
- data/lib/meibo/factory_bot/demographic.rb +1 -1
- data/lib/meibo/factory_bot/enrollment.rb +1 -1
- data/lib/meibo/factory_bot/manifest.rb +0 -21
- data/lib/meibo/factory_bot/organization.rb +1 -1
- data/lib/meibo/factory_bot/role.rb +2 -4
- data/lib/meibo/factory_bot/user.rb +7 -7
- data/lib/meibo/factory_bot/user_profile.rb +1 -1
- data/lib/meibo/japan_k12_schools_profile/v1/enrollment.rb +16 -0
- data/lib/meibo/japan_k12_schools_profile/v1.rb +20 -0
- data/lib/meibo/japan_k12_schools_profile.rb +6 -0
- data/lib/meibo/japan_profile/v1_1/academic_session.rb +29 -0
- data/lib/meibo/japan_profile/v1_1/classroom.rb +27 -0
- data/lib/meibo/japan_profile/v1_1/course.rb +16 -0
- data/lib/meibo/japan_profile/v1_1/demographic.rb +11 -0
- data/lib/meibo/japan_profile/v1_1/enrollment.rb +47 -0
- data/lib/meibo/japan_profile/v1_1/organization.rb +16 -0
- data/lib/meibo/japan_profile/v1_1/organization_set.rb +23 -0
- data/lib/meibo/japan_profile/v1_1/user.rb +39 -0
- data/lib/meibo/japan_profile/v1_1/user_set.rb +17 -0
- data/lib/meibo/japan_profile/v1_1.rb +35 -0
- data/lib/meibo/japan_profile/v1_1_1.rb +9 -0
- data/lib/meibo/japan_profile/v1_2/user.rb +42 -0
- data/lib/meibo/japan_profile/v1_2.rb +20 -0
- data/lib/meibo/japan_profile.rb +6 -0
- data/lib/meibo/manifest.rb +41 -46
- data/lib/meibo/oneroster/v1_2/user.rb +43 -0
- data/lib/meibo/oneroster/v1_2.rb +62 -0
- data/lib/meibo/oneroster/v1_2_1.rb +22 -0
- data/lib/meibo/oneroster.rb +6 -0
- data/lib/meibo/organization.rb +17 -17
- data/lib/meibo/processing_mode.rb +53 -0
- data/lib/meibo/profile.rb +8 -4
- data/lib/meibo/profiles.rb +12 -120
- data/lib/meibo/pse_interoperability_standard/v5.rb +9 -0
- data/lib/meibo/pse_interoperability_standard/v6/enrollment.rb +11 -0
- data/lib/meibo/pse_interoperability_standard/v6.rb +18 -0
- data/lib/meibo/pse_interoperability_standard.rb +6 -0
- data/lib/meibo/reader.rb +24 -36
- data/lib/meibo/role.rb +24 -24
- data/lib/meibo/roster.rb +46 -47
- data/lib/meibo/user.rb +35 -35
- data/lib/meibo/user_profile.rb +20 -20
- data/lib/meibo/user_set.rb +1 -1
- data/lib/meibo/version.rb +1 -1
- data/lib/meibo.rb +10 -2
- data/meibo.gemspec +1 -1
- metadata +45 -28
- data/lib/meibo/eportal_v3/classroom.rb +0 -15
- data/lib/meibo/eportal_v3/course.rb +0 -15
- data/lib/meibo/eportal_v3/enrollment.rb +0 -15
- data/lib/meibo/eportal_v3/organization.rb +0 -15
- data/lib/meibo/eportal_v3/user.rb +0 -16
- data/lib/meibo/eportal_v3/user_profile.rb +0 -15
- data/lib/meibo/japan_profile/academic_session.rb +0 -29
- data/lib/meibo/japan_profile/classroom.rb +0 -24
- data/lib/meibo/japan_profile/course.rb +0 -18
- data/lib/meibo/japan_profile/demographic.rb +0 -15
- data/lib/meibo/japan_profile/enrollment.rb +0 -40
- data/lib/meibo/japan_profile/organization.rb +0 -20
- data/lib/meibo/japan_profile/organization_set.rb +0 -17
- data/lib/meibo/japan_profile/role_jp_m0.rb +0 -26
- data/lib/meibo/japan_profile/user.rb +0 -45
- data/lib/meibo/japan_profile/user_m0.rb +0 -12
- data/lib/meibo/japan_profile/user_set.rb +0 -14
- data/lib/meibo/manifest/processing_mode.rb +0 -41
- 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(&
|
|
64
|
-
read_data(:file_academic_sessions, &
|
|
63
|
+
def each_academic_session(&)
|
|
64
|
+
read_data(:file_academic_sessions, &)
|
|
65
65
|
end
|
|
66
66
|
|
|
67
|
-
def each_class(&
|
|
68
|
-
read_data(:file_classes, &
|
|
67
|
+
def each_class(&)
|
|
68
|
+
read_data(:file_classes, &)
|
|
69
69
|
end
|
|
70
70
|
|
|
71
|
-
def each_course(&
|
|
72
|
-
read_data(:file_courses, &
|
|
71
|
+
def each_course(&)
|
|
72
|
+
read_data(:file_courses, &)
|
|
73
73
|
end
|
|
74
74
|
|
|
75
|
-
def each_demographic(&
|
|
76
|
-
read_data(:file_demographics, &
|
|
75
|
+
def each_demographic(&)
|
|
76
|
+
read_data(:file_demographics, &)
|
|
77
77
|
end
|
|
78
78
|
|
|
79
|
-
def each_enrollment(&
|
|
80
|
-
read_data(:file_enrollments, &
|
|
79
|
+
def each_enrollment(&)
|
|
80
|
+
read_data(:file_enrollments, &)
|
|
81
81
|
end
|
|
82
82
|
|
|
83
|
-
def each_organization(&
|
|
84
|
-
read_data(:file_orgs, &
|
|
83
|
+
def each_organization(&)
|
|
84
|
+
read_data(:file_orgs, &)
|
|
85
85
|
end
|
|
86
86
|
|
|
87
|
-
def each_role(&
|
|
88
|
-
read_data(:file_roles, &
|
|
87
|
+
def each_role(&)
|
|
88
|
+
read_data(:file_roles, &)
|
|
89
89
|
end
|
|
90
90
|
|
|
91
|
-
def each_user_profile(&
|
|
92
|
-
read_data(:file_user_profiles, &
|
|
91
|
+
def each_user_profile(&)
|
|
92
|
+
read_data(:file_user_profiles, &)
|
|
93
93
|
end
|
|
94
94
|
|
|
95
|
-
def each_user(&
|
|
96
|
-
read_data(:file_users, &
|
|
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
|
|
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:
|
|
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, &
|
|
122
|
+
def read_data(file_attribute, &)
|
|
135
123
|
filename = Manifest.filename_for(file_attribute)
|
|
136
|
-
raise CsvFileNotFoundError
|
|
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)
|
|
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
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
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, **
|
|
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, **
|
|
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
|
|
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
|
-
|
|
44
|
-
|
|
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
|
-
|
|
48
|
-
|
|
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 ==
|
|
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 ==
|
|
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:
|
|
93
|
+
return if manifest.file_attributes(processing_mode: ProcessingMode.delta).empty?
|
|
81
94
|
|
|
82
|
-
raise NotSupportedError, "DELTA
|
|
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(:
|
|
94
|
-
@classes = profile.data_set_for(:
|
|
95
|
-
@courses = profile.data_set_for(:
|
|
96
|
-
@demographics = profile.data_set_for(:
|
|
97
|
-
@enrollments = profile.data_set_for(:
|
|
98
|
-
@organizations = profile.data_set_for(:
|
|
99
|
-
@roles = profile.data_set_for(:
|
|
100
|
-
@user_profiles = profile.data_set_for(:
|
|
101
|
-
@users = profile.data_set_for(:
|
|
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(
|
|
139
|
-
f.puts
|
|
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
|
-
|
|
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
|
-
|
|
194
|
+
ProcessingMode.absent
|
|
196
195
|
else
|
|
197
|
-
|
|
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
|
-
|
|
5
|
+
include DataModel
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
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,
|
data/lib/meibo/user_profile.rb
CHANGED
|
@@ -2,26 +2,26 @@
|
|
|
2
2
|
|
|
3
3
|
module Meibo
|
|
4
4
|
class UserProfile
|
|
5
|
-
DataModel
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
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,
|
data/lib/meibo/user_set.rb
CHANGED
|
@@ -5,7 +5,7 @@ module Meibo
|
|
|
5
5
|
def check_semantically_consistent
|
|
6
6
|
super
|
|
7
7
|
|
|
8
|
-
raise Error, "userMasterIdentifier
|
|
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
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
|
|
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 = ">=
|
|
14
|
+
spec.required_ruby_version = ">= 3.4.0"
|
|
15
15
|
|
|
16
16
|
spec.metadata["allowed_push_host"] = "https://rubygems.org/"
|
|
17
17
|
|