mumuki-domain 6.7.2 → 7.0.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/README.md +3 -3
- data/app/models/application_record.rb +11 -0
- data/app/models/assignment.rb +7 -1
- data/app/models/concerns/with_assignments.rb +3 -3
- data/app/models/content.rb +1 -1
- data/app/models/course.rb +5 -3
- data/app/models/exercise.rb +2 -0
- data/app/models/guide.rb +4 -2
- data/app/models/invitation.rb +1 -1
- data/app/models/language.rb +28 -8
- data/app/models/organization.rb +15 -7
- data/app/models/user.rb +7 -3
- data/db/migrate/20170621222902_introduce_settings_and_themes.rb +3 -3
- data/db/migrate/20190530173142_add_organization_to_assignment.rb +5 -0
- data/db/migrate/20190702003600_add_loading_flags_to_language.rb +6 -0
- data/db/migrate/20190702182407_add_new_profile_fields.rb +6 -0
- data/lib/mumuki/domain/extensions/module.rb +17 -0
- data/lib/mumuki/domain/extensions.rb +1 -0
- data/lib/mumuki/domain/factories/assignments_factory.rb +1 -0
- data/lib/mumuki/domain/factories/organization_factory.rb +17 -6
- data/lib/mumuki/domain/factories/user_factory.rb +2 -0
- data/lib/mumuki/domain/helpers/course.rb +13 -0
- data/lib/mumuki/domain/helpers/organization.rb +72 -0
- data/lib/mumuki/domain/helpers/user.rb +109 -0
- data/lib/mumuki/domain/helpers.rb +8 -0
- data/lib/mumuki/domain/organization/profile.rb +39 -0
- data/lib/mumuki/domain/organization/settings.rb +27 -0
- data/lib/mumuki/domain/organization/theme.rb +4 -0
- data/lib/mumuki/domain/organization.rb +8 -0
- data/lib/mumuki/domain/stores/bibliotheca_store.rb +29 -0
- data/lib/mumuki/domain/stores/exercise_schema.rb +37 -0
- data/lib/mumuki/domain/stores/guide_schema.rb +34 -0
- data/lib/mumuki/domain/stores/thesaurus_store.rb +79 -0
- data/lib/mumuki/domain/stores.rb +4 -0
- data/lib/mumuki/domain/syncable/with_resource_fields.rb +18 -0
- data/{app/models/concerns → lib/mumuki/domain}/syncable.rb +3 -1
- data/lib/mumuki/domain/version.rb +1 -1
- data/lib/mumuki/domain.rb +10 -0
- metadata +31 -12
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: dd3eb525947de7658551f36161b8f937d6d9e192b02c9f9a60f72e5170a612f4
|
|
4
|
+
data.tar.gz: 1c2a08701b38e3aa25ce125739359500a727582c3d42ddf2f4ad7b3df537df36
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9cae5a11974987b65a5231351c7e2e51c6c05d9d11071f98a3ecf34fb5aadb909093d3fb2d1340e7d8ba78c778baf2504e74985d741b49d7c985652d848def3e
|
|
7
|
+
data.tar.gz: 6e39bad09b6c1c4fe9afc57ddf8d77407253d9fe6e5c38fde08223d02c8d10710357b011b8009d553fadf1d106b4798247e9f09d5310dbf8f85e98e5c237dfb0
|
data/README.md
CHANGED
|
@@ -43,7 +43,7 @@ _as defined in `Language#to_resource_h`_
|
|
|
43
43
|
theme
|
|
44
44
|
```
|
|
45
45
|
|
|
46
|
-
_as defined in `
|
|
46
|
+
_as defined in `Mumuki::Domain::Helpers::Organization#to_resource_h`_
|
|
47
47
|
|
|
48
48
|
### `User`
|
|
49
49
|
|
|
@@ -57,7 +57,7 @@ _as defined in `Mumukit::Platform::Organization::Helpers#to_resource_h`_
|
|
|
57
57
|
permissions
|
|
58
58
|
```
|
|
59
59
|
|
|
60
|
-
_as defined in `
|
|
60
|
+
_as defined in `Mumuki::Domain::Helpers::User#to_resource_h`_
|
|
61
61
|
|
|
62
62
|
### `Course`
|
|
63
63
|
|
|
@@ -70,7 +70,7 @@ _as defined in `Mumukit::Platform::User::Helpers#to_resource_h`_
|
|
|
70
70
|
description
|
|
71
71
|
```
|
|
72
72
|
|
|
73
|
-
_as defined in `
|
|
73
|
+
_as defined in `Mumuki::Domain::Helpers::Course#to_resource_h`_
|
|
74
74
|
|
|
75
75
|
## Content Hashes
|
|
76
76
|
|
|
@@ -109,6 +109,17 @@ class ApplicationRecord < ActiveRecord::Base
|
|
|
109
109
|
end
|
|
110
110
|
end
|
|
111
111
|
|
|
112
|
+
## Partially implements resource-hash protocol, by
|
|
113
|
+
## defining `to_resource_h` and helper methods `resource_fields` and `slice_resource_h`
|
|
114
|
+
## using the given fields
|
|
115
|
+
def self.resource_fields(*fields)
|
|
116
|
+
include Mumuki::Domain::Syncable::WithResourceFields
|
|
117
|
+
|
|
118
|
+
define_singleton_method :resource_fields do
|
|
119
|
+
fields
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
112
123
|
private
|
|
113
124
|
|
|
114
125
|
def raise_foreign_key_error!
|
data/app/models/assignment.rb
CHANGED
|
@@ -12,6 +12,7 @@ class Assignment < ApplicationRecord
|
|
|
12
12
|
primary_key: :submission_id,
|
|
13
13
|
dependent: :destroy
|
|
14
14
|
|
|
15
|
+
belongs_to :organization
|
|
15
16
|
belongs_to :submitter, class_name: 'User'
|
|
16
17
|
|
|
17
18
|
validates_presence_of :exercise, :submitter
|
|
@@ -126,7 +127,7 @@ class Assignment < ApplicationRecord
|
|
|
126
127
|
end
|
|
127
128
|
|
|
128
129
|
def to_resource_h
|
|
129
|
-
as_json(except: [:exercise_id, :submission_id, :id, :submitter_id, :solution, :created_at, :updated_at, :submission_status],
|
|
130
|
+
as_json(except: [:exercise_id, :submission_id, :organization_id, :id, :submitter_id, :solution, :created_at, :updated_at, :submission_status],
|
|
130
131
|
include: {
|
|
131
132
|
guide: {
|
|
132
133
|
only: [:slug, :name],
|
|
@@ -189,6 +190,11 @@ class Assignment < ApplicationRecord
|
|
|
189
190
|
exercise.files_for(current_content)
|
|
190
191
|
end
|
|
191
192
|
|
|
193
|
+
def save!(*)
|
|
194
|
+
self.organization = Organization.current
|
|
195
|
+
super
|
|
196
|
+
end
|
|
197
|
+
|
|
192
198
|
private
|
|
193
199
|
|
|
194
200
|
def update_submissions_count!
|
|
@@ -18,7 +18,7 @@ module WithAssignments
|
|
|
18
18
|
messages_for(user).present?
|
|
19
19
|
end
|
|
20
20
|
|
|
21
|
-
def find_assignment_for(user)
|
|
21
|
+
def find_assignment_for(user, _organization)
|
|
22
22
|
assignments.find_by(submitter: user)
|
|
23
23
|
end
|
|
24
24
|
|
|
@@ -26,7 +26,7 @@ module WithAssignments
|
|
|
26
26
|
assignment_for(user).status if user
|
|
27
27
|
end
|
|
28
28
|
|
|
29
|
-
def assignment_for(user)
|
|
30
|
-
find_assignment_for(user) || user.assignments.build(exercise: self)
|
|
29
|
+
def assignment_for(user, organization: Organization.current)
|
|
30
|
+
find_assignment_for(user, organization) || user.assignments.build(exercise: self, organization: organization)
|
|
31
31
|
end
|
|
32
32
|
end
|
data/app/models/content.rb
CHANGED
data/app/models/course.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
class Course < ApplicationRecord
|
|
2
|
-
include Syncable
|
|
3
|
-
include
|
|
2
|
+
include Mumuki::Domain::Syncable
|
|
3
|
+
include Mumuki::Domain::Helpers::Course
|
|
4
4
|
|
|
5
5
|
validates_presence_of :slug, :shifts, :code, :days, :period, :description, :organization_id
|
|
6
6
|
validates_uniqueness_of :slug
|
|
@@ -10,12 +10,14 @@ class Course < ApplicationRecord
|
|
|
10
10
|
|
|
11
11
|
alias_attribute :name, :code
|
|
12
12
|
|
|
13
|
+
resource_fields :slug, :shifts, :code, :days, :period, :description
|
|
14
|
+
|
|
13
15
|
def current_invitation
|
|
14
16
|
invitations.where('expiration_date > ?', Time.now).take
|
|
15
17
|
end
|
|
16
18
|
|
|
17
19
|
def import_from_resource_h!(resource_h)
|
|
18
|
-
update!
|
|
20
|
+
update! self.class.slice_resource_h(resource_h)
|
|
19
21
|
end
|
|
20
22
|
|
|
21
23
|
def slug=(slug)
|
data/app/models/exercise.rb
CHANGED
|
@@ -111,6 +111,8 @@ class Exercise < ApplicationRecord
|
|
|
111
111
|
choice_values.index(value)
|
|
112
112
|
end
|
|
113
113
|
|
|
114
|
+
# Keep this list up to date with
|
|
115
|
+
# Mumukit::Sync::Store::Github::Schema::Exercise
|
|
114
116
|
def to_resource_h
|
|
115
117
|
language_resource_h = language.to_embedded_resource_h if language != guide.language
|
|
116
118
|
as_json(only: %i(name layout editor corollary teacher_info manual_evaluation locale
|
data/app/models/guide.rb
CHANGED
|
@@ -14,10 +14,10 @@ class Guide < Content
|
|
|
14
14
|
|
|
15
15
|
enum type: [:learning, :practice]
|
|
16
16
|
|
|
17
|
-
def clear_progress!(user)
|
|
17
|
+
def clear_progress!(user, organization)
|
|
18
18
|
transaction do
|
|
19
19
|
exercises.each do |exercise|
|
|
20
|
-
exercise.find_assignment_for(user)&.destroy!
|
|
20
|
+
exercise.find_assignment_for(user, organization)&.destroy!
|
|
21
21
|
end
|
|
22
22
|
end
|
|
23
23
|
end
|
|
@@ -86,6 +86,8 @@ class Guide < Content
|
|
|
86
86
|
reload
|
|
87
87
|
end
|
|
88
88
|
|
|
89
|
+
# Keep this list up to date with
|
|
90
|
+
# Mumukit::Sync::Store::Github::Schema::Guide
|
|
89
91
|
def to_resource_h
|
|
90
92
|
as_json(only: %i(beta type id_format private expectations corollary teacher_info sources learn_more authors collaborators extra settings))
|
|
91
93
|
.symbolize_keys
|
data/app/models/invitation.rb
CHANGED
data/app/models/language.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
class Language < ApplicationRecord
|
|
2
2
|
include WithCaseInsensitiveSearch
|
|
3
|
-
include Syncable
|
|
3
|
+
include Mumuki::Domain::Syncable
|
|
4
4
|
|
|
5
5
|
enum output_content_type: [:plain, :html, :markdown]
|
|
6
6
|
|
|
@@ -8,6 +8,33 @@ class Language < ApplicationRecord
|
|
|
8
8
|
|
|
9
9
|
validates :name, presence: true, uniqueness: {case_sensitive: false}
|
|
10
10
|
|
|
11
|
+
# This list must kept up to date with
|
|
12
|
+
# Mumukit::Sync::Store::Thesaurus::InfoConverter
|
|
13
|
+
resource_fields :comment_type,
|
|
14
|
+
:devicon,
|
|
15
|
+
:editor_css_urls,
|
|
16
|
+
:editor_html_urls,
|
|
17
|
+
:editor_js_urls,
|
|
18
|
+
:editor_shows_loading_content,
|
|
19
|
+
:extension,
|
|
20
|
+
:feedback,
|
|
21
|
+
:highlight_mode,
|
|
22
|
+
:layout_css_urls,
|
|
23
|
+
:layout_html_urls,
|
|
24
|
+
:layout_js_urls,
|
|
25
|
+
:layout_shows_loading_content,
|
|
26
|
+
:multifile,
|
|
27
|
+
:name,
|
|
28
|
+
:output_content_type,
|
|
29
|
+
:prompt,
|
|
30
|
+
:queriable,
|
|
31
|
+
:runner_url,
|
|
32
|
+
:stateful_console,
|
|
33
|
+
:test_extension,
|
|
34
|
+
:test_template,
|
|
35
|
+
:triable,
|
|
36
|
+
:visible_success_output
|
|
37
|
+
|
|
11
38
|
markdown_on :description
|
|
12
39
|
|
|
13
40
|
delegate :run_tests!, :run_query!, :run_try!, to: :bridge
|
|
@@ -64,13 +91,6 @@ class Language < ApplicationRecord
|
|
|
64
91
|
as_json(only: [:name, :extension, :test_extension]).symbolize_keys
|
|
65
92
|
end
|
|
66
93
|
|
|
67
|
-
def to_resource_h
|
|
68
|
-
as_json(only: %i(comment_type devicon editor_css_urls editor_html_urls editor_js_urls
|
|
69
|
-
extension feedback highlight_mode layout_css_urls layout_html_urls
|
|
70
|
-
layout_js_urls multifile name output_content_type prompt queriable runner_url
|
|
71
|
-
stateful_console test_extension test_template triable visible_success_output)).symbolize_keys
|
|
72
|
-
end
|
|
73
|
-
|
|
74
94
|
private
|
|
75
95
|
|
|
76
96
|
# TODO we should use Mumukit::Directives::Pipeline
|
data/app/models/organization.rb
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
class Organization < ApplicationRecord
|
|
2
|
-
include Syncable
|
|
3
|
-
include
|
|
2
|
+
include Mumuki::Domain::Syncable
|
|
3
|
+
include Mumuki::Domain::Helpers::Organization
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
serialize :
|
|
5
|
+
include Mumukit::Login::OrganizationHelpers
|
|
6
|
+
|
|
7
|
+
serialize :profile, Mumuki::Domain::Organization::Profile
|
|
8
|
+
serialize :settings, Mumuki::Domain::Organization::Settings
|
|
9
|
+
serialize :theme, Mumuki::Domain::Organization::Theme
|
|
8
10
|
|
|
9
11
|
markdown_on :description
|
|
10
12
|
|
|
@@ -16,7 +18,7 @@ class Organization < ApplicationRecord
|
|
|
16
18
|
validates_presence_of :contact_email, :locale
|
|
17
19
|
validates :name, uniqueness: true,
|
|
18
20
|
presence: true,
|
|
19
|
-
format: { with: Mumukit::Platform::Organization
|
|
21
|
+
format: { with: Mumukit::Platform::Organization.anchored_valid_name_regex }
|
|
20
22
|
validates :locale, inclusion: { in: Mumukit::Platform::Locale.supported }
|
|
21
23
|
|
|
22
24
|
after_create :reindex_usages!
|
|
@@ -28,6 +30,8 @@ class Organization < ApplicationRecord
|
|
|
28
30
|
has_many :exams
|
|
29
31
|
has_many :courses
|
|
30
32
|
|
|
33
|
+
resource_fields :name, :book, :profile, :settings, :theme
|
|
34
|
+
|
|
31
35
|
defaults do
|
|
32
36
|
self.class.base.try do |base|
|
|
33
37
|
self.theme = base.theme if theme.empty?
|
|
@@ -113,11 +117,15 @@ class Organization < ApplicationRecord
|
|
|
113
117
|
end
|
|
114
118
|
|
|
115
119
|
def import_from_resource_h!(resource_h)
|
|
116
|
-
attrs =
|
|
120
|
+
attrs = self.class.slice_resource_h resource_h
|
|
117
121
|
attrs[:book] = Book.locate! attrs[:book]
|
|
118
122
|
update! attrs
|
|
119
123
|
end
|
|
120
124
|
|
|
125
|
+
def to_resource_h
|
|
126
|
+
super.merge(book: book.slug)
|
|
127
|
+
end
|
|
128
|
+
|
|
121
129
|
private
|
|
122
130
|
|
|
123
131
|
def ensure_consistent_public_login
|
data/app/models/user.rb
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
class User < ApplicationRecord
|
|
2
|
-
include Syncable
|
|
2
|
+
include Mumuki::Domain::Syncable
|
|
3
3
|
include WithProfile,
|
|
4
4
|
WithUserNavigation,
|
|
5
5
|
WithReminders,
|
|
6
6
|
WithDiscussionCreation,
|
|
7
|
-
|
|
7
|
+
Mumuki::Domain::Helpers::User
|
|
8
8
|
|
|
9
9
|
serialize :permissions, Mumukit::Auth::Permissions
|
|
10
10
|
|
|
@@ -31,9 +31,13 @@ class User < ApplicationRecord
|
|
|
31
31
|
|
|
32
32
|
after_initialize :init
|
|
33
33
|
|
|
34
|
+
enum gender: %i(female male other)
|
|
35
|
+
|
|
34
36
|
before_validation :set_uid!
|
|
35
37
|
validates :uid, presence: true
|
|
36
38
|
|
|
39
|
+
resource_fields :uid, :social_id, :image_url, :email, :permissions, *profile_fields
|
|
40
|
+
|
|
37
41
|
def last_lesson
|
|
38
42
|
last_guide.try(:lesson)
|
|
39
43
|
end
|
|
@@ -98,7 +102,7 @@ class User < ApplicationRecord
|
|
|
98
102
|
end
|
|
99
103
|
|
|
100
104
|
def import_from_resource_h!(json)
|
|
101
|
-
update!
|
|
105
|
+
update! self.class.slice_resource_h json
|
|
102
106
|
end
|
|
103
107
|
|
|
104
108
|
def unsubscribe_from_reminders!
|
|
@@ -5,7 +5,7 @@ class IntroduceSettingsAndThemes < ActiveRecord::Migration[4.2]
|
|
|
5
5
|
add_column :organizations, :profile, :text, default: "{}", null: false
|
|
6
6
|
|
|
7
7
|
Organization.all.each do |organization|
|
|
8
|
-
organization.profile =
|
|
8
|
+
organization.profile = Mumuki::Domain::Organization::Profile.new(
|
|
9
9
|
logo_url: organization[:logo_url],
|
|
10
10
|
locale: organization[:locale],
|
|
11
11
|
description: organization[:description],
|
|
@@ -13,12 +13,12 @@ class IntroduceSettingsAndThemes < ActiveRecord::Migration[4.2]
|
|
|
13
13
|
terms_of_service: organization[:terms_of_service],
|
|
14
14
|
community_link: organization[:community_link]
|
|
15
15
|
)
|
|
16
|
-
organization.settings =
|
|
16
|
+
organization.settings = Mumuki::Domain::Organization::Settings.new(
|
|
17
17
|
login_methods: organization[:login_methods],
|
|
18
18
|
raise_hand_enabled: organization[:raise_hand_enabled],
|
|
19
19
|
public: organization[:public]
|
|
20
20
|
)
|
|
21
|
-
organization.theme =
|
|
21
|
+
organization.theme = Mumuki::Domain::Organization::Theme.new(
|
|
22
22
|
theme_stylesheet_url: organization[:theme_stylesheet_url],
|
|
23
23
|
extension_javascript_url: organization[:extension_javascript_url]
|
|
24
24
|
)
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#TODO move to mumukit-core
|
|
2
|
+
class Module
|
|
3
|
+
def ensure_defined!(selector)
|
|
4
|
+
# FIXME pass additional false flag in ruby 2.6
|
|
5
|
+
raise "method #{selector} was not previously defined here" unless method_defined?(selector)
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def ensure_undefined!(selector)
|
|
9
|
+
# FIXME pass additional false flag in ruby 2.6
|
|
10
|
+
raise "method #{selector} was previously defined here" if method_defined?(selector)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def define_once(selector, *args, &block)
|
|
14
|
+
ensure_undefined! selector
|
|
15
|
+
define_method selector, *args, &block
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -9,10 +9,8 @@ FactoryBot.define do
|
|
|
9
9
|
book
|
|
10
10
|
end
|
|
11
11
|
|
|
12
|
-
factory :
|
|
13
|
-
|
|
14
|
-
name { 'base' }
|
|
15
|
-
login_methods { Mumukit::Login::Settings.login_methods }
|
|
12
|
+
factory :private_organization, parent: :organization do
|
|
13
|
+
name { 'the-private-org' }
|
|
16
14
|
end
|
|
17
15
|
|
|
18
16
|
factory :public_organization, parent: :organization do
|
|
@@ -21,7 +19,20 @@ FactoryBot.define do
|
|
|
21
19
|
login_methods { Mumukit::Login::Settings.login_methods }
|
|
22
20
|
end
|
|
23
21
|
|
|
24
|
-
factory :
|
|
25
|
-
name { '
|
|
22
|
+
factory :base, parent: :public_organization do
|
|
23
|
+
name { 'base' }
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
factory :test_organization, parent: :public_organization do
|
|
27
|
+
name { 'test' }
|
|
28
|
+
book { create(:book, name: 'test', slug: 'mumuki/mumuki-the-book') }
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
factory :another_test_organization, parent: :test_organization, traits: [:skip_unique_name_validation] do
|
|
32
|
+
book { create(:book, name: 'another-test', slug: 'mumuki/mumuki-another-book') }
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
trait :skip_unique_name_validation do
|
|
36
|
+
to_create { |instance| instance.save(validate: false) }
|
|
26
37
|
end
|
|
27
38
|
end
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
module Mumuki::Domain::Helpers::Organization
|
|
2
|
+
extend ActiveSupport::Concern
|
|
3
|
+
include Mumukit::Platform::Notifiable
|
|
4
|
+
|
|
5
|
+
included do
|
|
6
|
+
delegate *Mumuki::Domain::Organization::Theme.accessors, to: :theme
|
|
7
|
+
delegate *Mumuki::Domain::Organization::Settings.accessors, :private?, :login_settings, to: :settings
|
|
8
|
+
delegate *Mumuki::Domain::Organization::Profile.accessors, :locale_json, to: :profile
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def platform_class_name
|
|
12
|
+
:Organization
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def slug
|
|
16
|
+
Mumukit::Auth::Slug.join_s name
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def central?
|
|
20
|
+
name == 'central'
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def test?
|
|
24
|
+
name == 'test'
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def base?
|
|
28
|
+
name == 'base'
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def switch!
|
|
32
|
+
Mumukit::Platform::Organization.switch! self
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def to_s
|
|
36
|
+
name
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def url_for(path)
|
|
40
|
+
Mumukit::Platform.application.organic_url_for(name, path)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def url
|
|
44
|
+
url_for '/'
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def domain
|
|
48
|
+
Mumukit::Platform.application.organic_domain(name)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
## API Exposure
|
|
52
|
+
|
|
53
|
+
def to_param
|
|
54
|
+
name
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
## Resource Hash
|
|
58
|
+
|
|
59
|
+
module ClassMethods
|
|
60
|
+
def current
|
|
61
|
+
Mumukit::Platform::Organization.current
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def parse(json)
|
|
65
|
+
json
|
|
66
|
+
.slice(:name)
|
|
67
|
+
.merge(theme: Mumuki::Domain::Organization::Theme.parse(json[:theme]))
|
|
68
|
+
.merge(settings: Mumuki::Domain::Organization::Settings.parse(json[:settings]))
|
|
69
|
+
.merge(profile: Mumuki::Domain::Organization::Profile.parse(json[:profile]))
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
module Mumuki::Domain::Helpers::User
|
|
2
|
+
extend ActiveSupport::Concern
|
|
3
|
+
include Mumukit::Auth::Roles
|
|
4
|
+
include Mumukit::Platform::Notifiable
|
|
5
|
+
|
|
6
|
+
## Permissions
|
|
7
|
+
|
|
8
|
+
delegate :has_role?,
|
|
9
|
+
:add_permission!,
|
|
10
|
+
:remove_permission!,
|
|
11
|
+
:has_permission?,
|
|
12
|
+
:has_permission_delegation?,
|
|
13
|
+
:protect!,
|
|
14
|
+
:protect_delegation!,
|
|
15
|
+
:protect_permissions_assignment!,
|
|
16
|
+
to: :permissions
|
|
17
|
+
|
|
18
|
+
def platform_class_name
|
|
19
|
+
:User
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def merge_permissions!(new_permissions)
|
|
23
|
+
self.permissions = permissions.merge(new_permissions)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
(Mumukit::Auth::Roles::ROLES - [:writer, :editor, :owner] + [:discusser]).each do |role|
|
|
27
|
+
role_of = "#{role}_of?"
|
|
28
|
+
role_here = "#{role}_here?"
|
|
29
|
+
|
|
30
|
+
# Tells whether this user has #{role} permissions in
|
|
31
|
+
# the given organization
|
|
32
|
+
define_method role_of do |organization|
|
|
33
|
+
has_permission? role, organization.slug
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Tells whether this user has #{role} permissions in
|
|
37
|
+
# the current organization
|
|
38
|
+
define_method role_here do
|
|
39
|
+
send role_of, Mumukit::Platform::Organization.current
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Tells whether this user has forum discusser permissions in
|
|
44
|
+
# the given organization
|
|
45
|
+
def discusser_of?(organization)
|
|
46
|
+
has_permission? organization.forum_discussions_minimal_role, organization.slug
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
(Mumukit::Auth::Roles::ROLES - [:owner]).each do |role|
|
|
50
|
+
|
|
51
|
+
# Assignes the #{role} role to this user
|
|
52
|
+
# for the given slug
|
|
53
|
+
define_method "make_#{role}_of!" do |slug|
|
|
54
|
+
add_permission! role, slug
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
## Profile
|
|
59
|
+
|
|
60
|
+
def full_name
|
|
61
|
+
"#{first_name} #{last_name}"
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
alias_method :name, :full_name
|
|
65
|
+
|
|
66
|
+
def profile_completed?
|
|
67
|
+
self.class.profile_fields.map { |it| self[it] }.all? &:present?
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def to_s
|
|
71
|
+
"#{full_name} <#{email}> [#{uid}]"
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
## Accesible organizations
|
|
75
|
+
|
|
76
|
+
def student_granted_organizations
|
|
77
|
+
permissions.student_granted_organizations.map do |org|
|
|
78
|
+
Mumukit::Platform::Organization.find_by_name!(org) rescue nil
|
|
79
|
+
end.compact
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def has_student_granted_organizations?
|
|
83
|
+
student_granted_organizations.present?
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def main_organization
|
|
87
|
+
student_granted_organizations.first
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def has_main_organization?
|
|
91
|
+
student_granted_organizations.length == 1
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def has_immersive_main_organization?
|
|
95
|
+
!!main_organization.try(&:immersive?)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
## API Exposure
|
|
99
|
+
|
|
100
|
+
def to_param
|
|
101
|
+
uid
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
class_methods do
|
|
105
|
+
def profile_fields
|
|
106
|
+
[:first_name, :last_name, :gender, :birthdate]
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
class Mumuki::Domain::Organization::Profile < Mumukit::Platform::Model
|
|
2
|
+
LOCALES = Mumukit::Platform::Locale::SPECS
|
|
3
|
+
|
|
4
|
+
model_attr_accessor :logo_url,
|
|
5
|
+
:banner_url,
|
|
6
|
+
:favicon_url,
|
|
7
|
+
:breadcrumb_image_url,
|
|
8
|
+
:open_graph_image_url,
|
|
9
|
+
:locale,
|
|
10
|
+
:description,
|
|
11
|
+
:contact_email,
|
|
12
|
+
:terms_of_service,
|
|
13
|
+
:community_link,
|
|
14
|
+
:errors_explanations
|
|
15
|
+
|
|
16
|
+
def locale_json
|
|
17
|
+
locale_h.to_json
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def locale_h
|
|
21
|
+
Mumukit::Platform::Locale::SPECS[locale]
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def logo_url
|
|
25
|
+
@logo_url ||= 'https://mumuki.io/logo-alt-large.png' # Best image size: 350x75
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def banner_url
|
|
29
|
+
@banner_url || logo_url # Best image size: 350x75
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def favicon_url
|
|
33
|
+
@favicon_url ||= '/favicon.ico' # Best image size: 16x16, 32x32 or 48x48
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def open_graph_image_url
|
|
37
|
+
@open_graph_image_url ||= Mumukit::Platform.application.url_for("logo-alt.png") # Best image size: 256x256
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
class Mumuki::Domain::Organization::Settings < Mumukit::Platform::Model
|
|
2
|
+
include Mumukit::Login::LoginSettingsHelpers
|
|
3
|
+
|
|
4
|
+
model_attr_accessor :login_methods,
|
|
5
|
+
:login_provider,
|
|
6
|
+
:login_provider_settings,
|
|
7
|
+
:forum_discussions_minimal_role,
|
|
8
|
+
:raise_hand_enabled?,
|
|
9
|
+
:feedback_suggestions_enabled?,
|
|
10
|
+
:public?,
|
|
11
|
+
:embeddable?,
|
|
12
|
+
:immersive?,
|
|
13
|
+
:forum_enabled?,
|
|
14
|
+
:report_issue_enabled?
|
|
15
|
+
|
|
16
|
+
def private?
|
|
17
|
+
!public?
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def login_methods
|
|
21
|
+
@login_methods ||= ['user_pass']
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def forum_discussions_minimal_role
|
|
25
|
+
(@forum_discussions_minimal_role || 'student').to_sym
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module Mumukit::Sync::Store
|
|
2
|
+
|
|
3
|
+
## This Store enables importing content
|
|
4
|
+
## from Bibliotheca API
|
|
5
|
+
class Bibliotheca < Mumukit::Sync::Store::Base
|
|
6
|
+
include Mumukit::Sync::Store::WithWrappedLanguage
|
|
7
|
+
include Mumukit::Sync::Store::WithFilteredId
|
|
8
|
+
|
|
9
|
+
def initialize(bibliotheca_bridge)
|
|
10
|
+
@bibliotheca_bridge = bibliotheca_bridge
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def sync_keys
|
|
14
|
+
%w(guide topic book).flat_map do |kind|
|
|
15
|
+
@bibliotheca_bridge
|
|
16
|
+
.send(kind.as_variable_name.pluralize)
|
|
17
|
+
.map { |it| Mumukit::Sync.key kind, it['slug'] }
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def do_read(sync_key)
|
|
22
|
+
@bibliotheca_bridge.send(sync_key.kind.as_variable_name, sync_key.id)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def write_resource!(*)
|
|
26
|
+
Mumukit::Sync::Store.read_only!
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
module Mumukit::Sync::Store::Github::Schema::Exercise
|
|
2
|
+
extend Mumukit::Sync::Store::Github::Schema
|
|
3
|
+
|
|
4
|
+
def self.fields_schema
|
|
5
|
+
[
|
|
6
|
+
{name: :id, kind: :special},
|
|
7
|
+
{name: :name, kind: :special},
|
|
8
|
+
|
|
9
|
+
{name: :tags, kind: :metadata, reverse: :tag_list, transform: with { |it| it.to_a }},
|
|
10
|
+
{name: :layout, kind: :metadata},
|
|
11
|
+
{name: :editor, kind: :metadata},
|
|
12
|
+
|
|
13
|
+
{name: :type, kind: :metadata},
|
|
14
|
+
{name: :extra_visible, kind: :metadata},
|
|
15
|
+
{name: :language, kind: :metadata, transform: name },
|
|
16
|
+
{name: :teacher_info, kind: :metadata},
|
|
17
|
+
{name: :manual_evaluation, kind: :metadata},
|
|
18
|
+
{name: :choices, kind: :metadata},
|
|
19
|
+
|
|
20
|
+
{name: :expectations, kind: :file, extension: 'yml', transform: yaml_list('expectations')},
|
|
21
|
+
{name: :assistance_rules, kind: :file, extension: 'yml', transform: yaml_list('rules')},
|
|
22
|
+
{name: :randomizations, kind: :file, extension: 'yml', transform: yaml_hash},
|
|
23
|
+
|
|
24
|
+
{name: :goal, kind: :metadata},
|
|
25
|
+
{name: :test, kind: :file, extension: :test},
|
|
26
|
+
{name: :extra, kind: :file, extension: :code},
|
|
27
|
+
{name: :default, kind: :file, extension: :code, reverse: :default_content},
|
|
28
|
+
|
|
29
|
+
{name: :description, kind: :file, extension: 'md', required: true},
|
|
30
|
+
{name: :hint, kind: :file, extension: 'md'},
|
|
31
|
+
{name: :corollary, kind: :file, extension: 'md'},
|
|
32
|
+
{name: :initial_state, kind: :file, extension: 'md'},
|
|
33
|
+
{name: :final_state, kind: :file, extension: 'md'},
|
|
34
|
+
{name: :free_form_editor_source, kind: :file, extension: 'html'}
|
|
35
|
+
]
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
module Mumukit::Sync::Store::Github::Schema::Guide
|
|
2
|
+
extend Mumukit::Sync::Store::Github::Schema
|
|
3
|
+
|
|
4
|
+
def self.fields_schema
|
|
5
|
+
[
|
|
6
|
+
{name: :exercises, kind: :special},
|
|
7
|
+
{name: :id, kind: :special},
|
|
8
|
+
{name: :slug, kind: :special},
|
|
9
|
+
|
|
10
|
+
{name: :name, kind: :metadata},
|
|
11
|
+
{name: :locale, kind: :metadata},
|
|
12
|
+
{name: :type, kind: :metadata},
|
|
13
|
+
{name: :beta, kind: :metadata},
|
|
14
|
+
{name: :teacher_info, kind: :metadata},
|
|
15
|
+
{name: :language, kind: :metadata, transform: name },
|
|
16
|
+
{name: :id_format, kind: :metadata},
|
|
17
|
+
{name: :order, kind: :metadata, transform: with { |it| it.map { |e| e[:id] } }, reverse: :exercises},
|
|
18
|
+
{name: :private, kind: :metadata},
|
|
19
|
+
|
|
20
|
+
{name: :expectations, kind: :file, extension: 'yml', transform: yaml_list('expectations')},
|
|
21
|
+
{name: :description, kind: :file, extension: 'md', required: true},
|
|
22
|
+
{name: :corollary, kind: :file, extension: 'md'},
|
|
23
|
+
{name: :sources, kind: :file, extension: 'md'},
|
|
24
|
+
{name: :learn_more, kind: :file, extension: 'md'},
|
|
25
|
+
{name: :extra, kind: :file, extension: :code},
|
|
26
|
+
{name: :AUTHORS, kind: :file, extension: 'txt', reverse: :authors},
|
|
27
|
+
{name: :COLLABORATORS, kind: :file, extension: 'txt', reverse: :collaborators}
|
|
28
|
+
]
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def self.fixed_file_patterns
|
|
32
|
+
%w(LICENSE.txt README.md COPYRIGHT.txt meta.yml *_*/*)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
module Mumukit::Sync::Store
|
|
2
|
+
|
|
3
|
+
## This Store enables importing languages
|
|
4
|
+
## from Thesaurus API
|
|
5
|
+
class Thesaurus < Mumukit::Sync::Store::Base
|
|
6
|
+
def initialize(thesaurus_bridge)
|
|
7
|
+
@thesaurus_bridge = thesaurus_bridge
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def sync_keys
|
|
11
|
+
@thesaurus_bridge.runners.map { |it| Mumukit::Sync.key(:language, it) }
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def do_read(sync_key)
|
|
15
|
+
return unless sync_key.kind.like? :language
|
|
16
|
+
transform_after_read(sync_key.id, Mumukit::Bridge::Runner.new(sync_key.id).info)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def transform_after_read(runner_url, info)
|
|
20
|
+
Mumukit::Sync::Store::Thesaurus::InfoConverter.new(runner_url, info).call
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def write_resource!(*)
|
|
24
|
+
Mumukit::Sync::Store.read_only!
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
class InfoConverter
|
|
28
|
+
def initialize(runner_url, info)
|
|
29
|
+
@runner_url = runner_url
|
|
30
|
+
@info = info
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def call
|
|
34
|
+
{
|
|
35
|
+
name: @info['name'],
|
|
36
|
+
comment_type: @info['comment_type'],
|
|
37
|
+
runner_url: @runner_url,
|
|
38
|
+
output_content_type: @info['output_content_type'],
|
|
39
|
+
prompt: (@info.dig('language', 'prompt') || 'ム') + ' ',
|
|
40
|
+
extension: @info.dig('language', 'extension'),
|
|
41
|
+
highlight_mode: @info.dig('language', 'ace_mode'),
|
|
42
|
+
visible_success_output: @info.dig('language', 'graphic').present?,
|
|
43
|
+
devicon: @info.dig('language', 'icon', 'name'),
|
|
44
|
+
triable: @info.dig('features', 'try').present?,
|
|
45
|
+
feedback: @info.dig('features', 'feedback').present?,
|
|
46
|
+
queriable: @info.dig('features', 'query').present?,
|
|
47
|
+
stateful_console: @info.dig('features', 'stateful').present?,
|
|
48
|
+
multifile: @info.dig('features', 'multifile').present?,
|
|
49
|
+
test_extension: @info.dig('test_framework', 'test_extension'),
|
|
50
|
+
test_template: @info.dig('test_framework', 'template'),
|
|
51
|
+
layout_js_urls: get_assets_for(:layout, 'js'),
|
|
52
|
+
layout_html_urls: get_assets_for(:layout, 'html'),
|
|
53
|
+
layout_css_urls: get_assets_for(:layout, 'css'),
|
|
54
|
+
editor_js_urls: get_assets_for(:editor, 'js'),
|
|
55
|
+
editor_html_urls: get_assets_for(:editor, 'html'),
|
|
56
|
+
editor_css_urls: get_assets_for(:editor, 'css'),
|
|
57
|
+
layout_shows_loading_content: shows_loading_content_for?(:layout),
|
|
58
|
+
editor_shows_loading_content: shows_loading_content_for?(:editor)
|
|
59
|
+
}
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def get_assets_for(kind, content_type)
|
|
63
|
+
absolutize(get_asset_field(kind, content_type) || [])
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def get_asset_field(kind, field)
|
|
67
|
+
@info.dig("#{kind}_assets_urls", field)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def absolutize(urls)
|
|
71
|
+
urls.map { |url| "#{@runner_url}/#{url}"}
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def shows_loading_content_for?(kind)
|
|
75
|
+
get_asset_field(kind, 'shows_loading_content').present?
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module Mumuki::Domain::Syncable
|
|
2
|
+
## Syncable objects that also declare
|
|
3
|
+
## a `resource_fields` method can define `resource_h`
|
|
4
|
+
## and `self.slice_resource_h` based on it.
|
|
5
|
+
module WithResourceFields
|
|
6
|
+
extend ActiveSupport::Concern
|
|
7
|
+
|
|
8
|
+
def to_resource_h
|
|
9
|
+
self.class.resource_fields.map { |it| [it, send(it)] }.to_h.compact
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
class_methods do
|
|
13
|
+
def slice_resource_h(resource_h)
|
|
14
|
+
resource_h.slice(*resource_fields)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
# be treated as `Mumukit::Sync` resources
|
|
3
3
|
#
|
|
4
4
|
# `Syncable` objects also get `Mumukit::Platform::Notifiable` by free
|
|
5
|
-
module Syncable
|
|
5
|
+
module Mumuki::Domain::Syncable
|
|
6
6
|
extend ActiveSupport::Concern
|
|
7
7
|
include Mumukit::Platform::Notifiable
|
|
8
8
|
|
|
@@ -87,3 +87,5 @@ module Syncable
|
|
|
87
87
|
end
|
|
88
88
|
end
|
|
89
89
|
end
|
|
90
|
+
|
|
91
|
+
require_relative './syncable/with_resource_fields'
|
data/lib/mumuki/domain.rb
CHANGED
|
@@ -11,6 +11,7 @@ require 'mumukit/inspection'
|
|
|
11
11
|
require 'mumukit/platform'
|
|
12
12
|
require 'mumukit/randomizer'
|
|
13
13
|
require 'mumukit/sync'
|
|
14
|
+
require 'mumukit/login'
|
|
14
15
|
|
|
15
16
|
I18n.load_translations_path File.join(__dir__, 'domain', 'locales', '**', '*.yml')
|
|
16
17
|
|
|
@@ -30,6 +31,10 @@ require_relative './domain/status'
|
|
|
30
31
|
require_relative './domain/exceptions'
|
|
31
32
|
require_relative './domain/file'
|
|
32
33
|
require_relative './domain/extensions'
|
|
34
|
+
require_relative './domain/organization'
|
|
35
|
+
require_relative './domain/helpers'
|
|
36
|
+
require_relative './domain/syncable'
|
|
37
|
+
require_relative './domain/stores'
|
|
33
38
|
|
|
34
39
|
class Mumukit::Assistant
|
|
35
40
|
def self.valid?(rules)
|
|
@@ -48,3 +53,8 @@ class Mumukit::Randomizer
|
|
|
48
53
|
!!parse(randomizations) rescue false
|
|
49
54
|
end
|
|
50
55
|
end
|
|
56
|
+
|
|
57
|
+
Mumukit::Sync::Store::Github.configure do |config|
|
|
58
|
+
config.guide_schema = Mumukit::Sync::Store::Github::Schema::Guide
|
|
59
|
+
config.exercise_schema = Mumukit::Sync::Store::Github::Schema::Exercise
|
|
60
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: mumuki-domain
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 7.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Franco Leonardo Bulgarelli
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2019-
|
|
11
|
+
date: 2019-07-24 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rails
|
|
@@ -58,14 +58,14 @@ dependencies:
|
|
|
58
58
|
requirements:
|
|
59
59
|
- - "~>"
|
|
60
60
|
- !ruby/object:Gem::Version
|
|
61
|
-
version: '
|
|
61
|
+
version: '4.0'
|
|
62
62
|
type: :runtime
|
|
63
63
|
prerelease: false
|
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
|
65
65
|
requirements:
|
|
66
66
|
- - "~>"
|
|
67
67
|
- !ruby/object:Gem::Version
|
|
68
|
-
version: '
|
|
68
|
+
version: '4.0'
|
|
69
69
|
- !ruby/object:Gem::Dependency
|
|
70
70
|
name: mumukit-content-type
|
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -142,28 +142,28 @@ dependencies:
|
|
|
142
142
|
requirements:
|
|
143
143
|
- - "~>"
|
|
144
144
|
- !ruby/object:Gem::Version
|
|
145
|
-
version: '
|
|
145
|
+
version: '5.1'
|
|
146
146
|
type: :runtime
|
|
147
147
|
prerelease: false
|
|
148
148
|
version_requirements: !ruby/object:Gem::Requirement
|
|
149
149
|
requirements:
|
|
150
150
|
- - "~>"
|
|
151
151
|
- !ruby/object:Gem::Version
|
|
152
|
-
version: '
|
|
152
|
+
version: '5.1'
|
|
153
153
|
- !ruby/object:Gem::Dependency
|
|
154
154
|
name: mumukit-sync
|
|
155
155
|
requirement: !ruby/object:Gem::Requirement
|
|
156
156
|
requirements:
|
|
157
157
|
- - "~>"
|
|
158
158
|
- !ruby/object:Gem::Version
|
|
159
|
-
version: '0
|
|
159
|
+
version: '1.0'
|
|
160
160
|
type: :runtime
|
|
161
161
|
prerelease: false
|
|
162
162
|
version_requirements: !ruby/object:Gem::Requirement
|
|
163
163
|
requirements:
|
|
164
164
|
- - "~>"
|
|
165
165
|
- !ruby/object:Gem::Version
|
|
166
|
-
version: '0
|
|
166
|
+
version: '1.0'
|
|
167
167
|
- !ruby/object:Gem::Dependency
|
|
168
168
|
name: pg
|
|
169
169
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -184,14 +184,14 @@ dependencies:
|
|
|
184
184
|
requirements:
|
|
185
185
|
- - "~>"
|
|
186
186
|
- !ruby/object:Gem::Version
|
|
187
|
-
version: '
|
|
187
|
+
version: '7.0'
|
|
188
188
|
type: :development
|
|
189
189
|
prerelease: false
|
|
190
190
|
version_requirements: !ruby/object:Gem::Requirement
|
|
191
191
|
requirements:
|
|
192
192
|
- - "~>"
|
|
193
193
|
- !ruby/object:Gem::Version
|
|
194
|
-
version: '
|
|
194
|
+
version: '7.0'
|
|
195
195
|
description: Mumuki Platform's Domain Model
|
|
196
196
|
email:
|
|
197
197
|
- franco@mumuki.org
|
|
@@ -221,7 +221,6 @@ files:
|
|
|
221
221
|
- app/models/concerns/submittable/solvable.rb
|
|
222
222
|
- app/models/concerns/submittable/submittable.rb
|
|
223
223
|
- app/models/concerns/submittable/triable.rb
|
|
224
|
-
- app/models/concerns/syncable.rb
|
|
225
224
|
- app/models/concerns/with_assignments.rb
|
|
226
225
|
- app/models/concerns/with_case_insensitive_search.rb
|
|
227
226
|
- app/models/concerns/with_description.rb
|
|
@@ -538,6 +537,9 @@ files:
|
|
|
538
537
|
- db/migrate/20190326152631_add_settings_to_content.rb
|
|
539
538
|
- db/migrate/20190404181724_add_organization_to_discussion.rb
|
|
540
539
|
- db/migrate/20190506180102_add_multifile_to_languages.rb
|
|
540
|
+
- db/migrate/20190530173142_add_organization_to_assignment.rb
|
|
541
|
+
- db/migrate/20190702003600_add_loading_flags_to_language.rb
|
|
542
|
+
- db/migrate/20190702182407_add_new_profile_fields.rb
|
|
541
543
|
- lib/mumuki/domain.rb
|
|
542
544
|
- lib/mumuki/domain/engine.rb
|
|
543
545
|
- lib/mumuki/domain/evaluation.rb
|
|
@@ -551,6 +553,7 @@ files:
|
|
|
551
553
|
- lib/mumuki/domain/exceptions/unauthorized_error.rb
|
|
552
554
|
- lib/mumuki/domain/extensions.rb
|
|
553
555
|
- lib/mumuki/domain/extensions/array.rb
|
|
556
|
+
- lib/mumuki/domain/extensions/module.rb
|
|
554
557
|
- lib/mumuki/domain/extensions/string.rb
|
|
555
558
|
- lib/mumuki/domain/factories.rb
|
|
556
559
|
- lib/mumuki/domain/factories/api_client_factory.rb
|
|
@@ -572,12 +575,20 @@ files:
|
|
|
572
575
|
- lib/mumuki/domain/factories/usage_factory.rb
|
|
573
576
|
- lib/mumuki/domain/factories/user_factory.rb
|
|
574
577
|
- lib/mumuki/domain/file.rb
|
|
578
|
+
- lib/mumuki/domain/helpers.rb
|
|
579
|
+
- lib/mumuki/domain/helpers/course.rb
|
|
580
|
+
- lib/mumuki/domain/helpers/organization.rb
|
|
581
|
+
- lib/mumuki/domain/helpers/user.rb
|
|
575
582
|
- lib/mumuki/domain/locales/activerecord/en.yml
|
|
576
583
|
- lib/mumuki/domain/locales/activerecord/es.yml
|
|
577
584
|
- lib/mumuki/domain/locales/activerecord/pt.yml
|
|
578
585
|
- lib/mumuki/domain/locales/console_submission/en.yml
|
|
579
586
|
- lib/mumuki/domain/locales/console_submission/es.yml
|
|
580
587
|
- lib/mumuki/domain/locales/console_submission/pt.yml
|
|
588
|
+
- lib/mumuki/domain/organization.rb
|
|
589
|
+
- lib/mumuki/domain/organization/profile.rb
|
|
590
|
+
- lib/mumuki/domain/organization/settings.rb
|
|
591
|
+
- lib/mumuki/domain/organization/theme.rb
|
|
581
592
|
- lib/mumuki/domain/seed.rb
|
|
582
593
|
- lib/mumuki/domain/status.rb
|
|
583
594
|
- lib/mumuki/domain/status/discussion/closed.rb
|
|
@@ -594,6 +605,11 @@ files:
|
|
|
594
605
|
- lib/mumuki/domain/status/submission/pending.rb
|
|
595
606
|
- lib/mumuki/domain/status/submission/running.rb
|
|
596
607
|
- lib/mumuki/domain/status/submission/submission.rb
|
|
608
|
+
- lib/mumuki/domain/stores.rb
|
|
609
|
+
- lib/mumuki/domain/stores/bibliotheca_store.rb
|
|
610
|
+
- lib/mumuki/domain/stores/exercise_schema.rb
|
|
611
|
+
- lib/mumuki/domain/stores/guide_schema.rb
|
|
612
|
+
- lib/mumuki/domain/stores/thesaurus_store.rb
|
|
597
613
|
- lib/mumuki/domain/submission.rb
|
|
598
614
|
- lib/mumuki/domain/submission/base.rb
|
|
599
615
|
- lib/mumuki/domain/submission/confirmation.rb
|
|
@@ -603,6 +619,8 @@ files:
|
|
|
603
619
|
- lib/mumuki/domain/submission/question.rb
|
|
604
620
|
- lib/mumuki/domain/submission/solution.rb
|
|
605
621
|
- lib/mumuki/domain/submission/try.rb
|
|
622
|
+
- lib/mumuki/domain/syncable.rb
|
|
623
|
+
- lib/mumuki/domain/syncable/with_resource_fields.rb
|
|
606
624
|
- lib/mumuki/domain/version.rb
|
|
607
625
|
homepage: https://mumuki.org
|
|
608
626
|
licenses:
|
|
@@ -623,7 +641,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
623
641
|
- !ruby/object:Gem::Version
|
|
624
642
|
version: '0'
|
|
625
643
|
requirements: []
|
|
626
|
-
|
|
644
|
+
rubyforge_project:
|
|
645
|
+
rubygems_version: 2.7.7
|
|
627
646
|
signing_key:
|
|
628
647
|
specification_version: 4
|
|
629
648
|
summary: Mumuki Platform's Domain Model
|