studyplus_for_school_sync 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: a2e702e5c3f589aae651d73fd8792ffe2e77d363f1d31e2260372bd141f6fe6e
4
+ data.tar.gz: 236437dbc571d0923d29060933bfc9aafd53cee3549b242d2f17ba17460c188c
5
+ SHA512:
6
+ metadata.gz: 1268f823939fd29b58ecccd8a1574af5ec7f6b9e8fff563b40e43b659d429cfd60b58e89ae57cf93bc926b4e4ea5e6418d51564066546ddc1a60682e6828f38f
7
+ data.tar.gz: 39adf012bec5f9d27f986e2ad273e2f70b1be5ab13475ca3650e3f336f2055ecab4fcfa462ffcd15a28b36bf3952bc978a39d794b36f9169e169f34c5046e6ce
data/.gitignore ADDED
@@ -0,0 +1,13 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+ /vendor/bundle
10
+ /.envrc
11
+
12
+ # rspec failure tracking
13
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.7.2
data/.travis.yml ADDED
@@ -0,0 +1,16 @@
1
+ ---
2
+ sudo: false
3
+ env:
4
+ global:
5
+ - CC_TEST_REPORTER_ID=6eafb21db695d9524525bbb70e8eb3f01a20329e9663451317e180a7c7d4a9de
6
+ language: ruby
7
+ cache: bundler
8
+ rvm:
9
+ - 2.7.2
10
+ before_install: gem install bundler -v 2.1.4
11
+ before_script:
12
+ - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
13
+ - chmod +x ./cc-test-reporter
14
+ - ./cc-test-reporter before-build
15
+ after_script:
16
+ - ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
@@ -0,0 +1,74 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to making participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, gender identity and expression, level of experience,
9
+ nationality, personal appearance, race, religion, or sexual identity and
10
+ orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
16
+
17
+ * Using welcoming and inclusive language
18
+ * Being respectful of differing viewpoints and experiences
19
+ * Gracefully accepting constructive criticism
20
+ * Focusing on what is best for the community
21
+ * Showing empathy towards other community members
22
+
23
+ Examples of unacceptable behavior by participants include:
24
+
25
+ * The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ * Trolling, insulting/derogatory comments, and personal or political attacks
28
+ * Public or private harassment
29
+ * Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies both within project spaces and in public spaces
49
+ when an individual is representing the project or its community. Examples of
50
+ representing a project or community include using an official project e-mail
51
+ address, posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event. Representation of a project may be
53
+ further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported by contacting the project team at shimada227@gmail.com. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
63
+
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
67
+
68
+ ## Attribution
69
+
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at [http://contributor-covenant.org/version/1/4][version]
72
+
73
+ [homepage]: http://contributor-covenant.org
74
+ [version]: http://contributor-covenant.org/version/1/4/
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "https://rubygems.org"
2
+
3
+ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ # Specify your gem's dependencies in studyplus_for_school_sync.gemspec
6
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,71 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ studyplus_for_school_sync (0.1.0)
5
+ faraday
6
+ faraday-encoding
7
+ faraday_middleware
8
+ launchy
9
+ thor
10
+ webrick
11
+
12
+ GEM
13
+ remote: https://rubygems.org/
14
+ specs:
15
+ addressable (2.8.0)
16
+ public_suffix (>= 2.0.2, < 5.0)
17
+ diff-lcs (1.3)
18
+ docile (1.4.0)
19
+ faraday (1.4.1)
20
+ faraday-excon (~> 1.1)
21
+ faraday-net_http (~> 1.0)
22
+ faraday-net_http_persistent (~> 1.1)
23
+ multipart-post (>= 1.2, < 3)
24
+ ruby2_keywords (>= 0.0.4)
25
+ faraday-encoding (0.0.5)
26
+ faraday
27
+ faraday-excon (1.1.0)
28
+ faraday-net_http (1.0.1)
29
+ faraday-net_http_persistent (1.1.0)
30
+ faraday_middleware (1.0.0)
31
+ faraday (~> 1.0)
32
+ launchy (2.5.0)
33
+ addressable (~> 2.7)
34
+ multipart-post (2.1.1)
35
+ public_suffix (4.0.6)
36
+ rake (13.0.1)
37
+ rspec (3.9.0)
38
+ rspec-core (~> 3.9.0)
39
+ rspec-expectations (~> 3.9.0)
40
+ rspec-mocks (~> 3.9.0)
41
+ rspec-core (3.9.1)
42
+ rspec-support (~> 3.9.1)
43
+ rspec-expectations (3.9.0)
44
+ diff-lcs (>= 1.2.0, < 2.0)
45
+ rspec-support (~> 3.9.0)
46
+ rspec-mocks (3.9.1)
47
+ diff-lcs (>= 1.2.0, < 2.0)
48
+ rspec-support (~> 3.9.0)
49
+ rspec-support (3.9.2)
50
+ ruby2_keywords (0.0.4)
51
+ simplecov (0.21.2)
52
+ docile (~> 1.1)
53
+ simplecov-html (~> 0.11)
54
+ simplecov_json_formatter (~> 0.1)
55
+ simplecov-html (0.12.3)
56
+ simplecov_json_formatter (0.1.3)
57
+ thor (1.1.0)
58
+ webrick (1.7.0)
59
+
60
+ PLATFORMS
61
+ ruby
62
+
63
+ DEPENDENCIES
64
+ bundler (~> 2.1)
65
+ rake (~> 13.0)
66
+ rspec (~> 3.0)
67
+ simplecov
68
+ studyplus_for_school_sync!
69
+
70
+ BUNDLED WITH
71
+ 2.1.4
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2020 shimada
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,129 @@
1
+ # StudyplusForSchoolSync
2
+
3
+ [![Build Status](https://travis-ci.com/yshimada0330/studyplus_for_school_sync.svg?branch=master)](https://travis-ci.com/yshimada0330/studyplus_for_school_sync)
4
+ [![Maintainability](https://api.codeclimate.com/v1/badges/be0e005027ea497a53db/maintainability)](https://codeclimate.com/github/yshimada0330/studyplus_for_school_sync/maintainability)
5
+ [![Test Coverage](https://api.codeclimate.com/v1/badges/be0e005027ea497a53db/test_coverage)](https://codeclimate.com/github/yshimada0330/studyplus_for_school_sync/test_coverage)
6
+ ![GitHub code size in bytes](https://img.shields.io/github/languages/code-size/yshimada0330/studyplus_for_school_sync)
7
+ [![Inline docs](https://inch-ci.org/github/yshimada0330/studyplus_for_school_sync.svg?branch=master)](http://inch-ci.org/github/yshimada0330/studyplus_for_school_sync)
8
+ ![GitHub](https://img.shields.io/github/license/yshimada0330/studyplus_for_school_sync)
9
+
10
+ A Ruby Client for [Studyplus for School SYNC API](https://studyplus.github.io/fs-sync-api/)
11
+
12
+ ![logo](https://user-images.githubusercontent.com/7440963/124934927-251b3180-e040-11eb-82bf-04cf82021593.jpg)
13
+
14
+ ## Installation
15
+
16
+ Add this line to your application's Gemfile:
17
+
18
+ ```ruby
19
+ gem 'studyplus_for_school_sync', github: 'yshimada0330/studyplus_for_school_sync'
20
+ ```
21
+
22
+ And then execute:
23
+
24
+ $ bundle
25
+
26
+ Or install it yourself as:
27
+
28
+ $ gem install studyplus_for_school_sync
29
+
30
+ ## Usage
31
+
32
+ ### Authorization
33
+
34
+ 1. Redirect Server Start: Case where the redirect server that receives authorization code is localhost
35
+ 1. Retrieve Authorization Code:
36
+ 1. If you start localhost, run it in a different terminal
37
+ 1. Authorize and receive the authorization code on the redirect server.
38
+ 1. Create/Refresh Token: Creating a token from authorization code
39
+
40
+ Redirect Server Start:
41
+
42
+ $ bundle exec studyplus_for_school_sync server
43
+
44
+ => https://localhost:8080/
45
+
46
+ If to get a token with a form
47
+
48
+ $ BASE_URL=[BASE_URL] bundle exec studyplus_for_school_sync server
49
+
50
+ If you want to change the port
51
+
52
+ $ bundle exec studyplus_for_school_sync server --port 3000
53
+
54
+ => https://localhost:3000/
55
+
56
+ Retrieve Authorization Code:
57
+
58
+ $ bundle exec studyplus_for_school_sync authorize [BASE_URL] [CLIENT_ID]
59
+
60
+ Create/Refresh Token:
61
+
62
+ ```ruby
63
+ base_url = "https://sandbox.fs-lms.studyplus.co.jp" # SYNC API URL
64
+ client_id = "sample_id" # YOUR CLIENT_ID
65
+ client_secret = "sample_pass" # YOUR CLIENT SECRET
66
+ authorization_code = "xxx" # Retrieve Authorization Code
67
+ token = StudyplusForSchoolSync::Token.new(base_url: base_url, client_id: client_id, client_secret: client_secret)
68
+ response = token.create(authorization_code: authorization_code, redirect_uri: "https://localhost:8080")
69
+ response.status # => 200
70
+ response.body # => {"access_token"=>"xxx", "token_type"=>"Bearer", "expires_in"=>86399, "refresh_token"=>"xxxx", "scope"=>"learning_material_supplier lms_passcode_issue", "created_at"=>1621558627}
71
+
72
+ # Refresh token
73
+ response = token.refresh(response.body["refresh_token"])
74
+ response.status # => 200
75
+ response.body # => {"access_token"=>"xxx", "token_type"=>"Bearer", "expires_in"=>86399, "refresh_token"=>"xxx", "scope"=>"learning_material_supplier lms_passcode_issue", "created_at"=>1621558753}
76
+ ```
77
+
78
+ ### Resource Access
79
+
80
+ `access_token` is the value obtained from Authorization flow.
81
+
82
+ ```ruby
83
+ client = StudyplusForSchoolSync::Client.new(base_url: base_url, access_token: access_token)
84
+ response = client.create_partner(school_name: "school A")
85
+ response.status # => 200
86
+ response.body # => {"public_id"=>"12345abcde"}
87
+
88
+ response = client.create_student(
89
+ partner_public_id: response.body["public_id"],
90
+ last_name: "山田",
91
+ first_name: "太郎",
92
+ last_name_kana: "ヤマダ",
93
+ first_name_kana: "タロウ"
94
+ )
95
+ response.status #=> 200
96
+ response.body # => {"public_id"=>"xxxx"}
97
+ student_public_id = response.body["public_id"]
98
+
99
+ response = client.create_learning_material(name: "text A")
100
+ learning_material_public_id = response.body["public_id"]
101
+ response = client.update_learning_material(learning_material_public_id: learning_material_public_id, name: "text B")
102
+
103
+ response = client.create_study_record(
104
+ learning_material_public_id: learning_material_public_id,
105
+ student_public_id: student_public_id,
106
+ recorded_at: "2020/03/01 09:30:10",
107
+ number_of_seconds: 600
108
+ )
109
+
110
+ response = client.create_passcode(student_public_id)
111
+ ```
112
+
113
+ ## Contributing
114
+
115
+ Bug reports and pull requests are welcome on GitHub at https://github.com/yshimada0330/studyplus_for_school_sync. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
116
+
117
+ 1. Fork it ( https://github.com/yshimada0330/studyplus_for_school_sync/fork )
118
+ 1. Create your feature branch (`git checkout -b my-new-feature`)
119
+ 1. Commit your changes (`git commit -am 'Add some feature'`)
120
+ 1. Push to the branch (`git push origin my-new-feature`)
121
+ 1. Create new Pull Request
122
+
123
+ ## License
124
+
125
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
126
+
127
+ ## Code of Conduct
128
+
129
+ Everyone interacting in the StudyplusForSchoolSync project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/yshimada0330/studyplus_for_school_sync/blob/master/CODE_OF_CONDUCT.md).
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "studyplus_for_school_sync"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "studyplus_for_school_sync"
4
+
5
+ StudyplusForSchoolSync::Cli.start
@@ -0,0 +1,12 @@
1
+ require "studyplus_for_school_sync/version"
2
+
3
+ require "studyplus_for_school_sync/endpoint"
4
+ require "studyplus_for_school_sync/client"
5
+ require "studyplus_for_school_sync/server"
6
+ require "studyplus_for_school_sync/authorizer"
7
+ require "studyplus_for_school_sync/token"
8
+ require "studyplus_for_school_sync/cli"
9
+
10
+ module StudyplusForSchoolSync
11
+ class Error < StandardError; end
12
+ end
@@ -0,0 +1,37 @@
1
+ require "uri"
2
+ require "launchy"
3
+
4
+ module StudyplusForSchoolSync
5
+ # Retrieve Authorization Code
6
+ class Authorizer
7
+ OOB_URI = 'urn:ietf:wg:oauth:2.0:oob'
8
+ RESPONSE_TYPE = "code"
9
+ END_POINT = "learning_material_supplier_api/v1/oauth/authorize"
10
+ DEFAULT_SCOPES = %w(learning_material_supplier lms_passcode_issue)
11
+
12
+ attr_reader :base_url, :client_id, :redirect_uri, :scopes
13
+
14
+ # @param base_url [String] API domain
15
+ # @param client_id [String] ApplicationClientID
16
+ # @param redirect_uri [String]
17
+ # @param scopes [Array]
18
+ def initialize(base_url:, client_id:, redirect_uri: nil, scopes: DEFAULT_SCOPES)
19
+ @base_url = base_url
20
+ @client_id = client_id
21
+ @redirect_uri = redirect_uri || OOB_URI
22
+ @scopes = scopes
23
+ end
24
+
25
+ # Launch the browser to get the Authorization Code and authorize it.
26
+ def authorize
27
+ query = URI.encode_www_form({ client_id: client_id, response_type: RESPONSE_TYPE, redirect_uri: redirect_uri, scope: scopes.join(" ") })
28
+ Launchy.open(build_url(query))
29
+ end
30
+
31
+ private
32
+
33
+ def build_url(query)
34
+ "#{URI.join(base_url, END_POINT)}?#{query}"
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,26 @@
1
+ require "thor"
2
+
3
+ module StudyplusForSchoolSync
4
+ # Command Line Tool
5
+ class Cli < Thor
6
+ DEFAULT_REDIRECT_URI = "https://localhost:8080"
7
+
8
+ desc "server", "Start the server for redirection. ex) server --port 8080"
9
+ option :port
10
+ def server
11
+ params = {}
12
+ params[:port] = options[:port] if options[:port]
13
+ StudyplusForSchoolSync::Server.new.start(**params)
14
+ end
15
+
16
+ desc "authorize [BASE_URL] [CLIENT_ID]", "Retrieve Authorization Code. ex) authorize https://xxxx.studyplus.co.jp xxxxxxxx"
17
+ option :redirect_uri
18
+ option :scopes, desc: "Specify scopes separated by commas"
19
+ def authorize(base_url, client_id)
20
+ params = { client_id: client_id, base_url: base_url, redirect_uri: DEFAULT_REDIRECT_URI }
21
+ params[:redirect_uri] = options[:redirect_uri] if options[:redirect_uri]
22
+ params[:scopes] = options[:scopes].split(",") if options[:scopes]
23
+ StudyplusForSchoolSync::Authorizer.new(**params).authorize
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,85 @@
1
+ require "uri"
2
+ require "json"
3
+ require "faraday"
4
+ require "faraday/encoding"
5
+ require "faraday_middleware"
6
+
7
+ module StudyplusForSchoolSync
8
+ # Sync API Http Client
9
+ class Client
10
+ include Endpoint
11
+
12
+ attr_accessor :access_token
13
+
14
+ # @param base_url [String] API domain
15
+ # @param access_token [String] OAuth access token
16
+ def initialize(base_url:, access_token: nil)
17
+ @base_url = base_url
18
+ @access_token = access_token
19
+ @conn = Faraday.new(headers: default_header) do |connection|
20
+ connection.response :json
21
+ connection.response :encoding
22
+ connection.adapter Faraday.default_adapter
23
+ end
24
+ end
25
+
26
+ # GET Http Request
27
+ # @param path [String]
28
+ # @param params [Hash]
29
+ # @return [Hash] API response
30
+ def get(path:, params: nil)
31
+ @conn.get(build_url(path)) do |req|
32
+ req.params = params if params
33
+ end
34
+ end
35
+
36
+ # POST Http Request
37
+ # @param path [String]
38
+ # @param params [Hash]
39
+ # @return [Hash] API response
40
+ def post(path:, params: nil)
41
+ @conn.post(build_url(path)) do |req|
42
+ req.body = params.to_json if params
43
+ end
44
+ end
45
+
46
+ # PUT Http Request
47
+ # @param path [String]
48
+ # @param params [Hash]
49
+ # @return [Hash] API response
50
+ def put(path:, params: nil)
51
+ @conn.put(build_url(path)) do |req|
52
+ req.body = params.to_json if params
53
+ end
54
+ end
55
+
56
+ # PATCH Http Request
57
+ # @param path [String]
58
+ # @param params [Hash]
59
+ # @return [Hash] API response
60
+ def patch(path:, params: nil)
61
+ @conn.patch(build_url(path)) do |req|
62
+ req.body = params.to_json if params
63
+ end
64
+ end
65
+
66
+ # DELETE Http Request
67
+ # @param path [String]
68
+ # @return [Hash] API response
69
+ def delete(path:)
70
+ @conn.delete(build_url(path))
71
+ end
72
+
73
+ private
74
+
75
+ def build_url(path)
76
+ URI.join(@base_url, path)
77
+ end
78
+
79
+ def default_header
80
+ header = { 'Accept' => 'application/json', 'Content-Type' => 'application/json' }
81
+ header['Authorization'] = "Bearer #{access_token}" if access_token
82
+ header
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,13 @@
1
+ require_relative "endpoint/learning_material"
2
+ require_relative "endpoint/partner"
3
+ require_relative "endpoint/student"
4
+
5
+ module StudyplusForSchoolSync
6
+ module Endpoint
7
+ BASE_PAH = "learning_material_supplier_api/v1"
8
+
9
+ include LearningMaterial
10
+ include Partner
11
+ include Student
12
+ end
13
+ end
@@ -0,0 +1,27 @@
1
+ module StudyplusForSchoolSync
2
+ module Endpoint
3
+ module LearningMaterial
4
+ # Creae learning material
5
+ # @param name[String] learning material name
6
+ # @param [Hash]options
7
+ # @option options [String] :image_url
8
+ # @option options [String] :unit
9
+ # @option options [String] :customer_id
10
+ # @return [Hash] API response
11
+ def create_learning_material(name:, **options)
12
+ post(path: "#{BASE_PAH}/learning_materials", params: options.merge(name: name))
13
+ end
14
+
15
+ # Update learning material
16
+ # @param name[String] learning material name
17
+ # @param [Hash] options
18
+ # @option options [String] :image_url
19
+ # @option options [String] :unit
20
+ # @option options [String] :customer_id
21
+ # @return [Hash] API response
22
+ def update_learning_material(learning_material_public_id:, name:, **options)
23
+ put(path: "#{BASE_PAH}/learning_materials/#{learning_material_public_id}", params: options.merge(name: name))
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,78 @@
1
+ module StudyplusForSchoolSync
2
+ module Endpoint
3
+ module Partner
4
+ # Create partner
5
+ # @param partner_name [String]
6
+ # @param [Hash] options
7
+ # @option options [String] :name
8
+ # @option options [String] :timezone
9
+ # @option options [String] :started_on
10
+ # @option options [String] :customer_id
11
+ # @return [Hash] API response
12
+ def create_partner(school_name:, **options)
13
+ post(path: "#{BASE_PAH}/partners", params: options.merge(school_name: school_name))
14
+ end
15
+
16
+ # Create student
17
+ # @param partner_public_id [String]
18
+ # @param last_name [String]
19
+ # @param first_name [String]
20
+ # @param last_name_kana [String]
21
+ # @param first_name_kana [String]
22
+ # @param [Hash] options
23
+ # @option options [String] :school_type
24
+ # @option options [String] :grade
25
+ # @option options [String] :code
26
+ # @return [Hash] API response
27
+ def create_student(partner_public_id:, last_name:, first_name:, last_name_kana:, first_name_kana:, **options)
28
+ post(
29
+ path: "#{BASE_PAH}/partners/#{partner_public_id}/students",
30
+ params: options.merge(
31
+ last_name: last_name,
32
+ first_name: first_name,
33
+ last_name_kana: last_name_kana,
34
+ first_name_kana: first_name_kana
35
+ )
36
+ )
37
+ end
38
+
39
+ # Get tags
40
+ # @param parner_id [String]
41
+ # @param page [Integer]
42
+ # @return [Hash] API response
43
+ def tags(partner_id:, page: 1)
44
+ get(path: "#{BASE_PAH}/partners/#{partner_id}/tags", params: { page: page })
45
+ end
46
+
47
+ # Creae tag
48
+ # @param partner_id [String]
49
+ # @param name [String]
50
+ # @param [Hash] options
51
+ # @option options [String] :customer_id
52
+ # @return [Hash] API response
53
+ def create_tag(partner_id:, name:, **options)
54
+ post(path: "#{BASE_PAH}/partners/#{partner_id}/tags", params: options.merge(name: name))
55
+ end
56
+
57
+ # Update tag
58
+ # @param partner_id [String]
59
+ # @param tag_id [String]
60
+ # @param name [String]
61
+ # @param options [Hash]
62
+ # @param options [String] :customer_id
63
+ # @return [Hash] API response
64
+ def update_tag(partner_id:, tag_id:, name:, **options)
65
+ patch(path: "#{BASE_PAH}/partners/#{partner_id}/tags/#{tag_id}", params: options.merge(name: name))
66
+ end
67
+
68
+ # Delete tag
69
+ # @param partner_id [String]
70
+ # @param tag_id [String]
71
+ # @return [Hash] API response
72
+ def delete_tag(partner_id:, tag_id:)
73
+ delete(path: "#{BASE_PAH}/partners/#{partner_id}/tags/#{tag_id}")
74
+ end
75
+ end
76
+ end
77
+ end
78
+
@@ -0,0 +1,83 @@
1
+ module StudyplusForSchoolSync
2
+ module Endpoint
3
+ module Student
4
+ # Creae passcode
5
+ # @param student_id [String]
6
+ # @return [Hash] API response
7
+ def create_passcode(student_id)
8
+ post(path: "#{BASE_PAH}/students/#{student_id}/passcode")
9
+ end
10
+
11
+ # Stop passcode
12
+ # @param student_id [String]
13
+ # @return [Hash] API response
14
+ def inactivate_passcode(student_id)
15
+ delete(path: "#{BASE_PAH}/students/#{student_id}/passcode")
16
+ end
17
+
18
+ # Create study record
19
+ # @param learning_material_public_id [String]
20
+ # @param student_public_id [String]
21
+ # @param recorded_at [String]
22
+ # @param [Hash] options
23
+ # @option options [Integer] :amount
24
+ # @option options [Integer] :number_of_seconds
25
+ # @option options [Integer] :start_position
26
+ # @option options [Integer] :end_position
27
+ # @option options [String] :comment
28
+ # @option options [String] :external_link
29
+ # @option options [String] :learning_material_customer_uid
30
+ # @option options [String] :student_customer_uid
31
+ # @return [Hash] API response
32
+ def create_study_record(learning_material_public_id:, student_public_id:, recorded_at:, **options)
33
+ post(
34
+ path: "#{BASE_PAH}/study_records",
35
+ params: options.merge(
36
+ learning_material_public_id: learning_material_public_id,
37
+ student_public_id: student_public_id,
38
+ recorded_at: recorded_at
39
+ )
40
+ )
41
+ end
42
+
43
+ # Get student tags
44
+ # @param student_id [String]
45
+ # @return [Hash] API response
46
+ def student_tags(student_id:)
47
+ get(path: "#{BASE_PAH}/students/#{student_id}/tags")
48
+ end
49
+
50
+ # Attach student tag
51
+ # @param student_id [String]
52
+ # @param tag_id [String]
53
+ # @return [Hash] API response
54
+ def attach_student_tag(student_id:, tag_id:)
55
+ put(path: "#{BASE_PAH}/students/#{student_id}/tags/#{tag_id}")
56
+ end
57
+
58
+ # Detach student tag
59
+ # @param student_id [String]
60
+ # @param tag_id [String]
61
+ # @return [Hash] API response
62
+ def detach_student_tag(student_id:, tag_id:)
63
+ delete(path: "#{BASE_PAH}/students/#{student_id}/tags/#{tag_id}")
64
+ end
65
+
66
+ # Ge transfer student
67
+ # @param student_id [String]
68
+ # @param transfer_id [String]
69
+ # @return [Hash] API response
70
+ def student_transfer(student_id:, transfer_id:)
71
+ get(path: "#{BASE_PAH}/students/#{student_id}/transfers/#{transfer_id}")
72
+ end
73
+
74
+ # Create transfer student
75
+ # @param student_id [String]
76
+ # @param partner_id [String]
77
+ # @return [Hash] API response
78
+ def create_student_transfer(student_id:, partner_id:)
79
+ post(path: "#{BASE_PAH}/students/#{student_id}/transfers", params: { partner_id: partner_id })
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,79 @@
1
+ <html>
2
+ <head>
3
+ <meta charset="utf-8"/>
4
+ <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
5
+ </head>
6
+ <body>
7
+ <div class="container">
8
+ <div class="row my-3">
9
+ <h1>StudyplusForSchoolSync</h1>
10
+ </div>
11
+ <div class="row my-3">
12
+ <div class="col-6">
13
+ <h2>Authorization Code</h2>
14
+ <input class="form-control" type="text" value="<%= code %>" aria-label="readonly input example" readonly>
15
+ </div>
16
+ </div>
17
+
18
+ <div class="row my-3">
19
+ <div class="col-6">
20
+ <h2>Request Token</h2>
21
+ <div class="card">
22
+ <div class="card-body">
23
+ The token can be obtained from the sdk or form
24
+ </div>
25
+ </div>
26
+ <h3>To get a token with a sdk</h3>
27
+ <div class="card">
28
+ <div class="card-body">
29
+ <pre>
30
+ <code>
31
+ token = StudyplusForSchoolSync::Token.new(
32
+ base_url: base_url,
33
+ client_id: client_id,
34
+ client_secret: client_secret
35
+ )
36
+ response = token.create(
37
+ authorization_code: "<%= code %>",
38
+ redirect_uri: redirect_uri
39
+ )
40
+ </code>
41
+ </pre>
42
+ </div>
43
+ </div>
44
+ <h3>To get a token with a form</h3>
45
+ BASE_URL:
46
+ <% if ENV["BASE_URL"] %>
47
+ <%= ENV["BASE_URL"] %>
48
+ <% else %>
49
+ <p class="text-danger">Specify the environment variable to start!!</p>
50
+ <% end %>
51
+ <form action="<%= ENV["BASE_URL"]%>/learning_material_supplier_api/v1/oauth/token" method="post">
52
+ <div class="mb-3">
53
+ <label class="form-label">client_id: </label>
54
+ <input type="text" name="client_id" class="form-control">
55
+ </div>
56
+ <div class="mb-3">
57
+ <label class="form-label">client_secret: </label>
58
+ <input type="text" name="client_secret" class="form-control">
59
+ </div>
60
+ <div class="mb-3">
61
+ <label class="form-label">redirect_uri: </label>
62
+ <input type="text" name="redirect_uri" class="form-control">
63
+ </div>
64
+ <div class="mb-3">
65
+ <label class="form-label">grant_type: </label>
66
+ <input type="text" name="grant_type" value="authorization_code" class="form-control">
67
+ </div>
68
+ <div class="mb-3">
69
+ <label class="form-label">code: </label>
70
+ <input type="text" name="code" value="<%= code %>" class="form-control">
71
+ </div>
72
+
73
+ <input class="btn btn-primary" type="submit" value="Submit">
74
+ </form>
75
+ </div>
76
+ </div>
77
+ </div>
78
+ </body>
79
+ </html>
@@ -0,0 +1,28 @@
1
+ require "webrick"
2
+ require "webrick/https"
3
+ require "erb"
4
+
5
+ module StudyplusForSchoolSync
6
+ class Server
7
+ def start(port: "8080")
8
+ root = File.expand_path("../html/index.erb", __FILE__)
9
+
10
+ server = WEBrick::HTTPServer.new(
11
+ Port: port,
12
+ DocumentRoot: ".",
13
+ SSLEnable: true,
14
+ SSLCertName: [["CN", WEBrick::Utils.getservername]],
15
+ )
16
+
17
+ WEBrick::HTTPServlet::FileHandler.add_handler("erb", WEBrick::HTTPServlet::ERBHandler)
18
+ server.config[:MimeTypes]["erb"] = "text/html"
19
+ server.mount_proc("/") { |req, res|
20
+ code = req.query["code"]
21
+ template = ERB.new(File.read(root))
22
+ res.body << template.result(binding)
23
+ }
24
+ trap "INT" do server.shutdown end
25
+ server.start
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,74 @@
1
+ require "uri"
2
+ require "json"
3
+ require "faraday"
4
+ require "faraday/encoding"
5
+ require "faraday_middleware"
6
+
7
+ module StudyplusForSchoolSync
8
+ # Handling access token
9
+ class Token
10
+ END_POINT = "/learning_material_supplier_api/v1/oauth/token"
11
+
12
+ attr_reader :base_url, :client_id, :client_secret, :grant_type
13
+
14
+ # @param base_url [String] API domain
15
+ # @param client_id [String] Application ClientID
16
+ # @param client_secret [String] Application Secret
17
+ def initialize(base_url:, client_id:, client_secret:)
18
+ @base_url = base_url
19
+ @client_id = client_id
20
+ @client_secret = client_secret
21
+ @conn = Faraday.new(headers: default_header) do |connection|
22
+ connection.response :json
23
+ connection.response :encoding
24
+ connection.adapter Faraday.default_adapter
25
+ end
26
+ end
27
+
28
+ # Creating a token from authorization code
29
+ # @param authorization_code [String] Authorization Code
30
+ # @param redirect_uri [String] Application Redirect URI
31
+ def create(authorization_code:, redirect_uri:)
32
+ post(
33
+ path: END_POINT,
34
+ params: {
35
+ client_id: client_id,
36
+ client_secret: client_secret,
37
+ redirect_uri: redirect_uri,
38
+ grant_type: "authorization_code",
39
+ code: authorization_code,
40
+ }
41
+ )
42
+ end
43
+
44
+ # Refresh Token
45
+ # @param refresh_token [String] Refresh token obtained during token generation
46
+ def refresh(refresh_token)
47
+ post(
48
+ path: END_POINT,
49
+ params: {
50
+ client_id: client_id,
51
+ client_secret: client_secret,
52
+ grant_type: "refresh_token",
53
+ refresh_token: refresh_token,
54
+ }
55
+ )
56
+ end
57
+
58
+ private
59
+
60
+ def post(path:, params: nil)
61
+ @conn.post(build_url(path)) do |req|
62
+ req.body = params.to_json if params
63
+ end
64
+ end
65
+
66
+ def build_url(path)
67
+ URI.join(base_url, path)
68
+ end
69
+
70
+ def default_header
71
+ { "Accept" => "application/json", "Content-Type" => "application/json" }
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,3 @@
1
+ module StudyplusForSchoolSync
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,36 @@
1
+
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "studyplus_for_school_sync/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "studyplus_for_school_sync"
8
+ spec.version = StudyplusForSchoolSync::VERSION
9
+ spec.authors = ["shimada"]
10
+ spec.email = ["shimada227@gmail.com"]
11
+
12
+ spec.summary = "StudyplusForSchoolSync::Client - SDK of the Studyplus for School SYNC API for Ruby"
13
+ spec.description = "SDK of the Studyplus for School SYNC API for Ruby"
14
+ spec.homepage = "https://github.com/yshimada0330/studyplus_for_school_sync"
15
+ spec.license = "MIT"
16
+
17
+ # Specify which files should be added to the gem when it is released.
18
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
19
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
20
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
21
+ end
22
+ spec.bindir = "exe"
23
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
24
+ spec.require_paths = ["lib"]
25
+
26
+ spec.add_dependency "faraday"
27
+ spec.add_dependency "faraday-encoding"
28
+ spec.add_dependency "faraday_middleware"
29
+ spec.add_dependency "launchy"
30
+ spec.add_dependency "thor"
31
+ spec.add_dependency "webrick"
32
+ spec.add_development_dependency "bundler", "~> 2.1"
33
+ spec.add_development_dependency "rake", "~> 13.0"
34
+ spec.add_development_dependency "rspec", "~> 3.0"
35
+ spec.add_development_dependency "simplecov"
36
+ end
metadata ADDED
@@ -0,0 +1,211 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: studyplus_for_school_sync
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - shimada
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2021-07-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: faraday
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: faraday-encoding
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: faraday_middleware
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: launchy
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: thor
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: webrick
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: bundler
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '2.1'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '2.1'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rake
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '13.0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '13.0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: rspec
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '3.0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '3.0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: simplecov
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ description: SDK of the Studyplus for School SYNC API for Ruby
154
+ email:
155
+ - shimada227@gmail.com
156
+ executables:
157
+ - studyplus_for_school_sync
158
+ extensions: []
159
+ extra_rdoc_files: []
160
+ files:
161
+ - ".gitignore"
162
+ - ".rspec"
163
+ - ".ruby-version"
164
+ - ".travis.yml"
165
+ - CODE_OF_CONDUCT.md
166
+ - Gemfile
167
+ - Gemfile.lock
168
+ - LICENSE.txt
169
+ - README.md
170
+ - Rakefile
171
+ - bin/console
172
+ - bin/setup
173
+ - exe/studyplus_for_school_sync
174
+ - lib/studyplus_for_school_sync.rb
175
+ - lib/studyplus_for_school_sync/authorizer.rb
176
+ - lib/studyplus_for_school_sync/cli.rb
177
+ - lib/studyplus_for_school_sync/client.rb
178
+ - lib/studyplus_for_school_sync/endpoint.rb
179
+ - lib/studyplus_for_school_sync/endpoint/learning_material.rb
180
+ - lib/studyplus_for_school_sync/endpoint/partner.rb
181
+ - lib/studyplus_for_school_sync/endpoint/student.rb
182
+ - lib/studyplus_for_school_sync/html/index.erb
183
+ - lib/studyplus_for_school_sync/server.rb
184
+ - lib/studyplus_for_school_sync/token.rb
185
+ - lib/studyplus_for_school_sync/version.rb
186
+ - studyplus_for_school_sync.gemspec
187
+ homepage: https://github.com/yshimada0330/studyplus_for_school_sync
188
+ licenses:
189
+ - MIT
190
+ metadata: {}
191
+ post_install_message:
192
+ rdoc_options: []
193
+ require_paths:
194
+ - lib
195
+ required_ruby_version: !ruby/object:Gem::Requirement
196
+ requirements:
197
+ - - ">="
198
+ - !ruby/object:Gem::Version
199
+ version: '0'
200
+ required_rubygems_version: !ruby/object:Gem::Requirement
201
+ requirements:
202
+ - - ">="
203
+ - !ruby/object:Gem::Version
204
+ version: '0'
205
+ requirements: []
206
+ rubygems_version: 3.1.4
207
+ signing_key:
208
+ specification_version: 4
209
+ summary: StudyplusForSchoolSync::Client - SDK of the Studyplus for School SYNC API
210
+ for Ruby
211
+ test_files: []