assembly-client 0.7.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 (46) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +19 -0
  3. data/.ruby-version +1 -0
  4. data/Gemfile +6 -0
  5. data/Guardfile +9 -0
  6. data/LICENSE.txt +21 -0
  7. data/README.md +56 -0
  8. data/Rakefile +9 -0
  9. data/assembly-client.gemspec +31 -0
  10. data/bin/console +12 -0
  11. data/bin/setup +7 -0
  12. data/lib/assembly.rb +64 -0
  13. data/lib/assembly/actions/create.rb +16 -0
  14. data/lib/assembly/actions/delete.rb +21 -0
  15. data/lib/assembly/actions/list.rb +33 -0
  16. data/lib/assembly/actions/read.rb +18 -0
  17. data/lib/assembly/actions/update.rb +22 -0
  18. data/lib/assembly/api_model.rb +25 -0
  19. data/lib/assembly/client.rb +227 -0
  20. data/lib/assembly/config.rb +25 -0
  21. data/lib/assembly/faraday_middleware/assembly_oauth2.rb +25 -0
  22. data/lib/assembly/model.rb +109 -0
  23. data/lib/assembly/models/academic_year.rb +7 -0
  24. data/lib/assembly/models/aspect.rb +10 -0
  25. data/lib/assembly/models/assessment.rb +18 -0
  26. data/lib/assembly/models/assessment_point.rb +12 -0
  27. data/lib/assembly/models/attendance.rb +7 -0
  28. data/lib/assembly/models/calendar_event.rb +7 -0
  29. data/lib/assembly/models/contact.rb +7 -0
  30. data/lib/assembly/models/exclusion.rb +7 -0
  31. data/lib/assembly/models/facet.rb +8 -0
  32. data/lib/assembly/models/grade.rb +4 -0
  33. data/lib/assembly/models/grade_set.rb +9 -0
  34. data/lib/assembly/models/list.rb +31 -0
  35. data/lib/assembly/models/registration_group.rb +13 -0
  36. data/lib/assembly/models/result.rb +11 -0
  37. data/lib/assembly/models/school_detail.rb +7 -0
  38. data/lib/assembly/models/staff_member.rb +8 -0
  39. data/lib/assembly/models/student.rb +8 -0
  40. data/lib/assembly/models/subject.rb +7 -0
  41. data/lib/assembly/models/teaching_group.rb +13 -0
  42. data/lib/assembly/models/year_group.rb +13 -0
  43. data/lib/assembly/resource.rb +65 -0
  44. data/lib/assembly/util.rb +44 -0
  45. data/lib/assembly/version.rb +3 -0
  46. metadata +214 -0
@@ -0,0 +1,25 @@
1
+ module Assembly
2
+ class Config
3
+
4
+ attr_accessor :host, :auth_host, :token, :refresh_token, :client_id, :client_secret, :api_version
5
+
6
+ def initialize(options={})
7
+ @host = "https://api.assembly.education"
8
+ @auth_host = "https://platform.assembly.education"
9
+ @api_version = 1
10
+ merge(options)
11
+ end
12
+
13
+ def copy_with_overrides(options={})
14
+ copy = self.dup
15
+ copy.merge(options)
16
+ copy
17
+ end
18
+
19
+ def merge(options)
20
+ options.each do |key, value|
21
+ send(:"#{key}=", value)
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,25 @@
1
+ require 'faraday'
2
+ require 'forwardable'
3
+
4
+ module FaradayMiddleware
5
+ class AssemblyOAuth2 < Faraday::Middleware
6
+ AUTH_HEADER = 'Authorization'.freeze
7
+
8
+ attr_reader :token
9
+
10
+ def call(env)
11
+ env[:request_headers][AUTH_HEADER] ||= "Bearer #{token}"
12
+ @app.call env
13
+ end
14
+
15
+ def initialize(app, token)
16
+ unless token && token.is_a?(String)
17
+ raise ArgumentError.new("An access_token string was expected, got: #{token.inspect}")
18
+ end
19
+ super(app)
20
+ @token = token
21
+ end
22
+ end
23
+ end
24
+
25
+ Faraday::Request.register_middleware(assembly_oauth2: FaradayMiddleware::AssemblyOAuth2)
@@ -0,0 +1,109 @@
1
+ module Assembly
2
+ class Model
3
+ include Enumerable
4
+
5
+ undef :id if method_defined?(:id)
6
+ undef :name if method_defined?(:name)
7
+
8
+ attr_reader :id
9
+ attr_reader :client
10
+
11
+ def initialize(id=nil, client=nil)
12
+ @id = id
13
+ @client = client
14
+ @values = {}
15
+ @dirty_values = Set.new
16
+ end
17
+
18
+ def merge(values, client=nil)
19
+ added = Set.new(values.keys - @values.keys)
20
+ add_accessors(added)
21
+ values.each do |k, v|
22
+ @values[k] = Util.build(v, client)
23
+ end
24
+ self
25
+ end
26
+
27
+ def self.construct_from(response, client=nil)
28
+ new(response[:id], client).merge(response, client)
29
+ end
30
+
31
+ def update_from(response)
32
+ @dirty_values.clear
33
+ merge(response)
34
+ end
35
+
36
+ def dirty?
37
+ @dirty_values.any?
38
+ end
39
+
40
+ def [](k)
41
+ @values[k.to_sym]
42
+ end
43
+
44
+ def []=(k, v)
45
+ send(:"#{k}=", v)
46
+ end
47
+
48
+ def keys
49
+ @values.keys
50
+ end
51
+
52
+ def values
53
+ @values.values
54
+ end
55
+
56
+ def to_json(*a)
57
+ JSON.generate(@values)
58
+ end
59
+
60
+ def as_json(*a)
61
+ @values.as_json(*a)
62
+ end
63
+
64
+ def to_hash
65
+ @values.inject({}) do |acc, (key, value)|
66
+ acc[key] = value.respond_to?(:to_hash) ? value.to_hash : value
67
+ acc
68
+ end
69
+ end
70
+
71
+ def each(&blk)
72
+ @values.each(&blk)
73
+ end
74
+
75
+ def self.class_name
76
+ self.name.split('::')[-1]
77
+ end
78
+
79
+ def dirty_params
80
+ @dirty_values.reduce({}) do |hsh, k|
81
+ hsh[k] = @values[k]
82
+ hsh
83
+ end
84
+ end
85
+
86
+ protected
87
+
88
+ def metaclass
89
+ class << self; self; end
90
+ end
91
+
92
+ def add_accessors(keys)
93
+ keys.each do |k|
94
+ next if k == :id
95
+ next if self.class.instance_methods(false).include?(k)
96
+ self.class.class_eval %[
97
+ def #{k}
98
+ @values[:#{k}]
99
+ end
100
+
101
+ def #{k}=(v)
102
+ @values[:#{k}] = v
103
+ @dirty_values.add(:#{k})
104
+ end
105
+ ]
106
+ end
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,7 @@
1
+ module Assembly
2
+ class AcademicYear < ApiModel
3
+ include Assembly::Actions::List
4
+ end
5
+
6
+ Resource.build(AcademicYear)
7
+ end
@@ -0,0 +1,10 @@
1
+ module Assembly
2
+ class Aspect < ApiModel
3
+ include Assembly::Actions::Read
4
+ include Assembly::Actions::List
5
+ include Assembly::Actions::Create
6
+ include Assembly::Actions::Delete
7
+ end
8
+
9
+ Resource.build(Aspect)
10
+ end
@@ -0,0 +1,18 @@
1
+ module Assembly
2
+ class Assessment < ApiModel
3
+ include Assembly::Actions::Read
4
+ include Assembly::Actions::List
5
+
6
+ def grade_set(params={})
7
+ response = client.get(path + '/grade_set', params)
8
+ Util.build(response[:grade_set], client)
9
+ end
10
+
11
+ def results(params={})
12
+ response = client.get(path + '/results', params)
13
+ Util.build(response, client)
14
+ end
15
+ end
16
+
17
+ Resource.build(Assessment)
18
+ end
@@ -0,0 +1,12 @@
1
+ module Assembly
2
+ class AssessmentPoint < ApiModel
3
+ include Assembly::Actions::Read
4
+ include Assembly::Actions::List
5
+
6
+ def results(params={})
7
+ pages(path + "#{rank}/results", params)
8
+ end
9
+ end
10
+
11
+ Resource.build(AssessmentPoint)
12
+ end
@@ -0,0 +1,7 @@
1
+ module Assembly
2
+ class Attendance < ApiModel
3
+ include Assembly::Actions::List
4
+ end
5
+
6
+ Resource.build(Attendance)
7
+ end
@@ -0,0 +1,7 @@
1
+ module Assembly
2
+ class CalendarEvent < ApiModel
3
+ include Assembly::Actions::List
4
+ end
5
+
6
+ Resource.build(CalendarEvent)
7
+ end
@@ -0,0 +1,7 @@
1
+ module Assembly
2
+ class Contact < ApiModel
3
+ include Assembly::Actions::List
4
+ end
5
+
6
+ Resource.build(Contact)
7
+ end
@@ -0,0 +1,7 @@
1
+ module Assembly
2
+ class Exclusion < ApiModel
3
+ include Assembly::Actions::List
4
+ end
5
+
6
+ Resource.build(Exclusion)
7
+ end
@@ -0,0 +1,8 @@
1
+ module Assembly
2
+ class Facet < ApiModel
3
+ include Assembly::Actions::Read
4
+ include Assembly::Actions::List
5
+ end
6
+
7
+ Resource.build(Facet)
8
+ end
@@ -0,0 +1,4 @@
1
+ module Assembly
2
+ class Grade < Model
3
+ end
4
+ end
@@ -0,0 +1,9 @@
1
+ module Assembly
2
+ class GradeSet < ApiModel
3
+ include Assembly::Actions::Read
4
+ include Assembly::Actions::Create
5
+ include Assembly::Actions::List
6
+ end
7
+
8
+ Resource.build(GradeSet)
9
+ end
@@ -0,0 +1,31 @@
1
+ module Assembly
2
+ class List < Model
3
+ def each(&blk)
4
+ self.data.each(&blk)
5
+ end
6
+
7
+ def next
8
+ self
9
+ end
10
+
11
+ def next_page
12
+ @values[:next_page]
13
+ end
14
+
15
+ def prev_page
16
+ @values[:prev_page]
17
+ end
18
+
19
+ def current_page
20
+ @values[:current_page] || 1
21
+ end
22
+
23
+ def total_pages
24
+ @values[:total_pages] || 1
25
+ end
26
+
27
+ def total_count
28
+ @values[:total_count] || 0
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,13 @@
1
+ module Assembly
2
+ class RegistrationGroup < ApiModel
3
+ include Assembly::Actions::Read
4
+ include Assembly::Actions::List
5
+
6
+ def students(params={})
7
+ response = client.get(path + '/students', params)
8
+ Util.build(response, client)
9
+ end
10
+ end
11
+
12
+ Resource.build(RegistrationGroup)
13
+ end
@@ -0,0 +1,11 @@
1
+ module Assembly
2
+ class Result < ApiModel
3
+ include Assembly::Actions::Read
4
+ include Assembly::Actions::List
5
+ include Assembly::Actions::Create
6
+ include Assembly::Actions::Delete
7
+ include Assembly::Actions::Update
8
+ end
9
+
10
+ Resource.build(Result)
11
+ end
@@ -0,0 +1,7 @@
1
+ module Assembly
2
+ class SchoolDetail < ApiModel
3
+ include Assembly::Actions::List
4
+ end
5
+
6
+ Resource.build(SchoolDetail)
7
+ end
@@ -0,0 +1,8 @@
1
+ module Assembly
2
+ class StaffMember < ApiModel
3
+ include Assembly::Actions::Read
4
+ include Assembly::Actions::List
5
+ end
6
+
7
+ Resource.build(StaffMember)
8
+ end
@@ -0,0 +1,8 @@
1
+ module Assembly
2
+ class Student < ApiModel
3
+ include Assembly::Actions::Read
4
+ include Assembly::Actions::List
5
+ end
6
+
7
+ Resource.build(Student)
8
+ end
@@ -0,0 +1,7 @@
1
+ module Assembly
2
+ class Subject < ApiModel
3
+ include Assembly::Actions::List
4
+ end
5
+
6
+ Resource.build(Subject)
7
+ end
@@ -0,0 +1,13 @@
1
+ module Assembly
2
+ class TeachingGroup < ApiModel
3
+ include Assembly::Actions::Read
4
+ include Assembly::Actions::List
5
+
6
+ def students(params={})
7
+ response = client.get(path + '/students', params)
8
+ Util.build(response, client)
9
+ end
10
+ end
11
+
12
+ Resource.build(TeachingGroup)
13
+ end
@@ -0,0 +1,13 @@
1
+ module Assembly
2
+ class YearGroup < ApiModel
3
+ include Assembly::Actions::Read
4
+ include Assembly::Actions::List
5
+
6
+ def students(params={})
7
+ response = client.get(path + '/students', params)
8
+ Util.build(response, client)
9
+ end
10
+ end
11
+
12
+ Resource.build(YearGroup)
13
+ end
@@ -0,0 +1,65 @@
1
+ module Assembly
2
+ class Resource
3
+ def initialize(client)
4
+ @client = client
5
+ end
6
+
7
+ def self.build(model_class)
8
+ Assembly.const_set("#{model_class.class_name.split(':').last}Resource", resource_class_for(model_class))
9
+ end
10
+
11
+ def self.resource_class_for(model_class)
12
+ Class.new(Assembly::Resource) do
13
+ @model_class = model_class
14
+
15
+ def self.model_class
16
+ @model_class
17
+ end
18
+
19
+ def model_class
20
+ self.class.model_class
21
+ end
22
+
23
+ if model_class.included_modules.include?(Assembly::Actions::Create)
24
+ def create(params)
25
+ model_class.create(params, @client)
26
+ end
27
+ end
28
+
29
+ if model_class.included_modules.include?(Assembly::Actions::Read)
30
+ def fetch(id, params={})
31
+ model_class.fetch(id, params, @client)
32
+ end
33
+ alias_method :find, :fetch
34
+ end
35
+
36
+ if model_class.included_modules.include?(Assembly::Actions::List)
37
+ def list(params={})
38
+ model_class.list(params, @client)
39
+ end
40
+
41
+ def all(params={})
42
+ model_class.all(params, @client)
43
+ end
44
+
45
+ def total_count(params={})
46
+ model_class.total_count(params, @client)
47
+ end
48
+ end
49
+
50
+ if model_class.included_modules.include?(Assembly::Actions::Update)
51
+ def update(id, params)
52
+ model_class.update(id, params, @client)
53
+ end
54
+ end
55
+
56
+ if model_class.included_modules.include?(Assembly::Actions::Delete)
57
+ def delete(id)
58
+ model_class.delete(id, @client)
59
+ end
60
+ end
61
+
62
+ end
63
+ end
64
+ end
65
+ end