From 8b80bd766f17b2724b1ab005394bc923e38232a8 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Thu, 26 Nov 2015 17:34:36 +0900 Subject: [PATCH 001/358] create get access token method --- app/apis/api/v1/authorize.rb | 12 ++++++++++++ app/views/apis/api/v1/auth/token.jbuilder | 1 + 2 files changed, 13 insertions(+) create mode 100644 app/views/apis/api/v1/auth/token.jbuilder diff --git a/app/apis/api/v1/authorize.rb b/app/apis/api/v1/authorize.rb index 9d575db..073595b 100644 --- a/app/apis/api/v1/authorize.rb +++ b/app/apis/api/v1/authorize.rb @@ -11,6 +11,18 @@ class Authorize < Grape::API end end resource :auth do + desc 'トークンの取得', notes: <<-NOTE +

アクセストークンを作成する

+

+ このURLにリクエストすることによって、アクセストークンを取得することができます。
+ アクセストークンは基本的にどんなリクエストをする時でも必要なので、値をキャッシュするようにしてください。 +

+ NOTE + get '/token', jbuilder: 'api/v1/auth/token' do + user = save_object(User.new) + @token = user.auth_tokens.new_token + end + desc '確認用のテストAPI', notes: <<-NOTE

signup

diff --git a/app/views/apis/api/v1/auth/token.jbuilder b/app/views/apis/api/v1/auth/token.jbuilder new file mode 100644 index 0000000..f0088ec --- /dev/null +++ b/app/views/apis/api/v1/auth/token.jbuilder @@ -0,0 +1 @@ +json.auth_token @token \ No newline at end of file From 98f637869e487ff8a344bf35dccb1ae4f082a456 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Thu, 26 Nov 2015 18:23:30 +0900 Subject: [PATCH 002/358] create jbuilder file --- app/views/apis/api/v1/auth/token.jbuilder | 1 - app/views/apis/api/v1/{auth => authorize}/signup.jbuilder | 0 app/views/apis/api/v1/authorize/token.jbuilder | 1 + 3 files changed, 1 insertion(+), 1 deletion(-) delete mode 100644 app/views/apis/api/v1/auth/token.jbuilder rename app/views/apis/api/v1/{auth => authorize}/signup.jbuilder (100%) create mode 100644 app/views/apis/api/v1/authorize/token.jbuilder diff --git a/app/views/apis/api/v1/auth/token.jbuilder b/app/views/apis/api/v1/auth/token.jbuilder deleted file mode 100644 index f0088ec..0000000 --- a/app/views/apis/api/v1/auth/token.jbuilder +++ /dev/null @@ -1 +0,0 @@ -json.auth_token @token \ No newline at end of file diff --git a/app/views/apis/api/v1/auth/signup.jbuilder b/app/views/apis/api/v1/authorize/signup.jbuilder similarity index 100% rename from app/views/apis/api/v1/auth/signup.jbuilder rename to app/views/apis/api/v1/authorize/signup.jbuilder diff --git a/app/views/apis/api/v1/authorize/token.jbuilder b/app/views/apis/api/v1/authorize/token.jbuilder new file mode 100644 index 0000000..c978e8d --- /dev/null +++ b/app/views/apis/api/v1/authorize/token.jbuilder @@ -0,0 +1 @@ +json.auth_token @token From 7c2d70da60f25ac1c8e6e68c40c53b06919e7661 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Thu, 26 Nov 2015 18:23:37 +0900 Subject: [PATCH 003/358] bundle install --- Gemfile | 10 ++++++++- Gemfile.lock | 57 ++++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 53 insertions(+), 14 deletions(-) diff --git a/Gemfile b/Gemfile index 463a2cf..b70833b 100644 --- a/Gemfile +++ b/Gemfile @@ -55,5 +55,13 @@ group :development, :test do gem 'awesome_print' gem 'quiet_assets' gem 'annotate' - gem 'rspec-rails', '~> 3.0.0.beta2' + gem 'rspec-rails', '~> 3.1.0' + gem 'factory_girl_rails', "~> 4.4.1" +end + +group :test do + gem "faker", "~> 1.4.3" + gem "capybara", "~> 2.4.3" + gem "database_cleaner", "~> 1.3.0" + gem "selenium-webdriver", "~> 2.43.0" end diff --git a/Gemfile.lock b/Gemfile.lock index e114a1a..dbbbf1e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -53,6 +53,14 @@ GEM debug_inspector (>= 0.0.1) builder (3.2.2) byebug (8.2.0) + capybara (2.4.4) + mime-types (>= 1.16) + nokogiri (>= 1.3.3) + rack (>= 1.0.0) + rack-test (>= 0.5.4) + xpath (~> 2.0) + childprocess (0.5.8) + ffi (~> 1.0, >= 1.0.11) choice (0.2.0) coderay (1.1.0) coercible (1.0.0) @@ -64,6 +72,7 @@ GEM coffee-script-source execjs coffee-script-source (1.10.0) + database_cleaner (1.3.0) debug_inspector (0.0.2) descendants_tracker (0.0.4) thread_safe (~> 0.3, >= 0.3.1) @@ -71,6 +80,14 @@ GEM equalizer (0.0.11) erubis (2.7.0) execjs (2.6.0) + factory_girl (4.4.0) + activesupport (>= 3.0.0) + factory_girl_rails (4.4.1) + factory_girl (~> 4.4.0) + railties (>= 3.0.0) + faker (1.4.3) + i18n (~> 0.5) + ffi (1.9.10) globalid (0.3.6) activesupport (>= 4.1.0) grape (0.13.0) @@ -194,22 +211,22 @@ GEM rake (10.4.2) rdoc (4.2.0) json (~> 1.4) - rspec-core (3.0.3) - rspec-support (~> 3.0.0) - rspec-expectations (3.0.3) + rspec-core (3.1.7) + rspec-support (~> 3.1.0) + rspec-expectations (3.1.2) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.0.0) - rspec-mocks (3.0.3) - rspec-support (~> 3.0.0) - rspec-rails (3.0.2) + rspec-support (~> 3.1.0) + rspec-mocks (3.1.3) + rspec-support (~> 3.1.0) + rspec-rails (3.1.0) actionpack (>= 3.0) activesupport (>= 3.0) railties (>= 3.0) - rspec-core (~> 3.0.0) - rspec-expectations (~> 3.0.0) - rspec-mocks (~> 3.0.0) - rspec-support (~> 3.0.0) - rspec-support (3.0.3) + rspec-core (~> 3.1.0) + rspec-expectations (~> 3.1.0) + rspec-mocks (~> 3.1.0) + rspec-support (~> 3.1.0) + rspec-support (3.1.2) rubocop (0.35.1) astrolabe (~> 1.3) parser (>= 2.2.3.0, < 3.0) @@ -221,6 +238,7 @@ GEM ruby-progressbar (1.7.5) ruby_parser (3.7.1) sexp_processor (~> 4.1) + rubyzip (1.1.7) sass (3.4.19) sass-rails (5.0.4) railties (>= 4.0.0, < 5.0) @@ -231,6 +249,11 @@ GEM sdoc (0.4.1) json (~> 1.7, >= 1.7.7) rdoc (~> 4.0) + selenium-webdriver (2.43.0) + childprocess (~> 0.5) + multi_json (~> 1.0) + rubyzip (~> 1.0) + websocket (~> 1.0) sexp_processor (4.6.0) slop (3.6.0) spring (1.4.4) @@ -268,6 +291,9 @@ GEM binding_of_caller (>= 0.7.2) railties (>= 4.0) sprockets-rails (>= 2.0, < 4.0) + websocket (1.2.2) + xpath (2.0.0) + nokogiri (~> 1.3) yard (0.8.7.6) PLATFORMS @@ -278,7 +304,11 @@ DEPENDENCIES awesome_print bcrypt (~> 3.1.7) byebug + capybara (~> 2.4.3) coffee-rails (~> 4.1.0) + database_cleaner (~> 1.3.0) + factory_girl_rails (~> 4.4.1) + faker (~> 1.4.3) grape grape-jbuilder grape-swagger @@ -294,10 +324,11 @@ DEPENDENCIES quiet_assets rails (= 4.2.1) rails-erd - rspec-rails (~> 3.0.0.beta2) + rspec-rails (~> 3.1.0) rubocop sass-rails (~> 5.0) sdoc (~> 0.4.0) + selenium-webdriver (~> 2.43.0) spring sqlite3 tapp From 59f6be2fde9ca7e9502eab32516756c3a65a2922 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Thu, 26 Nov 2015 18:23:43 +0900 Subject: [PATCH 004/358] bin/rails generate rspec:install --- .rspec | 2 ++ spec/rails_helper.rb | 50 ++++++++++++++++++++++++++ spec/spec_helper.rb | 85 ++++++++++++++++++++++++++++++++++++++++++++ spec/test_spec.rb | 5 --- 4 files changed, 137 insertions(+), 5 deletions(-) create mode 100644 .rspec create mode 100644 spec/rails_helper.rb create mode 100644 spec/spec_helper.rb delete mode 100644 spec/test_spec.rb diff --git a/.rspec b/.rspec new file mode 100644 index 0000000..83e16f8 --- /dev/null +++ b/.rspec @@ -0,0 +1,2 @@ +--color +--require spec_helper diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb new file mode 100644 index 0000000..e6c0b68 --- /dev/null +++ b/spec/rails_helper.rb @@ -0,0 +1,50 @@ +# This file is copied to spec/ when you run 'rails generate rspec:install' +ENV["RAILS_ENV"] ||= 'test' +require 'spec_helper' +require File.expand_path("../../config/environment", __FILE__) +require 'rspec/rails' +# Add additional requires below this line. Rails is not loaded until this point! + +# Requires supporting ruby files with custom matchers and macros, etc, in +# spec/support/ and its subdirectories. Files matching `spec/**/*_spec.rb` are +# run as spec files by default. This means that files in spec/support that end +# in _spec.rb will both be required and run as specs, causing the specs to be +# run twice. It is recommended that you do not name files matching this glob to +# end with _spec.rb. You can configure this pattern with the --pattern +# option on the command line or in ~/.rspec, .rspec or `.rspec-local`. +# +# The following line is provided for convenience purposes. It has the downside +# of increasing the boot-up time by auto-requiring all files in the support +# directory. Alternatively, in the individual `*_spec.rb` files, manually +# require only the support files necessary. +# +# Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f } + +# Checks for pending migrations before tests are run. +# If you are not using ActiveRecord, you can remove this line. +ActiveRecord::Migration.maintain_test_schema! + +RSpec.configure do |config| + # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures + config.fixture_path = "#{::Rails.root}/spec/fixtures" + + # If you're not using ActiveRecord, or you'd prefer not to run each of your + # examples within a transaction, remove the following line or assign false + # instead of true. + config.use_transactional_fixtures = true + + # RSpec Rails can automatically mix in different behaviours to your tests + # based on their file location, for example enabling you to call `get` and + # `post` in specs under `spec/controllers`. + # + # You can disable this behaviour by removing the line below, and instead + # explicitly tag your specs with their type, e.g.: + # + # RSpec.describe UsersController, :type => :controller do + # # ... + # end + # + # The different available types are documented in the features, such as in + # https://relishapp.com/rspec/rspec-rails/docs + config.infer_spec_type_from_file_location! +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb new file mode 100644 index 0000000..275ba49 --- /dev/null +++ b/spec/spec_helper.rb @@ -0,0 +1,85 @@ +# This file was generated by the `rails generate rspec:install` command. Conventionally, all +# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`. +# The generated `.rspec` file contains `--require spec_helper` which will cause this +# file to always be loaded, without a need to explicitly require it in any files. +# +# Given that it is always loaded, you are encouraged to keep this file as +# light-weight as possible. Requiring heavyweight dependencies from this file +# will add to the boot time of your test suite on EVERY test run, even for an +# individual file that may not need all of that loaded. Instead, consider making +# a separate helper file that requires the additional dependencies and performs +# the additional setup, and require it from the spec files that actually need it. +# +# The `.rspec` file also contains a few flags that are not defaults but that +# users commonly want. +# +# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration +RSpec.configure do |config| + # rspec-expectations config goes here. You can use an alternate + # assertion/expectation library such as wrong or the stdlib/minitest + # assertions if you prefer. + config.expect_with :rspec do |expectations| + # This option will default to `true` in RSpec 4. It makes the `description` + # and `failure_message` of custom matchers include text for helper methods + # defined using `chain`, e.g.: + # be_bigger_than(2).and_smaller_than(4).description + # # => "be bigger than 2 and smaller than 4" + # ...rather than: + # # => "be bigger than 2" + expectations.include_chain_clauses_in_custom_matcher_descriptions = true + end + + # rspec-mocks config goes here. You can use an alternate test double + # library (such as bogus or mocha) by changing the `mock_with` option here. + config.mock_with :rspec do |mocks| + # Prevents you from mocking or stubbing a method that does not exist on + # a real object. This is generally recommended, and will default to + # `true` in RSpec 4. + mocks.verify_partial_doubles = true + end + +# The settings below are suggested to provide a good initial experience +# with RSpec, but feel free to customize to your heart's content. +=begin + # These two settings work together to allow you to limit a spec run + # to individual examples or groups you care about by tagging them with + # `:focus` metadata. When nothing is tagged with `:focus`, all examples + # get run. + config.filter_run :focus + config.run_all_when_everything_filtered = true + + # Limits the available syntax to the non-monkey patched syntax that is recommended. + # For more details, see: + # - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax + # - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/ + # - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching + config.disable_monkey_patching! + + # Many RSpec users commonly either run the entire suite or an individual + # file, and it's useful to allow more verbose output when running an + # individual spec file. + if config.files_to_run.one? + # Use the documentation formatter for detailed output, + # unless a formatter has already been configured + # (e.g. via a command-line flag). + config.default_formatter = 'doc' + end + + # Print the 10 slowest examples and example groups at the + # end of the spec run, to help surface which specs are running + # particularly slow. + config.profile_examples = 10 + + # Run specs in random order to surface order dependencies. If you find an + # order dependency and want to debug it, you can fix the order by providing + # the seed, which is printed after each run. + # --seed 1234 + config.order = :random + + # Seed global randomization in this process using the `--seed` CLI option. + # Setting this allows you to use `--seed` to deterministically reproduce + # test failures related to randomization by passing the same `--seed` value + # as the one that triggered the failure. + Kernel.srand config.seed +=end +end diff --git a/spec/test_spec.rb b/spec/test_spec.rb deleted file mode 100644 index 7dd62c7..0000000 --- a/spec/test_spec.rb +++ /dev/null @@ -1,5 +0,0 @@ -describe '足し算' do - it '1+1' do - expect(1+1).to eq (2) - end -end \ No newline at end of file From 145d9b04baf33bcca066936255595d42b5fbc39e Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Thu, 26 Nov 2015 18:24:31 +0900 Subject: [PATCH 005/358] bundle binstubs rspec-core --- bin/rspec | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100755 bin/rspec diff --git a/bin/rspec b/bin/rspec new file mode 100755 index 0000000..0c86b5c --- /dev/null +++ b/bin/rspec @@ -0,0 +1,16 @@ +#!/usr/bin/env ruby +# +# This file was generated by Bundler. +# +# The application 'rspec' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'pathname' +ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require 'rubygems' +require 'bundler/setup' + +load Gem.bin_path('rspec-core', 'rspec') From 46715cbe11594548ab851534e35321189d6cc1ee Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Thu, 26 Nov 2015 18:24:59 +0900 Subject: [PATCH 006/358] rspec formatting --- .rspec | 1 + 1 file changed, 1 insertion(+) diff --git a/.rspec b/.rspec index 83e16f8..43ae203 100644 --- a/.rspec +++ b/.rspec @@ -1,2 +1,3 @@ --color --require spec_helper +--format documentation From 116d8e8d04aed10093c183f81b577a447cbd459a Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Thu, 26 Nov 2015 18:26:00 +0900 Subject: [PATCH 007/358] =?UTF-8?q?rspec=E3=81=AE=E8=87=AA=E5=8B=95?= =?UTF-8?q?=E7=94=9F=E6=88=90=E3=81=AE=E8=A8=AD=E5=AE=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/application.rb | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/config/application.rb b/config/application.rb index 4cb9da7..2790797 100644 --- a/config/application.rb +++ b/config/application.rb @@ -14,6 +14,18 @@ class Application < Rails::Application env['api.tilt.root'] = Rails.root.join 'app', 'views', 'apis' end config.assets.precompile += ['swagger_ui.css', 'swagger_ui.js'] + + #rspecの自動生成の設定 + config.generatorsdo|g| + g.test_framework :rspec, + fixtures: true, + view_specs: false, + helper_specs: false, + routing_specs: false, + controller_specs: true, + request_specs: false + g.fixture_replacement :factory_girl, dir: "spec/factories" + end # Settings in config/environments/* take precedence over those specified here. # Application configuration should go into files in config/initializers # -- all .rb files in that directory are automatically loaded. From ef46b13ab9e244ac016cd1f6eb54eba3a6572105 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Thu, 26 Nov 2015 18:27:16 +0900 Subject: [PATCH 008/358] setting factory girl and capybara --- spec/rails_helper.rb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index e6c0b68..c9c8c4a 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -33,6 +33,12 @@ # instead of true. config.use_transactional_fixtures = true + # FactoryGirl.buildなどの呼び出しを、create, buildなどでメソッドが呼べる + config.include FactoryGirl::Syntax::Methods + + # capybaraでvisit使おうとするとエラーが出るときに、下記を書く + config.include Capybara::DSL + # RSpec Rails can automatically mix in different behaviours to your tests # based on their file location, for example enabling you to call `get` and # `post` in specs under `spec/controllers`. From cb908b11422eb482c92b368add551fdf636a7dbf Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Thu, 26 Nov 2015 18:31:02 +0900 Subject: [PATCH 009/358] bundle install --- Gemfile | 4 ++++ Gemfile.lock | 17 +++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/Gemfile b/Gemfile index b70833b..7964930 100644 --- a/Gemfile +++ b/Gemfile @@ -64,4 +64,8 @@ group :test do gem "capybara", "~> 2.4.3" gem "database_cleaner", "~> 1.3.0" gem "selenium-webdriver", "~> 2.43.0" + gem 'database_rewinder' + gem 'rspec-request_describer' + gem 'autodoc' + gem 'json_spec' end diff --git a/Gemfile.lock b/Gemfile.lock index dbbbf1e..75664a1 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -43,6 +43,10 @@ GEM ast (2.1.0) astrolabe (1.3.1) parser (~> 2.2) + autodoc (0.5.2) + actionpack + activesupport (>= 3.0.0) + rspec awesome_print (1.6.1) axiom-types (0.1.1) descendants_tracker (~> 0.0.4) @@ -73,6 +77,7 @@ GEM execjs coffee-script-source (1.10.0) database_cleaner (1.3.0) + database_rewinder (0.5.3) debug_inspector (0.0.2) descendants_tracker (0.0.4) thread_safe (~> 0.3, >= 0.3.1) @@ -142,6 +147,9 @@ GEM railties (>= 4.2.0) thor (>= 0.14, < 2.0) json (1.8.3) + json_spec (1.1.4) + multi_json (~> 1.0) + rspec (>= 2.0, < 4.0) loofah (2.0.3) nokogiri (>= 1.5.9) mail (2.6.3) @@ -211,6 +219,10 @@ GEM rake (10.4.2) rdoc (4.2.0) json (~> 1.4) + rspec (3.1.0) + rspec-core (~> 3.1.0) + rspec-expectations (~> 3.1.0) + rspec-mocks (~> 3.1.0) rspec-core (3.1.7) rspec-support (~> 3.1.0) rspec-expectations (3.1.2) @@ -226,6 +238,7 @@ GEM rspec-expectations (~> 3.1.0) rspec-mocks (~> 3.1.0) rspec-support (~> 3.1.0) + rspec-request_describer (0.1.0) rspec-support (3.1.2) rubocop (0.35.1) astrolabe (~> 1.3) @@ -301,12 +314,14 @@ PLATFORMS DEPENDENCIES annotate + autodoc awesome_print bcrypt (~> 3.1.7) byebug capybara (~> 2.4.3) coffee-rails (~> 4.1.0) database_cleaner (~> 1.3.0) + database_rewinder factory_girl_rails (~> 4.4.1) faker (~> 1.4.3) grape @@ -318,6 +333,7 @@ DEPENDENCIES hirb-unicode jbuilder (~> 2.0) jquery-rails + json_spec pry-byebug pry-doc pry-rails @@ -325,6 +341,7 @@ DEPENDENCIES rails (= 4.2.1) rails-erd rspec-rails (~> 3.1.0) + rspec-request_describer rubocop sass-rails (~> 5.0) sdoc (~> 0.4.0) From db15ab52b7696fd21ea32c53f99d535c4f535059 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Thu, 26 Nov 2015 19:27:18 +0900 Subject: [PATCH 010/358] bundle instal --- Gemfile | 14 ++-------- Gemfile.lock | 76 +++++++++++----------------------------------------- 2 files changed, 17 insertions(+), 73 deletions(-) diff --git a/Gemfile b/Gemfile index 7964930..d497b16 100644 --- a/Gemfile +++ b/Gemfile @@ -55,17 +55,7 @@ group :development, :test do gem 'awesome_print' gem 'quiet_assets' gem 'annotate' - gem 'rspec-rails', '~> 3.1.0' - gem 'factory_girl_rails', "~> 4.4.1" + gem 'json_expressions' + gem 'rspec-rails', '~> 3.0.0' end -group :test do - gem "faker", "~> 1.4.3" - gem "capybara", "~> 2.4.3" - gem "database_cleaner", "~> 1.3.0" - gem "selenium-webdriver", "~> 2.43.0" - gem 'database_rewinder' - gem 'rspec-request_describer' - gem 'autodoc' - gem 'json_spec' -end diff --git a/Gemfile.lock b/Gemfile.lock index 75664a1..b947311 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -43,10 +43,6 @@ GEM ast (2.1.0) astrolabe (1.3.1) parser (~> 2.2) - autodoc (0.5.2) - actionpack - activesupport (>= 3.0.0) - rspec awesome_print (1.6.1) axiom-types (0.1.1) descendants_tracker (~> 0.0.4) @@ -57,14 +53,6 @@ GEM debug_inspector (>= 0.0.1) builder (3.2.2) byebug (8.2.0) - capybara (2.4.4) - mime-types (>= 1.16) - nokogiri (>= 1.3.3) - rack (>= 1.0.0) - rack-test (>= 0.5.4) - xpath (~> 2.0) - childprocess (0.5.8) - ffi (~> 1.0, >= 1.0.11) choice (0.2.0) coderay (1.1.0) coercible (1.0.0) @@ -76,8 +64,6 @@ GEM coffee-script-source execjs coffee-script-source (1.10.0) - database_cleaner (1.3.0) - database_rewinder (0.5.3) debug_inspector (0.0.2) descendants_tracker (0.0.4) thread_safe (~> 0.3, >= 0.3.1) @@ -85,14 +71,6 @@ GEM equalizer (0.0.11) erubis (2.7.0) execjs (2.6.0) - factory_girl (4.4.0) - activesupport (>= 3.0.0) - factory_girl_rails (4.4.1) - factory_girl (~> 4.4.0) - railties (>= 3.0.0) - faker (1.4.3) - i18n (~> 0.5) - ffi (1.9.10) globalid (0.3.6) activesupport (>= 4.1.0) grape (0.13.0) @@ -147,9 +125,7 @@ GEM railties (>= 4.2.0) thor (>= 0.14, < 2.0) json (1.8.3) - json_spec (1.1.4) - multi_json (~> 1.0) - rspec (>= 2.0, < 4.0) + json_expressions (0.8.3) loofah (2.0.3) nokogiri (>= 1.5.9) mail (2.6.3) @@ -219,27 +195,22 @@ GEM rake (10.4.2) rdoc (4.2.0) json (~> 1.4) - rspec (3.1.0) - rspec-core (~> 3.1.0) - rspec-expectations (~> 3.1.0) - rspec-mocks (~> 3.1.0) - rspec-core (3.1.7) - rspec-support (~> 3.1.0) - rspec-expectations (3.1.2) + rspec-core (3.0.4) + rspec-support (~> 3.0.0) + rspec-expectations (3.0.4) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.1.0) - rspec-mocks (3.1.3) - rspec-support (~> 3.1.0) - rspec-rails (3.1.0) + rspec-support (~> 3.0.0) + rspec-mocks (3.0.4) + rspec-support (~> 3.0.0) + rspec-rails (3.0.2) actionpack (>= 3.0) activesupport (>= 3.0) railties (>= 3.0) - rspec-core (~> 3.1.0) - rspec-expectations (~> 3.1.0) - rspec-mocks (~> 3.1.0) - rspec-support (~> 3.1.0) - rspec-request_describer (0.1.0) - rspec-support (3.1.2) + rspec-core (~> 3.0.0) + rspec-expectations (~> 3.0.0) + rspec-mocks (~> 3.0.0) + rspec-support (~> 3.0.0) + rspec-support (3.0.4) rubocop (0.35.1) astrolabe (~> 1.3) parser (>= 2.2.3.0, < 3.0) @@ -251,7 +222,6 @@ GEM ruby-progressbar (1.7.5) ruby_parser (3.7.1) sexp_processor (~> 4.1) - rubyzip (1.1.7) sass (3.4.19) sass-rails (5.0.4) railties (>= 4.0.0, < 5.0) @@ -262,11 +232,6 @@ GEM sdoc (0.4.1) json (~> 1.7, >= 1.7.7) rdoc (~> 4.0) - selenium-webdriver (2.43.0) - childprocess (~> 0.5) - multi_json (~> 1.0) - rubyzip (~> 1.0) - websocket (~> 1.0) sexp_processor (4.6.0) slop (3.6.0) spring (1.4.4) @@ -304,9 +269,6 @@ GEM binding_of_caller (>= 0.7.2) railties (>= 4.0) sprockets-rails (>= 2.0, < 4.0) - websocket (1.2.2) - xpath (2.0.0) - nokogiri (~> 1.3) yard (0.8.7.6) PLATFORMS @@ -314,16 +276,10 @@ PLATFORMS DEPENDENCIES annotate - autodoc awesome_print bcrypt (~> 3.1.7) byebug - capybara (~> 2.4.3) coffee-rails (~> 4.1.0) - database_cleaner (~> 1.3.0) - database_rewinder - factory_girl_rails (~> 4.4.1) - faker (~> 1.4.3) grape grape-jbuilder grape-swagger @@ -333,19 +289,17 @@ DEPENDENCIES hirb-unicode jbuilder (~> 2.0) jquery-rails - json_spec + json_expressions pry-byebug pry-doc pry-rails quiet_assets rails (= 4.2.1) rails-erd - rspec-rails (~> 3.1.0) - rspec-request_describer + rspec-rails (~> 3.0.0) rubocop sass-rails (~> 5.0) sdoc (~> 0.4.0) - selenium-webdriver (~> 2.43.0) spring sqlite3 tapp From 162342099607bf2cf91ba3604a2583c67e1bf0ef Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Thu, 26 Nov 2015 19:34:35 +0900 Subject: [PATCH 011/358] :bug: --- config/application.rb | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/config/application.rb b/config/application.rb index 2790797..b41db45 100644 --- a/config/application.rb +++ b/config/application.rb @@ -15,17 +15,6 @@ class Application < Rails::Application end config.assets.precompile += ['swagger_ui.css', 'swagger_ui.js'] - #rspecの自動生成の設定 - config.generatorsdo|g| - g.test_framework :rspec, - fixtures: true, - view_specs: false, - helper_specs: false, - routing_specs: false, - controller_specs: true, - request_specs: false - g.fixture_replacement :factory_girl, dir: "spec/factories" - end # Settings in config/environments/* take precedence over those specified here. # Application configuration should go into files in config/initializers # -- all .rb files in that directory are automatically loaded. From bbc38fc36ac68e34897d030f4a344df5afb97285 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Fri, 27 Nov 2015 17:24:27 +0900 Subject: [PATCH 012/358] =?UTF-8?q?=F0=9F=9A=80update=20swagger.html.haml?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/layouts/swagger.html.haml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/views/layouts/swagger.html.haml b/app/views/layouts/swagger.html.haml index d383f6a..4cfdf3a 100644 --- a/app/views/layouts/swagger.html.haml +++ b/app/views/layouts/swagger.html.haml @@ -35,14 +35,14 @@ %body#swagger #header .swagger-ui-wrap - %a#logo{ href: "http://localhost:3000" } Shampoo + %a#logo{ href: "#{request.protocol}#{request.raw_host_with_port}" } Switch %form#api_selector .input - %input#input_baseUrl{ value: "http://localhost:3000/api/v1/swagger_doc", name: "baseUrl", type: "text" } + %input#input_baseUrl{ value: "#{request.protocol}#{request.raw_host_with_port}/api/v1/swagger_doc", name: "baseUrl", type: "text" } .input %input#input_apiKey{ placeholder: "api_key", name: "apiKey", type: "text" } .input - %a#explore{ href: "#"} Explore + %a#explore{ href: "#"} 表示する #message-bar.swagger-ui-wrap   #swagger-ui-container.swagger-ui-wrap \ No newline at end of file From 42352e022d2ba748af255bec8f50efc310ea65a6 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Fri, 27 Nov 2015 18:16:52 +0900 Subject: [PATCH 013/358] =?UTF-8?q?=F0=9F=9A=80add=20readme?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.rdoc | 32 ++++++-------------------------- 1 file changed, 6 insertions(+), 26 deletions(-) diff --git a/README.rdoc b/README.rdoc index dd4e97e..9972824 100644 --- a/README.rdoc +++ b/README.rdoc @@ -1,28 +1,8 @@ -== README +Switch API +== -This README would normally document whatever steps are necessary to get the -application up and running. +大学のプロジェクト課題で作成したAPIサーバーです。 +家電製品を動かしたいという欲望で動いてるデザイアドリブン駆動なプロジェクトです。 -Things you may want to cover: - -* Ruby version - -* System dependencies - -* Configuration - -* Database creation - -* Database initialization - -* How to run the test suite - -* Services (job queues, cache servers, search engines, etc.) - -* Deployment instructions - -* ... - - -Please feel free to use a different markup language if you do not plan to run -rake doc:app. +基本git flowの思想の元ブランチは切っていて、 +circleCIでテストを動かして通らない場合はプルリクを受け付けない方針をとっています。 From 05960a6dc4ef5179106d974eed138543922cdf7e Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Fri, 27 Nov 2015 18:21:28 +0900 Subject: [PATCH 014/358] :bug: fix --- README.rdoc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.rdoc b/README.rdoc index 9972824..f1c2c1f 100644 --- a/README.rdoc +++ b/README.rdoc @@ -1,5 +1,4 @@ -Switch API -== +== Switch API 大学のプロジェクト課題で作成したAPIサーバーです。 家電製品を動かしたいという欲望で動いてるデザイアドリブン駆動なプロジェクトです。 From e985ffd499221d888716309dc4135564c839e3f6 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Fri, 27 Nov 2015 18:35:38 +0900 Subject: [PATCH 015/358] remove spec --- spec/rails_helper.rb | 56 ----------------------------- spec/spec_helper.rb | 85 -------------------------------------------- 2 files changed, 141 deletions(-) delete mode 100644 spec/rails_helper.rb delete mode 100644 spec/spec_helper.rb diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb deleted file mode 100644 index c9c8c4a..0000000 --- a/spec/rails_helper.rb +++ /dev/null @@ -1,56 +0,0 @@ -# This file is copied to spec/ when you run 'rails generate rspec:install' -ENV["RAILS_ENV"] ||= 'test' -require 'spec_helper' -require File.expand_path("../../config/environment", __FILE__) -require 'rspec/rails' -# Add additional requires below this line. Rails is not loaded until this point! - -# Requires supporting ruby files with custom matchers and macros, etc, in -# spec/support/ and its subdirectories. Files matching `spec/**/*_spec.rb` are -# run as spec files by default. This means that files in spec/support that end -# in _spec.rb will both be required and run as specs, causing the specs to be -# run twice. It is recommended that you do not name files matching this glob to -# end with _spec.rb. You can configure this pattern with the --pattern -# option on the command line or in ~/.rspec, .rspec or `.rspec-local`. -# -# The following line is provided for convenience purposes. It has the downside -# of increasing the boot-up time by auto-requiring all files in the support -# directory. Alternatively, in the individual `*_spec.rb` files, manually -# require only the support files necessary. -# -# Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f } - -# Checks for pending migrations before tests are run. -# If you are not using ActiveRecord, you can remove this line. -ActiveRecord::Migration.maintain_test_schema! - -RSpec.configure do |config| - # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures - config.fixture_path = "#{::Rails.root}/spec/fixtures" - - # If you're not using ActiveRecord, or you'd prefer not to run each of your - # examples within a transaction, remove the following line or assign false - # instead of true. - config.use_transactional_fixtures = true - - # FactoryGirl.buildなどの呼び出しを、create, buildなどでメソッドが呼べる - config.include FactoryGirl::Syntax::Methods - - # capybaraでvisit使おうとするとエラーが出るときに、下記を書く - config.include Capybara::DSL - - # RSpec Rails can automatically mix in different behaviours to your tests - # based on their file location, for example enabling you to call `get` and - # `post` in specs under `spec/controllers`. - # - # You can disable this behaviour by removing the line below, and instead - # explicitly tag your specs with their type, e.g.: - # - # RSpec.describe UsersController, :type => :controller do - # # ... - # end - # - # The different available types are documented in the features, such as in - # https://relishapp.com/rspec/rspec-rails/docs - config.infer_spec_type_from_file_location! -end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb deleted file mode 100644 index 275ba49..0000000 --- a/spec/spec_helper.rb +++ /dev/null @@ -1,85 +0,0 @@ -# This file was generated by the `rails generate rspec:install` command. Conventionally, all -# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`. -# The generated `.rspec` file contains `--require spec_helper` which will cause this -# file to always be loaded, without a need to explicitly require it in any files. -# -# Given that it is always loaded, you are encouraged to keep this file as -# light-weight as possible. Requiring heavyweight dependencies from this file -# will add to the boot time of your test suite on EVERY test run, even for an -# individual file that may not need all of that loaded. Instead, consider making -# a separate helper file that requires the additional dependencies and performs -# the additional setup, and require it from the spec files that actually need it. -# -# The `.rspec` file also contains a few flags that are not defaults but that -# users commonly want. -# -# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration -RSpec.configure do |config| - # rspec-expectations config goes here. You can use an alternate - # assertion/expectation library such as wrong or the stdlib/minitest - # assertions if you prefer. - config.expect_with :rspec do |expectations| - # This option will default to `true` in RSpec 4. It makes the `description` - # and `failure_message` of custom matchers include text for helper methods - # defined using `chain`, e.g.: - # be_bigger_than(2).and_smaller_than(4).description - # # => "be bigger than 2 and smaller than 4" - # ...rather than: - # # => "be bigger than 2" - expectations.include_chain_clauses_in_custom_matcher_descriptions = true - end - - # rspec-mocks config goes here. You can use an alternate test double - # library (such as bogus or mocha) by changing the `mock_with` option here. - config.mock_with :rspec do |mocks| - # Prevents you from mocking or stubbing a method that does not exist on - # a real object. This is generally recommended, and will default to - # `true` in RSpec 4. - mocks.verify_partial_doubles = true - end - -# The settings below are suggested to provide a good initial experience -# with RSpec, but feel free to customize to your heart's content. -=begin - # These two settings work together to allow you to limit a spec run - # to individual examples or groups you care about by tagging them with - # `:focus` metadata. When nothing is tagged with `:focus`, all examples - # get run. - config.filter_run :focus - config.run_all_when_everything_filtered = true - - # Limits the available syntax to the non-monkey patched syntax that is recommended. - # For more details, see: - # - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax - # - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/ - # - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching - config.disable_monkey_patching! - - # Many RSpec users commonly either run the entire suite or an individual - # file, and it's useful to allow more verbose output when running an - # individual spec file. - if config.files_to_run.one? - # Use the documentation formatter for detailed output, - # unless a formatter has already been configured - # (e.g. via a command-line flag). - config.default_formatter = 'doc' - end - - # Print the 10 slowest examples and example groups at the - # end of the spec run, to help surface which specs are running - # particularly slow. - config.profile_examples = 10 - - # Run specs in random order to surface order dependencies. If you find an - # order dependency and want to debug it, you can fix the order by providing - # the seed, which is printed after each run. - # --seed 1234 - config.order = :random - - # Seed global randomization in this process using the `--seed` CLI option. - # Setting this allows you to use `--seed` to deterministically reproduce - # test failures related to randomization by passing the same `--seed` value - # as the one that triggered the failure. - Kernel.srand config.seed -=end -end From b131d951051640edcada6d247826966eee287d86 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Fri, 27 Nov 2015 18:41:19 +0900 Subject: [PATCH 016/358] rails g rspec:install --- .rspec | 2 +- spec/rails_helper.rb | 43 ++++++++++++++++++++++++ spec/spec_helper.rb | 78 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 spec/rails_helper.rb create mode 100644 spec/spec_helper.rb diff --git a/.rspec b/.rspec index 43ae203..0d786ba 100644 --- a/.rspec +++ b/.rspec @@ -1,3 +1,3 @@ --color +--warnings --require spec_helper ---format documentation diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb new file mode 100644 index 0000000..4d1d439 --- /dev/null +++ b/spec/rails_helper.rb @@ -0,0 +1,43 @@ +# This file is copied to spec/ when you run 'rails generate rspec:install' +ENV["RAILS_ENV"] ||= 'test' +require 'spec_helper' +require File.expand_path("../../config/environment", __FILE__) +require 'rspec/rails' + +# Requires supporting ruby files with custom matchers and macros, etc, in +# spec/support/ and its subdirectories. Files matching `spec/**/*_spec.rb` are +# run as spec files by default. This means that files in spec/support that end +# in _spec.rb will both be required and run as specs, causing the specs to be +# run twice. It is recommended that you do not name files matching this glob to +# end with _spec.rb. You can configure this pattern with the --pattern +# option on the command line or in ~/.rspec, .rspec or `.rspec-local`. +Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f } + +# Checks for pending migrations before tests are run. +# If you are not using ActiveRecord, you can remove this line. +ActiveRecord::Migration.maintain_test_schema! + +RSpec.configure do |config| + # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures + config.fixture_path = "#{::Rails.root}/spec/fixtures" + + # If you're not using ActiveRecord, or you'd prefer not to run each of your + # examples within a transaction, remove the following line or assign false + # instead of true. + config.use_transactional_fixtures = true + + # RSpec Rails can automatically mix in different behaviours to your tests + # based on their file location, for example enabling you to call `get` and + # `post` in specs under `spec/controllers`. + # + # You can disable this behaviour by removing the line below, and instead + # explicitly tag your specs with their type, e.g.: + # + # RSpec.describe UsersController, :type => :controller do + # # ... + # end + # + # The different available types are documented in the features, such as in + # https://relishapp.com/rspec/rspec-rails/docs + config.infer_spec_type_from_file_location! +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb new file mode 100644 index 0000000..cfb18dc --- /dev/null +++ b/spec/spec_helper.rb @@ -0,0 +1,78 @@ +# This file was generated by the `rails generate rspec:install` command. Conventionally, all +# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`. +# The generated `.rspec` file contains `--require spec_helper` which will cause this +# file to always be loaded, without a need to explicitly require it in any files. +# +# Given that it is always loaded, you are encouraged to keep this file as +# light-weight as possible. Requiring heavyweight dependencies from this file +# will add to the boot time of your test suite on EVERY test run, even for an +# individual file that may not need all of that loaded. Instead, make a +# separate helper file that requires this one and then use it only in the specs +# that actually need it. +# +# The `.rspec` file also contains a few flags that are not defaults but that +# users commonly want. +# +# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration +RSpec.configure do |config| +# The settings below are suggested to provide a good initial experience +# with RSpec, but feel free to customize to your heart's content. +=begin + # These two settings work together to allow you to limit a spec run + # to individual examples or groups you care about by tagging them with + # `:focus` metadata. When nothing is tagged with `:focus`, all examples + # get run. + config.filter_run :focus + config.run_all_when_everything_filtered = true + + # Many RSpec users commonly either run the entire suite or an individual + # file, and it's useful to allow more verbose output when running an + # individual spec file. + if config.files_to_run.one? + # Use the documentation formatter for detailed output, + # unless a formatter has already been configured + # (e.g. via a command-line flag). + config.default_formatter = 'doc' + end + + # Print the 10 slowest examples and example groups at the + # end of the spec run, to help surface which specs are running + # particularly slow. + config.profile_examples = 10 + + # Run specs in random order to surface order dependencies. If you find an + # order dependency and want to debug it, you can fix the order by providing + # the seed, which is printed after each run. + # --seed 1234 + config.order = :random + + # Seed global randomization in this process using the `--seed` CLI option. + # Setting this allows you to use `--seed` to deterministically reproduce + # test failures related to randomization by passing the same `--seed` value + # as the one that triggered the failure. + Kernel.srand config.seed + + # rspec-expectations config goes here. You can use an alternate + # assertion/expectation library such as wrong or the stdlib/minitest + # assertions if you prefer. + config.expect_with :rspec do |expectations| + # Enable only the newer, non-monkey-patching expect syntax. + # For more details, see: + # - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax + expectations.syntax = :expect + end + + # rspec-mocks config goes here. You can use an alternate test double + # library (such as bogus or mocha) by changing the `mock_with` option here. + config.mock_with :rspec do |mocks| + # Enable only the newer, non-monkey-patching expect syntax. + # For more details, see: + # - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/ + mocks.syntax = :expect + + # Prevents you from mocking or stubbing a method that does not exist on + # a real object. This is generally recommended. + mocks.verify_partial_doubles = true + end +=end +end From 00abcfa83f14042f2106e96cb9bcebe73981d7a6 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Fri, 27 Nov 2015 18:56:45 +0900 Subject: [PATCH 017/358] write a test spec --- spec/requests/test_spec.rb | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 spec/requests/test_spec.rb diff --git a/spec/requests/test_spec.rb b/spec/requests/test_spec.rb new file mode 100644 index 0000000..14d184c --- /dev/null +++ b/spec/requests/test_spec.rb @@ -0,0 +1,8 @@ +require "rails_helper" + +describe "mathmatics" do + example "1 + 1" do + get "/api/v1/users/hello" + expect(1 + 1).to eq 2 + end +end From b5870f9800a4afcfdc1159cf5fffd574915676a1 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Fri, 27 Nov 2015 18:58:17 +0900 Subject: [PATCH 018/358] make silent --- .rspec | 1 - 1 file changed, 1 deletion(-) diff --git a/.rspec b/.rspec index 0d786ba..83e16f8 100644 --- a/.rspec +++ b/.rspec @@ -1,3 +1,2 @@ --color ---warnings --require spec_helper From 2ff571025797c67b28b5d15b75ebc25fc5c39217 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Fri, 27 Nov 2015 19:10:13 +0900 Subject: [PATCH 019/358] fix warning --- Gemfile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Gemfile b/Gemfile index d497b16..22d171d 100644 --- a/Gemfile +++ b/Gemfile @@ -37,14 +37,13 @@ gem 'grape-jbuilder' gem 'grape-swagger' gem 'grape-swagger-ui' gem 'haml-rails' - +gem 'rubocop', group: :development group :development, :test do gem 'byebug' gem 'web-console', '~> 2.0' gem 'spring' - gem 'rubocop' gem 'rails-erd' gem 'pry-rails' gem 'pry-doc' From a2580a4a2a80244a3ab13ee709e575f27dc16f94 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Fri, 27 Nov 2015 19:39:04 +0900 Subject: [PATCH 020/358] mkdir requests/api/v1/ --- spec/requests/{ => api/v1}/test_spec.rb | 1 + 1 file changed, 1 insertion(+) rename spec/requests/{ => api/v1}/test_spec.rb (89%) diff --git a/spec/requests/test_spec.rb b/spec/requests/api/v1/test_spec.rb similarity index 89% rename from spec/requests/test_spec.rb rename to spec/requests/api/v1/test_spec.rb index 14d184c..f437d9d 100644 --- a/spec/requests/test_spec.rb +++ b/spec/requests/api/v1/test_spec.rb @@ -3,6 +3,7 @@ describe "mathmatics" do example "1 + 1" do get "/api/v1/users/hello" + binding.pry expect(1 + 1).to eq 2 end end From f27bf974efea7e1dac7aa5dd45db6ffa94123083 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Fri, 27 Nov 2015 19:53:17 +0900 Subject: [PATCH 021/358] :bug: fix directory name --- app/views/apis/api/v1/{authorize => auth}/signup.jbuilder | 0 app/views/apis/api/v1/{authorize => auth}/token.jbuilder | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename app/views/apis/api/v1/{authorize => auth}/signup.jbuilder (100%) rename app/views/apis/api/v1/{authorize => auth}/token.jbuilder (100%) diff --git a/app/views/apis/api/v1/authorize/signup.jbuilder b/app/views/apis/api/v1/auth/signup.jbuilder similarity index 100% rename from app/views/apis/api/v1/authorize/signup.jbuilder rename to app/views/apis/api/v1/auth/signup.jbuilder diff --git a/app/views/apis/api/v1/authorize/token.jbuilder b/app/views/apis/api/v1/auth/token.jbuilder similarity index 100% rename from app/views/apis/api/v1/authorize/token.jbuilder rename to app/views/apis/api/v1/auth/token.jbuilder From ddd85feb9a6f02df84cbaa78d4e8dcaf49d6b2a0 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Fri, 27 Nov 2015 19:53:25 +0900 Subject: [PATCH 022/358] remove test spec --- spec/requests/api/v1/test_spec.rb | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 spec/requests/api/v1/test_spec.rb diff --git a/spec/requests/api/v1/test_spec.rb b/spec/requests/api/v1/test_spec.rb deleted file mode 100644 index f437d9d..0000000 --- a/spec/requests/api/v1/test_spec.rb +++ /dev/null @@ -1,9 +0,0 @@ -require "rails_helper" - -describe "mathmatics" do - example "1 + 1" do - get "/api/v1/users/hello" - binding.pry - expect(1 + 1).to eq 2 - end -end From 730633d422f00f212610b2910d4916137cf192a4 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Fri, 27 Nov 2015 19:53:36 +0900 Subject: [PATCH 023/358] check response code --- spec/requests/api/v1/authorize_spec.rb | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 spec/requests/api/v1/authorize_spec.rb diff --git a/spec/requests/api/v1/authorize_spec.rb b/spec/requests/api/v1/authorize_spec.rb new file mode 100644 index 0000000..8103169 --- /dev/null +++ b/spec/requests/api/v1/authorize_spec.rb @@ -0,0 +1,12 @@ +require "rails_helper" + +describe "Authorize" do + describe "GET /api/v1/auth/token"do + before(:all) do + get "/api/v1/auth/token" + end + it 'return 200 status' do + expect(response.status).to be 200 + end + end +end From af3c2e10aede48e98950e97651955bc59d81a740 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Fri, 27 Nov 2015 20:11:50 +0900 Subject: [PATCH 024/358] update return jbuilder --- app/views/apis/api/v1/auth/token.jbuilder | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/app/views/apis/api/v1/auth/token.jbuilder b/app/views/apis/api/v1/auth/token.jbuilder index c978e8d..e9d5e0d 100644 --- a/app/views/apis/api/v1/auth/token.jbuilder +++ b/app/views/apis/api/v1/auth/token.jbuilder @@ -1 +1,8 @@ -json.auth_token @token +json.meta do + json.code 200 + json.message "トークンを作成しました。" +end +json.response do + json.auth_token @token +end + From c976fe5dce5af390f317e99f1379447ea2ff33f7 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Fri, 27 Nov 2015 20:30:24 +0900 Subject: [PATCH 025/358] =?UTF-8?q?test=20=E6=9B=B8=E3=81=84=E3=81=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- spec/requests/api/v1/authorize_spec.rb | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/spec/requests/api/v1/authorize_spec.rb b/spec/requests/api/v1/authorize_spec.rb index 8103169..8a74dc9 100644 --- a/spec/requests/api/v1/authorize_spec.rb +++ b/spec/requests/api/v1/authorize_spec.rb @@ -4,9 +4,16 @@ describe "GET /api/v1/auth/token"do before(:all) do get "/api/v1/auth/token" + @json = JSON.parse(response.body) end it 'return 200 status' do expect(response.status).to be 200 end + it 'meta code is same status' do + expect(@json["meta"]["code"]).to be 200 + end + it 'response is not nil' do + expect(@json["response"]).not_to be_empty + end end end From d1a5771b56d3b95b90cd91885e948bff58d27e1d Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sat, 28 Nov 2015 01:25:11 +0900 Subject: [PATCH 026/358] update spec test --- spec/requests/api/v1/authorize_spec.rb | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/spec/requests/api/v1/authorize_spec.rb b/spec/requests/api/v1/authorize_spec.rb index 8a74dc9..6d498d5 100644 --- a/spec/requests/api/v1/authorize_spec.rb +++ b/spec/requests/api/v1/authorize_spec.rb @@ -15,5 +15,13 @@ it 'response is not nil' do expect(@json["response"]).not_to be_empty end + + it 'correct data type' do + expect(String === @json["response"]["auth_token"]).to be true + end + + it 'correct token size' do + expect(@json["response"]["auth_token"].size).to eq 22 + end end end From e516c67c4efdf7910e84f62d2ec26c345d4cc65c Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sat, 28 Nov 2015 02:47:46 +0900 Subject: [PATCH 027/358] bundle install factory_girl_rails --- Gemfile | 2 ++ Gemfile.lock | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/Gemfile b/Gemfile index 22d171d..2cedf17 100644 --- a/Gemfile +++ b/Gemfile @@ -38,6 +38,7 @@ gem 'grape-swagger' gem 'grape-swagger-ui' gem 'haml-rails' gem 'rubocop', group: :development + group :development, :test do gem 'byebug' @@ -56,5 +57,6 @@ group :development, :test do gem 'annotate' gem 'json_expressions' gem 'rspec-rails', '~> 3.0.0' + gem 'factory_girl_rails' end diff --git a/Gemfile.lock b/Gemfile.lock index b947311..9f62d8a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -71,6 +71,11 @@ GEM equalizer (0.0.11) erubis (2.7.0) execjs (2.6.0) + factory_girl (4.5.0) + activesupport (>= 3.0.0) + factory_girl_rails (4.5.0) + factory_girl (~> 4.5.0) + railties (>= 3.0.0) globalid (0.3.6) activesupport (>= 4.1.0) grape (0.13.0) @@ -280,6 +285,7 @@ DEPENDENCIES bcrypt (~> 3.1.7) byebug coffee-rails (~> 4.1.0) + factory_girl_rails grape grape-jbuilder grape-swagger From 3236a372477e15a2cd1e96c32dd1dea3500ab692 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sat, 28 Nov 2015 02:48:49 +0900 Subject: [PATCH 028/358] add a factory to spec_helper --- spec/spec_helper.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index cfb18dc..1647387 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -15,6 +15,7 @@ # # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration RSpec.configure do |config| + config.include FactoryGirl::Syntax::Methods # The settings below are suggested to provide a good initial experience # with RSpec, but feel free to customize to your heart's content. =begin From f9361d95237aed7200cddd20dcb367c42232cdf2 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sat, 28 Nov 2015 22:09:50 +0900 Subject: [PATCH 029/358] create factory base --- spec/factories/auth_tokens.rb | 0 spec/factories/user_infos.rb | 0 spec/factories/users.rb | 5 +++++ 3 files changed, 5 insertions(+) create mode 100644 spec/factories/auth_tokens.rb create mode 100644 spec/factories/user_infos.rb create mode 100644 spec/factories/users.rb diff --git a/spec/factories/auth_tokens.rb b/spec/factories/auth_tokens.rb new file mode 100644 index 0000000..e69de29 diff --git a/spec/factories/user_infos.rb b/spec/factories/user_infos.rb new file mode 100644 index 0000000..e69de29 diff --git a/spec/factories/users.rb b/spec/factories/users.rb new file mode 100644 index 0000000..1eaa395 --- /dev/null +++ b/spec/factories/users.rb @@ -0,0 +1,5 @@ +FactoryGirl.define do + factory :user do + + end +end \ No newline at end of file From 018c98826f087e408e6c5326870e5f454d2699bc Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sat, 28 Nov 2015 22:45:40 +0900 Subject: [PATCH 030/358] =?UTF-8?q?Factory=E3=82=92=E4=B8=80=E3=81=A4?= =?UTF-8?q?=E3=81=AB=E3=81=BE=E3=81=A8=E3=82=81=E3=81=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- spec/factories/auth_tokens.rb | 0 spec/factories/{users.rb => factory.rb} | 1 - spec/factories/user_infos.rb | 0 3 files changed, 1 deletion(-) delete mode 100644 spec/factories/auth_tokens.rb rename spec/factories/{users.rb => factory.rb} (98%) delete mode 100644 spec/factories/user_infos.rb diff --git a/spec/factories/auth_tokens.rb b/spec/factories/auth_tokens.rb deleted file mode 100644 index e69de29..0000000 diff --git a/spec/factories/users.rb b/spec/factories/factory.rb similarity index 98% rename from spec/factories/users.rb rename to spec/factories/factory.rb index 1eaa395..2aad321 100644 --- a/spec/factories/users.rb +++ b/spec/factories/factory.rb @@ -1,5 +1,4 @@ FactoryGirl.define do factory :user do - end end \ No newline at end of file diff --git a/spec/factories/user_infos.rb b/spec/factories/user_infos.rb deleted file mode 100644 index e69de29..0000000 From 4192ca80ccc17e89a4b50d70db22eed1ff2be791 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sat, 28 Nov 2015 22:45:59 +0900 Subject: [PATCH 031/358] :bug: missed import factory setting --- spec/rails_helper.rb | 2 ++ spec/spec_helper.rb | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 4d1d439..6cda2fb 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -26,6 +26,8 @@ # instead of true. config.use_transactional_fixtures = true + config.include FactoryGirl::Syntax::Methods + # RSpec Rails can automatically mix in different behaviours to your tests # based on their file location, for example enabling you to call `get` and # `post` in specs under `spec/controllers`. diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 1647387..cfb18dc 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -15,7 +15,6 @@ # # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration RSpec.configure do |config| - config.include FactoryGirl::Syntax::Methods # The settings below are suggested to provide a good initial experience # with RSpec, but feel free to customize to your heart's content. =begin From 6ed3175980d3be4896e2f699b3c2db755ecb361b Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sat, 28 Nov 2015 22:46:05 +0900 Subject: [PATCH 032/358] add test --- spec/requests/api/v1/authorize_spec.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/spec/requests/api/v1/authorize_spec.rb b/spec/requests/api/v1/authorize_spec.rb index 6d498d5..71d2d02 100644 --- a/spec/requests/api/v1/authorize_spec.rb +++ b/spec/requests/api/v1/authorize_spec.rb @@ -23,5 +23,9 @@ it 'correct token size' do expect(@json["response"]["auth_token"].size).to eq 22 end + + it 'include correct word' do + expect(@json["meta"]["message"]).to include("を作成しました") + end end end From c7ae3882035898d9ff167eed7e21ac904e936402 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sat, 28 Nov 2015 23:46:24 +0900 Subject: [PATCH 033/358] :construction: spec test --- spec/factories/factory.rb | 5 +++++ spec/requests/api/v1/authorize_spec.rb | 12 +++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/spec/factories/factory.rb b/spec/factories/factory.rb index 2aad321..d796c38 100644 --- a/spec/factories/factory.rb +++ b/spec/factories/factory.rb @@ -1,4 +1,9 @@ FactoryGirl.define do factory :user do + + end + factory :auth_token do + user + token "hoehoge" end end \ No newline at end of file diff --git a/spec/requests/api/v1/authorize_spec.rb b/spec/requests/api/v1/authorize_spec.rb index 71d2d02..c8b5cf7 100644 --- a/spec/requests/api/v1/authorize_spec.rb +++ b/spec/requests/api/v1/authorize_spec.rb @@ -1,7 +1,7 @@ require "rails_helper" describe "Authorize" do - describe "GET /api/v1/auth/token"do + describe "GET /api/v1/auth/token" do before(:all) do get "/api/v1/auth/token" @json = JSON.parse(response.body) @@ -28,4 +28,14 @@ expect(@json["meta"]["message"]).to include("を作成しました") end end + + describe "POST /api/v1/auth/signup" do + before(:all) do + user = create(:user) + binding.pry + end + it 'test' do + expect(1+1).to be 2 + end + end end From d6d18443ad602697f62b169a4425720ce61219fa Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 29 Nov 2015 12:52:48 +0900 Subject: [PATCH 034/358] :construction: receive correct post response --- spec/factories/factory.rb | 7 +++++++ spec/requests/api/v1/authorize_spec.rb | 6 +++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/spec/factories/factory.rb b/spec/factories/factory.rb index d796c38..23cfd81 100644 --- a/spec/factories/factory.rb +++ b/spec/factories/factory.rb @@ -6,4 +6,11 @@ user token "hoehoge" end + factory :user_info do + user + name "random" + email "random@gmail.com" + screen_name "random" + password "random" + end end \ No newline at end of file diff --git a/spec/requests/api/v1/authorize_spec.rb b/spec/requests/api/v1/authorize_spec.rb index c8b5cf7..e91d5f9 100644 --- a/spec/requests/api/v1/authorize_spec.rb +++ b/spec/requests/api/v1/authorize_spec.rb @@ -31,7 +31,11 @@ describe "POST /api/v1/auth/signup" do before(:all) do - user = create(:user) + token = create(:auth_token) + user = token.user + attributes = attributes_for(:user_info) + attributes.store(:auth_token, token.token) + post "/api/v1/auth/signup", attributes binding.pry end it 'test' do From e7440eaffea6c41e18d6a7420740c0a10478ebaf Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 29 Nov 2015 13:05:58 +0900 Subject: [PATCH 035/358] :bug: --- spec/requests/api/v1/authorize_spec.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/spec/requests/api/v1/authorize_spec.rb b/spec/requests/api/v1/authorize_spec.rb index e91d5f9..cebbd2f 100644 --- a/spec/requests/api/v1/authorize_spec.rb +++ b/spec/requests/api/v1/authorize_spec.rb @@ -36,7 +36,6 @@ attributes = attributes_for(:user_info) attributes.store(:auth_token, token.token) post "/api/v1/auth/signup", attributes - binding.pry end it 'test' do expect(1+1).to be 2 From 8bfbaa5895f6f31ce1d579f538f24391beb470a8 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 29 Nov 2015 13:28:31 +0900 Subject: [PATCH 036/358] bundle install faker --- Gemfile | 1 + Gemfile.lock | 3 +++ 2 files changed, 4 insertions(+) diff --git a/Gemfile b/Gemfile index 2cedf17..b579b88 100644 --- a/Gemfile +++ b/Gemfile @@ -58,5 +58,6 @@ group :development, :test do gem 'json_expressions' gem 'rspec-rails', '~> 3.0.0' gem 'factory_girl_rails' + gem 'faker' end diff --git a/Gemfile.lock b/Gemfile.lock index 9f62d8a..10c9f50 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -76,6 +76,8 @@ GEM factory_girl_rails (4.5.0) factory_girl (~> 4.5.0) railties (>= 3.0.0) + faker (1.4.3) + i18n (~> 0.5) globalid (0.3.6) activesupport (>= 4.1.0) grape (0.13.0) @@ -286,6 +288,7 @@ DEPENDENCIES byebug coffee-rails (~> 4.1.0) factory_girl_rails + faker grape grape-jbuilder grape-swagger From 73678c77f66b84a4b13113d8b3e3339d1f4c0f82 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 29 Nov 2015 13:51:49 +0900 Subject: [PATCH 037/358] add sequence --- spec/factories/factory.rb | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/spec/factories/factory.rb b/spec/factories/factory.rb index 23cfd81..3dacb74 100644 --- a/spec/factories/factory.rb +++ b/spec/factories/factory.rb @@ -1,16 +1,7 @@ +require 'faker' FactoryGirl.define do - factory :user do - - end - factory :auth_token do - user - token "hoehoge" - end - factory :user_info do - user - name "random" - email "random@gmail.com" - screen_name "random" - password "random" - end + sequence(:screen_name){ Faker::Name.first_name } + sequence(:email){ Faker::Internet.email } + sequence(:password){ Faker::Internet.password } + sequence(:auth_token){ SecureRandom.urlsafe_base64 } end \ No newline at end of file From 4a679bf916a2471bd98859fc71e2cbf904738e7b Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 29 Nov 2015 13:52:04 +0900 Subject: [PATCH 038/358] separate spec files --- spec/factories/auth_token.rb | 6 ++++++ spec/factories/user.rb | 4 ++++ spec/factories/user_info.rb | 8 ++++++++ 3 files changed, 18 insertions(+) create mode 100644 spec/factories/auth_token.rb create mode 100644 spec/factories/user.rb create mode 100644 spec/factories/user_info.rb diff --git a/spec/factories/auth_token.rb b/spec/factories/auth_token.rb new file mode 100644 index 0000000..ec83526 --- /dev/null +++ b/spec/factories/auth_token.rb @@ -0,0 +1,6 @@ +FactoryGirl.define do + factory :auth_token do + user + token {generate :auth_token} + end +end \ No newline at end of file diff --git a/spec/factories/user.rb b/spec/factories/user.rb new file mode 100644 index 0000000..2aad321 --- /dev/null +++ b/spec/factories/user.rb @@ -0,0 +1,4 @@ +FactoryGirl.define do + factory :user do + end +end \ No newline at end of file diff --git a/spec/factories/user_info.rb b/spec/factories/user_info.rb new file mode 100644 index 0000000..3ce96d4 --- /dev/null +++ b/spec/factories/user_info.rb @@ -0,0 +1,8 @@ +FactoryGirl.define do + factory :user_info do + user + email {generate :email} + screen_name {generate :screen_name} + password {generate :password} + end +end \ No newline at end of file From f2fa78ba192cd13698cf47a35d389197191d9498 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 29 Nov 2015 14:03:07 +0900 Subject: [PATCH 039/358] rubocop -a --- Gemfile | 1 - app/apis/api/base.rb | 16 +-- app/apis/api/v1/users.rb | 33 +++--- app/views/apis/api/v1/auth/token.jbuilder | 3 +- app/views/apis/api/v1/users/destroy.jbuilder | 2 +- bin/rspec | 4 +- spec/factories/auth_token.rb | 4 +- spec/factories/factory.rb | 10 +- spec/factories/user.rb | 2 +- spec/factories/user_info.rb | 8 +- spec/rails_helper.rb | 6 +- spec/requests/api/v1/authorize_spec.rb | 24 ++-- spec/spec_helper.rb | 118 +++++++++---------- 13 files changed, 113 insertions(+), 118 deletions(-) diff --git a/Gemfile b/Gemfile index b579b88..e519d56 100644 --- a/Gemfile +++ b/Gemfile @@ -60,4 +60,3 @@ group :development, :test do gem 'factory_girl_rails' gem 'faker' end - diff --git a/app/apis/api/base.rb b/app/apis/api/base.rb index cf29158..239089f 100644 --- a/app/apis/api/base.rb +++ b/app/apis/api/base.rb @@ -26,15 +26,15 @@ def check_password(user_info, raw_password) if BCrypt::Password.new(user_info.hashed_password) == raw_password true else - error!(json:{ - errors:[ - { - message: 'errors.messages.invalid_pin', - code: ErrorCodes::INVALID_PIN - } - ] + error!(json: { + errors: [ + { + message: 'errors.messages.invalid_pin', + code: ErrorCodes::INVALID_PIN + } + ] }, status: 400 - ) + ) false end end diff --git a/app/apis/api/v1/users.rb b/app/apis/api/v1/users.rb index f9d8b39..239b4c1 100644 --- a/app/apis/api/v1/users.rb +++ b/app/apis/api/v1/users.rb @@ -29,7 +29,6 @@ def set_message_board params :token do requires :auth_token, type: String, desc: 'auth_token' end - end resource :users do desc '確認用のテストAPI', notes: <<-NOTE @@ -65,15 +64,15 @@ def set_message_board end delete '/', jbuilder: 'api/v1/users/destroy' do unless token = AuthToken.find_by(token: params[:auth_token]) - error!( json:{ - errors: [ - { + error!(json: { + errors: [ + { message: 'errors.messages.cant_find_token', code: ErrorCodes::INVALID_TOKEN - } - ] - }, status: 400 - ) + } + ] + }, status: 400 + ) false end @@ -84,15 +83,15 @@ def set_message_board @message = '退会しました。' end else - error!( json:{ - errors: [ - { - message: 'errors.messages.need_a_password', - code: ErrorCodes::NEED_A_PASSWORD - } - ] - }, status: 400 - ) + error!(json: { + errors: [ + { + message: 'errors.messages.need_a_password', + code: ErrorCodes::NEED_A_PASSWORD + } + ] + }, status: 400 + ) false end else diff --git a/app/views/apis/api/v1/auth/token.jbuilder b/app/views/apis/api/v1/auth/token.jbuilder index e9d5e0d..518f6a1 100644 --- a/app/views/apis/api/v1/auth/token.jbuilder +++ b/app/views/apis/api/v1/auth/token.jbuilder @@ -1,8 +1,7 @@ json.meta do json.code 200 - json.message "トークンを作成しました。" + json.message 'トークンを作成しました。' end json.response do json.auth_token @token end - diff --git a/app/views/apis/api/v1/users/destroy.jbuilder b/app/views/apis/api/v1/users/destroy.jbuilder index 21cb0d3..747317e 100644 --- a/app/views/apis/api/v1/users/destroy.jbuilder +++ b/app/views/apis/api/v1/users/destroy.jbuilder @@ -1 +1 @@ -json.message @message \ No newline at end of file +json.message @message diff --git a/bin/rspec b/bin/rspec index 0c86b5c..8bc8461 100755 --- a/bin/rspec +++ b/bin/rspec @@ -7,8 +7,8 @@ # require 'pathname' -ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", - Pathname.new(__FILE__).realpath) +ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', + Pathname.new(__FILE__).realpath) require 'rubygems' require 'bundler/setup' diff --git a/spec/factories/auth_token.rb b/spec/factories/auth_token.rb index ec83526..acd4b0d 100644 --- a/spec/factories/auth_token.rb +++ b/spec/factories/auth_token.rb @@ -1,6 +1,6 @@ FactoryGirl.define do factory :auth_token do user - token {generate :auth_token} + token { generate :auth_token } end -end \ No newline at end of file +end diff --git a/spec/factories/factory.rb b/spec/factories/factory.rb index 3dacb74..9296c2c 100644 --- a/spec/factories/factory.rb +++ b/spec/factories/factory.rb @@ -1,7 +1,7 @@ require 'faker' FactoryGirl.define do - sequence(:screen_name){ Faker::Name.first_name } - sequence(:email){ Faker::Internet.email } - sequence(:password){ Faker::Internet.password } - sequence(:auth_token){ SecureRandom.urlsafe_base64 } -end \ No newline at end of file + sequence(:screen_name) { Faker::Name.first_name } + sequence(:email) { Faker::Internet.email } + sequence(:password) { Faker::Internet.password } + sequence(:auth_token) { SecureRandom.urlsafe_base64 } +end diff --git a/spec/factories/user.rb b/spec/factories/user.rb index 2aad321..c81bd3a 100644 --- a/spec/factories/user.rb +++ b/spec/factories/user.rb @@ -1,4 +1,4 @@ FactoryGirl.define do factory :user do end -end \ No newline at end of file +end diff --git a/spec/factories/user_info.rb b/spec/factories/user_info.rb index 3ce96d4..c9e4134 100644 --- a/spec/factories/user_info.rb +++ b/spec/factories/user_info.rb @@ -1,8 +1,8 @@ FactoryGirl.define do factory :user_info do user - email {generate :email} - screen_name {generate :screen_name} - password {generate :password} + email { generate :email } + screen_name { generate :screen_name } + password { generate :password } end -end \ No newline at end of file +end diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 6cda2fb..addee83 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -1,7 +1,7 @@ # This file is copied to spec/ when you run 'rails generate rspec:install' -ENV["RAILS_ENV"] ||= 'test' +ENV['RAILS_ENV'] ||= 'test' require 'spec_helper' -require File.expand_path("../../config/environment", __FILE__) +require File.expand_path('../../config/environment', __FILE__) require 'rspec/rails' # Requires supporting ruby files with custom matchers and macros, etc, in @@ -11,7 +11,7 @@ # run twice. It is recommended that you do not name files matching this glob to # end with _spec.rb. You can configure this pattern with the --pattern # option on the command line or in ~/.rspec, .rspec or `.rspec-local`. -Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f } +Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f } # Checks for pending migrations before tests are run. # If you are not using ActiveRecord, you can remove this line. diff --git a/spec/requests/api/v1/authorize_spec.rb b/spec/requests/api/v1/authorize_spec.rb index cebbd2f..43da24c 100644 --- a/spec/requests/api/v1/authorize_spec.rb +++ b/spec/requests/api/v1/authorize_spec.rb @@ -1,44 +1,44 @@ -require "rails_helper" +require 'rails_helper' -describe "Authorize" do - describe "GET /api/v1/auth/token" do +describe 'Authorize' do + describe 'GET /api/v1/auth/token' do before(:all) do - get "/api/v1/auth/token" + get '/api/v1/auth/token' @json = JSON.parse(response.body) end it 'return 200 status' do expect(response.status).to be 200 end it 'meta code is same status' do - expect(@json["meta"]["code"]).to be 200 + expect(@json['meta']['code']).to be 200 end it 'response is not nil' do - expect(@json["response"]).not_to be_empty + expect(@json['response']).not_to be_empty end it 'correct data type' do - expect(String === @json["response"]["auth_token"]).to be true + expect(String === @json['response']['auth_token']).to be true end it 'correct token size' do - expect(@json["response"]["auth_token"].size).to eq 22 + expect(@json['response']['auth_token'].size).to eq 22 end it 'include correct word' do - expect(@json["meta"]["message"]).to include("を作成しました") + expect(@json['meta']['message']).to include('を作成しました') end end - describe "POST /api/v1/auth/signup" do + describe 'POST /api/v1/auth/signup' do before(:all) do token = create(:auth_token) user = token.user attributes = attributes_for(:user_info) attributes.store(:auth_token, token.token) - post "/api/v1/auth/signup", attributes + post '/api/v1/auth/signup', attributes end it 'test' do - expect(1+1).to be 2 + expect(1 + 1).to be 2 end end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index cfb18dc..6ca893a 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -15,64 +15,62 @@ # # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration RSpec.configure do |config| -# The settings below are suggested to provide a good initial experience -# with RSpec, but feel free to customize to your heart's content. -=begin - # These two settings work together to allow you to limit a spec run - # to individual examples or groups you care about by tagging them with - # `:focus` metadata. When nothing is tagged with `:focus`, all examples - # get run. - config.filter_run :focus - config.run_all_when_everything_filtered = true - - # Many RSpec users commonly either run the entire suite or an individual - # file, and it's useful to allow more verbose output when running an - # individual spec file. - if config.files_to_run.one? - # Use the documentation formatter for detailed output, - # unless a formatter has already been configured - # (e.g. via a command-line flag). - config.default_formatter = 'doc' - end - - # Print the 10 slowest examples and example groups at the - # end of the spec run, to help surface which specs are running - # particularly slow. - config.profile_examples = 10 - - # Run specs in random order to surface order dependencies. If you find an - # order dependency and want to debug it, you can fix the order by providing - # the seed, which is printed after each run. - # --seed 1234 - config.order = :random - - # Seed global randomization in this process using the `--seed` CLI option. - # Setting this allows you to use `--seed` to deterministically reproduce - # test failures related to randomization by passing the same `--seed` value - # as the one that triggered the failure. - Kernel.srand config.seed - - # rspec-expectations config goes here. You can use an alternate - # assertion/expectation library such as wrong or the stdlib/minitest - # assertions if you prefer. - config.expect_with :rspec do |expectations| - # Enable only the newer, non-monkey-patching expect syntax. - # For more details, see: - # - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax - expectations.syntax = :expect - end - - # rspec-mocks config goes here. You can use an alternate test double - # library (such as bogus or mocha) by changing the `mock_with` option here. - config.mock_with :rspec do |mocks| - # Enable only the newer, non-monkey-patching expect syntax. - # For more details, see: - # - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/ - mocks.syntax = :expect - - # Prevents you from mocking or stubbing a method that does not exist on - # a real object. This is generally recommended. - mocks.verify_partial_doubles = true - end -=end + # The settings below are suggested to provide a good initial experience + # with RSpec, but feel free to customize to your heart's content. + # # These two settings work together to allow you to limit a spec run + # # to individual examples or groups you care about by tagging them with + # # `:focus` metadata. When nothing is tagged with `:focus`, all examples + # # get run. + # config.filter_run :focus + # config.run_all_when_everything_filtered = true + # + # # Many RSpec users commonly either run the entire suite or an individual + # # file, and it's useful to allow more verbose output when running an + # # individual spec file. + # if config.files_to_run.one? + # # Use the documentation formatter for detailed output, + # # unless a formatter has already been configured + # # (e.g. via a command-line flag). + # config.default_formatter = 'doc' + # end + # + # # Print the 10 slowest examples and example groups at the + # # end of the spec run, to help surface which specs are running + # # particularly slow. + # config.profile_examples = 10 + # + # # Run specs in random order to surface order dependencies. If you find an + # # order dependency and want to debug it, you can fix the order by providing + # # the seed, which is printed after each run. + # # --seed 1234 + # config.order = :random + # + # # Seed global randomization in this process using the `--seed` CLI option. + # # Setting this allows you to use `--seed` to deterministically reproduce + # # test failures related to randomization by passing the same `--seed` value + # # as the one that triggered the failure. + # Kernel.srand config.seed + # + # # rspec-expectations config goes here. You can use an alternate + # # assertion/expectation library such as wrong or the stdlib/minitest + # # assertions if you prefer. + # config.expect_with :rspec do |expectations| + # # Enable only the newer, non-monkey-patching expect syntax. + # # For more details, see: + # # - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax + # expectations.syntax = :expect + # end + # + # # rspec-mocks config goes here. You can use an alternate test double + # # library (such as bogus or mocha) by changing the `mock_with` option here. + # config.mock_with :rspec do |mocks| + # # Enable only the newer, non-monkey-patching expect syntax. + # # For more details, see: + # # - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/ + # mocks.syntax = :expect + # + # # Prevents you from mocking or stubbing a method that does not exist on + # # a real object. This is generally recommended. + # mocks.verify_partial_doubles = true + # end end From e5e42b0419a12d832d5cfb3143cc94bd2b6c093b Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 29 Nov 2015 15:27:17 +0900 Subject: [PATCH 040/358] =?UTF-8?q?=F0=9F=92=84refactor=20factory?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- spec/factories/user.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/spec/factories/user.rb b/spec/factories/user.rb index c81bd3a..d26df2c 100644 --- a/spec/factories/user.rb +++ b/spec/factories/user.rb @@ -1,4 +1,3 @@ FactoryGirl.define do - factory :user do - end + factory :user end From 066863866dcf7cb6c3738b22fe5e09e8e945a941 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 29 Nov 2015 16:19:01 +0900 Subject: [PATCH 041/358] bundle install database cleaner --- Gemfile | 1 + Gemfile.lock | 2 ++ 2 files changed, 3 insertions(+) diff --git a/Gemfile b/Gemfile index e519d56..1d7aeba 100644 --- a/Gemfile +++ b/Gemfile @@ -59,4 +59,5 @@ group :development, :test do gem 'rspec-rails', '~> 3.0.0' gem 'factory_girl_rails' gem 'faker' + gem 'database_cleaner' end diff --git a/Gemfile.lock b/Gemfile.lock index 10c9f50..3186672 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -64,6 +64,7 @@ GEM coffee-script-source execjs coffee-script-source (1.10.0) + database_cleaner (1.3.0) debug_inspector (0.0.2) descendants_tracker (0.0.4) thread_safe (~> 0.3, >= 0.3.1) @@ -287,6 +288,7 @@ DEPENDENCIES bcrypt (~> 3.1.7) byebug coffee-rails (~> 4.1.0) + database_cleaner factory_girl_rails faker grape From 2c2703728abc64a3a7fa894875daf952c6d222c4 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 29 Nov 2015 16:32:19 +0900 Subject: [PATCH 042/358] setting database_cleaner --- spec/requests/api/v1/authorize_spec.rb | 1 - spec/spec_helper.rb | 11 +++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/spec/requests/api/v1/authorize_spec.rb b/spec/requests/api/v1/authorize_spec.rb index 43da24c..ef65989 100644 --- a/spec/requests/api/v1/authorize_spec.rb +++ b/spec/requests/api/v1/authorize_spec.rb @@ -1,5 +1,4 @@ require 'rails_helper' - describe 'Authorize' do describe 'GET /api/v1/auth/token' do before(:all) do diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 6ca893a..638b541 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,3 +1,4 @@ +require 'database_cleaner' # This file was generated by the `rails generate rspec:install` command. Conventionally, all # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`. # The generated `.rspec` file contains `--require spec_helper` which will cause this @@ -15,6 +16,16 @@ # # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration RSpec.configure do |config| + config.before(:suite) do + DatabaseCleaner.strategy = :transaction + DatabaseCleaner.clean_with(:truncation) + end + config.before(:each) do + DatabaseCleaner.start + end + config.after(:each) do + DatabaseCleaner.clean + end # The settings below are suggested to provide a good initial experience # with RSpec, but feel free to customize to your heart's content. # # These two settings work together to allow you to limit a spec run From 4f8983f117d5b9ee76f346a1aa28e9853c5d49f5 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 29 Nov 2015 16:50:28 +0900 Subject: [PATCH 043/358] edit response json message --- app/views/apis/api/v1/auth/signup.jbuilder | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/views/apis/api/v1/auth/signup.jbuilder b/app/views/apis/api/v1/auth/signup.jbuilder index 63c1989..ce26a51 100644 --- a/app/views/apis/api/v1/auth/signup.jbuilder +++ b/app/views/apis/api/v1/auth/signup.jbuilder @@ -1 +1,7 @@ -json.greet @hoge +json.meta do + json.code 201 + json.message "#{@screen_name}を登録しました" +end +json.response do + json.auth_token @token +end From 05e6ddd038ba66d33a21043414593fd9fa3ce266 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 29 Nov 2015 16:50:40 +0900 Subject: [PATCH 044/358] update api --- app/apis/api/v1/authorize.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/apis/api/v1/authorize.rb b/app/apis/api/v1/authorize.rb index 073595b..2334c4a 100644 --- a/app/apis/api/v1/authorize.rb +++ b/app/apis/api/v1/authorize.rb @@ -47,8 +47,8 @@ class Authorize < Grape::API screen_name: params[:screen_name], password: params[:password] ) - save_object(user_info) - @hoge = token + obj = save_object(user_info) + @screen_name = obj.screen_name end end end From e09547a3a7faf67a038c2b32f4d2e4431f433d3f Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 29 Nov 2015 17:06:13 +0900 Subject: [PATCH 045/358] fix set parameter --- app/apis/api/v1/authorize.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/apis/api/v1/authorize.rb b/app/apis/api/v1/authorize.rb index 2334c4a..1abd42a 100644 --- a/app/apis/api/v1/authorize.rb +++ b/app/apis/api/v1/authorize.rb @@ -49,6 +49,7 @@ class Authorize < Grape::API ) obj = save_object(user_info) @screen_name = obj.screen_name + @token = token.token end end end From 3e998445e3be5f5cb02b8787bdfb202092966302 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 29 Nov 2015 17:06:23 +0900 Subject: [PATCH 046/358] update spec test --- spec/requests/api/v1/authorize_spec.rb | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/spec/requests/api/v1/authorize_spec.rb b/spec/requests/api/v1/authorize_spec.rb index 43da24c..d847d2b 100644 --- a/spec/requests/api/v1/authorize_spec.rb +++ b/spec/requests/api/v1/authorize_spec.rb @@ -15,15 +15,12 @@ it 'response is not nil' do expect(@json['response']).not_to be_empty end - it 'correct data type' do expect(String === @json['response']['auth_token']).to be true end - it 'correct token size' do expect(@json['response']['auth_token'].size).to eq 22 end - it 'include correct word' do expect(@json['meta']['message']).to include('を作成しました') end @@ -36,9 +33,25 @@ attributes = attributes_for(:user_info) attributes.store(:auth_token, token.token) post '/api/v1/auth/signup', attributes + @json = JSON.parse(response.body) + end + it 'return 201 status' do + expect(response.status).to be 201 end - it 'test' do - expect(1 + 1).to be 2 + it 'meta code is same status' do + expect(@json['meta']['code']).to be 201 + end + it 'response is not nil' do + expect(@json['response']).not_to be_empty + end + it 'correct data type' do + expect(String === @json['response']['auth_token']).to be true + end + it 'correct token size' do + expect(@json['response']['auth_token'].size).to eq 22 + end + it 'include correct word' do + expect(@json['meta']['message']).to include('を登録しました') end end end From af04ed2a20c3875b7a17b849856e2722457cd43e Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 29 Nov 2015 17:51:44 +0900 Subject: [PATCH 047/358] update test --- app/apis/api/v1/authorize.rb | 5 ++-- app/views/apis/api/v1/auth/signup.jbuilder | 2 +- app/views/apis/api/v1/auth/token.jbuilder | 2 +- spec/requests/api/v1/authorize_spec.rb | 27 ++++++++++++++++------ 4 files changed, 25 insertions(+), 11 deletions(-) diff --git a/app/apis/api/v1/authorize.rb b/app/apis/api/v1/authorize.rb index 1abd42a..f0679f3 100644 --- a/app/apis/api/v1/authorize.rb +++ b/app/apis/api/v1/authorize.rb @@ -35,12 +35,13 @@ class Authorize < Grape::API post '/signup', jbuilder: 'api/v1/auth/signup' do if (token = AuthToken.find_by(token: params[:auth_token])) if !user.info.nil? - error!(json: { + error!(meta: { + status: 500, errors: [ message: ('errors.messages.already_existing'), code: ErrorCodes::ALREADY_EXISTING ] - }, status: 400) + }, response:{ }) else user_info = user.build_info( email: params[:email], diff --git a/app/views/apis/api/v1/auth/signup.jbuilder b/app/views/apis/api/v1/auth/signup.jbuilder index ce26a51..f4c0209 100644 --- a/app/views/apis/api/v1/auth/signup.jbuilder +++ b/app/views/apis/api/v1/auth/signup.jbuilder @@ -1,5 +1,5 @@ json.meta do - json.code 201 + json.status 201 json.message "#{@screen_name}を登録しました" end json.response do diff --git a/app/views/apis/api/v1/auth/token.jbuilder b/app/views/apis/api/v1/auth/token.jbuilder index 518f6a1..ca33a9d 100644 --- a/app/views/apis/api/v1/auth/token.jbuilder +++ b/app/views/apis/api/v1/auth/token.jbuilder @@ -1,5 +1,5 @@ json.meta do - json.code 200 + json.status 200 json.message 'トークンを作成しました。' end json.response do diff --git a/spec/requests/api/v1/authorize_spec.rb b/spec/requests/api/v1/authorize_spec.rb index d847d2b..a320b60 100644 --- a/spec/requests/api/v1/authorize_spec.rb +++ b/spec/requests/api/v1/authorize_spec.rb @@ -1,4 +1,5 @@ require 'rails_helper' +require 'error_codes' describe 'Authorize' do describe 'GET /api/v1/auth/token' do @@ -9,8 +10,8 @@ it 'return 200 status' do expect(response.status).to be 200 end - it 'meta code is same status' do - expect(@json['meta']['code']).to be 200 + it 'meta status is same status' do + expect(@json['meta']['status']).to be 200 end it 'response is not nil' do expect(@json['response']).not_to be_empty @@ -30,16 +31,16 @@ before(:all) do token = create(:auth_token) user = token.user - attributes = attributes_for(:user_info) - attributes.store(:auth_token, token.token) - post '/api/v1/auth/signup', attributes + @attributes = attributes_for(:user_info) + @attributes.store(:auth_token, token.token) + post '/api/v1/auth/signup', @attributes @json = JSON.parse(response.body) end it 'return 201 status' do expect(response.status).to be 201 end - it 'meta code is same status' do - expect(@json['meta']['code']).to be 201 + it 'meta status is same status' do + expect(@json['meta']['status']).to be 201 end it 'response is not nil' do expect(@json['response']).not_to be_empty @@ -53,5 +54,17 @@ it 'include correct word' do expect(@json['meta']['message']).to include('を登録しました') end + describe 'already exist' do + before(:all) do + post '/api/v1/auth/signup', @attributes + @json = JSON.parse(response.body) + end + it 'return 500 status' do + expect(response.status).to be 500 + end + it 'correct code' do + expect(@json['meta']['errors'][0]["code"]).to be ErrorCodes::ALREADY_EXISTING + end + end end end From beb0bc462959f40b341489905c44bba0f77971b7 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 29 Nov 2015 18:20:34 +0900 Subject: [PATCH 048/358] fix spec error code --- app/apis/api/v1/authorize.rb | 2 +- spec/requests/api/v1/authorize_spec.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/apis/api/v1/authorize.rb b/app/apis/api/v1/authorize.rb index f0679f3..3694e98 100644 --- a/app/apis/api/v1/authorize.rb +++ b/app/apis/api/v1/authorize.rb @@ -36,7 +36,7 @@ class Authorize < Grape::API if (token = AuthToken.find_by(token: params[:auth_token])) if !user.info.nil? error!(meta: { - status: 500, + status: 400, errors: [ message: ('errors.messages.already_existing'), code: ErrorCodes::ALREADY_EXISTING diff --git a/spec/requests/api/v1/authorize_spec.rb b/spec/requests/api/v1/authorize_spec.rb index a320b60..b8df87d 100644 --- a/spec/requests/api/v1/authorize_spec.rb +++ b/spec/requests/api/v1/authorize_spec.rb @@ -60,7 +60,7 @@ @json = JSON.parse(response.body) end it 'return 500 status' do - expect(response.status).to be 500 + expect(@json['meta']['status']).to be 400 end it 'correct code' do expect(@json['meta']['errors'][0]["code"]).to be ErrorCodes::ALREADY_EXISTING From 12d4c0f6ea9e8862ec2f73d92c2abcd14478d812 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 29 Nov 2015 18:29:24 +0900 Subject: [PATCH 049/358] update base error message --- app/apis/api/base.rb | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/app/apis/api/base.rb b/app/apis/api/base.rb index 239089f..f2effe1 100644 --- a/app/apis/api/base.rb +++ b/app/apis/api/base.rb @@ -14,11 +14,10 @@ def save_object(object) code: ErrorCodes::FAIL_SAVE } end - error!(json: { - errors: errors - }, status: 400 - ) - false + error!(meta: { + status: 400, + errors: errors + }, response:{ }) end end From d843660d0d7f3d164f993ed0319c0442474d3bdf Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 29 Nov 2015 19:17:57 +0900 Subject: [PATCH 050/358] create login api --- app/apis/api/v1/authorize.rb | 53 +++++++++++++++++++++-- app/views/apis/api/v1/auth/login.jbuilder | 7 +++ 2 files changed, 57 insertions(+), 3 deletions(-) create mode 100644 app/views/apis/api/v1/auth/login.jbuilder diff --git a/app/apis/api/v1/authorize.rb b/app/apis/api/v1/authorize.rb index 3694e98..f1239be 100644 --- a/app/apis/api/v1/authorize.rb +++ b/app/apis/api/v1/authorize.rb @@ -2,13 +2,44 @@ module API module V1 class Authorize < Grape::API helpers do - params :attributes do + params :signup_params do requires :screen_name, type: String, desc: '表示名' requires :email, type: String, desc: 'メールアドレス' requires :password, type: String, desc: 'パスワード' requires :auth_token, type: String, desc: 'トークン' # optional :body, type: String, desc: "MessageBoard body." end + params :login_params do + requires :email_or_screen_name, type: String, desc: 'メールアドレスまたは名前' + requires :password, type: String, desc: 'パスワード' + end + def find_user_by_identifier(identifier) + if(user_info = UserInfo.find_by(screen_name: identifier) || UserInfo.find_by(email: identifier)) + user_info.user + else + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.user_not_found'), + code: ErrorCodes::NOT_FOUND_USER + ] + }, response:{ }) + end + end + def check_password(user_info, raw_password) + if BCrypt::Password.new(user_info.hashed_password) == raw_password + true + else + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.invalid_pin'), + code: ErrorCodes::INVALID_PIN + ] + }, response:{ }) + false + end + end end resource :auth do desc 'トークンの取得', notes: <<-NOTE @@ -23,14 +54,14 @@ class Authorize < Grape::API @token = user.auth_tokens.new_token end - desc '確認用のテストAPI', notes: <<-NOTE + desc 'User登録用API', notes: <<-NOTE

signup

User登録をします。

NOTE params do - use :attributes + use :signup_params end post '/signup', jbuilder: 'api/v1/auth/signup' do if (token = AuthToken.find_by(token: params[:auth_token])) @@ -54,6 +85,22 @@ class Authorize < Grape::API end end end + + desc 'ログイン用API', notes: <<-NOTE +

signup

+

+ emailまたはスクリーンネームを用いてログインします。
+

+ NOTE + params do + use :login_params + end + post '/login', jbuilder: 'api/v1/auth/login' do + user = find_user_by_identifier(params[:email_or_screen_name]) + if check_password(user.info, params[:password]) + @token = user.auth_tokens.new_token + end + end end end end diff --git a/app/views/apis/api/v1/auth/login.jbuilder b/app/views/apis/api/v1/auth/login.jbuilder new file mode 100644 index 0000000..ec4cb6b --- /dev/null +++ b/app/views/apis/api/v1/auth/login.jbuilder @@ -0,0 +1,7 @@ +json.meta do + json.status 201 + json.message "ログインに成功しました" +end +json.response do + json.auth_token @token +end From 722643e40198b261e5453af9bb5eaad22d23bb74 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 29 Nov 2015 19:30:48 +0900 Subject: [PATCH 051/358] rubocop -a --- app/apis/api/base.rb | 6 ++--- app/apis/api/v1/authorize.rb | 29 ++++++++++++----------- app/views/apis/api/v1/auth/login.jbuilder | 2 +- 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/app/apis/api/base.rb b/app/apis/api/base.rb index f2effe1..f290941 100644 --- a/app/apis/api/base.rb +++ b/app/apis/api/base.rb @@ -15,9 +15,9 @@ def save_object(object) } end error!(meta: { - status: 400, - errors: errors - }, response:{ }) + status: 400, + errors: errors + }, response: {}) end end diff --git a/app/apis/api/v1/authorize.rb b/app/apis/api/v1/authorize.rb index f1239be..b1cefb3 100644 --- a/app/apis/api/v1/authorize.rb +++ b/app/apis/api/v1/authorize.rb @@ -14,29 +14,30 @@ class Authorize < Grape::API requires :password, type: String, desc: 'パスワード' end def find_user_by_identifier(identifier) - if(user_info = UserInfo.find_by(screen_name: identifier) || UserInfo.find_by(email: identifier)) + if (user_info = UserInfo.find_by(screen_name: identifier) || UserInfo.find_by(email: identifier)) user_info.user else error!(meta: { - status: 400, - errors: [ - message: ('errors.messages.user_not_found'), - code: ErrorCodes::NOT_FOUND_USER - ] - }, response:{ }) + status: 400, + errors: [ + message: ('errors.messages.user_not_found'), + code: ErrorCodes::NOT_FOUND_USER + ] + }, response: {}) end end + def check_password(user_info, raw_password) if BCrypt::Password.new(user_info.hashed_password) == raw_password true else error!(meta: { - status: 400, - errors: [ - message: ('errors.messages.invalid_pin'), - code: ErrorCodes::INVALID_PIN - ] - }, response:{ }) + status: 400, + errors: [ + message: ('errors.messages.invalid_pin'), + code: ErrorCodes::INVALID_PIN + ] + }, response: {}) false end end @@ -72,7 +73,7 @@ def check_password(user_info, raw_password) message: ('errors.messages.already_existing'), code: ErrorCodes::ALREADY_EXISTING ] - }, response:{ }) + }, response: {}) else user_info = user.build_info( email: params[:email], diff --git a/app/views/apis/api/v1/auth/login.jbuilder b/app/views/apis/api/v1/auth/login.jbuilder index ec4cb6b..d539cdd 100644 --- a/app/views/apis/api/v1/auth/login.jbuilder +++ b/app/views/apis/api/v1/auth/login.jbuilder @@ -1,6 +1,6 @@ json.meta do json.status 201 - json.message "ログインに成功しました" + json.message 'ログインに成功しました' end json.response do json.auth_token @token From 9450a8308f97e773560587d2e44de2752f613b5f Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 29 Nov 2015 19:31:03 +0900 Subject: [PATCH 052/358] rubocop -a --- spec/requests/api/v1/authorize_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/requests/api/v1/authorize_spec.rb b/spec/requests/api/v1/authorize_spec.rb index b8df87d..d727848 100644 --- a/spec/requests/api/v1/authorize_spec.rb +++ b/spec/requests/api/v1/authorize_spec.rb @@ -63,7 +63,7 @@ expect(@json['meta']['status']).to be 400 end it 'correct code' do - expect(@json['meta']['errors'][0]["code"]).to be ErrorCodes::ALREADY_EXISTING + expect(@json['meta']['errors'][0]['code']).to be ErrorCodes::ALREADY_EXISTING end end end From cb05e3df90177ee7e72738d3d2358121abaa2b3c Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 29 Nov 2015 19:50:32 +0900 Subject: [PATCH 053/358] change name users -> user --- app/views/apis/api/v1/{users => user}/create.jbuilder | 0 app/views/apis/api/v1/{users => user}/destroy.jbuilder | 0 app/views/apis/api/v1/{users => user}/hello.jbuilder | 0 app/views/apis/api/v1/{users => user}/info/show.jbuilder | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename app/views/apis/api/v1/{users => user}/create.jbuilder (100%) rename app/views/apis/api/v1/{users => user}/destroy.jbuilder (100%) rename app/views/apis/api/v1/{users => user}/hello.jbuilder (100%) rename app/views/apis/api/v1/{users => user}/info/show.jbuilder (100%) diff --git a/app/views/apis/api/v1/users/create.jbuilder b/app/views/apis/api/v1/user/create.jbuilder similarity index 100% rename from app/views/apis/api/v1/users/create.jbuilder rename to app/views/apis/api/v1/user/create.jbuilder diff --git a/app/views/apis/api/v1/users/destroy.jbuilder b/app/views/apis/api/v1/user/destroy.jbuilder similarity index 100% rename from app/views/apis/api/v1/users/destroy.jbuilder rename to app/views/apis/api/v1/user/destroy.jbuilder diff --git a/app/views/apis/api/v1/users/hello.jbuilder b/app/views/apis/api/v1/user/hello.jbuilder similarity index 100% rename from app/views/apis/api/v1/users/hello.jbuilder rename to app/views/apis/api/v1/user/hello.jbuilder diff --git a/app/views/apis/api/v1/users/info/show.jbuilder b/app/views/apis/api/v1/user/info/show.jbuilder similarity index 100% rename from app/views/apis/api/v1/users/info/show.jbuilder rename to app/views/apis/api/v1/user/info/show.jbuilder From 0b4712c8abbf459511920f1f05b78ec85f347a4d Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 29 Nov 2015 19:52:28 +0900 Subject: [PATCH 054/358] fix error message --- app/apis/api/base.rb | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/app/apis/api/base.rb b/app/apis/api/base.rb index f290941..8b70f97 100644 --- a/app/apis/api/base.rb +++ b/app/apis/api/base.rb @@ -25,15 +25,13 @@ def check_password(user_info, raw_password) if BCrypt::Password.new(user_info.hashed_password) == raw_password true else - error!(json: { - errors: [ - { - message: 'errors.messages.invalid_pin', + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.invalid_pin'), code: ErrorCodes::INVALID_PIN - } - ] - }, status: 400 - ) + ] + }, response: {}) false end end From 2dfd332faf7023838fab54d697d360fa0795c923 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 29 Nov 2015 20:02:43 +0900 Subject: [PATCH 055/358] =?UTF-8?q?response=E3=81=AE=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/apis/api/v1/user/destroy.jbuilder | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/views/apis/api/v1/user/destroy.jbuilder b/app/views/apis/api/v1/user/destroy.jbuilder index 747317e..3178227 100644 --- a/app/views/apis/api/v1/user/destroy.jbuilder +++ b/app/views/apis/api/v1/user/destroy.jbuilder @@ -1 +1,6 @@ -json.message @message +json.meta do + json.status 200 + json.message @message +end +json.response do +end From 266315982198b81cf7388b3e0d9929110902afcb Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 29 Nov 2015 20:02:58 +0900 Subject: [PATCH 056/358] =?UTF-8?q?base.rb=E3=81=AE=E6=9B=B8=E3=81=8D?= =?UTF-8?q?=E7=9B=B4=E3=81=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/apis/api/base.rb | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/app/apis/api/base.rb b/app/apis/api/base.rb index 8b70f97..14ac164 100644 --- a/app/apis/api/base.rb +++ b/app/apis/api/base.rb @@ -38,9 +38,18 @@ def check_password(user_info, raw_password) def user return @user if @user - return nil unless (token = AuthToken.find_by(token: params[:auth_token])) - update_auth_token token - @user = token.user + if (token = AuthToken.find_by(token: params[:auth_token])) + update_auth_token token + @user = token.user + else + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.invalid_auth_token'), + code: ErrorCodes::INVALID_TOKEN + ] + }, response: {}) + end end def update_auth_token(token) @@ -54,15 +63,13 @@ def user_signed_in? def authenticate_user! unless user_signed_in? - error!(json: { - errors: [ - { - message: t('errors.messages.invalid_auth_token'), + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.invalid_auth_token'), code: ErrorCodes::INVALID_TOKEN - } - ] - }, status: 400 - ) + ] + }, response: {}) end end end From 229cc23a7bc0af1186e02f13221849ca5c1770de Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 29 Nov 2015 20:03:27 +0900 Subject: [PATCH 057/358] =?UTF-8?q?=F0=9F=92=84refactoring=20users.rb?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/apis/api/v1/users.rb | 133 +++++++++------------------------------ 1 file changed, 28 insertions(+), 105 deletions(-) diff --git a/app/apis/api/v1/users.rb b/app/apis/api/v1/users.rb index 239b4c1..614c963 100644 --- a/app/apis/api/v1/users.rb +++ b/app/apis/api/v1/users.rb @@ -4,15 +4,6 @@ module API module V1 class Users < Grape::API helpers do - # Strong Parametersの設定 - def message_board_params - ActionController::Parameters.new(params).permit(:title, :body) - end - - def set_message_board - @message_board = MessageBoard.find(params[:id]) - end - # パラメータのチェック # パラメーターの必須、任意を指定することができる。 # use :attributesという形で使うことができる。 @@ -23,35 +14,14 @@ def set_message_board # パラメータのチェック params :id do - requires :id, type: Integer, desc: 'MessageBoard id.' + requires :id, type: Integer, desc: 'id.' end params :token do requires :auth_token, type: String, desc: 'auth_token' end end - resource :users do - desc '確認用のテストAPI', notes: <<-NOTE -

helloと返すAPI

-

- このURLにアクセスするとHelloを返してくれます。
- 実際にリクエストできてるか確認するためのAPIです。 -

- NOTE - get '/hello', jbuilder: 'api/v1/users/hello' do - @hoge = 'hello' - end - desc 'ユーザー作成', notes: <<-NOTE -

Userを作成するAPI

-

- このURLにアクセスするとUserを作るよ。 -

- NOTE - post '/', jbuilder: 'api/v1/users/create' do - user = save_object(User.new) - @token = user.auth_tokens.new_token - end - + resource :user do desc 'ユーザー削除', notes: <<-NOTE

Userを削除します

@@ -62,36 +32,32 @@ def set_message_board use :token optional :password, type: String, desc: 'サインアップしている場合' end - delete '/', jbuilder: 'api/v1/users/destroy' do + delete '/', jbuilder: 'api/v1/user/destroy' do unless token = AuthToken.find_by(token: params[:auth_token]) - error!(json: { + error!(meta: { + status: 400, errors: [ - { - message: 'errors.messages.cant_find_token', - code: ErrorCodes::INVALID_TOKEN - } + message: ('errors.messages.cant_find_token'), + code: ErrorCodes::INVALID_TOKEN ] - }, status: 400 - ) + }, response: {}) false end - if info = token.user.info if params[:password] if check_password(info, params[:password]) + name = user.info.screen_name user.destroy - @message = '退会しました。' + @message = "#{name}さんは退会しました。" end else - error!(json: { - errors: [ - { - message: 'errors.messages.need_a_password', - code: ErrorCodes::NEED_A_PASSWORD - } - ] - }, status: 400 - ) + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.need_a_password'), + code: ErrorCodes::NEED_A_PASSWORD + ] + }, response: {}) false end else @@ -99,74 +65,31 @@ def set_message_board @message = '退会しました。' end end - resource :info do desc 'ユーザー情報の表示', notes: <<-NOTE -

helloと返すAPI

+

ユーザー情報を表示する

- このURLにアクセスするとHelloを返してくれます。
- 実際にリクエストできてるか確認するためのAPIです。 + ユーザーのプロフィール情報がかえってきます。

NOTE params do use :token end - get '/', jbuilder: 'api/v1/users/info/show' do + get '/', jbuilder: 'api/v1/user/info/show' do if user.info.nil? - error!(json: { - errors: [ - message: ('info did not create'), - code: ErrorCodes::NOT_FOUND - ] - }, status: 400) + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.not_create_info'), + code: ErrorCodes::NOT_FOUND + ] + }, response: {}) + false end @info = user.info end end end - - # resource :message_boards do - # desc 'GET /api/v1/message_boards' - # get '/', jbuilder: 'api/v1/message_boards/index' do - # @message_boards = MessageBoard.all - # end - - # desc 'POST /api/v1/message_boards' - # params do - # use :attributes - # end - # post '/' do - # message_board = MessageBoard.new(message_board_params) - # message_board.save - # end - - # desc 'GET /api/v1/message_boards/:id' - # params do - # use :id - # end - # get '/:id', jbuilder: 'api/v1/message_boards/show' do - # set_message_board - # end - - # desc 'PUT /api/v1/message_boards/:id' - # params do - # use :id - # use :attributes - # end - # put '/:id' do - # set_message_board - # @message_board.update(message_board_params) - # end - - # desc 'DELETE /api/v1/message_boards/:id' - # params do - # use :id - # end - # delete '/:id' do - # set_message_board - # @message_board.destroy - # end - # end end end end From 8171163c6199af058197778f70a4088f4aa40b53 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 29 Nov 2015 20:03:51 +0900 Subject: [PATCH 058/358] =?UTF-8?q?=F0=9F=92=84refactoring=20authorize.rb?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/apis/api/v1/authorize.rb | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/app/apis/api/v1/authorize.rb b/app/apis/api/v1/authorize.rb index b1cefb3..8e347c2 100644 --- a/app/apis/api/v1/authorize.rb +++ b/app/apis/api/v1/authorize.rb @@ -26,21 +26,6 @@ def find_user_by_identifier(identifier) }, response: {}) end end - - def check_password(user_info, raw_password) - if BCrypt::Password.new(user_info.hashed_password) == raw_password - true - else - error!(meta: { - status: 400, - errors: [ - message: ('errors.messages.invalid_pin'), - code: ErrorCodes::INVALID_PIN - ] - }, response: {}) - false - end - end end resource :auth do desc 'トークンの取得', notes: <<-NOTE From 5dae44a15a63fd5611d1bc06df0251ff5b71a5d8 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 29 Nov 2015 20:09:45 +0900 Subject: [PATCH 059/358] rubocop -a --- app/apis/api/base.rb | 36 ++++++++++++++++++------------------ app/apis/api/v1/users.rb | 26 +++++++++++++------------- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/app/apis/api/base.rb b/app/apis/api/base.rb index 14ac164..0beea2b 100644 --- a/app/apis/api/base.rb +++ b/app/apis/api/base.rb @@ -26,12 +26,12 @@ def check_password(user_info, raw_password) true else error!(meta: { - status: 400, - errors: [ - message: ('errors.messages.invalid_pin'), - code: ErrorCodes::INVALID_PIN - ] - }, response: {}) + status: 400, + errors: [ + message: ('errors.messages.invalid_pin'), + code: ErrorCodes::INVALID_PIN + ] + }, response: {}) false end end @@ -43,12 +43,12 @@ def user @user = token.user else error!(meta: { - status: 400, - errors: [ - message: ('errors.messages.invalid_auth_token'), - code: ErrorCodes::INVALID_TOKEN - ] - }, response: {}) + status: 400, + errors: [ + message: ('errors.messages.invalid_auth_token'), + code: ErrorCodes::INVALID_TOKEN + ] + }, response: {}) end end @@ -64,12 +64,12 @@ def user_signed_in? def authenticate_user! unless user_signed_in? error!(meta: { - status: 400, - errors: [ - message: ('errors.messages.invalid_auth_token'), - code: ErrorCodes::INVALID_TOKEN - ] - }, response: {}) + status: 400, + errors: [ + message: ('errors.messages.invalid_auth_token'), + code: ErrorCodes::INVALID_TOKEN + ] + }, response: {}) end end end diff --git a/app/apis/api/v1/users.rb b/app/apis/api/v1/users.rb index 614c963..e7d6705 100644 --- a/app/apis/api/v1/users.rb +++ b/app/apis/api/v1/users.rb @@ -34,7 +34,7 @@ class Users < Grape::API end delete '/', jbuilder: 'api/v1/user/destroy' do unless token = AuthToken.find_by(token: params[:auth_token]) - error!(meta: { + error!(meta: { status: 400, errors: [ message: ('errors.messages.cant_find_token'), @@ -52,12 +52,12 @@ class Users < Grape::API end else error!(meta: { - status: 400, - errors: [ - message: ('errors.messages.need_a_password'), - code: ErrorCodes::NEED_A_PASSWORD - ] - }, response: {}) + status: 400, + errors: [ + message: ('errors.messages.need_a_password'), + code: ErrorCodes::NEED_A_PASSWORD + ] + }, response: {}) false end else @@ -78,12 +78,12 @@ class Users < Grape::API get '/', jbuilder: 'api/v1/user/info/show' do if user.info.nil? error!(meta: { - status: 400, - errors: [ - message: ('errors.messages.not_create_info'), - code: ErrorCodes::NOT_FOUND - ] - }, response: {}) + status: 400, + errors: [ + message: ('errors.messages.not_create_info'), + code: ErrorCodes::NOT_FOUND + ] + }, response: {}) false end @info = user.info From 3645564ecf862f79fa7bfd4a7bb9d0b226892628 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Mon, 30 Nov 2015 01:39:45 +0900 Subject: [PATCH 060/358] add error code --- lib/error_codes.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/error_codes.rb b/lib/error_codes.rb index 6a7cf03..c7388fa 100644 --- a/lib/error_codes.rb +++ b/lib/error_codes.rb @@ -20,4 +20,5 @@ module ErrorCodes TIMEOUT = 19 ALREADY_EXISTING = 20 NEED_A_PASSWORD = 21 + NOT_FOUND_INFO = 22 end From 7fe5ea474731b4333da9466d870b5afb6fad3fb0 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Mon, 30 Nov 2015 01:39:54 +0900 Subject: [PATCH 061/358] create logout jbuilder --- app/views/apis/api/v1/auth/logout.jbuilder | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 app/views/apis/api/v1/auth/logout.jbuilder diff --git a/app/views/apis/api/v1/auth/logout.jbuilder b/app/views/apis/api/v1/auth/logout.jbuilder new file mode 100644 index 0000000..d0c9256 --- /dev/null +++ b/app/views/apis/api/v1/auth/logout.jbuilder @@ -0,0 +1,6 @@ +json.meta do + json.status 200 + json.message 'ログアウトしました。' +end +json.response do +end From 099d67f80e59d66b1201bda1cfd2176a731df8ab Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Mon, 30 Nov 2015 01:40:10 +0900 Subject: [PATCH 062/358] edit response message --- app/apis/api/v1/users.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/apis/api/v1/users.rb b/app/apis/api/v1/users.rb index e7d6705..413ce88 100644 --- a/app/apis/api/v1/users.rb +++ b/app/apis/api/v1/users.rb @@ -37,7 +37,7 @@ class Users < Grape::API error!(meta: { status: 400, errors: [ - message: ('errors.messages.cant_find_token'), + message: ('errors.messages.invalid_token'), code: ErrorCodes::INVALID_TOKEN ] }, response: {}) From f8f06bf72c5587ec39c19a10210aab7b93d4d680 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Mon, 30 Nov 2015 01:40:20 +0900 Subject: [PATCH 063/358] create logout api --- app/apis/api/v1/authorize.rb | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/app/apis/api/v1/authorize.rb b/app/apis/api/v1/authorize.rb index 8e347c2..914b2e0 100644 --- a/app/apis/api/v1/authorize.rb +++ b/app/apis/api/v1/authorize.rb @@ -87,6 +87,40 @@ def find_user_by_identifier(identifier) @token = user.auth_tokens.new_token end end + + desc 'ログアウト用API', notes: <<-NOTE +

logout

+

+ トークンを削除してログアウトします。ユーザー情報がまだ作成されてないトークンは削除できません。 +

+ NOTE + params do + requires :auth_token, type: String, desc: 'トークン' + end + delete '/logout', jbuilder: 'api/v1/auth/logout' do + if(token = AuthToken.find_by(token: params[:auth_token])) + if token.user.info + token.destroy + else + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.info_not_found'), + code: ErrorCodes::NOT_FOUND_INFO + ] + }, response: {}) + end + else + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.invalid_token'), + code: ErrorCodes::INVALID_TOKEN + ] + }, response: {}) + end + end + end end end From 4f8eea5219ee0d447ca3d0a99350cf8e54009dfc Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Mon, 30 Nov 2015 01:53:13 +0900 Subject: [PATCH 064/358] create raspberry.rb --- app/apis/api/v1/raspberry.rb | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 app/apis/api/v1/raspberry.rb diff --git a/app/apis/api/v1/raspberry.rb b/app/apis/api/v1/raspberry.rb new file mode 100644 index 0000000..4613dca --- /dev/null +++ b/app/apis/api/v1/raspberry.rb @@ -0,0 +1,8 @@ +# app/apis/api/v1/raspberry.rb + +module API + module V1 + class Raspberry < Grape::API + end + end +end From c26405576ac4192d1f03e29c38ad7c0dbb7aa23e Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Mon, 30 Nov 2015 02:05:34 +0900 Subject: [PATCH 065/358] mount V1::Raspberry --- app/apis/api/v1/base.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/apis/api/v1/base.rb b/app/apis/api/v1/base.rb index dbc9151..2ccd330 100644 --- a/app/apis/api/v1/base.rb +++ b/app/apis/api/v1/base.rb @@ -32,6 +32,7 @@ class Base < Grape::API mount V1::Users mount V1::Authorize + mount V1::Raspberry add_swagger_documentation format: :json, api_version: 'v1', hide_documentation_path: true end end From 810415c9a29a492257a15023feedaf0cc16404be Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Mon, 30 Nov 2015 02:06:20 +0900 Subject: [PATCH 066/358] add blink.jbuilder --- app/views/apis/api/v1/raspberry/commands/blink.jbuilder | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 app/views/apis/api/v1/raspberry/commands/blink.jbuilder diff --git a/app/views/apis/api/v1/raspberry/commands/blink.jbuilder b/app/views/apis/api/v1/raspberry/commands/blink.jbuilder new file mode 100644 index 0000000..c3ea5aa --- /dev/null +++ b/app/views/apis/api/v1/raspberry/commands/blink.jbuilder @@ -0,0 +1,6 @@ +json.meta do + json.status 200 + json.message "LEDを点滅させます。" +end +json.response do +end From ab8c263b4ca3623922aaf80154d49f1c804effc4 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Mon, 30 Nov 2015 02:06:37 +0900 Subject: [PATCH 067/358] add raspberry/commands/blink --- app/apis/api/v1/raspberry.rb | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/app/apis/api/v1/raspberry.rb b/app/apis/api/v1/raspberry.rb index 4613dca..4cbec32 100644 --- a/app/apis/api/v1/raspberry.rb +++ b/app/apis/api/v1/raspberry.rb @@ -3,6 +3,42 @@ module API module V1 class Raspberry < Grape::API + resource :raspberry do + desc 'LEDの点滅', notes: <<-NOTE +

LEDを点滅させる

+

+ LEDがつくよ +

+ NOTE + params do + requires :auth_token, type: String, desc: 'Auth token.' + end + get '/commands/blink', jbuilder: 'api/v1/raspberry/commands/blink' do + if(token = AuthToken.find_by(token: params[:auth_token])) + if token.user.info + + else + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.info_not_found'), + code: ErrorCodes::NOT_FOUND_INFO + ] + }, response: {}) + false + end + else + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.invalid_token'), + code: ErrorCodes::INVALID_TOKEN + ] + }, response: {}) + false + end + end + end end end end From 6ec9be5bdd8daa65337d11723da399b978ee62ba Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Mon, 30 Nov 2015 02:44:19 +0900 Subject: [PATCH 068/358] create blink api --- app/apis/api/v1/raspberry.rb | 3 ++- commands/blink.sh | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 commands/blink.sh diff --git a/app/apis/api/v1/raspberry.rb b/app/apis/api/v1/raspberry.rb index 4cbec32..c365e7f 100644 --- a/app/apis/api/v1/raspberry.rb +++ b/app/apis/api/v1/raspberry.rb @@ -16,7 +16,8 @@ class Raspberry < Grape::API get '/commands/blink', jbuilder: 'api/v1/raspberry/commands/blink' do if(token = AuthToken.find_by(token: params[:auth_token])) if token.user.info - + path = File.join(Rails.root.instance_values["path"], "commands/blink.sh") + `sudo sh #{path}` else error!(meta: { status: 400, diff --git a/commands/blink.sh b/commands/blink.sh new file mode 100644 index 0000000..5e74e71 --- /dev/null +++ b/commands/blink.sh @@ -0,0 +1,17 @@ +echo 2 > /sys/class/gpio/export #「GPIO2」を使う +sleep 1 +echo out > /sys/class/gpio/gpio2/direction #「GPIO2」を出力用に使う + +echo 1 > /sys/class/gpio/gpio2/value #点灯 +sleep 1 #1秒休む +echo 0 > /sys/class/gpio/gpio2/value #消灯 +sleep 1 +echo 1 > /sys/class/gpio/gpio2/value +sleep 1 +echo 0 > /sys/class/gpio/gpio2/value +sleep 1 +echo 1 > /sys/class/gpio/gpio2/value +sleep 1 +echo 0 > /sys/class/gpio/gpio2/value + +echo 2 > /sys/class/gpio/unexport #「GPIO2」の使用を終了 \ No newline at end of file From f00d115bc1fac1e4e0acd259b3762d749cfbe9ca Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Mon, 30 Nov 2015 10:54:12 +0900 Subject: [PATCH 069/358] =?UTF-8?q?=F0=9F=92=84refactoring=20root=20path?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/apis/api/v1/raspberry.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/apis/api/v1/raspberry.rb b/app/apis/api/v1/raspberry.rb index c365e7f..7198ebc 100644 --- a/app/apis/api/v1/raspberry.rb +++ b/app/apis/api/v1/raspberry.rb @@ -16,7 +16,7 @@ class Raspberry < Grape::API get '/commands/blink', jbuilder: 'api/v1/raspberry/commands/blink' do if(token = AuthToken.find_by(token: params[:auth_token])) if token.user.info - path = File.join(Rails.root.instance_values["path"], "commands/blink.sh") + path = File.join(Rails.root.to_s + "commands/blink.sh") `sudo sh #{path}` else error!(meta: { From 8b2ee2fffa279fd6c7b7042d78ca058ddee3d263 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Mon, 30 Nov 2015 19:37:05 +0900 Subject: [PATCH 070/358] add helper.css --- app/assets/stylesheets/helper.css.scss | 1117 ++++++++++++++++++++++++ 1 file changed, 1117 insertions(+) create mode 100644 app/assets/stylesheets/helper.css.scss diff --git a/app/assets/stylesheets/helper.css.scss b/app/assets/stylesheets/helper.css.scss new file mode 100644 index 0000000..9dd5478 --- /dev/null +++ b/app/assets/stylesheets/helper.css.scss @@ -0,0 +1,1117 @@ +.scroll-wrap { + overflow: hidden; +} + +.scroll { + position: relative; + overflow: scroll; + width: 100%; + height: 100%; + padding-right: 40px; + padding-bottom: 40px; + z-index: 99; +} + +.clear{ + clear: both; +} + +.max-h{ + height: 100%; +} + +.container { + max-width: 100%; + margin-right: auto; + margin-left: auto; +} + +@media (min-width: 768px) { + .container { + width: 750px; + } +} +@media (min-width: 992px) { + .container { + width: 970px; + } +} +@media (min-width: 1200px) { + .container { + width: 1170px; + } +} +.container-fluid { + margin-right: auto; + margin-left: auto; +} + +.row { + display: -webkit-box; + display: -moz-box; + display: -ms-box; + display: -webkit-flexbox; + display: -moz-flexbox; + display: -ms-flexbox; + display: -webkit-flex; + display: -moz-flex; + display: -ms-flex; + display: flex; + -webkit-box-lines: multiple; + -moz-box-lines: multiple; + -webkit-flex-wrap: wrap; + -moz-flex-wrap: wrap; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + flex-direction: row; + -webkit-flex-direction: row; + box-sizing: border-box; +} +.row.left { + justify-content: flex-start; +} +.row.right { + justify-content: flex-end; +} +.row.center { + justify-content: center; +} +.row.around { + justify-content: space-around; +} +.row.between { + justify-content: space-between; +} +.row.top { + align-items: flex-start; +} +.row.content-top { + align-content: flex-start; +} +.row.content-bottom { + align-content: flex-end; +} +.row.content-center { + align-content: center; +} +.row.content-between { + align-content: between; +} +.row.content-around { + align-content: around; +} +.row.bottom { + align-items: flex-end; +} +.row.middle { + align-items: center; +} +.row.baseline { + align-items: baseline; +} +.row.stretch { + align-items: stretch; +} +.row.reverse { + flex-direction: row-reverse; + -webkit-flex-direction: row-reverse; +} +.row.nowrap { + flex-wrap: nowrap; +} + +.column.nowrap { + flex-wrap: nowrap; +} + +.row.wrap-reverse { + flex-wrap: wrap-reverse; +} + +.column { + display: -webkit-box; + display: -moz-box; + display: -ms-box; + display: -webkit-flexbox; + display: -moz-flexbox; + display: -ms-flexbox; + display: -webkit-flex; + display: -moz-flex; + display: -ms-flex; + display: flex; + -webkit-box-lines: multiple; + -moz-box-lines: multiple; + -webkit-flex-wrap: wrap; + -moz-flex-wrap: wrap; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + flex-direction: column; + -webkit-flex-direction: column; + box-sizing: border-box; +} +.column.wrap-reverse { + flex-wrap: wrap-reverse; +} +.column.reverse { + flex-direction: column-reverse; + -webkit-flex-direction: column-reverse; +} + +.flex { + box-sizing: border-box; + align-self: auto; + padding: 4px; + max-width: 100%; + flex: 100%; +} + +.hidden-xs { + display: none; +} + +.flex-fluid-xs-66 { + display: block; + max-width: 66.6%; + flex: 0 0 66.6%; + width: 66.6%; +} + +.flex-fluid-xs-33 { + display: block; + max-width: 33.3%; + flex: 0 0 33.3%; + width: 33.3%; +} + +.flex-fluid-xs-16 { + display: block; + max-width: 16.6%; + flex: 0 0 16.6%; + width: 16.6%; +} + +.flex-xs-auto { + display: block; + flex: 1; +} + +.flex-xs-20 { + display: block; + max-width: 100%; + flex: 100%; +} + +.flex-xs-19 { + display: block; + max-width: 95%; + flex: 0 0 95%; + width: 95%; +} + +.flex-xs-18 { + display: block; + max-width: 90%; + flex: 0 0 90%; + width: 90%; +} + +.flex-xs-17 { + display: block; + max-width: 85%; + flex: 0 0 85%; + width: 85%; +} + +.flex-xs-16 { + display: block; + max-width: 80%; + flex: 0 0 80%; + width: 80%; +} + +.flex-xs-15 { + display: block; + max-width: 75%; + flex: 0 0 75%; + width: 75%; +} + +.flex-xs-14 { + display: block; + max-width: 70%; + flex: 0 0 70%; + width: 70%; +} + +.flex-xs-13 { + display: block; + max-width: 65%; + flex: 0 0 65%; + width: 65%; +} + +.flex-xs-12 { + display: block; + max-width: 60%; + flex: 0 0 60%; + width: 60%; +} + +.flex-xs-11 { + display: block; + max-width: 55%; + flex: 0 0 55%; + width: 55%; +} + +.flex-xs-10 { + display: block; + max-width: 50%; + flex: 0 0 50%; + width: 50%; +} + +.flex-xs-9 { + display: block; + max-width: 45%; + flex: 0 0 45%; + width: 45%; +} + +.flex-xs-8 { + display: block; + max-width: 40%; + flex: 0 0 40%; + width: 40%; +} + +.flex-xs-7 { + display: block; + max-width: 35%; + flex: 0 0 35%; + width: 35%; +} + +.flex-xs-6 { + display: block; + max-width: 30%; + flex: 0 0 30%; + width: 30%; +} + +.flex-xs-5 { + display: block; + max-width: 25%; + flex: 0 0 25%; + width: 25%; +} + +.flex-xs-4 { + display: block; + max-width: 20%; + flex: 0 0 20%; + width: 20%; +} + +.flex-xs-3 { + display: block; + max-width: 15%; + flex: 0 0 15%; + width: 15%; +} + +.flex-xs-2 { + display: block; + max-width: 10%; + flex: 0 0 10%; + width: 10%; +} + +.flex-xs-1 { + display: block; + max-width: 5%; + flex: 0 0 5%; + width: 5%; +} +.flex-xs-order-1{ + order: 1; +} +.flex-xs-order-2{ + order: 2; +} +.flex-xs-order-3{ + order: 3; +} +.flex-xs-order-4{ + order: 4; +} +.flex-xs-order-5{ + order: 5; +} +.flex-xs-order-6{ + order: 6; +} +.flex-xs-order-7{ + order: 7; +} +.flex-xs-order-8{ + order: 8; +} +.flex-xs-order-9{ + order: 9; +} +.flex-xs-order-10{ + order: 10; +} +.flex-xs-order-11{ + order: 11; +} +.flex-xs-order-12{ + order: 12; +} +.flex-xs-order-13{ + order: 13; +} +.flex-xs-order-14{ + order: 14; +} +.flex-xs-order-15{ + order: 15; +} +.flex-xs-order-16{ + order: 16; +} +.flex-xs-order-17{ + order: 17; +} +.flex-xs-order-18{ + order: 18; +} +.flex-xs-order-19{ + order: 19; +} +.flex-xs-order-20{ + order: 20; +} +@media (min-width: 768px) { + .flex-fluid-sm-66 { + display: block; + max-width: 66.6%; + flex: 0 0 66.6%; + width: 66.6%; + } + + .flex-fluid-sm-33 { + display: block; + max-width: 33.3%; + flex: 0 0 33.3%; + width: 33.3%; + } + + .flex-fluid-sm-16 { + display: block; + max-width: 16.6%; + flex: 0 0 16.6%; + width: 16.6%; + } + + .hidden-sm { + display: none; + } + + .flex-sm-auto { + display: block; + flex: 1; + } + + .flex-sm-20 { + display: block; + max-width: 100%; + flex: 100%; + } + + .flex-sm-19 { + display: block; + max-width: 95%; + flex: 0 0 95%; + width: 95%; + } + + .flex-sm-18 { + display: block; + max-width: 90%; + flex: 0 0 90%; + width: 90%; + } + + .flex-sm-17 { + display: block; + max-width: 85%; + flex: 0 0 85%; + width: 85%; + } + + .flex-sm-16 { + display: block; + max-width: 80%; + flex: 0 0 80%; + width: 80%; + } + + .flex-sm-15 { + display: block; + max-width: 75%; + flex: 0 0 75%; + width: 75%; + } + + .flex-sm-14 { + display: block; + max-width: 70%; + flex: 0 0 70%; + width: 70%; + } + + .flex-sm-13 { + display: block; + max-width: 65%; + flex: 0 0 65%; + width: 65%; + } + + .flex-sm-12 { + display: block; + max-width: 60%; + flex: 0 0 60%; + width: 60%; + } + + .flex-sm-11 { + display: block; + max-width: 55%; + flex: 0 0 55%; + width: 55%; + } + + .flex-sm-10 { + display: block; + max-width: 50%; + flex: 0 0 50%; + width: 50%; + } + + .flex-sm-9 { + display: block; + max-width: 45%; + flex: 0 0 45%; + width: 45%; + } + + .flex-sm-8 { + display: block; + max-width: 40%; + flex: 0 0 40%; + width: 40%; + } + + .flex-sm-7 { + display: block; + max-width: 35%; + flex: 0 0 35%; + width: 35%; + } + + .flex-sm-6 { + display: block; + max-width: 30%; + flex: 0 0 30%; + width: 30%; + } + + .flex-sm-5 { + display: block; + max-width: 25%; + flex: 0 0 25%; + width: 25%; + } + + .flex-sm-4 { + display: block; + max-width: 20%; + flex: 0 0 20%; + width: 20%; + } + + .flex-sm-3 { + display: block; + max-width: 15%; + flex: 0 0 15%; + width: 15%; + } + + .flex-sm-2 { + display: block; + max-width: 10%; + flex: 0 0 10%; + width: 10%; + } + + .flex-sm-1 { + display: block; + max-width: 5%; + flex: 0 0 5%; + width: 5%; + } + .flex-sm-order-1{ + order: 1; + } + .flex-sm-order-2{ + order: 2; + } + .flex-sm-order-3{ + order: 3; + } + .flex-sm-order-4{ + order: 4; + } + .flex-sm-order-5{ + order: 5; + } + .flex-sm-order-6{ + order: 6; + } + .flex-sm-order-7{ + order: 7; + } + .flex-sm-order-8{ + order: 8; + } + .flex-sm-order-9{ + order: 9; + } + .flex-sm-order-10{ + order: 10; + } + .flex-sm-order-11{ + order: 11; + } + .flex-sm-order-12{ + order: 12; + } + .flex-sm-order-13{ + order: 13; + } + .flex-sm-order-14{ + order: 14; + } + .flex-sm-order-15{ + order: 15; + } + .flex-sm-order-16{ + order: 16; + } + .flex-sm-order-17{ + order: 17; + } + .flex-sm-order-18{ + order: 18; + } + .flex-sm-order-19{ + order: 19; + } + .flex-sm-order-20{ + order: 20; + } +} +@media (min-width: 960px) { + .flex-fluid-md-66 { + display: block; + max-width: 66.6%; + flex: 0 0 66.6%; + width: 66.6%; + } + + .flex-fluid-md-33 { + display: block; + max-width: 33.3%; + flex: 0 0 33.3%; + width: 33.3%; + } + + .flex-fluid-md-16 { + display: block; + max-width: 16.6%; + flex: 0 0 16.6%; + width: 16.6%; + } + + .hidden-md { + display: none; + } + + .flex-md-auto { + display: block; + flex: 1; + } + + .flex-md-20 { + display: block; + max-width: 100%; + flex: 100%; + } + + .flex-md-19 { + display: block; + max-width: 95%; + flex: 0 0 95%; + width: 95%; + } + + .flex-md-18 { + display: block; + max-width: 90%; + flex: 0 0 90%; + width: 90%; + } + + .flex-md-17 { + display: block; + max-width: 85%; + flex: 0 0 85%; + width: 85%; + } + + .flex-md-16 { + display: block; + max-width: 80%; + flex: 0 0 80%; + width: 80%; + } + + .flex-md-15 { + display: block; + max-width: 75%; + flex: 0 0 75%; + width: 75%; + } + + .flex-md-14 { + display: block; + max-width: 70%; + flex: 0 0 70%; + width: 70%; + } + + .flex-md-13 { + display: block; + max-width: 65%; + flex: 0 0 65%; + width: 65%; + } + + .flex-md-12 { + display: block; + max-width: 60%; + flex: 0 0 60%; + width: 60%; + } + + .flex-md-11 { + display: block; + max-width: 55%; + flex: 0 0 55%; + width: 55%; + } + + .flex-md-10 { + display: block; + max-width: 50%; + flex: 0 0 50%; + width: 50%; + } + + .flex-md-9 { + display: block; + max-width: 45%; + flex: 0 0 45%; + width: 45%; + } + + .flex-md-8 { + display: block; + max-width: 40%; + flex: 0 0 40%; + width: 40%; + } + + .flex-md-7 { + display: block; + max-width: 35%; + flex: 0 0 35%; + width: 35%; + } + + .flex-md-6 { + display: block; + max-width: 30%; + flex: 0 0 30%; + width: 30%; + } + + .flex-md-5 { + display: block; + max-width: 25%; + flex: 0 0 25%; + width: 25%; + } + + .flex-md-4 { + display: block; + max-width: 20%; + flex: 0 0 20%; + width: 20%; + } + + .flex-md-3 { + display: block; + max-width: 15%; + flex: 0 0 15%; + width: 15%; + } + + .flex-md-2 { + display: block; + max-width: 10%; + flex: 0 0 10%; + width: 10%; + } + + .flex-md-1 { + display: block; + max-width: 5%; + flex: 0 0 5%; + width: 5%; + } + .flex-md-order-1{ + order: 1; + } + .flex-md-order-2{ + order: 2; + } + .flex-md-order-3{ + order: 3; + } + .flex-md-order-4{ + order: 4; + } + .flex-md-order-5{ + order: 5; + } + .flex-md-order-6{ + order: 6; + } + .flex-md-order-7{ + order: 7; + } + .flex-md-order-8{ + order: 8; + } + .flex-md-order-9{ + order: 9; + } + .flex-md-order-10{ + order: 10; + } + .flex-md-order-11{ + order: 11; + } + .flex-md-order-12{ + order: 12; + } + .flex-md-order-13{ + order: 13; + } + .flex-md-order-14{ + order: 14; + } + .flex-md-order-15{ + order: 15; + } + .flex-md-order-16{ + order: 16; + } + .flex-md-order-17{ + order: 17; + } + .flex-md-order-18{ + order: 18; + } + .flex-md-order-19{ + order: 19; + } + .flex-md-order-20{ + order: 20; + } +} +@media (min-width: 1280px) { + .flex-fluid-lg-66 { + display: block; + max-width: 66.6%; + flex: 0 0 66.6%; + width: 66.6%; + } + + .flex-fluid-lg-33 { + display: block; + max-width: 33.3%; + flex: 0 0 33.3%; + width: 33.3%; + } + + .flex-fluid-lg-16 { + display: block; + max-width: 16.6%; + flex: 0 0 16.6%; + width: 16.6%; + } + + .hidden-lg { + display: none; + } + + .flex-lg-auto { + display: block; + flex: 1; + } + + .flex-lg-20 { + display: block; + max-width: 100%; + flex: 100%; + } + + .flex-lg-19 { + display: block; + max-width: 95%; + flex: 0 0 95%; + width: 95%; + } + + .flex-lg-18 { + display: block; + max-width: 90%; + flex: 0 0 90%; + width: 90%; + } + + .flex-lg-17 { + display: block; + max-width: 85%; + flex: 0 0 85%; + width: 85%; + } + + .flex-lg-16 { + display: block; + max-width: 80%; + flex: 0 0 80%; + width: 80%; + } + + .flex-lg-15 { + display: block; + max-width: 75%; + flex: 0 0 75%; + width: 75%; + } + + .flex-lg-14 { + display: block; + max-width: 70%; + flex: 0 0 70%; + width: 70%; + } + + .flex-lg-13 { + display: block; + max-width: 65%; + flex: 0 0 65%; + width: 65%; + } + + .flex-lg-12 { + display: block; + max-width: 60%; + flex: 0 0 60%; + width: 60%; + } + + .flex-lg-11 { + display: block; + max-width: 55%; + flex: 0 0 55%; + width: 55%; + } + + .flex-lg-10 { + display: block; + max-width: 50%; + flex: 0 0 50%; + width: 50%; + } + + .flex-lg-9 { + display: block; + max-width: 45%; + flex: 0 0 45%; + width: 45%; + } + + .flex-lg-8 { + display: block; + max-width: 40%; + flex: 0 0 40%; + width: 40%; + } + + .flex-lg-7 { + display: block; + max-width: 35%; + flex: 0 0 35%; + width: 35%; + } + + .flex-lg-6 { + display: block; + max-width: 30%; + flex: 0 0 30%; + width: 30%; + } + + .flex-lg-5 { + display: block; + max-width: 25%; + flex: 0 0 25%; + width: 25%; + } + + .flex-lg-4 { + display: block; + max-width: 20%; + flex: 0 0 20%; + width: 20%; + } + + .flex-lg-3 { + display: block; + max-width: 15%; + flex: 0 0 15%; + width: 15%; + } + + .flex-lg-2 { + display: block; + max-width: 10%; + flex: 0 0 10%; + width: 10%; + } + + .flex-lg-1 { + display: block; + max-width: 5%; + flex: 0 0 5%; + width: 5%; + } + .flex-lg-order-1{ + order: 1; + } + .flex-lg-order-2{ + order: 2; + } + .flex-lg-order-3{ + order: 3; + } + .flex-lg-order-4{ + order: 4; + } + .flex-lg-order-5{ + order: 5; + } + .flex-lg-order-6{ + order: 6; + } + .flex-lg-order-7{ + order: 7; + } + .flex-lg-order-8{ + order: 8; + } + .flex-lg-order-9{ + order: 9; + } + .flex-lg-order-10{ + order: 10; + } + .flex-lg-order-11{ + order: 11; + } + .flex-lg-order-12{ + order: 12; + } + .flex-lg-order-13{ + order: 13; + } + .flex-lg-order-14{ + order: 14; + } + .flex-lg-order-15{ + order: 15; + } + .flex-lg-order-16{ + order: 16; + } + .flex-lg-order-17{ + order: 17; + } + .flex-lg-order-18{ + order: 18; + } + .flex-lg-order-19{ + order: 19; + } + .flex-lg-order-20{ + order: 20; + } +} + +.row .frame { + width: 100%; + box-sizing: border-box; + background-color: white; +} + +.column .frame { + height: 100%; + box-sizing: border-box; + background-color: white; +} + +.z1 { + box-shadow: 0 3px 1px -2px rgba(0, 0, 0, 0.14), 0 2px 2px 0 rgba(0, 0, 0, 0.098), 0 1px 5px 0 rgba(0, 0, 0, 0.084); +} + +.z2 { + box-shadow: 0 2px 4px -1px rgba(0, 0, 0, 0.14), 0 4px 5px 0 rgba(0, 0, 0, 0.098), 0 1px 10px 0 rgba(0, 0, 0, 0.084); +} + +.z3 { + box-shadow: 0 3px 5px -1px rgba(0, 0, 0, 0.14), 0 6px 10px 0 rgba(0, 0, 0, 0.098), 0 1px 18px 0 rgba(0, 0, 0, 0.084); +} + +.z4 { + box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.14), 0 8px 10px 1px rgba(0, 0, 0, 0.098), 0 3px 14px 2px rgba(0, 0, 0, 0.084); +} + +.z5 { + box-shadow: 0 8px 10px -5px rgba(0, 0, 0, 0.14), 0 16px 24px 2px rgba(0, 0, 0, 0.098), 0 6px 30px 5px rgba(0, 0, 0, 0.084); +} From 5c6874fe4324b5df49b7ff6ee203322e3913fe0f Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Mon, 30 Nov 2015 19:43:04 +0900 Subject: [PATCH 071/358] fix info/show.jbuilder --- app/views/apis/api/v1/user/hello.jbuilder | 1 - app/views/apis/api/v1/user/info/show.jbuilder | 8 +++++++- 2 files changed, 7 insertions(+), 2 deletions(-) delete mode 100644 app/views/apis/api/v1/user/hello.jbuilder diff --git a/app/views/apis/api/v1/user/hello.jbuilder b/app/views/apis/api/v1/user/hello.jbuilder deleted file mode 100644 index 63c1989..0000000 --- a/app/views/apis/api/v1/user/hello.jbuilder +++ /dev/null @@ -1 +0,0 @@ -json.greet @hoge diff --git a/app/views/apis/api/v1/user/info/show.jbuilder b/app/views/apis/api/v1/user/info/show.jbuilder index c64adfa..2b224f4 100644 --- a/app/views/apis/api/v1/user/info/show.jbuilder +++ b/app/views/apis/api/v1/user/info/show.jbuilder @@ -1 +1,7 @@ -json.data @info +json.meta do + json.status 200 + json.message "ユーザー情報を取得しました" +end +json.response do + json.user @info +end From 4d99a4ec9ccf0f10a80840e2740fab52f3148a26 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Thu, 3 Dec 2015 07:51:07 +0900 Subject: [PATCH 072/358] rails g model Infrared name:string data:string user:references --- app/models/infrared.rb | 3 +++ db/migrate/20151202225038_create_infrareds.rb | 11 +++++++++++ spec/factories/infrareds.rb | 8 ++++++++ spec/models/infrared_spec.rb | 5 +++++ 4 files changed, 27 insertions(+) create mode 100644 app/models/infrared.rb create mode 100644 db/migrate/20151202225038_create_infrareds.rb create mode 100644 spec/factories/infrareds.rb create mode 100644 spec/models/infrared_spec.rb diff --git a/app/models/infrared.rb b/app/models/infrared.rb new file mode 100644 index 0000000..2a6b353 --- /dev/null +++ b/app/models/infrared.rb @@ -0,0 +1,3 @@ +class Infrared < ActiveRecord::Base + belongs_to :user +end diff --git a/db/migrate/20151202225038_create_infrareds.rb b/db/migrate/20151202225038_create_infrareds.rb new file mode 100644 index 0000000..fab4ba8 --- /dev/null +++ b/db/migrate/20151202225038_create_infrareds.rb @@ -0,0 +1,11 @@ +class CreateInfrareds < ActiveRecord::Migration + def change + create_table :infrareds do |t| + t.string :name + t.string :data + t.references :user, index: true, foreign_key: true + + t.timestamps null: false + end + end +end diff --git a/spec/factories/infrareds.rb b/spec/factories/infrareds.rb new file mode 100644 index 0000000..11cf37c --- /dev/null +++ b/spec/factories/infrareds.rb @@ -0,0 +1,8 @@ +FactoryGirl.define do + factory :infrared do + name "MyString" +data "MyString" +user nil + end + +end diff --git a/spec/models/infrared_spec.rb b/spec/models/infrared_spec.rb new file mode 100644 index 0000000..6e5d3f7 --- /dev/null +++ b/spec/models/infrared_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe Infrared, :type => :model do + pending "add some examples to (or delete) #{__FILE__}" +end From 87155ed8b6fe880e72244262de5df9e41ca5d127 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Thu, 3 Dec 2015 07:51:25 +0900 Subject: [PATCH 073/358] rake db:migrate --- db/schema.rb | 50 +++++++++++++++++++++++++++++++------------------- 1 file changed, 31 insertions(+), 19 deletions(-) diff --git a/db/schema.rb b/db/schema.rb index 79e6574..f3e540d 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,30 +11,42 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20_151_125_081_142) do - create_table 'auth_tokens', force: :cascade do |t| - t.string 'token' - t.integer 'user_id' - t.datetime 'created_at', null: false - t.datetime 'updated_at', null: false +ActiveRecord::Schema.define(version: 20151202225038) do + + create_table "auth_tokens", force: :cascade do |t| + t.string "token" + t.integer "user_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end - add_index 'auth_tokens', ['user_id'], name: 'index_auth_tokens_on_user_id' + add_index "auth_tokens", ["user_id"], name: "index_auth_tokens_on_user_id" - create_table 'user_infos', force: :cascade do |t| - t.string 'screen_name' - t.string 'hashed_password' - t.string 'email' - t.string 'email_for_index' - t.integer 'user_id' - t.datetime 'created_at', null: false - t.datetime 'updated_at', null: false + create_table "infrareds", force: :cascade do |t| + t.string "name" + t.string "data" + t.integer "user_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end - add_index 'user_infos', ['user_id'], name: 'index_user_infos_on_user_id' + add_index "infrareds", ["user_id"], name: "index_infrareds_on_user_id" - create_table 'users', force: :cascade do |t| - t.datetime 'created_at', null: false - t.datetime 'updated_at', null: false + create_table "user_infos", force: :cascade do |t| + t.string "screen_name" + t.string "hashed_password" + t.string "email" + t.string "email_for_index" + t.integer "user_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end + + add_index "user_infos", ["user_id"], name: "index_user_infos_on_user_id" + + create_table "users", force: :cascade do |t| + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + end From fa487fdbf1f66bc5efd42a6143e7ffb6fbea3980 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Thu, 3 Dec 2015 07:55:28 +0900 Subject: [PATCH 074/358] add relational --- app/models/user.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/models/user.rb b/app/models/user.rb index 295dc9e..8241ed5 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,4 +1,5 @@ class User < ActiveRecord::Base has_many :auth_tokens, dependent: :destroy has_one :info, class_name: 'UserInfo', dependent: :destroy + has_many :infrareds end From 5e7695595e94cc0a66035aaecb5014d943555791 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Thu, 3 Dec 2015 08:26:12 +0900 Subject: [PATCH 075/358] rails g model Task name:string user:references --- app/models/task.rb | 3 +++ db/migrate/20151202232602_create_tasks.rb | 10 ++++++++++ spec/factories/tasks.rb | 7 +++++++ spec/models/task_spec.rb | 5 +++++ 4 files changed, 25 insertions(+) create mode 100644 app/models/task.rb create mode 100644 db/migrate/20151202232602_create_tasks.rb create mode 100644 spec/factories/tasks.rb create mode 100644 spec/models/task_spec.rb diff --git a/app/models/task.rb b/app/models/task.rb new file mode 100644 index 0000000..5c58542 --- /dev/null +++ b/app/models/task.rb @@ -0,0 +1,3 @@ +class Task < ActiveRecord::Base + belongs_to :user +end diff --git a/db/migrate/20151202232602_create_tasks.rb b/db/migrate/20151202232602_create_tasks.rb new file mode 100644 index 0000000..ccd5812 --- /dev/null +++ b/db/migrate/20151202232602_create_tasks.rb @@ -0,0 +1,10 @@ +class CreateTasks < ActiveRecord::Migration + def change + create_table :tasks do |t| + t.string :name + t.references :user, index: true, foreign_key: true + + t.timestamps null: false + end + end +end diff --git a/spec/factories/tasks.rb b/spec/factories/tasks.rb new file mode 100644 index 0000000..28cfd88 --- /dev/null +++ b/spec/factories/tasks.rb @@ -0,0 +1,7 @@ +FactoryGirl.define do + factory :task do + name "MyString" +user nil + end + +end diff --git a/spec/models/task_spec.rb b/spec/models/task_spec.rb new file mode 100644 index 0000000..2c17e87 --- /dev/null +++ b/spec/models/task_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe Task, :type => :model do + pending "add some examples to (or delete) #{__FILE__}" +end From 2daab113a2e8aa383c50f48118ff8430cdf76d0a Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Thu, 3 Dec 2015 08:26:41 +0900 Subject: [PATCH 076/358] rake db:migrate --- db/schema.rb | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/db/schema.rb b/db/schema.rb index f3e540d..10d72e4 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20151202225038) do +ActiveRecord::Schema.define(version: 20151202232602) do create_table "auth_tokens", force: :cascade do |t| t.string "token" @@ -32,6 +32,15 @@ add_index "infrareds", ["user_id"], name: "index_infrareds_on_user_id" + create_table "tasks", force: :cascade do |t| + t.string "name" + t.integer "user_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + add_index "tasks", ["user_id"], name: "index_tasks_on_user_id" + create_table "user_infos", force: :cascade do |t| t.string "screen_name" t.string "hashed_password" From 4987c6ac71fbc6e6bd0528bdf9021f5882c40c94 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Thu, 3 Dec 2015 08:27:37 +0900 Subject: [PATCH 077/358] add relation --- app/models/user.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/models/user.rb b/app/models/user.rb index 8241ed5..bd1e121 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -2,4 +2,5 @@ class User < ActiveRecord::Base has_many :auth_tokens, dependent: :destroy has_one :info, class_name: 'UserInfo', dependent: :destroy has_many :infrareds + has_many :tasks end From e9623158a614a34d6cfc74d44526ee7c29892254 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Thu, 3 Dec 2015 08:47:38 +0900 Subject: [PATCH 078/358] rails g model TaskInfrared --- app/models/task_infrared.rb | 2 ++ db/migrate/20151202234724_create_task_infrareds.rb | 8 ++++++++ spec/factories/task_infrareds.rb | 6 ++++++ spec/models/task_infrared_spec.rb | 5 +++++ 4 files changed, 21 insertions(+) create mode 100644 app/models/task_infrared.rb create mode 100644 db/migrate/20151202234724_create_task_infrareds.rb create mode 100644 spec/factories/task_infrareds.rb create mode 100644 spec/models/task_infrared_spec.rb diff --git a/app/models/task_infrared.rb b/app/models/task_infrared.rb new file mode 100644 index 0000000..0d7289b --- /dev/null +++ b/app/models/task_infrared.rb @@ -0,0 +1,2 @@ +class TaskInfrared < ActiveRecord::Base +end diff --git a/db/migrate/20151202234724_create_task_infrareds.rb b/db/migrate/20151202234724_create_task_infrareds.rb new file mode 100644 index 0000000..3844dfa --- /dev/null +++ b/db/migrate/20151202234724_create_task_infrareds.rb @@ -0,0 +1,8 @@ +class CreateTaskInfrareds < ActiveRecord::Migration + def change + create_table :task_infrareds do |t| + + t.timestamps null: false + end + end +end diff --git a/spec/factories/task_infrareds.rb b/spec/factories/task_infrareds.rb new file mode 100644 index 0000000..fe4adbe --- /dev/null +++ b/spec/factories/task_infrareds.rb @@ -0,0 +1,6 @@ +FactoryGirl.define do + factory :task_infrared do + + end + +end diff --git a/spec/models/task_infrared_spec.rb b/spec/models/task_infrared_spec.rb new file mode 100644 index 0000000..353d44e --- /dev/null +++ b/spec/models/task_infrared_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe TaskInfrared, :type => :model do + pending "add some examples to (or delete) #{__FILE__}" +end From a5ef058ada8ddbe80da2c32caa9da29b0fdbbf0e Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Thu, 3 Dec 2015 10:59:35 +0900 Subject: [PATCH 079/358] setting relational --- app/models/infrared.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/models/infrared.rb b/app/models/infrared.rb index 2a6b353..d5c82db 100644 --- a/app/models/infrared.rb +++ b/app/models/infrared.rb @@ -1,3 +1,5 @@ class Infrared < ActiveRecord::Base belongs_to :user + has_many :task_infrareds + has_many :tasks, through: :task_infrareds end From 013a09ea2a4bad5a2553be9ea10d11bb8d608727 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Thu, 3 Dec 2015 10:59:51 +0900 Subject: [PATCH 080/358] add migration references --- db/migrate/20151202234724_create_task_infrareds.rb | 2 ++ db/schema.rb | 12 +++++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/db/migrate/20151202234724_create_task_infrareds.rb b/db/migrate/20151202234724_create_task_infrareds.rb index 3844dfa..365533a 100644 --- a/db/migrate/20151202234724_create_task_infrareds.rb +++ b/db/migrate/20151202234724_create_task_infrareds.rb @@ -1,6 +1,8 @@ class CreateTaskInfrareds < ActiveRecord::Migration def change create_table :task_infrareds do |t| + t.references :task, index: true, foreign_key: true + t.references :infrared, index: true, foreign_key: true t.timestamps null: false end diff --git a/db/schema.rb b/db/schema.rb index 10d72e4..fecf9e5 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20151202232602) do +ActiveRecord::Schema.define(version: 20151202234724) do create_table "auth_tokens", force: :cascade do |t| t.string "token" @@ -32,6 +32,16 @@ add_index "infrareds", ["user_id"], name: "index_infrareds_on_user_id" + create_table "task_infrareds", force: :cascade do |t| + t.integer "task_id" + t.integer "infrared_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + add_index "task_infrareds", ["infrared_id"], name: "index_task_infrareds_on_infrared_id" + add_index "task_infrareds", ["task_id"], name: "index_task_infrareds_on_task_id" + create_table "tasks", force: :cascade do |t| t.string "name" t.integer "user_id" From 0d095647b2a2ddbdef8cbb1638b07aa0cb78af67 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Thu, 3 Dec 2015 11:00:01 +0900 Subject: [PATCH 081/358] has_many --- app/models/task.rb | 2 ++ app/models/task_infrared.rb | 2 ++ 2 files changed, 4 insertions(+) diff --git a/app/models/task.rb b/app/models/task.rb index 5c58542..66987c8 100644 --- a/app/models/task.rb +++ b/app/models/task.rb @@ -1,3 +1,5 @@ class Task < ActiveRecord::Base belongs_to :user + has_many :task_infrareds + has_many :infrareds, through: :task_infrareds end diff --git a/app/models/task_infrared.rb b/app/models/task_infrared.rb index 0d7289b..17ca13d 100644 --- a/app/models/task_infrared.rb +++ b/app/models/task_infrared.rb @@ -1,2 +1,4 @@ class TaskInfrared < ActiveRecord::Base + belongs_to :task + belongs_to :infrared end From c963cd57a98d48aa9cc53686a3e87f056897fa54 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Thu, 3 Dec 2015 12:51:03 +0900 Subject: [PATCH 082/358] rails g model Log user:references --- app/models/log.rb | 3 +++ db/migrate/20151203035051_create_logs.rb | 9 +++++++++ spec/factories/logs.rb | 6 ++++++ spec/models/log_spec.rb | 5 +++++ 4 files changed, 23 insertions(+) create mode 100644 app/models/log.rb create mode 100644 db/migrate/20151203035051_create_logs.rb create mode 100644 spec/factories/logs.rb create mode 100644 spec/models/log_spec.rb diff --git a/app/models/log.rb b/app/models/log.rb new file mode 100644 index 0000000..a9551fe --- /dev/null +++ b/app/models/log.rb @@ -0,0 +1,3 @@ +class Log < ActiveRecord::Base + belongs_to :user +end diff --git a/db/migrate/20151203035051_create_logs.rb b/db/migrate/20151203035051_create_logs.rb new file mode 100644 index 0000000..38c7fb3 --- /dev/null +++ b/db/migrate/20151203035051_create_logs.rb @@ -0,0 +1,9 @@ +class CreateLogs < ActiveRecord::Migration + def change + create_table :logs do |t| + t.references :user, index: true, foreign_key: true + + t.timestamps null: false + end + end +end diff --git a/spec/factories/logs.rb b/spec/factories/logs.rb new file mode 100644 index 0000000..4e3e785 --- /dev/null +++ b/spec/factories/logs.rb @@ -0,0 +1,6 @@ +FactoryGirl.define do + factory :log do + user nil + end + +end diff --git a/spec/models/log_spec.rb b/spec/models/log_spec.rb new file mode 100644 index 0000000..b3fe5ca --- /dev/null +++ b/spec/models/log_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe Log, :type => :model do + pending "add some examples to (or delete) #{__FILE__}" +end From 9a3a9397b99feadc63b5f3d95f577c2d18ee0d1f Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Thu, 3 Dec 2015 12:51:30 +0900 Subject: [PATCH 083/358] rake db:migrate --- db/schema.rb | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/db/schema.rb b/db/schema.rb index fecf9e5..1e45189 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20151202234724) do +ActiveRecord::Schema.define(version: 20151203035051) do create_table "auth_tokens", force: :cascade do |t| t.string "token" @@ -32,6 +32,14 @@ add_index "infrareds", ["user_id"], name: "index_infrareds_on_user_id" + create_table "logs", force: :cascade do |t| + t.integer "user_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + add_index "logs", ["user_id"], name: "index_logs_on_user_id" + create_table "task_infrareds", force: :cascade do |t| t.integer "task_id" t.integer "infrared_id" From 40e0058849a3d496f4ff16e37e5b0dd2428c1c1e Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Thu, 3 Dec 2015 13:02:39 +0900 Subject: [PATCH 084/358] rails g migration AddReferencesToTasks log:references --- db/migrate/20151203040158_add_references_to_tasks.rb | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 db/migrate/20151203040158_add_references_to_tasks.rb diff --git a/db/migrate/20151203040158_add_references_to_tasks.rb b/db/migrate/20151203040158_add_references_to_tasks.rb new file mode 100644 index 0000000..d009f6f --- /dev/null +++ b/db/migrate/20151203040158_add_references_to_tasks.rb @@ -0,0 +1,5 @@ +class AddReferencesToTasks < ActiveRecord::Migration + def change + add_reference :tasks, :log, index: true, foreign_key: true + end +end From 8d43362e93186f0ca0fc493490f58f5b51ee6f5f Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Thu, 3 Dec 2015 13:02:43 +0900 Subject: [PATCH 085/358] rails g migration AddReferencesToInfrareds log:references --- db/migrate/20151203040210_add_references_to_infrareds.rb | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 db/migrate/20151203040210_add_references_to_infrareds.rb diff --git a/db/migrate/20151203040210_add_references_to_infrareds.rb b/db/migrate/20151203040210_add_references_to_infrareds.rb new file mode 100644 index 0000000..de807a5 --- /dev/null +++ b/db/migrate/20151203040210_add_references_to_infrareds.rb @@ -0,0 +1,5 @@ +class AddReferencesToInfrareds < ActiveRecord::Migration + def change + add_reference :infrareds, :log, index: true, foreign_key: true + end +end From aee1430361e730302c7d4a2cb5a74e30dfc9963e Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Thu, 3 Dec 2015 13:02:50 +0900 Subject: [PATCH 086/358] rake db:migrate --- db/schema.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/db/schema.rb b/db/schema.rb index 1e45189..051bddd 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20151203035051) do +ActiveRecord::Schema.define(version: 20151203040210) do create_table "auth_tokens", force: :cascade do |t| t.string "token" @@ -28,8 +28,10 @@ t.integer "user_id" t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.integer "log_id" end + add_index "infrareds", ["log_id"], name: "index_infrareds_on_log_id" add_index "infrareds", ["user_id"], name: "index_infrareds_on_user_id" create_table "logs", force: :cascade do |t| @@ -55,8 +57,10 @@ t.integer "user_id" t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.integer "log_id" end + add_index "tasks", ["log_id"], name: "index_tasks_on_log_id" add_index "tasks", ["user_id"], name: "index_tasks_on_user_id" create_table "user_infos", force: :cascade do |t| From 09ce0cd2f4ca7657c3601eb14b34c27d9ae24d59 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Thu, 3 Dec 2015 16:01:14 +0900 Subject: [PATCH 087/358] setting relational --- app/models/infrared.rb | 1 + app/models/log.rb | 2 ++ app/models/task.rb | 1 + app/models/user.rb | 1 + 4 files changed, 5 insertions(+) diff --git a/app/models/infrared.rb b/app/models/infrared.rb index d5c82db..920a46e 100644 --- a/app/models/infrared.rb +++ b/app/models/infrared.rb @@ -2,4 +2,5 @@ class Infrared < ActiveRecord::Base belongs_to :user has_many :task_infrareds has_many :tasks, through: :task_infrareds + belongs_to :log end diff --git a/app/models/log.rb b/app/models/log.rb index a9551fe..26608bf 100644 --- a/app/models/log.rb +++ b/app/models/log.rb @@ -1,3 +1,5 @@ class Log < ActiveRecord::Base belongs_to :user + has_many :tasks + has_many :infrareds end diff --git a/app/models/task.rb b/app/models/task.rb index 66987c8..0ff5cc1 100644 --- a/app/models/task.rb +++ b/app/models/task.rb @@ -2,4 +2,5 @@ class Task < ActiveRecord::Base belongs_to :user has_many :task_infrareds has_many :infrareds, through: :task_infrareds + belongs_to :log end diff --git a/app/models/user.rb b/app/models/user.rb index bd1e121..efdcde2 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -3,4 +3,5 @@ class User < ActiveRecord::Base has_one :info, class_name: 'UserInfo', dependent: :destroy has_many :infrareds has_many :tasks + has_one :log, dependent: :destroy end From d4df1235a06ecb593ebb69525b26d47246e64b44 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Thu, 3 Dec 2015 16:01:29 +0900 Subject: [PATCH 088/358] bundle exec erd.pdf --- erd.pdf | Bin 0 -> 33028 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 erd.pdf diff --git a/erd.pdf b/erd.pdf new file mode 100644 index 0000000000000000000000000000000000000000..8984ac7dfe464823447496501310a3e1bc2489cb GIT binary patch literal 33028 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 BY`Fjc literal 0 HcmV?d00001 From d3e34b86b35a84cd8eb3253c3d68c828a467b34f Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Fri, 4 Dec 2015 22:17:47 +0900 Subject: [PATCH 089/358] drop migration table tasks --- db/migrate/20151204131528_drop_table_tasks.rb | 5 +++++ db/schema.rb | 13 +------------ 2 files changed, 6 insertions(+), 12 deletions(-) create mode 100644 db/migrate/20151204131528_drop_table_tasks.rb diff --git a/db/migrate/20151204131528_drop_table_tasks.rb b/db/migrate/20151204131528_drop_table_tasks.rb new file mode 100644 index 0000000..e99a4bb --- /dev/null +++ b/db/migrate/20151204131528_drop_table_tasks.rb @@ -0,0 +1,5 @@ +class DropTableTasks < ActiveRecord::Migration + def change + drop_table :tasks + end +end diff --git a/db/schema.rb b/db/schema.rb index 051bddd..dd2f7de 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20151203040210) do +ActiveRecord::Schema.define(version: 20151204131528) do create_table "auth_tokens", force: :cascade do |t| t.string "token" @@ -52,17 +52,6 @@ add_index "task_infrareds", ["infrared_id"], name: "index_task_infrareds_on_infrared_id" add_index "task_infrareds", ["task_id"], name: "index_task_infrareds_on_task_id" - create_table "tasks", force: :cascade do |t| - t.string "name" - t.integer "user_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.integer "log_id" - end - - add_index "tasks", ["log_id"], name: "index_tasks_on_log_id" - add_index "tasks", ["user_id"], name: "index_tasks_on_user_id" - create_table "user_infos", force: :cascade do |t| t.string "screen_name" t.string "hashed_password" From 95e351761d7afe774eb1868bede22af5849da92b Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Fri, 4 Dec 2015 22:27:58 +0900 Subject: [PATCH 090/358] rails g model InfraredGroup --- app/models/infrared_group.rb | 2 ++ db/migrate/20151204132603_create_infrared_groups.rb | 11 +++++++++++ spec/factories/infrared_groups.rb | 6 ++++++ spec/models/infrared_group_spec.rb | 5 +++++ 4 files changed, 24 insertions(+) create mode 100644 app/models/infrared_group.rb create mode 100644 db/migrate/20151204132603_create_infrared_groups.rb create mode 100644 spec/factories/infrared_groups.rb create mode 100644 spec/models/infrared_group_spec.rb diff --git a/app/models/infrared_group.rb b/app/models/infrared_group.rb new file mode 100644 index 0000000..09d6479 --- /dev/null +++ b/app/models/infrared_group.rb @@ -0,0 +1,2 @@ +class InfraredGroup < ActiveRecord::Base +end diff --git a/db/migrate/20151204132603_create_infrared_groups.rb b/db/migrate/20151204132603_create_infrared_groups.rb new file mode 100644 index 0000000..d8022fd --- /dev/null +++ b/db/migrate/20151204132603_create_infrared_groups.rb @@ -0,0 +1,11 @@ +class CreateInfraredGroups < ActiveRecord::Migration + def change + create_table :infrared_groups do |t| + t.string :name + t.references :user, index: true, foreign_key: true + t.references :log, index: true, foreign_key: true + + t.timestamps null: false + end + end +end diff --git a/spec/factories/infrared_groups.rb b/spec/factories/infrared_groups.rb new file mode 100644 index 0000000..5399f0c --- /dev/null +++ b/spec/factories/infrared_groups.rb @@ -0,0 +1,6 @@ +FactoryGirl.define do + factory :infrared_group do + name "MyString" + end + +end diff --git a/spec/models/infrared_group_spec.rb b/spec/models/infrared_group_spec.rb new file mode 100644 index 0000000..7b14b28 --- /dev/null +++ b/spec/models/infrared_group_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe InfraredGroup, :type => :model do + pending "add some examples to (or delete) #{__FILE__}" +end From 4387bcb4d6b73f38cedd06ef22041c9e9ac53ce1 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Fri, 4 Dec 2015 22:28:16 +0900 Subject: [PATCH 091/358] rake db:migrate --- db/schema.rb | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/db/schema.rb b/db/schema.rb index dd2f7de..1919ee9 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20151204131528) do +ActiveRecord::Schema.define(version: 20151204132603) do create_table "auth_tokens", force: :cascade do |t| t.string "token" @@ -22,6 +22,17 @@ add_index "auth_tokens", ["user_id"], name: "index_auth_tokens_on_user_id" + create_table "infrared_groups", force: :cascade do |t| + t.string "name" + t.integer "user_id" + t.integer "log_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + add_index "infrared_groups", ["log_id"], name: "index_infrared_groups_on_log_id" + add_index "infrared_groups", ["user_id"], name: "index_infrared_groups_on_user_id" + create_table "infrareds", force: :cascade do |t| t.string "name" t.string "data" From 40491c3504dbb27be599d4cecb35b4f3a98c7e35 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Fri, 4 Dec 2015 22:32:16 +0900 Subject: [PATCH 092/358] :construction: rename tasks -> infrared_groups --- app/models/infrared_group.rb | 4 ++++ app/models/log.rb | 2 +- app/models/task.rb | 6 ------ app/models/task_infrared.rb | 4 ---- app/models/user.rb | 2 +- 5 files changed, 6 insertions(+), 12 deletions(-) delete mode 100644 app/models/task.rb delete mode 100644 app/models/task_infrared.rb diff --git a/app/models/infrared_group.rb b/app/models/infrared_group.rb index 09d6479..33e6815 100644 --- a/app/models/infrared_group.rb +++ b/app/models/infrared_group.rb @@ -1,2 +1,6 @@ class InfraredGroup < ActiveRecord::Base + belongs_to :user + has_many :task_infrareds + has_many :infrareds, through: :task_infrareds + belongs_to :log end diff --git a/app/models/log.rb b/app/models/log.rb index 26608bf..3b06f0c 100644 --- a/app/models/log.rb +++ b/app/models/log.rb @@ -1,5 +1,5 @@ class Log < ActiveRecord::Base belongs_to :user - has_many :tasks + has_many :infrared_groups has_many :infrareds end diff --git a/app/models/task.rb b/app/models/task.rb deleted file mode 100644 index 0ff5cc1..0000000 --- a/app/models/task.rb +++ /dev/null @@ -1,6 +0,0 @@ -class Task < ActiveRecord::Base - belongs_to :user - has_many :task_infrareds - has_many :infrareds, through: :task_infrareds - belongs_to :log -end diff --git a/app/models/task_infrared.rb b/app/models/task_infrared.rb deleted file mode 100644 index 17ca13d..0000000 --- a/app/models/task_infrared.rb +++ /dev/null @@ -1,4 +0,0 @@ -class TaskInfrared < ActiveRecord::Base - belongs_to :task - belongs_to :infrared -end diff --git a/app/models/user.rb b/app/models/user.rb index efdcde2..aad5e17 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -2,6 +2,6 @@ class User < ActiveRecord::Base has_many :auth_tokens, dependent: :destroy has_one :info, class_name: 'UserInfo', dependent: :destroy has_many :infrareds - has_many :tasks + has_many :infrared_groups has_one :log, dependent: :destroy end From 3066758dd4bac7b4e3bb281c5e8dfd70d17a1c03 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Fri, 4 Dec 2015 22:33:18 +0900 Subject: [PATCH 093/358] drop table --- db/migrate/20151204133102_drop_table_task_infrareds.rb | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 db/migrate/20151204133102_drop_table_task_infrareds.rb diff --git a/db/migrate/20151204133102_drop_table_task_infrareds.rb b/db/migrate/20151204133102_drop_table_task_infrareds.rb new file mode 100644 index 0000000..7501654 --- /dev/null +++ b/db/migrate/20151204133102_drop_table_task_infrareds.rb @@ -0,0 +1,5 @@ +class DropTableTaskInfrareds < ActiveRecord::Migration + def change + drop_table :task_infrareds + end +end From 9c22ca3b2d3c210477d1f9bf3415bf500f2c94d5 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Fri, 4 Dec 2015 22:33:23 +0900 Subject: [PATCH 094/358] rake db:mgirate --- db/schema.rb | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/db/schema.rb b/db/schema.rb index 1919ee9..d6b39e3 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20151204132603) do +ActiveRecord::Schema.define(version: 20151204133102) do create_table "auth_tokens", force: :cascade do |t| t.string "token" @@ -53,16 +53,6 @@ add_index "logs", ["user_id"], name: "index_logs_on_user_id" - create_table "task_infrareds", force: :cascade do |t| - t.integer "task_id" - t.integer "infrared_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - end - - add_index "task_infrareds", ["infrared_id"], name: "index_task_infrareds_on_infrared_id" - add_index "task_infrareds", ["task_id"], name: "index_task_infrareds_on_task_id" - create_table "user_infos", force: :cascade do |t| t.string "screen_name" t.string "hashed_password" From 8db1da37d583b1054bcf78c19d6681d6f96e0c2e Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Fri, 4 Dec 2015 22:34:30 +0900 Subject: [PATCH 095/358] rails g model InfraredRelational infrared:references infrared_group:references --- app/models/infrared_relational.rb | 4 ++++ .../20151204133422_create_infrared_relationals.rb | 10 ++++++++++ spec/factories/infrared_relationals.rb | 7 +++++++ spec/models/infrared_relational_spec.rb | 5 +++++ 4 files changed, 26 insertions(+) create mode 100644 app/models/infrared_relational.rb create mode 100644 db/migrate/20151204133422_create_infrared_relationals.rb create mode 100644 spec/factories/infrared_relationals.rb create mode 100644 spec/models/infrared_relational_spec.rb diff --git a/app/models/infrared_relational.rb b/app/models/infrared_relational.rb new file mode 100644 index 0000000..038f94e --- /dev/null +++ b/app/models/infrared_relational.rb @@ -0,0 +1,4 @@ +class InfraredRelational < ActiveRecord::Base + belongs_to :infrared + belongs_to :infrared_group +end diff --git a/db/migrate/20151204133422_create_infrared_relationals.rb b/db/migrate/20151204133422_create_infrared_relationals.rb new file mode 100644 index 0000000..ad0ae1b --- /dev/null +++ b/db/migrate/20151204133422_create_infrared_relationals.rb @@ -0,0 +1,10 @@ +class CreateInfraredRelationals < ActiveRecord::Migration + def change + create_table :infrared_relationals do |t| + t.references :infrared, index: true, foreign_key: true + t.references :infrared_group, index: true, foreign_key: true + + t.timestamps null: false + end + end +end diff --git a/spec/factories/infrared_relationals.rb b/spec/factories/infrared_relationals.rb new file mode 100644 index 0000000..0aae296 --- /dev/null +++ b/spec/factories/infrared_relationals.rb @@ -0,0 +1,7 @@ +FactoryGirl.define do + factory :infrared_relational do + infrared nil +infrared_group nil + end + +end diff --git a/spec/models/infrared_relational_spec.rb b/spec/models/infrared_relational_spec.rb new file mode 100644 index 0000000..297b009 --- /dev/null +++ b/spec/models/infrared_relational_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe InfraredRelational, :type => :model do + pending "add some examples to (or delete) #{__FILE__}" +end From 74a4b300282f3aee238d673f3c82e11defa196ae Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Fri, 4 Dec 2015 22:34:51 +0900 Subject: [PATCH 096/358] rake db:mgirate --- db/schema.rb | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/db/schema.rb b/db/schema.rb index d6b39e3..d22d20e 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20151204133102) do +ActiveRecord::Schema.define(version: 20151204133422) do create_table "auth_tokens", force: :cascade do |t| t.string "token" @@ -33,6 +33,16 @@ add_index "infrared_groups", ["log_id"], name: "index_infrared_groups_on_log_id" add_index "infrared_groups", ["user_id"], name: "index_infrared_groups_on_user_id" + create_table "infrared_relationals", force: :cascade do |t| + t.integer "infrared_id" + t.integer "infrared_group_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + add_index "infrared_relationals", ["infrared_group_id"], name: "index_infrared_relationals_on_infrared_group_id" + add_index "infrared_relationals", ["infrared_id"], name: "index_infrared_relationals_on_infrared_id" + create_table "infrareds", force: :cascade do |t| t.string "name" t.string "data" From 0becf5fb273373513adc332ba5daa11afda6956a Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Fri, 4 Dec 2015 22:36:54 +0900 Subject: [PATCH 097/358] rename task_infrared -> infrared_relational --- app/models/infrared.rb | 4 ++-- app/models/infrared_group.rb | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/models/infrared.rb b/app/models/infrared.rb index 920a46e..abfa3b8 100644 --- a/app/models/infrared.rb +++ b/app/models/infrared.rb @@ -1,6 +1,6 @@ class Infrared < ActiveRecord::Base belongs_to :user - has_many :task_infrareds - has_many :tasks, through: :task_infrareds + has_many :infrared_relationals + has_many :tasks, through: :infrared_relationals belongs_to :log end diff --git a/app/models/infrared_group.rb b/app/models/infrared_group.rb index 33e6815..abf66fb 100644 --- a/app/models/infrared_group.rb +++ b/app/models/infrared_group.rb @@ -1,6 +1,6 @@ class InfraredGroup < ActiveRecord::Base belongs_to :user - has_many :task_infrareds - has_many :infrareds, through: :task_infrareds + has_many :infrared_relationals + has_many :infrareds, through: :infrared_relationals belongs_to :log end From ea0a93ff8d1c07e9aea014163d4f5cc017fca836 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Fri, 4 Dec 2015 22:37:20 +0900 Subject: [PATCH 098/358] remove factories --- spec/factories/task_infrareds.rb | 6 ------ spec/factories/tasks.rb | 7 ------- 2 files changed, 13 deletions(-) delete mode 100644 spec/factories/task_infrareds.rb delete mode 100644 spec/factories/tasks.rb diff --git a/spec/factories/task_infrareds.rb b/spec/factories/task_infrareds.rb deleted file mode 100644 index fe4adbe..0000000 --- a/spec/factories/task_infrareds.rb +++ /dev/null @@ -1,6 +0,0 @@ -FactoryGirl.define do - factory :task_infrared do - - end - -end diff --git a/spec/factories/tasks.rb b/spec/factories/tasks.rb deleted file mode 100644 index 28cfd88..0000000 --- a/spec/factories/tasks.rb +++ /dev/null @@ -1,7 +0,0 @@ -FactoryGirl.define do - factory :task do - name "MyString" -user nil - end - -end From 9caa779b323135693f1b1bb5c83257fb6bcd09a4 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Fri, 4 Dec 2015 22:43:16 +0900 Subject: [PATCH 099/358] fix --- app/models/infrared.rb | 2 +- spec/models/task_infrared_spec.rb | 5 ----- spec/models/task_spec.rb | 5 ----- 3 files changed, 1 insertion(+), 11 deletions(-) delete mode 100644 spec/models/task_infrared_spec.rb delete mode 100644 spec/models/task_spec.rb diff --git a/app/models/infrared.rb b/app/models/infrared.rb index abfa3b8..518fed2 100644 --- a/app/models/infrared.rb +++ b/app/models/infrared.rb @@ -1,6 +1,6 @@ class Infrared < ActiveRecord::Base belongs_to :user has_many :infrared_relationals - has_many :tasks, through: :infrared_relationals + has_many :infrared_groups, through: :infrared_relationals belongs_to :log end diff --git a/spec/models/task_infrared_spec.rb b/spec/models/task_infrared_spec.rb deleted file mode 100644 index 353d44e..0000000 --- a/spec/models/task_infrared_spec.rb +++ /dev/null @@ -1,5 +0,0 @@ -require 'rails_helper' - -RSpec.describe TaskInfrared, :type => :model do - pending "add some examples to (or delete) #{__FILE__}" -end diff --git a/spec/models/task_spec.rb b/spec/models/task_spec.rb deleted file mode 100644 index 2c17e87..0000000 --- a/spec/models/task_spec.rb +++ /dev/null @@ -1,5 +0,0 @@ -require 'rails_helper' - -RSpec.describe Task, :type => :model do - pending "add some examples to (or delete) #{__FILE__}" -end From 9798db194265fe6d95473586036c246ce6e18c74 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Fri, 4 Dec 2015 22:57:11 +0900 Subject: [PATCH 100/358] resetting log model --- app/models/log.rb | 4 ++-- app/models/user.rb | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/models/log.rb b/app/models/log.rb index 3b06f0c..ea9868b 100644 --- a/app/models/log.rb +++ b/app/models/log.rb @@ -1,5 +1,5 @@ class Log < ActiveRecord::Base belongs_to :user - has_many :infrared_groups - has_many :infrareds + has_one :infrared_groups + has_one :infrareds end diff --git a/app/models/user.rb b/app/models/user.rb index aad5e17..30c6bfe 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -3,5 +3,5 @@ class User < ActiveRecord::Base has_one :info, class_name: 'UserInfo', dependent: :destroy has_many :infrareds has_many :infrared_groups - has_one :log, dependent: :destroy + has_many :logs, dependent: :destroy end From 226a8940c4d94b8f0dec52bdd833d3e57ac96607 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Fri, 4 Dec 2015 23:03:14 +0900 Subject: [PATCH 101/358] add column name to logs --- db/migrate/20151204140119_add_name_to_logs.rb | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 db/migrate/20151204140119_add_name_to_logs.rb diff --git a/db/migrate/20151204140119_add_name_to_logs.rb b/db/migrate/20151204140119_add_name_to_logs.rb new file mode 100644 index 0000000..c813240 --- /dev/null +++ b/db/migrate/20151204140119_add_name_to_logs.rb @@ -0,0 +1,5 @@ +class AddNameToLogs < ActiveRecord::Migration + def change + add_column :logs, :name, :string + end +end From 7ce0ce342ae8c59dca3737d70c3e20f625b2f20b Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Fri, 4 Dec 2015 23:03:21 +0900 Subject: [PATCH 102/358] rake db:migrate --- db/schema.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/db/schema.rb b/db/schema.rb index d22d20e..9685ee1 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20151204133422) do +ActiveRecord::Schema.define(version: 20151204140119) do create_table "auth_tokens", force: :cascade do |t| t.string "token" @@ -59,6 +59,7 @@ t.integer "user_id" t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.string "name" end add_index "logs", ["user_id"], name: "index_logs_on_user_id" From 36fc7d810451049ea70d5dda1c23456bb90af00c Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Fri, 4 Dec 2015 23:03:32 +0900 Subject: [PATCH 103/358] fix name --- app/models/log.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/log.rb b/app/models/log.rb index ea9868b..68487c1 100644 --- a/app/models/log.rb +++ b/app/models/log.rb @@ -1,5 +1,5 @@ class Log < ActiveRecord::Base belongs_to :user - has_one :infrared_groups - has_one :infrareds + has_one :infrared_group + has_one :infrared end From c6a56c4a1bb4fa652ef3298eeb20139c7662dbcc Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Fri, 4 Dec 2015 23:11:21 +0900 Subject: [PATCH 104/358] rubocop -a --- app/apis/api/v1/authorize.rb | 15 ++- app/apis/api/v1/raspberry.rb | 16 +-- .../api/v1/raspberry/commands/blink.jbuilder | 2 +- app/views/apis/api/v1/user/info/show.jbuilder | 2 +- db/schema.rb | 100 +++++++++--------- spec/factories/infrared_groups.rb | 3 +- spec/factories/infrared_relationals.rb | 3 +- spec/factories/infrareds.rb | 7 +- spec/factories/logs.rb | 1 - spec/models/infrared_group_spec.rb | 2 +- spec/models/infrared_relational_spec.rb | 2 +- spec/models/infrared_spec.rb | 2 +- spec/models/log_spec.rb | 2 +- 13 files changed, 75 insertions(+), 82 deletions(-) diff --git a/app/apis/api/v1/authorize.rb b/app/apis/api/v1/authorize.rb index 914b2e0..ad5e196 100644 --- a/app/apis/api/v1/authorize.rb +++ b/app/apis/api/v1/authorize.rb @@ -98,17 +98,17 @@ def find_user_by_identifier(identifier) requires :auth_token, type: String, desc: 'トークン' end delete '/logout', jbuilder: 'api/v1/auth/logout' do - if(token = AuthToken.find_by(token: params[:auth_token])) + if (token = AuthToken.find_by(token: params[:auth_token])) if token.user.info token.destroy else error!(meta: { - status: 400, - errors: [ - message: ('errors.messages.info_not_found'), - code: ErrorCodes::NOT_FOUND_INFO - ] - }, response: {}) + status: 400, + errors: [ + message: ('errors.messages.info_not_found'), + code: ErrorCodes::NOT_FOUND_INFO + ] + }, response: {}) end else error!(meta: { @@ -120,7 +120,6 @@ def find_user_by_identifier(identifier) }, response: {}) end end - end end end diff --git a/app/apis/api/v1/raspberry.rb b/app/apis/api/v1/raspberry.rb index 7198ebc..7fa2c0a 100644 --- a/app/apis/api/v1/raspberry.rb +++ b/app/apis/api/v1/raspberry.rb @@ -14,18 +14,18 @@ class Raspberry < Grape::API requires :auth_token, type: String, desc: 'Auth token.' end get '/commands/blink', jbuilder: 'api/v1/raspberry/commands/blink' do - if(token = AuthToken.find_by(token: params[:auth_token])) + if (token = AuthToken.find_by(token: params[:auth_token])) if token.user.info - path = File.join(Rails.root.to_s + "commands/blink.sh") + path = File.join(Rails.root.to_s + 'commands/blink.sh') `sudo sh #{path}` else error!(meta: { - status: 400, - errors: [ - message: ('errors.messages.info_not_found'), - code: ErrorCodes::NOT_FOUND_INFO - ] - }, response: {}) + status: 400, + errors: [ + message: ('errors.messages.info_not_found'), + code: ErrorCodes::NOT_FOUND_INFO + ] + }, response: {}) false end else diff --git a/app/views/apis/api/v1/raspberry/commands/blink.jbuilder b/app/views/apis/api/v1/raspberry/commands/blink.jbuilder index c3ea5aa..3d8891c 100644 --- a/app/views/apis/api/v1/raspberry/commands/blink.jbuilder +++ b/app/views/apis/api/v1/raspberry/commands/blink.jbuilder @@ -1,6 +1,6 @@ json.meta do json.status 200 - json.message "LEDを点滅させます。" + json.message 'LEDを点滅させます。' end json.response do end diff --git a/app/views/apis/api/v1/user/info/show.jbuilder b/app/views/apis/api/v1/user/info/show.jbuilder index 2b224f4..aebb8f7 100644 --- a/app/views/apis/api/v1/user/info/show.jbuilder +++ b/app/views/apis/api/v1/user/info/show.jbuilder @@ -1,6 +1,6 @@ json.meta do json.status 200 - json.message "ユーザー情報を取得しました" + json.message 'ユーザー情報を取得しました' end json.response do json.user @info diff --git a/db/schema.rb b/db/schema.rb index 9685ee1..0190e8b 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,74 +11,72 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20151204140119) do - - create_table "auth_tokens", force: :cascade do |t| - t.string "token" - t.integer "user_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false +ActiveRecord::Schema.define(version: 20_151_204_140_119) do + create_table 'auth_tokens', force: :cascade do |t| + t.string 'token' + t.integer 'user_id' + t.datetime 'created_at', null: false + t.datetime 'updated_at', null: false end - add_index "auth_tokens", ["user_id"], name: "index_auth_tokens_on_user_id" + add_index 'auth_tokens', ['user_id'], name: 'index_auth_tokens_on_user_id' - create_table "infrared_groups", force: :cascade do |t| - t.string "name" - t.integer "user_id" - t.integer "log_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + create_table 'infrared_groups', force: :cascade do |t| + t.string 'name' + t.integer 'user_id' + t.integer 'log_id' + t.datetime 'created_at', null: false + t.datetime 'updated_at', null: false end - add_index "infrared_groups", ["log_id"], name: "index_infrared_groups_on_log_id" - add_index "infrared_groups", ["user_id"], name: "index_infrared_groups_on_user_id" + add_index 'infrared_groups', ['log_id'], name: 'index_infrared_groups_on_log_id' + add_index 'infrared_groups', ['user_id'], name: 'index_infrared_groups_on_user_id' - create_table "infrared_relationals", force: :cascade do |t| - t.integer "infrared_id" - t.integer "infrared_group_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + create_table 'infrared_relationals', force: :cascade do |t| + t.integer 'infrared_id' + t.integer 'infrared_group_id' + t.datetime 'created_at', null: false + t.datetime 'updated_at', null: false end - add_index "infrared_relationals", ["infrared_group_id"], name: "index_infrared_relationals_on_infrared_group_id" - add_index "infrared_relationals", ["infrared_id"], name: "index_infrared_relationals_on_infrared_id" + add_index 'infrared_relationals', ['infrared_group_id'], name: 'index_infrared_relationals_on_infrared_group_id' + add_index 'infrared_relationals', ['infrared_id'], name: 'index_infrared_relationals_on_infrared_id' - create_table "infrareds", force: :cascade do |t| - t.string "name" - t.string "data" - t.integer "user_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.integer "log_id" + create_table 'infrareds', force: :cascade do |t| + t.string 'name' + t.string 'data' + t.integer 'user_id' + t.datetime 'created_at', null: false + t.datetime 'updated_at', null: false + t.integer 'log_id' end - add_index "infrareds", ["log_id"], name: "index_infrareds_on_log_id" - add_index "infrareds", ["user_id"], name: "index_infrareds_on_user_id" + add_index 'infrareds', ['log_id'], name: 'index_infrareds_on_log_id' + add_index 'infrareds', ['user_id'], name: 'index_infrareds_on_user_id' - create_table "logs", force: :cascade do |t| - t.integer "user_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.string "name" + create_table 'logs', force: :cascade do |t| + t.integer 'user_id' + t.datetime 'created_at', null: false + t.datetime 'updated_at', null: false + t.string 'name' end - add_index "logs", ["user_id"], name: "index_logs_on_user_id" + add_index 'logs', ['user_id'], name: 'index_logs_on_user_id' - create_table "user_infos", force: :cascade do |t| - t.string "screen_name" - t.string "hashed_password" - t.string "email" - t.string "email_for_index" - t.integer "user_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + create_table 'user_infos', force: :cascade do |t| + t.string 'screen_name' + t.string 'hashed_password' + t.string 'email' + t.string 'email_for_index' + t.integer 'user_id' + t.datetime 'created_at', null: false + t.datetime 'updated_at', null: false end - add_index "user_infos", ["user_id"], name: "index_user_infos_on_user_id" + add_index 'user_infos', ['user_id'], name: 'index_user_infos_on_user_id' - create_table "users", force: :cascade do |t| - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + create_table 'users', force: :cascade do |t| + t.datetime 'created_at', null: false + t.datetime 'updated_at', null: false end - end diff --git a/spec/factories/infrared_groups.rb b/spec/factories/infrared_groups.rb index 5399f0c..a0e91f8 100644 --- a/spec/factories/infrared_groups.rb +++ b/spec/factories/infrared_groups.rb @@ -1,6 +1,5 @@ FactoryGirl.define do factory :infrared_group do - name "MyString" + name 'MyString' end - end diff --git a/spec/factories/infrared_relationals.rb b/spec/factories/infrared_relationals.rb index 0aae296..e953f7e 100644 --- a/spec/factories/infrared_relationals.rb +++ b/spec/factories/infrared_relationals.rb @@ -1,7 +1,6 @@ FactoryGirl.define do factory :infrared_relational do infrared nil -infrared_group nil + infrared_group nil end - end diff --git a/spec/factories/infrareds.rb b/spec/factories/infrareds.rb index 11cf37c..05819f7 100644 --- a/spec/factories/infrareds.rb +++ b/spec/factories/infrareds.rb @@ -1,8 +1,7 @@ FactoryGirl.define do factory :infrared do - name "MyString" -data "MyString" -user nil + name 'MyString' + data 'MyString' + user nil end - end diff --git a/spec/factories/logs.rb b/spec/factories/logs.rb index 4e3e785..9627ea8 100644 --- a/spec/factories/logs.rb +++ b/spec/factories/logs.rb @@ -2,5 +2,4 @@ factory :log do user nil end - end diff --git a/spec/models/infrared_group_spec.rb b/spec/models/infrared_group_spec.rb index 7b14b28..e285c64 100644 --- a/spec/models/infrared_group_spec.rb +++ b/spec/models/infrared_group_spec.rb @@ -1,5 +1,5 @@ require 'rails_helper' -RSpec.describe InfraredGroup, :type => :model do +RSpec.describe InfraredGroup, type: :model do pending "add some examples to (or delete) #{__FILE__}" end diff --git a/spec/models/infrared_relational_spec.rb b/spec/models/infrared_relational_spec.rb index 297b009..315c612 100644 --- a/spec/models/infrared_relational_spec.rb +++ b/spec/models/infrared_relational_spec.rb @@ -1,5 +1,5 @@ require 'rails_helper' -RSpec.describe InfraredRelational, :type => :model do +RSpec.describe InfraredRelational, type: :model do pending "add some examples to (or delete) #{__FILE__}" end diff --git a/spec/models/infrared_spec.rb b/spec/models/infrared_spec.rb index 6e5d3f7..edad672 100644 --- a/spec/models/infrared_spec.rb +++ b/spec/models/infrared_spec.rb @@ -1,5 +1,5 @@ require 'rails_helper' -RSpec.describe Infrared, :type => :model do +RSpec.describe Infrared, type: :model do pending "add some examples to (or delete) #{__FILE__}" end diff --git a/spec/models/log_spec.rb b/spec/models/log_spec.rb index b3fe5ca..afb9cd7 100644 --- a/spec/models/log_spec.rb +++ b/spec/models/log_spec.rb @@ -1,5 +1,5 @@ require 'rails_helper' -RSpec.describe Log, :type => :model do +RSpec.describe Log, type: :model do pending "add some examples to (or delete) #{__FILE__}" end From 3375fe79bd6b3009566352869d67bff999cbeb6f Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Fri, 4 Dec 2015 23:40:45 +0900 Subject: [PATCH 105/358] bundle exec erd --- erd.pdf | Bin 33028 -> 33637 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/erd.pdf b/erd.pdf index 8984ac7dfe464823447496501310a3e1bc2489cb..a9db265fc9f733817d4ea8579ff3ddf617688c8a 100644 GIT binary patch delta 26743 zcmX_n18^q5(rvJ@ZEIuOPBylajcxPG#?}|xwry@~+qU)g{&nxG>ZM|d#?I` zL%9+Ft9c%=Nb;i+C$W*sv(fhl-cvHzwEn=`ysR4vS+ki(?c%AtxjpVGQT7-m>RYF03Zzj+?;&Y-RW7 zCBA-VZq1Xb4Z50(f3w(ej@G}LNm#@<6rLFXxI|?mteEOyoruz1K6W!_H_r@m+(f+r z!_bujHQ5ihp=SNOd!$kth$8HHA}0O9P}CQDw_U_A)>X@rD>Lo3QIzitYceN94>{NM z*qAk42s5xQJg3lMP5O$yABD!j-|=l@5{eiVK~69Wr%}mUsq3wGB9FIXaB*46D6sDU zxS>xd`b??oU!Wn}6&#! z>zIWxnQ;KrJ};Zwt_oaw`|e%)rtQ-yFoIlTmOEA>*#}@uWHd5jbPx2{6Zn>o5^E<#t}s;@U_<`EFo**Ls*M+p$yU!rJY$(PXZ{~ zD;`bX@x)K`*L(C=xt#p!jT^;puSMKRFh)8m1J7OOl>BtGj0xQh7ll=!0=Vk^1oYcK z>W`RVWHDSK#tw#-wk9v}go<-V0^qhpe>!W`+bA0KW;s6ULQ}cyAv~*~pq(@UGNLZ^ zIwk)$-@XyS_5el`jnGu%#*4^&z*8YJIDI04*fQlzqO&8of#DS{lil>g&EGL33x^{f zwko7GkC5dj7Q_P{DnY3ZSE7$CJAT-VIPHl_*v}sSHqsb}_XavgDM$XMjB~D67HK}t zblgenIY=Z#h%`J zD|1)u7j}Z<7|+FFbd6tj!;cU68F7>LD4bDVu0Xx*bNgmAI#ON=CdhrPUs3$-*ilb~ z_h7At@(lj#$~rpOZ-r2ajjl>vmt@fC^_YE7^rkA@bJUr1`~?tVBzRK*=~))|hTtDq z|91iG|8oHx={*nZY>1|5R6=54;c?P%3E^_glLV1W0k~x+5ACC$cpxQ`gl!rMT?^@1 z@^G2XjQWUpGw5n-7MVKOs0nq|6CSOTPBtMWCcofS!5oIQ zCgr>3C%)wd&+dK5eep3;uQJ_iirhX8*+tO1 zqc#2Yyx48C4N{;x?Q4j#e)Zd}zC@9T;OD~e6I&Ay$!<;Ni_zIYKk`fu#!|l@au{~F z8xn1-)`zGbAo3H#Wn!taRk5>ClfXfNFC8g>w*_0)cIGQ&t0HzlsDJ|IL*>I0Y0E}T zDTE-uk0D8>0c<@LVF}jUgvf}|7k0wjtbZ4JoQxRhh9e&Bf^reF5!+kT21z1!beBzf z!sg8qjPiw?z@~-E2|}s|e5}+VGRKfOKzw$LARmLloi(Gy{6WpOY^ch;11p4N^9%-woM!^>}vw5r)(C@2}-XqRb{Uajf zwS&Fz3uG8!;dU^%ffa*Y^8tj@51`A#L_sP{&Ar|)3DL&XC71#&b)8;;Yls72<<@i^ z9*FeMfIaX{-)fW)Bb492C3d7q6N2j?$2|t$USeglZ}8>_(IV7cJZ{fWD6 zbbMIHA@FIJ=`4pts3IkDpuD64++!nQApwngfaY2TW=yAbih__o$Yy*yk1M7WzaYdc z%lOAkX|KbgibydoQs_I`mB#~EA?U-U;>XtlE)Y$@3{c?$TPvr7Fgk_BjVNr?kOVQX zjKLHA&YR0O!8(Z{f=h&5V^Mo;SxE(3pl28TbjS%(u>z?fa8~&j^Ha&v-~tgFBT%7| z0lOS*TTxu_C3AkghjhU(G!kx}7*v62dvCvu5?GwKi#kNBzru1@ATmI~6Ii#6(Z;bg zYE??G16EnrF!zd}{@^by?P1Y!@DB$juF>A(;GpLtkiPDyi(?gX)R!RB&%up3GeVPN zxTsYj`6ts`{P10ujxdaim3E*wlE$)*0KgzNZJKG+vUy@Y7pvS8sv&tr`|K{LMz-k4 z+j3?NJG=PW*tYU2(cm0WXzLRnq)L3%cgWFZRc3Nt1teb$f|rcuugGRB;WB2 z_kdNt&*@=_Bi<-SlD0v<<R9N=q{I7*voDx&S&Oe@lZzBMg#(8A_7M8kfi z#VIIYknC{OlKg7so293sqT;U71Ngkp;HezfKX&g}Bs}V;$L{yM?7P8*aCwVoTyzU( zEQkDr$JU3LDIhnYRY`8L^UgbevOJ7T3ef1S)e~#Hz2d6E=q(EhFDwgMWli!ARbnLZ z%j>PVj?^VNh`={CMHYk%EP$@p!`jAr;TOyFr8bfkQ>KCcaN6mIbKb>^1T3F**!{7F z`YM$khA{IdCnqitt`02h=iR4)r5weHN8GJI+E!U5vmG3fQHRqq5dPAQpCsL5d_iZc z&$a(XiuD)4fHk!MtOjOD)=A0IKJs;7e~F{7fP zxhZf5MjVv8ff6Gc+FLY#XhK283xS=nz83A_ccrQ<^}S-L2Y@^%`~ z#MOIK21g4}w=ZXD?N#ECi8C41Ns&n{gFJyCf|=Ay{S~f=ae>Q4tA%nvc0kWX4oGZ~ z0I>$?02u*|NTd(;A~ozP7J}W`0$Dmw^f^E$hKQ5Gwq*Xz@f!uO!_dp%Px^M7&hAg| zALu_15{#Wtb9|*dvAOJ=G5S=ksYV)Mdurqy`SYr)k~(WTGh@n{@t1prtUI1Tay20@ zMHUu%k+XYcAzI+|;swPgyZ%_DxEJ$nlN7agI2SdAVZF{@a%m7ClbVvT)K%B(ZGs*Y zMVex`bRr$au4)fJ%=@A`0XMp6g?f+D@QE5vs-^Z%7ox^kb$aA#&KO~@u>as!)Vc4I zz-oVtb2?cSV4pD^?TOsMS_U9bq@&`=?XKE>hiO82npI^IdsbhS!nW43>z1knx3U=tIMg zRgYG4vF<$!_>(H^xo;svQQc9oN=ERq(^kj03#&a@Y&$qDe%U7h&Aq5Hvtje zb<5-EMrYc~%KR*inW-O_@Uv6+YnC%p$ERX(`9R#R?Vsw{eruj#ZeKxe)g@VufHj0fD z2RD57_J*$Qe9iSHa+B~+q;@_iHXiZ#;G@51B9RNQm`5YAr@|X?YoTY5xFDoJ(I2J; zc&<>(&@7pA|ADm-4zRglrH%j? zkK}A3ufbWFyE4V^8L&5ds*;uP}$hfy}m<=1G~){fr7?Y$?y3%&s8yI#Zk;&UPW zkS>h{<;U?7_z0ECk@fDk&pk@>-CY)K2?6MBm`hB;-3mlp2#L9D5~X8*jgic{(&7?c zz-*5;`0nC~%n#6t=I8NmIt+Ow!kc^O`xtsa4p$)1BjTMiA9XvpovQLiCFKx=0Fw)+b0EMBabgWjWU?|lFiMz+JJb67pl%dc?Fm|7 zj3J+%ihWYDz3MNd<_V_Ud@S_qOFS49^UX<5PoYy-pjzZk;dBG2c$uSF0c|9SDBy74 zEh02*;V3s%@Sf3r>8)Qu-}x*w^QNbVZF|c#^{nx)sxenR36fXk*Eez8K2CqLr{7T3 z1D}_s?PUeBHWTS~rD!_J1YS2^aVkorK)1tR@kob`pRp)a%Q`px0xqRz9LPh4?xlGPp30ny|^R{;R&(B5_Ss-$pUDzVD?8Nhi?hlM@oDSI09! z6HQK9$K}@?;*Jx4v6(D_eSrKeB~*FVfZP`z)gdI(3{_}`i)u%{ij>j7@FQM$kDaIO zn?1i@=~``k18Eke$0pz-PeyOfqT;aI)wkXO;OATKb=5y?rzUP|ZHsnBBY9T2)ZVQM zXm_Hcq4kuM=2?zkR=eeiG;Q4nq(CrJsRr`A?^^Knq~LP9fNO1&Q#hYtF{K7TzzK&O z1xG{e$lS^q`J!RAW>cQL#m~O*{E(kx|1qvF2!_XjXgtuk!ju_VeU3(6=NCjyHbB7z zs1qZ#Xd(ffH{%fk^QW6fBPSk#nG!6E1*P&7XykKEXt~e)gb1m&$AI&)*YC3o~VSOcBjj^>Qv9hDMcSuwG=Es$K+%vgj;+O~>GkoZZ+K@s- zW_&CWAki7+IDKxl#;XJJDT^M(u^%7;yriwjEGb70GNicMf^_AU=B8AQ&!!eO%SJ|H zNBvGU%7l$5v`k>C2g(%W0J2@8!#gqFqu>YFUF&yr%r}Yh4!bLj5NBXqc*fb;OU#M^h-i%2 zbua}2LSCZ+y1obI2ewwMS@QhJJaS-#VY)$&4++~dewG#v=ZfqnW?)GYK-k7gl5cT+ z5=qO%ugoguRapwkfrqMv^Fh&JAmqdo%*HFqCshZ^GUlnNr?wTWqd&v;?gC{G`Sm=V zwygQQ%&J9m$fu&Vrj`c3(*VD{xA~=3HFmx1Y zbh?ayHhSjqVf{hw4K(8~W?kq?PSN$4!dQ>WdhHqQsFf3xXUGSz{Zx!6MPEK;cG89S z6Vcb7uvqd`T73YsHt8a_X$XLK(9M8no}08T?VcZbTkL)#b1qgO7MX4M(!K&v_~y@nsZ9ElJF(m zW3pnI)*s;D*9wPjdcI@m7welt(C3=?8STsPTF6IDA{SR)NNI^+)}*%{{rNeFq!kh zg>%Q6qOG8F;4NcRX1Vs_bYwi%bFN|~&}dPVBvNDinlHjE(^~@&>rrjeQWPy0x)%w` zm>1PJ6q(2&j(a-k%8$+;ir-1RhTe_bjTD>BR}>>*$Z1t=mvI?fubQU@m ze9z90)TNFi547&^$!|7d2~(PXxz05l$g9&pIRw2T9C)H=(M+1esXmc!_Sxlj(QP+M zrwvlhY8^DN<9ur{-}*HCV;*|R95pXnk`&RL^obDw=u_lO+jbqISjfbAf-UpDC`zKlLh0spqz0!Qj%7*ZBq+Bzhm^p$-St<$3_e{IbS@P(cGt-#=*HsbU6;Z&~JOV!l-KgL(cBEnV#N=;UX-jDV#>>vDD zP&+tV*ffE^=zCf)i+Uk{joT2nJ}5ZFO>NLPg5vYX(`$AcZm%M_VowQg$#IsReYc;q>?-W=kl~FdD-Q( zBOeLLoK+MG`&G%tl`BSV?!aE-tw?RH!1(0nwhgd(O~O`0+K4!3B~SgT}A3of}eIRJ`aDurIz_vI-&V zMZ5q4w+yw0RJ9>;nW%*P_LIgXDVDAD#Qj+u*5MncMg$DoW3@&~veNXYNr5rwo*D$X z?Gww~WBq#vax}tSt%ktt`?LRf~MJGDJP*FR)}tu9k-pf zwpJ45V*_A58-J*PGH@%A%q>k;%>y9xjYJ5Q4yo{CsIJFOyZZ6RZObH*E`${!{J zJyT9HGv4IXiHM~o3UH;32*W~6z4f_+%(iIProN4hVrFq^9#?4>#{>rjYLfQ2vOQ*L zQ!8bR*l@bgSRi?eczfhqhu!u3*xpi*t)+{lj zYTeJzTJfy>o-y`jN>6W{Y;4mRZ@PmsbzIWIsvo;GWvIBxO>UsT9;)Q5jWOF~JslV5 zf=385!a}K@q;Ifx9^F(OMovFVJ!`5*tKFAgSxuhiu4kv9o?IvBnrX5q-j2y8;S5~t zvry5oEnOFFKhkUA{4EByZG)q-PzC6i3%YdU3Ps8I^eH3|Q)q#abvf4j>~u~n@`;&^ z+<~DalOau&Hb%Ej9|b;z7g~>rF@f|@Msy^|^u-@ak1s4SbR{eshqGBmoX$!u3qq3< z^W3!9FEt`8|789o3gUF)=BBceUgHR$LJK!BB*8*)rSXX1md8AVF^;G{H3rO{XcHWp z`&ke>3#~U7|22vekR%LJ#t=yi4hVCM| z&Xhcny7m(S=ZtGOAi+Y;dlW#Xx5L1>mf!>rh(JCo@-4?vrna&$(N?z4ikHu5+}JS8 zdIfAQr0`5$qpmKuATW|?rD11Vc&&{|Z~p`sdo?qZ`GLwJ2AXd#7Woz+Zhd-em#oXvDE({apY_sMDSNn?@Ebu8Ke?w#W-XPn{5;Ob6rYx6ir7Qy@9j!6~ zeQK0__egaBe4*+U*-1%SEp*Z3*vF-?| zPXipvJBskp&s>GGPm&i7QGoa~-GD>|%s9&~I%m^xPHIukj3DU{E7Wi-kn+GR1%2l_7FGlX=-^W8Af&$IRyK98lJZ@ zywevDJqRQ|0uuS1RSnKeY8K1c&_S5N@V)tN9!h=x97}egbFrMcr(MUeEPGkX8=OV$ z)~_Z)wq%r0;wezwC~AX`^mo?^DyeF!lW3spkx&0@U)V@&o$KUtjJEB#TyCDe%%Rdf zG)1I2A9^+IPSB10chuPnR!TNd6Jt^WsA#!rDgT zR1>NJcoQHlAz#aMwJ8wqduACQo2uLpir z#BR0kpK`Ykr96v_w!9RvPf}E*FnW_``>G5ynm13b@r>`+njeldR*dMbEbLylR&4<+ zIy^3l=MC&S97uiLRi%j78$2Y=4;vUeF)D;es!oM)`VRVlRRUr@%d%jqxCj7sYWne;Y_XCDqBBMh@RalGP zj?5>Xo6H*D2#t`Wk=BUjiN@>GE2Z; z?BkuIog-D8l%ew+H@W($79%V#$vegzop2!sPaFG-qb8Vx%8q#_L;~&uG!44hQHIwA zf0gyM$ssV1xIi9rOzv%-i04gwkkKGiEYheDbOOt7<;xX?TzzUUC;%d15SoBY%-Cet zfnt0^)9z#VN?stgCe;$6qk|gyIX%_Qhw@-;Nm~# zBgi^V@iuF}`HGoW2^&&YtuFz^FxfD9<11jc+2(#HG|dYOc3OLu2#=u#oL%v^b~^)6 zNc<%}00f^@U%pIO?}1%0^`sV>3IS_d4|7d|@w-dot|Xg)uI$Ct5>EzLy<$D9p1)st zcXiKjUc-6wvSWseS>({34k+|!XV;8HSsOKF z=b%v-Id$h3q4F6MhUDKFwF*|mB{qmH2LoQ~bIi`a9mIn3rU}&E`~@^!1MVv$0wb*% z%&{MmTn^-S)?i)bSSJ8#XZa!&REdsL(rD`jYj?xL7&Y4qUiPew{b zi;{}jliez~f$P$BHpIhxF{Ys&+B<&Z55dPa$$VRSIM_txj?;jNa+pb1PN<{cwT+5~ zHIa-&xis@tt)3YF-1)2f$=hbH<-J9Z(KeOsDptLeKoU6$s2zGCqu}`Bji9s4E1t&v zY

-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 Z8acaqI-8lJ0lEG>^=Nc-;))Vz{{fxu@pu3L From 36e5039ec028393e9345c90aef79d0e7d00cf57d Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sat, 5 Dec 2015 02:53:41 +0900 Subject: [PATCH 106/358] add wiring pi --- Gemfile | 1 + app/apis/api/v1/raspberry.rb | 15 +++++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/Gemfile b/Gemfile index 1d7aeba..72e0b63 100644 --- a/Gemfile +++ b/Gemfile @@ -37,6 +37,7 @@ gem 'grape-jbuilder' gem 'grape-swagger' gem 'grape-swagger-ui' gem 'haml-rails' +gem 'wiringpi2' gem 'rubocop', group: :development group :development, :test do diff --git a/app/apis/api/v1/raspberry.rb b/app/apis/api/v1/raspberry.rb index 7fa2c0a..1ee4eba 100644 --- a/app/apis/api/v1/raspberry.rb +++ b/app/apis/api/v1/raspberry.rb @@ -16,8 +16,19 @@ class Raspberry < Grape::API get '/commands/blink', jbuilder: 'api/v1/raspberry/commands/blink' do if (token = AuthToken.find_by(token: params[:auth_token])) if token.user.info - path = File.join(Rails.root.to_s + 'commands/blink.sh') - `sudo sh #{path}` + # path = File.join(Rails.root.to_s + 'commands/blink.sh') + # `sudo sh #{path}` + io = WiringPi::GPIO.new do |gpio| + gpio.pin_mode(0, WiringPi::OUTPUT) + # gpio.pin_mode(1, WiringPi::INPUT) + end + + # pin_state = io.digital_read(1) # Read from pin 1 + # puts pin_state + + io.digital_write(0, WiringPi::HIGH) # Turn pin 0 on + io.delay(100) # Wait + io.digital_write(0, WiringPi::LOW) # Turn pin 0 off else error!(meta: { status: 400, From b389aad4ec451d3c55a1ab8ea8a7472300372228 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sat, 5 Dec 2015 03:02:20 +0900 Subject: [PATCH 107/358] require 'wiringpi' --- app/apis/api/v1/raspberry.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/apis/api/v1/raspberry.rb b/app/apis/api/v1/raspberry.rb index 1ee4eba..4a36918 100644 --- a/app/apis/api/v1/raspberry.rb +++ b/app/apis/api/v1/raspberry.rb @@ -1,4 +1,5 @@ # app/apis/api/v1/raspberry.rb +require 'wiringpi' module API module V1 From cb4d7aa5cba0990000a5f72ff06efee688b71651 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sat, 5 Dec 2015 10:42:59 +0900 Subject: [PATCH 108/358] remove require 'wiringpi' --- app/apis/api/v1/raspberry.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/app/apis/api/v1/raspberry.rb b/app/apis/api/v1/raspberry.rb index 4a36918..1ee4eba 100644 --- a/app/apis/api/v1/raspberry.rb +++ b/app/apis/api/v1/raspberry.rb @@ -1,5 +1,4 @@ # app/apis/api/v1/raspberry.rb -require 'wiringpi' module API module V1 From 863fbb79623adac08ab5885db3b73cf4b84f8445 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sat, 5 Dec 2015 11:40:43 +0900 Subject: [PATCH 109/358] vagrant up --- .ruby-version | 1 + .../default/virtualbox/action_provision | 1 + .../default/virtualbox/action_set_name | 1 + .../machines/default/virtualbox/creator_uid | 1 + .vagrant/machines/default/virtualbox/id | 1 + .../machines/default/virtualbox/index_uuid | 1 + .../machines/default/virtualbox/private_key | 27 ++++++++ .../default/virtualbox/synced_folders | 1 + Vagrantfile | 24 ++++++++ provision/chruby.sh | 29 +++++++++ provision/foreman.sh | 10 +++ provision/limits.sh | 61 +++++++++++++++++++ provision/mysql-server.sh | 13 ++++ provision/postgresql-server.sh | 16 +++++ provision/rails.sh | 10 +++ provision/redis.sh | 8 +++ provision/ruby-install.sh | 20 ++++++ provision/ruby.sh | 13 ++++ 18 files changed, 238 insertions(+) create mode 100644 .ruby-version create mode 100644 .vagrant/machines/default/virtualbox/action_provision create mode 100644 .vagrant/machines/default/virtualbox/action_set_name create mode 100644 .vagrant/machines/default/virtualbox/creator_uid create mode 100644 .vagrant/machines/default/virtualbox/id create mode 100644 .vagrant/machines/default/virtualbox/index_uuid create mode 100644 .vagrant/machines/default/virtualbox/private_key create mode 100644 .vagrant/machines/default/virtualbox/synced_folders create mode 100644 Vagrantfile create mode 100644 provision/chruby.sh create mode 100644 provision/foreman.sh create mode 100644 provision/limits.sh create mode 100644 provision/mysql-server.sh create mode 100644 provision/postgresql-server.sh create mode 100644 provision/rails.sh create mode 100644 provision/redis.sh create mode 100644 provision/ruby-install.sh create mode 100644 provision/ruby.sh diff --git a/.ruby-version b/.ruby-version new file mode 100644 index 0000000..b1b25a5 --- /dev/null +++ b/.ruby-version @@ -0,0 +1 @@ +2.2.2 diff --git a/.vagrant/machines/default/virtualbox/action_provision b/.vagrant/machines/default/virtualbox/action_provision new file mode 100644 index 0000000..4b01913 --- /dev/null +++ b/.vagrant/machines/default/virtualbox/action_provision @@ -0,0 +1 @@ +1.5:9313ad11-54f8-413e-8d21-0bb472f6b228 \ No newline at end of file diff --git a/.vagrant/machines/default/virtualbox/action_set_name b/.vagrant/machines/default/virtualbox/action_set_name new file mode 100644 index 0000000..04c8368 --- /dev/null +++ b/.vagrant/machines/default/virtualbox/action_set_name @@ -0,0 +1 @@ +1449280828 \ No newline at end of file diff --git a/.vagrant/machines/default/virtualbox/creator_uid b/.vagrant/machines/default/virtualbox/creator_uid new file mode 100644 index 0000000..ec52cb8 --- /dev/null +++ b/.vagrant/machines/default/virtualbox/creator_uid @@ -0,0 +1 @@ +501 \ No newline at end of file diff --git a/.vagrant/machines/default/virtualbox/id b/.vagrant/machines/default/virtualbox/id new file mode 100644 index 0000000..0292b61 --- /dev/null +++ b/.vagrant/machines/default/virtualbox/id @@ -0,0 +1 @@ +9313ad11-54f8-413e-8d21-0bb472f6b228 \ No newline at end of file diff --git a/.vagrant/machines/default/virtualbox/index_uuid b/.vagrant/machines/default/virtualbox/index_uuid new file mode 100644 index 0000000..7b5aa61 --- /dev/null +++ b/.vagrant/machines/default/virtualbox/index_uuid @@ -0,0 +1 @@ +e735aec682ff40739f5ff3b1bdb81964 \ No newline at end of file diff --git a/.vagrant/machines/default/virtualbox/private_key b/.vagrant/machines/default/virtualbox/private_key new file mode 100644 index 0000000..ef139d1 --- /dev/null +++ b/.vagrant/machines/default/virtualbox/private_key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEApphMBFF7LeGQZfz89dJhgEl3Wz31aTTyY1BdSIQCJvc/cqW4 +5yvNaKJZsyVzMvb9RaKE6nJMbqujC/lT1JpPsYZ/0+MRSfxtP2u1KRGIgF8iFvwX +Eska5FQngTqW3delrVN7LQHYllKrGDBerjl+j3pp4+KKHj4c779EwkaKWhnsp+xq +Gq1v/gao+UPTzxIhGeoPxDOBZG3s6bi3BxoHrd2OJEwOyDl1Ju6zAZjchcXGbGO0 +RESm+i1sc2IaoDhdjX2fLn4FZOtEBDjJnF2V5pol1rTKaV/+HyEvfXLIYDItxPyA +iriLGe0G+derZUHc075VRYgiDKi4diZ4GSuRuwIDAQABAoIBAC7WGGEKa2Adz1Pt +CU0vJXxEq0q6o5k9anvjZyZw/o3n6y2XS+GqHeix5BgKilWkvNXr+ARVuAlRNdiy +8w+NhqQ5VQzEBONRFYHEDT2LkV3N4S6nFvGQGoBg7G5Xg3zBGPIeyz1/DF5OxY1a +Y/QFdABwgP6xfPU9rzL0Cie4X0MvHImiLGF4HJCckhL5acKoNWCBF4hRpnydfbj2 +pyaWeU9fA12Rx/3yHBY7V0UvnAUZ/yJOdEisG2BrkLYx9ffKjZqZWiMHF8Mq3En/ +mB19dqKQE9SSZZGe/Oj6vqwCcnWrtDv/8nEw0ktQlxMO9kI/CQBxfrSulfHy1zRy +lis2xFECgYEA0QqPk5g+OAVIf6i9NYXqlozhvVMzx8r+TPX+ccrKf1y8m+dXFgJX +Wd7Qaog/zm4gBi0soZXavJLGqUTLRVuK6Zx6yVz34MePKBBG4SvbVRJY4uKYlGRA +aHDiP9EDY8ol1kptDZux7oRsq7j861begxI20g4fdtqx2+1ZnebWz4MCgYEAzATA +zmZ4+Mx5YDBeNDBeIYPXigMputF/0hqK7nMEaHzOtdiRzSKcibxPK3EYrjZ26RPi +i+uHW1CBL/LnhzNNd21A2TssCtLQ3pIIzdEtJlUkJdYU7bNcxGg86Zrw0w6Xeq1B +9H6wFgDSUA886HiwMh+HxkRo5W6dhRSbL57mp2kCgYEAwR5RkBgo+tYeqRk5W3YR +R+51KdPw1VX6Yx0raPLg6pLBCALL2GBnVHZc8t5WnB3u5eXcApePkYDDmWMdq0Cr +77AJW3fQ5E9YOLn40VMT+N7PUSPns8d+HT6UNkKhMBJzrCnr35OD6Qdb4bUvqzcA +r/Qmwx4bAVF+2N/IV/EHaIMCgYBZOo709p5b+lnvdtgMrUbOE7KWGvIKUgw8YP14 +cndwF330zGZgOI4MM37QuiMYNpvlLpw7o+RMTLZjuTIH0KlF3VOqbpXBmhhd77LI +CX9cr4oivjHjEDo3cHuLlAdV16Dqt5IME8iBpxRUjYWPCxHMqjugvFTAW5OrG6sP +tcidWQKBgQDOrRzQ2iHO+jUNGMI6u6B2hAdXvhykgnTCB2zY7rM05XTuh6kjxT67 +GaPy3pSgK0mSbkZeT81aQLT2v/LLtoP0gCs4GgSfANJchXwUSJLYqtk92A0askVo +JRYpyGrKWHb+AS9LeesOekSYVcH3E4aHNADNikYL1BP0DPhL7M2AOQ== +-----END RSA PRIVATE KEY----- diff --git a/.vagrant/machines/default/virtualbox/synced_folders b/.vagrant/machines/default/virtualbox/synced_folders new file mode 100644 index 0000000..3f30c24 --- /dev/null +++ b/.vagrant/machines/default/virtualbox/synced_folders @@ -0,0 +1 @@ +{"virtualbox":{"/vagrant":{"guestpath":"/vagrant","hostpath":"/Users/gamerinshaft/rails_app/switch_api","disabled":false}}} \ No newline at end of file diff --git a/Vagrantfile b/Vagrantfile new file mode 100644 index 0000000..950f7cf --- /dev/null +++ b/Vagrantfile @@ -0,0 +1,24 @@ +Vagrant.configure("2") do |config| + config.vm.box = "centos.for.Switch" + config.vm.box_url = "https://github.com/2creatives/vagrant-centos/" + + "releases/download/v6.5.3/centos65-x86_64-20140116.box" + config.vm.provider :virtualbox do |vb| + vb.customize [ 'modifyvm', :id, '--memory', 1024 ] + end + config.vm.network "forwarded_port", guest: 3000, host: 4000 + + config.vm.provision :shell, inline: "yum -y update" + config.vm.provision :shell, inline: "yum -y install wget" + config.vm.provision :shell, inline: "yum -y install tmux" + config.vm.provision :shell, inline: "yum -y install graphviz" + + config.vm.provision :shell, path: "provision/chruby.sh" + config.vm.provision :shell, path: "provision/ruby-install.sh" + config.vm.provision :shell, path: "provision/ruby.sh" + config.vm.provision :shell, path: "provision/rails.sh", privileged: false + config.vm.provision :shell, path: "provision/foreman.sh", privileged: false + config.vm.provision :shell, path: "provision/mysql-server.sh" + # config.vm.provision :shell, path: "provision/postgresql-server.sh" + config.vm.provision :shell, path: "provision/redis.sh" + config.vm.provision :shell, path: "provision/limits.sh" +end diff --git a/provision/chruby.sh b/provision/chruby.sh new file mode 100644 index 0000000..0f8fd57 --- /dev/null +++ b/provision/chruby.sh @@ -0,0 +1,29 @@ +#!/bin/bash + +version="0.3.8" + +if [[ -d /usr/local/share/chruby ]]; then + source /usr/local/share/chruby/chruby.sh + current_version=$(chruby --version) +fi + +if [[ "${current_version}" != "chruby: ${version}" ]]; then + mkdir -p /opt/src + cd /opt/src + wget -O chruby-${version}.tar.gz \ + https://github.com/postmodern/chruby/archive/v${version}.tar.gz + tar xzf chruby-${version}.tar.gz + cd chruby-${version}/ + make install + cd .. + rm chruby-${version}.tar.gz + rm -r chruby-${version}/ +fi + +if [ $(grep -c chruby.sh ~vagrant/.bashrc) -eq 0 ]; then + echo 'source /usr/local/share/chruby/chruby.sh' >> ~vagrant/.bashrc +fi + +if [ $(grep -c auto.sh ~vagrant/.bashrc) -eq 0 ]; then + echo 'source /usr/local/share/chruby/auto.sh' >> ~vagrant/.bashrc +fi diff --git a/provision/foreman.sh b/provision/foreman.sh new file mode 100644 index 0000000..86e00cc --- /dev/null +++ b/provision/foreman.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +version="0.78.0" + +source /usr/local/share/chruby/chruby.sh +chruby $(cat ~/.ruby-version) + +if [[ ! -d ${GEM_HOME}/gems/rails-${version}/ ]]; then + gem install foreman --version=${version} --no-ri --no-rdoc --verbose +fi diff --git a/provision/limits.sh b/provision/limits.sh new file mode 100644 index 0000000..b53ff78 --- /dev/null +++ b/provision/limits.sh @@ -0,0 +1,61 @@ +#!/usr/bin/env bash + +cat > /etc/security/limits.conf < +# +#Where: +# can be: +# - a user name +# - a group name, with @group syntax +# - the wildcard *, for default entry +# - the wildcard %, can be also used with %group syntax, +# for maxlogin limit +# +# can have the two values: +# - "soft" for enforcing the soft limits +# - "hard" for enforcing hard limits +# +# can be one of the following: +# - core - limits the core file size (KB) +# - data - max data size (KB) +# - fsize - maximum filesize (KB) +# - memlock - max locked-in-memory address space (KB) +# - nofile - max number of open file descriptors +# - rss - max resident set size (KB) +# - stack - max stack size (KB) +# - cpu - max CPU time (MIN) +# - nproc - max number of processes +# - as - address space limit (KB) +# - maxlogins - max number of logins for this user +# - maxsyslogins - max number of logins on the system +# - priority - the priority to run user process with +# - locks - max number of file locks the user can hold +# - sigpending - max number of pending signals +# - msgqueue - max memory used by POSIX message queues (bytes) +# - nice - max nice priority allowed to raise to values: [-20, 19] +# - rtprio - max realtime priority +# +# +# + +#* soft core 0 +#* hard rss 10000 +#@student hard nproc 20 +#@faculty soft nproc 20 +#@faculty hard nproc 50 +#ftp hard nproc 0 +#@student - maxlogins 4 + +* soft nofile 4096 +* hard nofile 4096 + +# End of file +""" +EOF + +ulimit -n 4096 diff --git a/provision/mysql-server.sh b/provision/mysql-server.sh new file mode 100644 index 0000000..b891952 --- /dev/null +++ b/provision/mysql-server.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +password="password" + +if [[ ! -f /usr/sbin/mysqld ]]; then + rpm -Uvh http://dev.mysql.com/get/mysql-community-release-el6-5.noarch.rpm + sed -i -e "19c enabled=1" /etc/yum.repos.d/mysql-community.repo + sed -i -e "27c enabled=0" /etc/yum.repos.d/mysql-community.repo + yum install -y mysql-server mysql-devel + service mysqld start + chkconfig mysqld on + mysql -u root -e "SET PASSWORD FOR 'root'@'localhost' = PASSWORD('${password}')" +fi diff --git a/provision/postgresql-server.sh b/provision/postgresql-server.sh new file mode 100644 index 0000000..9d72835 --- /dev/null +++ b/provision/postgresql-server.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +if [[ ! -d /usr/lib/postgresql/9.3/ ]]; then + rpm -Uvh http://yum.postgresql.org/9.3/redhat/rhel-6-x86_64/pgdg-centos93-9.3-1.noarch.rpm + yum install -y postgresql93-server postgresql-devel + service postgresql-9.3 initdb + service postgresql-9.3 start + chkconfig postgresql-9.3 on + su - postgres -c " + psql -c \"UPDATE pg_database SET datistemplate=false WHERE datname='template1'\" + psql -c \"DROP DATABASE template1\" + psql -c \"CREATE DATABASE template1 WITH TEMPLATE = template0 ENCODING = 'UTF8'\" + psql -c \"UPDATE pg_database SET datistemplate=true WHERE datname='template1'\" + createuser -d -S -R vagrant + " +fi diff --git a/provision/rails.sh b/provision/rails.sh new file mode 100644 index 0000000..ae15365 --- /dev/null +++ b/provision/rails.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +version="4.2.1" + +source /usr/local/share/chruby/chruby.sh +chruby $(cat ~/.ruby-version) + +if [[ ! -d ${GEM_HOME}/gems/rails-${version}/ ]]; then + gem install rails --version=${version} --no-ri --no-rdoc --verbose +fi diff --git a/provision/redis.sh b/provision/redis.sh new file mode 100644 index 0000000..e17a128 --- /dev/null +++ b/provision/redis.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +sudo rpm --import http://rpms.famillecollet.com/RPM-GPG-KEY-remi +sudo rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-6.rpm + +sudo yum -y install redis --enablerepo=remi +sudo chkconfig redis on +sudo service redis start diff --git a/provision/ruby-install.sh b/provision/ruby-install.sh new file mode 100644 index 0000000..f1a794b --- /dev/null +++ b/provision/ruby-install.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +version="0.4.1" + +if [[ -f /usr/local/bin/ruby-install ]]; then + current_version=$(ruby-install --version) +fi + +if [[ "${current_version}" != "ruby-install: ${version}" ]]; then + mkdir -p /opt/src + cd /opt/src + wget -O ruby-install-${version}.tar.gz \ + https://github.com/postmodern/ruby-install/archive/v${version}.tar.gz + tar xzf ruby-install-${version}.tar.gz + cd ruby-install-${version}/ + make install + cd .. + rm ruby-install-${version}.tar.gz + rm -r ruby-install-${version}/ +fi diff --git a/provision/ruby.sh b/provision/ruby.sh new file mode 100644 index 0000000..776f6a5 --- /dev/null +++ b/provision/ruby.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +version="2.2.2" + +if [[ ! -d /opt/rubies/ruby-${version}/ ]]; then + /usr/local/bin/ruby-install ruby $version + /opt/rubies/ruby-${version}/bin/gem update --system --verbose +fi + +su vagrant -c " + echo ${version} > ~/.ruby-version + echo ${version} > /vagrant/.ruby-version +" From fba163694fcd02cad2be8aa26c522567c24b20e0 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sat, 5 Dec 2015 13:30:09 +0900 Subject: [PATCH 110/358] byndle install --- Gemfile | 4 ++-- Gemfile.lock | 29 ++++++++++++++++++----------- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/Gemfile b/Gemfile index 72e0b63..76d9e8d 100644 --- a/Gemfile +++ b/Gemfile @@ -11,7 +11,7 @@ gem 'uglifier', '>= 1.3.0' # Use CoffeeScript for .coffee assets and views gem 'coffee-rails', '~> 4.1.0' # See https://github.com/rails/execjs#readme for more supported runtimes -# gem 'therubyracer', platforms: :ruby +gem 'therubyracer', platforms: :ruby # Use jquery as the JavaScript library gem 'jquery-rails' @@ -37,7 +37,7 @@ gem 'grape-jbuilder' gem 'grape-swagger' gem 'grape-swagger-ui' gem 'haml-rails' -gem 'wiringpi2' +# gem 'wiringpi2' gem 'rubocop', group: :development group :development, :test do diff --git a/Gemfile.lock b/Gemfile.lock index 3186672..56fdfd2 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -52,7 +52,7 @@ GEM binding_of_caller (0.7.2) debug_inspector (>= 0.0.1) builder (3.2.2) - byebug (8.2.0) + byebug (8.2.1) choice (0.2.0) coderay (1.1.0) coercible (1.0.0) @@ -64,7 +64,8 @@ GEM coffee-script-source execjs coffee-script-source (1.10.0) - database_cleaner (1.3.0) + concurrent-ruby (1.0.0) + database_cleaner (1.5.1) debug_inspector (0.0.2) descendants_tracker (0.0.4) thread_safe (~> 0.3, >= 0.3.1) @@ -77,7 +78,7 @@ GEM factory_girl_rails (4.5.0) factory_girl (~> 4.5.0) railties (>= 3.0.0) - faker (1.4.3) + faker (1.6.1) i18n (~> 0.5) globalid (0.3.6) activesupport (>= 4.1.0) @@ -134,18 +135,19 @@ GEM thor (>= 0.14, < 2.0) json (1.8.3) json_expressions (0.8.3) + libv8 (3.16.14.13) loofah (2.0.3) nokogiri (>= 1.5.9) mail (2.6.3) mime-types (>= 1.16, < 3) method_source (0.8.2) - mime-types (2.6.2) - mini_portile (0.6.2) + mime-types (2.99) + mini_portile2 (2.0.0) minitest (5.8.3) multi_json (1.11.2) multi_xml (0.5.5) - nokogiri (1.6.6.4) - mini_portile (~> 0.6.0) + nokogiri (1.6.7) + mini_portile2 (~> 2.0.0.rc2) parser (2.2.3.0) ast (>= 1.1, < 3.0) powerpack (0.1.1) @@ -202,7 +204,7 @@ GEM rainbow (2.0.0) rake (10.4.2) rdoc (4.2.0) - json (~> 1.4) + ref (2.0.0) rspec-core (3.0.4) rspec-support (~> 3.0.0) rspec-expectations (3.0.4) @@ -228,7 +230,7 @@ GEM tins (<= 1.6.0) ruby-graphviz (1.2.2) ruby-progressbar (1.7.5) - ruby_parser (3.7.1) + ruby_parser (3.7.2) sexp_processor (~> 4.1) sass (3.4.19) sass-rails (5.0.4) @@ -242,8 +244,9 @@ GEM rdoc (~> 4.0) sexp_processor (4.6.0) slop (3.6.0) - spring (1.4.4) - sprockets (3.4.0) + spring (1.5.0) + sprockets (3.5.0) + concurrent-ruby (~> 1.0) rack (> 1, < 3) sprockets-rails (2.3.3) actionpack (>= 3.0) @@ -252,6 +255,9 @@ GEM sqlite3 (1.3.11) tapp (1.5.0) thor + therubyracer (0.12.2) + libv8 (~> 3.16.14.0) + ref thor (0.19.1) thread_safe (0.3.5) tilt (2.0.1) @@ -314,6 +320,7 @@ DEPENDENCIES spring sqlite3 tapp + therubyracer turbolinks uglifier (>= 1.3.0) web-console (~> 2.0) From 6cc4db7ece67aa432fe188a090aa162df63968ea Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sat, 5 Dec 2015 13:30:17 +0900 Subject: [PATCH 111/358] rake db:migrate --- db/schema.rb | 100 ++++++++++++++++++++++++++------------------------- 1 file changed, 51 insertions(+), 49 deletions(-) diff --git a/db/schema.rb b/db/schema.rb index 0190e8b..9685ee1 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,72 +11,74 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20_151_204_140_119) do - create_table 'auth_tokens', force: :cascade do |t| - t.string 'token' - t.integer 'user_id' - t.datetime 'created_at', null: false - t.datetime 'updated_at', null: false +ActiveRecord::Schema.define(version: 20151204140119) do + + create_table "auth_tokens", force: :cascade do |t| + t.string "token" + t.integer "user_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end - add_index 'auth_tokens', ['user_id'], name: 'index_auth_tokens_on_user_id' + add_index "auth_tokens", ["user_id"], name: "index_auth_tokens_on_user_id" - create_table 'infrared_groups', force: :cascade do |t| - t.string 'name' - t.integer 'user_id' - t.integer 'log_id' - t.datetime 'created_at', null: false - t.datetime 'updated_at', null: false + create_table "infrared_groups", force: :cascade do |t| + t.string "name" + t.integer "user_id" + t.integer "log_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end - add_index 'infrared_groups', ['log_id'], name: 'index_infrared_groups_on_log_id' - add_index 'infrared_groups', ['user_id'], name: 'index_infrared_groups_on_user_id' + add_index "infrared_groups", ["log_id"], name: "index_infrared_groups_on_log_id" + add_index "infrared_groups", ["user_id"], name: "index_infrared_groups_on_user_id" - create_table 'infrared_relationals', force: :cascade do |t| - t.integer 'infrared_id' - t.integer 'infrared_group_id' - t.datetime 'created_at', null: false - t.datetime 'updated_at', null: false + create_table "infrared_relationals", force: :cascade do |t| + t.integer "infrared_id" + t.integer "infrared_group_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end - add_index 'infrared_relationals', ['infrared_group_id'], name: 'index_infrared_relationals_on_infrared_group_id' - add_index 'infrared_relationals', ['infrared_id'], name: 'index_infrared_relationals_on_infrared_id' + add_index "infrared_relationals", ["infrared_group_id"], name: "index_infrared_relationals_on_infrared_group_id" + add_index "infrared_relationals", ["infrared_id"], name: "index_infrared_relationals_on_infrared_id" - create_table 'infrareds', force: :cascade do |t| - t.string 'name' - t.string 'data' - t.integer 'user_id' - t.datetime 'created_at', null: false - t.datetime 'updated_at', null: false - t.integer 'log_id' + create_table "infrareds", force: :cascade do |t| + t.string "name" + t.string "data" + t.integer "user_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.integer "log_id" end - add_index 'infrareds', ['log_id'], name: 'index_infrareds_on_log_id' - add_index 'infrareds', ['user_id'], name: 'index_infrareds_on_user_id' + add_index "infrareds", ["log_id"], name: "index_infrareds_on_log_id" + add_index "infrareds", ["user_id"], name: "index_infrareds_on_user_id" - create_table 'logs', force: :cascade do |t| - t.integer 'user_id' - t.datetime 'created_at', null: false - t.datetime 'updated_at', null: false - t.string 'name' + create_table "logs", force: :cascade do |t| + t.integer "user_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.string "name" end - add_index 'logs', ['user_id'], name: 'index_logs_on_user_id' + add_index "logs", ["user_id"], name: "index_logs_on_user_id" - create_table 'user_infos', force: :cascade do |t| - t.string 'screen_name' - t.string 'hashed_password' - t.string 'email' - t.string 'email_for_index' - t.integer 'user_id' - t.datetime 'created_at', null: false - t.datetime 'updated_at', null: false + create_table "user_infos", force: :cascade do |t| + t.string "screen_name" + t.string "hashed_password" + t.string "email" + t.string "email_for_index" + t.integer "user_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end - add_index 'user_infos', ['user_id'], name: 'index_user_infos_on_user_id' + add_index "user_infos", ["user_id"], name: "index_user_infos_on_user_id" - create_table 'users', force: :cascade do |t| - t.datetime 'created_at', null: false - t.datetime 'updated_at', null: false + create_table "users", force: :cascade do |t| + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end + end From 3fa2c52ebbe9be8e073667671eab7b6cba56bc70 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sat, 5 Dec 2015 15:48:56 +0900 Subject: [PATCH 112/358] update erd.pdf --- erd.pdf | Bin 33637 -> 118558 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/erd.pdf b/erd.pdf index a9db265fc9f733817d4ea8579ff3ddf617688c8a..511f862b300e674fad5781e79ffcde7df340cacc 100644 GIT binary patch literal 118558 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

=O(+D1+s%0sWm|oPkjY_GLxffX`>Uv(Mu0cUG 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 z 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�v$qv0-)K9>ipkiK())Y%(3+f?* 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 From aebfe421aca6bcd3f2b435f44835362d69f94ccf Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 6 Dec 2015 00:26:00 +0900 Subject: [PATCH 113/358] Revert "Merge branch 'develop' of https://github.com/gamerinshaft/switch_api into feature/issues/#53" This reverts commit 307018494f4a774f61093356c9328bfc8cde6888, reversing changes made to cb4d7aa5cba0990000a5f72ff06efee688b71651. --- .ruby-version | 1 - .../default/virtualbox/action_provision | 1 - .../default/virtualbox/action_set_name | 1 - .../machines/default/virtualbox/creator_uid | 1 - .vagrant/machines/default/virtualbox/id | 1 - .../machines/default/virtualbox/index_uuid | 1 - .../machines/default/virtualbox/private_key | 27 -------- .../default/virtualbox/synced_folders | 1 - Vagrantfile | 24 -------- provision/chruby.sh | 29 --------- provision/foreman.sh | 10 --- provision/limits.sh | 61 ------------------- provision/mysql-server.sh | 13 ---- provision/postgresql-server.sh | 16 ----- provision/rails.sh | 10 --- provision/redis.sh | 8 --- provision/ruby-install.sh | 20 ------ provision/ruby.sh | 13 ---- 18 files changed, 238 deletions(-) delete mode 100644 .ruby-version delete mode 100644 .vagrant/machines/default/virtualbox/action_provision delete mode 100644 .vagrant/machines/default/virtualbox/action_set_name delete mode 100644 .vagrant/machines/default/virtualbox/creator_uid delete mode 100644 .vagrant/machines/default/virtualbox/id delete mode 100644 .vagrant/machines/default/virtualbox/index_uuid delete mode 100644 .vagrant/machines/default/virtualbox/private_key delete mode 100644 .vagrant/machines/default/virtualbox/synced_folders delete mode 100644 Vagrantfile delete mode 100644 provision/chruby.sh delete mode 100644 provision/foreman.sh delete mode 100644 provision/limits.sh delete mode 100644 provision/mysql-server.sh delete mode 100644 provision/postgresql-server.sh delete mode 100644 provision/rails.sh delete mode 100644 provision/redis.sh delete mode 100644 provision/ruby-install.sh delete mode 100644 provision/ruby.sh diff --git a/.ruby-version b/.ruby-version deleted file mode 100644 index b1b25a5..0000000 --- a/.ruby-version +++ /dev/null @@ -1 +0,0 @@ -2.2.2 diff --git a/.vagrant/machines/default/virtualbox/action_provision b/.vagrant/machines/default/virtualbox/action_provision deleted file mode 100644 index 4b01913..0000000 --- a/.vagrant/machines/default/virtualbox/action_provision +++ /dev/null @@ -1 +0,0 @@ -1.5:9313ad11-54f8-413e-8d21-0bb472f6b228 \ No newline at end of file diff --git a/.vagrant/machines/default/virtualbox/action_set_name b/.vagrant/machines/default/virtualbox/action_set_name deleted file mode 100644 index 04c8368..0000000 --- a/.vagrant/machines/default/virtualbox/action_set_name +++ /dev/null @@ -1 +0,0 @@ -1449280828 \ No newline at end of file diff --git a/.vagrant/machines/default/virtualbox/creator_uid b/.vagrant/machines/default/virtualbox/creator_uid deleted file mode 100644 index ec52cb8..0000000 --- a/.vagrant/machines/default/virtualbox/creator_uid +++ /dev/null @@ -1 +0,0 @@ -501 \ No newline at end of file diff --git a/.vagrant/machines/default/virtualbox/id b/.vagrant/machines/default/virtualbox/id deleted file mode 100644 index 0292b61..0000000 --- a/.vagrant/machines/default/virtualbox/id +++ /dev/null @@ -1 +0,0 @@ -9313ad11-54f8-413e-8d21-0bb472f6b228 \ No newline at end of file diff --git a/.vagrant/machines/default/virtualbox/index_uuid b/.vagrant/machines/default/virtualbox/index_uuid deleted file mode 100644 index 7b5aa61..0000000 --- a/.vagrant/machines/default/virtualbox/index_uuid +++ /dev/null @@ -1 +0,0 @@ -e735aec682ff40739f5ff3b1bdb81964 \ No newline at end of file diff --git a/.vagrant/machines/default/virtualbox/private_key b/.vagrant/machines/default/virtualbox/private_key deleted file mode 100644 index ef139d1..0000000 --- a/.vagrant/machines/default/virtualbox/private_key +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEpAIBAAKCAQEApphMBFF7LeGQZfz89dJhgEl3Wz31aTTyY1BdSIQCJvc/cqW4 -5yvNaKJZsyVzMvb9RaKE6nJMbqujC/lT1JpPsYZ/0+MRSfxtP2u1KRGIgF8iFvwX -Eska5FQngTqW3delrVN7LQHYllKrGDBerjl+j3pp4+KKHj4c779EwkaKWhnsp+xq -Gq1v/gao+UPTzxIhGeoPxDOBZG3s6bi3BxoHrd2OJEwOyDl1Ju6zAZjchcXGbGO0 -RESm+i1sc2IaoDhdjX2fLn4FZOtEBDjJnF2V5pol1rTKaV/+HyEvfXLIYDItxPyA -iriLGe0G+derZUHc075VRYgiDKi4diZ4GSuRuwIDAQABAoIBAC7WGGEKa2Adz1Pt -CU0vJXxEq0q6o5k9anvjZyZw/o3n6y2XS+GqHeix5BgKilWkvNXr+ARVuAlRNdiy -8w+NhqQ5VQzEBONRFYHEDT2LkV3N4S6nFvGQGoBg7G5Xg3zBGPIeyz1/DF5OxY1a -Y/QFdABwgP6xfPU9rzL0Cie4X0MvHImiLGF4HJCckhL5acKoNWCBF4hRpnydfbj2 -pyaWeU9fA12Rx/3yHBY7V0UvnAUZ/yJOdEisG2BrkLYx9ffKjZqZWiMHF8Mq3En/ -mB19dqKQE9SSZZGe/Oj6vqwCcnWrtDv/8nEw0ktQlxMO9kI/CQBxfrSulfHy1zRy -lis2xFECgYEA0QqPk5g+OAVIf6i9NYXqlozhvVMzx8r+TPX+ccrKf1y8m+dXFgJX -Wd7Qaog/zm4gBi0soZXavJLGqUTLRVuK6Zx6yVz34MePKBBG4SvbVRJY4uKYlGRA -aHDiP9EDY8ol1kptDZux7oRsq7j861begxI20g4fdtqx2+1ZnebWz4MCgYEAzATA -zmZ4+Mx5YDBeNDBeIYPXigMputF/0hqK7nMEaHzOtdiRzSKcibxPK3EYrjZ26RPi -i+uHW1CBL/LnhzNNd21A2TssCtLQ3pIIzdEtJlUkJdYU7bNcxGg86Zrw0w6Xeq1B -9H6wFgDSUA886HiwMh+HxkRo5W6dhRSbL57mp2kCgYEAwR5RkBgo+tYeqRk5W3YR -R+51KdPw1VX6Yx0raPLg6pLBCALL2GBnVHZc8t5WnB3u5eXcApePkYDDmWMdq0Cr -77AJW3fQ5E9YOLn40VMT+N7PUSPns8d+HT6UNkKhMBJzrCnr35OD6Qdb4bUvqzcA -r/Qmwx4bAVF+2N/IV/EHaIMCgYBZOo709p5b+lnvdtgMrUbOE7KWGvIKUgw8YP14 -cndwF330zGZgOI4MM37QuiMYNpvlLpw7o+RMTLZjuTIH0KlF3VOqbpXBmhhd77LI -CX9cr4oivjHjEDo3cHuLlAdV16Dqt5IME8iBpxRUjYWPCxHMqjugvFTAW5OrG6sP -tcidWQKBgQDOrRzQ2iHO+jUNGMI6u6B2hAdXvhykgnTCB2zY7rM05XTuh6kjxT67 -GaPy3pSgK0mSbkZeT81aQLT2v/LLtoP0gCs4GgSfANJchXwUSJLYqtk92A0askVo -JRYpyGrKWHb+AS9LeesOekSYVcH3E4aHNADNikYL1BP0DPhL7M2AOQ== ------END RSA PRIVATE KEY----- diff --git a/.vagrant/machines/default/virtualbox/synced_folders b/.vagrant/machines/default/virtualbox/synced_folders deleted file mode 100644 index 3f30c24..0000000 --- a/.vagrant/machines/default/virtualbox/synced_folders +++ /dev/null @@ -1 +0,0 @@ -{"virtualbox":{"/vagrant":{"guestpath":"/vagrant","hostpath":"/Users/gamerinshaft/rails_app/switch_api","disabled":false}}} \ No newline at end of file diff --git a/Vagrantfile b/Vagrantfile deleted file mode 100644 index 950f7cf..0000000 --- a/Vagrantfile +++ /dev/null @@ -1,24 +0,0 @@ -Vagrant.configure("2") do |config| - config.vm.box = "centos.for.Switch" - config.vm.box_url = "https://github.com/2creatives/vagrant-centos/" + - "releases/download/v6.5.3/centos65-x86_64-20140116.box" - config.vm.provider :virtualbox do |vb| - vb.customize [ 'modifyvm', :id, '--memory', 1024 ] - end - config.vm.network "forwarded_port", guest: 3000, host: 4000 - - config.vm.provision :shell, inline: "yum -y update" - config.vm.provision :shell, inline: "yum -y install wget" - config.vm.provision :shell, inline: "yum -y install tmux" - config.vm.provision :shell, inline: "yum -y install graphviz" - - config.vm.provision :shell, path: "provision/chruby.sh" - config.vm.provision :shell, path: "provision/ruby-install.sh" - config.vm.provision :shell, path: "provision/ruby.sh" - config.vm.provision :shell, path: "provision/rails.sh", privileged: false - config.vm.provision :shell, path: "provision/foreman.sh", privileged: false - config.vm.provision :shell, path: "provision/mysql-server.sh" - # config.vm.provision :shell, path: "provision/postgresql-server.sh" - config.vm.provision :shell, path: "provision/redis.sh" - config.vm.provision :shell, path: "provision/limits.sh" -end diff --git a/provision/chruby.sh b/provision/chruby.sh deleted file mode 100644 index 0f8fd57..0000000 --- a/provision/chruby.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/bin/bash - -version="0.3.8" - -if [[ -d /usr/local/share/chruby ]]; then - source /usr/local/share/chruby/chruby.sh - current_version=$(chruby --version) -fi - -if [[ "${current_version}" != "chruby: ${version}" ]]; then - mkdir -p /opt/src - cd /opt/src - wget -O chruby-${version}.tar.gz \ - https://github.com/postmodern/chruby/archive/v${version}.tar.gz - tar xzf chruby-${version}.tar.gz - cd chruby-${version}/ - make install - cd .. - rm chruby-${version}.tar.gz - rm -r chruby-${version}/ -fi - -if [ $(grep -c chruby.sh ~vagrant/.bashrc) -eq 0 ]; then - echo 'source /usr/local/share/chruby/chruby.sh' >> ~vagrant/.bashrc -fi - -if [ $(grep -c auto.sh ~vagrant/.bashrc) -eq 0 ]; then - echo 'source /usr/local/share/chruby/auto.sh' >> ~vagrant/.bashrc -fi diff --git a/provision/foreman.sh b/provision/foreman.sh deleted file mode 100644 index 86e00cc..0000000 --- a/provision/foreman.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env bash - -version="0.78.0" - -source /usr/local/share/chruby/chruby.sh -chruby $(cat ~/.ruby-version) - -if [[ ! -d ${GEM_HOME}/gems/rails-${version}/ ]]; then - gem install foreman --version=${version} --no-ri --no-rdoc --verbose -fi diff --git a/provision/limits.sh b/provision/limits.sh deleted file mode 100644 index b53ff78..0000000 --- a/provision/limits.sh +++ /dev/null @@ -1,61 +0,0 @@ -#!/usr/bin/env bash - -cat > /etc/security/limits.conf < -# -#Where: -# can be: -# - a user name -# - a group name, with @group syntax -# - the wildcard *, for default entry -# - the wildcard %, can be also used with %group syntax, -# for maxlogin limit -# -# can have the two values: -# - "soft" for enforcing the soft limits -# - "hard" for enforcing hard limits -# -# can be one of the following: -# - core - limits the core file size (KB) -# - data - max data size (KB) -# - fsize - maximum filesize (KB) -# - memlock - max locked-in-memory address space (KB) -# - nofile - max number of open file descriptors -# - rss - max resident set size (KB) -# - stack - max stack size (KB) -# - cpu - max CPU time (MIN) -# - nproc - max number of processes -# - as - address space limit (KB) -# - maxlogins - max number of logins for this user -# - maxsyslogins - max number of logins on the system -# - priority - the priority to run user process with -# - locks - max number of file locks the user can hold -# - sigpending - max number of pending signals -# - msgqueue - max memory used by POSIX message queues (bytes) -# - nice - max nice priority allowed to raise to values: [-20, 19] -# - rtprio - max realtime priority -# -# -# - -#* soft core 0 -#* hard rss 10000 -#@student hard nproc 20 -#@faculty soft nproc 20 -#@faculty hard nproc 50 -#ftp hard nproc 0 -#@student - maxlogins 4 - -* soft nofile 4096 -* hard nofile 4096 - -# End of file -""" -EOF - -ulimit -n 4096 diff --git a/provision/mysql-server.sh b/provision/mysql-server.sh deleted file mode 100644 index b891952..0000000 --- a/provision/mysql-server.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash - -password="password" - -if [[ ! -f /usr/sbin/mysqld ]]; then - rpm -Uvh http://dev.mysql.com/get/mysql-community-release-el6-5.noarch.rpm - sed -i -e "19c enabled=1" /etc/yum.repos.d/mysql-community.repo - sed -i -e "27c enabled=0" /etc/yum.repos.d/mysql-community.repo - yum install -y mysql-server mysql-devel - service mysqld start - chkconfig mysqld on - mysql -u root -e "SET PASSWORD FOR 'root'@'localhost' = PASSWORD('${password}')" -fi diff --git a/provision/postgresql-server.sh b/provision/postgresql-server.sh deleted file mode 100644 index 9d72835..0000000 --- a/provision/postgresql-server.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash - -if [[ ! -d /usr/lib/postgresql/9.3/ ]]; then - rpm -Uvh http://yum.postgresql.org/9.3/redhat/rhel-6-x86_64/pgdg-centos93-9.3-1.noarch.rpm - yum install -y postgresql93-server postgresql-devel - service postgresql-9.3 initdb - service postgresql-9.3 start - chkconfig postgresql-9.3 on - su - postgres -c " - psql -c \"UPDATE pg_database SET datistemplate=false WHERE datname='template1'\" - psql -c \"DROP DATABASE template1\" - psql -c \"CREATE DATABASE template1 WITH TEMPLATE = template0 ENCODING = 'UTF8'\" - psql -c \"UPDATE pg_database SET datistemplate=true WHERE datname='template1'\" - createuser -d -S -R vagrant - " -fi diff --git a/provision/rails.sh b/provision/rails.sh deleted file mode 100644 index ae15365..0000000 --- a/provision/rails.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash - -version="4.2.1" - -source /usr/local/share/chruby/chruby.sh -chruby $(cat ~/.ruby-version) - -if [[ ! -d ${GEM_HOME}/gems/rails-${version}/ ]]; then - gem install rails --version=${version} --no-ri --no-rdoc --verbose -fi diff --git a/provision/redis.sh b/provision/redis.sh deleted file mode 100644 index e17a128..0000000 --- a/provision/redis.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env bash - -sudo rpm --import http://rpms.famillecollet.com/RPM-GPG-KEY-remi -sudo rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-6.rpm - -sudo yum -y install redis --enablerepo=remi -sudo chkconfig redis on -sudo service redis start diff --git a/provision/ruby-install.sh b/provision/ruby-install.sh deleted file mode 100644 index f1a794b..0000000 --- a/provision/ruby-install.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/bash - -version="0.4.1" - -if [[ -f /usr/local/bin/ruby-install ]]; then - current_version=$(ruby-install --version) -fi - -if [[ "${current_version}" != "ruby-install: ${version}" ]]; then - mkdir -p /opt/src - cd /opt/src - wget -O ruby-install-${version}.tar.gz \ - https://github.com/postmodern/ruby-install/archive/v${version}.tar.gz - tar xzf ruby-install-${version}.tar.gz - cd ruby-install-${version}/ - make install - cd .. - rm ruby-install-${version}.tar.gz - rm -r ruby-install-${version}/ -fi diff --git a/provision/ruby.sh b/provision/ruby.sh deleted file mode 100644 index 776f6a5..0000000 --- a/provision/ruby.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash - -version="2.2.2" - -if [[ ! -d /opt/rubies/ruby-${version}/ ]]; then - /usr/local/bin/ruby-install ruby $version - /opt/rubies/ruby-${version}/bin/gem update --system --verbose -fi - -su vagrant -c " - echo ${version} > ~/.ruby-version - echo ${version} > /vagrant/.ruby-version -" From c8d450f8dfb7ad1a50bdd9b969d64af66dacde85 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 6 Dec 2015 03:28:59 +0900 Subject: [PATCH 114/358] vagrant setting --- .../machines/nox/virtualbox/action_provision | 1 + .../machines/nox/virtualbox/action_set_name | 1 + .vagrant/machines/nox/virtualbox/creator_uid | 1 + .vagrant/machines/nox/virtualbox/id | 1 + .vagrant/machines/nox/virtualbox/index_uuid | 1 + .vagrant/machines/nox/virtualbox/private_key | 27 ++++++ .../machines/nox/virtualbox/synced_folders | 1 + Vagrantfile | 28 ++++++ modules/apt/manifests/init.pp | 7 ++ modules/apt/manifests/source.pp | 20 +++++ modules/puppet/manifests/init.pp | 16 ++++ .../files/etc/profile.d/raspberry-dev.sh | 1 + .../files/rootfs/etc/apt/sources.list | 2 + .../puppet/modules/raspbian/manifests/init.pp | 10 +++ modules/raspberry_dev/manifests/config.pp | 58 ++++++++++++ modules/raspberry_dev/manifests/init.pp | 26 ++++++ modules/raspberry_dev/manifests/packages.pp | 9 ++ modules/raspberry_dev/manifests/qemu.pp | 15 ++++ .../manifests/raspbian_chroot.pp | 89 +++++++++++++++++++ .../raspberry_dev/manifests/scratchbox2.pp | 16 ++++ modules/raspberry_dev/manifests/toolchain.pp | 15 ++++ modules/ssh/manifests/init.pp | 0 modules/ssh/manifests/server.pp | 20 +++++ modules/ssh/manifests/user.pp | 13 +++ modules/ssh/templates/server/sshd_config.erb | 80 +++++++++++++++++ modules/ssh/templates/user/config.erb | 11 +++ modules/ssh/templates/user/known_hosts.erb | 1 + modules/sysconfig/manifests/init.pp | 3 + modules/sysconfig/manifests/misc.pp | 9 ++ modules/sysconfig/manifests/sudoers.pp | 15 ++++ modules/sysconfig/templates/etc/sudoers.erb | 25 ++++++ puppetmanifests/raspberry-nox.pp | 2 + 32 files changed, 524 insertions(+) create mode 100644 .vagrant/machines/nox/virtualbox/action_provision create mode 100644 .vagrant/machines/nox/virtualbox/action_set_name create mode 100644 .vagrant/machines/nox/virtualbox/creator_uid create mode 100644 .vagrant/machines/nox/virtualbox/id create mode 100644 .vagrant/machines/nox/virtualbox/index_uuid create mode 100644 .vagrant/machines/nox/virtualbox/private_key create mode 100644 .vagrant/machines/nox/virtualbox/synced_folders create mode 100644 Vagrantfile create mode 100644 modules/apt/manifests/init.pp create mode 100644 modules/apt/manifests/source.pp create mode 100644 modules/puppet/manifests/init.pp create mode 100644 modules/raspberry_dev/files/etc/profile.d/raspberry-dev.sh create mode 100644 modules/raspberry_dev/files/rootfs/etc/apt/sources.list create mode 100644 modules/raspberry_dev/files/rootfs/etc/puppet/modules/raspbian/manifests/init.pp create mode 100644 modules/raspberry_dev/manifests/config.pp create mode 100644 modules/raspberry_dev/manifests/init.pp create mode 100644 modules/raspberry_dev/manifests/packages.pp create mode 100644 modules/raspberry_dev/manifests/qemu.pp create mode 100644 modules/raspberry_dev/manifests/raspbian_chroot.pp create mode 100644 modules/raspberry_dev/manifests/scratchbox2.pp create mode 100644 modules/raspberry_dev/manifests/toolchain.pp create mode 100644 modules/ssh/manifests/init.pp create mode 100644 modules/ssh/manifests/server.pp create mode 100644 modules/ssh/manifests/user.pp create mode 100644 modules/ssh/templates/server/sshd_config.erb create mode 100644 modules/ssh/templates/user/config.erb create mode 100644 modules/ssh/templates/user/known_hosts.erb create mode 100644 modules/sysconfig/manifests/init.pp create mode 100644 modules/sysconfig/manifests/misc.pp create mode 100644 modules/sysconfig/manifests/sudoers.pp create mode 100644 modules/sysconfig/templates/etc/sudoers.erb create mode 100644 puppetmanifests/raspberry-nox.pp diff --git a/.vagrant/machines/nox/virtualbox/action_provision b/.vagrant/machines/nox/virtualbox/action_provision new file mode 100644 index 0000000..6ac823e --- /dev/null +++ b/.vagrant/machines/nox/virtualbox/action_provision @@ -0,0 +1 @@ +1.5:78672f12-18ae-4cd7-8606-7073530c02a2 \ No newline at end of file diff --git a/.vagrant/machines/nox/virtualbox/action_set_name b/.vagrant/machines/nox/virtualbox/action_set_name new file mode 100644 index 0000000..cbd1fc2 --- /dev/null +++ b/.vagrant/machines/nox/virtualbox/action_set_name @@ -0,0 +1 @@ +1449329777 \ No newline at end of file diff --git a/.vagrant/machines/nox/virtualbox/creator_uid b/.vagrant/machines/nox/virtualbox/creator_uid new file mode 100644 index 0000000..ec52cb8 --- /dev/null +++ b/.vagrant/machines/nox/virtualbox/creator_uid @@ -0,0 +1 @@ +501 \ No newline at end of file diff --git a/.vagrant/machines/nox/virtualbox/id b/.vagrant/machines/nox/virtualbox/id new file mode 100644 index 0000000..3a96458 --- /dev/null +++ b/.vagrant/machines/nox/virtualbox/id @@ -0,0 +1 @@ +78672f12-18ae-4cd7-8606-7073530c02a2 \ No newline at end of file diff --git a/.vagrant/machines/nox/virtualbox/index_uuid b/.vagrant/machines/nox/virtualbox/index_uuid new file mode 100644 index 0000000..727ceb1 --- /dev/null +++ b/.vagrant/machines/nox/virtualbox/index_uuid @@ -0,0 +1 @@ +d1b79d4f7a9d4b558848ddcb5403877d \ No newline at end of file diff --git a/.vagrant/machines/nox/virtualbox/private_key b/.vagrant/machines/nox/virtualbox/private_key new file mode 100644 index 0000000..79f8c9c --- /dev/null +++ b/.vagrant/machines/nox/virtualbox/private_key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpQIBAAKCAQEA0biLLIvog+G2O6O/pLfYPBQQjSCWQbfowrUqfSEQb8RysEH7 +sIJs6xDFS8ovasOueiCgSdiB/6nbFjPP8VHpfVSvSSK0CcQk4XGnldPhhex35jlp +QzHubCvLW3sophMHRDehf76971Wd1QwPWgJazuvwblyKm70GeEcwQR/QBnLBy4T0 +/YjhMXpBRDWmFUCTkb7p2kQeIfLZbbinsTj8ytY9YT6PYRX0cYnJmwYV1qPePIru +jNhBoEDSkyanCXnwhteJK3uRyJTUEUIXmw429WUxrzloOTyQQAoHXAXvTvFwMZCL +bh7GmhxrHJC5HSHWZ/4d///nHWH1++2sF2xhPQIDAQABAoIBAQDEgGN248iC+ZPk +IbPJRLEI6cvwT945yXYAKfubrsVV0/2aBNktM6eWQOp77v+qy5rJt5Q4XPLBeIdd +MELgW92onxZ2Mlv64puj2PgrPJINB9n4D0b/vOMm24n5N1aI9T9TvcRGi5QvkksG +efxQW/B1/UAUSAVfkydiv2EJRCOIRX9htFx5rzHIP3hDw8AL7nl890DFL6tXiYBo +vbvmSADnisChew+E01DSxLnoxHtERtq+9tEtLQJY6+aoOaRg1GSwjqTXe9mUxRPM +0Y/ne1u1zxXt9VocOFSN9o1Palluh00U2tWuCry1mr+Qpq4/OyxI8TciGqFCr94H +ZEujgkkJAoGBAPP2CsueBY23FbiMqTxEfiRzv47v2bI9SXybBPmQMWm7l68sprmI +6xWBgxETL6/pqLPSijWf/CT6lzPMReeGnp4+Rua0OI854/Gp3TcALn64S078c1A4 +piH9H5ZaWRlNSRhSRU0Po5iSEM2mKRvgotYpJNF3afDUVY5Kg2DGk77vAoGBANwR +8e97h6W51tp/ryZnjJLFx2Z4YlTZtdg/qV0M/nCAKqbvUHu8lyP72fF219cpA4qC +ef0nmZGYcAPdmPsZuonioMVkm1zfF04sGwZwL8rYF4bo7GXji3JHcE1HUKottlYA +/wp4U7rXXMNxwm1pA8sKY3d+VMMPUfUMoYmCZiKTAoGBAMMXmlB0wSowJG2eBuRM +Pbf23FR5GFVCT5cW/OZ6Whmcy9NpWLb8eEqNdHveJP9/Usri7mWt19zWjL3+eFSL +QiN32Ak8TBK1j8S9O0t1mLj7tjWnCqw3cRuzKWR6QdBLDs4lVIgonoIvJMLgQvWp +MW8kHe5omU7e7sBIdEGa66H/AoGAEo5Yzg6mc2zmFuppRF261q1ikNtZvznUQXWs +vDHaSnYkIotPR/+w5tHXoKqarIPCzq0NyDDMnCA0Yb8PpSyYNAQt9jbzerM87dR+ +Ot6+yOXLpg6B0F2NZodririWrqLIGxxeZO2cccazBa/T6xHNxhMMLAk08HWcPYNh +I40hO40CgYEA7ggFL3LiDEZcDIss4U6vBhGQncRqfmyqAiLrqhby2vKRV+gnR+Fe +UYIRF7IxO2BBKJw3lFQR3YsRhqeSM4q13X//UAippJQlNZX0dPQsrVNfp6tU+fNF +SyGaWggqPDuY7JVHS+cMXWBW9nWBuBRY8AqaadTlCC/6irkUlr9UStY= +-----END RSA PRIVATE KEY----- diff --git a/.vagrant/machines/nox/virtualbox/synced_folders b/.vagrant/machines/nox/virtualbox/synced_folders new file mode 100644 index 0000000..5a0a1c8 --- /dev/null +++ b/.vagrant/machines/nox/virtualbox/synced_folders @@ -0,0 +1 @@ +{"virtualbox":{"/vagrant":{"guestpath":"/vagrant","hostpath":"/Users/gamerinshaft/rails_app/switch_api","disabled":false},"/tmp/vagrant-puppet/manifests-165a8fe60decd8583fc5c43cbcd1c9cf":{"owner":"root","nfs__quiet":true,"guestpath":"/tmp/vagrant-puppet/manifests-165a8fe60decd8583fc5c43cbcd1c9cf","hostpath":"/Users/gamerinshaft/rails_app/switch_api/puppetmanifests","disabled":false},"/tmp/vagrant-puppet/modules-5f5d0cebfa4e3f108c5e8c7b7edd953b":{"owner":"root","nfs__quiet":true,"guestpath":"/tmp/vagrant-puppet/modules-5f5d0cebfa4e3f108c5e8c7b7edd953b","hostpath":"/Users/gamerinshaft/rails_app/switch_api/modules","disabled":false}}} \ No newline at end of file diff --git a/Vagrantfile b/Vagrantfile new file mode 100644 index 0000000..f49bb8d --- /dev/null +++ b/Vagrantfile @@ -0,0 +1,28 @@ +# -*- mode: ruby -*- +# vi: set ft=ruby : + +Vagrant::Config.run do |config| + # All Vagrant configuration is done here. The most common configuration + # options are documented and commented below. For a complete reference, + # please see the online documentation at vagrantup.com. + + config.vm.define :nox do |box| + # Every Vagrant virtual environment requires a box to build off of. + box.vm.box = "precise64" + # The url from where the 'config.vm.box' box will be fetched if it + # doesn't already exist on the user's system. + box.vm.box_url = "http://files.vagrantup.com/precise64.box" + + # Boot with a GUI so you can see the screen. (Default is headless) + #box.vm.boot_mode = :gui + # add a hostonly network if desired + #box.vm.network :hostonly, "33.33.33.151" + + box.vm.provision :puppet do |puppet| + puppet.manifests_path = "puppetmanifests" + puppet.manifest_file = "raspberry-nox.pp" + puppet.module_path = "modules" + puppet.options = ["--verbose", "--debug"] + end + end +end diff --git a/modules/apt/manifests/init.pp b/modules/apt/manifests/init.pp new file mode 100644 index 0000000..aa0ba8f --- /dev/null +++ b/modules/apt/manifests/init.pp @@ -0,0 +1,7 @@ +class apt { + + exec {"apt-get update": + command => "/usr/bin/apt-get update", + } + +} \ No newline at end of file diff --git a/modules/apt/manifests/source.pp b/modules/apt/manifests/source.pp new file mode 100644 index 0000000..c037ed9 --- /dev/null +++ b/modules/apt/manifests/source.pp @@ -0,0 +1,20 @@ +# Here's how you generate a keyring file to put in your puppet fileserver and +# reference with a puppet:///path/to/foo.gpg: +# +# gpg --no-default-keyring --keyserver keyserver.ubuntu.com --keyring /path/to/fileserver/foo.gpg --recv-keys DEADBEEF +define apt::source ($url, $suite = $::lsbdistcodename, $component = 'main', $type = 'deb', $keyring = '', $ensure = present) { + + if $keyring != '' { + file { "/etc/apt/trusted.gpg.d/${name}.gpg": + source => $keyring, + ensure => $ensure + } + } + + file { "/etc/apt/sources.list.d/${name}.list": + content => "# This file is managed by puppet\n\n${type} ${url} ${suite} ${component}\n", + ensure => $ensure, + notify => Exec["apt-get update"], + } + +} \ No newline at end of file diff --git a/modules/puppet/manifests/init.pp b/modules/puppet/manifests/init.pp new file mode 100644 index 0000000..56dc012 --- /dev/null +++ b/modules/puppet/manifests/init.pp @@ -0,0 +1,16 @@ +# creates the user/group puppet that the puppet provisioner will need later + +class puppet { + + group { "puppet": + ensure => "present", + } + + user { "puppet": + ensure => "present", + gid => "puppet", + require => Group["puppet"] + } + + +} \ No newline at end of file diff --git a/modules/raspberry_dev/files/etc/profile.d/raspberry-dev.sh b/modules/raspberry_dev/files/etc/profile.d/raspberry-dev.sh new file mode 100644 index 0000000..04c2fe3 --- /dev/null +++ b/modules/raspberry_dev/files/etc/profile.d/raspberry-dev.sh @@ -0,0 +1 @@ +PATH=$PATH:/opt/raspberry-dev/bin \ No newline at end of file diff --git a/modules/raspberry_dev/files/rootfs/etc/apt/sources.list b/modules/raspberry_dev/files/rootfs/etc/apt/sources.list new file mode 100644 index 0000000..4cf60af --- /dev/null +++ b/modules/raspberry_dev/files/rootfs/etc/apt/sources.list @@ -0,0 +1,2 @@ +deb http://archive.raspbian.org/raspbian/ wheezy main contrib non-free rpi +deb-src http://archive.raspbian.org/raspbian/ wheezy main contrib non-free rpi diff --git a/modules/raspberry_dev/files/rootfs/etc/puppet/modules/raspbian/manifests/init.pp b/modules/raspberry_dev/files/rootfs/etc/puppet/modules/raspbian/manifests/init.pp new file mode 100644 index 0000000..896544e --- /dev/null +++ b/modules/raspberry_dev/files/rootfs/etc/puppet/modules/raspbian/manifests/init.pp @@ -0,0 +1,10 @@ + class raspbian { + + package {['locales', 'dialog']: + ensure => installed + } + + package {['pkg-config', 'libglib2.0-dev']: + ensure => installed + } +} diff --git a/modules/raspberry_dev/manifests/config.pp b/modules/raspberry_dev/manifests/config.pp new file mode 100644 index 0000000..bdae630 --- /dev/null +++ b/modules/raspberry_dev/manifests/config.pp @@ -0,0 +1,58 @@ + +class raspberry_dev::config { + $tools_prefix = '/opt/raspberry-dev' + $debs_dir = '/opt/raspberry-dev/debs' + $bin_dir = '/opt/raspberry-dev/bin' + + $user = 'vagrant' + $sbox2_container_path = '/home/vagrant/raspberry-dev/rootfs' + $sbox2_container_name = 'raspberry' + + $arm_gcc_path = "${bin_dir}/arm-linux-gnueabihf-gcc" + $qemu_path = "${bin_dir}/qemu-arm" + + + file {['/home/vagrant/raspberry-dev', + '/home/vagrant/raspberry-dev/rootfs']: + ensure => directory, + owner => vagrant, + group => vagrant + } + + file {['/opt/', + '/opt/raspberry-dev', + '/opt/raspberry-dev/debs']: + ensure => directory, + } + + file {'/etc/profile.d/raspberry-dev.sh': + source => 'puppet:///modules/raspberry_dev/etc/profile.d/raspberry-dev.sh', + mode => '0755' + } + + user {'vagrant': + ensure => present, + home => '/home/vagrant' + } -> file {'/home/vagrant': + ensure => directory, + owner => vagrant, + group => vagrant + } + + + user {'root': + ensure => present, + home => '/root' + } -> file {'/root': + ensure => directory, + owner => root, + group => root + } + + ssh::user {'vagrant': + } + + ssh::user { 'root': + home => '/root' + } +} diff --git a/modules/raspberry_dev/manifests/init.pp b/modules/raspberry_dev/manifests/init.pp new file mode 100644 index 0000000..6fd97ab --- /dev/null +++ b/modules/raspberry_dev/manifests/init.pp @@ -0,0 +1,26 @@ +# - This is cobbled together from various sources, including: +# - +# - +# - +# - +# - (This is an decent introduction to ScratchBox2) + +class raspberry_dev { + Exec { path => ['/usr/local/bin/', '/bin/', '/sbin/', '/usr/bin/', + '/usr/sbin/', '/opt/vagrant_ruby/bin', + '/opt/raspberry-dev/bin'], + timeout => 600 + } + + include sysconfig + include sysconfig::sudoers + include ssh::server + include apt + + include raspberry_dev::packages + include raspberry_dev::config + include raspberry_dev::toolchain + include raspberry_dev::qemu + include raspberry_dev::scratchbox2 + include raspberry_dev::raspbian_chroot +} \ No newline at end of file diff --git a/modules/raspberry_dev/manifests/packages.pp b/modules/raspberry_dev/manifests/packages.pp new file mode 100644 index 0000000..87d7669 --- /dev/null +++ b/modules/raspberry_dev/manifests/packages.pp @@ -0,0 +1,9 @@ +class raspberry_dev::packages { + $required_packages = ['libncurses5', 'fakeroot', 'debootstrap', 'curl', + 'libstdc++6:i386', 'zlib1g:i386', 'libc6-dev-i386', 'build-essential'] + + package {$required_packages: + ensure => installed, + require => Exec['apt-get update'] + } +} diff --git a/modules/raspberry_dev/manifests/qemu.pp b/modules/raspberry_dev/manifests/qemu.pp new file mode 100644 index 0000000..467758e --- /dev/null +++ b/modules/raspberry_dev/manifests/qemu.pp @@ -0,0 +1,15 @@ +class raspberry_dev::qemu { + $qemu_url = 'http://commondatastorage.googleapis.com/howling-fantods/raspberrypi/raspberry-qemu_1.3.0_amd64.deb' + $qemu_deb_filename = 'raspberry-qemu_1.3.0_amd64.deb' + + exec {'download-qemu': + command => "curl -L ${qemu_url} -o ${qemu_deb_filename}", + cwd => $raspberry_dev::config::debs_dir, + creates => "${raspberry_dev::config::debs_dir}/${qemu_deb_filename}" + + } -> package {'raspberry-qemu': + provider => dpkg, + source => "${raspberry_dev::config::debs_dir}/${qemu_deb_filename}", + ensure => installed + } +} \ No newline at end of file diff --git a/modules/raspberry_dev/manifests/raspbian_chroot.pp b/modules/raspberry_dev/manifests/raspbian_chroot.pp new file mode 100644 index 0000000..45bc639 --- /dev/null +++ b/modules/raspberry_dev/manifests/raspbian_chroot.pp @@ -0,0 +1,89 @@ +# Class: raspberry_dev::scratchbox2 +# +# +class raspberry_dev::raspbian_chroot { + $raspbian_mirror = 'http://archive.raspbian.org/raspbian/' + + $container_init_cmd = "sb2-init -n \ + -c ${raspberry_dev::config::qemu_path} \ + ${raspberry_dev::config::sbox2_container_name} \ + ${raspberry_dev::config::arm_gcc_path}" + + $bootstrap_cmd = + "fakeroot debootstrap --verbose --foreign --variant=scratchbox \ + --arch armhf --keyring /etc/apt/trusted.gpg wheezy \ + ${raspberry_dev::config::sbox2_container_path} ${raspbian_mirror}" + + # without this, sbox2 sees HOME as "/root" for some reason, and all sb2 + # commands fail. + $sbox2_required_env_flags = ["HOME=/home/vagrant"] + + exec {'scratchbox2-init-container': + command => $container_init_cmd, + environment => $sbox2_required_env_flags, + cwd => $raspberry_dev::config::sbox2_container_path, + unless => "sudo -u vagrant sb2-config -l | grep \"^${raspberry_dev::config::sbox2_container_name}$\"", + user => vagrant, + group => vagrant, + + } -> exec {'raspbian-install-key': + command => 'curl http://archive.raspbian.org/raspbian.public.key | apt-key add -', + unless => 'apt-key list | grep "Raspberry Pi Debian"' + + } -> exec {'debootstrap-first-stage': + command => $bootstrap_cmd, + environment => $sbox2_required_env_flags, + creates => "${raspberry_dev::config::sbox2_container_path}/var", + user => vagrant, + group => vagrant, + timeout => 1500, # 25 minutes + + } -> exec {'debootstrap-second-stage': + command => "sb2 -t raspberry -eR ./debootstrap/debootstrap --verbose --second-stage", + environment => $sbox2_required_env_flags, + cwd => $raspberry_dev::config::sbox2_container_path, + user => vagrant, + group => vagrant, + onlyif => "test -f \"${raspberry_dev::config::sbox2_container_path}/debootstrap/debootstrap\"", + # tries => 2 is set because in my experience, debootstrap fails the first + # time round, only to succeed on the second. Hmph. The error is: + # I: Configuring initramfs-tools... + # W: Failure while configuring required packages. + tries => 2, + timeout => 1500, # 25 minutes + + } -> file {"${raspberry_dev::config::sbox2_container_path}/etc/apt/sources.list": + source => "puppet:///modules/raspberry_dev/rootfs/etc/apt/sources.list", + ensure => present, + owner => vagrant, + group => vagrant + + } -> exec {'sandbox-apt-get-update': + command => "sb2 -t ${raspberry_dev::config::sbox2_container_name} -eR apt-get update", + environment => $sbox2_required_env_flags, + cwd => $raspberry_dev::config::sbox2_container_path, + user => vagrant, + group => vagrant, + + } -> exec {'sandbox-install-essentials': + command => "sb2 -t ${raspberry_dev::config::sbox2_container_name} -eR apt-get install puppet --assume-yes", + environment => $sbox2_required_env_flags, + cwd => $raspberry_dev::config::sbox2_container_path, + user => vagrant, + group => vagrant, + + } -> file {"${raspberry_dev::config::sbox2_container_path}/etc/puppet/modules/raspbian": + source => "puppet:///modules/raspberry_dev/rootfs/etc/puppet/modules/raspbian", + recurse => true, + ensure => present, + owner => vagrant, + group => vagrant + + } -> exec {'sandbox-provision': + command => "sb2 -t ${raspberry_dev::config::sbox2_container_name} -eR puppet apply -e \"include raspbian\"", + environment => $sbox2_required_env_flags, + cwd => $raspberry_dev::config::sbox2_container_path, + user => vagrant, + group => vagrant, + } +} diff --git a/modules/raspberry_dev/manifests/scratchbox2.pp b/modules/raspberry_dev/manifests/scratchbox2.pp new file mode 100644 index 0000000..c2e6aff --- /dev/null +++ b/modules/raspberry_dev/manifests/scratchbox2.pp @@ -0,0 +1,16 @@ +class raspberry_dev::scratchbox2 { + $sbox2_url = 'http://commondatastorage.googleapis.com/howling-fantods/raspberrypi/raspberry-scratchbox2_2.3.90_amd64.deb' + $sbox2_deb_filename = 'raspberry-scratchbox2_2.3.90_amd64.deb' + + exec {'download-sbox2': + command => "curl -L ${sbox2_url} -o ${sbox2_deb_filename}", + cwd => $raspberry_dev::config::debs_dir, + creates => "${raspberry_dev::config::debs_dir}/${sbox2_deb_filename}" + + } -> package {'raspberry-scratchbox2': + provider => dpkg, + source => "${raspberry_dev::config::debs_dir}/${sbox2_deb_filename}", + ensure => installed + + } +} \ No newline at end of file diff --git a/modules/raspberry_dev/manifests/toolchain.pp b/modules/raspberry_dev/manifests/toolchain.pp new file mode 100644 index 0000000..4b25185 --- /dev/null +++ b/modules/raspberry_dev/manifests/toolchain.pp @@ -0,0 +1,15 @@ +class raspberry_dev::toolchain { + $toolchain_url = 'http://commondatastorage.googleapis.com/howling-fantods/raspberrypi/raspberry-gcc-toolchain_1.0_i386.deb' + $toolchain_deb_filename = 'raspberry-gcc-toolchain_1.0_i386.deb' + + exec {'download-toolchain': + command => "curl -L ${toolchain_url} -o ${toolchain_deb_filename}", + cwd => $raspberry_dev::config::debs_dir, + creates => "${raspberry_dev::config::debs_dir}/${toolchain_deb_filename}" + + } -> package {'raspberry-gcc-toolchain': + provider => dpkg, + ensure => installed, + source => "${raspberry_dev::config::debs_dir}/${toolchain_deb_filename}" + } +} \ No newline at end of file diff --git a/modules/ssh/manifests/init.pp b/modules/ssh/manifests/init.pp new file mode 100644 index 0000000..e69de29 diff --git a/modules/ssh/manifests/server.pp b/modules/ssh/manifests/server.pp new file mode 100644 index 0000000..6ce13d5 --- /dev/null +++ b/modules/ssh/manifests/server.pp @@ -0,0 +1,20 @@ + +class ssh::server { + + file { "/etc/ssh/sshd_config": + content => template("ssh/server/sshd_config.erb"), + ensure => present, + notify => Service['ssh'] + } + + service { "ssh": + require => Package['openssh-server'], + ensure => running, + enable => true + } + + package { "openssh-server": + ensure => present + } + +} \ No newline at end of file diff --git a/modules/ssh/manifests/user.pp b/modules/ssh/manifests/user.pp new file mode 100644 index 0000000..11adfc9 --- /dev/null +++ b/modules/ssh/manifests/user.pp @@ -0,0 +1,13 @@ +define ssh::user($user = "${name}", $home = "/home/${name}") { + + + User[$user] -> File[$home] -> file { "$home/.ssh/": + ensure => directory, + } -> file { "$home/.ssh/known_hosts": + ensure => present, + content => template("ssh/user/known_hosts.erb"), + owner => $user, + mode => "0420" + } + +} \ No newline at end of file diff --git a/modules/ssh/templates/server/sshd_config.erb b/modules/ssh/templates/server/sshd_config.erb new file mode 100644 index 0000000..b685cb9 --- /dev/null +++ b/modules/ssh/templates/server/sshd_config.erb @@ -0,0 +1,80 @@ +# Package generated configuration file +# See the sshd(8) manpage for details + +# What ports, IPs and protocols we listen for +Port 22 +# Use these options to restrict which interfaces/protocols sshd will bind to +#ListenAddress :: +#ListenAddress 0.0.0.0 +Protocol 2 +# HostKeys for protocol version 2 +HostKey /etc/ssh/ssh_host_rsa_key +HostKey /etc/ssh/ssh_host_dsa_key +#Privilege Separation is turned on for security +UsePrivilegeSeparation yes + +# Lifetime and size of ephemeral version 1 server key +KeyRegenerationInterval 3600 +ServerKeyBits 768 + +# Logging +SyslogFacility AUTH +LogLevel INFO + +# Authentication: +LoginGraceTime 120 +PermitRootLogin yes +StrictModes yes + +RSAAuthentication yes +PubkeyAuthentication yes +#AuthorizedKeysFile %h/.ssh/authorized_keys + +# Don't read the user's ~/.rhosts and ~/.shosts files +IgnoreRhosts yes +# For this to work you will also need host keys in /etc/ssh_known_hosts +RhostsRSAAuthentication no +# similar for protocol version 2 +HostbasedAuthentication no +# Uncomment if you don't trust ~/.ssh/known_hosts for RhostsRSAAuthentication +#IgnoreUserKnownHosts yes + +# To enable empty passwords, change to yes (NOT RECOMMENDED) +PermitEmptyPasswords no + +# Change to yes to enable challenge-response passwords (beware issues with +# some PAM modules and threads) +ChallengeResponseAuthentication no + +# Change to no to disable tunnelled clear text passwords +PasswordAuthentication no + +# Kerberos options +#KerberosAuthentication no +#KerberosGetAFSToken no +#KerberosOrLocalPasswd yes +#KerberosTicketCleanup yes + +# GSSAPI options +#GSSAPIAuthentication no +#GSSAPICleanupCredentials yes + +X11Forwarding yes +X11DisplayOffset 10 +PrintMotd no +PrintLastLog yes +TCPKeepAlive yes +#UseLogin no + +#MaxStartups 10:30:60 +#Banner /etc/issue.net + +# Allow client to pass locale environment variables +AcceptEnv LANG LC_* + +# Accept git variables as well +AcceptEnv GIT_* + +Subsystem sftp /usr/lib/openssh/sftp-server + +UsePAM yes diff --git a/modules/ssh/templates/user/config.erb b/modules/ssh/templates/user/config.erb new file mode 100644 index 0000000..f0bfad4 --- /dev/null +++ b/modules/ssh/templates/user/config.erb @@ -0,0 +1,11 @@ +# this file is managed by puppet. local changes will not be retained + +Host * + SendEnv GIT_* + ForwardAgent yes + +# legacy support +Host github* + User git + Hostname github.com + PreferredAuthentications publickey \ No newline at end of file diff --git a/modules/ssh/templates/user/known_hosts.erb b/modules/ssh/templates/user/known_hosts.erb new file mode 100644 index 0000000..cbf637e --- /dev/null +++ b/modules/ssh/templates/user/known_hosts.erb @@ -0,0 +1 @@ +github.com,207.97.227.239 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ== \ No newline at end of file diff --git a/modules/sysconfig/manifests/init.pp b/modules/sysconfig/manifests/init.pp new file mode 100644 index 0000000..7a26e2b --- /dev/null +++ b/modules/sysconfig/manifests/init.pp @@ -0,0 +1,3 @@ +class sysconfig { + stage { 'sysconfig': before => Stage['main'] } +} \ No newline at end of file diff --git a/modules/sysconfig/manifests/misc.pp b/modules/sysconfig/manifests/misc.pp new file mode 100644 index 0000000..5c03a0b --- /dev/null +++ b/modules/sysconfig/manifests/misc.pp @@ -0,0 +1,9 @@ +class sysconfig::misc { + package { "vim": + ensure => present, + } + + package { "htop": + ensure => present, + } +} \ No newline at end of file diff --git a/modules/sysconfig/manifests/sudoers.pp b/modules/sysconfig/manifests/sudoers.pp new file mode 100644 index 0000000..aead254 --- /dev/null +++ b/modules/sysconfig/manifests/sudoers.pp @@ -0,0 +1,15 @@ + +class sysconfig::sudoers { + + file { "/etc/sudoers": + content => template("sysconfig/etc/sudoers.erb"), + ensure => present, + mode => 0440 + } + +} + + +class { + 'sysconfig::sudoers': stage => sysconfig; +} diff --git a/modules/sysconfig/templates/etc/sudoers.erb b/modules/sysconfig/templates/etc/sudoers.erb new file mode 100644 index 0000000..2c3aa6a --- /dev/null +++ b/modules/sysconfig/templates/etc/sudoers.erb @@ -0,0 +1,25 @@ +# /etc/sudoers +# This file MUST be edited with the 'visudo' command as root. +# See the man page for details on how to write a sudoers file. + +Defaults env_reset +Defaults env_keep = "SSH_AUTH_SOCK SSH_AGENT_PID GIT_EDITOR GIT_AUTHOR_NAME GIT_COMMITTER_NAME GIT_COMMITTER_EMAIL GIT_AUTHOR_EMAIL" + +# Host alias specification + +# User alias specification + +# Cmnd alias specification + +# User privilege specification +root ALL=(ALL) ALL + +# Uncomment to allow members of group sudo to not need a password +# (Note that later entries override this, so you might need to move +# it further down) +# %sudo ALL=NOPASSWD: ALL + +# Members of the admin group may gain root privileges +%admin ALL=(ALL) ALL + +vagrant ALL=(ALL) NOPASSWD:ALL \ No newline at end of file diff --git a/puppetmanifests/raspberry-nox.pp b/puppetmanifests/raspberry-nox.pp new file mode 100644 index 0000000..34279c2 --- /dev/null +++ b/puppetmanifests/raspberry-nox.pp @@ -0,0 +1,2 @@ + +include raspberry_dev \ No newline at end of file From 60a8ec757bdf95e663bf16fecfa07c374513c9d7 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 6 Dec 2015 23:22:15 +0900 Subject: [PATCH 115/358] bundle install wiringpi2 --- Gemfile | 2 +- Gemfile.lock | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index 76d9e8d..63750cc 100644 --- a/Gemfile +++ b/Gemfile @@ -37,7 +37,7 @@ gem 'grape-jbuilder' gem 'grape-swagger' gem 'grape-swagger-ui' gem 'haml-rails' -# gem 'wiringpi2' +gem 'wiringpi2' gem 'rubocop', group: :development group :development, :test do diff --git a/Gemfile.lock b/Gemfile.lock index 56fdfd2..11ae2db 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -283,6 +283,7 @@ GEM binding_of_caller (>= 0.7.2) railties (>= 4.0) sprockets-rails (>= 2.0, < 4.0) + wiringpi2 (2.0.1) yard (0.8.7.6) PLATFORMS @@ -324,6 +325,7 @@ DEPENDENCIES turbolinks uglifier (>= 1.3.0) web-console (~> 2.0) + wiringpi2 BUNDLED WITH 1.10.6 From df09e91ffc05fda24716279c222c740f345d3c9d Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Mon, 7 Dec 2015 02:40:26 +0900 Subject: [PATCH 116/358] remove wiring pi --- Gemfile | 1 - Gemfile.lock | 2 -- 2 files changed, 3 deletions(-) diff --git a/Gemfile b/Gemfile index 63750cc..bb86f0e 100644 --- a/Gemfile +++ b/Gemfile @@ -37,7 +37,6 @@ gem 'grape-jbuilder' gem 'grape-swagger' gem 'grape-swagger-ui' gem 'haml-rails' -gem 'wiringpi2' gem 'rubocop', group: :development group :development, :test do diff --git a/Gemfile.lock b/Gemfile.lock index 11ae2db..56fdfd2 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -283,7 +283,6 @@ GEM binding_of_caller (>= 0.7.2) railties (>= 4.0) sprockets-rails (>= 2.0, < 4.0) - wiringpi2 (2.0.1) yard (0.8.7.6) PLATFORMS @@ -325,7 +324,6 @@ DEPENDENCIES turbolinks uglifier (>= 1.3.0) web-console (~> 2.0) - wiringpi2 BUNDLED WITH 1.10.6 From 1e9bbcd15b0028965df5d0172265b23c7b1d6f74 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Mon, 7 Dec 2015 03:28:07 +0900 Subject: [PATCH 117/358] add vagrant setting --- Vagrantfile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Vagrantfile b/Vagrantfile index f49bb8d..a814cd7 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -1,7 +1,7 @@ # -*- mode: ruby -*- # vi: set ft=ruby : -Vagrant::Config.run do |config| +Vagrant.configure("2") do |config| # All Vagrant configuration is done here. The most common configuration # options are documented and commented below. For a complete reference, # please see the online documentation at vagrantup.com. @@ -12,11 +12,12 @@ Vagrant::Config.run do |config| # The url from where the 'config.vm.box' box will be fetched if it # doesn't already exist on the user's system. box.vm.box_url = "http://files.vagrantup.com/precise64.box" - + # Boot with a GUI so you can see the screen. (Default is headless) #box.vm.boot_mode = :gui # add a hostonly network if desired #box.vm.network :hostonly, "33.33.33.151" + box.vm.network :forwarded_port, guest: 3000, host: 4000 box.vm.provision :puppet do |puppet| puppet.manifests_path = "puppetmanifests" From 46066e6e8fd6013116231e7c507b4b3641e08c40 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Mon, 7 Dec 2015 17:18:46 +0900 Subject: [PATCH 118/358] add column count:integer to infrareds --- db/migrate/20151207081758_add_count_to_infrareds.rb | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 db/migrate/20151207081758_add_count_to_infrareds.rb diff --git a/db/migrate/20151207081758_add_count_to_infrareds.rb b/db/migrate/20151207081758_add_count_to_infrareds.rb new file mode 100644 index 0000000..f66eda0 --- /dev/null +++ b/db/migrate/20151207081758_add_count_to_infrareds.rb @@ -0,0 +1,5 @@ +class AddCountToInfrareds < ActiveRecord::Migration + def change + add_column :infrareds, :count, :integer + end +end From d23b026e8a014147c6d974da6253c3219b697c87 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Mon, 7 Dec 2015 17:18:52 +0900 Subject: [PATCH 119/358] rake db:migrate --- db/schema.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/db/schema.rb b/db/schema.rb index 9685ee1..36076d5 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20151204140119) do +ActiveRecord::Schema.define(version: 20151207081758) do create_table "auth_tokens", force: :cascade do |t| t.string "token" @@ -50,6 +50,7 @@ t.datetime "created_at", null: false t.datetime "updated_at", null: false t.integer "log_id" + t.integer "count" end add_index "infrareds", ["log_id"], name: "index_infrareds_on_log_id" From 7bc26d48663560b6b4b6481e331fab4f032a180d Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Mon, 7 Dec 2015 17:30:02 +0900 Subject: [PATCH 120/358] add error response --- app/apis/api/v1/authorize.rb | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/app/apis/api/v1/authorize.rb b/app/apis/api/v1/authorize.rb index ad5e196..a071978 100644 --- a/app/apis/api/v1/authorize.rb +++ b/app/apis/api/v1/authorize.rb @@ -69,6 +69,14 @@ def find_user_by_identifier(identifier) @screen_name = obj.screen_name @token = token.token end + else + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.invalid_token'), + code: ErrorCodes::INVALID_TOKEN + ] + }, response: {}) end end From c24367f95091b6440f6e5333c7c73c2ecf13a2f7 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Mon, 7 Dec 2015 17:51:01 +0900 Subject: [PATCH 121/358] rename --- app/apis/api/v1/base.rb | 2 +- app/apis/api/v1/ir.rb | 23 ++++++++ app/apis/api/v1/raspberry.rb | 56 ------------------- .../{raspberry => ir}/commands/blink.jbuilder | 0 4 files changed, 24 insertions(+), 57 deletions(-) create mode 100644 app/apis/api/v1/ir.rb delete mode 100644 app/apis/api/v1/raspberry.rb rename app/views/apis/api/v1/{raspberry => ir}/commands/blink.jbuilder (100%) diff --git a/app/apis/api/v1/base.rb b/app/apis/api/v1/base.rb index 2ccd330..d60b3db 100644 --- a/app/apis/api/v1/base.rb +++ b/app/apis/api/v1/base.rb @@ -32,7 +32,7 @@ class Base < Grape::API mount V1::Users mount V1::Authorize - mount V1::Raspberry + mount V1::IR add_swagger_documentation format: :json, api_version: 'v1', hide_documentation_path: true end end diff --git a/app/apis/api/v1/ir.rb b/app/apis/api/v1/ir.rb new file mode 100644 index 0000000..ff8553e --- /dev/null +++ b/app/apis/api/v1/ir.rb @@ -0,0 +1,23 @@ +# app/apis/api/v1/ir.rb + +module API + module V1 + class IR < Grape::API + resource :ir do + desc 'LEDの点滅', notes: <<-NOTE +

LEDを点滅させる

+

+ LEDがつくよ +

+ NOTE + params do + requires :auth_token, type: String, desc: 'Auth token.' + end + get '/recieve', jbuilder: 'api/v1/ir/recieve' do + # path = File.join(Rails.root.to_s + 'commands/blink.sh') + # `sudo sh #{path}` + end + end + end + end +end diff --git a/app/apis/api/v1/raspberry.rb b/app/apis/api/v1/raspberry.rb deleted file mode 100644 index 1ee4eba..0000000 --- a/app/apis/api/v1/raspberry.rb +++ /dev/null @@ -1,56 +0,0 @@ -# app/apis/api/v1/raspberry.rb - -module API - module V1 - class Raspberry < Grape::API - resource :raspberry do - desc 'LEDの点滅', notes: <<-NOTE -

LEDを点滅させる

-

- LEDがつくよ -

- NOTE - params do - requires :auth_token, type: String, desc: 'Auth token.' - end - get '/commands/blink', jbuilder: 'api/v1/raspberry/commands/blink' do - if (token = AuthToken.find_by(token: params[:auth_token])) - if token.user.info - # path = File.join(Rails.root.to_s + 'commands/blink.sh') - # `sudo sh #{path}` - io = WiringPi::GPIO.new do |gpio| - gpio.pin_mode(0, WiringPi::OUTPUT) - # gpio.pin_mode(1, WiringPi::INPUT) - end - - # pin_state = io.digital_read(1) # Read from pin 1 - # puts pin_state - - io.digital_write(0, WiringPi::HIGH) # Turn pin 0 on - io.delay(100) # Wait - io.digital_write(0, WiringPi::LOW) # Turn pin 0 off - else - error!(meta: { - status: 400, - errors: [ - message: ('errors.messages.info_not_found'), - code: ErrorCodes::NOT_FOUND_INFO - ] - }, response: {}) - false - end - else - error!(meta: { - status: 400, - errors: [ - message: ('errors.messages.invalid_token'), - code: ErrorCodes::INVALID_TOKEN - ] - }, response: {}) - false - end - end - end - end - end -end diff --git a/app/views/apis/api/v1/raspberry/commands/blink.jbuilder b/app/views/apis/api/v1/ir/commands/blink.jbuilder similarity index 100% rename from app/views/apis/api/v1/raspberry/commands/blink.jbuilder rename to app/views/apis/api/v1/ir/commands/blink.jbuilder From 753d3e5aba4662bc99b42c3b7afb184be9058b38 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Mon, 7 Dec 2015 17:51:12 +0900 Subject: [PATCH 122/358] :construction: create receive jbuilder --- app/views/apis/api/v1/ir/recieve.jbuilder | 1 + 1 file changed, 1 insertion(+) create mode 100644 app/views/apis/api/v1/ir/recieve.jbuilder diff --git a/app/views/apis/api/v1/ir/recieve.jbuilder b/app/views/apis/api/v1/ir/recieve.jbuilder new file mode 100644 index 0000000..34835ed --- /dev/null +++ b/app/views/apis/api/v1/ir/recieve.jbuilder @@ -0,0 +1 @@ +json.hello "wa" \ No newline at end of file From f98272cbc4c10b5d640ed19b120c0d3772298925 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Mon, 7 Dec 2015 19:16:13 +0900 Subject: [PATCH 123/358] mkdir data --- data/.keep | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 data/.keep diff --git a/data/.keep b/data/.keep new file mode 100644 index 0000000..e69de29 From 46f9230856405bcb16acb8b2942ee5c258b15982 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Mon, 7 Dec 2015 19:16:36 +0900 Subject: [PATCH 124/358] =?UTF-8?q?=E3=83=95=E3=82=A1=E3=82=A4=E3=83=AB?= =?UTF-8?q?=E5=87=BA=E5=8A=9B=E7=94=A8=E3=81=AE=E3=83=97=E3=83=AD=E3=82=B0?= =?UTF-8?q?=E3=83=A9=E3=83=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- commands/recieve | Bin 0 -> 8586 bytes commands/recieve.c | 20 ++++++++++++++++++++ 2 files changed, 20 insertions(+) create mode 100755 commands/recieve create mode 100644 commands/recieve.c diff --git a/commands/recieve b/commands/recieve new file mode 100755 index 0000000000000000000000000000000000000000..8f57a3c8ac9efbf15547eed97bfd59642c7ffc3c GIT binary patch literal 8586 zcmeHMeQZ&955 zB^HgR$6Ce$Z7pqE{i%e1v#57H212^KdiRNtxE&i&qL^3UpZWmhe{`<@{nOuD^P?}n zd*hLbzrM9{YxC}nWXpd{-Zgnqv!R0a+6D0K3*hA2i+?ArLZDLl^gb%#TNc1U*AI^* z;(E#qB~4uiY|b#XUKEBBtwg z@BIu7@+}Pf2IC^qGBMwkU?$?5*3Ptq7kMFgX6*rDi06YD(>EK;JmyQs!dlO_<)4 z5i`Q3cQj-UKLW1R?j1DuR8cTwj%)xMZ4~(|@(JW8use!Y#Wc;kM6PH1!8KOzTD^3U zht@71Vzky?_?Kl1we>q|8+X?&Ip#S5Ut6_f{TAP&WJfyK{opG4`aS{ewe>G3oy%&J zm$4+PoCw1E(RYUOpM0_Ug&Mt99bfca zGVcv9Dwez$b%^#`43=0%+htbDQ!-zg|IZnJuR0xlDC_kX$!|$sQ>_Zs2POZK$RL3GY^an}18ornCUJt+QkRf9m*%85%@xCM`b9sc76ZlB3{{ zCrrcN-qF)yh7L>Va6IiFOh@rUGa3OuNyDMkF!&?K<5-@>&7_rc)JUeHiFlcyV_wpT zg~&jrMq?)Uqwy#{O#?Sq{vi}FFG1Ta@EgPWP%<=P=))1TWeNOYGm%W8LyH{=V9_{DJ$?zpvzVYZWqY2F_@kZc$^M=7 zKk2aN`K?jDD4q|=p5|<){Y!{ZTofM>&*$f*J^QzE9cKv$(zk%!J}2jyoU|WhL&>>4 znZM$&=kv){S>gS~hOr7@J1+K|!=Bfl)6}Vvcm#bxYbe z3#s&Q+MmZPyFH)h@j2gylBq~J?SJ90pOyY+rT;e^_Wb@B&PjXO-E8NdmWH#voc5Cr zdpdC-3dn~0PxikM-`zPCTTvyT7?w`-S zrt2^RiS;e1Bs2ae%&^<@ej+dJH8zx-?U;Y!uy2*;T&*%dj+2XFJCdO)c~P}PBJIYn0-pEmnQmAPJfD^04aIq?9KRpuokMm=q}{li=Xu4R z>4pdJ{-%=tgT?dja{Y&Z$9Fm22t01f@s+^iu^gw{f^xFP!7?~dt(Ilb_^N`>ir-h9 zN&6xf-Yn1oqMc~Gx?p}g1Oz_69l8-$U>Tfn_&Rn9px+( z|4C6!1GGBge_7zmVZx(gszg7;q^rVvd=qhszt7RHE+Jm2-F_>IYyh9bueA=$?+@1& z(4Rxx1@rquEjCmG#zUw7L_GaGjJOxS4xRmEozNGmWse<**W-J4_MeUg^q&&={Bd^x z@#V_>K$i!0iY`#jX~gR*#Q7@XUV8yD{RZO8l|~52{=h145e}vC&ij@e;?zELEkZ>5 zKcXqbslI)Va{eIod0%H~<2kd`ceYPn>eGD-kvNM+epBEADu3V$@|Gh)T7h__dpo)Z zu7rO@;1%Z2a3~hDUFktMX{O9H-n@kI#;$W +#include + +int main(int argc, char *argv[]){ + char *path; + if(argc >= 2){ + path = argv[1]; + }else{ + printf("Not select path!\n"); + return 0; + } + + FILE *fp; + char *fileName = "irdata.txt"; + strcat(path, fileName); + fp = fopen(path, "w"); + fprintf(fp, "Test\n"); + fclose(fp); + return 0; +} \ No newline at end of file From 21cdc4af7a44b7d3630a40c2e1dcddb6945a4aa4 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Mon, 7 Dec 2015 19:16:43 +0900 Subject: [PATCH 125/358] result output --- data/irdata.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 data/irdata.txt diff --git a/data/irdata.txt b/data/irdata.txt new file mode 100644 index 0000000..345e6ae --- /dev/null +++ b/data/irdata.txt @@ -0,0 +1 @@ +Test From 86e223cae8cd4b0dbf36d08a04b0c3135d94d93d Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Mon, 7 Dec 2015 19:16:56 +0900 Subject: [PATCH 126/358] edit file output api --- app/apis/api/v1/ir.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/apis/api/v1/ir.rb b/app/apis/api/v1/ir.rb index ff8553e..4c93c3f 100644 --- a/app/apis/api/v1/ir.rb +++ b/app/apis/api/v1/ir.rb @@ -14,8 +14,9 @@ class IR < Grape::API requires :auth_token, type: String, desc: 'Auth token.' end get '/recieve', jbuilder: 'api/v1/ir/recieve' do - # path = File.join(Rails.root.to_s + 'commands/blink.sh') - # `sudo sh #{path}` + path = Rails.root.to_s + command = File.join(path, "commands/recieve") + `#{command} #{path}/data/` end end end From ba99025bfbdb8305d0f4c3dccecd1034420fa17a Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Mon, 7 Dec 2015 21:00:19 +0900 Subject: [PATCH 127/358] .gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 050c9d9..012a20d 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,5 @@ /log/* !/log/.keep /tmp + +/data/* \ No newline at end of file From a08af5e404bf42022ec73a198b813841efe50089 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Mon, 7 Dec 2015 21:00:27 +0900 Subject: [PATCH 128/358] remove --- data/irdata.txt | 1 - 1 file changed, 1 deletion(-) delete mode 100644 data/irdata.txt diff --git a/data/irdata.txt b/data/irdata.txt deleted file mode 100644 index 345e6ae..0000000 --- a/data/irdata.txt +++ /dev/null @@ -1 +0,0 @@ -Test From 68b514d75ca46992cbf078fe1acea15c986357ff Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Mon, 7 Dec 2015 21:00:35 +0900 Subject: [PATCH 129/358] update ir.rb --- app/apis/api/v1/ir.rb | 38 +++++++++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/app/apis/api/v1/ir.rb b/app/apis/api/v1/ir.rb index 4c93c3f..95e0200 100644 --- a/app/apis/api/v1/ir.rb +++ b/app/apis/api/v1/ir.rb @@ -4,19 +4,43 @@ module API module V1 class IR < Grape::API resource :ir do - desc 'LEDの点滅', notes: <<-NOTE -

LEDを点滅させる

+ desc '赤外線の受信', notes: <<-NOTE +

赤外線を受信します

- LEDがつくよ + 赤外線を受信します

NOTE params do requires :auth_token, type: String, desc: 'Auth token.' end - get '/recieve', jbuilder: 'api/v1/ir/recieve' do - path = Rails.root.to_s - command = File.join(path, "commands/recieve") - `#{command} #{path}/data/` + post '/recieve', jbuilder: 'api/v1/ir/recieve' do + if (token = AuthToken.find_by(token: params[:auth_token])) + if user.info.nil? + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.user_not_found'), + code: ErrorCodes::NOT_FOUND_USER + ] + }, response: {}) + else + infrared = user.infrareds.create(name: "名無しの赤外線", data: "") + path = Rails.root.to_s + command = File.join(path, "commands/recieve") + fname = "user_#{user.id}_ir_#{infrared.id}.txt" + `#{command} #{path}/data/#{fname}` + infrared.update(data: "#{fname}") + @infrared = infrared + end + else + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.invalid_token'), + code: ErrorCodes::INVALID_TOKEN + ] + }, response: {}) + end end end end From 4cb4b7155c4a87d38567136477394d1e6ce9286a Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Mon, 7 Dec 2015 21:00:42 +0900 Subject: [PATCH 130/358] add jbuilder --- app/views/apis/api/v1/ir/recieve.jbuilder | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/views/apis/api/v1/ir/recieve.jbuilder b/app/views/apis/api/v1/ir/recieve.jbuilder index 34835ed..54a3f01 100644 --- a/app/views/apis/api/v1/ir/recieve.jbuilder +++ b/app/views/apis/api/v1/ir/recieve.jbuilder @@ -1 +1,7 @@ -json.hello "wa" \ No newline at end of file +json.meta do + json.status 201 + json.message '赤外線を作成しました。' +end +json.response do + json.infrared @infrared +end From d621b5845a79dd8b031b12aaba8e35b1b9dbaae3 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Mon, 7 Dec 2015 21:00:50 +0900 Subject: [PATCH 131/358] create recieve.c --- commands/recieve | Bin 8586 -> 8534 bytes commands/recieve.c | 8 ++++---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/commands/recieve b/commands/recieve index 8f57a3c8ac9efbf15547eed97bfd59642c7ffc3c..acf09606ec91f135c0c9569b79eba0fbe6ef04a9 100755 GIT binary patch delta 1475 zcmYLJeP~-%6u&nwpY58DCNZCF64ug8W3vh+sb78BR`#MpQduF@Su<@*855)Hww5_( zsOX+$l6e?Y1~M2}MZwuJUFTOu-O~K$K+ClL5zCa6RmjGK4AkejFE@HZ&bhzex#!&T z&i#06`^vVw+g8L3U<`lc;ysH3!@9+8HR=&B?1 z^Qk{?EI)f%d+6NF?k%@9)lYU_fOj<$kP+OFGHbyv?0_jD0v`)qMxs%F1XhJMIskWt z)5oNl4P)gTX0ALyQN4gmN;BUXm+ET~qVzu193)ET9@LhAh$Dt4n0vjfpmaXTFvgPg z?^XO5!>sc4f{M2>EHHdt#Sb#9W%#V3^eR1nB;{)(lDsC(+^D8@CyRx$UL;cSa!NJD zA9NzA%wgo6e4Z66&FU6mRM%y#GzAGc`1qHiIYW?KgEP90-mj5V99QCX?o&ik-}RT* zuIkRX0-$P?lyzqa+Vh zFFlMMN1`gpE0SES6#r2a32!8(_o`O<7pN`nFKq z!oy_u*n!C=^2Cdi!2@Ia$DW@IX7^4`gxE6FCp;8E%Q_tY8^h4Pg5g=THMDuO$Kf}_ zeY(nDijo1RadSwE{1N0y!fbs*v%N*HIkd@uC$R&mQT%6M*w{sv7jniq9h@~zK-etW zvi$tEut1bBOq&BV1Mi_8ghg{dor1gOKx<79RX;zzq%6R_mTp>rVM~C{L(XHzlzX6J zafd$ODL?1-Dz_`#{tmz5>@w9Zh}Pp8`XQ8BqqYpspJ8VVWe^f(7X2r{9_nXRYbsCXCcE?QNKpk~M$^8XxM$Y3>d+Zd9qyV2GDkJ9jH=Iik}VZ`U9ewg+h#;R}m zT%Jaqv|a|;hn5l#5h3Jv(eu#f--+=#e^gV|!@U1(54-G4_)|yPF)~QpSio>w6c>?E zhhedeh0*pX-3mSJxD4+nZ#gMoR4ZvADcIZY8kBgm)WoQMp;FA2i1lS4h%;OGX0>O+Pg!pSKwtoS(j{%8HNyL3FXRuDCUW;?_(=9Ivu_ zo_m*HzBM&d^jYOM56WVHEc%}gKCj}eFvJcc6OYe`3igUsmbXSn`uj#PDh6c%_zyt9 zn_@9*$GhUCcY@AdV{M+n%wk}D@_{Y+ISrGC8L0~tr%!%oTTR#O+fxeZiYn5MfJP&Z zhj`4^W}2kp363cSwh{&|;Fzb~iW@keW0B*9bh?uQaygO1iH{8jfn$l|7~zAzwMA~f zrbq7UlRu|AjV=z{y%&hQ zhTT$m&3iS=5xYLC6`a2`{e~|iV$oL7nUtJv>9ISQ(-lZJ?9s0Qr{7R~PDHIvs z&?Bc3lj9rg?O{FIlF*}?O^>uB^|hAN6~3ovXNvfw9$D8TYsvVdbo$1e!S8Zch@+5) z*RP_(qBLLTFxv8vyT3@|>pbJHj&HxDsN{hx@#AXD5Iyo{`JML2K>4PA?m)k_6xz>K z^x*53Dz=0(mJ`A)3qG=_{@?$hMfp_$FuLwHMh5yu`>IFBMzO(KP{9hthAPU!>kZtK z%rVL|Og2R}M)nMjTlY%~e-n#eSofA~kl#h(q0#PqUue#=2-A;Q>9v*9_m%a&Vucnr-4M zjsQ#GwBL;(TMs53%KmlJ^%v9rWm=1*8A%>D?URy*x0!dT&N(HpIIiTYt}!v=GR7Ys zNf$D=>Pnbw!epJ;=vL)TlikFyyEYfhB#?tQ+|RhO+f|GL0>qGcR5^Rtd93%;y5eR? z-1Hg736Hw_(TAk$7FH;7imsZ=6z)*utchmLY6P*-tIGd<_F-?WoHBh_rl|HE&Xvl@O<;*)t};&KsJN;>f;mM=d`o5}|&;gUbFS8!)Kv!=DS Sw>32%KU96Fx&|A{3jYOI)1M3g diff --git a/commands/recieve.c b/commands/recieve.c index 1ae5aca..124048f 100644 --- a/commands/recieve.c +++ b/commands/recieve.c @@ -3,17 +3,17 @@ int main(int argc, char *argv[]){ char *path; + char *fileName; if(argc >= 2){ - path = argv[1]; + fileName = argv[1]; }else{ printf("Not select path!\n"); return 0; } FILE *fp; - char *fileName = "irdata.txt"; - strcat(path, fileName); - fp = fopen(path, "w"); + + fp = fopen(fileName, "w"); fprintf(fp, "Test\n"); fclose(fp); return 0; From 3524dd28dc1a5a02402a3c9d33c813990299eea3 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Tue, 8 Dec 2015 01:24:59 +0900 Subject: [PATCH 132/358] update error_codes --- lib/error_codes.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/error_codes.rb b/lib/error_codes.rb index c7388fa..4680aa0 100644 --- a/lib/error_codes.rb +++ b/lib/error_codes.rb @@ -9,7 +9,7 @@ module ErrorCodes NOT_FOUND_USER = 8 SERIAL_PARAMS = 9 DATA_PARAM_NIL = 10 - NO_DEVICES = 11 + FAIL_SHELLSCRIPT = 11 DEVICE_ID_NOT_SPECIFIED = 12 DEVICE_NOT_FOUND = 13 TIME_SPAN_NOT_SPECIFIED = 14 From 1c6dc6adda1d54eb8647783cfd283741c4f710e0 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Tue, 8 Dec 2015 01:25:25 +0900 Subject: [PATCH 133/358] remove --- commands/recieve | Bin 8534 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100755 commands/recieve diff --git a/commands/recieve b/commands/recieve deleted file mode 100755 index acf09606ec91f135c0c9569b79eba0fbe6ef04a9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8534 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

Date: Tue, 8 Dec 2015 01:25:35 +0900 Subject: [PATCH 134/358] update jbuilder --- app/views/apis/api/v1/ir/recieve.jbuilder | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/apis/api/v1/ir/recieve.jbuilder b/app/views/apis/api/v1/ir/recieve.jbuilder index 54a3f01..8243d19 100644 --- a/app/views/apis/api/v1/ir/recieve.jbuilder +++ b/app/views/apis/api/v1/ir/recieve.jbuilder @@ -1,6 +1,6 @@ json.meta do json.status 201 - json.message '赤外線を作成しました。' + json.message '赤外線データを作成しました。' end json.response do json.infrared @infrared From 350a991ca1bfc44ef5ed4bba351a3c3326d98114 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Tue, 8 Dec 2015 01:25:48 +0900 Subject: [PATCH 135/358] update error code --- app/apis/api/v1/ir.rb | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/app/apis/api/v1/ir.rb b/app/apis/api/v1/ir.rb index 95e0200..53d12fa 100644 --- a/app/apis/api/v1/ir.rb +++ b/app/apis/api/v1/ir.rb @@ -29,6 +29,16 @@ class IR < Grape::API command = File.join(path, "commands/recieve") fname = "user_#{user.id}_ir_#{infrared.id}.txt" `#{command} #{path}/data/#{fname}` + status = `echo %ERRORLEVEL%` + if(status != 0){ + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.fail_shell_sclipt'), + code: ErrorCodes::FAIL_SHELLSCRIPT + ] + }, response: {}) + } infrared.update(data: "#{fname}") @infrared = infrared end From 9bf0038179b4101f00b33fce396fffde0d9f4dbc Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Tue, 8 Dec 2015 01:25:54 +0900 Subject: [PATCH 136/358] update c --- commands/recieve.c | 117 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 101 insertions(+), 16 deletions(-) diff --git a/commands/recieve.c b/commands/recieve.c index 124048f..c900e3c 100644 --- a/commands/recieve.c +++ b/commands/recieve.c @@ -1,20 +1,105 @@ +#include #include -#include - -int main(int argc, char *argv[]){ - char *path; - char *fileName; - if(argc >= 2){ - fileName = argv[1]; - }else{ - printf("Not select path!\n"); +#include +#include +#include + +int readable = 1; // 非同期でイベントが発生した場合、コールバックにより0に設定される +int pin = 7; // 入力ピン番号(wiringpiの番号) +int span = 10; // 継続時間判定の間隔(us) +int max_wait = 40000; // 最大継続時間(us) + +void signalErrorCallBack(int sig) +{ + readable = 0; +} + +double getTime() //tv_sec : 指定する時間の1秒以上の部分,tv_usec : 指定する時間の1秒未満の部分 +{ + struct timeval tv; + gettimeofday(&tv, NULL); + return ((double)(tv.tv_sec) * 1000000 + (double)(tv.tv_usec)); +} + +int main(int argc, char *argv[]) +{ + int result; + + // スキャンデータを書きだすファイルのポインタを取得 + FILE *fp; + char *fileName = "irdata.txt"; + if(argc >= 2){ fileName = argv[1]; } + if((fp = fopen(fileName, "w")) == NULL){ + exit(1); + } + printf("write file: %s\n", fileName); + + // signal関数は、シグナル(非同期イベント)が発生したときに、 + // そのシグナルを受信して、シグナル特有の処理を行うシグナル処理関数(シグナルハンドラ)を登録します。 + if(signal(SIGINT, signalErrorCallBack) == SIG_ERR){ + exit(1); + } + + // wiringpiのセットアップ + if(wiringPiSetup() == -1){ + exit(1); + } + + pinMode(pin, INPUT); + + // スキャン開始 + result = scan(fp); + + close(fp); + + if(result || !readable){ + exit(1); + } else { + reutrn(0) + } return 0; - } +} + +int scan(FILE *fp) +{ + // 受光モジュールは受光するとLOWになる + if(!digitalRead(pin)){ return 1; } + + int on, off; + + // 送信が開始されるまで待機 + while( readable && digitalRead(pin) ){} + + // 解析開始 + while( readable ){ + on = getActivateTime(0); + off = getActivateTime(1); + fprintf(fp, "%6d %6d\n", on, off); + if(off > max_wait){ break; } + } + + return 0; +} + +int getActivateTime(int status) +{ + int count = 0; + int max = max_wait / span; + double start, end; + + start = getTime(); + while( digitalRead(pin) == status ) + { + delayMicroseconds(span); + count++; + if(count > max){ break; } + } + end = getTime(); - FILE *fp; + return getSpan(start, end); +} - fp = fopen(fileName, "w"); - fprintf(fp, "Test\n"); - fclose(fp); - return 0; -} \ No newline at end of file +int getSpan(double t1, double t2) +{ + return (int)(t2-t1); +} From 35a732b36cb733f2cf2ef7a093e82fbf5146239b Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Tue, 8 Dec 2015 01:28:49 +0900 Subject: [PATCH 137/358] :bug: fix --- app/apis/api/v1/ir.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/apis/api/v1/ir.rb b/app/apis/api/v1/ir.rb index 53d12fa..d882862 100644 --- a/app/apis/api/v1/ir.rb +++ b/app/apis/api/v1/ir.rb @@ -30,7 +30,7 @@ class IR < Grape::API fname = "user_#{user.id}_ir_#{infrared.id}.txt" `#{command} #{path}/data/#{fname}` status = `echo %ERRORLEVEL%` - if(status != 0){ + if status != 0 error!(meta: { status: 400, errors: [ @@ -38,7 +38,7 @@ class IR < Grape::API code: ErrorCodes::FAIL_SHELLSCRIPT ] }, response: {}) - } + end infrared.update(data: "#{fname}") @infrared = infrared end From 789c618b64b07dc6bf98ea64e9d55e766c99f0c8 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Tue, 8 Dec 2015 02:03:09 +0900 Subject: [PATCH 138/358] :bug: fix --- app/apis/api/v1/ir.rb | 10 ---------- commands/recieve.c | 2 +- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/app/apis/api/v1/ir.rb b/app/apis/api/v1/ir.rb index d882862..95e0200 100644 --- a/app/apis/api/v1/ir.rb +++ b/app/apis/api/v1/ir.rb @@ -29,16 +29,6 @@ class IR < Grape::API command = File.join(path, "commands/recieve") fname = "user_#{user.id}_ir_#{infrared.id}.txt" `#{command} #{path}/data/#{fname}` - status = `echo %ERRORLEVEL%` - if status != 0 - error!(meta: { - status: 400, - errors: [ - message: ('errors.messages.fail_shell_sclipt'), - code: ErrorCodes::FAIL_SHELLSCRIPT - ] - }, response: {}) - end infrared.update(data: "#{fname}") @infrared = infrared end diff --git a/commands/recieve.c b/commands/recieve.c index c900e3c..5d3816f 100644 --- a/commands/recieve.c +++ b/commands/recieve.c @@ -55,7 +55,7 @@ int main(int argc, char *argv[]) if(result || !readable){ exit(1); } else { - reutrn(0) + return(0); } return 0; } From 45507b1f2bb505160b7b169fbf8396bb8171f9c8 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Tue, 8 Dec 2015 02:40:54 +0900 Subject: [PATCH 139/358] update recieve.c --- commands/recieve.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/commands/recieve.c b/commands/recieve.c index 5d3816f..56863e2 100644 --- a/commands/recieve.c +++ b/commands/recieve.c @@ -6,6 +6,8 @@ int readable = 1; // 非同期でイベントが発生した場合、コールバックにより0に設定される int pin = 7; // 入力ピン番号(wiringpiの番号) +int good_pin = 25; // ok led +int bad_pin = 24; // bad led int span = 10; // 継続時間判定の間隔(us) int max_wait = 40000; // 最大継続時間(us) @@ -46,6 +48,8 @@ int main(int argc, char *argv[]) } pinMode(pin, INPUT); + pinMode(good_pin, OUTPUT); + pinMode(bad_pin, OUTPUT); // スキャン開始 result = scan(fp); @@ -53,8 +57,24 @@ int main(int argc, char *argv[]) close(fp); if(result || !readable){ + int i = 0; + while(i<10){ + digitalWrite(bad_pin, 1); + delay(500); + digitalWrite(bad_pin, 0); + delay(500); + i++; + } exit(1); } else { + int i = 0; + while(i<10){ + digitalWrite(good_pin, 1); + delay(500); + digitalWrite(good_pin, 0); + delay(500); + i++; + } return(0); } return 0; From b37a95ed95b4b2b0cc626d0fcc58944633de7e6d Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Tue, 8 Dec 2015 02:49:55 +0900 Subject: [PATCH 140/358] change blink short time --- commands/recieve.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/commands/recieve.c b/commands/recieve.c index 56863e2..3f314c8 100644 --- a/commands/recieve.c +++ b/commands/recieve.c @@ -58,7 +58,7 @@ int main(int argc, char *argv[]) if(result || !readable){ int i = 0; - while(i<10){ + while(i<4){ digitalWrite(bad_pin, 1); delay(500); digitalWrite(bad_pin, 0); @@ -68,7 +68,7 @@ int main(int argc, char *argv[]) exit(1); } else { int i = 0; - while(i<10){ + while(i<4){ digitalWrite(good_pin, 1); delay(500); digitalWrite(good_pin, 0); From ad4f4820f47d78721b9b8ed3aa5a6f392ad9c185 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Tue, 8 Dec 2015 03:06:06 +0900 Subject: [PATCH 141/358] add limit time --- commands/recieve.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/commands/recieve.c b/commands/recieve.c index 3f314c8..92f20a5 100644 --- a/commands/recieve.c +++ b/commands/recieve.c @@ -85,10 +85,16 @@ int scan(FILE *fp) // 受光モジュールは受光するとLOWになる if(!digitalRead(pin)){ return 1; } - int on, off; - + int on, off, limit; + limit = 0; // 送信が開始されるまで待機 - while( readable && digitalRead(pin) ){} + while( readable && digitalRead(pin) && limit <= 10000 ){ + limit++; + } + + if(limit >= 10000){ + return 1; + } // 解析開始 while( readable ){ From 78d39d147f56cc9c445651302430e0fe84c4ff19 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Tue, 8 Dec 2015 03:14:31 +0900 Subject: [PATCH 142/358] change limit --- commands/recieve.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commands/recieve.c b/commands/recieve.c index 92f20a5..9b0408d 100644 --- a/commands/recieve.c +++ b/commands/recieve.c @@ -92,7 +92,7 @@ int scan(FILE *fp) limit++; } - if(limit >= 10000){ + if(limit >= 100000){ return 1; } From 86b9da216a227cf3689b75de7275f7a146110783 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Tue, 8 Dec 2015 03:39:45 +0900 Subject: [PATCH 143/358] update --- commands/recieve.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/commands/recieve.c b/commands/recieve.c index 9b0408d..e54d04f 100644 --- a/commands/recieve.c +++ b/commands/recieve.c @@ -88,11 +88,12 @@ int scan(FILE *fp) int on, off, limit; limit = 0; // 送信が開始されるまで待機 - while( readable && digitalRead(pin) && limit <= 10000 ){ + while( readable && digitalRead(pin) && limit <= 50000000 ){ limit++; } - if(limit >= 100000){ + if(limit >= 50000000){ + readable = 1; return 1; } From 5bdfc0f12c51a5f847d78a706834d6106ca7a35d Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Tue, 8 Dec 2015 03:54:16 +0900 Subject: [PATCH 144/358] update --- app/apis/api/v1/ir.rb | 10 ++++++++++ lib/error_codes.rb | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/app/apis/api/v1/ir.rb b/app/apis/api/v1/ir.rb index 95e0200..94de369 100644 --- a/app/apis/api/v1/ir.rb +++ b/app/apis/api/v1/ir.rb @@ -29,6 +29,16 @@ class IR < Grape::API command = File.join(path, "commands/recieve") fname = "user_#{user.id}_ir_#{infrared.id}.txt" `#{command} #{path}/data/#{fname}` + if File.read("#{path}/data/#{fname}").size == 0 + infrared.destroy + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.fail_scanir'), + code: ErrorCodes::FAIL_SCANIR + ] + }, response: {}) + end infrared.update(data: "#{fname}") @infrared = infrared end diff --git a/lib/error_codes.rb b/lib/error_codes.rb index 4680aa0..78f0f2b 100644 --- a/lib/error_codes.rb +++ b/lib/error_codes.rb @@ -9,7 +9,7 @@ module ErrorCodes NOT_FOUND_USER = 8 SERIAL_PARAMS = 9 DATA_PARAM_NIL = 10 - FAIL_SHELLSCRIPT = 11 + FAIL_SCANIR = 11 DEVICE_ID_NOT_SPECIFIED = 12 DEVICE_NOT_FOUND = 13 TIME_SPAN_NOT_SPECIFIED = 14 From 60a1c95329b48511e65baaa7c2c1d44e84c43da1 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Tue, 8 Dec 2015 04:29:28 +0900 Subject: [PATCH 145/358] create get ir api --- app/apis/api/v1/ir.rb | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/app/apis/api/v1/ir.rb b/app/apis/api/v1/ir.rb index 95e0200..b19f5cc 100644 --- a/app/apis/api/v1/ir.rb +++ b/app/apis/api/v1/ir.rb @@ -4,6 +4,39 @@ module API module V1 class IR < Grape::API resource :ir do + desc '赤外線一覧の表示', notes: <<-NOTE +

赤外線一覧の表示

+

+ 赤外線一覧を表示します +

+ NOTE + params do + requires :auth_token, type: String, desc: 'Auth token.' + end + get '/', jbuilder: 'api/v1/ir/index' do + if (token = AuthToken.find_by(token: params[:auth_token])) + if user.info.nil? + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.user_not_found'), + code: ErrorCodes::NOT_FOUND_USER + ] + }, response: {}) + else + @infrareds = user.infrareds + end + else + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.invalid_token'), + code: ErrorCodes::INVALID_TOKEN + ] + }, response: {}) + end + end + desc '赤外線の受信', notes: <<-NOTE

赤外線を受信します

@@ -30,7 +63,7 @@ class IR < Grape::API fname = "user_#{user.id}_ir_#{infrared.id}.txt" `#{command} #{path}/data/#{fname}` infrared.update(data: "#{fname}") - @infrared = infrared + @infrared = infrared.id end else error!(meta: { From 58f14dd8fee02c6cb7968b4785e031986411cc18 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Tue, 8 Dec 2015 04:29:36 +0900 Subject: [PATCH 146/358] create ir/index jbuilder --- app/views/apis/api/v1/ir/index.jbuilder | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 app/views/apis/api/v1/ir/index.jbuilder diff --git a/app/views/apis/api/v1/ir/index.jbuilder b/app/views/apis/api/v1/ir/index.jbuilder new file mode 100644 index 0000000..2f7f6a6 --- /dev/null +++ b/app/views/apis/api/v1/ir/index.jbuilder @@ -0,0 +1,8 @@ +json.meta do + json.status 200 + json.message '赤外線データ一覧を受信しました。' +end +json.response do + json.infrareds @infrareds, :name, :id, :updated_at +end + From 96aba6ac2956c724d44a595dfd8664a57fa14cba Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Tue, 8 Dec 2015 04:29:50 +0900 Subject: [PATCH 147/358] fix response data --- app/views/apis/api/v1/ir/recieve.jbuilder | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/apis/api/v1/ir/recieve.jbuilder b/app/views/apis/api/v1/ir/recieve.jbuilder index 8243d19..5e0a264 100644 --- a/app/views/apis/api/v1/ir/recieve.jbuilder +++ b/app/views/apis/api/v1/ir/recieve.jbuilder @@ -3,5 +3,5 @@ json.meta do json.message '赤外線データを作成しました。' end json.response do - json.infrared @infrared + json.ir_id @infrared end From 473be460a33d23ba0be2fefaf3534c750107e30c Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Tue, 8 Dec 2015 04:50:03 +0900 Subject: [PATCH 148/358] create ir rename api --- app/apis/api/v1/ir.rb | 45 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/app/apis/api/v1/ir.rb b/app/apis/api/v1/ir.rb index 666ff03..3f80527 100644 --- a/app/apis/api/v1/ir.rb +++ b/app/apis/api/v1/ir.rb @@ -85,6 +85,51 @@ class IR < Grape::API }, response: {}) end end + desc '赤外線の名前変更', notes: <<-NOTE +

赤外線の名前を変更します

+

+ 赤外線名を変更します +

+ NOTE + params do + requires :auth_token, type: String, desc: 'Auth token.' + requires :name, type: String, desc: 'IR name.' + requires :ir_id, type: Integer, desc: 'IR Id.' + end + put '/rename', jbuilder: 'api/v1/ir/rename' do + if (token = AuthToken.find_by(token: params[:auth_token])) + if user.info.nil? + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.user_not_found'), + code: ErrorCodes::NOT_FOUND_USER + ] + }, response: {}) + else + if infrared = user.infrareds.find_by(id: params[:ir_id]) + infrared.update(name: params[:name]) + @infrared = infrared + else + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.ir_not_found'), + code: ErrorCodes::NOT_FOUND + ] + }, response: {}) + end + end + else + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.invalid_token'), + code: ErrorCodes::INVALID_TOKEN + ] + }, response: {}) + end + end end end end From c52224efcb0b84f40ffaa88177d3c6aa7584962d Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Tue, 8 Dec 2015 04:50:11 +0900 Subject: [PATCH 149/358] create rename jbuilder --- app/views/apis/api/v1/ir/rename.jbuilder | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 app/views/apis/api/v1/ir/rename.jbuilder diff --git a/app/views/apis/api/v1/ir/rename.jbuilder b/app/views/apis/api/v1/ir/rename.jbuilder new file mode 100644 index 0000000..72916a8 --- /dev/null +++ b/app/views/apis/api/v1/ir/rename.jbuilder @@ -0,0 +1,7 @@ +json.meta do + json.status 200 + json.message '赤外線名を変更しました。' +end +json.response do + json.infrared @infrared, :name, :id, :updated_at +end From 44ea5337573a71a1f950f05ba20517c811eb5646 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Tue, 8 Dec 2015 05:02:05 +0900 Subject: [PATCH 150/358] create delete ir api --- app/apis/api/v1/ir.rb | 46 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/app/apis/api/v1/ir.rb b/app/apis/api/v1/ir.rb index 3f80527..3119c2b 100644 --- a/app/apis/api/v1/ir.rb +++ b/app/apis/api/v1/ir.rb @@ -130,6 +130,52 @@ class IR < Grape::API }, response: {}) end end + desc '赤外線の削除', notes: <<-NOTE +

赤外線を削除します

+

+ 赤外線をデータベースから削除します +

+ NOTE + params do + requires :auth_token, type: String, desc: 'Auth token.' + requires :ir_id, type: Integer, desc: 'IR Id.' + end + delete '/', jbuilder: 'api/v1/ir/destroy' do + if (token = AuthToken.find_by(token: params[:auth_token])) + if user.info.nil? + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.user_not_found'), + code: ErrorCodes::NOT_FOUND_USER + ] + }, response: {}) + else + if infrared = user.infrareds.find_by(id: params[:ir_id]) + name = infrared.data + file = Rails.root.to_s + "/data/" + name + File.delete file + infrared.destroy + else + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.ir_not_found'), + code: ErrorCodes::NOT_FOUND + ] + }, response: {}) + end + end + else + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.invalid_token'), + code: ErrorCodes::INVALID_TOKEN + ] + }, response: {}) + end + end end end end From 37c81009da73ed4b0fb4bab5827f5c721b8ae455 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Tue, 8 Dec 2015 05:02:18 +0900 Subject: [PATCH 151/358] create destroy jbuilder --- app/views/apis/api/v1/ir/destroy.jbuilder | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 app/views/apis/api/v1/ir/destroy.jbuilder diff --git a/app/views/apis/api/v1/ir/destroy.jbuilder b/app/views/apis/api/v1/ir/destroy.jbuilder new file mode 100644 index 0000000..e334340 --- /dev/null +++ b/app/views/apis/api/v1/ir/destroy.jbuilder @@ -0,0 +1,6 @@ +json.meta do + json.status 200 + json.message '赤外線データを削除しました。' +end +json.response do +end From ce12d4a0f8388e7e26f3cd8a5624f493f4dc3b46 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Tue, 8 Dec 2015 11:50:37 +0900 Subject: [PATCH 152/358] add dependent --- app/models/log.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/log.rb b/app/models/log.rb index 68487c1..3334adb 100644 --- a/app/models/log.rb +++ b/app/models/log.rb @@ -1,5 +1,5 @@ class Log < ActiveRecord::Base belongs_to :user - has_one :infrared_group - has_one :infrared + has_one :infrared_group, dependent: :destroy + has_one :infrared, dependent: :destroy end From a22764978170ae7dbcfce84367b6170b6cc0f5d7 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Tue, 8 Dec 2015 16:29:47 +0900 Subject: [PATCH 153/358] create send.c --- commands/send.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 commands/send.c diff --git a/commands/send.c b/commands/send.c new file mode 100644 index 0000000..5528358 --- /dev/null +++ b/commands/send.c @@ -0,0 +1,99 @@ +#include +#include +#include +#include +#include +#define BUF_LEN 256 + +int send_pin = 0; + +int khz = 38 * 1000; // 周波数(KHz) +int d_num = 1; // duty比(分子) +int d_denomi = 3; // duty比(分母) +int unit = 26; // ユニット長us +int d_high; // HIGH時間 +int d_low; // LOW時間 + +void high(int on_time) +{ + // パルス信号に変換して送信 + int i; + int count = on_time/unit; + for(i=0; i= 2){ fileName = argv[1]; } //読み込むフィル名 + if((fp = fopen(fileName, "r")) == NULL){ + exit(1); + } + + // wiringpiのセットアップ + if(wiringPiSetup() == -1){ + exit(1); + } + + pinMode(send_pin, OUTPUT); + + // unit長 1sec = 1 * 10^6 us + unit = (1.0f / khz) * 1000000; + d_high = roundf(((float)unit / d_denomi) * d_num); + unit = (int)unit; //us + d_low = unit - d_high; + + // 準備完了 + + // データ読み込みと赤外線の送信 + readAndSend(fp); + + fclose(fp); + + return 0; +} From 9126ff7c6d0f934fa0a41775b6afd5f3f084d298 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Tue, 8 Dec 2015 16:47:14 +0900 Subject: [PATCH 154/358] create send api --- app/apis/api/v1/ir.rb | 47 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/app/apis/api/v1/ir.rb b/app/apis/api/v1/ir.rb index 3119c2b..5bccdb1 100644 --- a/app/apis/api/v1/ir.rb +++ b/app/apis/api/v1/ir.rb @@ -85,6 +85,53 @@ class IR < Grape::API }, response: {}) end end + desc '赤外線の送信', notes: <<-NOTE +

赤外線を送信します

+

+ 赤外線を照射します +

+ NOTE + params do + requires :auth_token, type: String, desc: 'Auth token.' + requires :ir_id, type: Integer, desc: 'IR Id.' + end + post '/send', jbuilder: 'api/v1/ir/send' do + if (token = AuthToken.find_by(token: params[:auth_token])) + if user.info.nil? + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.user_not_found'), + code: ErrorCodes::NOT_FOUND_USER + ] + }, response: {}) + else + if infrared = user.infrareds.find_by(id: params[:ir_id]) + fname = infrared.data + path = Rails.root.to_s + command = File.join(path, "commands/send") + `#{command} #{path}/data/#{fname}` + @infrared = infrared + else + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.ir_not_found'), + code: ErrorCodes::NOT_FOUND + ] + }, response: {}) + end + end + else + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.invalid_token'), + code: ErrorCodes::INVALID_TOKEN + ] + }, response: {}) + end + end desc '赤外線の名前変更', notes: <<-NOTE

赤外線の名前を変更します

From f9f46edd226b60c94060d8369fa9998ef1835289 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Tue, 8 Dec 2015 16:47:21 +0900 Subject: [PATCH 155/358] create send jbuilder --- app/views/apis/api/v1/ir/send.jbuilder | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 app/views/apis/api/v1/ir/send.jbuilder diff --git a/app/views/apis/api/v1/ir/send.jbuilder b/app/views/apis/api/v1/ir/send.jbuilder new file mode 100644 index 0000000..f266870 --- /dev/null +++ b/app/views/apis/api/v1/ir/send.jbuilder @@ -0,0 +1,7 @@ +json.meta do + json.status 201 + json.message '赤外線データを照射しました。' +end +json.response do + json.ir_id @infrared +end From 719bcd0b4099e1e31e80cbb2e7456a57e5e420bc Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Wed, 9 Dec 2015 01:00:42 +0900 Subject: [PATCH 156/358] update read --- README.rdoc | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/README.rdoc b/README.rdoc index f1c2c1f..0616149 100644 --- a/README.rdoc +++ b/README.rdoc @@ -5,3 +5,15 @@ 基本git flowの思想の元ブランチは切っていて、 circleCIでテストを動かして通らない場合はプルリクを受け付けない方針をとっています。 + +### 受信コマンドコンパイル + +``` +sudo gcc recieve.c -o recieve -lwiringPi +``` + +### 送信コマンドコンパイル + +``` +sudo gcc send.c -lm -o send -lwiringPi +``` \ No newline at end of file From ef7f61cf78a284bb1cf51a590fb5d3379a62cf5e Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Wed, 9 Dec 2015 01:06:07 +0900 Subject: [PATCH 157/358] rename --- README.rdoc => README.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename README.rdoc => README.md (100%) diff --git a/README.rdoc b/README.md similarity index 100% rename from README.rdoc rename to README.md From 1ebcef2ae9008c37506186cc595ed505da20a57f Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Wed, 9 Dec 2015 01:06:50 +0900 Subject: [PATCH 158/358] update --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0616149..171e5db 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -== Switch API +# Switch API 大学のプロジェクト課題で作成したAPIサーバーです。 家電製品を動かしたいという欲望で動いてるデザイアドリブン駆動なプロジェクトです。 From a5862ad08a3f62319dd47e265da08902407e95c5 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Wed, 9 Dec 2015 01:21:13 +0900 Subject: [PATCH 159/358] remove column --- db/migrate/20151204132603_create_infrared_groups.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/db/migrate/20151204132603_create_infrared_groups.rb b/db/migrate/20151204132603_create_infrared_groups.rb index d8022fd..6ff1cd2 100644 --- a/db/migrate/20151204132603_create_infrared_groups.rb +++ b/db/migrate/20151204132603_create_infrared_groups.rb @@ -3,7 +3,6 @@ def change create_table :infrared_groups do |t| t.string :name t.references :user, index: true, foreign_key: true - t.references :log, index: true, foreign_key: true t.timestamps null: false end From 7d1281f22d2cafcd70f7b47c560eba71fc82acd4 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Wed, 9 Dec 2015 01:21:22 +0900 Subject: [PATCH 160/358] rake db:migrate --- db/schema.rb | 2 -- 1 file changed, 2 deletions(-) diff --git a/db/schema.rb b/db/schema.rb index 36076d5..07b12a8 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -25,12 +25,10 @@ create_table "infrared_groups", force: :cascade do |t| t.string "name" t.integer "user_id" - t.integer "log_id" t.datetime "created_at", null: false t.datetime "updated_at", null: false end - add_index "infrared_groups", ["log_id"], name: "index_infrared_groups_on_log_id" add_index "infrared_groups", ["user_id"], name: "index_infrared_groups_on_user_id" create_table "infrared_relationals", force: :cascade do |t| From a2b1e55f9b0354d23c034e30c8f3b3d1186ca565 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Wed, 9 Dec 2015 01:21:30 +0900 Subject: [PATCH 161/358] remove relational --- app/models/infrared.rb | 1 - app/models/infrared_group.rb | 1 - 2 files changed, 2 deletions(-) diff --git a/app/models/infrared.rb b/app/models/infrared.rb index 518fed2..4e62132 100644 --- a/app/models/infrared.rb +++ b/app/models/infrared.rb @@ -2,5 +2,4 @@ class Infrared < ActiveRecord::Base belongs_to :user has_many :infrared_relationals has_many :infrared_groups, through: :infrared_relationals - belongs_to :log end diff --git a/app/models/infrared_group.rb b/app/models/infrared_group.rb index abf66fb..6b3396c 100644 --- a/app/models/infrared_group.rb +++ b/app/models/infrared_group.rb @@ -2,5 +2,4 @@ class InfraredGroup < ActiveRecord::Base belongs_to :user has_many :infrared_relationals has_many :infrareds, through: :infrared_relationals - belongs_to :log end From a36d47d25072daf7aeb8fdf56124a1de83a67e77 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Wed, 9 Dec 2015 01:28:34 +0900 Subject: [PATCH 162/358] update recieve.c --- commands/recieve.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/commands/recieve.c b/commands/recieve.c index e54d04f..43f6033 100644 --- a/commands/recieve.c +++ b/commands/recieve.c @@ -82,6 +82,9 @@ int main(int argc, char *argv[]) int scan(FILE *fp) { + digitalWrite(good_pin, 1); + digitalWrite(bad_pin, 1); + // 受光モジュールは受光するとLOWになる if(!digitalRead(pin)){ return 1; } @@ -94,6 +97,8 @@ int scan(FILE *fp) if(limit >= 50000000){ readable = 1; + digitalWrite(good_pin, 0); + digitalWrite(bad_pin, 0); return 1; } @@ -105,6 +110,8 @@ int scan(FILE *fp) if(off > max_wait){ break; } } + digitalWrite(good_pin, 0); + digitalWrite(bad_pin, 0); return 0; } From 8d03732f675bb9c468305471af59fb0b7aee7c37 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Wed, 9 Dec 2015 01:54:55 +0900 Subject: [PATCH 163/358] setting default value --- db/migrate/20151207081758_add_count_to_infrareds.rb | 2 +- db/schema.rb | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/db/migrate/20151207081758_add_count_to_infrareds.rb b/db/migrate/20151207081758_add_count_to_infrareds.rb index f66eda0..e14a3aa 100644 --- a/db/migrate/20151207081758_add_count_to_infrareds.rb +++ b/db/migrate/20151207081758_add_count_to_infrareds.rb @@ -1,5 +1,5 @@ class AddCountToInfrareds < ActiveRecord::Migration def change - add_column :infrareds, :count, :integer + add_column :infrareds, :count, :integer, default: 0 end end diff --git a/db/schema.rb b/db/schema.rb index 07b12a8..0d05078 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -45,10 +45,10 @@ t.string "name" t.string "data" t.integer "user_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.integer "log_id" - t.integer "count" + t.integer "count", default: 0 end add_index "infrareds", ["log_id"], name: "index_infrareds_on_log_id" From 78976f8f6a28557e39f106f21ee240bf364269b3 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Wed, 9 Dec 2015 01:55:07 +0900 Subject: [PATCH 164/358] change response data --- app/views/apis/api/v1/ir/index.jbuilder | 2 +- app/views/apis/api/v1/ir/recieve.jbuilder | 2 +- app/views/apis/api/v1/ir/rename.jbuilder | 2 +- app/views/apis/api/v1/ir/send.jbuilder | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/views/apis/api/v1/ir/index.jbuilder b/app/views/apis/api/v1/ir/index.jbuilder index 2f7f6a6..f689dd8 100644 --- a/app/views/apis/api/v1/ir/index.jbuilder +++ b/app/views/apis/api/v1/ir/index.jbuilder @@ -3,6 +3,6 @@ json.meta do json.message '赤外線データ一覧を受信しました。' end json.response do - json.infrareds @infrareds, :name, :id, :updated_at + json.infrareds @infrareds, :name, :id, :count, :updated_at end diff --git a/app/views/apis/api/v1/ir/recieve.jbuilder b/app/views/apis/api/v1/ir/recieve.jbuilder index 5e0a264..99d474d 100644 --- a/app/views/apis/api/v1/ir/recieve.jbuilder +++ b/app/views/apis/api/v1/ir/recieve.jbuilder @@ -3,5 +3,5 @@ json.meta do json.message '赤外線データを作成しました。' end json.response do - json.ir_id @infrared + json.infrared @infrared, :name, :id, :count, :updated_at end diff --git a/app/views/apis/api/v1/ir/rename.jbuilder b/app/views/apis/api/v1/ir/rename.jbuilder index 72916a8..946a9ee 100644 --- a/app/views/apis/api/v1/ir/rename.jbuilder +++ b/app/views/apis/api/v1/ir/rename.jbuilder @@ -3,5 +3,5 @@ json.meta do json.message '赤外線名を変更しました。' end json.response do - json.infrared @infrared, :name, :id, :updated_at + json.infrared @infrared, :name, :id, :count, :updated_at end diff --git a/app/views/apis/api/v1/ir/send.jbuilder b/app/views/apis/api/v1/ir/send.jbuilder index f266870..6625878 100644 --- a/app/views/apis/api/v1/ir/send.jbuilder +++ b/app/views/apis/api/v1/ir/send.jbuilder @@ -3,5 +3,5 @@ json.meta do json.message '赤外線データを照射しました。' end json.response do - json.ir_id @infrared + json.infrared @infrared, :name, :id, :count, :updated_at end From c3e6c98c4a486804cc311564f6d26511f37298c4 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Wed, 9 Dec 2015 02:01:07 +0900 Subject: [PATCH 165/358] count using ir.rb --- app/apis/api/v1/ir.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/apis/api/v1/ir.rb b/app/apis/api/v1/ir.rb index 5bccdb1..3c16b9e 100644 --- a/app/apis/api/v1/ir.rb +++ b/app/apis/api/v1/ir.rb @@ -73,7 +73,7 @@ class IR < Grape::API }, response: {}) end infrared.update(data: "#{fname}") - @infrared = infrared.id + @infrared = infrared end else error!(meta: { @@ -111,6 +111,8 @@ class IR < Grape::API path = Rails.root.to_s command = File.join(path, "commands/send") `#{command} #{path}/data/#{fname}` + count = infrared.count + 1 + infrared.update(count: count) @infrared = infrared else error!(meta: { From d33e2bfc62ec80a620258315cc76662adcb68246 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Wed, 9 Dec 2015 02:17:06 +0900 Subject: [PATCH 166/358] remove dependent --- app/models/log.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/app/models/log.rb b/app/models/log.rb index 3334adb..b3b98a7 100644 --- a/app/models/log.rb +++ b/app/models/log.rb @@ -1,5 +1,4 @@ class Log < ActiveRecord::Base belongs_to :user - has_one :infrared_group, dependent: :destroy has_one :infrared, dependent: :destroy end From a4da19f92575d7fe842f4a48f84ee792ea5614bd Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Wed, 9 Dec 2015 02:17:19 +0900 Subject: [PATCH 167/358] check erd --- erd.pdf | Bin 118558 -> 33890 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/erd.pdf b/erd.pdf index 511f862b300e674fad5781e79ffcde7df340cacc..0477b5db3614fe022d4d1556108653b0bd3091c1 100644 GIT binary patch literal 33890 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

=O(+D1+s%0sWm|oPkjY_GLxffX`>Uv(Mu0cUG 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 z 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�v$qv0-)K9>ipkiK())Y%(3+f?* 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 Date: Wed, 9 Dec 2015 02:45:40 +0900 Subject: [PATCH 168/358] add references --- db/migrate/20151203035051_create_logs.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/db/migrate/20151203035051_create_logs.rb b/db/migrate/20151203035051_create_logs.rb index 38c7fb3..1767a3f 100644 --- a/db/migrate/20151203035051_create_logs.rb +++ b/db/migrate/20151203035051_create_logs.rb @@ -2,6 +2,7 @@ class CreateLogs < ActiveRecord::Migration def change create_table :logs do |t| t.references :user, index: true, foreign_key: true + t.references :infrared, index: true, foreign_key: true t.timestamps null: false end From 2f4fa4e00d982cad4c3724d7d315d9900d1af560 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Wed, 9 Dec 2015 02:45:56 +0900 Subject: [PATCH 169/358] setting model log --- app/models/log.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/models/log.rb b/app/models/log.rb index b3b98a7..facdc52 100644 --- a/app/models/log.rb +++ b/app/models/log.rb @@ -1,4 +1,5 @@ class Log < ActiveRecord::Base belongs_to :user - has_one :infrared, dependent: :destroy + belongs_to :infrared, dependent: :destroy + enum status: %i(recieve_ir send_ir update_ir destroy_ir) end From c3ffa5607b75af86d594cfaf8007a791cb5069ae Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Wed, 9 Dec 2015 02:46:21 +0900 Subject: [PATCH 170/358] add relational infrared --- app/models/infrared.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/models/infrared.rb b/app/models/infrared.rb index 4e62132..51be52e 100644 --- a/app/models/infrared.rb +++ b/app/models/infrared.rb @@ -1,5 +1,6 @@ class Infrared < ActiveRecord::Base belongs_to :user + has_many :logs has_many :infrared_relationals has_many :infrared_groups, through: :infrared_relationals end From 6d2fcb53ddfb9cad0e80f668ea752382f7582c40 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Wed, 9 Dec 2015 02:46:50 +0900 Subject: [PATCH 171/358] add column status to log --- db/migrate/20151203040210_add_references_to_infrareds.rb | 5 ----- db/migrate/20151208172013_add_status_to_logs.rb | 5 +++++ 2 files changed, 5 insertions(+), 5 deletions(-) delete mode 100644 db/migrate/20151203040210_add_references_to_infrareds.rb create mode 100644 db/migrate/20151208172013_add_status_to_logs.rb diff --git a/db/migrate/20151203040210_add_references_to_infrareds.rb b/db/migrate/20151203040210_add_references_to_infrareds.rb deleted file mode 100644 index de807a5..0000000 --- a/db/migrate/20151203040210_add_references_to_infrareds.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddReferencesToInfrareds < ActiveRecord::Migration - def change - add_reference :infrareds, :log, index: true, foreign_key: true - end -end diff --git a/db/migrate/20151208172013_add_status_to_logs.rb b/db/migrate/20151208172013_add_status_to_logs.rb new file mode 100644 index 0000000..fafe3de --- /dev/null +++ b/db/migrate/20151208172013_add_status_to_logs.rb @@ -0,0 +1,5 @@ +class AddStatusToLogs < ActiveRecord::Migration + def change + add_column :logs, :status, :integer + end +end From 0903b38a9bd4535cbcf134c50d462d30913f0675 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Wed, 9 Dec 2015 02:46:57 +0900 Subject: [PATCH 172/358] rake db:migrate --- db/schema.rb | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/db/schema.rb b/db/schema.rb index 0d05078..f15b46e 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20151207081758) do +ActiveRecord::Schema.define(version: 20151208172013) do create_table "auth_tokens", force: :cascade do |t| t.string "token" @@ -47,20 +47,21 @@ t.integer "user_id" t.datetime "created_at", null: false t.datetime "updated_at", null: false - t.integer "log_id" t.integer "count", default: 0 end - add_index "infrareds", ["log_id"], name: "index_infrareds_on_log_id" add_index "infrareds", ["user_id"], name: "index_infrareds_on_user_id" create_table "logs", force: :cascade do |t| t.integer "user_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.integer "infrared_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.string "name" + t.integer "status" end + add_index "logs", ["infrared_id"], name: "index_logs_on_infrared_id" add_index "logs", ["user_id"], name: "index_logs_on_user_id" create_table "user_infos", force: :cascade do |t| From b58bac656cdb8a71a83a8e83f90d09794062ceee Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Wed, 9 Dec 2015 02:47:50 +0900 Subject: [PATCH 173/358] bundle exec erd --- erd.pdf | Bin 33890 -> 33982 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/erd.pdf b/erd.pdf index 0477b5db3614fe022d4d1556108653b0bd3091c1..27b062f45ed29f02bd580762db9a52ed3e183e6a 100644 GIT binary patch delta 26917 zcmZs>18`NlnW?Ph8M}B8ZOT)n_qic9r{@1Ln5Rl-??|lr)KR8xsLa(C#{@Rh~X$ zkJG!NfQIFzWzZT2E;Y}(lhx4C^3RYj+nyG0m+!8CLa&-{|I%-OHC3q>amUT8qTKLq z#Mb>|jR79=DL*B0*ExBQ`|hqo+R%XTGtp*A0FF}2^Wv31;OI;7TkiV1{JU|ur0NUx z``fVP>&#>Q?OZFZ*)c{fp!rSo$6Ru!pab&BsK?()Yv7Z8$TE&iQsZd((oI0NyyG}qX^fw$N@1TvD0Z>_7-I*fag*KhyrLD3#8n97f;%${|S zgq@?&bTCY_j3lAw=j9#`elKoh=IiU^Ce7<`rvN;mAaLwFeUTh{vMCn9i4uXLcRAVf z5_iaY&J`wk{0WTAZpWQ_w}I7WRm?V##e$p+vK_r|rwC~P_p0{hs*fxCr*~058ky3j z>aXKK%?{+r%z7a(_-=FK%P;5BXJJhkBNprs_u1aGQEcc=}|*=iV8% zO97=>&iUN%e{bf#BpM`j~C;sez?)}rRlunvhiiPx$(YY%yzFkl)1U3c_3TTR|Z4o$W>`LVbF>fM1 z>ts;%+Xea+J_NRcUc?98U$8PhB?y~BMCj||^)mwS{0kmxkkEFW&>==IhQ)1VZ<@Qq z@A>IoZ=sARRFJ&3t9?l2CSA25SRQ~UNRyq`5NxTbE$~5*9T%B$nQvNyzU#a|Q-chy z@{n;xc`w%tr$m{IkguqzNsY0)%D)Lh?N$ZB4l_c=>YtGGkQ#*i)=xwgg<+eeLthMy zrh5pG^#gMtyoH*srz&)I;cDiLQ{EdJc2FQcNi^^CqMR~sW|E0{^j$|oa5u&K9q%uk zB)P!({4}FK7b)=sQ`<;ylOnlrrHg07a7hujFmZRBYqvCuxYZ2eG9aj4>$vf#4h}S^ zT(20DX>CsiP`5s%^q^EbHO`|xvA%6;8Xf{H4HEb`R>2w?^W3r#*mMcu9mm*ncin!= zv%cZJkZbv=QFo^-Z6F*GA$a2(GNYQ;GNQYE`usvgdES>===%EijZH$Is^sOz!9Q37 zEtk|D9-cs8L63vspg@nSsu|C1(u#8AKI59>Ag20_n>@H0vnOevMtr3h#aP*_SGqPIp=w=OvSSZrS@L_NP!33ju+PJ4`HA`T zteBZjbV3JEWAL;h+NH=pI|GlrOKSmex7vYH&h*9`R7H@AS>RKt`n+a2>muq)?1Jhv zni(VlX>=rZ%t2Ot`XM67BM}rkY8t7x_V2CInAy@&CzJy8lnE)J1Tf-y%sWMAJV6@8 za0^TDFN+y4;_F97=859;(hAhwzpNze`kSxBkJ3K3gB^>xqA&b0VsM$Jr{n;M{h*%* z6fN)T%p|xuoA#|Kt8(hH90xx*i$|~<{C*XPO8$gsiDq$!C&8)M#H;N4DJwbj`k5VD zw*Ih~CMnr^cUnDdt!1|KBg1OG`Z9+My~c}gWSZ{pu;|+b=8nCNk zGn&=O+n^qxgv*s?1I5iZh7$^S%r@;Olu^J9^h!U9O(3ELw#2!%+= za3!Z%R5?pnfrVi!K?<#-k3?{uSpDnF=mq2b&ZS=ubQ=-gh{$v9cPooaoPW#c85Jdq zuFp}S3m!%}i-`%y%!xU(J$MDF#NB9c4qkm3ktoP2=<}t~lP=&fvyIN7Mg*dz(lUOE}y90qU(W^$-6#3vg5a}1L zOOZF^13BECm4e(V@0J8WZ^`=!q7lT3$YhI<4yvQZ8mquEB_f^tP+0RcY-71PdqWPOU@w+ej35Rqe-yr$S8Y*g-9`GS z)tq?a+b&7*;8yU_oTS)JMK)qp%xec?&^S|QG}UIAr6I$p)^bmsg=GiQLzrntCyoc3 z2u#+_{1ha!5rAHAgINk{6bG03OEYDF@Gfv{YibWkB`MH8x_3)oF2~a^1A}L%AkjI( zB83uy8>KRUp*jS}K=J(5rcqi_xDd<@CJ26LWK>wc#OZaDK2jl8x!;hEkAjN)M>}qrwN+0`&KVh`KFP8u>X~tHojKSXSsOIq;sa(pa>PRkGThYOzqU+X zbiUc9L)+=5EMldLjv{1kklp~H$-v-;uu$L*6+SQG)_xd|>EfO$>J9Fy4NFGVg}bMK zaz{WGG#h~3DXM>g5UCiE*04w)p#m6Vd}QR^z8qlu+hR76pIfMACkB?ia?OB@Y`Xid z9>g%Sp{y3b$B9VS*bbeB&n$CintSi(Oqu5@WWv0c^f+AJ$3r;6CZySBhTnVaYDS}V z=24EHZSJ5de%&VXE8Zndq18!GuWQf>BTO z$>yZ>Dsv3TZEzo~gh4Y>)~^v19*4fXkqM`{{vrlYN#F!Wvfo&u-BavV?p)a)x$^I( zj2tSh7Cp+7T)tVj*}S=~+3Xp&Q`&Dh<=GLA$F6CA!=)w}9uv4f>DsV!diULjaOXvE z;*lma@ZZNVg;NAb!P&pOWvXeuU|NnM7*5y4sO2J!=Nvir^UV7%I|%!Rqv!e@=$GcC zI3fX>@blzM_9glpLb&PplV4{R-i<Xf})A_nU7dedAUKyp>A;%JKH{0*moW9{hj&g`w;Vc}@-P~O*OdS4;oJ?)uI7wJY{(G`< zaYw{)zw)^c>W7X{)Ox$tSk*aip2pXBPOpXrwkNw#Rn#12{Z^RgMtDFu^CbR?>xP-`az%W%rnSv|!AmJF$WU;{*0vKY*sw=#;mbzN^ES_7=1KtbI#j-xEwvu(mU4L&|m9Dbk*i_sxGevU~+*d08RxQ43u>*8pL(gYq~4V=R}~oL9thQt7c8)x_6uiy&XrV0=MO{(6h3Npz%Jd3S)p`%{$}` za59a*m&lG6KnVBhq)F@>&d#&4;t`%iQfpoIS;Dp?d6gg&>GM9u9R^N)donn8!|Vc# zE6)OnbqUXbY!+&K1z(zc>=&lcuI2(*y7|+MGU_*tPVZkz`2@e<@{sS?4R@FCTJE@S zd4J;N_51lmwcPrOQd>hb<)ev3EdVc(n|kb66EP6u9$^TH2E++u-l`Z&aVc=UW2?rappBba#62c*F`D%ybj8FP$& zl=rYS9e@6lfR+)*C&5hYo?u#6ciWrV-|ExR=KUqtj%HR zo;lLPGrFd=#k-GP$Cc+QmGc8OEu>~X?oJVe7#TAsqZXS*CeRRy6^!MMKMHuAsax% z_y$AJsj9|KeQ%B2yQDoPo6=7ydcnB#7&dIx0NQ z_lM?-Y5q+v4SCHV3RSilD>&N$iX_&JSrsP~lB5Fa3z8!lHgj&dK)gvT2-oCsg5?fE z82Std+gw1UB7GBkU_%4UaGba?E_CAN;0eaM(-5W<=+YR(82%-CQ*9*7P(d|*hVX^E z6zvf)+Ix34Y7|_UY()mh6I&8R3ZZ_waeyUDi~eD;WnYWV4f{eK zaD!5}hxB7TAcBrUMK&d>ii8U7PF5f2 z-W-k;OVT#~UL7PS))bZ&92Z`bpLJVQ(qq z^!nYvmSg4hVgCVuzdXO7e_(b?)+I-?Dch(+H>L1N=M)>3V$ZFg44-b#8?mEnM{f=U zjQPB5i|dl(lh;Va6c9`GKw{F9z-pFYEatB(!%uk9;)Q&{Te`sH4%FHn&&ZtwfBX!- zEF<=ZR~ONasN#Xv8c+*y8oIv~`=AhlosMB++E%VbNe%|gsZxz8E~-^6pq0n?rkxcy zxYG${-8J!9H~$O}o+@h13s4_7uC#D&rCe%_R&kMR zuh_VR`)r@MgxlAd$0PYx&ghuMJWIP@bp1l*C5HBq3C7kxJbGf&g5mBM`+=Erxp_Eg zfqVKQjxs`OS%f}_DlR+c0;6EBg9wMEK*2cnL(@ygXJjv2U|}}*F4gDvnhoNi1(%F% zC>sr++%AxnZ4NseMCl>lHrH<}WS7L&fvPQa6_K>Pm{pt;*xhJD3hZDoZ+}<2_u6^X ze=R{xAsthjom(;!Au;0hc?mQJSqLsyJ_( zm>zJBATwz<^$9vh>oEY)8wz$s*UNs8Nsqh-WezXBpc&YHj0KXjvm9xX2@jeVMGEH~ z{uHXMq#;*U@x_OCX~BAsiJkID$DrwhPUjH%G`X4SQmZ;+xbNu!KvJ`%s-5Ex)fTEwFp7tXaz2A#S0+rp0<{{&&1`%R(|tWUD30ZOig zV(8-0(Oz-n(Ltww*()C_rTDv`s)H4PPNTgI;x0CC^4GY~foFYbg$LWm@i%*KTU^`>oga=`ulJ+a zJ<1espqnS%!tszV=z1}HyY`v;q6Na56D>0yG_`w5#kk?y5AGOwAJHiu(*E884*Np{gXu#EgXp=7MxP`0 z6cK|7Dmw-yZ20?_Mqn2TF73k)4m#o%ioyxZK7=hy4nP8@^bgMTZivA|JoEqsrv)-~ z7}^i~a>JeT&g}$?vM z;V~E0G!Mxp1OsFb^toX%gMD9taE42|2VR*6Pv~&<28^e;7~KtikbR*ElT>1CsmN<| z(y;AW9O4{WYOwMU7YFW0+=STl+L&I%%8ek9Lj~uWNV>LT>tjL{ zH0*_FY5*4*mq+7U|tWk12pjo})tR6JQgRX9>cYQY>1Sr1JT!$R%{-U?Nz zce69;LltZ}@<=m`Wa}I9sYgi!U2@+{jq%){TLyYJoqvv0hkjvGUUmucB6C)(*)kDo)iYM;wc1Z*vT_ZC0s{W}=ANDE z+zlly;j-)GYMy~aPRO4YwZW+yP;RvNXAX z+eh-%=03-K8Mg<6BmA9Pc^>RYh~t-if5#ebqa135yJp{O&Fz%RRs)s_1)_45&1#_p z@t89gnNbgzD9{UG zftIGF>TIx^*47%}VaEuEG7%HjoA?0a;UzsE(=95p6h{=458a^98hKoQp8-rIlQWZk zQA^~9eqst$LLv;F+vo875K6VyvKV%;-mB<0aH5gdGL5rVBbCwg577gkt{4mQ#ST&AJ9s zuC=iB_Oef}!KliYq@K3k#sHHuQBZK^_MxB@dD16(i^EyyPFRm@+t>v@z7*c%`%g>& zMPBaUK$|t|n?o%LCwvTEv4X|(p{6Ys9hS|Dm}sf$Of!Ly&hAVZfrO2EuaSFaB;AI!t5ok1Jn582a7|wun|I^Z2@dlU z%t?y7_TaG3ZP{wsXbyQpT00TODqna;DHPLO({e2Nqb{5xl#wW#n3>d#tjx4fj@g73 zHm;b$+#{Vr8zeIPfyt!F@0yZfDVbs3PC#?t8=)Mq6nGCi01CJzxXul9i(0XJoPh~f z4sm_*@u#>wiW?=)3S1nwbF|xFYC2}HnXDf6M@J}szYZvqM)O z%TkStuB+K@xO^BT+;p0dtyz07>zn$se~|%yV@kT2&Ds%QYx_CgK~L|6bX7||`@n~( zb%q4cWO`c-cbKN!84s1(aZl+USr~bm=r%qQg5R>aLPbhH9S!zu$t`)z9vB zYRKRaA}sMwUOGeZr-~sI;=PqBKCFl+gMZg`@c@{RCSIckGXY%@>S2gdL?6gJf`?)} z*1Qp&KqDm@Lsp<8)=fa#>t=bw$Y)m}#ZZFzmO zH#}I@$|zmp&ka_6RId3Q!MtXRzy;YnzI6PLYfJen@H45sGCFR5<5^BA&A;lU5vpmWd+wcht z{Rl!ouJJHeP=4F}NTc!=j=>eT-c#jP!}As5yNj3q(#wzOeA-{`C3H4juCg!bOv#Ra`kn0BR&Tg-wE(HK97@}b+ zVxAY2#knHa9a~oT>p}Y?Ij|C}4L3Dh2{he;hZ={LPa#;c#)Kz@dNlO{QmJouFbXLw z>Y1!q^m5R}wnZbD42!G};U{Kkkn|Q*V30903BHJ}?pc?&4!SNB7ul*^926}og^T@{ zwlPV9oMLmLa&_k?m5VXpp$njuP&1G4b5N*$|M#iR8~MlNsz-%mxgX`7mHijFC!HD< zaeHaRprhs7WsAI?z-xw;k?mNX`h#`;Qgxr>3z69FT%?!8pubcH>+25E8<7Ci*xzo* z0C5kNI4|ddkfGZ*F*AZvbjJLrMHk&3nc?%jMMchHq8Yu3R8X6~Oi}BN973w%0MO1oaoiioOYd4fBO^+6TD(xnL8!$5yh9jOoy0w;Eh#+RYBij&qYe}scL;qgrgkD92r?D zO=g>}n*94VGM+#G2M?{rGS{X(w|0|RAuVPA#3pmU_`$rThe%4eP>8+UaU6%kdl`!gI! zYg3M*FCQNEOJxI%P+4JTw*h0E76Pjo=4Jvn6WvGgpwb0S_JN#|C#6gE9M(Se@+Q=H z5bFlHw-f?^-`N^^ae>qSb|#Wpt9uV0-kP9rVLOQ%r_3<&MOGGa$by+&0g`ywbXEQ1 z<#C$q{x)%%tcxEhNYo7_@7D(FitK6!xp2~P3#zr$hc(`7NNqF=JPFhNu3!>XWra5|Wo?WeO0*t72Eful6aQ+gnD=)j&F?0##ayt|GY-P9ee%0*iLX91t_a+eH|pbHsQX{Ur@xuKtJoIyC2>QpXy@hZmO$ z!089T-(UV{DhoKAMxixP1~7d)>Z@D8ZdrER;(wv>u$7rgrrsvWroJcKMD`8O&Yys_ zBtD*U!x%W_&Fco9@91C|a1CB2%J$9wbaeo{xkxQ#<^xf?5!9R`{1Uc_<$>^&F z@AqPhea5knxUXEpjGcp~`9E(pv-+)SwH-_NjE4@pN80TvI= z>}Yq0`DgfddG+X>db`E!f!<*^+X#R`Mp4O6OS^iU83+o1YUf~1ry(C<77@(e;mXY3HKU`-6NZ!c}P^9WMr+xr9`7lE>M8nRE&C9-&~u0FX3=+0|(F#ZC9@p z(pKrA#(aIRo-Lqp6~u$alTFie5 zO%4d=6>9iw?)+Qcw~dAi!CTTCh+sQADO&UEX(+Cknl)B;M%gw@^YzJjGz zUTm4XBdSZ=e={wJ#LKs^pzo2^DyG+#hFIHT{~-P)DznZld5}n;$3kd)bRnQu_um zWRvJAz_?(TLGloefseFW;E9zBCK}SVF5qn{YYJ`;$7c&LSH=hI*-$IYf=k8>!ZmLu zJac##I;7#=-@J2%q#aI%XuH>=3mq`~-beZ@yIt&v){ycusa$8D=&_&AO0DW7dbJ>> zVpGttHtCRVbOid^RCI28NeKT2K;PMeAsj;thdtJu&`Jd7w@_$5&~6w!yw|RhX)=;A zDVmFVW%xAU>emATPqb*OG%u(}x;-}W5`MA3z7O0X6B=Wohm%wym+Fx#!EcyZbgV(Y z_&Nu1o`2<~`Me=1U$MeB2k7PnA+u+Mgn5`{`dNO4sv7y-kKX>7C$3qS_BW=ygWZN% z5tOIWhx343mN!MBF_vu&u2HQn?FjSOt61QDv-k?WsrLqm{>h$ZMqB$EHl`SmGDBOf zTD{+qLS`eUP;f0quj6YO%?kNIsTLZO9&tN>P-@Il70RxzI7p_5lET4UZj$Joy3RN= z!JDX>twz?VXAwny#EpY_Fwl-CQuM31rPvV7!amy^e; zH84zKKi9IGLQG3&_-iqq8U$%p=<0wI-`&yj_4dd{R`{N9#U_?LcdycDf=B`H27~!5Q-*KgE zQ_>7^Om*s9>|<=!n?c|}@7|sW<{lk0Y12dM&dV>K`@^YbJ5RTc<<;!LkiAaUl2Ad~ z4&4t0lMk^gNla$-H!{79SmXt)zhx!|qz{1-lBtjF3^qKF(kv%-Z3D<3dAz*`nAlZj_twad992a~p)i*EI*Ag2H znG*=WLxs(j>#&s8{Bn=132Go`2{9h2ZdlOJWh7$Eke|Xr$YM2ivb=W-D8{W5Z>TQ02aKb0f z+X`pgM!SF=yes`iaaFv2(|aGflpNXHLi~OE^9Z~OK=ZiG%q zL1O#Y#Xw8rVX&PZE4NTR%ce%}PED=*;dJ}^UFT#xyU5QWZy=E+(Fq_ex1~*_!uI3C zey-~_autbNvG52i?o63pxkiGKrmRsdT~P8lUnqJ^je1=sOW7-5D3b1P(~nxom8mjg zH)5+Snvlf~AcW0etovwgIz?9j>-f#UT-MXGVy%1S7H%q0jwEbK)P>3uOjF|D012k% z3|rc?OX9KfR4^FA0z=@Yrv-rcR^y7o#xO&zed)HFgIlVBbwwgxlD6jn(gq2SOhK}g z$*Vm1aD|*v#JYJPs{!N@f`0-@S%@FSV^MDSw`uzi4jcJ`09j97NUAZdAC4IZ*MVraSsoLUIRr~Ea%5?ym16P)YSx=Ov zbSk=iAf3o~Z^EQ0I_DEac0a7=Uw5L{Dur4XuKLND2d_FG+{u}hUgzlFqP&)@oH0Z3 z2!r}k8%f62!MM`92!z}lQD$86XEGLEc35ix7J#rWG6$8j54>saO)yLIJ;R&Hv>e_A zf5b_l$J&9KRJ`b`8zrEKH#{gNP~KY=xyj_RsLu26@S5@?r1;{pLUDC{ zm87C=(smQL?#%=nFG0vk$E{hH07UbVhB{I7O*$$B8vD>8M`!MAN>XRU0OYPo_*1}v z89plDg$r}QOCJW%MIfH9IQUfg3ed!tok;rNZ^#}rR@&pV8KW8hkm17kBm0{bkEz4K z-!b)BV7;#r;PJ!ui)PI2a|*JC^0W3BhfL><8T6ZeqL3rgp!()YNZlOWrtTX z%&?e>q+%6RV?@)|E(SplwjZ^#7qwSON7Ih#xU7DbDRQPro||o*dCYy7ZSz(>m5jM4 zOd_lvpq03YEf8HbWD=K6^yKu6H-OiuojNG%U)^Hdys)$aOcgbsehu&Jbnd=Jq( z8g4Zb-<<*r6AwBfD=9W!qa4Yx4^(bZGF)p?S-_CfASfQ^`VMM+p~T{!h&q4zFaW*m zN<2hEccC5x^rUK`b>QdZZh}ByY#l1S6YUuTK*n~f!Y}AVOXW1Zg1>)H!cKOa2j`Eq z*#`fXjyprTfM^THWvSd@(ng$QYd>s$_orJILhA2bfh>aBSYhwOJV{!FD3(2qbcYmS zVtkfh-@rZEtxyFrXI?3C#})LWzAw2_TMDbH>!{m|xR(0c$p<{_r+=rY{8(!d`eZT( z4BYX6P8f^)0aw&;5-ih01k)#VuKd60UPhfP@U{%4iOg?e~p;}N&OJ8 zZ*tmS$$udmQP=%>l-aL&u?0_1i)f1gm^eca=*{}6sPQxq)H2!+6^EAjGbHx%$xeQ| zI&qja*h@WNGY$qDPp@h|z} zhg+X<1G2y@T^+k)EAH1+!0SRS zwVH?Dhc=}B_AFH%Uv$p-GkFC?JVs=T``R#T8kn1m(4N+?Z(oNTj=>8#YT>kH-k!P? zdE!LmtzXP4USSO3l}m)AWVC48P``pT{BIuiNls@v#ojyoY{L*n!MehmsQ{bs<3X3g zLk|)DY4g?#HdX-u9RhPY+Q6X;pa_U#2s3dAHL(5ugk#7NwHqzRei6S9H6okuk%gdT zKowq5+FxrWi{Q5}P0gwgK4BQLJGf0W&;-P(?%)`BblCt|1!;Vw8i-4a+ND%8@jgw) z=@yE2M;lP+{n^!bQ}6U^_YjEV*v&COzt;-tN;y-_f@|oJf%EmHj`O4dh%x~XoKl2q zfj4X$zl8G)T*;>}2}BHF6Lz?-A|G*LE5~zFvLaqD*7aCZeGSMArAe@fDgIR62d;G< z%?d~(wNYdbwc!8y4lFnO9$z`KrO01XCPm15XT=v{&Xx!7pU8wV zFtzdhvowY1QeG@|f5f~14zL$9YYzmv?-NZ7ePOm4jl4*wc+Q9P_~c?@=qDkGHL6)y;wBHpUW$9TzrF;wp#l9f8Bs=?Eh;A z16e&Q1xPXsk0J|MOg!@S?QDx=|k-lV+{!nU5|N<277Lev?|@EpohF$_s~C~ zowYb_KZ%|<{JviW#N4=@wiFYCnj=eB<>2w^ zA9Hg&Uup}(JOKKgPCE>F*|uWP%)>3_fw#h=$3^pd{6&SFYC>^cOOq~4elG)+x+ z``g#r1PiE_v^wnku62n=>1jji_gyg_YXxjZC0LQyskk3W+!MlVXIb`FOBCOdiDtkg z{>c4tpXDu?3dVoQO ztXa8BfJlBjuu*H7j;jetu2dF%%o{Ir4a8r!2jx-+S6_8$7yN??H8}Mc86`!t!LPo#K;D--;Eb&`T{I6e_b*j^^ zTsa<~nB<5&lVxaGZD(!zV&gaw_#gQ>YIE9L?Y`&N&~!w~OWSl=s)*WnNnL2QnOqsu zF#IvN8`sg67^*5S*^#^I)xWFap7i$9;r%il02;W&iz$1u4)o@jQHpl=a#fntfWTl& zL5}lw7DE+n%6QINaW-J$QY>}0sV6nC&dQlsHrLF(7DW}V)kVH9PRiBZ4$EyfyTE{s zN1_x)XOyM6{6TRL9Tf(h(nKQyy;{?wum#Gt!lFN%4OK`JZg(vS24ACCBJ@0el?GJ^ z5a1rFAQ3tlf!=o=&!u65YQoR4PSLL*CAFd=-umj?&sgpl ziILwdLB)_7KJjv6;*qF0^@~&>Pf8FsSRX5~`FOm1Ungm zw)?w~{6i9TcXt5x*S`(kVJyUtgi4Kz^Qgn^)+NFGs*sI=>4BZxN87!bMUBTmjVDs{ z7W-G3wJawARw*^==2R6%DMkDxw!AU&hJzz75oWq9^v4s!B|vYT@5WUUU;*&=vmENs-e&qWPzz?CUW&8PL;XU;hxS!<`-M zslnL!Z9~1=_jjlRQOV&H_PTg^acpWUX8l<2AucXWwOhYauO%%f8HYKQdS~3-OhfuK zbyc&aHIl<`u%BxJNdG@g>A&kO%zs^hm6L@N$b%&ar6n$n)<84UAVg~(p zrxn4%0&ZYq{qN!nb}w+kofCM8BLxuYH#MiuG$w;Zu}CqfD+r|vb}4MWa_B3rcE|{g z1ih5gt#VL-bE;_8#jGq_;p#t^vN1?{4LFt$o@u#$|9qXyInF+2c;0Z!yA(L)WyfE3 zvL)x5Q=~9u(AjKHja16VU)`l#c8Ikc^Asi>3$9o;Y~WLy(v^rjZLrhabOv~o5XhsV zdt9NYywP zY=#pMn;|8gta0LVMU%05b6H)!HTQir2BDk-^z}Va#Ae6kgs3$Rpv5U;Pl`hI6(c+4 zr%0)ieLA8x-L8+la`g@>-vAxF=12QU!$J%Ud#~enYX(MFmpziymiW<`C)4=Od3-L$ zSQ!OC=I4M{M!|cEEw+bSA`emBsu<*{ksQ(Ph{nu2C?ZrbMf#0r(k)xl#QW6Qft+ziKk_D#t&t8yvDse`b=j159&hvA)f zhNrnL8N<<-vsC!Adv0GL?G4!t=8>%0=rE|k2h zgh@T>y#l)iwq%~`x4ksfQ;ATd>&;Q3{z9V~S);i4$@#5Zw|CUq+2D*pjzA_Zw6Tfi2jV>`sidfUR-IOBB9SqK`vVy7mRBpt z0CAtH2R)*>F;4>*i`5%28RioFeS&o+Ne zPg3ihA%ZsE=6|}B90PTMK$;k@b4UEuXmDmE6l${12)Kyxq*OxehiZ$(HjT*NqA;@2%g>8oT0}x8>JcW}g6b zYXO)JN^?&v4%5Y#P!52^cyQXaKePTSb#piKPXmpg)Q$e&4oWjmJPyqHmnym@54D}u zxHEj_O=RobQS^l4>t3Vc+Qii3;1c&F_dd0-5eY<)MG~VTrPcu@ZX{{PukX?2?1zc_ za?A3WQ-(uv%pr)(zDBqmCc2tC-NvLxhLY$v%7yH`sr_EPfEjB`7uBVa)Lgt zsuaCU@KE9}a(r*0scLbT0}_v$jwh*Zn7r7ZcvmJON?}H^ zAEayK^VK6+Wj>C8gSeZ^#O>sVbd`J6f(SBx983e`&|!%HS8eyr@bHKZGVXhOz(L7P ziMeiJC=0B%N_HVz;o{?@iXhI|MrwoO=-u$xXb<&-mgyFr)@PEFc!hD_em zTU&r5l^&|H=H&Nytm$JwlW0y=yoTJODW_6g8LzGMWBR7$<^{|81XjapWx54BJ9#piGqs!cr@@(CErz9+uRaM}}(f&7-!W)qH&-?iicTw)7 zjeLqLMb5l-+S}EKwHjam^o>_gP0uax3ws(5A4wYh^tkEXyNjc)q^_->6 zA>=Q~4`FsJ%dKDHlWiFR$X0KIF2Zk^Hwd2`aepOxT1%n=*bYDWxG@%%+_6YRiH(x& zQT(}H3b3De38eCP&>n7^fdd88CQkgG*ADNbIV@;FaJ=y+Se4vDxjTi7nM_1Y*`qc5xU)=J~%zoEch z5@m%-y6=X^H)-y=k8$(s_&t3Q%*O%tkW=yL%#IrF|0?9GgYx*6Z4(F{++BjZe>lP2 z-QC@t2@u@*f?IHR_h7-@-Q6`fH|M@rukQJsTlMxoGqtL_ckkX)Q!`y_?XAqXgD!4Y zl=b16zBF6eC1bFP`-kKcRIs@0w%jDm`tH{Tm+B$l=6n03(9^9UIL2DT7GRaKU#&Mn zzgl3d8uA5g29-vqbJ4L{B`mzIAh*sIM$O}$>ns#R>@O6Q9x&P-s;bR4&a&s)zbIzT zX|I6K$5dlP_dM5?62?7t-PGFUXP|lCJhV_;ggJ^`KE(Wvd@hcc0VNBKM~=Vaf80zi}GYs~C;0CE6W7O~sL0Vgmz9lAzH+m>KdYynX!VU<}l zA!jQgLz4`(emUj46&oS>$FGyO7;uAdfv*Zr=)Y*Pkm(h&x6k-2fPkD6+)u(;l!7@U zLkfeW*9hLw9%mFVlAtX{MZ`yeCE-p9cS9|mu(XvSK3&RLAQpNWSX)fxi-5XOa{lC3 zMFIi`^~t;*DGaIC>OJwFFUy~jXUmeg4B|OschGl)v&ZjTGvo*AidRzDSoyS)`guI9 z-=gnI?0&mFaTTmdAkhjuk$hsCA)dKNKyBU;xJKcYznIISg3g+b$r2^n zi+b819yf+_M>;KbzjI6~_~k+|{YdsH{1z9Dq~8>Jy(s-9>0TQ0bp^Uq2!vkDo}rp+ zhWLnlP3Ii-`*30j4?L!7%__Sg-6h0l%3d;Ho86O1JOfk%=}vZu`iVt_ROm2=*M#zR z*D}{15vS33()Gtf>NrkAr@f7Tqf6{)OD6@bBOBlTAr*g4jV4SaO3ns%DLX^U=M!#9 z2J#8}fAyC?^PHhx``RV9kxN`lV~gtZ{Z;EJ>m}-iw*k|^4^vC-oNOWxf=cNR}R6A)*4si}FYv!#Y+#Hk4m&3mRq?a#x zX`Rud!F;y8rx#xY`_c(XB!*U+W59wc=ncv+mDFQ-cemoYpqaKqlUu8&&u70?Vx|OV z6l%y{GyVIkr&)u8H(wmFsejM+_P!833-Csq;5_34&%)PIkIKq;U(}?cr}0LuL+cS1 zZl+i{vI!{f&6?7H1tyqJh_wf#=Al4Pp{VUYK*@L%c(I;A?HS zNIB7BpqkNrMYH<1jXxsW_X!&+_?FoDVyZE)b{`M_>xk;(^tggwtz%L??=#S_s;3JM1i3l;Riq*nf>UXFr^IRT@ z%refhKgEB4Wkwm|#*>F`cA+FUACdVIv3kOcJTbvqbU@ACa&Vu-~>cjf&r!9wTx%ehVkxL zMD+ToJRRpW6mbcfz%)~VlC!dRbo&>=qS6=YN3d;*jyS%f=iMS; zn#UX6D{BtT_;J{mYS$CX56j)?BSXRak7>ss3!wbpQ;O#=M?pjvw-AP8UQMhsN?Cts2MsBNV$}=U0vvw;?Q7EoQ0rjbXIapZr2xh&6h>>T_+pj&m* zlCS%F{|i*Z&aA>);7QTusOU^&zQ`M7szT|EN8!eISLC2zzcBicUT-vqN8BuCy<-Y9 z$U036@6vj#3!jWpIl;sjMFg!ReKB)z@?fkgx|JGu(<$N&>B8rWmC4OCenDfv-p^kC zpMf8(?E+t0)>4$a3=@?2uM$cDxE;CywI~`UIzs+Z)7`Lb)2U0N;BZeNdO;?i%M>1RXEZLUSV_I29qb)_k$;Y!N7`02}NaunLi&Sac^Pq6wi4Y|2@fe}fn7-}j^ z=irFzXYDChB?UjfzT@&b-o!GFxtnyEcQ0vC1<2mk6n%e)w5<`n|}C zv;59*RgzH+-cB%T9br`p{BLV(l>i+3erDzNMmH<#@zs#!G(~;=ov>|;%v$nBF0tmK z9~gRr7*{DjSSbo321JvA-T|q2-rUUo4nmLnLsKW2=|=X(`i2rxiU#ATJG0jS#JM~1wVWTxgx`4VLdBO;o^idBB8j5_5~$Kopa z>LEw=&mS)e-pE0wLM}IQ#xQ++yt(EIx;SJRG{#UqbHQibqt+rgCKHGAwVChH@eb9l zJ@JxxRvdX;(J_wOweQTPSfX*+epx8-sk2UwR#3WlpI%J@tg6z9%YtkOD$Xo%e=N5` zVJEVlW&He!zYJZYI{yQjrcZHz1uH?+=C=sZF@#4;cT&R61Fdjz@_n(nWI=JxR0&Oo znKz|f{q7#(@#y4Uu^#w5sT><2d}*Zm6$Q} zOGHtRxx1@uv{;dQy=(n_{tEU$u6Oy)hi9l~v4Lf6&9j&5~~}9@oAG(UY3N#H#!-V zFBk`klc}*u5Avn`iFBtm=rL&!pIN*S{(=Q{!d(S9dzry6)0kI*=ZB!!*?&vd1IZvC zMvB=Z>FAtih}e@Mxnqb3|85|_xB2Cxspl=cybf%;17Zo(GYbAaBNB^4W^-7&Y0i4k z9p}vu0Ie=eY|Hk z@|4b^o4}L^JVbxwp}q6BOBvK4r~MNseuNCYx%2r2lRqdVS{)sW-3SCSOAzFi5i9{@ zrOof7i729nMq&mhKGVP7H?i=vu=`0Pji7G<2&&bn;x*ef zBh$N>tXqRtH$4)IXj?svV?xe0!jf%QGPmy(2FO0{UGD-4T;*s2Z6w(+B@FdHLMToy z)jJZY-FeHXuG#~$Za4Z230TV88^1OJOL6!43fp^7&gzOEIWF+j-1p%G7E z|2as;AW)8>rO#ERlXbcTsaNH6^sJb`DSFNwPWoJc)~U z1FJC50|hYZr+!w;Ax9?aoi2zBWos>WAsIj3mra^3eBEOzAFmDIpRu}X3rk$@uFYa8 zob5}ppH}a+R?NK!?hS=jozKE#@D?5y)|4#j^?96cQmYybSYtXt^ySFuTC5#=!%NA! z$Ysn_e$vN5qA*82^1q`KmChHB^X2I{P~6cC%am znrquda2|W8w!iFBV@GU=dZqW{ABR_A&76|WC8xd=UGmU*d=7~Qr1VknJ$&)C9-BZyPySzxlyGg+T$fzHTNpufqAF} zad)xV`0`%@)4W;HH48P`&#DtqmzYT-XA6sh$^uvZQWHF`X$;)ut>Et@$c)BAAy3aE z)ZuLzPI`j-xve9P4b97X&Y$wl?@)v2GDgNKB4tuIDnl59W#UGdmc6I5^XRD0ogE|c z7A$&TKRgz(q`C|=OzAmF@|O~605hedTI@QBv$~|t!r(bwfjC+Pg71y7lIQy|)Cv*C}F$)^iDkjpoOx6@SkIjo6Dq<$+bH(W^aGVBi1sa>Bsx z;7;RVSSd8|3$}L>V%8YQ7Zq*X{7$*9M60Z+QHoB^rk=BmJAFm!YWZuF7r_YJP5tC+ z5xX;cgsFIbI#RXnQzxEI_T{qW0cOi?cW^Jk@HHjL1=s$-uJF>A6)u)Inw=WfW$4Y>1woo~R^Mp2?h_0-<9K(QPmH3=@+hez6`i zu!$(ec$}ASzp%YsFS^ZcJ68(nebCfD3BcKaUb7yG*9Pw_XK|_FqTq1?8UiG2H<|=Z zKrm;$rzKw1y=);Q ze6|;^&`G1OKfDl5LlnU|Ui7RbYH#YRad7hc5FwT!mb}1vXEsdchgWV z_C53tm7iKwYajTbES8Yt^kl}}yoGMAw362ct}vujNDp&-Ty>^K;y72dCA9_xDSV2O zw*O+tDwot9cvUcveiqU49Z{uLkGIv~yyLvcZ7p4Wyrpc|wfgFvaCVafM`+1ZhpmHC`4C z3r|la#k-O~_6U4@T&{M+8?GCDm+rXxNrZiJ3)$a9aTwHdbuWLO~tuGC0N2C0~Gb;Hpk{Fz}TmMcx!!0&#tJ{u2Z&e*xzRvpn zt0gN3%92XRxI=kzWfOA~+So81$fT-$LQgYB-=a0XO)i&AK^3PdS3KSfT&`+4W2&Ny z3m92d>oVEZwtw*}E>@srFC?FBZc)Z9Qd_ZD!QT@v5VD)KPjF!7&+jOGk@uJ3F8Qmf z5P9s$IBV3DO(16zQ{otl3N+^&Q0vbtjUXR!0{5G+YS9};*%p#?NhyuR$r{IBu|bKj z1?(?+?52CsFwwS?Z4s1p>oLE~a~U~F14hNAs9UCSS07F4Vw0OM^Md9OFrSsrRtN0~u0CI0G=7Fm9enti@^XY3PkRfgA z;3_6IpQ&jOr%UEw&5Kf+Gu};`4Mc^XWBwxE z`E-9(UNaXe>I_PY5k0XHrI6+^Muc811Mo8>#$f=sK~d zYuVA}0@Kv&FSl12tz8{R4d<4207@!&vLE?R`gbznK<__lQFPc|k14VO)~=Kjv5~7` zz2!V|s03RCprN|>3>GQW8Eus|8oM4Q^{`+mT#?@r5WGIowwkwV-|u@m%(1l_qTJ!j zl3W7RMlN~kkWyi=bE2$sZM2(_zCyeG7)@ZBSE{z=S0~LW)aCFB2b%j^fr1s+%aM|o zwHkG5I8OzZr!vSsB#xcwPtn69iY0=0Y!&y{&A!S4C4QUF)YjfJu8hOJ`)UdZc)0y}{$i*l4{uFR5GGy}^CfC}{Xd zvq+{`IVku0()`1z{7zx9p$0rj{oA)V0q19=^uo<=Qa?|>#c%x%exkZ>>f>#m_T}Hj z&*0!Q9zxwu2y;vN1i#Jideg}_p5#!U&^CBdwi%AdJ!v=um2Qaf1X#>9&iS?@wGnY4 zGS>))=TxpvA~8sEDya9ExC9rkWbxONAhz0WI&l8MYZu5eO`_Nm)NTICul=+eaY7Wf z>iZBnaURJbr~BM-9#W8OhtEWHp59>T)Z5+h{EV=Ktj>T3Y@oj)S67auAMm|ozBR$@ zi9O+5Zx?`YwJ4>A0Aqy{{-@AsDlLnA7cKbtC^m7-Py5iB0>#8P*_TDH&a4LmM>|XpF>A}}{)R81{aF}$Sn>YjFqo5*M)M;}!KazXJ zU$k4O%yI=TPF`VkSe1kLRY;pHsXn$k1Dy9!(tcR6c}{&pYR-@Y5V_qI+7OLa!>%`b z(s_?~W-Uv)m9ZYNe`2l{j@{0A94fkoX7k5p($~h;z24>u=a!ZI8hjc&O5VNGDrhL5 z6Q?0&AVv}!)s)jq#%hPnuY%3ypuk%+u;CT9l3_pqJaXTMfSP2~^u_KEum*E2tvQcT zDcN7Sh(Gl#sFHMus|&UJ{*VqYEmN{JlOPU_-n?Ubz=Chi`?g51y5@S+P`#YPB*jb7?wr^gN#fjKH_)-w zE*}DX?Y2G4k1!Rb6V6bTBFhonJ2@0q-$n$LE~0^sorkX*0hNSJZf7f<>!;Cj<@VC-!o>)dPtUeKF3Kp=Og1C`*Z=}F43x)y<MMooDu zcdPN;jKAN!N;jSx50eF*G9uCYbarx`g_8jMjr5AMUxR~LG3d!>!sqQzVAlly5qGK& zSz3&@iL-FkhX@Y=26Rc95&oYq(Yh)5o z2zh~-mn#CCUQWqIS+?98S8LPm$Rzx$DmImFom7x(0BtO z!>HQP8%dIj%0On#Z&ghb+ICV}VN=yU>dBpq>fgC#iystGw}ZpKQ_p-g)eg?~M{oK7 z`c69kJdri~9J(0s6{CGwASZTpp3FKx-&AitPO1NjSp}t=+EohM(P036=R&XXW-&r; zz(Ln@LUIATVCR2c5{=ITla%g1&*A}`XCA>26F(fsjQsusQ1CnLCN8Y|o?Q|*Gpr%0 z`C{_9#&6)DOV<`N&ZOuvDs(GoR3?FjBlcNs%*V3!rcXs#Rmw;NYAk!*Q%kr7)5PjD zJ5PXhy39YcZ&uBWm$Vq9*S=5$t~BFF_Q@EeH@F_oNj}Spw(@b%g=O$E>NmjB9qcLW zv7rySdcJh-yLsqNp$1pQ{LFsN995l#S`F^<+hX6|oQ6J!)AcT#hL`hRU*1V!EKusG z?KblC2I9gjMRhs(gefj1up`dB0T$G6Q!S%u=IderBHf$ZZMwl)6PWM9wKknUH$bJ8 z4-DBfeaE;nG9~>RruNfm^nlzvr4HCH*ekfPr?#iHr?F=}^N`UMixM6lAtaVT)6%M* zQI4Llk)^TbXUAq+(#6U-;r-Vuzr3t!J`&@bGV7Kk49d%`Y8tLE`RQ=*NwgsJGeM)NOUS*ZNU6#>E&LQRZCd@el2 zi~vbPxlPZnF`v%is((!w#yARt!zpnuUvUB@q0M;w{rX_%Xm+Lw{D>U5ClJ@RXp3A; zRmMvRlF-N1Yu>I+KG+`r3<~TfV5x1c9NLPXmyCl(fDljWYX7mJ-;>Br!bf9&63}}| z8tps*j(o0O} zs+g~@Nn6@SM$660hlXx1z6OFUOR6s~7VahGj}5+}$k zeVz~BfjQ^szlZJKPxjmq(fH0k1M>Zq!khx2YjDldwoV3Yn+eZxq)We`8RxdHAlIiQo@GxkS zlb5MXP(99`$E;Xtb1YalFdS<)=&cnDf3mqH;wZQ;9Z-cD`C}2MR{pH}iAy5Dml3J( zo8yGR?2C#dp0y_mb=}jA8gxpvuI1nZ)3H!v;KR|P{AoxR+{3Ts-pM~#KPQIjE?ZDi z&n0Z}_!#Jb8K4&=Ib^yzaFmSGYvND|pYoD2(knG_yJ@Btse!rSebRZ5J@L2E=;zub zP;y#F7P$*XLJZZS){qw2x)~y6l+rvU#b|w zsFptd*tIrli)(;v{wV&R=jI(e4E-8~hh6~?XqgM}#pk=cfde!NeuocsPV|<1yEgP4 zqiW=&&SpE+C7u>oKFRCU5*p95J^utV@o8y!Gs}=R1!-95)1zl3Y%OVFzF33FGMt>a znfcbHr1=(3)I~S;c;5x0eHXUq{kDHqL9!gHb&%YW7 zd0r8qSd=Aw)X~dKCv0)75@pM%F*nyvGcX4^=m0v{P(F2J2OXXzX-D}k2~_3n+h~8* z*jky%`{x{PZQ~-V)B8RJ@pS#o&m%gE)8mbwSBnBdF)VTG(=(Lg0KHAt6*}v7nMp z&!deTJ1XlkSss=Ohi#B#5kH%yUQ)k>Xnd&eR}?lG)LyOeOzn?2EXVXquzP>07NI%N zBwtG&i^myS&V3oOV;#?ZL``Kfd$kW2gJ+dyT+BA+HcvBdRVlNk!E?}}Q7SXG(Cnbt zSzymjtcb+(r|rGcw*axOH6-5XUU-1nBB!m7Ek?Du3bbMFuju{j9>Xt<->%>2%Tg7A z>kD2@T~mX~HO&FldEIcb_9FZ>?Hwl&e@x~UHcO-Y$8eCw)QQUsFPOI~`NmA08+8I_K18`huqbV!+AU85(#l_BmxD^0gdS4WqSF>-`V=93SV@euPq zzA`8>#Z2m&zBA+YK@FlZ%1;8173DKXh+GY9UX$WPU^u16Xz92nfbL|XmSzO#+Bxy$ zGPS9?sJgYRNr{fhQO2?`Lu?vx>QT^n{a(ZUQ4DiM#}1s64l{NCXFp$q}Othm8_;O802~)Dj4;>1c=}HnTulGO7j$>BlupNaz1yBZ#Pi!%vl!BM=$FtMF!lP)C>TNVUmO=$`V(o zZG&9y%s2TrL6K7regaO}bbiL!6tog>S!-N4Reay9I%+obq#`~lUXIffaoS?g4kUZL z{P^(A(#*w#h+*V9x?)f`;`{H*1tV?H<#xA4>0Ye`(kYS4&|3%O8j}Fq3$kGltBRZHV4o}yf3Hf~{bXXI= zXiSq?)fkMn&THtt`rtQt{qqiL-sHLAu6oDqmGDUJOz;et7OVxDLw}4|_X=KT`12+q zeNs@^l7vlB=|=7i@9)7NiYyL<|HdiID*Sscf~>?`E-xYww(+~z8eF7Zk$jO}lkt+F zdztABLj;(c;i+s_E&9kQ*Xy#&E_}&AOqbUljFJYX$1@J*I;$1g4L55{Z?#x-Xx!7u zsEBZ{Gdjx2!Tt=G#Y|U9N+YKmbLCEt(F2^8+`SEAwqj`$_fFjB$WPC=vA1=8#56cB8JRT{*Kg_2!MumM*cZe_|>_Y{M(7N;fAlk?mFl=bheDuUM zvd&!blyRpRn<$%&a-BjJ*>(a zEj#eeetel7rxhkU-VJ=%-&&Ztdr)}A%>VdqErfzk9HIF^_Ok%I|D9N6aVjTpAGMo* zH=?64rh7>Vd^{M_Nc&G-HXF`#}6Bb`T3U*ymd|1UEO>Hh=<>lM@6M z4WO{#WaB1b{?{O}CxQR(8)jAz=U=hWzhfMn|BCq!jO(x0zhkV-94!CDSlBtZS-_J4 z6aWjyUs=+>$6)2+{(H{(zhfMn{}F?k1H|#qxXhfa%>R)mCp*VKvA^?!{@WM$AB+6U zR|oy4A&BFj$^47g{vUQ6Y^;9|U;nqHS-4o({=<%oll_0%{hgngnT6|rbLRYC0&;Qx zvs$do>|FocEmmeO?*G94Zu>tmHdZcW)_<1pFZgd6{wu-1*#9Zl|ELxlEBC+jXa5@i z?=ks{ae%;mK>~&*9PCD>X3XrSATBd*4kHjJtFgH$m#Hb+-xaVK8*>T3^ZkEKNc2el dYRz0+jhtOQoz2YQ+1OZ^+2JWD#1zEg{|m+9b_M_d delta 26700 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 From 245bfecc3d6c66748fef72613e27940807246bd1 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Wed, 9 Dec 2015 02:54:18 +0900 Subject: [PATCH 174/358] update ir.rb --- app/apis/api/v1/ir.rb | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/app/apis/api/v1/ir.rb b/app/apis/api/v1/ir.rb index 3c16b9e..f7c8ed0 100644 --- a/app/apis/api/v1/ir.rb +++ b/app/apis/api/v1/ir.rb @@ -73,6 +73,8 @@ class IR < Grape::API }, response: {}) end infrared.update(data: "#{fname}") + user.log.create(name: "赤外線を受信しました", status: :recieve_ir) + user.log.infrared = infrared @infrared = infrared end else @@ -113,6 +115,8 @@ class IR < Grape::API `#{command} #{path}/data/#{fname}` count = infrared.count + 1 infrared.update(count: count) + user.log.create(name: "「#{infrared.name}」を実行しました", status: :send_ir) + user.log.infrared = infrared @infrared = infrared else error!(meta: { @@ -158,6 +162,8 @@ class IR < Grape::API else if infrared = user.infrareds.find_by(id: params[:ir_id]) infrared.update(name: params[:name]) + user.log.create(name: "「#{infrared.name}」に名前を変更しました", status: :update_ir) + user.log.infrared = infrared @infrared = infrared else error!(meta: { @@ -204,6 +210,8 @@ class IR < Grape::API name = infrared.data file = Rails.root.to_s + "/data/" + name File.delete file + user.log.create(name: "「#{infrared.name}」を削除しました", status: :destroy_ir) + user.log.infrared = infrared infrared.destroy else error!(meta: { From c9b48f5477163dcb9e3b7d7dad3a557b5dc1b2b6 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Wed, 9 Dec 2015 03:03:25 +0900 Subject: [PATCH 175/358] :bug: fix --- app/apis/api/v1/ir.rb | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/app/apis/api/v1/ir.rb b/app/apis/api/v1/ir.rb index 3c16b9e..49cf72e 100644 --- a/app/apis/api/v1/ir.rb +++ b/app/apis/api/v1/ir.rb @@ -73,6 +73,8 @@ class IR < Grape::API }, response: {}) end infrared.update(data: "#{fname}") + user.logs.create(name: "赤外線を受信しました", status: :recieve_ir) + user.logs.infrared = infrared @infrared = infrared end else @@ -113,6 +115,8 @@ class IR < Grape::API `#{command} #{path}/data/#{fname}` count = infrared.count + 1 infrared.update(count: count) + user.logs.create(name: "「#{infrared.name}」を実行しました", status: :send_ir) + user.logs.infrared = infrared @infrared = infrared else error!(meta: { @@ -158,6 +162,8 @@ class IR < Grape::API else if infrared = user.infrareds.find_by(id: params[:ir_id]) infrared.update(name: params[:name]) + user.logs.create(name: "「#{infrared.name}」に名前を変更しました", status: :update_ir) + user.logs.infrared = infrared @infrared = infrared else error!(meta: { @@ -204,6 +210,8 @@ class IR < Grape::API name = infrared.data file = Rails.root.to_s + "/data/" + name File.delete file + user.logs.create(name: "「#{infrared.name}」を削除しました", status: :destroy_ir) + user.logs.infrared = infrared infrared.destroy else error!(meta: { From 38485e964585fff65132d317cf085f2fd76f2864 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Wed, 9 Dec 2015 03:07:57 +0900 Subject: [PATCH 176/358] :bug: fix --- app/apis/api/v1/ir.rb | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/app/apis/api/v1/ir.rb b/app/apis/api/v1/ir.rb index 49cf72e..413eda1 100644 --- a/app/apis/api/v1/ir.rb +++ b/app/apis/api/v1/ir.rb @@ -73,8 +73,8 @@ class IR < Grape::API }, response: {}) end infrared.update(data: "#{fname}") - user.logs.create(name: "赤外線を受信しました", status: :recieve_ir) - user.logs.infrared = infrared + log = user.logs.create(name: "赤外線を受信しました", status: :recieve_ir) + log.infrared = infrared @infrared = infrared end else @@ -115,8 +115,8 @@ class IR < Grape::API `#{command} #{path}/data/#{fname}` count = infrared.count + 1 infrared.update(count: count) - user.logs.create(name: "「#{infrared.name}」を実行しました", status: :send_ir) - user.logs.infrared = infrared + log = user.logs.create(name: "「#{infrared.name}」を実行しました", status: :send_ir) + log.infrared = infrared @infrared = infrared else error!(meta: { @@ -162,8 +162,8 @@ class IR < Grape::API else if infrared = user.infrareds.find_by(id: params[:ir_id]) infrared.update(name: params[:name]) - user.logs.create(name: "「#{infrared.name}」に名前を変更しました", status: :update_ir) - user.logs.infrared = infrared + log = user.logs.create(name: "「#{infrared.name}」に名前を変更しました", status: :update_ir) + log.infrared = infrared @infrared = infrared else error!(meta: { @@ -210,8 +210,8 @@ class IR < Grape::API name = infrared.data file = Rails.root.to_s + "/data/" + name File.delete file - user.logs.create(name: "「#{infrared.name}」を削除しました", status: :destroy_ir) - user.logs.infrared = infrared + log = user.logs.create(name: "「#{infrared.name}」を削除しました", status: :destroy_ir) + log.infrared = infrared infrared.destroy else error!(meta: { From 3a616745b6dedaffffb1034afe72cedddcae9525 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Wed, 9 Dec 2015 03:21:24 +0900 Subject: [PATCH 177/358] update readme --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 171e5db..a579d6e 100644 --- a/README.md +++ b/README.md @@ -16,4 +16,9 @@ sudo gcc recieve.c -o recieve -lwiringPi ``` sudo gcc send.c -lm -o send -lwiringPi +``` + +### 本番サーバーからdumpファイルを作成 +``` +scp pi@hostname:~/rails_app/switch_api/db/development.sqlite3 ./dump.sqlite3 ``` \ No newline at end of file From 4b14199d7ef7c475571574553942c96b2dbf1110 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Wed, 9 Dec 2015 03:30:20 +0900 Subject: [PATCH 178/358] update readme --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index a579d6e..53252eb 100644 --- a/README.md +++ b/README.md @@ -21,4 +21,10 @@ sudo gcc send.c -lm -o send -lwiringPi ### 本番サーバーからdumpファイルを作成 ``` scp pi@hostname:~/rails_app/switch_api/db/development.sqlite3 ./dump.sqlite3 +``` + +### 赤外線情報ファイルの取得 + +``` +scp -r pi@hostname:~/rails_app/switch_api/data ./ ``` \ No newline at end of file From 842645db5bf05251846907aa357ec6e02a96a00d Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Wed, 9 Dec 2015 05:10:07 +0900 Subject: [PATCH 179/358] create logs api --- app/apis/api/v1/ir.rb | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/app/apis/api/v1/ir.rb b/app/apis/api/v1/ir.rb index 413eda1..177cd0c 100644 --- a/app/apis/api/v1/ir.rb +++ b/app/apis/api/v1/ir.rb @@ -233,6 +233,44 @@ class IR < Grape::API }, response: {}) end end + desc '赤外線のlog', notes: <<-NOTE +

赤外線のログを表示します

+

+ sizeを渡すと最新〜sizeまでのログを取得します。 + 何も指定しない場合は全部取得します +

+ NOTE + params do + requires :auth_token, type: String, desc: 'Auth token.' + optional :size, type: Integer, desc: 'Array size' + end + get '/logs', jbuilder: 'api/v1/ir/logs' do + if (token = AuthToken.find_by(token: params[:auth_token])) + if user.info.nil? + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.user_not_found'), + code: ErrorCodes::NOT_FOUND_USER + ] + }, response: {}) + else + if params[:size].nil? + @logs = user.logs.sort{|a,b|b<=>a} + else + @logs = user.logs.last(params[:size].to_i).sort{|a,b|b<=>a} + end + end + else + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.invalid_token'), + code: ErrorCodes::INVALID_TOKEN + ] + }, response: {}) + end + end end end end From 0ee5c1c9bd2ffdb1ef9fd745709c1bf57de576e0 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Wed, 9 Dec 2015 05:10:13 +0900 Subject: [PATCH 180/358] create logs jbuilder --- app/views/apis/api/v1/ir/logs.jbuilder | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 app/views/apis/api/v1/ir/logs.jbuilder diff --git a/app/views/apis/api/v1/ir/logs.jbuilder b/app/views/apis/api/v1/ir/logs.jbuilder new file mode 100644 index 0000000..cf963bc --- /dev/null +++ b/app/views/apis/api/v1/ir/logs.jbuilder @@ -0,0 +1,8 @@ +json.meta do + json.status 200 + json.message 'ログデータ一覧を受信しました。' +end +json.response do + json.logs @logs +end + From 5a71e896c08132a3d9043587f08b3f49bb009d01 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Wed, 9 Dec 2015 05:30:11 +0900 Subject: [PATCH 181/358] add setting --- app/apis/api/v1/base.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/apis/api/v1/base.rb b/app/apis/api/v1/base.rb index d60b3db..8877cf3 100644 --- a/app/apis/api/v1/base.rb +++ b/app/apis/api/v1/base.rb @@ -33,6 +33,7 @@ class Base < Grape::API mount V1::Users mount V1::Authorize mount V1::IR + mount V1::InfraredGroup add_swagger_documentation format: :json, api_version: 'v1', hide_documentation_path: true end end From bec35aade1cb92730aa2cab7261331623802e17e Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Wed, 9 Dec 2015 05:30:20 +0900 Subject: [PATCH 182/358] create infrared group base --- app/apis/api/v1/infrared_group.rb | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 app/apis/api/v1/infrared_group.rb diff --git a/app/apis/api/v1/infrared_group.rb b/app/apis/api/v1/infrared_group.rb new file mode 100644 index 0000000..0b96bed --- /dev/null +++ b/app/apis/api/v1/infrared_group.rb @@ -0,0 +1,18 @@ +# app/apis/api/v1/ir.rb + +module API + module V1 + class InfraredGroup < Grape::API + resource :group do + desc 'グループ内の赤外線一覧の表示', notes: <<-NOTE +

グループ内の赤外線を表示

+

+ グループ内の赤外線を表示します +

+ NOTE + get '/ping', jbuilder: 'api/v1/group/ping' do + end + end + end + end +end From 694cc9148e038c9bb4eb8400d0e52290a2a92e4b Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Wed, 9 Dec 2015 05:30:25 +0900 Subject: [PATCH 183/358] add jbuilder --- app/views/apis/api/v1/group/ping.jbuilder | 1 + 1 file changed, 1 insertion(+) create mode 100644 app/views/apis/api/v1/group/ping.jbuilder diff --git a/app/views/apis/api/v1/group/ping.jbuilder b/app/views/apis/api/v1/group/ping.jbuilder new file mode 100644 index 0000000..a677448 --- /dev/null +++ b/app/views/apis/api/v1/group/ping.jbuilder @@ -0,0 +1 @@ +json.response "pong" \ No newline at end of file From 5f7bc2eb16dc5881c9c19c8d3cb2443492d1ec7e Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Wed, 9 Dec 2015 05:47:18 +0900 Subject: [PATCH 184/358] create group api --- app/apis/api/v1/infrared_group.rb | 34 +++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/app/apis/api/v1/infrared_group.rb b/app/apis/api/v1/infrared_group.rb index 0b96bed..c2dbaa5 100644 --- a/app/apis/api/v1/infrared_group.rb +++ b/app/apis/api/v1/infrared_group.rb @@ -12,6 +12,40 @@ class InfraredGroup < Grape::API NOTE get '/ping', jbuilder: 'api/v1/group/ping' do end + + desc 'グループの作成', notes: <<-NOTE +

グループを作成する

+

+ グループを作成します。 +

+ NOTE + params do + requires :auth_token, type: String, desc: 'Auth token.' + requires :name, type: String, desc: 'Group name.' + end + post '/', jbuilder: 'api/v1/group/create' do + if (token = AuthToken.find_by(token: params[:auth_token])) + if user.info.nil? + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.user_not_found'), + code: ErrorCodes::NOT_FOUND_USER + ] + }, response: {}) + else + @group = user.infrared_groups.create(name: params[:name]) + end + else + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.invalid_token'), + code: ErrorCodes::INVALID_TOKEN + ] + }, response: {}) + end + end end end end From 3fec27cbcd6c4cdef0c39558c86b880faae5b7ef Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Wed, 9 Dec 2015 05:47:26 +0900 Subject: [PATCH 185/358] remove not using jbuilder --- app/views/apis/api/v1/user/create.jbuilder | 1 - 1 file changed, 1 deletion(-) delete mode 100644 app/views/apis/api/v1/user/create.jbuilder diff --git a/app/views/apis/api/v1/user/create.jbuilder b/app/views/apis/api/v1/user/create.jbuilder deleted file mode 100644 index c978e8d..0000000 --- a/app/views/apis/api/v1/user/create.jbuilder +++ /dev/null @@ -1 +0,0 @@ -json.auth_token @token From 1c60c5582bebf037192299d93bdf5ced3f9d0606 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Wed, 9 Dec 2015 05:47:34 +0900 Subject: [PATCH 186/358] create jbuilder --- app/views/apis/api/v1/group/create.jbuilder | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 app/views/apis/api/v1/group/create.jbuilder diff --git a/app/views/apis/api/v1/group/create.jbuilder b/app/views/apis/api/v1/group/create.jbuilder new file mode 100644 index 0000000..ad49c44 --- /dev/null +++ b/app/views/apis/api/v1/group/create.jbuilder @@ -0,0 +1,7 @@ +json.meta do + json.status 201 + json.message "#{@group.name}を作成しました。" +end +json.response do + json.group @group +end From e1b0f80a27dbca2be1749cc082c774592e8424ce Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Wed, 9 Dec 2015 05:55:42 +0900 Subject: [PATCH 187/358] create group index --- app/apis/api/v1/infrared_group.rb | 33 +++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/app/apis/api/v1/infrared_group.rb b/app/apis/api/v1/infrared_group.rb index c2dbaa5..1fa67e1 100644 --- a/app/apis/api/v1/infrared_group.rb +++ b/app/apis/api/v1/infrared_group.rb @@ -13,6 +13,39 @@ class InfraredGroup < Grape::API get '/ping', jbuilder: 'api/v1/group/ping' do end + desc 'グループの一覧表示', notes: <<-NOTE +

グループを一覧表示する

+

+ グループを一覧表示します。 +

+ NOTE + params do + requires :auth_token, type: String, desc: 'Auth token.' + end + get '/', jbuilder: 'api/v1/group/index' do + if (token = AuthToken.find_by(token: params[:auth_token])) + if user.info.nil? + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.user_not_found'), + code: ErrorCodes::NOT_FOUND_USER + ] + }, response: {}) + else + @groups = user.infrared_groups + end + else + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.invalid_token'), + code: ErrorCodes::INVALID_TOKEN + ] + }, response: {}) + end + end + desc 'グループの作成', notes: <<-NOTE

グループを作成する

From 35fd09c5cfaab1b4612b26105344164f925aac24 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Wed, 9 Dec 2015 05:55:50 +0900 Subject: [PATCH 188/358] create group index jbuilder --- app/views/apis/api/v1/group/index.jbuilder | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 app/views/apis/api/v1/group/index.jbuilder diff --git a/app/views/apis/api/v1/group/index.jbuilder b/app/views/apis/api/v1/group/index.jbuilder new file mode 100644 index 0000000..1bf7fe2 --- /dev/null +++ b/app/views/apis/api/v1/group/index.jbuilder @@ -0,0 +1,8 @@ +json.meta do + json.status 200 + json.message 'グループ一覧を取得しました。' +end +json.response do + json.groups @groups +end + From 3ee268fb116c7fea55d6fbb364f2378058b8d56e Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Wed, 9 Dec 2015 06:05:30 +0900 Subject: [PATCH 189/358] create update group name api --- app/apis/api/v1/infrared_group.rb | 47 +++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/app/apis/api/v1/infrared_group.rb b/app/apis/api/v1/infrared_group.rb index 1fa67e1..94bbe00 100644 --- a/app/apis/api/v1/infrared_group.rb +++ b/app/apis/api/v1/infrared_group.rb @@ -79,6 +79,53 @@ class InfraredGroup < Grape::API }, response: {}) end end + + desc 'グループのアップデート', notes: <<-NOTE +

グループをアップデートする

+

+ グループをアップデートします。 +

+ NOTE + params do + requires :auth_token, type: String, desc: 'Auth token.' + requires :name, type: String, desc: 'Name.' + requires :group_id, type: Integer, desc: 'Group_id.' + end + put '/', jbuilder: 'api/v1/group/update' do + if (token = AuthToken.find_by(token: params[:auth_token])) + if user.info.nil? + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.user_not_found'), + code: ErrorCodes::NOT_FOUND_USER + ] + }, response: {}) + else + if group = user.infrared_groups.find_by(id: params[:group_id]) + group.update(name: params[:name]) + @group = group + else + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.group_not_found'), + code: ErrorCodes::NOT_FOUND + ] + }, response: {}) + end + end + else + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.invalid_token'), + code: ErrorCodes::INVALID_TOKEN + ] + }, response: {}) + end + end + end end end From d40fc2247fa9f3cc5fd977b91291c552aa2f3fdd Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Wed, 9 Dec 2015 06:05:36 +0900 Subject: [PATCH 190/358] create jbuilder --- app/views/apis/api/v1/group/update.jbuilder | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 app/views/apis/api/v1/group/update.jbuilder diff --git a/app/views/apis/api/v1/group/update.jbuilder b/app/views/apis/api/v1/group/update.jbuilder new file mode 100644 index 0000000..45134fc --- /dev/null +++ b/app/views/apis/api/v1/group/update.jbuilder @@ -0,0 +1,7 @@ +json.meta do + json.status 200 + json.message 'グループ名を変更しました。' +end +json.response do + json.group @group +end From 95862f7753ba725de672725e1352d4e4888c51dd Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Wed, 9 Dec 2015 06:14:11 +0900 Subject: [PATCH 191/358] create destroy api --- app/apis/api/v1/infrared_group.rb | 45 +++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/app/apis/api/v1/infrared_group.rb b/app/apis/api/v1/infrared_group.rb index 94bbe00..3aed881 100644 --- a/app/apis/api/v1/infrared_group.rb +++ b/app/apis/api/v1/infrared_group.rb @@ -126,6 +126,51 @@ class InfraredGroup < Grape::API end end + desc 'グループの削除', notes: <<-NOTE +

グループを削除する

+

+ グループを削除します。 +

+ NOTE + params do + requires :auth_token, type: String, desc: 'Auth token.' + requires :group_id, type: Integer, desc: 'Group_id.' + end + delete '/', jbuilder: 'api/v1/group/destroy' do + if (token = AuthToken.find_by(token: params[:auth_token])) + if user.info.nil? + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.user_not_found'), + code: ErrorCodes::NOT_FOUND_USER + ] + }, response: {}) + else + if group = user.infrared_groups.find_by(id: params[:group_id]) + @group = group + group.destroy + else + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.group_not_found'), + code: ErrorCodes::NOT_FOUND + ] + }, response: {}) + end + end + else + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.invalid_token'), + code: ErrorCodes::INVALID_TOKEN + ] + }, response: {}) + end + end + end end end From b8cee37a06c04102ef81a2f01263b06fd14e7078 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Wed, 9 Dec 2015 06:14:16 +0900 Subject: [PATCH 192/358] create jbuilder --- app/views/apis/api/v1/group/destroy.jbuilder | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 app/views/apis/api/v1/group/destroy.jbuilder diff --git a/app/views/apis/api/v1/group/destroy.jbuilder b/app/views/apis/api/v1/group/destroy.jbuilder new file mode 100644 index 0000000..6452cc7 --- /dev/null +++ b/app/views/apis/api/v1/group/destroy.jbuilder @@ -0,0 +1,6 @@ +json.meta do + json.status 200 + json.message "「#{@group.name}」を削除しました。" +end +json.response do +end From 6fbaeb57019d970a203345cabecde1d419a0575a Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Wed, 9 Dec 2015 06:29:04 +0900 Subject: [PATCH 193/358] update ir add api --- app/apis/api/v1/infrared_group.rb | 70 +++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/app/apis/api/v1/infrared_group.rb b/app/apis/api/v1/infrared_group.rb index 3aed881..11e8603 100644 --- a/app/apis/api/v1/infrared_group.rb +++ b/app/apis/api/v1/infrared_group.rb @@ -171,6 +171,76 @@ class InfraredGroup < Grape::API end end + resource :ir do + desc '赤外線の追加', notes: <<-NOTE +

グループに赤外線を追加する

+

+ グループに赤外線を追加します。 +

+ NOTE + params do + requires :auth_token, type: String, desc: 'Auth token.' + requires :group_id, type: Integer, desc: 'Group_id.' + requires :ir_id, type: Integer, desc: 'IR_id.' + + end + post '/add', jbuilder: 'api/v1/group/ir/add' do + if (token = AuthToken.find_by(token: params[:auth_token])) + if user.info.nil? + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.user_not_found'), + code: ErrorCodes::NOT_FOUND_USER + ] + }, response: {}) + else + if group = user.infrared_groups.find_by(id: params[:group_id]) + if ir = user.infrareds.find_by(id: params[:ir_id]) + if !group.infrareds.find_by(id: params[:ir_id]) + group.infrareds << ir + @group = group + @ir = ir + else + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.ir_already_existing'), + code: ErrorCodes::ALREADY_EXISTING + ] + }, response: {}) + end + else + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.ir_not_found'), + code: ErrorCodes::NOT_FOUND + ] + }, response: {}) + end + else + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.group_not_found'), + code: ErrorCodes::NOT_FOUND + ] + }, response: {}) + end + end + else + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.invalid_token'), + code: ErrorCodes::INVALID_TOKEN + ] + }, response: {}) + end + end + + end end end end From da368f9e71136e9a6d7893384fed568d83249607 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Wed, 9 Dec 2015 06:29:12 +0900 Subject: [PATCH 194/358] create add jbuilder --- app/views/apis/api/v1/group/ir/add.jbuilder | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 app/views/apis/api/v1/group/ir/add.jbuilder diff --git a/app/views/apis/api/v1/group/ir/add.jbuilder b/app/views/apis/api/v1/group/ir/add.jbuilder new file mode 100644 index 0000000..a67e66e --- /dev/null +++ b/app/views/apis/api/v1/group/ir/add.jbuilder @@ -0,0 +1,9 @@ +json.meta do + json.status 201 + json.message "「#{@group.name}」に#{@ir.name}を追加しました。" +end +json.response do + json.group do + json.infrareds @group.infrareds + end +end From 0c75e464add3c642e0a9f9117f0d1d281cbaccb6 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Wed, 9 Dec 2015 11:11:55 +0900 Subject: [PATCH 195/358] create group ir index api --- app/apis/api/v1/infrared_group.rb | 48 ++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/app/apis/api/v1/infrared_group.rb b/app/apis/api/v1/infrared_group.rb index 11e8603..77b7f9b 100644 --- a/app/apis/api/v1/infrared_group.rb +++ b/app/apis/api/v1/infrared_group.rb @@ -182,7 +182,6 @@ class InfraredGroup < Grape::API requires :auth_token, type: String, desc: 'Auth token.' requires :group_id, type: Integer, desc: 'Group_id.' requires :ir_id, type: Integer, desc: 'IR_id.' - end post '/add', jbuilder: 'api/v1/group/ir/add' do if (token = AuthToken.find_by(token: params[:auth_token])) @@ -240,6 +239,53 @@ class InfraredGroup < Grape::API end end + desc 'グループの赤外線一覧表示', notes: <<-NOTE +

グループの赤外線を一覧表示する

+

+ グループの赤外線を一覧表示します。 +

+ NOTE + params do + requires :auth_token, type: String, desc: 'Auth token.' + requires :group_id, type: Integer, desc: 'Group_id.' + end + get '/', jbuilder: 'api/v1/group/ir/index' do + if (token = AuthToken.find_by(token: params[:auth_token])) + if user.info.nil? + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.user_not_found'), + code: ErrorCodes::NOT_FOUND_USER + ] + }, response: {}) + else + if group = user.infrared_groups.find_by(id: params[:group_id]) + @group = group + @infrareds = group.infrareds + else + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.group_not_found'), + code: ErrorCodes::NOT_FOUND + ] + }, response: {}) + end + end + else + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.invalid_token'), + code: ErrorCodes::INVALID_TOKEN + ] + }, response: {}) + end + end + + + end end end From 20fde59e3f1c01c94e309237444966045597c038 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Wed, 9 Dec 2015 11:12:07 +0900 Subject: [PATCH 196/358] create group ir index jbuilder --- app/views/apis/api/v1/group/ir/index.jbuilder | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 app/views/apis/api/v1/group/ir/index.jbuilder diff --git a/app/views/apis/api/v1/group/ir/index.jbuilder b/app/views/apis/api/v1/group/ir/index.jbuilder new file mode 100644 index 0000000..8b5f07b --- /dev/null +++ b/app/views/apis/api/v1/group/ir/index.jbuilder @@ -0,0 +1,9 @@ +json.meta do + json.status 200 + json.message "「#{@group.name}」の赤外線一覧を取得しました。" +end +json.response do + json.group do + json.infrareds @group.infrareds + end +end From 561645314918ab5eb65b522ae97bfc8d83fb1b24 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Wed, 9 Dec 2015 11:13:35 +0900 Subject: [PATCH 197/358] update --- app/apis/api/v1/infrared_group.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/apis/api/v1/infrared_group.rb b/app/apis/api/v1/infrared_group.rb index 77b7f9b..5be8522 100644 --- a/app/apis/api/v1/infrared_group.rb +++ b/app/apis/api/v1/infrared_group.rb @@ -183,7 +183,7 @@ class InfraredGroup < Grape::API requires :group_id, type: Integer, desc: 'Group_id.' requires :ir_id, type: Integer, desc: 'IR_id.' end - post '/add', jbuilder: 'api/v1/group/ir/add' do + post '/', jbuilder: 'api/v1/group/ir/add' do if (token = AuthToken.find_by(token: params[:auth_token])) if user.info.nil? error!(meta: { From f640a76b38f8547da5d72fc63965a571c5e4de08 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Wed, 9 Dec 2015 11:41:44 +0900 Subject: [PATCH 198/358] create group ir destroy --- app/apis/api/v1/infrared_group.rb | 67 +++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/app/apis/api/v1/infrared_group.rb b/app/apis/api/v1/infrared_group.rb index 5be8522..04fa2bb 100644 --- a/app/apis/api/v1/infrared_group.rb +++ b/app/apis/api/v1/infrared_group.rb @@ -239,6 +239,73 @@ class InfraredGroup < Grape::API end end + desc '赤外線の削除', notes: <<-NOTE +

グループに赤外線情報を削除する

+

+ グループに赤外線情報を削除します。 +

+ NOTE + params do + requires :auth_token, type: String, desc: 'Auth token.' + requires :group_id, type: Integer, desc: 'Group_id.' + requires :ir_id, type: Integer, desc: 'IR_id.' + end + delete '/', jbuilder: 'api/v1/group/ir/remove' do + if (token = AuthToken.find_by(token: params[:auth_token])) + if user.info.nil? + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.user_not_found'), + code: ErrorCodes::NOT_FOUND_USER + ] + }, response: {}) + else + if group = user.infrared_groups.find_by(id: params[:group_id]) + if ir = user.infrareds.find_by(id: params[:ir_id]) + if relational = group.infrared_relationals.find_by(infrared_id: params[:ir_id]) + @group = group + @ir = ir + relational.destroy + else + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.ir_not_found_in_group'), + code: ErrorCodes::NOT_FOUND + ] + }, response: {}) + end + else + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.ir_not_found'), + code: ErrorCodes::NOT_FOUND + ] + }, response: {}) + end + else + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.group_not_found'), + code: ErrorCodes::NOT_FOUND + ] + }, response: {}) + end + end + else + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.invalid_token'), + code: ErrorCodes::INVALID_TOKEN + ] + }, response: {}) + end + end + desc 'グループの赤外線一覧表示', notes: <<-NOTE

グループの赤外線を一覧表示する

From 3ed9cfefdf15ec648bc8e701ba40edb7e97d00d3 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Wed, 9 Dec 2015 11:42:30 +0900 Subject: [PATCH 199/358] create group ir delete jbuilder --- app/views/apis/api/v1/group/ir/remove.jbuilder | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 app/views/apis/api/v1/group/ir/remove.jbuilder diff --git a/app/views/apis/api/v1/group/ir/remove.jbuilder b/app/views/apis/api/v1/group/ir/remove.jbuilder new file mode 100644 index 0000000..64723ce --- /dev/null +++ b/app/views/apis/api/v1/group/ir/remove.jbuilder @@ -0,0 +1,9 @@ +json.meta do + json.status 200 + json.message "「#{@group.name}」から「#{@ir.name}」を削除しました。" +end +json.response do + json.group do + json.infrareds @group.infrareds + end +end From 74f9db6983d074f913664fc26f6d069b3cdbc1fd Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Wed, 9 Dec 2015 14:41:41 +0900 Subject: [PATCH 200/358] bundle exec erd --- erd.pdf | Bin 33982 -> 33988 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/erd.pdf b/erd.pdf index 27b062f45ed29f02bd580762db9a52ed3e183e6a..9f83264356d1401dd52b52e687e1b8bb03bbaa70 100644 GIT binary patch delta 23490 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 delta 23468 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 Tta17Id3gkIU%!@Blf(Tl%mW&> From d76d2098f8761913d4a10fc32bad5674a32a87e0 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Wed, 9 Dec 2015 14:59:21 +0900 Subject: [PATCH 201/358] add log --- app/apis/api/v1/infrared_group.rb | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/app/apis/api/v1/infrared_group.rb b/app/apis/api/v1/infrared_group.rb index 04fa2bb..602a1c1 100644 --- a/app/apis/api/v1/infrared_group.rb +++ b/app/apis/api/v1/infrared_group.rb @@ -195,11 +195,13 @@ class InfraredGroup < Grape::API }, response: {}) else if group = user.infrared_groups.find_by(id: params[:group_id]) - if ir = user.infrareds.find_by(id: params[:ir_id]) + if infrared = user.infrareds.find_by(id: params[:ir_id]) if !group.infrareds.find_by(id: params[:ir_id]) - group.infrareds << ir + group.infrareds << infrared + log = user.logs.create(name: "「#{infrared.name}」を「#{group.name}」に追加しました", status: :add_ir) + log.infrared = infrared @group = group - @ir = ir + @infrared = infrared else error!(meta: { status: 400, @@ -262,11 +264,13 @@ class InfraredGroup < Grape::API }, response: {}) else if group = user.infrared_groups.find_by(id: params[:group_id]) - if ir = user.infrareds.find_by(id: params[:ir_id]) + if infrared = user.infrareds.find_by(id: params[:ir_id]) if relational = group.infrared_relationals.find_by(infrared_id: params[:ir_id]) @group = group - @ir = ir + @infrared = infrared relational.destroy + log = user.logs.create(name: "「#{infrared.name}」を「#{group.name}」から削除しました", status: :remove_ir) + log.infrared = infrared else error!(meta: { status: 400, From 1ae207fd723a71a715d14479244d4a09c571d0ac Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Wed, 9 Dec 2015 14:59:36 +0900 Subject: [PATCH 202/358] add optional id field --- app/apis/api/v1/ir.rb | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/app/apis/api/v1/ir.rb b/app/apis/api/v1/ir.rb index 177cd0c..8804072 100644 --- a/app/apis/api/v1/ir.rb +++ b/app/apis/api/v1/ir.rb @@ -40,11 +40,13 @@ class IR < Grape::API desc '赤外線の受信', notes: <<-NOTE

赤外線を受信します

- 赤外線を受信します + 赤外線を受信します。 + 任意でグループIDを渡すと、そのグループに紐付けてくれます。

NOTE params do requires :auth_token, type: String, desc: 'Auth token.' + optional :group_id, type: Integer, desc: 'Group ID.' end post '/recieve', jbuilder: 'api/v1/ir/recieve' do if (token = AuthToken.find_by(token: params[:auth_token])) @@ -75,6 +77,21 @@ class IR < Grape::API infrared.update(data: "#{fname}") log = user.logs.create(name: "赤外線を受信しました", status: :recieve_ir) log.infrared = infrared + if !params[:group_id].nil? + if group = user.infrared_groups.find_by(id: params[:group_id]) + group.infrareds << infrared + log = user.logs.create(name: "「#{infrared.name}」を「#{group.name}」に追加しました", status: :add_ir) + log.infrared = infrared + else + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.ir_accept_but_group_not_found'), + code: ErrorCodes::NOT_FOUND + ] + }, response: {}) + end + end @infrared = infrared end else From 57b3dc9dcfcd3b4ac327a961fe62b21fb96d4fbd Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Wed, 9 Dec 2015 14:59:44 +0900 Subject: [PATCH 203/358] add enum status --- app/models/log.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/log.rb b/app/models/log.rb index facdc52..5af231e 100644 --- a/app/models/log.rb +++ b/app/models/log.rb @@ -1,5 +1,5 @@ class Log < ActiveRecord::Base belongs_to :user belongs_to :infrared, dependent: :destroy - enum status: %i(recieve_ir send_ir update_ir destroy_ir) + enum status: %i(recieve_ir send_ir update_ir destroy_ir add_ir remove_ir) end From a4ca200c9e00aca1053f42bde769380ff3d029e3 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Wed, 9 Dec 2015 14:59:52 +0900 Subject: [PATCH 204/358] rename jbuilder --- app/views/apis/api/v1/group/ir/add.jbuilder | 2 +- app/views/apis/api/v1/group/ir/remove.jbuilder | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/apis/api/v1/group/ir/add.jbuilder b/app/views/apis/api/v1/group/ir/add.jbuilder index a67e66e..d66f050 100644 --- a/app/views/apis/api/v1/group/ir/add.jbuilder +++ b/app/views/apis/api/v1/group/ir/add.jbuilder @@ -1,6 +1,6 @@ json.meta do json.status 201 - json.message "「#{@group.name}」に#{@ir.name}を追加しました。" + json.message "「#{@group.name}」に#{@infrared.name}を追加しました。" end json.response do json.group do diff --git a/app/views/apis/api/v1/group/ir/remove.jbuilder b/app/views/apis/api/v1/group/ir/remove.jbuilder index 64723ce..b4c50f6 100644 --- a/app/views/apis/api/v1/group/ir/remove.jbuilder +++ b/app/views/apis/api/v1/group/ir/remove.jbuilder @@ -1,6 +1,6 @@ json.meta do json.status 200 - json.message "「#{@group.name}」から「#{@ir.name}」を削除しました。" + json.message "「#{@group.name}」から「#{@infrared.name}」を削除しました。" end json.response do json.group do From 4af65ce7d6623e3bcaeac21aca289a2139e6be4d Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Wed, 9 Dec 2015 15:19:10 +0900 Subject: [PATCH 205/358] rubocop -a --- Vagrantfile | 18 +- app/apis/api/v1/authorize.rb | 12 +- app/apis/api/v1/infrared_group.rb | 191 ++++++++++----------- app/apis/api/v1/ir.rb | 154 ++++++++--------- app/views/apis/api/v1/group/index.jbuilder | 1 - app/views/apis/api/v1/group/ping.jbuilder | 2 +- app/views/apis/api/v1/ir/index.jbuilder | 1 - app/views/apis/api/v1/ir/logs.jbuilder | 1 - db/schema.rb | 100 ++++++----- 9 files changed, 236 insertions(+), 244 deletions(-) diff --git a/Vagrantfile b/Vagrantfile index a814cd7..8e908a1 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -1,29 +1,29 @@ # -*- mode: ruby -*- # vi: set ft=ruby : -Vagrant.configure("2") do |config| +Vagrant.configure('2') do |config| # All Vagrant configuration is done here. The most common configuration # options are documented and commented below. For a complete reference, # please see the online documentation at vagrantup.com. config.vm.define :nox do |box| # Every Vagrant virtual environment requires a box to build off of. - box.vm.box = "precise64" + box.vm.box = 'precise64' # The url from where the 'config.vm.box' box will be fetched if it # doesn't already exist on the user's system. - box.vm.box_url = "http://files.vagrantup.com/precise64.box" + box.vm.box_url = 'http://files.vagrantup.com/precise64.box' # Boot with a GUI so you can see the screen. (Default is headless) - #box.vm.boot_mode = :gui + # box.vm.boot_mode = :gui # add a hostonly network if desired - #box.vm.network :hostonly, "33.33.33.151" + # box.vm.network :hostonly, "33.33.33.151" box.vm.network :forwarded_port, guest: 3000, host: 4000 box.vm.provision :puppet do |puppet| - puppet.manifests_path = "puppetmanifests" - puppet.manifest_file = "raspberry-nox.pp" - puppet.module_path = "modules" - puppet.options = ["--verbose", "--debug"] + puppet.manifests_path = 'puppetmanifests' + puppet.manifest_file = 'raspberry-nox.pp' + puppet.module_path = 'modules' + puppet.options = ['--verbose', '--debug'] end end end diff --git a/app/apis/api/v1/authorize.rb b/app/apis/api/v1/authorize.rb index a071978..25b2e48 100644 --- a/app/apis/api/v1/authorize.rb +++ b/app/apis/api/v1/authorize.rb @@ -71,12 +71,12 @@ def find_user_by_identifier(identifier) end else error!(meta: { - status: 400, - errors: [ - message: ('errors.messages.invalid_token'), - code: ErrorCodes::INVALID_TOKEN - ] - }, response: {}) + status: 400, + errors: [ + message: ('errors.messages.invalid_token'), + code: ErrorCodes::INVALID_TOKEN + ] + }, response: {}) end end diff --git a/app/apis/api/v1/infrared_group.rb b/app/apis/api/v1/infrared_group.rb index 602a1c1..d9d66a1 100644 --- a/app/apis/api/v1/infrared_group.rb +++ b/app/apis/api/v1/infrared_group.rb @@ -37,12 +37,12 @@ class InfraredGroup < Grape::API end else error!(meta: { - status: 400, - errors: [ - message: ('errors.messages.invalid_token'), - code: ErrorCodes::INVALID_TOKEN - ] - }, response: {}) + status: 400, + errors: [ + message: ('errors.messages.invalid_token'), + code: ErrorCodes::INVALID_TOKEN + ] + }, response: {}) end end @@ -71,12 +71,12 @@ class InfraredGroup < Grape::API end else error!(meta: { - status: 400, - errors: [ - message: ('errors.messages.invalid_token'), - code: ErrorCodes::INVALID_TOKEN - ] - }, response: {}) + status: 400, + errors: [ + message: ('errors.messages.invalid_token'), + code: ErrorCodes::INVALID_TOKEN + ] + }, response: {}) end end @@ -107,22 +107,22 @@ class InfraredGroup < Grape::API @group = group else error!(meta: { - status: 400, - errors: [ - message: ('errors.messages.group_not_found'), - code: ErrorCodes::NOT_FOUND - ] - }, response: {}) + status: 400, + errors: [ + message: ('errors.messages.group_not_found'), + code: ErrorCodes::NOT_FOUND + ] + }, response: {}) end end else error!(meta: { - status: 400, - errors: [ - message: ('errors.messages.invalid_token'), - code: ErrorCodes::INVALID_TOKEN - ] - }, response: {}) + status: 400, + errors: [ + message: ('errors.messages.invalid_token'), + code: ErrorCodes::INVALID_TOKEN + ] + }, response: {}) end end @@ -152,22 +152,22 @@ class InfraredGroup < Grape::API group.destroy else error!(meta: { - status: 400, - errors: [ - message: ('errors.messages.group_not_found'), - code: ErrorCodes::NOT_FOUND - ] - }, response: {}) + status: 400, + errors: [ + message: ('errors.messages.group_not_found'), + code: ErrorCodes::NOT_FOUND + ] + }, response: {}) end end else error!(meta: { - status: 400, - errors: [ - message: ('errors.messages.invalid_token'), - code: ErrorCodes::INVALID_TOKEN - ] - }, response: {}) + status: 400, + errors: [ + message: ('errors.messages.invalid_token'), + code: ErrorCodes::INVALID_TOKEN + ] + }, response: {}) end end @@ -204,40 +204,40 @@ class InfraredGroup < Grape::API @infrared = infrared else error!(meta: { - status: 400, - errors: [ - message: ('errors.messages.ir_already_existing'), - code: ErrorCodes::ALREADY_EXISTING - ] - }, response: {}) + status: 400, + errors: [ + message: ('errors.messages.ir_already_existing'), + code: ErrorCodes::ALREADY_EXISTING + ] + }, response: {}) end else error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.ir_not_found'), + code: ErrorCodes::NOT_FOUND + ] + }, response: {}) + end + else + error!(meta: { status: 400, errors: [ - message: ('errors.messages.ir_not_found'), + message: ('errors.messages.group_not_found'), code: ErrorCodes::NOT_FOUND ] }, response: {}) - end - else - error!(meta: { - status: 400, - errors: [ - message: ('errors.messages.group_not_found'), - code: ErrorCodes::NOT_FOUND - ] - }, response: {}) end end else error!(meta: { - status: 400, - errors: [ - message: ('errors.messages.invalid_token'), - code: ErrorCodes::INVALID_TOKEN - ] - }, response: {}) + status: 400, + errors: [ + message: ('errors.messages.invalid_token'), + code: ErrorCodes::INVALID_TOKEN + ] + }, response: {}) end end @@ -273,40 +273,40 @@ class InfraredGroup < Grape::API log.infrared = infrared else error!(meta: { - status: 400, - errors: [ - message: ('errors.messages.ir_not_found_in_group'), - code: ErrorCodes::NOT_FOUND - ] - }, response: {}) + status: 400, + errors: [ + message: ('errors.messages.ir_not_found_in_group'), + code: ErrorCodes::NOT_FOUND + ] + }, response: {}) end else error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.ir_not_found'), + code: ErrorCodes::NOT_FOUND + ] + }, response: {}) + end + else + error!(meta: { status: 400, errors: [ - message: ('errors.messages.ir_not_found'), + message: ('errors.messages.group_not_found'), code: ErrorCodes::NOT_FOUND ] }, response: {}) - end - else - error!(meta: { - status: 400, - errors: [ - message: ('errors.messages.group_not_found'), - code: ErrorCodes::NOT_FOUND - ] - }, response: {}) end end else error!(meta: { - status: 400, - errors: [ - message: ('errors.messages.invalid_token'), - code: ErrorCodes::INVALID_TOKEN - ] - }, response: {}) + status: 400, + errors: [ + message: ('errors.messages.invalid_token'), + code: ErrorCodes::INVALID_TOKEN + ] + }, response: {}) end end @@ -332,31 +332,28 @@ class InfraredGroup < Grape::API }, response: {}) else if group = user.infrared_groups.find_by(id: params[:group_id]) - @group = group - @infrareds = group.infrareds + @group = group + @infrareds = group.infrareds else error!(meta: { - status: 400, - errors: [ - message: ('errors.messages.group_not_found'), - code: ErrorCodes::NOT_FOUND - ] - }, response: {}) + status: 400, + errors: [ + message: ('errors.messages.group_not_found'), + code: ErrorCodes::NOT_FOUND + ] + }, response: {}) end end else error!(meta: { - status: 400, - errors: [ - message: ('errors.messages.invalid_token'), - code: ErrorCodes::INVALID_TOKEN - ] - }, response: {}) + status: 400, + errors: [ + message: ('errors.messages.invalid_token'), + code: ErrorCodes::INVALID_TOKEN + ] + }, response: {}) end end - - - end end end diff --git a/app/apis/api/v1/ir.rb b/app/apis/api/v1/ir.rb index 8804072..6968fa9 100644 --- a/app/apis/api/v1/ir.rb +++ b/app/apis/api/v1/ir.rb @@ -28,12 +28,12 @@ class IR < Grape::API end else error!(meta: { - status: 400, - errors: [ - message: ('errors.messages.invalid_token'), - code: ErrorCodes::INVALID_TOKEN - ] - }, response: {}) + status: 400, + errors: [ + message: ('errors.messages.invalid_token'), + code: ErrorCodes::INVALID_TOKEN + ] + }, response: {}) end end @@ -59,49 +59,49 @@ class IR < Grape::API ] }, response: {}) else - infrared = user.infrareds.create(name: "名無しの赤外線", data: "") + infrared = user.infrareds.create(name: '名無しの赤外線', data: '') path = Rails.root.to_s - command = File.join(path, "commands/recieve") + command = File.join(path, 'commands/recieve') fname = "user_#{user.id}_ir_#{infrared.id}.txt" `#{command} #{path}/data/#{fname}` if File.read("#{path}/data/#{fname}").size == 0 infrared.destroy error!(meta: { - status: 400, - errors: [ - message: ('errors.messages.fail_scanir'), - code: ErrorCodes::FAIL_SCANIR - ] - }, response: {}) + status: 400, + errors: [ + message: ('errors.messages.fail_scanir'), + code: ErrorCodes::FAIL_SCANIR + ] + }, response: {}) end infrared.update(data: "#{fname}") - log = user.logs.create(name: "赤外線を受信しました", status: :recieve_ir) + log = user.logs.create(name: '赤外線を受信しました', status: :recieve_ir) log.infrared = infrared - if !params[:group_id].nil? + unless params[:group_id].nil? if group = user.infrared_groups.find_by(id: params[:group_id]) group.infrareds << infrared log = user.logs.create(name: "「#{infrared.name}」を「#{group.name}」に追加しました", status: :add_ir) log.infrared = infrared else error!(meta: { - status: 400, - errors: [ - message: ('errors.messages.ir_accept_but_group_not_found'), - code: ErrorCodes::NOT_FOUND - ] - }, response: {}) + status: 400, + errors: [ + message: ('errors.messages.ir_accept_but_group_not_found'), + code: ErrorCodes::NOT_FOUND + ] + }, response: {}) end end @infrared = infrared end else error!(meta: { - status: 400, - errors: [ - message: ('errors.messages.invalid_token'), - code: ErrorCodes::INVALID_TOKEN - ] - }, response: {}) + status: 400, + errors: [ + message: ('errors.messages.invalid_token'), + code: ErrorCodes::INVALID_TOKEN + ] + }, response: {}) end end desc '赤外線の送信', notes: <<-NOTE @@ -128,7 +128,7 @@ class IR < Grape::API if infrared = user.infrareds.find_by(id: params[:ir_id]) fname = infrared.data path = Rails.root.to_s - command = File.join(path, "commands/send") + command = File.join(path, 'commands/send') `#{command} #{path}/data/#{fname}` count = infrared.count + 1 infrared.update(count: count) @@ -136,23 +136,23 @@ class IR < Grape::API log.infrared = infrared @infrared = infrared else - error!(meta: { - status: 400, - errors: [ - message: ('errors.messages.ir_not_found'), - code: ErrorCodes::NOT_FOUND - ] - }, response: {}) + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.ir_not_found'), + code: ErrorCodes::NOT_FOUND + ] + }, response: {}) end end else error!(meta: { - status: 400, - errors: [ - message: ('errors.messages.invalid_token'), - code: ErrorCodes::INVALID_TOKEN - ] - }, response: {}) + status: 400, + errors: [ + message: ('errors.messages.invalid_token'), + code: ErrorCodes::INVALID_TOKEN + ] + }, response: {}) end end desc '赤外線の名前変更', notes: <<-NOTE @@ -183,23 +183,23 @@ class IR < Grape::API log.infrared = infrared @infrared = infrared else - error!(meta: { - status: 400, - errors: [ - message: ('errors.messages.ir_not_found'), - code: ErrorCodes::NOT_FOUND - ] - }, response: {}) + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.ir_not_found'), + code: ErrorCodes::NOT_FOUND + ] + }, response: {}) end end else error!(meta: { - status: 400, - errors: [ - message: ('errors.messages.invalid_token'), - code: ErrorCodes::INVALID_TOKEN - ] - }, response: {}) + status: 400, + errors: [ + message: ('errors.messages.invalid_token'), + code: ErrorCodes::INVALID_TOKEN + ] + }, response: {}) end end desc '赤外線の削除', notes: <<-NOTE @@ -225,29 +225,29 @@ class IR < Grape::API else if infrared = user.infrareds.find_by(id: params[:ir_id]) name = infrared.data - file = Rails.root.to_s + "/data/" + name + file = Rails.root.to_s + '/data/' + name File.delete file log = user.logs.create(name: "「#{infrared.name}」を削除しました", status: :destroy_ir) log.infrared = infrared infrared.destroy else - error!(meta: { - status: 400, - errors: [ - message: ('errors.messages.ir_not_found'), - code: ErrorCodes::NOT_FOUND - ] - }, response: {}) + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.ir_not_found'), + code: ErrorCodes::NOT_FOUND + ] + }, response: {}) end end else error!(meta: { - status: 400, - errors: [ - message: ('errors.messages.invalid_token'), - code: ErrorCodes::INVALID_TOKEN - ] - }, response: {}) + status: 400, + errors: [ + message: ('errors.messages.invalid_token'), + code: ErrorCodes::INVALID_TOKEN + ] + }, response: {}) end end desc '赤外線のlog', notes: <<-NOTE @@ -273,19 +273,19 @@ class IR < Grape::API }, response: {}) else if params[:size].nil? - @logs = user.logs.sort{|a,b|b<=>a} + @logs = user.logs.sort { |a, b| b <=> a } else - @logs = user.logs.last(params[:size].to_i).sort{|a,b|b<=>a} + @logs = user.logs.last(params[:size].to_i).sort { |a, b| b <=> a } end end else error!(meta: { - status: 400, - errors: [ - message: ('errors.messages.invalid_token'), - code: ErrorCodes::INVALID_TOKEN - ] - }, response: {}) + status: 400, + errors: [ + message: ('errors.messages.invalid_token'), + code: ErrorCodes::INVALID_TOKEN + ] + }, response: {}) end end end diff --git a/app/views/apis/api/v1/group/index.jbuilder b/app/views/apis/api/v1/group/index.jbuilder index 1bf7fe2..8d1d821 100644 --- a/app/views/apis/api/v1/group/index.jbuilder +++ b/app/views/apis/api/v1/group/index.jbuilder @@ -5,4 +5,3 @@ end json.response do json.groups @groups end - diff --git a/app/views/apis/api/v1/group/ping.jbuilder b/app/views/apis/api/v1/group/ping.jbuilder index a677448..d55ae81 100644 --- a/app/views/apis/api/v1/group/ping.jbuilder +++ b/app/views/apis/api/v1/group/ping.jbuilder @@ -1 +1 @@ -json.response "pong" \ No newline at end of file +json.response 'pong' diff --git a/app/views/apis/api/v1/ir/index.jbuilder b/app/views/apis/api/v1/ir/index.jbuilder index f689dd8..50bc640 100644 --- a/app/views/apis/api/v1/ir/index.jbuilder +++ b/app/views/apis/api/v1/ir/index.jbuilder @@ -5,4 +5,3 @@ end json.response do json.infrareds @infrareds, :name, :id, :count, :updated_at end - diff --git a/app/views/apis/api/v1/ir/logs.jbuilder b/app/views/apis/api/v1/ir/logs.jbuilder index cf963bc..4b59cdd 100644 --- a/app/views/apis/api/v1/ir/logs.jbuilder +++ b/app/views/apis/api/v1/ir/logs.jbuilder @@ -5,4 +5,3 @@ end json.response do json.logs @logs end - diff --git a/db/schema.rb b/db/schema.rb index f15b46e..ed957c8 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,74 +11,72 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20151208172013) do - - create_table "auth_tokens", force: :cascade do |t| - t.string "token" - t.integer "user_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false +ActiveRecord::Schema.define(version: 20_151_208_172_013) do + create_table 'auth_tokens', force: :cascade do |t| + t.string 'token' + t.integer 'user_id' + t.datetime 'created_at', null: false + t.datetime 'updated_at', null: false end - add_index "auth_tokens", ["user_id"], name: "index_auth_tokens_on_user_id" + add_index 'auth_tokens', ['user_id'], name: 'index_auth_tokens_on_user_id' - create_table "infrared_groups", force: :cascade do |t| - t.string "name" - t.integer "user_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + create_table 'infrared_groups', force: :cascade do |t| + t.string 'name' + t.integer 'user_id' + t.datetime 'created_at', null: false + t.datetime 'updated_at', null: false end - add_index "infrared_groups", ["user_id"], name: "index_infrared_groups_on_user_id" + add_index 'infrared_groups', ['user_id'], name: 'index_infrared_groups_on_user_id' - create_table "infrared_relationals", force: :cascade do |t| - t.integer "infrared_id" - t.integer "infrared_group_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + create_table 'infrared_relationals', force: :cascade do |t| + t.integer 'infrared_id' + t.integer 'infrared_group_id' + t.datetime 'created_at', null: false + t.datetime 'updated_at', null: false end - add_index "infrared_relationals", ["infrared_group_id"], name: "index_infrared_relationals_on_infrared_group_id" - add_index "infrared_relationals", ["infrared_id"], name: "index_infrared_relationals_on_infrared_id" + add_index 'infrared_relationals', ['infrared_group_id'], name: 'index_infrared_relationals_on_infrared_group_id' + add_index 'infrared_relationals', ['infrared_id'], name: 'index_infrared_relationals_on_infrared_id' - create_table "infrareds", force: :cascade do |t| - t.string "name" - t.string "data" - t.integer "user_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.integer "count", default: 0 + create_table 'infrareds', force: :cascade do |t| + t.string 'name' + t.string 'data' + t.integer 'user_id' + t.datetime 'created_at', null: false + t.datetime 'updated_at', null: false + t.integer 'count', default: 0 end - add_index "infrareds", ["user_id"], name: "index_infrareds_on_user_id" + add_index 'infrareds', ['user_id'], name: 'index_infrareds_on_user_id' - create_table "logs", force: :cascade do |t| - t.integer "user_id" - t.integer "infrared_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.string "name" - t.integer "status" + create_table 'logs', force: :cascade do |t| + t.integer 'user_id' + t.integer 'infrared_id' + t.datetime 'created_at', null: false + t.datetime 'updated_at', null: false + t.string 'name' + t.integer 'status' end - add_index "logs", ["infrared_id"], name: "index_logs_on_infrared_id" - add_index "logs", ["user_id"], name: "index_logs_on_user_id" + add_index 'logs', ['infrared_id'], name: 'index_logs_on_infrared_id' + add_index 'logs', ['user_id'], name: 'index_logs_on_user_id' - create_table "user_infos", force: :cascade do |t| - t.string "screen_name" - t.string "hashed_password" - t.string "email" - t.string "email_for_index" - t.integer "user_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + create_table 'user_infos', force: :cascade do |t| + t.string 'screen_name' + t.string 'hashed_password' + t.string 'email' + t.string 'email_for_index' + t.integer 'user_id' + t.datetime 'created_at', null: false + t.datetime 'updated_at', null: false end - add_index "user_infos", ["user_id"], name: "index_user_infos_on_user_id" + add_index 'user_infos', ['user_id'], name: 'index_user_infos_on_user_id' - create_table "users", force: :cascade do |t| - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + create_table 'users', force: :cascade do |t| + t.datetime 'created_at', null: false + t.datetime 'updated_at', null: false end - end From d65ef5759111cab667e7a04408e4fbc2a3523643 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Wed, 9 Dec 2015 15:20:48 +0900 Subject: [PATCH 206/358] remove test file --- app/apis/api/v1/infrared_group.rb | 9 --------- app/views/apis/api/v1/group/ping.jbuilder | 1 - 2 files changed, 10 deletions(-) delete mode 100644 app/views/apis/api/v1/group/ping.jbuilder diff --git a/app/apis/api/v1/infrared_group.rb b/app/apis/api/v1/infrared_group.rb index d9d66a1..d17dceb 100644 --- a/app/apis/api/v1/infrared_group.rb +++ b/app/apis/api/v1/infrared_group.rb @@ -4,15 +4,6 @@ module API module V1 class InfraredGroup < Grape::API resource :group do - desc 'グループ内の赤外線一覧の表示', notes: <<-NOTE -

グループ内の赤外線を表示

-

- グループ内の赤外線を表示します -

- NOTE - get '/ping', jbuilder: 'api/v1/group/ping' do - end - desc 'グループの一覧表示', notes: <<-NOTE

グループを一覧表示する

diff --git a/app/views/apis/api/v1/group/ping.jbuilder b/app/views/apis/api/v1/group/ping.jbuilder deleted file mode 100644 index d55ae81..0000000 --- a/app/views/apis/api/v1/group/ping.jbuilder +++ /dev/null @@ -1 +0,0 @@ -json.response 'pong' From 5237c8fd27dae79a306f6bd10b0f606fe09d26e3 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Wed, 9 Dec 2015 15:26:33 +0900 Subject: [PATCH 207/358] update README --- README.md | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 53252eb..21795b9 100644 --- a/README.md +++ b/README.md @@ -8,23 +8,36 @@ circleCIでテストを動かして通らない場合はプルリクを受け付 ### 受信コマンドコンパイル -``` -sudo gcc recieve.c -o recieve -lwiringPi +```sh +$ sudo gcc recieve.c -o recieve -lwiringPi ``` ### 送信コマンドコンパイル -``` -sudo gcc send.c -lm -o send -lwiringPi +```sh +$ sudo gcc send.c -lm -o send -lwiringPi ``` ### 本番サーバーからdumpファイルを作成 -``` + +```sh scp pi@hostname:~/rails_app/switch_api/db/development.sqlite3 ./dump.sqlite3 ``` ### 赤外線情報ファイルの取得 -``` +```sh scp -r pi@hostname:~/rails_app/switch_api/data ./ -``` \ No newline at end of file +``` + +### Vagrantで実行 + +```sh +$ vagrant up + +$ vagrant ssh + +$ cd /vagrant/ + +$ rails s -b 0.0.0.0 +``` From d9008c66fc33a89cc046716cb0759ea8d42ae36a Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Wed, 9 Dec 2015 15:27:32 +0900 Subject: [PATCH 208/358] =?UTF-8?q?=F0=9F=9A=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 21795b9..79d1c63 100644 --- a/README.md +++ b/README.md @@ -21,13 +21,13 @@ $ sudo gcc send.c -lm -o send -lwiringPi ### 本番サーバーからdumpファイルを作成 ```sh -scp pi@hostname:~/rails_app/switch_api/db/development.sqlite3 ./dump.sqlite3 +$ scp pi@hostname:~/rails_app/switch_api/db/development.sqlite3 ./dump.sqlite3 ``` ### 赤外線情報ファイルの取得 ```sh -scp -r pi@hostname:~/rails_app/switch_api/data ./ +$ scp -r pi@hostname:~/rails_app/switch_api/data ./ ``` ### Vagrantで実行 From ed51510b03bbc981d9592060db5a5930e462bc61 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Thu, 10 Dec 2015 02:22:12 +0900 Subject: [PATCH 209/358] gem install whenever --- Gemfile | 1 + Gemfile.lock | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/Gemfile b/Gemfile index bb86f0e..9fd97de 100644 --- a/Gemfile +++ b/Gemfile @@ -38,6 +38,7 @@ gem 'grape-swagger' gem 'grape-swagger-ui' gem 'haml-rails' gem 'rubocop', group: :development +gem 'whenever', :require => false group :development, :test do gem 'byebug' diff --git a/Gemfile.lock b/Gemfile.lock index 56fdfd2..4125fea 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -54,6 +54,7 @@ GEM builder (3.2.2) byebug (8.2.1) choice (0.2.0) + chronic (0.10.2) coderay (1.1.0) coercible (1.0.0) descendants_tracker (~> 0.0.1) @@ -283,6 +284,8 @@ GEM binding_of_caller (>= 0.7.2) railties (>= 4.0) sprockets-rails (>= 2.0, < 4.0) + whenever (0.9.4) + chronic (>= 0.6.3) yard (0.8.7.6) PLATFORMS @@ -324,6 +327,7 @@ DEPENDENCIES turbolinks uglifier (>= 1.3.0) web-console (~> 2.0) + whenever BUNDLED WITH 1.10.6 From 0e5d0386cc0f1c6a2fda4f5ef6b3435d99f6e1b5 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Thu, 10 Dec 2015 02:23:16 +0900 Subject: [PATCH 210/358] wheneverize . --- config/schedule.rb | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 config/schedule.rb diff --git a/config/schedule.rb b/config/schedule.rb new file mode 100644 index 0000000..de75cf9 --- /dev/null +++ b/config/schedule.rb @@ -0,0 +1,20 @@ +# Use this file to easily define all of your cron jobs. +# +# It's helpful, but not entirely necessary to understand cron before proceeding. +# http://en.wikipedia.org/wiki/Cron + +# Example: +# +# set :output, "/path/to/my/cron_log.log" +# +# every 2.hours do +# command "/usr/bin/some_great_command" +# runner "MyModel.some_method" +# rake "some:great:rake:task" +# end +# +# every 4.days do +# runner "AnotherModel.prune_old_records" +# end + +# Learn more: http://github.com/javan/whenever From a1f19fdd1149151bb7ab915525c4b6aa7c0f9b52 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Thu, 10 Dec 2015 03:14:18 +0900 Subject: [PATCH 211/358] setting whenever --- config/schedule.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/config/schedule.rb b/config/schedule.rb index de75cf9..b31df01 100644 --- a/config/schedule.rb +++ b/config/schedule.rb @@ -5,7 +5,11 @@ # Example: # -# set :output, "/path/to/my/cron_log.log" +set :output, "log/cron_log.log" + +every 1.minute do + command "echo 'poyopoyo'" +end # # every 2.hours do # command "/usr/bin/some_great_command" From 4d681d75af76f83faab6a859e67b99c74f7acfa8 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Fri, 11 Dec 2015 14:10:34 +0900 Subject: [PATCH 212/358] bundle install --- Gemfile | 1 - Gemfile.lock | 4 ---- 2 files changed, 5 deletions(-) diff --git a/Gemfile b/Gemfile index 9fd97de..bb86f0e 100644 --- a/Gemfile +++ b/Gemfile @@ -38,7 +38,6 @@ gem 'grape-swagger' gem 'grape-swagger-ui' gem 'haml-rails' gem 'rubocop', group: :development -gem 'whenever', :require => false group :development, :test do gem 'byebug' diff --git a/Gemfile.lock b/Gemfile.lock index 4125fea..56fdfd2 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -54,7 +54,6 @@ GEM builder (3.2.2) byebug (8.2.1) choice (0.2.0) - chronic (0.10.2) coderay (1.1.0) coercible (1.0.0) descendants_tracker (~> 0.0.1) @@ -284,8 +283,6 @@ GEM binding_of_caller (>= 0.7.2) railties (>= 4.0) sprockets-rails (>= 2.0, < 4.0) - whenever (0.9.4) - chronic (>= 0.6.3) yard (0.8.7.6) PLATFORMS @@ -327,7 +324,6 @@ DEPENDENCIES turbolinks uglifier (>= 1.3.0) web-console (~> 2.0) - whenever BUNDLED WITH 1.10.6 From eda20579c574bffc6faabc1f88586346a4f54bb0 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Fri, 11 Dec 2015 14:10:44 +0900 Subject: [PATCH 213/358] remove schedule --- config/schedule.rb | 24 ------------------------ 1 file changed, 24 deletions(-) delete mode 100644 config/schedule.rb diff --git a/config/schedule.rb b/config/schedule.rb deleted file mode 100644 index b31df01..0000000 --- a/config/schedule.rb +++ /dev/null @@ -1,24 +0,0 @@ -# Use this file to easily define all of your cron jobs. -# -# It's helpful, but not entirely necessary to understand cron before proceeding. -# http://en.wikipedia.org/wiki/Cron - -# Example: -# -set :output, "log/cron_log.log" - -every 1.minute do - command "echo 'poyopoyo'" -end -# -# every 2.hours do -# command "/usr/bin/some_great_command" -# runner "MyModel.some_method" -# rake "some:great:rake:task" -# end -# -# every 4.days do -# runner "AnotherModel.prune_old_records" -# end - -# Learn more: http://github.com/javan/whenever From 5083afd4658fc3105afa690fe8c53a04654f5de7 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Fri, 11 Dec 2015 16:15:51 +0900 Subject: [PATCH 214/358] bundle install clockwork --- Gemfile | 1 + Gemfile.lock | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/Gemfile b/Gemfile index bb86f0e..ff5208c 100644 --- a/Gemfile +++ b/Gemfile @@ -37,6 +37,7 @@ gem 'grape-jbuilder' gem 'grape-swagger' gem 'grape-swagger-ui' gem 'haml-rails' +gem 'clockwork' gem 'rubocop', group: :development group :development, :test do diff --git a/Gemfile.lock b/Gemfile.lock index 56fdfd2..f6fc930 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -54,6 +54,9 @@ GEM builder (3.2.2) byebug (8.2.1) choice (0.2.0) + clockwork (1.2.0) + activesupport + tzinfo coderay (1.1.0) coercible (1.0.0) descendants_tracker (~> 0.0.1) @@ -293,6 +296,7 @@ DEPENDENCIES awesome_print bcrypt (~> 3.1.7) byebug + clockwork coffee-rails (~> 4.1.0) database_cleaner factory_girl_rails From e5bc45d5cf5189fa771bad447a4646d7ea8c8c87 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Fri, 11 Dec 2015 17:50:01 +0900 Subject: [PATCH 215/358] add clock.rb --- config/clock.rb | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 config/clock.rb diff --git a/config/clock.rb b/config/clock.rb new file mode 100644 index 0000000..5757066 --- /dev/null +++ b/config/clock.rb @@ -0,0 +1,33 @@ +require_relative '../config/boot' +require_relative '../config/environment' + +require 'clockwork' +include Clockwork + +case Rails.env +when 'development' + every(1.second, 'seconds.job') do + puts "Running development job" + end +when 'staging' + every(1.minute, 'minutes.job') do + puts "Running staging job" + end +when 'production' + every(1.hour, 'hours.job') do + puts "Running staging job" + end +else # Unknown + every(1.day, 'days.job') do + puts "Running production job" + end +end + +# Shared jobs +every(1.week, 'weeks.job') do + puts "Running common job" +end + +every(1.second, 'seconds.job', :thread => true) do + puts AuthToken.all.count +end \ No newline at end of file From e860ac5a200aa12f63c5a6b06fb18913ee3baaac Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Fri, 11 Dec 2015 17:53:15 +0900 Subject: [PATCH 216/358] :construction: --- config/clock.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/config/clock.rb b/config/clock.rb index 5757066..9915fcf 100644 --- a/config/clock.rb +++ b/config/clock.rb @@ -29,5 +29,8 @@ end every(1.second, 'seconds.job', :thread => true) do - puts AuthToken.all.count + path = Rails.root.to_s + command = File.join(path, 'commands/recieve') + fname = "user_#{user.id}_ir_#{infrared.id}.txt" + `#{command} #{path}/data/#{fname}` end \ No newline at end of file From ecfcc98ba6157814b7f3c13ea2c9d04a20ce5a08 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Fri, 11 Dec 2015 18:20:19 +0900 Subject: [PATCH 217/358] update README --- README.md | 6 ++++++ config/clock.rb | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 79d1c63..7632c06 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,12 @@ $ scp pi@hostname:~/rails_app/switch_api/db/development.sqlite3 ./dump.sqlite3 $ scp -r pi@hostname:~/rails_app/switch_api/data ./ ``` +### タスクスケジューラーを起動 + +```sh +$ sudo bundle exec clockwork /config/clock.rb +``` + ### Vagrantで実行 ```sh diff --git a/config/clock.rb b/config/clock.rb index 9915fcf..e44b1ce 100644 --- a/config/clock.rb +++ b/config/clock.rb @@ -30,7 +30,7 @@ every(1.second, 'seconds.job', :thread => true) do path = Rails.root.to_s - command = File.join(path, 'commands/recieve') + command = File.join(path, 'commands/send') fname = "user_#{user.id}_ir_#{infrared.id}.txt" `#{command} #{path}/data/#{fname}` end \ No newline at end of file From 93fa0f09a35acb5cc7af0fa873d2ca08f37bacf2 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Fri, 11 Dec 2015 18:57:28 +0900 Subject: [PATCH 218/358] update --- README.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/README.md b/README.md index 7632c06..1a91b08 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,27 @@ $ scp -r pi@hostname:~/rails_app/switch_api/data ./ $ sudo bundle exec clockwork /config/clock.rb ``` +### cronの設定 + +``` +43 23 * * * 23:43に実行 +12 05 * * *    05:12に実行 +0 17 * * * 17:00に実行 +0 17 * * 1 毎週月曜の 17:00に実行 +0,10 17 * * 0,2,3 毎週日,火,水曜の 17:00と 17:10に実行 +0-10 17 1 * * 毎月 1日の 17:00から17:10まで 1分毎に実行 +0 0 1,15 * 1 毎月 1日と 15日と 月曜日の 0:00に実行 +42 4 1 * *     毎月 1日の 4:42分に実行 +0 21 * * 1-6   月曜日から土曜まで 21:00に実行 +0,10,20,30,40,50 * * * * 10分おきに実行 +*/10 * * * *        10分おきに実行 +* 1 * * *         1:00から 1:59まで 1分おきに実行 +0 1 * * *         1:00に実行 +0 */1 * * *        毎時 0分に 1時間おきに実行 +0 * * * *         毎時 0分に 1時間おきに実行 +2 8-20/3 * * *      8:02,11:02,14:02,17:02,20:02に実行 +30 5 1,15 * *       1日と 15日の 5:30に実行 +``` ### Vagrantで実行 ```sh From ab8993ab50a5eef8e321e048dcdf0aa43fcfd9ae Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Fri, 11 Dec 2015 21:05:47 +0900 Subject: [PATCH 219/358] update read --- README.md | 57 ++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 50 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 1a91b08..9469674 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,10 @@ 基本git flowの思想の元ブランチは切っていて、 circleCIでテストを動かして通らない場合はプルリクを受け付けない方針をとっています。 +## 下準備 + +クローンしたプロジェクト内のプログラムをコンパイルする + ### 受信コマンドコンパイル ```sh @@ -18,24 +22,44 @@ $ sudo gcc recieve.c -o recieve -lwiringPi $ sudo gcc send.c -lm -o send -lwiringPi ``` -### 本番サーバーからdumpファイルを作成 +## サーバーを立てる + +一部権限を求められるshコマンドが含まれているので、`sudo`をつけると間違いないかも + +### Rails立ち上げ ```sh -$ scp pi@hostname:~/rails_app/switch_api/db/development.sqlite3 ./dump.sqlite3 +$ sudo rails s ``` +### Redis立ち上げ -### 赤外線情報ファイルの取得 +```sh +$ redis-server +``` + +### Resque立ち上げ ```sh -$ scp -r pi@hostname:~/rails_app/switch_api/data ./ +$ $ QUEUE=* rake environment resque:work ``` -### タスクスケジューラーを起動 +### scheduler立ち上げ ```sh -$ sudo bundle exec clockwork /config/clock.rb +$ DYNAMIC_SCHEDULE=true rake environment resque:scheduler ``` +### ログを監視 + +```sh +$ tail -f log/outputFileName +``` + + +## スケジューラーに関して + +cron形式でデータを渡す時の値の諸々 + ### cronの設定 ``` @@ -57,7 +81,26 @@ $ sudo bundle exec clockwork /config/clock.rb 2 8-20/3 * * *      8:02,11:02,14:02,17:02,20:02に実行 30 5 1,15 * *       1日と 15日の 5:30に実行 ``` -### Vagrantで実行 + + + +## その他 + +データの同期に関して + +### 本番サーバーからdumpファイルを作成 + +```sh +$ scp pi@hostname:~/rails_app/switch_api/db/development.sqlite3 ./dump.sqlite3 +``` + +### 赤外線情報ファイルの取得 + +```sh +$ scp -r pi@hostname:~/rails_app/switch_api/data ./ +``` + +## Vagrantで実行する場合 ```sh $ vagrant up From 5b5b7cbacf251e40e701323c883589b1aae47723 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Fri, 11 Dec 2015 21:05:52 +0900 Subject: [PATCH 220/358] remove clock --- config/clock.rb | 36 ------------------------------------ 1 file changed, 36 deletions(-) delete mode 100644 config/clock.rb diff --git a/config/clock.rb b/config/clock.rb deleted file mode 100644 index e44b1ce..0000000 --- a/config/clock.rb +++ /dev/null @@ -1,36 +0,0 @@ -require_relative '../config/boot' -require_relative '../config/environment' - -require 'clockwork' -include Clockwork - -case Rails.env -when 'development' - every(1.second, 'seconds.job') do - puts "Running development job" - end -when 'staging' - every(1.minute, 'minutes.job') do - puts "Running staging job" - end -when 'production' - every(1.hour, 'hours.job') do - puts "Running staging job" - end -else # Unknown - every(1.day, 'days.job') do - puts "Running production job" - end -end - -# Shared jobs -every(1.week, 'weeks.job') do - puts "Running common job" -end - -every(1.second, 'seconds.job', :thread => true) do - path = Rails.root.to_s - command = File.join(path, 'commands/send') - fname = "user_#{user.id}_ir_#{infrared.id}.txt" - `#{command} #{path}/data/#{fname}` -end \ No newline at end of file From 91b56d2573a7ccf5d1e23cf8f3f4dc85411e75ee Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Fri, 11 Dec 2015 21:06:13 +0900 Subject: [PATCH 221/358] bundle install --- Gemfile | 4 +++- Gemfile.lock | 31 +++++++++++++++++++++++++++---- 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/Gemfile b/Gemfile index ff5208c..e3f651b 100644 --- a/Gemfile +++ b/Gemfile @@ -37,7 +37,9 @@ gem 'grape-jbuilder' gem 'grape-swagger' gem 'grape-swagger-ui' gem 'haml-rails' -gem 'clockwork' +gem 'redis' +gem 'resque' +gem 'resque-scheduler' gem 'rubocop', group: :development group :development, :test do diff --git a/Gemfile.lock b/Gemfile.lock index f6fc930..4804ad9 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -54,9 +54,6 @@ GEM builder (3.2.2) byebug (8.2.1) choice (0.2.0) - clockwork (1.2.0) - activesupport - tzinfo coderay (1.1.0) coercible (1.0.0) descendants_tracker (~> 0.0.1) @@ -147,6 +144,7 @@ GEM mime-types (2.99) mini_portile2 (2.0.0) minitest (5.8.3) + mono_logger (1.1.0) multi_json (1.11.2) multi_xml (0.5.5) nokogiri (1.6.7) @@ -173,6 +171,8 @@ GEM rack (>= 0.4) rack-mount (0.8.3) rack (>= 1.0.0) + rack-protection (1.5.3) + rack rack-test (0.6.3) rack (>= 1.0) rails (4.2.1) @@ -207,7 +207,21 @@ GEM rainbow (2.0.0) rake (10.4.2) rdoc (4.2.0) + redis (3.2.2) + redis-namespace (1.5.2) + redis (~> 3.0, >= 3.0.4) ref (2.0.0) + resque (1.25.2) + mono_logger (~> 1.0) + multi_json (~> 1.0) + redis-namespace (~> 1.3) + sinatra (>= 0.9.2) + vegas (~> 0.1.2) + resque-scheduler (4.0.0) + mono_logger (~> 1.0) + redis (~> 3.0) + resque (~> 1.25) + rufus-scheduler (~> 3.0) rspec-core (3.0.4) rspec-support (~> 3.0.0) rspec-expectations (3.0.4) @@ -235,6 +249,7 @@ GEM ruby-progressbar (1.7.5) ruby_parser (3.7.2) sexp_processor (~> 4.1) + rufus-scheduler (3.1.10) sass (3.4.19) sass-rails (5.0.4) railties (>= 4.0.0, < 5.0) @@ -246,6 +261,10 @@ GEM json (~> 1.7, >= 1.7.7) rdoc (~> 4.0) sexp_processor (4.6.0) + sinatra (1.4.6) + rack (~> 1.4) + rack-protection (~> 1.4) + tilt (>= 1.3, < 3) slop (3.6.0) spring (1.5.0) sprockets (3.5.0) @@ -276,6 +295,8 @@ GEM execjs (>= 0.3.0) json (>= 1.8.0) unicode-display_width (0.1.1) + vegas (0.1.11) + rack (>= 1.0.0) virtus (1.0.5) axiom-types (~> 0.1) coercible (~> 1.0) @@ -296,7 +317,6 @@ DEPENDENCIES awesome_print bcrypt (~> 3.1.7) byebug - clockwork coffee-rails (~> 4.1.0) database_cleaner factory_girl_rails @@ -317,6 +337,9 @@ DEPENDENCIES quiet_assets rails (= 4.2.1) rails-erd + redis + resque + resque-scheduler rspec-rails (~> 3.0.0) rubocop sass-rails (~> 5.0) From 7c15f3a9a25334729ada595a3c36ea0342e36d0c Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Fri, 11 Dec 2015 21:06:25 +0900 Subject: [PATCH 222/358] create resque task --- lib/tasks/resque.rake | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 lib/tasks/resque.rake diff --git a/lib/tasks/resque.rake b/lib/tasks/resque.rake new file mode 100644 index 0000000..1d5803d --- /dev/null +++ b/lib/tasks/resque.rake @@ -0,0 +1,34 @@ +require 'resque/tasks' +require 'resque/scheduler/tasks' + +namespace :resque do + task :preload => :environment + task :setup do + require 'resque' + end + + task :setup_schedule => :setup do + require 'resque-scheduler' + + # If you want to be able to dynamically change the schedule, + # uncomment this line. A dynamic schedule can be updated via the + # Resque::Scheduler.set_schedule (and remove_schedule) methods. + # When dynamic is set to true, the scheduler process looks for + # schedule changes and applies them on the fly. + # Note: This feature is only available in >=2.0.0. + Resque::Scheduler.dynamic = true + + # The schedule doesn't need to be stored in a YAML, it just needs to + # be a hash. YAML is usually the easiest. + # Resque.schedule = YAML.load_file('resque_schedule.yml') + + # If your schedule already has +queue+ set for each job, you don't + # need to require your jobs. This can be an advantage since it's + # less code that resque-scheduler needs to know about. But in a small + # project, it's usually easier to just include you job classes here. + # So, something like this: + # require 'jobs' + end + + task :scheduler_setup => :setup_schedule +end \ No newline at end of file From c1aacc52658f7614bfba68e065015303c1ad950f Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Fri, 11 Dec 2015 21:06:32 +0900 Subject: [PATCH 223/358] create routes --- config/routes.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/config/routes.rb b/config/routes.rb index b7aafe0..5ebee4f 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,4 +1,7 @@ +require 'resque/server' + Rails.application.routes.draw do + mount Resque::Server.new, at: "/resque" mount API::Base => '/' # The priority is based upon order of creation: first created -> highest priority. From e5672cd9bf1489a202927815d7f113e4857a2367 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Fri, 11 Dec 2015 21:06:44 +0900 Subject: [PATCH 224/358] create sample job --- app/jobs/resque_sample_job.rb | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 app/jobs/resque_sample_job.rb diff --git a/app/jobs/resque_sample_job.rb b/app/jobs/resque_sample_job.rb new file mode 100644 index 0000000..1e7328c --- /dev/null +++ b/app/jobs/resque_sample_job.rb @@ -0,0 +1,9 @@ +class ResqueSampleJob + @queue = :resque_sample_job + def self.perform(text) + path = File.expand_path("log/resque_sample.log", Rails.root) + File.open(path, 'a') do |f| + f.puts text + end + end +end \ No newline at end of file From dfacac284828ab66769cd7b0edce2ca959202268 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Fri, 11 Dec 2015 21:07:00 +0900 Subject: [PATCH 225/358] create reds setting --- config/initializers/redis.rb | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 config/initializers/redis.rb diff --git a/config/initializers/redis.rb b/config/initializers/redis.rb new file mode 100644 index 0000000..98a444a --- /dev/null +++ b/config/initializers/redis.rb @@ -0,0 +1,7 @@ +require 'resque-scheduler' +require 'resque/scheduler/server' +if ENV["REDISCLOUD_URL"] + $redis = Resque.redis = Redis.new(:url => ENV["REDISCLOUD_URL"]) +else + $redis = Resque.redis = Redis.new(host: "localhost", port: "6379") +end From 0099fc3f0bfc86475fdc637fa7c06714504eb919 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Fri, 11 Dec 2015 22:30:24 +0900 Subject: [PATCH 226/358] update --- README.md | 8 ++++++++ app/jobs/resque_sample_job.rb | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 9469674..855791c 100644 --- a/README.md +++ b/README.md @@ -62,6 +62,14 @@ cron形式でデータを渡す時の値の諸々 ### cronの設定 +左から、[分] [時] [日] [月] [曜日] [コマンド] +分は0~59の数字で指定 +時は0~23の数字で指定 +日は1~31の数字で指定 +月は1~12の数字で指定 +曜日に関しても数字で指定し、0と7が日曜日、1以降は順に、月、火、水、木、金、土となる +コマンドは、設定ファイルでパスを通していないものに関してはフルパスで指定するかカレントディレクトリからの相対パスで指定しなければならない + ``` 43 23 * * * 23:43に実行 12 05 * * *    05:12に実行 diff --git a/app/jobs/resque_sample_job.rb b/app/jobs/resque_sample_job.rb index 1e7328c..3c857d5 100644 --- a/app/jobs/resque_sample_job.rb +++ b/app/jobs/resque_sample_job.rb @@ -3,7 +3,7 @@ class ResqueSampleJob def self.perform(text) path = File.expand_path("log/resque_sample.log", Rails.root) File.open(path, 'a') do |f| - f.puts text + f.puts text["screen_name"] end end end \ No newline at end of file From 86a9bfd0c8186633a38fe9146a8557271b6a2135 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Fri, 11 Dec 2015 22:31:59 +0900 Subject: [PATCH 227/358] update --- README.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 855791c..dafcd26 100644 --- a/README.md +++ b/README.md @@ -63,11 +63,13 @@ cron形式でデータを渡す時の値の諸々 ### cronの設定 左から、[分] [時] [日] [月] [曜日] [コマンド] -分は0~59の数字で指定 -時は0~23の数字で指定 -日は1~31の数字で指定 -月は1~12の数字で指定 -曜日に関しても数字で指定し、0と7が日曜日、1以降は順に、月、火、水、木、金、土となる + +- 分は0~59の数字で指定 +- 時は0~23の数字で指定 +- 日は1~31の数字で指定 +- 月は1~12の数字で指定 +- 曜日に関しても数字で指定し、0と7が日曜日、1以降は順に、月、火、水、木、金、土となる + コマンドは、設定ファイルでパスを通していないものに関してはフルパスで指定するかカレントディレクトリからの相対パスで指定しなければならない ``` From 68a3d8a2643ff6361f29e0afe43721c7ad58f0cd Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Fri, 11 Dec 2015 22:33:06 +0900 Subject: [PATCH 228/358] update readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index dafcd26..c1ba667 100644 --- a/README.md +++ b/README.md @@ -70,7 +70,7 @@ cron形式でデータを渡す時の値の諸々 - 月は1~12の数字で指定 - 曜日に関しても数字で指定し、0と7が日曜日、1以降は順に、月、火、水、木、金、土となる -コマンドは、設定ファイルでパスを通していないものに関してはフルパスで指定するかカレントディレクトリからの相対パスで指定しなければならない +コマンドは、設定ファイルでパスを通していないものに関してはフルパスで指定するかカレントディレクトリからの相対パスで指定しなければならない、指定はこちらでするのでクライアントから引数を渡す時は曜日までの引数で良い ``` 43 23 * * * 23:43に実行 From 7339f75a1f40a57bad59bebf113e3df5822362a6 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Fri, 11 Dec 2015 23:26:41 +0900 Subject: [PATCH 229/358] rename --- app/jobs/resque_sample_job.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/jobs/resque_sample_job.rb b/app/jobs/resque_sample_job.rb index 3c857d5..55203dd 100644 --- a/app/jobs/resque_sample_job.rb +++ b/app/jobs/resque_sample_job.rb @@ -1,7 +1,7 @@ -class ResqueSampleJob - @queue = :resque_sample_job +class ResqueScheduleTask + @queue = :resque_schdule_task def self.perform(text) - path = File.expand_path("log/resque_sample.log", Rails.root) + path = File.expand_path("log/resque_schedule_task.log", Rails.root) File.open(path, 'a') do |f| f.puts text["screen_name"] end From 20bbe484f0f996ad1b4579630b1c0b619e7ff23c Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Fri, 11 Dec 2015 23:30:10 +0900 Subject: [PATCH 230/358] update .gitignore --- .gitignore | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 012a20d..2f53496 100644 --- a/.gitignore +++ b/.gitignore @@ -16,4 +16,6 @@ !/log/.keep /tmp -/data/* \ No newline at end of file +/data/* + +dump.rdb \ No newline at end of file From 880c1595815d3cda097f1fda618607555df7d786 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Fri, 11 Dec 2015 23:34:45 +0900 Subject: [PATCH 231/358] rails g model Schedule name:string description:text cron:string job_name:string user:references --- app/models/schedule.rb | 3 +++ db/migrate/20151211143436_create_schedules.rb | 13 +++++++++++++ spec/factories/schedules.rb | 10 ++++++++++ spec/models/schedule_spec.rb | 5 +++++ 4 files changed, 31 insertions(+) create mode 100644 app/models/schedule.rb create mode 100644 db/migrate/20151211143436_create_schedules.rb create mode 100644 spec/factories/schedules.rb create mode 100644 spec/models/schedule_spec.rb diff --git a/app/models/schedule.rb b/app/models/schedule.rb new file mode 100644 index 0000000..75072cb --- /dev/null +++ b/app/models/schedule.rb @@ -0,0 +1,3 @@ +class Schedule < ActiveRecord::Base + belongs_to :user +end diff --git a/db/migrate/20151211143436_create_schedules.rb b/db/migrate/20151211143436_create_schedules.rb new file mode 100644 index 0000000..f2aa312 --- /dev/null +++ b/db/migrate/20151211143436_create_schedules.rb @@ -0,0 +1,13 @@ +class CreateSchedules < ActiveRecord::Migration + def change + create_table :schedules do |t| + t.string :name + t.text :description + t.string :cron + t.string :job_name + t.references :user, index: true, foreign_key: true + + t.timestamps null: false + end + end +end diff --git a/spec/factories/schedules.rb b/spec/factories/schedules.rb new file mode 100644 index 0000000..dbcf627 --- /dev/null +++ b/spec/factories/schedules.rb @@ -0,0 +1,10 @@ +FactoryGirl.define do + factory :schedule do + name "MyString" +description "MyText" +cron "MyString" +job_name "MyString" +user nil + end + +end diff --git a/spec/models/schedule_spec.rb b/spec/models/schedule_spec.rb new file mode 100644 index 0000000..e226ff8 --- /dev/null +++ b/spec/models/schedule_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe Schedule, :type => :model do + pending "add some examples to (or delete) #{__FILE__}" +end From 7979e68c3d18a84e6adfd675b19a8a50c7cfd959 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Fri, 11 Dec 2015 23:35:04 +0900 Subject: [PATCH 232/358] rake db:migrate --- db/schema.rb | 114 +++++++++++++++++++++++++++++---------------------- 1 file changed, 64 insertions(+), 50 deletions(-) diff --git a/db/schema.rb b/db/schema.rb index ed957c8..2c18eef 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,72 +11,86 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20_151_208_172_013) do - create_table 'auth_tokens', force: :cascade do |t| - t.string 'token' - t.integer 'user_id' - t.datetime 'created_at', null: false - t.datetime 'updated_at', null: false +ActiveRecord::Schema.define(version: 20151211143436) do + + create_table "auth_tokens", force: :cascade do |t| + t.string "token" + t.integer "user_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + add_index "auth_tokens", ["user_id"], name: "index_auth_tokens_on_user_id" + + create_table "infrared_groups", force: :cascade do |t| + t.string "name" + t.integer "user_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end - add_index 'auth_tokens', ['user_id'], name: 'index_auth_tokens_on_user_id' + add_index "infrared_groups", ["user_id"], name: "index_infrared_groups_on_user_id" - create_table 'infrared_groups', force: :cascade do |t| - t.string 'name' - t.integer 'user_id' - t.datetime 'created_at', null: false - t.datetime 'updated_at', null: false + create_table "infrared_relationals", force: :cascade do |t| + t.integer "infrared_id" + t.integer "infrared_group_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end - add_index 'infrared_groups', ['user_id'], name: 'index_infrared_groups_on_user_id' + add_index "infrared_relationals", ["infrared_group_id"], name: "index_infrared_relationals_on_infrared_group_id" + add_index "infrared_relationals", ["infrared_id"], name: "index_infrared_relationals_on_infrared_id" - create_table 'infrared_relationals', force: :cascade do |t| - t.integer 'infrared_id' - t.integer 'infrared_group_id' - t.datetime 'created_at', null: false - t.datetime 'updated_at', null: false + create_table "infrareds", force: :cascade do |t| + t.string "name" + t.string "data" + t.integer "user_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.integer "count", default: 0 end - add_index 'infrared_relationals', ['infrared_group_id'], name: 'index_infrared_relationals_on_infrared_group_id' - add_index 'infrared_relationals', ['infrared_id'], name: 'index_infrared_relationals_on_infrared_id' + add_index "infrareds", ["user_id"], name: "index_infrareds_on_user_id" - create_table 'infrareds', force: :cascade do |t| - t.string 'name' - t.string 'data' - t.integer 'user_id' - t.datetime 'created_at', null: false - t.datetime 'updated_at', null: false - t.integer 'count', default: 0 + create_table "logs", force: :cascade do |t| + t.integer "user_id" + t.integer "infrared_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.string "name" + t.integer "status" end - add_index 'infrareds', ['user_id'], name: 'index_infrareds_on_user_id' + add_index "logs", ["infrared_id"], name: "index_logs_on_infrared_id" + add_index "logs", ["user_id"], name: "index_logs_on_user_id" - create_table 'logs', force: :cascade do |t| - t.integer 'user_id' - t.integer 'infrared_id' - t.datetime 'created_at', null: false - t.datetime 'updated_at', null: false - t.string 'name' - t.integer 'status' + create_table "schedules", force: :cascade do |t| + t.string "name" + t.text "description" + t.string "cron" + t.string "job_name" + t.integer "user_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end - add_index 'logs', ['infrared_id'], name: 'index_logs_on_infrared_id' - add_index 'logs', ['user_id'], name: 'index_logs_on_user_id' - - create_table 'user_infos', force: :cascade do |t| - t.string 'screen_name' - t.string 'hashed_password' - t.string 'email' - t.string 'email_for_index' - t.integer 'user_id' - t.datetime 'created_at', null: false - t.datetime 'updated_at', null: false + add_index "schedules", ["user_id"], name: "index_schedules_on_user_id" + + create_table "user_infos", force: :cascade do |t| + t.string "screen_name" + t.string "hashed_password" + t.string "email" + t.string "email_for_index" + t.integer "user_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end - add_index 'user_infos', ['user_id'], name: 'index_user_infos_on_user_id' + add_index "user_infos", ["user_id"], name: "index_user_infos_on_user_id" - create_table 'users', force: :cascade do |t| - t.datetime 'created_at', null: false - t.datetime 'updated_at', null: false + create_table "users", force: :cascade do |t| + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end + end From e52ea67f14b130eb39f8481d6f1d64f30a8a2dde Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sat, 12 Dec 2015 00:13:23 +0900 Subject: [PATCH 233/358] rake db:migrate --- db/migrate/20151211143436_create_schedules.rb | 1 + db/schema.rb | 2 ++ 2 files changed, 3 insertions(+) diff --git a/db/migrate/20151211143436_create_schedules.rb b/db/migrate/20151211143436_create_schedules.rb index f2aa312..6a41891 100644 --- a/db/migrate/20151211143436_create_schedules.rb +++ b/db/migrate/20151211143436_create_schedules.rb @@ -6,6 +6,7 @@ def change t.string :cron t.string :job_name t.references :user, index: true, foreign_key: true + t.references :infrared, index: true, foreign_key: true t.timestamps null: false end diff --git a/db/schema.rb b/db/schema.rb index 2c18eef..64d9f17 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -70,10 +70,12 @@ t.string "cron" t.string "job_name" t.integer "user_id" + t.integer "infrared_id" t.datetime "created_at", null: false t.datetime "updated_at", null: false end + add_index "schedules", ["infrared_id"], name: "index_schedules_on_infrared_id" add_index "schedules", ["user_id"], name: "index_schedules_on_user_id" create_table "user_infos", force: :cascade do |t| From 50bd87622005b764a725a055b8643c9a28488536 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sat, 12 Dec 2015 00:13:36 +0900 Subject: [PATCH 234/358] setting relational --- app/models/infrared.rb | 1 + app/models/schedule.rb | 1 + app/models/user.rb | 1 + 3 files changed, 3 insertions(+) diff --git a/app/models/infrared.rb b/app/models/infrared.rb index 51be52e..349b241 100644 --- a/app/models/infrared.rb +++ b/app/models/infrared.rb @@ -3,4 +3,5 @@ class Infrared < ActiveRecord::Base has_many :logs has_many :infrared_relationals has_many :infrared_groups, through: :infrared_relationals + has_one :schedule end diff --git a/app/models/schedule.rb b/app/models/schedule.rb index 75072cb..4421eaf 100644 --- a/app/models/schedule.rb +++ b/app/models/schedule.rb @@ -1,3 +1,4 @@ class Schedule < ActiveRecord::Base belongs_to :user + belongs_to :infrared end diff --git a/app/models/user.rb b/app/models/user.rb index 30c6bfe..556eeb4 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,6 +1,7 @@ class User < ActiveRecord::Base has_many :auth_tokens, dependent: :destroy has_one :info, class_name: 'UserInfo', dependent: :destroy + has_many :schedules, dependent: :destroy has_many :infrareds has_many :infrared_groups has_many :logs, dependent: :destroy From 22e2c342f8c8de9382ef5104b150d313cf8fc267 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sat, 12 Dec 2015 04:17:19 +0900 Subject: [PATCH 235/358] mount v1::Schedules --- app/apis/api/v1/base.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/apis/api/v1/base.rb b/app/apis/api/v1/base.rb index 8877cf3..357806f 100644 --- a/app/apis/api/v1/base.rb +++ b/app/apis/api/v1/base.rb @@ -34,6 +34,7 @@ class Base < Grape::API mount V1::Authorize mount V1::IR mount V1::InfraredGroup + mount V1::Schedules add_swagger_documentation format: :json, api_version: 'v1', hide_documentation_path: true end end From 196f2be77a21c95971d4218b9c0b25eb69bc8337 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sat, 12 Dec 2015 04:17:55 +0900 Subject: [PATCH 236/358] create regExp --- app/apis/api/v1/schedules.rb | 351 +++++++++++++++++++++++++++++++++++ 1 file changed, 351 insertions(+) create mode 100644 app/apis/api/v1/schedules.rb diff --git a/app/apis/api/v1/schedules.rb b/app/apis/api/v1/schedules.rb new file mode 100644 index 0000000..e682e89 --- /dev/null +++ b/app/apis/api/v1/schedules.rb @@ -0,0 +1,351 @@ +# app/apis/api/v1/users.rb + +module API + module V1 + class Schedules < Grape::API + helpers do + def integer_string?(str) + Integer(str) + true + rescue ArgumentError + false + end + + def invalid_cron + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.invalid_cron'), + code: ErrorCodes::INVALID_CRON + ] + }, response: {}) + end + def cron_check_value value, index + if value =~ /^(([0-9]+)((\,||\-||\/)[0-9]+)*||\*(\/[0-9]+)?)$/ + if integer_string?(value) || value == "*" + case index + when 0 #分 + if value == "*" + return "毎分" + elsif value.to_i <= 59 && value.to_i >= 0 + return value + "分に" + else + invalid_cron + end + when 1 #時 + if value == "*" + return "毎時" + elsif value.to_i <= 23 && value.to_i >= 0 + return value + "時" + else + invalid_cron + end + when 2 #日 + if value == "*" + return "毎日" + elsif value.to_i <= 31 && value.to_i >= 1 + return value + "日" + else + invalid_cron + end + when 3 #月 + if value == "*" + return "毎月" + elsif value.to_i <= 12 && value.to_i >= 1 + return value + "月" + else + invalid_cron + end + when 4 #曜日 + if value == "*" + return "毎曜日の" + elsif value.to_i <= 7 && value.to_i >= 0 + case value.to_i + when 0 + return "日曜日の" + when 1 + return "月曜日の" + when 2 + return "火曜日の" + when 3 + return "水曜日の" + when 4 + return "木曜日の" + when 5 + return "金曜日の" + when 6 + return "土曜日の" + when 7 + return "日曜日の" + end + else + invalid_cron + end + end + else + response = "" + if value.include?("-") + value.split("-").each_with_index do |val, i| + if i == 0 + case index + when 0 + response = response + val + "分から" + when 1 + response = response + val + "時から" + when 2 + response = response + val + "日から" + when 3 + response = response + val + "月から" + when 4 + case val.to_i + when 0 + response = response + "日曜日から" + when 1 + response = response + "月曜日から" + when 2 + response = response + "火曜日から" + when 3 + response = response + "水曜日から" + when 4 + response = response + "木曜日から" + when 5 + response = response + "金曜日から" + when 6 + response = response + "土曜日から" + when 7 + response = response + "日曜日から" + end + end + else + if val.include?("/") + val = val.split("/")[0] + end + case index + when 0 + response = response + val + "分まで1分ごとに" + when 1 + response = response + val + "時まで" + when 2 + response = response + val + "日まで" + when 3 + response = response + val + "月まで" + when 4 + case val.to_i + when 0 + response = response + "日曜日まで" + when 1 + response = response + "月曜日まで" + when 2 + response = response + "火曜日まで" + when 3 + response = response + "水曜日まで" + when 4 + response = response + "木曜日まで" + when 5 + response = response + "金曜日まで" + when 6 + response = response + "土曜日まで" + when 7 + response = response + "日曜日まで" + end + end + end + end + end + if value.include?("/") + value.split("/").each_with_index do |val, i| + if i == 0 + unless val.include?("-") + case index + when 0 + if val == "*" + else + response = response + val + "分から" + end + when 1 + if val == "*" + else + response = response + val + "時から" + end + when 2 + if val == "*" + else + response = response + val + "日から" + end + when 3 + if val == "*" + else + response = response + val + "月から" + end + when 4 + case val.to_i + when 0 + response = response + "日曜日から" + when 1 + response = response + "月曜日から" + when 2 + response = response + "火曜日から" + when 3 + response = response + "水曜日から" + when 4 + response = response + "木曜日から" + when 5 + response = response + "金曜日から" + when 6 + response = response + "土曜日から" + when 7 + response = response + "日曜日から" + end + end + end + else + case index + when 0 + response = response + val + "分おきに" + when 1 + response = response + val + "時間おきに" + when 2 + response = response + val + "日おきに" + when 3 + response = response + val + "月おきに" + when 4 + invalid_cron + end + end + end + end + if value.include?(",") + value.split(",").each_with_index do |val, i| + case index + when 0 + response = response + val + "分と" + when 1 + response = response + val + "時と" + when 2 + response = response + val + "日と" + when 3 + response = response + val + "月と" + when 4 + case val.to_i + when 0 + response = response + "日曜日と" + when 1 + response = response + "月曜日と" + when 2 + response = response + "火曜日と" + when 3 + response = response + "水曜日と" + when 4 + response = response + "木曜日と" + when 5 + response = response + "金曜日と" + when 6 + response = response + "土曜日と" + when 7 + response = response + "日曜日と" + end + end + end + if index == 0 + response.gsub!(/と$/u, "に") + else + response.gsub!(/と$/u, "の") + end + end + return response + end + else + invalid_cron + end + end + end + resource :schedule do + desc 'スケジュールの作成', notes: <<-NOTE +

スケジュールを作成します

+

+ cronの設定には気をつけてね +

+ NOTE + params do + requires :auth_token, type: String, desc: 'Auth token.' + requires :ir_id, type: Integer, desc: 'Auth token.' + requires :name, type: String, desc: 'Auth token.' + requires :cron, type: String, desc: 'Auth token.' + end + post '/', jbuilder: 'api/v1/schedule/create' do + if (token = AuthToken.find_by(token: params[:auth_token])) + if user.info.nil? + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.user_not_found'), + code: ErrorCodes::NOT_FOUND_USER + ] + }, response: {}) + else + if(infrared = Infrared.find_by(id: params[:ir_id])) + cron = params[:cron] + cron_a = cron.split(" ") + message = " " + isEveryWord = false + if cron_a.size == 5 + cron_a.each_with_index do |c, index| + if cron_check_value(c,index).to_s.include?("毎") + if isEveryWord + else + isEveryWord =true + message = cron_check_value(c,index).to_s + message + end + else + if index == 4 && cron_a[4] != "*" + message.gsub!(/毎日/u,"") + message.gsub!(/毎月/u,"") + message = cron_check_value(c,index).to_s + message + if cron_a[2] != "*" + message.gsub!(/曜日の/u,"曜日と") + end + else + message = cron_check_value(c,index).to_s + message + end + end + end + message.gsub!(/時毎分/u,"時に毎分") + message = message + "実行します" + schedule = user.schedules.create(name: params[:name], cron: params[:cron]) + schedule.update(job_name: "schedule_#{user.id}_#{schedule.id}") + infrared.schedule = schedule + @schedule = schedule + @message = message + else + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.invalid_cron'), + code: ErrorCodes::INVALID_CRON + ] + }, response: {}) + end + else + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.ir_not_found'), + code: ErrorCodes::NOT_FOUND + ] + }, response: {}) + end + end + else + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.invalid_token'), + code: ErrorCodes::INVALID_TOKEN + ] + }, response: {}) + end + end + end + end + end +end From be4c720222efe95c433218a9514290348af849f0 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sat, 12 Dec 2015 04:27:07 +0900 Subject: [PATCH 237/358] create jbuilder --- app/views/apis/api/v1/schedule/create.jbuilder | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 app/views/apis/api/v1/schedule/create.jbuilder diff --git a/app/views/apis/api/v1/schedule/create.jbuilder b/app/views/apis/api/v1/schedule/create.jbuilder new file mode 100644 index 0000000..6afc708 --- /dev/null +++ b/app/views/apis/api/v1/schedule/create.jbuilder @@ -0,0 +1,9 @@ +json.meta do + json.status 201 + json.message "#{@schedule.name}を作成しました。" +end +json.response do + json.schedule @schedule +end + +json.message @message \ No newline at end of file From d586f29c211ead32d9a28cfb46be831536738215 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sat, 12 Dec 2015 04:27:15 +0900 Subject: [PATCH 238/358] update error_codes --- lib/error_codes.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/error_codes.rb b/lib/error_codes.rb index 78f0f2b..a4caf83 100644 --- a/lib/error_codes.rb +++ b/lib/error_codes.rb @@ -21,4 +21,5 @@ module ErrorCodes ALREADY_EXISTING = 20 NEED_A_PASSWORD = 21 NOT_FOUND_INFO = 22 + INVALID_CRON = 23 end From b80043239ab0cf138ed81b052e48dbf9a90e7244 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sat, 12 Dec 2015 05:58:57 +0900 Subject: [PATCH 239/358] add enum status to log --- app/models/log.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/log.rb b/app/models/log.rb index 5af231e..fa56e4d 100644 --- a/app/models/log.rb +++ b/app/models/log.rb @@ -1,5 +1,5 @@ class Log < ActiveRecord::Base belongs_to :user belongs_to :infrared, dependent: :destroy - enum status: %i(recieve_ir send_ir update_ir destroy_ir add_ir remove_ir) + enum status: %i(recieve_ir send_ir update_ir destroy_ir add_ir remove_ir robot_send_ir) end From 5950d6b2f07370de5b5ad8cd8ae54814753aa6ed Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sat, 12 Dec 2015 05:59:04 +0900 Subject: [PATCH 240/358] remove sample job --- app/jobs/resque_sample_job.rb | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 app/jobs/resque_sample_job.rb diff --git a/app/jobs/resque_sample_job.rb b/app/jobs/resque_sample_job.rb deleted file mode 100644 index 55203dd..0000000 --- a/app/jobs/resque_sample_job.rb +++ /dev/null @@ -1,9 +0,0 @@ -class ResqueScheduleTask - @queue = :resque_schdule_task - def self.perform(text) - path = File.expand_path("log/resque_schedule_task.log", Rails.root) - File.open(path, 'a') do |f| - f.puts text["screen_name"] - end - end -end \ No newline at end of file From 80479f990d48950f9930ffa4572878c6b6c96eed Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sat, 12 Dec 2015 05:59:18 +0900 Subject: [PATCH 241/358] create rescue_infrared_send_job --- app/jobs/resque_infrared_send_job.rb | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 app/jobs/resque_infrared_send_job.rb diff --git a/app/jobs/resque_infrared_send_job.rb b/app/jobs/resque_infrared_send_job.rb new file mode 100644 index 0000000..8b17d6f --- /dev/null +++ b/app/jobs/resque_infrared_send_job.rb @@ -0,0 +1,19 @@ +class ResqueInfraredSendJob + @queue = :resque_infrared_send_job + def self.perform(task) + path = File.expand_path("log/resque_infrared_send_job.log", Rails.root) + File.open(path, 'a') do |f| + binding.pry + schedule = Schedule.find_by(id:task["id"]) + infrared = schedule.infrared + fname = infrared.data + path = Rails.root.to_s + command = File.join(path, 'commands/send') + `#{command} #{path}/data/#{fname}` + count = infrared.count + 1 + infrared.update(count: count) + log = user.logs.create(name: "「#{schedule.name}」のスケジューラーが「#{infrared.name}」を実行しました", status: :robot_send_ir) + log.infrared = infrared + end + end +end \ No newline at end of file From 27cc5e870b34b4a733bc8d4c69b1618fc9a5ca5a Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sat, 12 Dec 2015 05:59:36 +0900 Subject: [PATCH 242/358] update schedules.rb --- app/apis/api/v1/schedules.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/apis/api/v1/schedules.rb b/app/apis/api/v1/schedules.rb index e682e89..d462d54 100644 --- a/app/apis/api/v1/schedules.rb +++ b/app/apis/api/v1/schedules.rb @@ -312,8 +312,10 @@ def cron_check_value value, index message.gsub!(/時毎分/u,"時に毎分") message = message + "実行します" schedule = user.schedules.create(name: params[:name], cron: params[:cron]) - schedule.update(job_name: "schedule_#{user.id}_#{schedule.id}") + cron = params[:cron] + schedule.update(description: "#{message}", cron: "#{cron}", job_name: "schedule_#{user.id}_#{schedule.id}") infrared.schedule = schedule + Resque.set_schedule("#{schedule.job_name}", { class: "ResqueInfraredSendJob", cron: cron, args: schedule}) @schedule = schedule @message = message else From af223cc875bf476f5cf0b030a96f865878316276 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sat, 12 Dec 2015 06:23:01 +0900 Subject: [PATCH 243/358] fix --- app/views/apis/api/v1/schedule/create.jbuilder | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/views/apis/api/v1/schedule/create.jbuilder b/app/views/apis/api/v1/schedule/create.jbuilder index 6afc708..795f45a 100644 --- a/app/views/apis/api/v1/schedule/create.jbuilder +++ b/app/views/apis/api/v1/schedule/create.jbuilder @@ -5,5 +5,3 @@ end json.response do json.schedule @schedule end - -json.message @message \ No newline at end of file From 230c49a2ef4ca1f6b4334e8913867857dc99c00d Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sat, 12 Dec 2015 06:30:56 +0900 Subject: [PATCH 244/358] update --- app/jobs/resque_infrared_send_job.rb | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/app/jobs/resque_infrared_send_job.rb b/app/jobs/resque_infrared_send_job.rb index 8b17d6f..8b616da 100644 --- a/app/jobs/resque_infrared_send_job.rb +++ b/app/jobs/resque_infrared_send_job.rb @@ -1,19 +1,16 @@ class ResqueInfraredSendJob @queue = :resque_infrared_send_job def self.perform(task) - path = File.expand_path("log/resque_infrared_send_job.log", Rails.root) - File.open(path, 'a') do |f| - binding.pry - schedule = Schedule.find_by(id:task["id"]) - infrared = schedule.infrared - fname = infrared.data - path = Rails.root.to_s - command = File.join(path, 'commands/send') - `#{command} #{path}/data/#{fname}` - count = infrared.count + 1 - infrared.update(count: count) - log = user.logs.create(name: "「#{schedule.name}」のスケジューラーが「#{infrared.name}」を実行しました", status: :robot_send_ir) - log.infrared = infrared - end + # path = File.expand_path("log/resque_infrared_send_job.log", Rails.root) + schedule = Schedule.find_by(id:task["id"]) + infrared = schedule.infrared + fname = infrared.data + path = Rails.root.to_s + command = File.join(path, 'commands/send') + `#{command} #{path}/data/#{fname}` + count = infrared.count + 1 + infrared.update(count: count) + log = user.logs.create(name: "「#{schedule.name}」のスケジューラーが「#{infrared.name}」を実行しました", status: :robot_send_ir) + log.infrared = infrared end end \ No newline at end of file From d1971f3bb3ef2f14bd667e37b11c1050a383de70 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 13 Dec 2015 00:29:22 +0900 Subject: [PATCH 245/358] update error_codes --- lib/error_codes.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/error_codes.rb b/lib/error_codes.rb index a4caf83..7fbe4d3 100644 --- a/lib/error_codes.rb +++ b/lib/error_codes.rb @@ -22,4 +22,5 @@ module ErrorCodes NEED_A_PASSWORD = 21 NOT_FOUND_INFO = 22 INVALID_CRON = 23 + NOT_FOUND_SCHEDULE = 24 end From 0adce63845e608157004b68c5e26592ff7d96d70 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 13 Dec 2015 00:29:34 +0900 Subject: [PATCH 246/358] create remove jbuilder --- app/views/apis/api/v1/schedule/remove.jbuilder | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 app/views/apis/api/v1/schedule/remove.jbuilder diff --git a/app/views/apis/api/v1/schedule/remove.jbuilder b/app/views/apis/api/v1/schedule/remove.jbuilder new file mode 100644 index 0000000..7adad69 --- /dev/null +++ b/app/views/apis/api/v1/schedule/remove.jbuilder @@ -0,0 +1,7 @@ +json.meta do + json.status 201 + json.message "#{@schedule.name}を停止しました。" +end +json.response do + json.schedule @schedule +end From 196c5e4465ceccb351076980aa052a108b4d88ec Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 13 Dec 2015 00:29:54 +0900 Subject: [PATCH 247/358] :bug: fix rescue infrared send job --- app/jobs/resque_infrared_send_job.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/jobs/resque_infrared_send_job.rb b/app/jobs/resque_infrared_send_job.rb index 8b616da..0c5787e 100644 --- a/app/jobs/resque_infrared_send_job.rb +++ b/app/jobs/resque_infrared_send_job.rb @@ -3,6 +3,7 @@ class ResqueInfraredSendJob def self.perform(task) # path = File.expand_path("log/resque_infrared_send_job.log", Rails.root) schedule = Schedule.find_by(id:task["id"]) + user = schedule.user infrared = schedule.infrared fname = infrared.data path = Rails.root.to_s From 1e3348355ad8a02bc51cff7501ccf7656ecd1cb3 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 13 Dec 2015 00:30:05 +0900 Subject: [PATCH 248/358] create remove schedule --- app/apis/api/v1/schedules.rb | 43 ++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/app/apis/api/v1/schedules.rb b/app/apis/api/v1/schedules.rb index d462d54..ad64c3b 100644 --- a/app/apis/api/v1/schedules.rb +++ b/app/apis/api/v1/schedules.rb @@ -259,6 +259,49 @@ def cron_check_value value, index end end end + resource :schedule do + desc 'スケジュールの停止', notes: <<-NOTE +

スケジュールを停止します

+ NOTE + params do + requires :auth_token, type: String, desc: 'Auth token.' + requires :schedule_id, type: Integer, desc: 'Schedule id' + end + post '/remove', jbuilder: 'api/v1/schedule/remove' do + if (token = AuthToken.find_by(token: params[:auth_token])) + if user.info.nil? + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.user_not_found'), + code: ErrorCodes::NOT_FOUND_USER + ] + }, response: {}) + else + if schedule = user.schedules.find_by(id: params[:schedule_id]) + remove_schedule(schedule.job_name) + @schedule = schedule + else + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.schedule_not_found'), + code: ErrorCodes::NOT_FOUND_SCHEDULE + ] + }, response: {}) + end + end + else + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.invalid_token'), + code: ErrorCodes::INVALID_TOKEN + ] + }, response: {}) + end + end + end resource :schedule do desc 'スケジュールの作成', notes: <<-NOTE

スケジュールを作成します

From d0656f8e0b4d9ffca768fb0ed1039a3ae44fd98c Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 13 Dec 2015 00:46:45 +0900 Subject: [PATCH 249/358] :bug: fix --- app/apis/api/v1/schedules.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/apis/api/v1/schedules.rb b/app/apis/api/v1/schedules.rb index ad64c3b..18c313c 100644 --- a/app/apis/api/v1/schedules.rb +++ b/app/apis/api/v1/schedules.rb @@ -279,7 +279,7 @@ def cron_check_value value, index }, response: {}) else if schedule = user.schedules.find_by(id: params[:schedule_id]) - remove_schedule(schedule.job_name) + Resque.remove_schedule(schedule.job_name) @schedule = schedule else error!(meta: { From 87df227906b92a243fde869e4bd60639f5f2cce2 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 13 Dec 2015 01:34:31 +0900 Subject: [PATCH 250/358] rails g migration AddStatusToSchedules status:integer --- db/migrate/20151212163400_add_status_to_schedules.rb | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 db/migrate/20151212163400_add_status_to_schedules.rb diff --git a/db/migrate/20151212163400_add_status_to_schedules.rb b/db/migrate/20151212163400_add_status_to_schedules.rb new file mode 100644 index 0000000..a2f408f --- /dev/null +++ b/db/migrate/20151212163400_add_status_to_schedules.rb @@ -0,0 +1,5 @@ +class AddStatusToSchedules < ActiveRecord::Migration + def change + add_column :schedules, :status, :integer + end +end From 47d2e3587c53a5ecd79a1c4a9d64a7cc74737780 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 13 Dec 2015 01:34:39 +0900 Subject: [PATCH 251/358] rake db:migrate --- db/schema.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/db/schema.rb b/db/schema.rb index 64d9f17..713e609 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20151211143436) do +ActiveRecord::Schema.define(version: 20151212163400) do create_table "auth_tokens", force: :cascade do |t| t.string "token" @@ -73,6 +73,7 @@ t.integer "infrared_id" t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.integer "status" end add_index "schedules", ["infrared_id"], name: "index_schedules_on_infrared_id" From 123fad8a921895ee83c0a6aba5a436cac8223930 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 13 Dec 2015 01:56:51 +0900 Subject: [PATCH 252/358] create new status to log --- app/models/log.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/log.rb b/app/models/log.rb index fa56e4d..ce3bdaf 100644 --- a/app/models/log.rb +++ b/app/models/log.rb @@ -1,5 +1,5 @@ class Log < ActiveRecord::Base belongs_to :user belongs_to :infrared, dependent: :destroy - enum status: %i(recieve_ir send_ir update_ir destroy_ir add_ir remove_ir robot_send_ir) + enum status: %i(recieve_ir send_ir update_ir destroy_ir add_ir remove_ir robot_send_ir robot_remove_schedule) end From 640e7f7b47428b398db16425dee549e189e818cc Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 13 Dec 2015 02:01:09 +0900 Subject: [PATCH 253/358] add enum status to schedule --- app/models/schedule.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/models/schedule.rb b/app/models/schedule.rb index 4421eaf..48652c1 100644 --- a/app/models/schedule.rb +++ b/app/models/schedule.rb @@ -1,4 +1,5 @@ class Schedule < ActiveRecord::Base belongs_to :user belongs_to :infrared + enum status: %i(inactive_schedule active_schedule) end From 3289f87b982496220fa8ff28f507f14a89776d0a Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 13 Dec 2015 02:01:19 +0900 Subject: [PATCH 254/358] add enum status to log --- app/models/log.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/log.rb b/app/models/log.rb index ce3bdaf..9ac2abd 100644 --- a/app/models/log.rb +++ b/app/models/log.rb @@ -1,5 +1,5 @@ class Log < ActiveRecord::Base belongs_to :user belongs_to :infrared, dependent: :destroy - enum status: %i(recieve_ir send_ir update_ir destroy_ir add_ir remove_ir robot_send_ir robot_remove_schedule) + enum status: %i(recieve_ir send_ir update_ir destroy_ir add_ir remove_ir robot_send_ir robot_remove_schedule robot_create_schedule) end From f6cdff0507c7394cfa45dad4e332bc396652e7a9 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 13 Dec 2015 02:01:27 +0900 Subject: [PATCH 255/358] update schedules --- app/apis/api/v1/schedules.rb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/apis/api/v1/schedules.rb b/app/apis/api/v1/schedules.rb index 18c313c..944d9ea 100644 --- a/app/apis/api/v1/schedules.rb +++ b/app/apis/api/v1/schedules.rb @@ -280,6 +280,9 @@ def cron_check_value value, index else if schedule = user.schedules.find_by(id: params[:schedule_id]) Resque.remove_schedule(schedule.job_name) + schedule.update(status: :inactive_schedule) + log = user.logs.create(name: "「#{schedule.name}」のスケジューラーを停止しました", status: :robot_remove_schedule) + log.infrared = schedule.infrared @schedule = schedule else error!(meta: { @@ -359,6 +362,9 @@ def cron_check_value value, index schedule.update(description: "#{message}", cron: "#{cron}", job_name: "schedule_#{user.id}_#{schedule.id}") infrared.schedule = schedule Resque.set_schedule("#{schedule.job_name}", { class: "ResqueInfraredSendJob", cron: cron, args: schedule}) + schedule.update(status: :active_schedule) + log = user.logs.create(name: "「#{schedule.name}」のスケジューラーを作成しました", status: :robot_create_schedule) + log.infrared = infrared @schedule = schedule @message = message else From f30b9216b0a42809880a21308720d02538e82cbc Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 13 Dec 2015 02:41:45 +0900 Subject: [PATCH 256/358] add error codes --- lib/error_codes.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/error_codes.rb b/lib/error_codes.rb index 7fbe4d3..e696896 100644 --- a/lib/error_codes.rb +++ b/lib/error_codes.rb @@ -23,4 +23,5 @@ module ErrorCodes NOT_FOUND_INFO = 22 INVALID_CRON = 23 NOT_FOUND_SCHEDULE = 24 + INVALID_PARAMS = 25 end From 32510ca39ab2933b507ef6a771ca8c2febe75cb5 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 13 Dec 2015 02:43:35 +0900 Subject: [PATCH 257/358] create schedule index api --- app/apis/api/v1/schedules.rb | 56 ++++++++++++++++++++++++++++++++++-- 1 file changed, 54 insertions(+), 2 deletions(-) diff --git a/app/apis/api/v1/schedules.rb b/app/apis/api/v1/schedules.rb index 944d9ea..905a515 100644 --- a/app/apis/api/v1/schedules.rb +++ b/app/apis/api/v1/schedules.rb @@ -259,7 +259,60 @@ def cron_check_value value, index end end end + resource :schedule do + desc 'スケジュール一覧を取得する', notes: <<-NOTE +

スケジュール一覧を取得します

+

+ null ・・・ すべてのスケジュールの取得
+ 0 ・・・ 稼働してないスケジュールの取得
+ 1 ・・・ 稼働しているスケジュールの取得 + NOTE + params do + requires :auth_token, type: String, desc: 'Auth token.' + optional :status, type: Integer, desc: 'status number.' + end + get '/', jbuilder: 'api/v1/schedule/index' do + if (token = AuthToken.find_by(token: params[:auth_token])) + if user.info.nil? + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.user_not_found'), + code: ErrorCodes::NOT_FOUND_USER + ] + }, response: {}) + else + @user = user + if params[:status].nil? + @schedules = user.schedules + elsif params[:status].to_s =~ /^[0-1]$/ + if params[:status] == 0 + @schedules = user.schedules.inactive_schedule + elsif params[:status] == 1 + @schedules = user.schedules.active_schedule + end + else + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.invalid_params'), + code: ErrorCodes::INVALID_PARAMS + ] + }, response: {}) + end + end + else + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.invalid_token'), + code: ErrorCodes::INVALID_TOKEN + ] + }, response: {}) + end + end + desc 'スケジュールの停止', notes: <<-NOTE

スケジュールを停止します

NOTE @@ -304,8 +357,7 @@ def cron_check_value value, index }, response: {}) end end - end - resource :schedule do + desc 'スケジュールの作成', notes: <<-NOTE

スケジュールを作成します

From 231eae22a234a65dfaf4296ce85c906036afb481 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 13 Dec 2015 02:43:41 +0900 Subject: [PATCH 258/358] update index jbuilder --- app/views/apis/api/v1/schedule/index.jbuilder | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 app/views/apis/api/v1/schedule/index.jbuilder diff --git a/app/views/apis/api/v1/schedule/index.jbuilder b/app/views/apis/api/v1/schedule/index.jbuilder new file mode 100644 index 0000000..74f7f9c --- /dev/null +++ b/app/views/apis/api/v1/schedule/index.jbuilder @@ -0,0 +1,7 @@ +json.meta do + json.status 200 + json.message "#{@user.info.screen_name}の赤外線一覧を取得しました。" +end +json.response do + json.schedules @schedules +end From 5215ab26afde7e8036b4ccb91b9a6cedfda8def3 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 13 Dec 2015 03:26:42 +0900 Subject: [PATCH 259/358] add new status activate --- app/models/log.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/log.rb b/app/models/log.rb index 9ac2abd..99d6aac 100644 --- a/app/models/log.rb +++ b/app/models/log.rb @@ -1,5 +1,5 @@ class Log < ActiveRecord::Base belongs_to :user belongs_to :infrared, dependent: :destroy - enum status: %i(recieve_ir send_ir update_ir destroy_ir add_ir remove_ir robot_send_ir robot_remove_schedule robot_create_schedule) + enum status: %i(recieve_ir send_ir update_ir destroy_ir add_ir remove_ir robot_send_ir robot_remove_schedule robot_create_schedule robot_activate_schedule) end From 27f14255b7af8d0d46e57f124f3b812bff412036 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 13 Dec 2015 03:27:03 +0900 Subject: [PATCH 260/358] create scheduler activate api --- app/apis/api/v1/schedules.rb | 60 +++++++++++++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) diff --git a/app/apis/api/v1/schedules.rb b/app/apis/api/v1/schedules.rb index 905a515..2574565 100644 --- a/app/apis/api/v1/schedules.rb +++ b/app/apis/api/v1/schedules.rb @@ -313,6 +313,64 @@ def cron_check_value value, index end end + desc 'スケジュールを稼働させる', notes: <<-NOTE +

スケジューラーを稼働するAPI

+

+ 選択したスケジューラーを稼働させるためのAPIです。 +

+ NOTE + params do + requires :auth_token, type: String, desc: 'Auth token.' + requires :schedule_id, type: Integer, desc: 'Schedule id' + end + post '/activate', jbuilder: 'api/v1/schedule/activate' do + if (token = AuthToken.find_by(token: params[:auth_token])) + if user.info.nil? + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.user_not_found'), + code: ErrorCodes::NOT_FOUND_USER + ] + }, response: {}) + else + if schedule = user.schedules.find_by(id: params[:schedule_id]) + if schedule.active_schedule? + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.schedule_already_set'), + code: ErrorCodes::ALREADY_EXISTING + ] + }, response: {}) + else + Resque.set_schedule("#{schedule.job_name}", { class: "ResqueInfraredSendJob", cron: schedule.cron, args: schedule}) + schedule.update(status: :active_schedule) + log = user.logs.create(name: "「#{schedule.name}」のスケジューラーを稼働しました", status: :robot_activate_schedule) + log.infrared = schedule.infrared + @schedule = schedule + end + else + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.schedule_not_found'), + code: ErrorCodes::NOT_FOUND_SCHEDULE + ] + }, response: {}) + end + end + else + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.invalid_token'), + code: ErrorCodes::INVALID_TOKEN + ] + }, response: {}) + end + end + desc 'スケジュールの停止', notes: <<-NOTE

スケジュールを停止します

NOTE @@ -415,7 +473,7 @@ def cron_check_value value, index infrared.schedule = schedule Resque.set_schedule("#{schedule.job_name}", { class: "ResqueInfraredSendJob", cron: cron, args: schedule}) schedule.update(status: :active_schedule) - log = user.logs.create(name: "「#{schedule.name}」のスケジューラーを作成しました", status: :robot_create_schedule) + log = user.logs.create(name: "「#{schedule.name}」のスケジューラーを作成、稼働しました", status: :robot_create_schedule) log.infrared = infrared @schedule = schedule @message = message From 4cf35e6c002b5cb623516607c46502a24060a4d8 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 13 Dec 2015 03:27:13 +0900 Subject: [PATCH 261/358] create activate jbuilder --- app/views/apis/api/v1/schedule/activate.jbuilder | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 app/views/apis/api/v1/schedule/activate.jbuilder diff --git a/app/views/apis/api/v1/schedule/activate.jbuilder b/app/views/apis/api/v1/schedule/activate.jbuilder new file mode 100644 index 0000000..ed5295b --- /dev/null +++ b/app/views/apis/api/v1/schedule/activate.jbuilder @@ -0,0 +1,7 @@ +json.meta do + json.status 201 + json.message "「#{@schedule.name}」を稼働しました。" +end +json.response do + json.schedule @schedule +end From ff3028019891c2f02329f51c40c9d3ef2454b3fe Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 13 Dec 2015 03:31:28 +0900 Subject: [PATCH 262/358] fix readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c1ba667..3948ad9 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ $ redis-server ### Resque立ち上げ ```sh -$ $ QUEUE=* rake environment resque:work +$ QUEUE=* rake environment resque:work ``` ### scheduler立ち上げ From 5a73237825bb2943bf8efd694372a4f6d3c39483 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 13 Dec 2015 03:34:29 +0900 Subject: [PATCH 263/358] rubocop -a --- app/apis/api/v1/schedules.rb | 301 +++++++++++++-------------- app/jobs/resque_infrared_send_job.rb | 4 +- config/initializers/redis.rb | 6 +- config/routes.rb | 2 +- db/schema.rb | 128 ++++++------ lib/error_codes.rb | 2 +- lib/tasks/resque.rake | 8 +- spec/factories/schedules.rb | 11 +- spec/models/schedule_spec.rb | 2 +- 9 files changed, 229 insertions(+), 235 deletions(-) diff --git a/app/apis/api/v1/schedules.rb b/app/apis/api/v1/schedules.rb index 2574565..6eebfdb 100644 --- a/app/apis/api/v1/schedules.rb +++ b/app/apis/api/v1/schedules.rb @@ -13,243 +13,242 @@ def integer_string?(str) def invalid_cron error!(meta: { - status: 400, - errors: [ - message: ('errors.messages.invalid_cron'), - code: ErrorCodes::INVALID_CRON - ] - }, response: {}) + status: 400, + errors: [ + message: ('errors.messages.invalid_cron'), + code: ErrorCodes::INVALID_CRON + ] + }, response: {}) end - def cron_check_value value, index + + def cron_check_value(value, index) if value =~ /^(([0-9]+)((\,||\-||\/)[0-9]+)*||\*(\/[0-9]+)?)$/ - if integer_string?(value) || value == "*" + if integer_string?(value) || value == '*' case index - when 0 #分 - if value == "*" - return "毎分" + when 0 # 分 + if value == '*' + return '毎分' elsif value.to_i <= 59 && value.to_i >= 0 - return value + "分に" + return value + '分に' else invalid_cron end - when 1 #時 - if value == "*" - return "毎時" + when 1 # 時 + if value == '*' + return '毎時' elsif value.to_i <= 23 && value.to_i >= 0 - return value + "時" + return value + '時' else invalid_cron end - when 2 #日 - if value == "*" - return "毎日" + when 2 # 日 + if value == '*' + return '毎日' elsif value.to_i <= 31 && value.to_i >= 1 - return value + "日" + return value + '日' else invalid_cron end - when 3 #月 - if value == "*" - return "毎月" + when 3 # 月 + if value == '*' + return '毎月' elsif value.to_i <= 12 && value.to_i >= 1 - return value + "月" + return value + '月' else invalid_cron end - when 4 #曜日 - if value == "*" - return "毎曜日の" + when 4 # 曜日 + if value == '*' + return '毎曜日の' elsif value.to_i <= 7 && value.to_i >= 0 case value.to_i when 0 - return "日曜日の" + return '日曜日の' when 1 - return "月曜日の" + return '月曜日の' when 2 - return "火曜日の" + return '火曜日の' when 3 - return "水曜日の" + return '水曜日の' when 4 - return "木曜日の" + return '木曜日の' when 5 - return "金曜日の" + return '金曜日の' when 6 - return "土曜日の" + return '土曜日の' when 7 - return "日曜日の" + return '日曜日の' end else invalid_cron end end else - response = "" - if value.include?("-") - value.split("-").each_with_index do |val, i| + response = '' + if value.include?('-') + value.split('-').each_with_index do |val, i| if i == 0 case index when 0 - response = response + val + "分から" + response = response + val + '分から' when 1 - response = response + val + "時から" + response = response + val + '時から' when 2 - response = response + val + "日から" + response = response + val + '日から' when 3 - response = response + val + "月から" + response = response + val + '月から' when 4 case val.to_i when 0 - response = response + "日曜日から" + response += '日曜日から' when 1 - response = response + "月曜日から" + response += '月曜日から' when 2 - response = response + "火曜日から" + response += '火曜日から' when 3 - response = response + "水曜日から" + response += '水曜日から' when 4 - response = response + "木曜日から" + response += '木曜日から' when 5 - response = response + "金曜日から" + response += '金曜日から' when 6 - response = response + "土曜日から" + response += '土曜日から' when 7 - response = response + "日曜日から" + response += '日曜日から' end end else - if val.include?("/") - val = val.split("/")[0] - end + val = val.split('/')[0] if val.include?('/') case index when 0 - response = response + val + "分まで1分ごとに" + response = response + val + '分まで1分ごとに' when 1 - response = response + val + "時まで" + response = response + val + '時まで' when 2 - response = response + val + "日まで" + response = response + val + '日まで' when 3 - response = response + val + "月まで" + response = response + val + '月まで' when 4 case val.to_i when 0 - response = response + "日曜日まで" + response += '日曜日まで' when 1 - response = response + "月曜日まで" + response += '月曜日まで' when 2 - response = response + "火曜日まで" + response += '火曜日まで' when 3 - response = response + "水曜日まで" + response += '水曜日まで' when 4 - response = response + "木曜日まで" + response += '木曜日まで' when 5 - response = response + "金曜日まで" + response += '金曜日まで' when 6 - response = response + "土曜日まで" + response += '土曜日まで' when 7 - response = response + "日曜日まで" + response += '日曜日まで' end end end end end - if value.include?("/") - value.split("/").each_with_index do |val, i| + if value.include?('/') + value.split('/').each_with_index do |val, i| if i == 0 - unless val.include?("-") + unless val.include?('-') case index when 0 - if val == "*" + if val == '*' else - response = response + val + "分から" + response = response + val + '分から' end when 1 - if val == "*" + if val == '*' else - response = response + val + "時から" + response = response + val + '時から' end when 2 - if val == "*" + if val == '*' else - response = response + val + "日から" + response = response + val + '日から' end when 3 - if val == "*" + if val == '*' else - response = response + val + "月から" + response = response + val + '月から' end when 4 case val.to_i when 0 - response = response + "日曜日から" + response += '日曜日から' when 1 - response = response + "月曜日から" + response += '月曜日から' when 2 - response = response + "火曜日から" + response += '火曜日から' when 3 - response = response + "水曜日から" + response += '水曜日から' when 4 - response = response + "木曜日から" + response += '木曜日から' when 5 - response = response + "金曜日から" + response += '金曜日から' when 6 - response = response + "土曜日から" + response += '土曜日から' when 7 - response = response + "日曜日から" + response += '日曜日から' end end end else case index when 0 - response = response + val + "分おきに" + response = response + val + '分おきに' when 1 - response = response + val + "時間おきに" + response = response + val + '時間おきに' when 2 - response = response + val + "日おきに" + response = response + val + '日おきに' when 3 - response = response + val + "月おきに" + response = response + val + '月おきに' when 4 invalid_cron end end end end - if value.include?(",") - value.split(",").each_with_index do |val, i| + if value.include?(',') + value.split(',').each_with_index do |val, _i| case index when 0 - response = response + val + "分と" + response = response + val + '分と' when 1 - response = response + val + "時と" + response = response + val + '時と' when 2 - response = response + val + "日と" + response = response + val + '日と' when 3 - response = response + val + "月と" + response = response + val + '月と' when 4 case val.to_i when 0 - response = response + "日曜日と" + response += '日曜日と' when 1 - response = response + "月曜日と" + response += '月曜日と' when 2 - response = response + "火曜日と" + response += '火曜日と' when 3 - response = response + "水曜日と" + response += '水曜日と' when 4 - response = response + "木曜日と" + response += '木曜日と' when 5 - response = response + "金曜日と" + response += '金曜日と' when 6 - response = response + "土曜日と" + response += '土曜日と' when 7 - response = response + "日曜日と" + response += '日曜日と' end end end if index == 0 - response.gsub!(/と$/u, "に") + response.gsub!(/と$/u, 'に') else - response.gsub!(/と$/u, "の") + response.gsub!(/と$/u, 'の') end end return response @@ -294,12 +293,12 @@ def cron_check_value value, index end else error!(meta: { - status: 400, - errors: [ - message: ('errors.messages.invalid_params'), - code: ErrorCodes::INVALID_PARAMS - ] - }, response: {}) + status: 400, + errors: [ + message: ('errors.messages.invalid_params'), + code: ErrorCodes::INVALID_PARAMS + ] + }, response: {}) end end else @@ -337,14 +336,14 @@ def cron_check_value value, index if schedule = user.schedules.find_by(id: params[:schedule_id]) if schedule.active_schedule? error!(meta: { - status: 400, - errors: [ - message: ('errors.messages.schedule_already_set'), - code: ErrorCodes::ALREADY_EXISTING - ] - }, response: {}) + status: 400, + errors: [ + message: ('errors.messages.schedule_already_set'), + code: ErrorCodes::ALREADY_EXISTING + ] + }, response: {}) else - Resque.set_schedule("#{schedule.job_name}", { class: "ResqueInfraredSendJob", cron: schedule.cron, args: schedule}) + Resque.set_schedule("#{schedule.job_name}", class: 'ResqueInfraredSendJob', cron: schedule.cron, args: schedule) schedule.update(status: :active_schedule) log = user.logs.create(name: "「#{schedule.name}」のスケジューラーを稼働しました", status: :robot_activate_schedule) log.infrared = schedule.infrared @@ -352,12 +351,12 @@ def cron_check_value value, index end else error!(meta: { - status: 400, - errors: [ - message: ('errors.messages.schedule_not_found'), - code: ErrorCodes::NOT_FOUND_SCHEDULE - ] - }, response: {}) + status: 400, + errors: [ + message: ('errors.messages.schedule_not_found'), + code: ErrorCodes::NOT_FOUND_SCHEDULE + ] + }, response: {}) end end else @@ -397,12 +396,12 @@ def cron_check_value value, index @schedule = schedule else error!(meta: { - status: 400, - errors: [ - message: ('errors.messages.schedule_not_found'), - code: ErrorCodes::NOT_FOUND_SCHEDULE - ] - }, response: {}) + status: 400, + errors: [ + message: ('errors.messages.schedule_not_found'), + code: ErrorCodes::NOT_FOUND_SCHEDULE + ] + }, response: {}) end end else @@ -439,39 +438,37 @@ def cron_check_value value, index ] }, response: {}) else - if(infrared = Infrared.find_by(id: params[:ir_id])) + if (infrared = Infrared.find_by(id: params[:ir_id])) cron = params[:cron] - cron_a = cron.split(" ") - message = " " + cron_a = cron.split(' ') + message = ' ' isEveryWord = false if cron_a.size == 5 cron_a.each_with_index do |c, index| - if cron_check_value(c,index).to_s.include?("毎") + if cron_check_value(c, index).to_s.include?('毎') if isEveryWord else - isEveryWord =true - message = cron_check_value(c,index).to_s + message + isEveryWord = true + message = cron_check_value(c, index).to_s + message end else - if index == 4 && cron_a[4] != "*" - message.gsub!(/毎日/u,"") - message.gsub!(/毎月/u,"") - message = cron_check_value(c,index).to_s + message - if cron_a[2] != "*" - message.gsub!(/曜日の/u,"曜日と") - end + if index == 4 && cron_a[4] != '*' + message.gsub!(/毎日/u, '') + message.gsub!(/毎月/u, '') + message = cron_check_value(c, index).to_s + message + message.gsub!(/曜日の/u, '曜日と') if cron_a[2] != '*' else - message = cron_check_value(c,index).to_s + message + message = cron_check_value(c, index).to_s + message end end end - message.gsub!(/時毎分/u,"時に毎分") - message = message + "実行します" + message.gsub!(/時毎分/u, '時に毎分') + message += '実行します' schedule = user.schedules.create(name: params[:name], cron: params[:cron]) cron = params[:cron] schedule.update(description: "#{message}", cron: "#{cron}", job_name: "schedule_#{user.id}_#{schedule.id}") infrared.schedule = schedule - Resque.set_schedule("#{schedule.job_name}", { class: "ResqueInfraredSendJob", cron: cron, args: schedule}) + Resque.set_schedule("#{schedule.job_name}", { class: 'ResqueInfraredSendJob', cron: cron, args: schedule }) schedule.update(status: :active_schedule) log = user.logs.create(name: "「#{schedule.name}」のスケジューラーを作成、稼働しました", status: :robot_create_schedule) log.infrared = infrared @@ -479,12 +476,12 @@ def cron_check_value value, index @message = message else error!(meta: { - status: 400, - errors: [ - message: ('errors.messages.invalid_cron'), - code: ErrorCodes::INVALID_CRON - ] - }, response: {}) + status: 400, + errors: [ + message: ('errors.messages.invalid_cron'), + code: ErrorCodes::INVALID_CRON + ] + }, response: {}) end else error!(meta: { diff --git a/app/jobs/resque_infrared_send_job.rb b/app/jobs/resque_infrared_send_job.rb index 0c5787e..f416ea2 100644 --- a/app/jobs/resque_infrared_send_job.rb +++ b/app/jobs/resque_infrared_send_job.rb @@ -2,7 +2,7 @@ class ResqueInfraredSendJob @queue = :resque_infrared_send_job def self.perform(task) # path = File.expand_path("log/resque_infrared_send_job.log", Rails.root) - schedule = Schedule.find_by(id:task["id"]) + schedule = Schedule.find_by(id: task['id']) user = schedule.user infrared = schedule.infrared fname = infrared.data @@ -14,4 +14,4 @@ def self.perform(task) log = user.logs.create(name: "「#{schedule.name}」のスケジューラーが「#{infrared.name}」を実行しました", status: :robot_send_ir) log.infrared = infrared end -end \ No newline at end of file +end diff --git a/config/initializers/redis.rb b/config/initializers/redis.rb index 98a444a..3fdb0de 100644 --- a/config/initializers/redis.rb +++ b/config/initializers/redis.rb @@ -1,7 +1,7 @@ require 'resque-scheduler' require 'resque/scheduler/server' -if ENV["REDISCLOUD_URL"] - $redis = Resque.redis = Redis.new(:url => ENV["REDISCLOUD_URL"]) +if ENV['REDISCLOUD_URL'] + $redis = Resque.redis = Redis.new(url: ENV['REDISCLOUD_URL']) else - $redis = Resque.redis = Redis.new(host: "localhost", port: "6379") + $redis = Resque.redis = Redis.new(host: 'localhost', port: '6379') end diff --git a/config/routes.rb b/config/routes.rb index 5ebee4f..27e253e 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,7 +1,7 @@ require 'resque/server' Rails.application.routes.draw do - mount Resque::Server.new, at: "/resque" + mount Resque::Server.new, at: '/resque' mount API::Base => '/' # The priority is based upon order of creation: first created -> highest priority. diff --git a/db/schema.rb b/db/schema.rb index 713e609..0757fce 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,89 +11,87 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20151212163400) do - - create_table "auth_tokens", force: :cascade do |t| - t.string "token" - t.integer "user_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false +ActiveRecord::Schema.define(version: 20_151_212_163_400) do + create_table 'auth_tokens', force: :cascade do |t| + t.string 'token' + t.integer 'user_id' + t.datetime 'created_at', null: false + t.datetime 'updated_at', null: false end - add_index "auth_tokens", ["user_id"], name: "index_auth_tokens_on_user_id" + add_index 'auth_tokens', ['user_id'], name: 'index_auth_tokens_on_user_id' - create_table "infrared_groups", force: :cascade do |t| - t.string "name" - t.integer "user_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + create_table 'infrared_groups', force: :cascade do |t| + t.string 'name' + t.integer 'user_id' + t.datetime 'created_at', null: false + t.datetime 'updated_at', null: false end - add_index "infrared_groups", ["user_id"], name: "index_infrared_groups_on_user_id" + add_index 'infrared_groups', ['user_id'], name: 'index_infrared_groups_on_user_id' - create_table "infrared_relationals", force: :cascade do |t| - t.integer "infrared_id" - t.integer "infrared_group_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + create_table 'infrared_relationals', force: :cascade do |t| + t.integer 'infrared_id' + t.integer 'infrared_group_id' + t.datetime 'created_at', null: false + t.datetime 'updated_at', null: false end - add_index "infrared_relationals", ["infrared_group_id"], name: "index_infrared_relationals_on_infrared_group_id" - add_index "infrared_relationals", ["infrared_id"], name: "index_infrared_relationals_on_infrared_id" + add_index 'infrared_relationals', ['infrared_group_id'], name: 'index_infrared_relationals_on_infrared_group_id' + add_index 'infrared_relationals', ['infrared_id'], name: 'index_infrared_relationals_on_infrared_id' - create_table "infrareds", force: :cascade do |t| - t.string "name" - t.string "data" - t.integer "user_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.integer "count", default: 0 + create_table 'infrareds', force: :cascade do |t| + t.string 'name' + t.string 'data' + t.integer 'user_id' + t.datetime 'created_at', null: false + t.datetime 'updated_at', null: false + t.integer 'count', default: 0 end - add_index "infrareds", ["user_id"], name: "index_infrareds_on_user_id" + add_index 'infrareds', ['user_id'], name: 'index_infrareds_on_user_id' - create_table "logs", force: :cascade do |t| - t.integer "user_id" - t.integer "infrared_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.string "name" - t.integer "status" + create_table 'logs', force: :cascade do |t| + t.integer 'user_id' + t.integer 'infrared_id' + t.datetime 'created_at', null: false + t.datetime 'updated_at', null: false + t.string 'name' + t.integer 'status' end - add_index "logs", ["infrared_id"], name: "index_logs_on_infrared_id" - add_index "logs", ["user_id"], name: "index_logs_on_user_id" - - create_table "schedules", force: :cascade do |t| - t.string "name" - t.text "description" - t.string "cron" - t.string "job_name" - t.integer "user_id" - t.integer "infrared_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.integer "status" + add_index 'logs', ['infrared_id'], name: 'index_logs_on_infrared_id' + add_index 'logs', ['user_id'], name: 'index_logs_on_user_id' + + create_table 'schedules', force: :cascade do |t| + t.string 'name' + t.text 'description' + t.string 'cron' + t.string 'job_name' + t.integer 'user_id' + t.integer 'infrared_id' + t.datetime 'created_at', null: false + t.datetime 'updated_at', null: false + t.integer 'status' end - add_index "schedules", ["infrared_id"], name: "index_schedules_on_infrared_id" - add_index "schedules", ["user_id"], name: "index_schedules_on_user_id" - - create_table "user_infos", force: :cascade do |t| - t.string "screen_name" - t.string "hashed_password" - t.string "email" - t.string "email_for_index" - t.integer "user_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + add_index 'schedules', ['infrared_id'], name: 'index_schedules_on_infrared_id' + add_index 'schedules', ['user_id'], name: 'index_schedules_on_user_id' + + create_table 'user_infos', force: :cascade do |t| + t.string 'screen_name' + t.string 'hashed_password' + t.string 'email' + t.string 'email_for_index' + t.integer 'user_id' + t.datetime 'created_at', null: false + t.datetime 'updated_at', null: false end - add_index "user_infos", ["user_id"], name: "index_user_infos_on_user_id" + add_index 'user_infos', ['user_id'], name: 'index_user_infos_on_user_id' - create_table "users", force: :cascade do |t| - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + create_table 'users', force: :cascade do |t| + t.datetime 'created_at', null: false + t.datetime 'updated_at', null: false end - end diff --git a/lib/error_codes.rb b/lib/error_codes.rb index e696896..071e0c8 100644 --- a/lib/error_codes.rb +++ b/lib/error_codes.rb @@ -23,5 +23,5 @@ module ErrorCodes NOT_FOUND_INFO = 22 INVALID_CRON = 23 NOT_FOUND_SCHEDULE = 24 - INVALID_PARAMS = 25 + INVALID_PARAMS = 25 end diff --git a/lib/tasks/resque.rake b/lib/tasks/resque.rake index 1d5803d..f3e14c0 100644 --- a/lib/tasks/resque.rake +++ b/lib/tasks/resque.rake @@ -2,12 +2,12 @@ require 'resque/tasks' require 'resque/scheduler/tasks' namespace :resque do - task :preload => :environment + task preload: :environment task :setup do require 'resque' end - task :setup_schedule => :setup do + task setup_schedule: :setup do require 'resque-scheduler' # If you want to be able to dynamically change the schedule, @@ -30,5 +30,5 @@ namespace :resque do # require 'jobs' end - task :scheduler_setup => :setup_schedule -end \ No newline at end of file + task scheduler_setup: :setup_schedule +end diff --git a/spec/factories/schedules.rb b/spec/factories/schedules.rb index dbcf627..a1e1ce0 100644 --- a/spec/factories/schedules.rb +++ b/spec/factories/schedules.rb @@ -1,10 +1,9 @@ FactoryGirl.define do factory :schedule do - name "MyString" -description "MyText" -cron "MyString" -job_name "MyString" -user nil + name 'MyString' + description 'MyText' + cron 'MyString' + job_name 'MyString' + user nil end - end diff --git a/spec/models/schedule_spec.rb b/spec/models/schedule_spec.rb index e226ff8..776ecde 100644 --- a/spec/models/schedule_spec.rb +++ b/spec/models/schedule_spec.rb @@ -1,5 +1,5 @@ require 'rails_helper' -RSpec.describe Schedule, :type => :model do +RSpec.describe Schedule, type: :model do pending "add some examples to (or delete) #{__FILE__}" end From fd591b4c82b37d8fd0d341f78e72a615a547a17b Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 13 Dec 2015 03:52:08 +0900 Subject: [PATCH 264/358] create schedule rename api --- app/apis/api/v1/schedules.rb | 51 +++++++++++++++++++++++++++++++++--- 1 file changed, 48 insertions(+), 3 deletions(-) diff --git a/app/apis/api/v1/schedules.rb b/app/apis/api/v1/schedules.rb index 6eebfdb..0f9a630 100644 --- a/app/apis/api/v1/schedules.rb +++ b/app/apis/api/v1/schedules.rb @@ -345,7 +345,7 @@ def cron_check_value(value, index) else Resque.set_schedule("#{schedule.job_name}", class: 'ResqueInfraredSendJob', cron: schedule.cron, args: schedule) schedule.update(status: :active_schedule) - log = user.logs.create(name: "「#{schedule.name}」のスケジューラーを稼働しました", status: :robot_activate_schedule) + log = user.logs.create(name: "「#{schedule.name}」のスケジューラーを稼働しました", status: :activate_schedule) log.infrared = schedule.infrared @schedule = schedule end @@ -391,7 +391,52 @@ def cron_check_value(value, index) if schedule = user.schedules.find_by(id: params[:schedule_id]) Resque.remove_schedule(schedule.job_name) schedule.update(status: :inactive_schedule) - log = user.logs.create(name: "「#{schedule.name}」のスケジューラーを停止しました", status: :robot_remove_schedule) + log = user.logs.create(name: "「#{schedule.name}」のスケジューラーを停止しました", status: :remove_schedule) + log.infrared = schedule.infrared + @schedule = schedule + else + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.schedule_not_found'), + code: ErrorCodes::NOT_FOUND_SCHEDULE + ] + }, response: {}) + end + end + else + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.invalid_token'), + code: ErrorCodes::INVALID_TOKEN + ] + }, response: {}) + end + end + + desc 'スケジュールのリネーム', notes: <<-NOTE +

スケジュールをリネームします

+ NOTE + params do + requires :auth_token, type: String, desc: 'Auth token.' + requires :name, type: String, desc: 'Name.' + requires :schedule_id, type: Integer, desc: 'Schedule id' + end + put '/rename', jbuilder: 'api/v1/schedule/rename' do + if (token = AuthToken.find_by(token: params[:auth_token])) + if user.info.nil? + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.user_not_found'), + code: ErrorCodes::NOT_FOUND_USER + ] + }, response: {}) + else + if schedule = user.schedules.find_by(id: params[:schedule_id]) + schedule.update(name: params[:name]) + log = user.logs.create(name: "「スケジューラーを#{schedule.name}」にリネームしました", status: :update_schedule) log.infrared = schedule.infrared @schedule = schedule else @@ -470,7 +515,7 @@ def cron_check_value(value, index) infrared.schedule = schedule Resque.set_schedule("#{schedule.job_name}", { class: 'ResqueInfraredSendJob', cron: cron, args: schedule }) schedule.update(status: :active_schedule) - log = user.logs.create(name: "「#{schedule.name}」のスケジューラーを作成、稼働しました", status: :robot_create_schedule) + log = user.logs.create(name: "「#{schedule.name}」のスケジューラーを作成、稼働しました", status: :create_schedule) log.infrared = infrared @schedule = schedule @message = message From 9decbfc2163d884f36d5d0f1e0d625d4911bd002 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 13 Dec 2015 03:52:16 +0900 Subject: [PATCH 265/358] rename status log --- app/models/log.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/log.rb b/app/models/log.rb index 99d6aac..7bef3f8 100644 --- a/app/models/log.rb +++ b/app/models/log.rb @@ -1,5 +1,5 @@ class Log < ActiveRecord::Base belongs_to :user belongs_to :infrared, dependent: :destroy - enum status: %i(recieve_ir send_ir update_ir destroy_ir add_ir remove_ir robot_send_ir robot_remove_schedule robot_create_schedule robot_activate_schedule) + enum status: %i(recieve_ir send_ir update_ir destroy_ir add_ir remove_ir robot_send_ir remove_schedule create_schedule activate_schedule update_schedule) end From ce84b3fa2afd7af56766410d6cca1ddb9e919739 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 13 Dec 2015 03:52:23 +0900 Subject: [PATCH 266/358] create rename jbuilder --- app/views/apis/api/v1/schedule/rename.jbuilder | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 app/views/apis/api/v1/schedule/rename.jbuilder diff --git a/app/views/apis/api/v1/schedule/rename.jbuilder b/app/views/apis/api/v1/schedule/rename.jbuilder new file mode 100644 index 0000000..1df12a5 --- /dev/null +++ b/app/views/apis/api/v1/schedule/rename.jbuilder @@ -0,0 +1,7 @@ +json.meta do + json.status 200 + json.message "スケジューラーを「#{@schedule.name}」にリネームしました" +end +json.response do + json.schedule @schedule +end From d76a368b0042f0398be82e29a059e140dd5c3079 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 13 Dec 2015 04:15:36 +0900 Subject: [PATCH 267/358] add error code --- lib/error_codes.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/error_codes.rb b/lib/error_codes.rb index 071e0c8..dc27eb6 100644 --- a/lib/error_codes.rb +++ b/lib/error_codes.rb @@ -24,4 +24,5 @@ module ErrorCodes INVALID_CRON = 23 NOT_FOUND_SCHEDULE = 24 INVALID_PARAMS = 25 + NOT_ACTIVATE_SCHEDULE = 26 end From 1b3cb783b4e11dc65b168b4eea5908a01302ec1a Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 13 Dec 2015 04:15:46 +0900 Subject: [PATCH 268/358] create destroy jbuilder --- app/views/apis/api/v1/schedule/destroy.jbuilder | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 app/views/apis/api/v1/schedule/destroy.jbuilder diff --git a/app/views/apis/api/v1/schedule/destroy.jbuilder b/app/views/apis/api/v1/schedule/destroy.jbuilder new file mode 100644 index 0000000..481c2b6 --- /dev/null +++ b/app/views/apis/api/v1/schedule/destroy.jbuilder @@ -0,0 +1,6 @@ +json.meta do + json.status 200 + json.message 'スケジューラーを削除しました。' +end +json.response do +end From 028fc43002ee76c0666e441fc46b02fde7025e34 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 13 Dec 2015 04:15:54 +0900 Subject: [PATCH 269/358] add new status --- app/models/log.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/log.rb b/app/models/log.rb index 7bef3f8..c4334a3 100644 --- a/app/models/log.rb +++ b/app/models/log.rb @@ -1,5 +1,5 @@ class Log < ActiveRecord::Base belongs_to :user belongs_to :infrared, dependent: :destroy - enum status: %i(recieve_ir send_ir update_ir destroy_ir add_ir remove_ir robot_send_ir remove_schedule create_schedule activate_schedule update_schedule) + enum status: %i(recieve_ir send_ir update_ir destroy_ir add_ir remove_ir robot_send_ir remove_schedule create_schedule activate_schedule update_schedule delete_schedule) end From d01670266ca842560cfb5bb9b1c5503501396cae Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 13 Dec 2015 04:16:02 +0900 Subject: [PATCH 270/358] create delete api --- app/apis/api/v1/schedules.rb | 66 +++++++++++++++++++++++++++++++++--- 1 file changed, 61 insertions(+), 5 deletions(-) diff --git a/app/apis/api/v1/schedules.rb b/app/apis/api/v1/schedules.rb index 0f9a630..23e5fbb 100644 --- a/app/apis/api/v1/schedules.rb +++ b/app/apis/api/v1/schedules.rb @@ -389,11 +389,21 @@ def cron_check_value(value, index) }, response: {}) else if schedule = user.schedules.find_by(id: params[:schedule_id]) - Resque.remove_schedule(schedule.job_name) - schedule.update(status: :inactive_schedule) - log = user.logs.create(name: "「#{schedule.name}」のスケジューラーを停止しました", status: :remove_schedule) - log.infrared = schedule.infrared - @schedule = schedule + if schedule.active_schedule? + Resque.remove_schedule(schedule.job_name) + schedule.update(status: :inactive_schedule) + log = user.logs.create(name: "「#{schedule.name}」のスケジューラーを停止しました", status: :remove_schedule) + log.infrared = schedule.infrared + @schedule = schedule + else + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.schedule_not_activate'), + code: ErrorCodes::NOT_ACTIVATE_SCHEDULE + ] + }, response: {}) + end else error!(meta: { status: 400, @@ -548,6 +558,52 @@ def cron_check_value(value, index) }, response: {}) end end + + desc 'スケジュールの削除', notes: <<-NOTE +

スケジュールを削除します

+ NOTE + params do + requires :auth_token, type: String, desc: 'Auth token.' + requires :schedule_id, type: Integer, desc: 'Schedule id' + end + delete '/', jbuilder: 'api/v1/schedule/destroy' do + if (token = AuthToken.find_by(token: params[:auth_token])) + if user.info.nil? + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.user_not_found'), + code: ErrorCodes::NOT_FOUND_USER + ] + }, response: {}) + else + if schedule = user.schedules.find_by(id: params[:schedule_id]) + if schedule.active_schedule? + Resque.remove_schedule(schedule.job_name) + end + schedule.destroy + log = user.logs.create(name: "「#{schedule.name}」のスケジューラーを削除しました", status: :delete_schedule) + log.infrared = schedule.infrared + else + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.schedule_not_found'), + code: ErrorCodes::NOT_FOUND_SCHEDULE + ] + }, response: {}) + end + end + else + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.invalid_token'), + code: ErrorCodes::INVALID_TOKEN + ] + }, response: {}) + end + end end end end From b510b6f36cc1cefb45c0a5d1b7d38674c1519a52 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 13 Dec 2015 04:31:51 +0900 Subject: [PATCH 271/358] congraduration 400 commits ! --- README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/README.md b/README.md index 3948ad9..e0f13cd 100644 --- a/README.md +++ b/README.md @@ -92,7 +92,19 @@ cron形式でデータを渡す時の値の諸々 30 5 1,15 * *       1日と 15日の 5:30に実行 ``` +## デバッグに関して +### APIのテスト用ページ + +```sh + SITE_URL/api/swagger +``` + +### Resque Schedulerのログページ + +```sh + SITE_URL/resque +``` ## その他 From afdbd210569141c6c5c59433d16480b3763468a3 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 13 Dec 2015 04:41:03 +0900 Subject: [PATCH 272/358] bundle exec erd --- erd.pdf | Bin 33988 -> 35091 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/erd.pdf b/erd.pdf index 9f83264356d1401dd52b52e687e1b8bb03bbaa70..4f8cd7164ef9f872a6c635e44b560173cfa3d113 100644 GIT binary patch delta 26107 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 N3zd#eMokv={{ZaHJk|gJ delta 24997 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 Date: Sun, 13 Dec 2015 05:56:21 +0900 Subject: [PATCH 273/358] create schedule cron translator api --- app/apis/api/v1/schedules.rb | 99 ++++++++++++++++++++---------------- 1 file changed, 54 insertions(+), 45 deletions(-) diff --git a/app/apis/api/v1/schedules.rb b/app/apis/api/v1/schedules.rb index 23e5fbb..8c46b37 100644 --- a/app/apis/api/v1/schedules.rb +++ b/app/apis/api/v1/schedules.rb @@ -21,6 +21,35 @@ def invalid_cron }, response: {}) end + def cron_translator(array) + translation = '' + isEveryWord = false + if array.size == 5 + array.each_with_index do |c, index| + if cron_check_value(c, index).to_s.include?('毎') + if isEveryWord + else + isEveryWord = true + translation = cron_check_value(c, index).to_s + translation + end + else + if index == 4 && array[4] != '*' + translation.gsub!(/毎日/u, '') + translation.gsub!(/毎月/u, '') + translation = cron_check_value(c, index).to_s + translation + translation.gsub!(/曜日の/u, '曜日と') if array[2] != '*' + else + translation = cron_check_value(c, index).to_s + translation + end + end + end + translation.gsub!(/時毎分/u, '時に毎分') + translation += '実行します' + return translation + else + invalid_cron + end + end def cron_check_value(value, index) if value =~ /^(([0-9]+)((\,||\-||\/)[0-9]+)*||\*(\/[0-9]+)?)$/ if integer_string?(value) || value == '*' @@ -260,12 +289,24 @@ def cron_check_value(value, index) end resource :schedule do + desc 'cronの翻訳を取得する', notes: <<-NOTE +

cronの翻訳を取得します

+ NOTE + params do + requires :cron, type: String, desc: 'cron.' + end + get '/cron_translator', jbuilder: 'api/v1/schedule/cron_translator' do + array = params[:cron].split(' ') + @translation = cron_translator(array) + end + desc 'スケジュール一覧を取得する', notes: <<-NOTE

スケジュール一覧を取得します

null ・・・ すべてのスケジュールの取得
0 ・・・ 稼働してないスケジュールの取得
1 ・・・ 稼働しているスケジュールの取得 +

NOTE params do requires :auth_token, type: String, desc: 'Auth token.' @@ -478,9 +519,9 @@ def cron_check_value(value, index) NOTE params do requires :auth_token, type: String, desc: 'Auth token.' - requires :ir_id, type: Integer, desc: 'Auth token.' - requires :name, type: String, desc: 'Auth token.' - requires :cron, type: String, desc: 'Auth token.' + requires :ir_id, type: Integer, desc: 'infrared id.' + requires :name, type: String, desc: 'name.' + requires :cron, type: String, desc: 'cron.' end post '/', jbuilder: 'api/v1/schedule/create' do if (token = AuthToken.find_by(token: params[:auth_token])) @@ -496,48 +537,16 @@ def cron_check_value(value, index) if (infrared = Infrared.find_by(id: params[:ir_id])) cron = params[:cron] cron_a = cron.split(' ') - message = ' ' - isEveryWord = false - if cron_a.size == 5 - cron_a.each_with_index do |c, index| - if cron_check_value(c, index).to_s.include?('毎') - if isEveryWord - else - isEveryWord = true - message = cron_check_value(c, index).to_s + message - end - else - if index == 4 && cron_a[4] != '*' - message.gsub!(/毎日/u, '') - message.gsub!(/毎月/u, '') - message = cron_check_value(c, index).to_s + message - message.gsub!(/曜日の/u, '曜日と') if cron_a[2] != '*' - else - message = cron_check_value(c, index).to_s + message - end - end - end - message.gsub!(/時毎分/u, '時に毎分') - message += '実行します' - schedule = user.schedules.create(name: params[:name], cron: params[:cron]) - cron = params[:cron] - schedule.update(description: "#{message}", cron: "#{cron}", job_name: "schedule_#{user.id}_#{schedule.id}") - infrared.schedule = schedule - Resque.set_schedule("#{schedule.job_name}", { class: 'ResqueInfraredSendJob', cron: cron, args: schedule }) - schedule.update(status: :active_schedule) - log = user.logs.create(name: "「#{schedule.name}」のスケジューラーを作成、稼働しました", status: :create_schedule) - log.infrared = infrared - @schedule = schedule - @message = message - else - error!(meta: { - status: 400, - errors: [ - message: ('errors.messages.invalid_cron'), - code: ErrorCodes::INVALID_CRON - ] - }, response: {}) - end + translation = cron_translator(cron_a) + schedule = user.schedules.create(name: params[:name], cron: params[:cron]) + cron = params[:cron] + schedule.update(description: "#{translation}", cron: "#{cron}", job_name: "schedule_#{user.id}_#{schedule.id}") + infrared.schedule = schedule + Resque.set_schedule("#{schedule.job_name}", { class: 'ResqueInfraredSendJob', cron: cron, args: schedule }) + schedule.update(status: :active_schedule) + log = user.logs.create(name: "「#{schedule.name}」のスケジューラーを作成、稼働しました", status: :create_schedule) + log.infrared = infrared + @schedule = schedule else error!(meta: { status: 400, From 1b27368e32299575a60f6c4578b3b3f7e03892bc Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 13 Dec 2015 05:56:34 +0900 Subject: [PATCH 274/358] create translate jbuilder --- app/views/apis/api/v1/schedule/cron_translator.jbuilder | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 app/views/apis/api/v1/schedule/cron_translator.jbuilder diff --git a/app/views/apis/api/v1/schedule/cron_translator.jbuilder b/app/views/apis/api/v1/schedule/cron_translator.jbuilder new file mode 100644 index 0000000..595c407 --- /dev/null +++ b/app/views/apis/api/v1/schedule/cron_translator.jbuilder @@ -0,0 +1,7 @@ +json.meta do + json.status 200 + json.message 'cronを翻訳しました' +end +json.response do + json.translation @translation +end From 387af335e9d6f8fb0775c80e378da553a6a9177e Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 13 Dec 2015 06:31:33 +0900 Subject: [PATCH 275/358] rails g migration RemoveReferenceToLogs infrared:references --- db/migrate/20151212213102_remove_reference_to_logs.rb | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 db/migrate/20151212213102_remove_reference_to_logs.rb diff --git a/db/migrate/20151212213102_remove_reference_to_logs.rb b/db/migrate/20151212213102_remove_reference_to_logs.rb new file mode 100644 index 0000000..52f9ebb --- /dev/null +++ b/db/migrate/20151212213102_remove_reference_to_logs.rb @@ -0,0 +1,5 @@ +class RemoveReferenceToLogs < ActiveRecord::Migration + def change + remove_reference :logs, :infrared, index: true, foreign_key: true + end +end From 4fce79ae2bfae690b440c5242f8cdbe7f8b63599 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 13 Dec 2015 06:31:41 +0900 Subject: [PATCH 276/358] rake db:migrate --- db/schema.rb | 128 ++++++++++++++++++++++++++------------------------- 1 file changed, 65 insertions(+), 63 deletions(-) diff --git a/db/schema.rb b/db/schema.rb index 0757fce..2f9f33b 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,87 +11,89 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20_151_212_163_400) do - create_table 'auth_tokens', force: :cascade do |t| - t.string 'token' - t.integer 'user_id' - t.datetime 'created_at', null: false - t.datetime 'updated_at', null: false +ActiveRecord::Schema.define(version: 20151212213102) do + + create_table "auth_tokens", force: :cascade do |t| + t.string "token" + t.integer "user_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end - add_index 'auth_tokens', ['user_id'], name: 'index_auth_tokens_on_user_id' + add_index "auth_tokens", ["user_id"], name: "index_auth_tokens_on_user_id" - create_table 'infrared_groups', force: :cascade do |t| - t.string 'name' - t.integer 'user_id' - t.datetime 'created_at', null: false - t.datetime 'updated_at', null: false + create_table "infrared_groups", force: :cascade do |t| + t.string "name" + t.integer "user_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end - add_index 'infrared_groups', ['user_id'], name: 'index_infrared_groups_on_user_id' + add_index "infrared_groups", ["user_id"], name: "index_infrared_groups_on_user_id" - create_table 'infrared_relationals', force: :cascade do |t| - t.integer 'infrared_id' - t.integer 'infrared_group_id' - t.datetime 'created_at', null: false - t.datetime 'updated_at', null: false + create_table "infrared_relationals", force: :cascade do |t| + t.integer "infrared_id" + t.integer "infrared_group_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end - add_index 'infrared_relationals', ['infrared_group_id'], name: 'index_infrared_relationals_on_infrared_group_id' - add_index 'infrared_relationals', ['infrared_id'], name: 'index_infrared_relationals_on_infrared_id' + add_index "infrared_relationals", ["infrared_group_id"], name: "index_infrared_relationals_on_infrared_group_id" + add_index "infrared_relationals", ["infrared_id"], name: "index_infrared_relationals_on_infrared_id" - create_table 'infrareds', force: :cascade do |t| - t.string 'name' - t.string 'data' - t.integer 'user_id' - t.datetime 'created_at', null: false - t.datetime 'updated_at', null: false - t.integer 'count', default: 0 + create_table "infrareds", force: :cascade do |t| + t.string "name" + t.string "data" + t.integer "user_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.integer "count", default: 0 end - add_index 'infrareds', ['user_id'], name: 'index_infrareds_on_user_id' + add_index "infrareds", ["user_id"], name: "index_infrareds_on_user_id" - create_table 'logs', force: :cascade do |t| - t.integer 'user_id' - t.integer 'infrared_id' - t.datetime 'created_at', null: false - t.datetime 'updated_at', null: false - t.string 'name' - t.integer 'status' + create_table "logs", force: :cascade do |t| + t.integer "user_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.string "name" + t.integer "status" + t.integer "schedule_id" end - add_index 'logs', ['infrared_id'], name: 'index_logs_on_infrared_id' - add_index 'logs', ['user_id'], name: 'index_logs_on_user_id' - - create_table 'schedules', force: :cascade do |t| - t.string 'name' - t.text 'description' - t.string 'cron' - t.string 'job_name' - t.integer 'user_id' - t.integer 'infrared_id' - t.datetime 'created_at', null: false - t.datetime 'updated_at', null: false - t.integer 'status' + add_index "logs", ["schedule_id"], name: "index_logs_on_schedule_id" + add_index "logs", ["user_id"], name: "index_logs_on_user_id" + + create_table "schedules", force: :cascade do |t| + t.string "name" + t.text "description" + t.string "cron" + t.string "job_name" + t.integer "user_id" + t.integer "infrared_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.integer "status" end - add_index 'schedules', ['infrared_id'], name: 'index_schedules_on_infrared_id' - add_index 'schedules', ['user_id'], name: 'index_schedules_on_user_id' - - create_table 'user_infos', force: :cascade do |t| - t.string 'screen_name' - t.string 'hashed_password' - t.string 'email' - t.string 'email_for_index' - t.integer 'user_id' - t.datetime 'created_at', null: false - t.datetime 'updated_at', null: false + add_index "schedules", ["infrared_id"], name: "index_schedules_on_infrared_id" + add_index "schedules", ["user_id"], name: "index_schedules_on_user_id" + + create_table "user_infos", force: :cascade do |t| + t.string "screen_name" + t.string "hashed_password" + t.string "email" + t.string "email_for_index" + t.integer "user_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end - add_index 'user_infos', ['user_id'], name: 'index_user_infos_on_user_id' + add_index "user_infos", ["user_id"], name: "index_user_infos_on_user_id" - create_table 'users', force: :cascade do |t| - t.datetime 'created_at', null: false - t.datetime 'updated_at', null: false + create_table "users", force: :cascade do |t| + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end + end From d1d5d5bd2aecf2a19b04e9586c1e660ea6552440 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 13 Dec 2015 06:33:51 +0900 Subject: [PATCH 277/358] rails g migration AddReferenceToLogs loggable:references --- db/migrate/20151212213313_add_reference_to_logs.rb | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 db/migrate/20151212213313_add_reference_to_logs.rb diff --git a/db/migrate/20151212213313_add_reference_to_logs.rb b/db/migrate/20151212213313_add_reference_to_logs.rb new file mode 100644 index 0000000..fb1c104 --- /dev/null +++ b/db/migrate/20151212213313_add_reference_to_logs.rb @@ -0,0 +1,5 @@ +class AddReferenceToLogs < ActiveRecord::Migration + def change + add_reference :logs, :loggable, index: true, foreign_key: true + end +end From 4fba61a087612b09badfa60b93f0556832d576a2 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 13 Dec 2015 06:33:59 +0900 Subject: [PATCH 278/358] rake db:migrate --- db/schema.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/db/schema.rb b/db/schema.rb index 2f9f33b..99d2af0 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20151212213102) do +ActiveRecord::Schema.define(version: 20151212213313) do create_table "auth_tokens", force: :cascade do |t| t.string "token" @@ -59,8 +59,10 @@ t.string "name" t.integer "status" t.integer "schedule_id" + t.integer "loggable_id" end + add_index "logs", ["loggable_id"], name: "index_logs_on_loggable_id" add_index "logs", ["schedule_id"], name: "index_logs_on_schedule_id" add_index "logs", ["user_id"], name: "index_logs_on_user_id" From 0fa99ba110b396681eb219f5a950074eeed2b81f Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 13 Dec 2015 06:39:52 +0900 Subject: [PATCH 279/358] add relation --- app/models/infrared.rb | 2 +- app/models/log.rb | 2 +- app/models/schedule.rb | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/models/infrared.rb b/app/models/infrared.rb index 349b241..3508cd9 100644 --- a/app/models/infrared.rb +++ b/app/models/infrared.rb @@ -1,7 +1,7 @@ class Infrared < ActiveRecord::Base belongs_to :user - has_many :logs has_many :infrared_relationals has_many :infrared_groups, through: :infrared_relationals + has_many :logs, as: :loggable has_one :schedule end diff --git a/app/models/log.rb b/app/models/log.rb index c4334a3..72d341c 100644 --- a/app/models/log.rb +++ b/app/models/log.rb @@ -1,5 +1,5 @@ class Log < ActiveRecord::Base belongs_to :user - belongs_to :infrared, dependent: :destroy + belongs_to :loggable, polymorphic: true, dependent: :destroy enum status: %i(recieve_ir send_ir update_ir destroy_ir add_ir remove_ir robot_send_ir remove_schedule create_schedule activate_schedule update_schedule delete_schedule) end diff --git a/app/models/schedule.rb b/app/models/schedule.rb index 48652c1..4307fc3 100644 --- a/app/models/schedule.rb +++ b/app/models/schedule.rb @@ -1,5 +1,6 @@ class Schedule < ActiveRecord::Base belongs_to :user belongs_to :infrared + has_many :logs, as: :loggable enum status: %i(inactive_schedule active_schedule) end From 7df15421ccd930fb75ab20418657c4da239bdbf0 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 13 Dec 2015 06:40:03 +0900 Subject: [PATCH 280/358] bundle exec erd.pdf --- erd.pdf | Bin 35091 -> 35347 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/erd.pdf b/erd.pdf index 4f8cd7164ef9f872a6c635e44b560173cfa3d113..22d948522803067c8c6c53a088c1364d8e761790 100644 GIT binary patch delta 20842 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 From 86d55ac60ea8ab8baae965fd40b9e6c89bb043be Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 13 Dec 2015 06:41:05 +0900 Subject: [PATCH 281/358] rails g migration AddColumnToLogs loggable_type:string --- db/migrate/20151212214054_add_column_to_logs.rb | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 db/migrate/20151212214054_add_column_to_logs.rb diff --git a/db/migrate/20151212214054_add_column_to_logs.rb b/db/migrate/20151212214054_add_column_to_logs.rb new file mode 100644 index 0000000..4c6e0d0 --- /dev/null +++ b/db/migrate/20151212214054_add_column_to_logs.rb @@ -0,0 +1,5 @@ +class AddColumnToLogs < ActiveRecord::Migration + def change + add_column :logs, :loggable_type, :string + end +end From b27f4037247288e75b43b2f69f70edbefc5f2d25 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 13 Dec 2015 06:41:14 +0900 Subject: [PATCH 282/358] rake db:migrate --- db/schema.rb | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/db/schema.rb b/db/schema.rb index 99d2af0..f5c1e39 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20151212213313) do +ActiveRecord::Schema.define(version: 20151212214054) do create_table "auth_tokens", force: :cascade do |t| t.string "token" @@ -54,12 +54,13 @@ create_table "logs", force: :cascade do |t| t.integer "user_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.string "name" t.integer "status" t.integer "schedule_id" t.integer "loggable_id" + t.string "loggable_type" end add_index "logs", ["loggable_id"], name: "index_logs_on_loggable_id" From 2f291e7355afdc7ef954f14a322e5efc3c979b4c Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 13 Dec 2015 13:25:23 +0900 Subject: [PATCH 283/358] update --- commands/recieve.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commands/recieve.c b/commands/recieve.c index 43f6033..877866a 100644 --- a/commands/recieve.c +++ b/commands/recieve.c @@ -124,7 +124,7 @@ int getActivateTime(int status) start = getTime(); while( digitalRead(pin) == status ) { - delayMicroseconds(span); + delayMicroseconds(span); count++; if(count > max){ break; } } From 9375a31886e2085eb98f868c8de853d214a68225 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 13 Dec 2015 13:25:36 +0900 Subject: [PATCH 284/358] add polymorephic relation --- app/models/user.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/models/user.rb b/app/models/user.rb index 556eeb4..1770a29 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -5,4 +5,6 @@ class User < ActiveRecord::Base has_many :infrareds has_many :infrared_groups has_many :logs, dependent: :destroy + has_many :infrared_logs, through: :logs, source: :loggable, source_type: 'Infrared' + has_many :schedule_logs, through: :logs, source: :loggable, source_type: 'Schedule' end From e4ab46f45f193acab9c6326aa4f677928b918658 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 13 Dec 2015 14:09:46 +0900 Subject: [PATCH 285/358] update --- app/apis/api/v1/infrared_group.rb | 4 ++-- app/apis/api/v1/ir.rb | 8 ++++---- app/apis/api/v1/schedules.rb | 10 +++++----- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/app/apis/api/v1/infrared_group.rb b/app/apis/api/v1/infrared_group.rb index d17dceb..0c4404c 100644 --- a/app/apis/api/v1/infrared_group.rb +++ b/app/apis/api/v1/infrared_group.rb @@ -190,7 +190,7 @@ class InfraredGroup < Grape::API if !group.infrareds.find_by(id: params[:ir_id]) group.infrareds << infrared log = user.logs.create(name: "「#{infrared.name}」を「#{group.name}」に追加しました", status: :add_ir) - log.infrared = infrared + infrared.logs << log @group = group @infrared = infrared else @@ -261,7 +261,7 @@ class InfraredGroup < Grape::API @infrared = infrared relational.destroy log = user.logs.create(name: "「#{infrared.name}」を「#{group.name}」から削除しました", status: :remove_ir) - log.infrared = infrared + infrared.logs << log else error!(meta: { status: 400, diff --git a/app/apis/api/v1/ir.rb b/app/apis/api/v1/ir.rb index 6968fa9..ef91796 100644 --- a/app/apis/api/v1/ir.rb +++ b/app/apis/api/v1/ir.rb @@ -76,7 +76,7 @@ class IR < Grape::API end infrared.update(data: "#{fname}") log = user.logs.create(name: '赤外線を受信しました', status: :recieve_ir) - log.infrared = infrared + infrared.logs << log unless params[:group_id].nil? if group = user.infrared_groups.find_by(id: params[:group_id]) group.infrareds << infrared @@ -133,7 +133,7 @@ class IR < Grape::API count = infrared.count + 1 infrared.update(count: count) log = user.logs.create(name: "「#{infrared.name}」を実行しました", status: :send_ir) - log.infrared = infrared + infrared.logs << log @infrared = infrared else error!(meta: { @@ -180,7 +180,7 @@ class IR < Grape::API if infrared = user.infrareds.find_by(id: params[:ir_id]) infrared.update(name: params[:name]) log = user.logs.create(name: "「#{infrared.name}」に名前を変更しました", status: :update_ir) - log.infrared = infrared + infrared.logs << log @infrared = infrared else error!(meta: { @@ -228,7 +228,7 @@ class IR < Grape::API file = Rails.root.to_s + '/data/' + name File.delete file log = user.logs.create(name: "「#{infrared.name}」を削除しました", status: :destroy_ir) - log.infrared = infrared + infrared.logs << log infrared.destroy else error!(meta: { diff --git a/app/apis/api/v1/schedules.rb b/app/apis/api/v1/schedules.rb index 8c46b37..1b70031 100644 --- a/app/apis/api/v1/schedules.rb +++ b/app/apis/api/v1/schedules.rb @@ -387,7 +387,7 @@ def cron_check_value(value, index) Resque.set_schedule("#{schedule.job_name}", class: 'ResqueInfraredSendJob', cron: schedule.cron, args: schedule) schedule.update(status: :active_schedule) log = user.logs.create(name: "「#{schedule.name}」のスケジューラーを稼働しました", status: :activate_schedule) - log.infrared = schedule.infrared + schedule.logs << log @schedule = schedule end else @@ -434,7 +434,7 @@ def cron_check_value(value, index) Resque.remove_schedule(schedule.job_name) schedule.update(status: :inactive_schedule) log = user.logs.create(name: "「#{schedule.name}」のスケジューラーを停止しました", status: :remove_schedule) - log.infrared = schedule.infrared + schedule.logs << log @schedule = schedule else error!(meta: { @@ -488,7 +488,7 @@ def cron_check_value(value, index) if schedule = user.schedules.find_by(id: params[:schedule_id]) schedule.update(name: params[:name]) log = user.logs.create(name: "「スケジューラーを#{schedule.name}」にリネームしました", status: :update_schedule) - log.infrared = schedule.infrared + schedule.logs << log @schedule = schedule else error!(meta: { @@ -545,7 +545,7 @@ def cron_check_value(value, index) Resque.set_schedule("#{schedule.job_name}", { class: 'ResqueInfraredSendJob', cron: cron, args: schedule }) schedule.update(status: :active_schedule) log = user.logs.create(name: "「#{schedule.name}」のスケジューラーを作成、稼働しました", status: :create_schedule) - log.infrared = infrared + schedule.logs << log @schedule = schedule else error!(meta: { @@ -592,7 +592,7 @@ def cron_check_value(value, index) end schedule.destroy log = user.logs.create(name: "「#{schedule.name}」のスケジューラーを削除しました", status: :delete_schedule) - log.infrared = schedule.infrared + schedule.logs << log else error!(meta: { status: 400, From c118c6470b9aa1b6a26f7ac868a540e117d5fa37 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 13 Dec 2015 14:32:05 +0900 Subject: [PATCH 286/358] rake db:migrate --- db/schema.rb | 2 -- 1 file changed, 2 deletions(-) diff --git a/db/schema.rb b/db/schema.rb index f5c1e39..eb90d73 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -58,13 +58,11 @@ t.datetime "updated_at", null: false t.string "name" t.integer "status" - t.integer "schedule_id" t.integer "loggable_id" t.string "loggable_type" end add_index "logs", ["loggable_id"], name: "index_logs_on_loggable_id" - add_index "logs", ["schedule_id"], name: "index_logs_on_schedule_id" add_index "logs", ["user_id"], name: "index_logs_on_user_id" create_table "schedules", force: :cascade do |t| From f98e04c2a3848a1fe4fd009cbf32ed6855ffad7f Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 13 Dec 2015 14:34:37 +0900 Subject: [PATCH 287/358] gem kakurenbo-puti --- Gemfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Gemfile b/Gemfile index e3f651b..347eaea 100644 --- a/Gemfile +++ b/Gemfile @@ -41,6 +41,7 @@ gem 'redis' gem 'resque' gem 'resque-scheduler' gem 'rubocop', group: :development +gem 'kakurenbo-puti' group :development, :test do gem 'byebug' From f9dea8edb57268d817025f7c4af8ede3a9aec739 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 13 Dec 2015 14:34:45 +0900 Subject: [PATCH 288/358] bundle install --- Gemfile.lock | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Gemfile.lock b/Gemfile.lock index 4804ad9..4f256fa 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -135,6 +135,8 @@ GEM thor (>= 0.14, < 2.0) json (1.8.3) json_expressions (0.8.3) + kakurenbo-puti (0.1.0) + activerecord (>= 4.1.0) libv8 (3.16.14.13) loofah (2.0.3) nokogiri (>= 1.5.9) @@ -331,6 +333,7 @@ DEPENDENCIES jbuilder (~> 2.0) jquery-rails json_expressions + kakurenbo-puti pry-byebug pry-doc pry-rails From 1db1c84b7efbd7fc740d597d2ac2d144a8d6dfa7 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 13 Dec 2015 14:42:51 +0900 Subject: [PATCH 289/358] :bug: rename recieve -> receive --- README.md | 2 +- app/apis/api/v1/ir.rb | 6 +++--- app/models/log.rb | 2 +- .../apis/api/v1/ir/{recieve.jbuilder => receive.jbuilder} | 0 4 files changed, 5 insertions(+), 5 deletions(-) rename app/views/apis/api/v1/ir/{recieve.jbuilder => receive.jbuilder} (100%) diff --git a/README.md b/README.md index e0f13cd..722fa6d 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ circleCIでテストを動かして通らない場合はプルリクを受け付 ### 受信コマンドコンパイル ```sh -$ sudo gcc recieve.c -o recieve -lwiringPi +$ sudo gcc receive.c -o receive -lwiringPi ``` ### 送信コマンドコンパイル diff --git a/app/apis/api/v1/ir.rb b/app/apis/api/v1/ir.rb index ef91796..7017242 100644 --- a/app/apis/api/v1/ir.rb +++ b/app/apis/api/v1/ir.rb @@ -48,7 +48,7 @@ class IR < Grape::API requires :auth_token, type: String, desc: 'Auth token.' optional :group_id, type: Integer, desc: 'Group ID.' end - post '/recieve', jbuilder: 'api/v1/ir/recieve' do + post '/receive', jbuilder: 'api/v1/ir/receive' do if (token = AuthToken.find_by(token: params[:auth_token])) if user.info.nil? error!(meta: { @@ -61,7 +61,7 @@ class IR < Grape::API else infrared = user.infrareds.create(name: '名無しの赤外線', data: '') path = Rails.root.to_s - command = File.join(path, 'commands/recieve') + command = File.join(path, 'commands/receive') fname = "user_#{user.id}_ir_#{infrared.id}.txt" `#{command} #{path}/data/#{fname}` if File.read("#{path}/data/#{fname}").size == 0 @@ -75,7 +75,7 @@ class IR < Grape::API }, response: {}) end infrared.update(data: "#{fname}") - log = user.logs.create(name: '赤外線を受信しました', status: :recieve_ir) + log = user.logs.create(name: '赤外線を受信しました', status: :receive_ir) infrared.logs << log unless params[:group_id].nil? if group = user.infrared_groups.find_by(id: params[:group_id]) diff --git a/app/models/log.rb b/app/models/log.rb index 72d341c..f84161a 100644 --- a/app/models/log.rb +++ b/app/models/log.rb @@ -1,5 +1,5 @@ class Log < ActiveRecord::Base belongs_to :user belongs_to :loggable, polymorphic: true, dependent: :destroy - enum status: %i(recieve_ir send_ir update_ir destroy_ir add_ir remove_ir robot_send_ir remove_schedule create_schedule activate_schedule update_schedule delete_schedule) + enum status: %i(receive_ir send_ir update_ir destroy_ir add_ir remove_ir robot_send_ir remove_schedule create_schedule activate_schedule update_schedule delete_schedule) end diff --git a/app/views/apis/api/v1/ir/recieve.jbuilder b/app/views/apis/api/v1/ir/receive.jbuilder similarity index 100% rename from app/views/apis/api/v1/ir/recieve.jbuilder rename to app/views/apis/api/v1/ir/receive.jbuilder From e34e9df4649fb94a3b53b69dfee60f82b039d709 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 13 Dec 2015 14:44:49 +0900 Subject: [PATCH 290/358] rails g migration AddSoftDestroyedToUsers soft_destroyed_at:datetime:index --- db/migrate/20151213054438_add_soft_destroyed_to_users.rb | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 db/migrate/20151213054438_add_soft_destroyed_to_users.rb diff --git a/db/migrate/20151213054438_add_soft_destroyed_to_users.rb b/db/migrate/20151213054438_add_soft_destroyed_to_users.rb new file mode 100644 index 0000000..5402fe4 --- /dev/null +++ b/db/migrate/20151213054438_add_soft_destroyed_to_users.rb @@ -0,0 +1,6 @@ +class AddSoftDestroyedToUsers < ActiveRecord::Migration + def change + add_column :users, :soft_destroyed_at, :datetime + add_index :users, :soft_destroyed_at + end +end From f13237c10d10f8add7936316c2b1df10ce99ccc0 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 13 Dec 2015 14:48:16 +0900 Subject: [PATCH 291/358] rake db:migrate --- db/schema.rb | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/db/schema.rb b/db/schema.rb index eb90d73..dd78eea 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20151212214054) do +ActiveRecord::Schema.define(version: 20151213054438) do create_table "auth_tokens", force: :cascade do |t| t.string "token" @@ -93,8 +93,11 @@ add_index "user_infos", ["user_id"], name: "index_user_infos_on_user_id" create_table "users", force: :cascade do |t| - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.datetime "soft_destroyed_at" end + add_index "users", ["soft_destroyed_at"], name: "index_users_on_soft_destroyed_at" + end From 69c59c71ff6bc67eabff73a8458f97b6251423cf Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 13 Dec 2015 14:49:16 +0900 Subject: [PATCH 292/358] rails g migration AddSoftDestroyedToInfrareds soft_destroyed_at:datetime:index --- .../20151213054854_add_soft_destroyed_to_infrareds.rb | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 db/migrate/20151213054854_add_soft_destroyed_to_infrareds.rb diff --git a/db/migrate/20151213054854_add_soft_destroyed_to_infrareds.rb b/db/migrate/20151213054854_add_soft_destroyed_to_infrareds.rb new file mode 100644 index 0000000..9b5148f --- /dev/null +++ b/db/migrate/20151213054854_add_soft_destroyed_to_infrareds.rb @@ -0,0 +1,6 @@ +class AddSoftDestroyedToInfrareds < ActiveRecord::Migration + def change + add_column :infrareds, :soft_destroyed_at, :datetime + add_index :infrareds, :soft_destroyed_at + end +end From 1d82d5768bbae253c315595f885e36b3d72ab84f Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 13 Dec 2015 14:49:25 +0900 Subject: [PATCH 293/358] rake db:migrate --- db/schema.rb | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/db/schema.rb b/db/schema.rb index dd78eea..fef5cfc 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20151213054438) do +ActiveRecord::Schema.define(version: 20151213054854) do create_table "auth_tokens", force: :cascade do |t| t.string "token" @@ -45,11 +45,13 @@ t.string "name" t.string "data" t.integer "user_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.integer "count", default: 0 + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.integer "count", default: 0 + t.datetime "soft_destroyed_at" end + add_index "infrareds", ["soft_destroyed_at"], name: "index_infrareds_on_soft_destroyed_at" add_index "infrareds", ["user_id"], name: "index_infrareds_on_user_id" create_table "logs", force: :cascade do |t| From b59717ee31d85285ec7768b60d75158fe4ace2e4 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 13 Dec 2015 14:50:21 +0900 Subject: [PATCH 294/358] rails g migration AddSoftDestroyedToSchedules soft_destroyed_at:datetime:index --- .../20151213055014_add_soft_destroyed_to_schedules.rb | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 db/migrate/20151213055014_add_soft_destroyed_to_schedules.rb diff --git a/db/migrate/20151213055014_add_soft_destroyed_to_schedules.rb b/db/migrate/20151213055014_add_soft_destroyed_to_schedules.rb new file mode 100644 index 0000000..bc0f5f6 --- /dev/null +++ b/db/migrate/20151213055014_add_soft_destroyed_to_schedules.rb @@ -0,0 +1,6 @@ +class AddSoftDestroyedToSchedules < ActiveRecord::Migration + def change + add_column :schedules, :soft_destroyed_at, :datetime + add_index :schedules, :soft_destroyed_at + end +end From e18226c8598667e361d5688ab045dfad2994ae2f Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 13 Dec 2015 14:50:40 +0900 Subject: [PATCH 295/358] rake db:migrate --- db/schema.rb | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/db/schema.rb b/db/schema.rb index fef5cfc..a79696c 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20151213054854) do +ActiveRecord::Schema.define(version: 20151213055014) do create_table "auth_tokens", force: :cascade do |t| t.string "token" @@ -74,12 +74,14 @@ t.string "job_name" t.integer "user_id" t.integer "infrared_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.integer "status" + t.datetime "soft_destroyed_at" end add_index "schedules", ["infrared_id"], name: "index_schedules_on_infrared_id" + add_index "schedules", ["soft_destroyed_at"], name: "index_schedules_on_soft_destroyed_at" add_index "schedules", ["user_id"], name: "index_schedules_on_user_id" create_table "user_infos", force: :cascade do |t| From 54956304fd9a91898bd56bc0d4e82f4e315dd694 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 13 Dec 2015 15:06:47 +0900 Subject: [PATCH 296/358] add model soft deletable --- app/models/infrared.rb | 3 +++ app/models/schedule.rb | 4 ++++ app/models/user.rb | 2 ++ app/models/user_info.rb | 1 + 4 files changed, 10 insertions(+) diff --git a/app/models/infrared.rb b/app/models/infrared.rb index 3508cd9..b781ee0 100644 --- a/app/models/infrared.rb +++ b/app/models/infrared.rb @@ -1,7 +1,10 @@ class Infrared < ActiveRecord::Base + soft_deletable + belongs_to :user has_many :infrared_relationals has_many :infrared_groups, through: :infrared_relationals has_many :logs, as: :loggable has_one :schedule + soft_deletable dependent_associations: [:user] end diff --git a/app/models/schedule.rb b/app/models/schedule.rb index 4307fc3..c9085e1 100644 --- a/app/models/schedule.rb +++ b/app/models/schedule.rb @@ -1,6 +1,10 @@ class Schedule < ActiveRecord::Base + soft_deletable + belongs_to :user belongs_to :infrared has_many :logs, as: :loggable enum status: %i(inactive_schedule active_schedule) + soft_deletable dependent_associations: [:user] + soft_deletable dependent_associations: [:infrared] end diff --git a/app/models/user.rb b/app/models/user.rb index 1770a29..e68afa4 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,4 +1,6 @@ class User < ActiveRecord::Base + soft_deletable + has_many :auth_tokens, dependent: :destroy has_one :info, class_name: 'UserInfo', dependent: :destroy has_many :schedules, dependent: :destroy diff --git a/app/models/user_info.rb b/app/models/user_info.rb index 091be98..b7f4594 100644 --- a/app/models/user_info.rb +++ b/app/models/user_info.rb @@ -1,4 +1,5 @@ class UserInfo < ActiveRecord::Base + soft_deletable dependent_associations: [:user] belongs_to :user before_validation do From 066de9ce937b4608ad1a0602edf2023e345b8e9d Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 13 Dec 2015 15:07:10 +0900 Subject: [PATCH 297/358] soft_destroy --- app/apis/api/v1/ir.rb | 4 ++-- app/apis/api/v1/schedules.rb | 2 +- app/apis/api/v1/users.rb | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/apis/api/v1/ir.rb b/app/apis/api/v1/ir.rb index 7017242..d73fd60 100644 --- a/app/apis/api/v1/ir.rb +++ b/app/apis/api/v1/ir.rb @@ -65,7 +65,7 @@ class IR < Grape::API fname = "user_#{user.id}_ir_#{infrared.id}.txt" `#{command} #{path}/data/#{fname}` if File.read("#{path}/data/#{fname}").size == 0 - infrared.destroy + infrared.soft_destroy error!(meta: { status: 400, errors: [ @@ -229,7 +229,7 @@ class IR < Grape::API File.delete file log = user.logs.create(name: "「#{infrared.name}」を削除しました", status: :destroy_ir) infrared.logs << log - infrared.destroy + infrared.soft_destroy else error!(meta: { status: 400, diff --git a/app/apis/api/v1/schedules.rb b/app/apis/api/v1/schedules.rb index 1b70031..fb65057 100644 --- a/app/apis/api/v1/schedules.rb +++ b/app/apis/api/v1/schedules.rb @@ -590,7 +590,7 @@ def cron_check_value(value, index) if schedule.active_schedule? Resque.remove_schedule(schedule.job_name) end - schedule.destroy + schedule.soft_destroy log = user.logs.create(name: "「#{schedule.name}」のスケジューラーを削除しました", status: :delete_schedule) schedule.logs << log else diff --git a/app/apis/api/v1/users.rb b/app/apis/api/v1/users.rb index 413ce88..42727f2 100644 --- a/app/apis/api/v1/users.rb +++ b/app/apis/api/v1/users.rb @@ -47,7 +47,7 @@ class Users < Grape::API if params[:password] if check_password(info, params[:password]) name = user.info.screen_name - user.destroy + user.soft_destroy @message = "#{name}さんは退会しました。" end else @@ -61,7 +61,7 @@ class Users < Grape::API false end else - user.destroy + user.soft_destroy @message = '退会しました。' end end From 10dffe5231757ab6f314d31bf8afcdc69379836b Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 13 Dec 2015 15:07:42 +0900 Subject: [PATCH 298/358] dependent soft destroy --- app/models/auth_token.rb | 1 + app/models/infrared_group.rb | 1 + app/models/infrared_relational.rb | 1 + app/models/log.rb | 2 ++ 4 files changed, 5 insertions(+) diff --git a/app/models/auth_token.rb b/app/models/auth_token.rb index e5da7aa..f8b8d68 100644 --- a/app/models/auth_token.rb +++ b/app/models/auth_token.rb @@ -1,4 +1,5 @@ class AuthToken < ActiveRecord::Base + soft_deletable dependent_associations: [:user] belongs_to :user validates :user, presence: true diff --git a/app/models/infrared_group.rb b/app/models/infrared_group.rb index 6b3396c..235e0b5 100644 --- a/app/models/infrared_group.rb +++ b/app/models/infrared_group.rb @@ -2,4 +2,5 @@ class InfraredGroup < ActiveRecord::Base belongs_to :user has_many :infrared_relationals has_many :infrareds, through: :infrared_relationals + soft_deletable dependent_associations: [:user] end diff --git a/app/models/infrared_relational.rb b/app/models/infrared_relational.rb index 038f94e..fb91838 100644 --- a/app/models/infrared_relational.rb +++ b/app/models/infrared_relational.rb @@ -1,4 +1,5 @@ class InfraredRelational < ActiveRecord::Base belongs_to :infrared + soft_deletable dependent_associations: [:infrared] belongs_to :infrared_group end diff --git a/app/models/log.rb b/app/models/log.rb index f84161a..f753577 100644 --- a/app/models/log.rb +++ b/app/models/log.rb @@ -1,5 +1,7 @@ class Log < ActiveRecord::Base belongs_to :user belongs_to :loggable, polymorphic: true, dependent: :destroy + soft_deletable dependent_associations: [:loggable] enum status: %i(receive_ir send_ir update_ir destroy_ir add_ir remove_ir robot_send_ir remove_schedule create_schedule activate_schedule update_schedule delete_schedule) + soft_deletable dependent_associations: [:user] end From 05c21aeef11b9e48e6bc3799fbc21c4cd30def53 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 13 Dec 2015 15:21:20 +0900 Subject: [PATCH 299/358] update schedules.rb --- app/apis/api/v1/schedules.rb | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/app/apis/api/v1/schedules.rb b/app/apis/api/v1/schedules.rb index fb65057..cc02943 100644 --- a/app/apis/api/v1/schedules.rb +++ b/app/apis/api/v1/schedules.rb @@ -325,12 +325,12 @@ def cron_check_value(value, index) else @user = user if params[:status].nil? - @schedules = user.schedules + @schedules = user.schedules.without_soft_destroyed.all elsif params[:status].to_s =~ /^[0-1]$/ if params[:status] == 0 - @schedules = user.schedules.inactive_schedule + @schedules = user.schedules.without_soft_destroyed.all.inactive_schedule elsif params[:status] == 1 - @schedules = user.schedules.active_schedule + @schedules = user.schedules.without_soft_destroyed.all.active_schedule end else error!(meta: { @@ -374,7 +374,7 @@ def cron_check_value(value, index) ] }, response: {}) else - if schedule = user.schedules.find_by(id: params[:schedule_id]) + if schedule = user.schedules.without_soft_destroyed.find_by(id: params[:schedule_id]) if schedule.active_schedule? error!(meta: { status: 400, @@ -429,7 +429,7 @@ def cron_check_value(value, index) ] }, response: {}) else - if schedule = user.schedules.find_by(id: params[:schedule_id]) + if schedule = user.schedules.without_soft_destroyed.find_by(id: params[:schedule_id]) if schedule.active_schedule? Resque.remove_schedule(schedule.job_name) schedule.update(status: :inactive_schedule) @@ -485,7 +485,7 @@ def cron_check_value(value, index) ] }, response: {}) else - if schedule = user.schedules.find_by(id: params[:schedule_id]) + if schedule = user.schedules.without_soft_destroyed.find_by(id: params[:schedule_id]) schedule.update(name: params[:name]) log = user.logs.create(name: "「スケジューラーを#{schedule.name}」にリネームしました", status: :update_schedule) schedule.logs << log @@ -534,7 +534,7 @@ def cron_check_value(value, index) ] }, response: {}) else - if (infrared = Infrared.find_by(id: params[:ir_id])) + if (infrared = Infrared.without_soft_destroyed.find_by(id: params[:ir_id])) cron = params[:cron] cron_a = cron.split(' ') translation = cron_translator(cron_a) @@ -586,7 +586,7 @@ def cron_check_value(value, index) ] }, response: {}) else - if schedule = user.schedules.find_by(id: params[:schedule_id]) + if schedule = user.schedules.without_soft_destroyed.find_by(id: params[:schedule_id]) if schedule.active_schedule? Resque.remove_schedule(schedule.job_name) end From 16e1bc0628f14740ecd8247b353fec93ce333018 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 13 Dec 2015 15:25:36 +0900 Subject: [PATCH 300/358] update base.rb --- app/apis/api/base.rb | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/app/apis/api/base.rb b/app/apis/api/base.rb index 0beea2b..f0e2489 100644 --- a/app/apis/api/base.rb +++ b/app/apis/api/base.rb @@ -40,7 +40,17 @@ def user return @user if @user if (token = AuthToken.find_by(token: params[:auth_token])) update_auth_token token - @user = token.user + unless token.user.destroyed? + @user = token.user + else + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.invalid_auth_token'), + code: ErrorCodes::INVALID_TOKEN + ] + }, response: {}) + end else error!(meta: { status: 400, From 1063dbca8aad79c3721f2a8b82fe123e5d347b42 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 13 Dec 2015 15:36:10 +0900 Subject: [PATCH 301/358] update infrared group --- app/apis/api/v1/infrared_group.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/apis/api/v1/infrared_group.rb b/app/apis/api/v1/infrared_group.rb index 0c4404c..ec30ea1 100644 --- a/app/apis/api/v1/infrared_group.rb +++ b/app/apis/api/v1/infrared_group.rb @@ -186,8 +186,8 @@ class InfraredGroup < Grape::API }, response: {}) else if group = user.infrared_groups.find_by(id: params[:group_id]) - if infrared = user.infrareds.find_by(id: params[:ir_id]) - if !group.infrareds.find_by(id: params[:ir_id]) + if infrared = user.infrareds.without_soft_destroyed.find_by(id: params[:ir_id]) + if !group.infrareds.without_soft_destroyed.find_by(id: params[:ir_id]) group.infrareds << infrared log = user.logs.create(name: "「#{infrared.name}」を「#{group.name}」に追加しました", status: :add_ir) infrared.logs << log @@ -255,7 +255,7 @@ class InfraredGroup < Grape::API }, response: {}) else if group = user.infrared_groups.find_by(id: params[:group_id]) - if infrared = user.infrareds.find_by(id: params[:ir_id]) + if infrared = user.infrareds.without_soft_destroyed.find_by(id: params[:ir_id]) if relational = group.infrared_relationals.find_by(infrared_id: params[:ir_id]) @group = group @infrared = infrared From 373d2b664cb41471be75cd80638b42545dc62174 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 13 Dec 2015 15:39:35 +0900 Subject: [PATCH 302/358] update ir --- app/apis/api/v1/ir.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/apis/api/v1/ir.rb b/app/apis/api/v1/ir.rb index d73fd60..1443c50 100644 --- a/app/apis/api/v1/ir.rb +++ b/app/apis/api/v1/ir.rb @@ -24,7 +24,7 @@ class IR < Grape::API ] }, response: {}) else - @infrareds = user.infrareds + @infrareds = user.infrareds.without_soft_destroyed.all end else error!(meta: { @@ -125,7 +125,7 @@ class IR < Grape::API ] }, response: {}) else - if infrared = user.infrareds.find_by(id: params[:ir_id]) + if infrared = user.infrareds.without_soft_destroyed.find_by(id: params[:ir_id]) fname = infrared.data path = Rails.root.to_s command = File.join(path, 'commands/send') @@ -177,7 +177,7 @@ class IR < Grape::API ] }, response: {}) else - if infrared = user.infrareds.find_by(id: params[:ir_id]) + if infrared = user.infrareds.without_soft_destroyed.find_by(id: params[:ir_id]) infrared.update(name: params[:name]) log = user.logs.create(name: "「#{infrared.name}」に名前を変更しました", status: :update_ir) infrared.logs << log @@ -223,7 +223,7 @@ class IR < Grape::API ] }, response: {}) else - if infrared = user.infrareds.find_by(id: params[:ir_id]) + if infrared = user.infrareds.without_soft_destroyed.find_by(id: params[:ir_id]) name = infrared.data file = Rails.root.to_s + '/data/' + name File.delete file From 57e121845f806c142421072688736986b0734961 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 13 Dec 2015 15:51:43 +0900 Subject: [PATCH 303/358] :bug: --- commands/{recieve.c => receive.c} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename commands/{recieve.c => receive.c} (100%) diff --git a/commands/recieve.c b/commands/receive.c similarity index 100% rename from commands/recieve.c rename to commands/receive.c From 2c9fd97581cb0b8dc73c51c9c3baacb50aff2186 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 13 Dec 2015 15:53:57 +0900 Subject: [PATCH 304/358] update readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 722fa6d..a9fc65b 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ $ redis-server ### Resque立ち上げ ```sh -$ QUEUE=* rake environment resque:work +$ sudo QUEUE=* rake environment resque:work ``` ### scheduler立ち上げ From 928b68fe9333f5dd46029a7ded9fbabf606f940f Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 13 Dec 2015 16:08:21 +0900 Subject: [PATCH 305/358] :bug: fix --- app/jobs/resque_infrared_send_job.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/jobs/resque_infrared_send_job.rb b/app/jobs/resque_infrared_send_job.rb index f416ea2..e4a19a9 100644 --- a/app/jobs/resque_infrared_send_job.rb +++ b/app/jobs/resque_infrared_send_job.rb @@ -2,7 +2,7 @@ class ResqueInfraredSendJob @queue = :resque_infrared_send_job def self.perform(task) # path = File.expand_path("log/resque_infrared_send_job.log", Rails.root) - schedule = Schedule.find_by(id: task['id']) + schedule = Schedule.without_soft_destroyed.find_by(id: task['id']) user = schedule.user infrared = schedule.infrared fname = infrared.data @@ -12,6 +12,6 @@ def self.perform(task) count = infrared.count + 1 infrared.update(count: count) log = user.logs.create(name: "「#{schedule.name}」のスケジューラーが「#{infrared.name}」を実行しました", status: :robot_send_ir) - log.infrared = infrared + infrared.logs << log end end From 4334761dc981a37c0bfa9347737a7e41dd025e7e Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 13 Dec 2015 18:01:54 +0900 Subject: [PATCH 306/358] move ir log --- app/apis/api/v1/ir.rb | 38 ------------------- app/apis/api/v1/logs.rb | 81 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 38 deletions(-) create mode 100644 app/apis/api/v1/logs.rb diff --git a/app/apis/api/v1/ir.rb b/app/apis/api/v1/ir.rb index 1443c50..459189a 100644 --- a/app/apis/api/v1/ir.rb +++ b/app/apis/api/v1/ir.rb @@ -250,44 +250,6 @@ class IR < Grape::API }, response: {}) end end - desc '赤外線のlog', notes: <<-NOTE -

赤外線のログを表示します

-

- sizeを渡すと最新〜sizeまでのログを取得します。 - 何も指定しない場合は全部取得します -

- NOTE - params do - requires :auth_token, type: String, desc: 'Auth token.' - optional :size, type: Integer, desc: 'Array size' - end - get '/logs', jbuilder: 'api/v1/ir/logs' do - if (token = AuthToken.find_by(token: params[:auth_token])) - if user.info.nil? - error!(meta: { - status: 400, - errors: [ - message: ('errors.messages.user_not_found'), - code: ErrorCodes::NOT_FOUND_USER - ] - }, response: {}) - else - if params[:size].nil? - @logs = user.logs.sort { |a, b| b <=> a } - else - @logs = user.logs.last(params[:size].to_i).sort { |a, b| b <=> a } - end - end - else - error!(meta: { - status: 400, - errors: [ - message: ('errors.messages.invalid_token'), - code: ErrorCodes::INVALID_TOKEN - ] - }, response: {}) - end - end end end end diff --git a/app/apis/api/v1/logs.rb b/app/apis/api/v1/logs.rb new file mode 100644 index 0000000..42858d7 --- /dev/null +++ b/app/apis/api/v1/logs.rb @@ -0,0 +1,81 @@ +# app/apis/api/v1/users.rb + +module API + module V1 + class Logs < Grape::API + resource :log do + desc 'logを取得する', notes: <<-NOTE +

ログを取得します

+

size - 取得数

+

+ null ・・・ すべてのログの取得
+ num ・・・ 最新num件のログを取得 +

+

type - ログのタイプ

+

+ null ・・・ すべてのログの取得
+ 0 ・・・ 赤外線にまつわるログの取得
+ 1 ・・・ スケジューラーにまつわるログの取得 +

+ NOTE + params do + requires :auth_token, type: String, desc: 'Auth token.' + optional :size, type: Integer, desc: 'Array size' + optional :type, type: Integer, desc: 'Log type' + end + get '/', jbuilder: 'api/v1/log/index' do + if (token = AuthToken.find_by(token: params[:auth_token])) + if user.info.nil? + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.user_not_found'), + code: ErrorCodes::NOT_FOUND_USER + ] + }, response: {}) + else + @user = user + if params[:type].nil? + if params[:size].nil? + @logs = user.logs.sort { |a, b| b <=> a } + else + @logs = user.logs.last(params[:size].to_i).sort { |a, b| b <=> a } + end + elsif params[:type].to_s =~ /^[0-1]$/ + if params[:type] == 0 + if params[:size].nil? + @logs = user.infrared_logs.sort { |a, b| b <=> a } + else + @logs = user.infrared_logs.last(params[:size].to_i).sort { |a, b| b <=> a } + end + elsif params[:type] == 1 + if params[:size].nil? + @logs = user.schedule_logs.sort { |a, b| b <=> a } + else + @logs = user.schedule_logs.last(params[:size].to_i).sort { |a, b| b <=> a } + end + end + else + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.invalid_params'), + code: ErrorCodes::INVALID_PARAMS + ] + }, response: {}) + end + end + else + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.invalid_token'), + code: ErrorCodes::INVALID_TOKEN + ] + }, response: {}) + end + end + end + end + end +end From 2a9b97e3ea4ec4482fb67233655901fb8eaa6214 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 13 Dec 2015 18:02:21 +0900 Subject: [PATCH 307/358] move log jbuilder --- app/views/apis/api/v1/ir/logs.jbuilder | 7 ------- app/views/apis/api/v1/log/index.jbuilder | 7 +++++++ 2 files changed, 7 insertions(+), 7 deletions(-) delete mode 100644 app/views/apis/api/v1/ir/logs.jbuilder create mode 100644 app/views/apis/api/v1/log/index.jbuilder diff --git a/app/views/apis/api/v1/ir/logs.jbuilder b/app/views/apis/api/v1/ir/logs.jbuilder deleted file mode 100644 index 4b59cdd..0000000 --- a/app/views/apis/api/v1/ir/logs.jbuilder +++ /dev/null @@ -1,7 +0,0 @@ -json.meta do - json.status 200 - json.message 'ログデータ一覧を受信しました。' -end -json.response do - json.logs @logs -end diff --git a/app/views/apis/api/v1/log/index.jbuilder b/app/views/apis/api/v1/log/index.jbuilder new file mode 100644 index 0000000..55b29ea --- /dev/null +++ b/app/views/apis/api/v1/log/index.jbuilder @@ -0,0 +1,7 @@ +json.meta do + json.status 200 + json.message "#{@user.info.screen_name}のログ一覧を取得しました。" +end +json.response do + json.logs @logs +end From 6aa0cb60717fc8ef658cde535a6e56c546efb942 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 13 Dec 2015 18:02:28 +0900 Subject: [PATCH 308/358] mount log --- app/apis/api/v1/base.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/apis/api/v1/base.rb b/app/apis/api/v1/base.rb index 357806f..00f168c 100644 --- a/app/apis/api/v1/base.rb +++ b/app/apis/api/v1/base.rb @@ -35,6 +35,7 @@ class Base < Grape::API mount V1::IR mount V1::InfraredGroup mount V1::Schedules + mount V1::Logs add_swagger_documentation format: :json, api_version: 'v1', hide_documentation_path: true end end From a74c008acccb82d43551b2821b4d050d4a74d305 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 13 Dec 2015 21:30:50 +0900 Subject: [PATCH 309/358] add log methods --- app/models/log.rb | 1 + app/models/user.rb | 12 ++++++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/app/models/log.rb b/app/models/log.rb index f753577..9a82519 100644 --- a/app/models/log.rb +++ b/app/models/log.rb @@ -4,4 +4,5 @@ class Log < ActiveRecord::Base soft_deletable dependent_associations: [:loggable] enum status: %i(receive_ir send_ir update_ir destroy_ir add_ir remove_ir robot_send_ir remove_schedule create_schedule activate_schedule update_schedule delete_schedule) soft_deletable dependent_associations: [:user] + end diff --git a/app/models/user.rb b/app/models/user.rb index e68afa4..b338493 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -7,6 +7,14 @@ class User < ActiveRecord::Base has_many :infrareds has_many :infrared_groups has_many :logs, dependent: :destroy - has_many :infrared_logs, through: :logs, source: :loggable, source_type: 'Infrared' - has_many :schedule_logs, through: :logs, source: :loggable, source_type: 'Schedule' + has_many :log_infrareds, through: :logs, source: :loggable, source_type: 'Infrared' + has_many :log_schedules, through: :logs, source: :loggable, source_type: 'Schedule' + + def self.schedule_logs + self.logs.where(loggable_type: "Schedule") + end + + def self.infrared_logs + self.logs.where(loggable_type: "Infrared") + end end From 30706b93c6a7cabba3b6ab2567201dc4858ad822 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 13 Dec 2015 21:36:11 +0900 Subject: [PATCH 310/358] :bug: --- app/models/user.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/models/user.rb b/app/models/user.rb index b338493..229b8a0 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -10,11 +10,13 @@ class User < ActiveRecord::Base has_many :log_infrareds, through: :logs, source: :loggable, source_type: 'Infrared' has_many :log_schedules, through: :logs, source: :loggable, source_type: 'Schedule' - def self.schedule_logs + private + + def schedule_logs self.logs.where(loggable_type: "Schedule") end - def self.infrared_logs + def infrared_logs self.logs.where(loggable_type: "Infrared") end end From f9a023a6912ed39b0503e6c312d9c9a8b0bd7dc0 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 13 Dec 2015 21:38:04 +0900 Subject: [PATCH 311/358] :bug: --- app/models/user.rb | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/models/user.rb b/app/models/user.rb index 229b8a0..e18477c 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -10,8 +10,6 @@ class User < ActiveRecord::Base has_many :log_infrareds, through: :logs, source: :loggable, source_type: 'Infrared' has_many :log_schedules, through: :logs, source: :loggable, source_type: 'Schedule' - private - def schedule_logs self.logs.where(loggable_type: "Schedule") end From 83448862ec4efd185ef9183f8c043c5390e5a230 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 13 Dec 2015 22:42:19 +0900 Subject: [PATCH 312/358] convert space 4 to 2 --- commands/send.c | 120 ++++++++++++++++++++++++------------------------ 1 file changed, 60 insertions(+), 60 deletions(-) diff --git a/commands/send.c b/commands/send.c index 5528358..112e2cf 100644 --- a/commands/send.c +++ b/commands/send.c @@ -16,84 +16,84 @@ int d_low; // LOW時間 void high(int on_time) { - // パルス信号に変換して送信 - int i; - int count = on_time/unit; - for(i=0; i= 2){ fileName = argv[1]; } //読み込むフィル名 - if((fp = fopen(fileName, "r")) == NULL){ - exit(1); - } + // 送信データファイル + FILE *fp; + char *fileName = "irdata.txt"; + if(argc >= 2){ fileName = argv[1]; } //読み込むフィル名 + if((fp = fopen(fileName, "r")) == NULL){ + exit(1); + } - // wiringpiのセットアップ - if(wiringPiSetup() == -1){ - exit(1); - } + // wiringpiのセットアップ + if(wiringPiSetup() == -1){ + exit(1); + } - pinMode(send_pin, OUTPUT); + pinMode(send_pin, OUTPUT); - // unit長 1sec = 1 * 10^6 us - unit = (1.0f / khz) * 1000000; - d_high = roundf(((float)unit / d_denomi) * d_num); - unit = (int)unit; //us - d_low = unit - d_high; + // unit長 1sec = 1 * 10^6 us + unit = (1.0f / khz) * 1000000; + d_high = roundf(((float)unit / d_denomi) * d_num); + unit = (int)unit; //us + d_low = unit - d_high; - // 準備完了 + // 準備完了 - // データ読み込みと赤外線の送信 - readAndSend(fp); + // データ読み込みと赤外線の送信 + readAndSend(fp); - fclose(fp); + fclose(fp); - return 0; + return 0; } From 8f6a5cfa4df0fe44aaa9b35ab77d1569bac8d08b Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Sun, 13 Dec 2015 22:43:32 +0900 Subject: [PATCH 313/358] create temperature.c --- commands/temperature.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 commands/temperature.c diff --git a/commands/temperature.c b/commands/temperature.c new file mode 100644 index 0000000..169e87c --- /dev/null +++ b/commands/temperature.c @@ -0,0 +1,22 @@ +#include +#include +#include + +int read_pin = 1; +int temperature; +int main(void){ + FILE *fp; + char *fileName = "temperature.txt"; + if(argc >= 2){ fileName = argv[1]; } //読み込むフィル名 + if((fp = fopen(fileName, "w")) == NULL){ + exit(1); + } + // wiringpiのセットアップ + if(wiringPiSetup() == -1){ + exit(1); + } + pinMode(send_pin, INPUT); + temperature = digitalRead(read_pin) + fprintf(fp, "%6d\n", temperature); + return 0; +} \ No newline at end of file From b5415e95cc2f90ad6cb81e15f81d9b7ad3d90e29 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Mon, 14 Dec 2015 00:38:47 +0900 Subject: [PATCH 314/358] create multiple infrared assign --- app/apis/api/v1/infrared_group.rb | 64 +++++++++++++++++++++++-------- 1 file changed, 48 insertions(+), 16 deletions(-) diff --git a/app/apis/api/v1/infrared_group.rb b/app/apis/api/v1/infrared_group.rb index ec30ea1..5107a87 100644 --- a/app/apis/api/v1/infrared_group.rb +++ b/app/apis/api/v1/infrared_group.rb @@ -167,12 +167,13 @@ class InfraredGroup < Grape::API

グループに赤外線を追加する

グループに赤外線を追加します。 + カンマ区切りでir_idを渡すと複数の赤外線を一気に登録できます。

NOTE params do requires :auth_token, type: String, desc: 'Auth token.' requires :group_id, type: Integer, desc: 'Group_id.' - requires :ir_id, type: Integer, desc: 'IR_id.' + requires :ir_id, type: String, desc: 'IR_id.' end post '/', jbuilder: 'api/v1/group/ir/add' do if (token = AuthToken.find_by(token: params[:auth_token])) @@ -186,30 +187,61 @@ class InfraredGroup < Grape::API }, response: {}) else if group = user.infrared_groups.find_by(id: params[:group_id]) - if infrared = user.infrareds.without_soft_destroyed.find_by(id: params[:ir_id]) - if !group.infrareds.without_soft_destroyed.find_by(id: params[:ir_id]) - group.infrareds << infrared - log = user.logs.create(name: "「#{infrared.name}」を「#{group.name}」に追加しました", status: :add_ir) - infrared.logs << log - @group = group - @infrared = infrared + if params[:ir_id] =~ /^[0-9]+$/ + if infrared = user.infrareds.without_soft_destroyed.find_by(id: params[:ir_id]) + if !group.infrareds.without_soft_destroyed.find_by(id: params[:ir_id]) + group.infrareds << infrared + log = user.logs.create(name: "「#{infrared.name}」を「#{group.name}」に追加しました", status: :add_ir) + infrared.logs << log + @group = group + @infrared = infrared + else + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.ir_already_existing'), + code: ErrorCodes::ALREADY_EXISTING + ] + }, response: {}) + end else error!(meta: { status: 400, errors: [ - message: ('errors.messages.ir_already_existing'), - code: ErrorCodes::ALREADY_EXISTING + message: ('errors.messages.ir_not_found'), + code: ErrorCodes::NOT_FOUND ] }, response: {}) end + elsif params[:ir_id] =~ /^(([0-9]+)((\,||\-||\/)[0-9]+)*)$/ + infrareds = params[:ir_id].split(",") + infrareds.each do |infrared| + if infrared = user.infrareds.without_soft_destroyed.find_by(id: params[:ir_id]) + if !group.infrareds.without_soft_destroyed.find_by(id: params[:ir_id]) + group.infrareds << infrared + log = user.logs.create(name: "「#{infrared.name}」を「#{group.name}」に追加しました", status: :add_ir) + infrared.logs << log + @group = group + @infrared = infrared + end + else + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.ir_not_found'), + code: ErrorCodes::NOT_FOUND + ] + }, response: {}) + end + end else error!(meta: { - status: 400, - errors: [ - message: ('errors.messages.ir_not_found'), - code: ErrorCodes::NOT_FOUND - ] - }, response: {}) + status: 400, + errors: [ + message: ('errors.messages.invalid_params'), + code: ErrorCodes::INVALID_PARAMS + ] + }, response: {}) end else error!(meta: { From c3f2caf64fc12fb489c2744560f4d9a610715d61 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Mon, 14 Dec 2015 00:44:07 +0900 Subject: [PATCH 315/358] :bug: fix --- app/apis/api/v1/infrared_group.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/apis/api/v1/infrared_group.rb b/app/apis/api/v1/infrared_group.rb index 5107a87..572b15f 100644 --- a/app/apis/api/v1/infrared_group.rb +++ b/app/apis/api/v1/infrared_group.rb @@ -215,9 +215,9 @@ class InfraredGroup < Grape::API end elsif params[:ir_id] =~ /^(([0-9]+)((\,||\-||\/)[0-9]+)*)$/ infrareds = params[:ir_id].split(",") - infrareds.each do |infrared| - if infrared = user.infrareds.without_soft_destroyed.find_by(id: params[:ir_id]) - if !group.infrareds.without_soft_destroyed.find_by(id: params[:ir_id]) + infrareds.each do |i| + if infrared = user.infrareds.without_soft_destroyed.find_by(id: i.to_i) + if !group.infrareds.without_soft_destroyed.find_by(id: i.to_i) group.infrareds << infrared log = user.logs.create(name: "「#{infrared.name}」を「#{group.name}」に追加しました", status: :add_ir) infrared.logs << log From e195036898a74ab9f17437a9b1faf17207987957 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Mon, 14 Dec 2015 12:29:07 +0900 Subject: [PATCH 316/358] config local timezone --- config/application.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/config/application.rb b/config/application.rb index b41db45..20aac01 100644 --- a/config/application.rb +++ b/config/application.rb @@ -22,6 +22,8 @@ class Application < Rails::Application # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC. # config.time_zone = 'Central Time (US & Canada)' + config.time_zone = 'Tokyo' + config.active_record.default_timezone = :local # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] From 7d0a8f8c3e3817045be130940b84fb967e1bc4a1 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Tue, 15 Dec 2015 16:26:18 +0900 Subject: [PATCH 317/358] rails g task room --- lib/tasks/room.rake | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 lib/tasks/room.rake diff --git a/lib/tasks/room.rake b/lib/tasks/room.rake new file mode 100644 index 0000000..15111ae --- /dev/null +++ b/lib/tasks/room.rake @@ -0,0 +1,2 @@ +namespace :room do +end From bf2133916054c10a24eb0edde968f45cc8e5e2ca Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Tue, 15 Dec 2015 16:56:34 +0900 Subject: [PATCH 318/358] add test task --- lib/tasks/room.rake | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/tasks/room.rake b/lib/tasks/room.rake index 15111ae..1718311 100644 --- a/lib/tasks/room.rake +++ b/lib/tasks/room.rake @@ -1,2 +1,5 @@ namespace :room do + task :temperature do + puts "hello" + end end From 9d1f0299246bcdf4b7d121f7d5f3a904e5ba3a10 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Tue, 15 Dec 2015 16:56:43 +0900 Subject: [PATCH 319/358] bundle install piper --- Gemfile | 1 + Gemfile.lock | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/Gemfile b/Gemfile index 347eaea..3794aad 100644 --- a/Gemfile +++ b/Gemfile @@ -42,6 +42,7 @@ gem 'resque' gem 'resque-scheduler' gem 'rubocop', group: :development gem 'kakurenbo-puti' +gem 'pi_piper' group :development, :test do gem 'byebug' diff --git a/Gemfile.lock b/Gemfile.lock index 4f256fa..ca507c7 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -80,6 +80,7 @@ GEM railties (>= 3.0.0) faker (1.6.1) i18n (~> 0.5) + ffi (1.9.10) globalid (0.3.6) activesupport (>= 4.1.0) grape (0.13.0) @@ -153,6 +154,8 @@ GEM mini_portile2 (~> 2.0.0.rc2) parser (2.2.3.0) ast (>= 1.1, < 3.0) + pi_piper (1.3.2) + ffi powerpack (0.1.1) pry (0.10.3) coderay (~> 1.1.0) @@ -334,6 +337,7 @@ DEPENDENCIES jquery-rails json_expressions kakurenbo-puti + pi_piper pry-byebug pry-doc pry-rails From 1abdc8328c49f5911e84c4ab20d93100acb795dd Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Tue, 15 Dec 2015 17:17:20 +0900 Subject: [PATCH 320/358] add temperature --- lib/tasks/room.rake | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/tasks/room.rake b/lib/tasks/room.rake index 1718311..cf83ed6 100644 --- a/lib/tasks/room.rake +++ b/lib/tasks/room.rake @@ -1,5 +1,14 @@ namespace :room do task :temperature do - puts "hello" + require 'pi_piper' + loop do + value = 0 + PiPiper::Spi.begin do |spi| + raw = spi.write [0b01101000,0] + value = ((raw[0]<<8) + raw[1]) & 0x03FF + end + puts value + sleep(1) + end end end From d0226e0d00d88a4152c5c72d553b07f4f634a707 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Tue, 15 Dec 2015 18:24:30 +0900 Subject: [PATCH 321/358] create temperature.rb --- commands/temperature.c | 22 ---------------------- commands/temperature.rb | 13 +++++++++++++ lib/tasks/room.rake | 13 +++---------- 3 files changed, 16 insertions(+), 32 deletions(-) delete mode 100644 commands/temperature.c create mode 100644 commands/temperature.rb diff --git a/commands/temperature.c b/commands/temperature.c deleted file mode 100644 index 169e87c..0000000 --- a/commands/temperature.c +++ /dev/null @@ -1,22 +0,0 @@ -#include -#include -#include - -int read_pin = 1; -int temperature; -int main(void){ - FILE *fp; - char *fileName = "temperature.txt"; - if(argc >= 2){ fileName = argv[1]; } //読み込むフィル名 - if((fp = fopen(fileName, "w")) == NULL){ - exit(1); - } - // wiringpiのセットアップ - if(wiringPiSetup() == -1){ - exit(1); - } - pinMode(send_pin, INPUT); - temperature = digitalRead(read_pin) - fprintf(fp, "%6d\n", temperature); - return 0; -} \ No newline at end of file diff --git a/commands/temperature.rb b/commands/temperature.rb new file mode 100644 index 0000000..5390ed8 --- /dev/null +++ b/commands/temperature.rb @@ -0,0 +1,13 @@ +require 'pi_piper' +value = 0 +raw = 0 +PiPiper::Spi.begin do |spi| + raw = spi.write [0b01101000,0] + value = ((raw[0]<<8) + raw[1]) & 0x03FF +end +volt = (value * 3300)/1024 +degree = (volt - 500)/10 + +File.open("temperature.txt", "w") do |file| + file.print(volt) +end \ No newline at end of file diff --git a/lib/tasks/room.rake b/lib/tasks/room.rake index cf83ed6..4a53642 100644 --- a/lib/tasks/room.rake +++ b/lib/tasks/room.rake @@ -1,14 +1,7 @@ namespace :room do task :temperature do - require 'pi_piper' - loop do - value = 0 - PiPiper::Spi.begin do |spi| - raw = spi.write [0b01101000,0] - value = ((raw[0]<<8) + raw[1]) & 0x03FF - end - puts value - sleep(1) - end + path = Rails.root.to_s + command = File.join(path, 'commands/temperature.rb') + `ruby #{command}` end end From f48a1dc808271cc9bcd23e7fd209b6a44027557c Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Tue, 15 Dec 2015 19:11:31 +0900 Subject: [PATCH 322/358] add api --- app/apis/api/v1/base.rb | 1 + app/apis/api/v1/extra.rb | 18 ++++++++++++++++++ app/views/apis/api/v1/extra/ping.jbuilder | 1 + 3 files changed, 20 insertions(+) create mode 100644 app/apis/api/v1/extra.rb create mode 100644 app/views/apis/api/v1/extra/ping.jbuilder diff --git a/app/apis/api/v1/base.rb b/app/apis/api/v1/base.rb index 00f168c..396e512 100644 --- a/app/apis/api/v1/base.rb +++ b/app/apis/api/v1/base.rb @@ -36,6 +36,7 @@ class Base < Grape::API mount V1::InfraredGroup mount V1::Schedules mount V1::Logs + mount V1::Extra add_swagger_documentation format: :json, api_version: 'v1', hide_documentation_path: true end end diff --git a/app/apis/api/v1/extra.rb b/app/apis/api/v1/extra.rb new file mode 100644 index 0000000..7fe3d4f --- /dev/null +++ b/app/apis/api/v1/extra.rb @@ -0,0 +1,18 @@ +module API + module V1 + class Extra < Grape::API + resource :extra do + desc 'ping', notes: <<-NOTE +

レスポンスの有無

+

+ このURLにリクエストすることによって、アクセストークンを取得することができます。
+ アクセストークンは基本的にどんなリクエストをする時でも必要なので、値をキャッシュするようにしてください。 +

+ NOTE + get '/ping', jbuilder: 'api/v1/auth/ping' do + + end + end + end + end +end diff --git a/app/views/apis/api/v1/extra/ping.jbuilder b/app/views/apis/api/v1/extra/ping.jbuilder new file mode 100644 index 0000000..40df9a2 --- /dev/null +++ b/app/views/apis/api/v1/extra/ping.jbuilder @@ -0,0 +1 @@ +json.message "pong" \ No newline at end of file From ab1405db7571fe6f3a7c6efe2d225b530bcfcb81 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Tue, 15 Dec 2015 19:11:47 +0900 Subject: [PATCH 323/358] remo pi_piper --- Gemfile | 1 - 1 file changed, 1 deletion(-) diff --git a/Gemfile b/Gemfile index 3794aad..347eaea 100644 --- a/Gemfile +++ b/Gemfile @@ -42,7 +42,6 @@ gem 'resque' gem 'resque-scheduler' gem 'rubocop', group: :development gem 'kakurenbo-puti' -gem 'pi_piper' group :development, :test do gem 'byebug' From f86ca607f01a484021f29eb2a65924070fe491ef Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Tue, 15 Dec 2015 19:16:42 +0900 Subject: [PATCH 324/358] :bug: fix --- app/apis/api/v1/extra.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/apis/api/v1/extra.rb b/app/apis/api/v1/extra.rb index 7fe3d4f..ccc33bc 100644 --- a/app/apis/api/v1/extra.rb +++ b/app/apis/api/v1/extra.rb @@ -9,7 +9,7 @@ class Extra < Grape::API アクセストークンは基本的にどんなリクエストをする時でも必要なので、値をキャッシュするようにしてください。

NOTE - get '/ping', jbuilder: 'api/v1/auth/ping' do + get '/ping', jbuilder: 'api/v1/extra/ping' do end end From 17eb59a9c9a7acf6a3c95083a6269a76d4a75997 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Tue, 15 Dec 2015 19:51:58 +0900 Subject: [PATCH 325/358] update --- app/apis/api/v1/extra.rb | 12 ++++++++---- commands/temperature.rb | 2 +- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/app/apis/api/v1/extra.rb b/app/apis/api/v1/extra.rb index ccc33bc..1958281 100644 --- a/app/apis/api/v1/extra.rb +++ b/app/apis/api/v1/extra.rb @@ -5,14 +5,18 @@ class Extra < Grape::API desc 'ping', notes: <<-NOTE

レスポンスの有無

- このURLにリクエストすることによって、アクセストークンを取得することができます。
- アクセストークンは基本的にどんなリクエストをする時でも必要なので、値をキャッシュするようにしてください。 + このURLにリクエストすることによって、アクセストークンを取得すること\ +ができます。
+ アクセストークンは基本的にどんなリクエストをする時でも必要なので、\\ +値をキャッシュするようにしてください。

NOTE get '/ping', jbuilder: 'api/v1/extra/ping' do - + path = Rails.root.to_s + command = File.join(path, 'commands/temperature.rb') + `sudo ruby #{command} #{path}/data/extra/temperature.txt` end end end end -end +end \ No newline at end of file diff --git a/commands/temperature.rb b/commands/temperature.rb index 5390ed8..f416f4c 100644 --- a/commands/temperature.rb +++ b/commands/temperature.rb @@ -8,6 +8,6 @@ volt = (value * 3300)/1024 degree = (volt - 500)/10 -File.open("temperature.txt", "w") do |file| +File.open(ARGV[0], "w") do |file| file.print(volt) end \ No newline at end of file From 5819e392f83d6312c184e3a5dc803a6b77873003 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Tue, 15 Dec 2015 20:28:00 +0900 Subject: [PATCH 326/358] rails g model Room user:references --- Gemfile.lock | 4 ---- app/models/room.rb | 3 +++ db/migrate/20151215112744_create_rooms.rb | 9 +++++++++ spec/factories/rooms.rb | 6 ++++++ spec/models/room_spec.rb | 5 +++++ 5 files changed, 23 insertions(+), 4 deletions(-) create mode 100644 app/models/room.rb create mode 100644 db/migrate/20151215112744_create_rooms.rb create mode 100644 spec/factories/rooms.rb create mode 100644 spec/models/room_spec.rb diff --git a/Gemfile.lock b/Gemfile.lock index ca507c7..4f256fa 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -80,7 +80,6 @@ GEM railties (>= 3.0.0) faker (1.6.1) i18n (~> 0.5) - ffi (1.9.10) globalid (0.3.6) activesupport (>= 4.1.0) grape (0.13.0) @@ -154,8 +153,6 @@ GEM mini_portile2 (~> 2.0.0.rc2) parser (2.2.3.0) ast (>= 1.1, < 3.0) - pi_piper (1.3.2) - ffi powerpack (0.1.1) pry (0.10.3) coderay (~> 1.1.0) @@ -337,7 +334,6 @@ DEPENDENCIES jquery-rails json_expressions kakurenbo-puti - pi_piper pry-byebug pry-doc pry-rails diff --git a/app/models/room.rb b/app/models/room.rb new file mode 100644 index 0000000..9ab2ac2 --- /dev/null +++ b/app/models/room.rb @@ -0,0 +1,3 @@ +class Room < ActiveRecord::Base + belongs_to :user +end diff --git a/db/migrate/20151215112744_create_rooms.rb b/db/migrate/20151215112744_create_rooms.rb new file mode 100644 index 0000000..45d0586 --- /dev/null +++ b/db/migrate/20151215112744_create_rooms.rb @@ -0,0 +1,9 @@ +class CreateRooms < ActiveRecord::Migration + def change + create_table :rooms do |t| + t.references :user, index: true, foreign_key: true + + t.timestamps null: false + end + end +end diff --git a/spec/factories/rooms.rb b/spec/factories/rooms.rb new file mode 100644 index 0000000..0936608 --- /dev/null +++ b/spec/factories/rooms.rb @@ -0,0 +1,6 @@ +FactoryGirl.define do + factory :room do + user nil + end + +end diff --git a/spec/models/room_spec.rb b/spec/models/room_spec.rb new file mode 100644 index 0000000..93fdd2c --- /dev/null +++ b/spec/models/room_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe Room, :type => :model do + pending "add some examples to (or delete) #{__FILE__}" +end From cc614519c249c0c03d1b8206b05c26f3f17df1bd Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Tue, 15 Dec 2015 20:28:21 +0900 Subject: [PATCH 327/358] rake db:migrate --- db/schema.rb | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/db/schema.rb b/db/schema.rb index a79696c..3b63006 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20151213055014) do +ActiveRecord::Schema.define(version: 20151215112744) do create_table "auth_tokens", force: :cascade do |t| t.string "token" @@ -67,6 +67,14 @@ add_index "logs", ["loggable_id"], name: "index_logs_on_loggable_id" add_index "logs", ["user_id"], name: "index_logs_on_user_id" + create_table "rooms", force: :cascade do |t| + t.integer "user_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + add_index "rooms", ["user_id"], name: "index_rooms_on_user_id" + create_table "schedules", force: :cascade do |t| t.string "name" t.text "description" From 14250a9a9511a315513fd868b3f54a3d7ffb688b Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Tue, 15 Dec 2015 20:29:34 +0900 Subject: [PATCH 328/358] add relational --- app/models/user.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/models/user.rb b/app/models/user.rb index e18477c..5afcec7 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -3,6 +3,7 @@ class User < ActiveRecord::Base has_many :auth_tokens, dependent: :destroy has_one :info, class_name: 'UserInfo', dependent: :destroy + has_one :room, dependent: :destroy has_many :schedules, dependent: :destroy has_many :infrareds has_many :infrared_groups From ab910bfb21fbffb8b955144b0ec37cbb0c2ed15c Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Tue, 15 Dec 2015 20:33:10 +0900 Subject: [PATCH 329/358] rails g model Temperature --- app/models/temperature.rb | 3 +++ db/migrate/20151215113239_create_temperatures.rb | 10 ++++++++++ spec/factories/temperatures.rb | 7 +++++++ spec/models/temperature_spec.rb | 5 +++++ 4 files changed, 25 insertions(+) create mode 100644 app/models/temperature.rb create mode 100644 db/migrate/20151215113239_create_temperatures.rb create mode 100644 spec/factories/temperatures.rb create mode 100644 spec/models/temperature_spec.rb diff --git a/app/models/temperature.rb b/app/models/temperature.rb new file mode 100644 index 0000000..97e67f3 --- /dev/null +++ b/app/models/temperature.rb @@ -0,0 +1,3 @@ +class Temperature < ActiveRecord::Base + belongs_to :room +end diff --git a/db/migrate/20151215113239_create_temperatures.rb b/db/migrate/20151215113239_create_temperatures.rb new file mode 100644 index 0000000..7b360b4 --- /dev/null +++ b/db/migrate/20151215113239_create_temperatures.rb @@ -0,0 +1,10 @@ +class CreateTemperatures < ActiveRecord::Migration + def change + create_table :temperatures do |t| + t.references :room, index: true, foreign_key: true + t.string :centigrade + + t.timestamps null: false + end + end +end diff --git a/spec/factories/temperatures.rb b/spec/factories/temperatures.rb new file mode 100644 index 0000000..7f0d602 --- /dev/null +++ b/spec/factories/temperatures.rb @@ -0,0 +1,7 @@ +FactoryGirl.define do + factory :temperature do + room nil +centigrade "MyString" + end + +end diff --git a/spec/models/temperature_spec.rb b/spec/models/temperature_spec.rb new file mode 100644 index 0000000..888b548 --- /dev/null +++ b/spec/models/temperature_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe Temperature, :type => :model do + pending "add some examples to (or delete) #{__FILE__}" +end From 0ff8d4ea91635db22a009fd89e9d626a85a52d8e Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Tue, 15 Dec 2015 20:33:16 +0900 Subject: [PATCH 330/358] rake db:migrate --- db/schema.rb | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/db/schema.rb b/db/schema.rb index 3b63006..17abf0b 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20151215112744) do +ActiveRecord::Schema.define(version: 20151215113239) do create_table "auth_tokens", force: :cascade do |t| t.string "token" @@ -92,6 +92,15 @@ add_index "schedules", ["soft_destroyed_at"], name: "index_schedules_on_soft_destroyed_at" add_index "schedules", ["user_id"], name: "index_schedules_on_user_id" + create_table "temperatures", force: :cascade do |t| + t.integer "room_id" + t.string "centigrade" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + add_index "temperatures", ["room_id"], name: "index_temperatures_on_room_id" + create_table "user_infos", force: :cascade do |t| t.string "screen_name" t.string "hashed_password" From c053afd3ff512f40957cbbe1d52e3c75d29cb2d3 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Tue, 15 Dec 2015 20:37:23 +0900 Subject: [PATCH 331/358] add relational --- app/models/room.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/models/room.rb b/app/models/room.rb index 9ab2ac2..e01c819 100644 --- a/app/models/room.rb +++ b/app/models/room.rb @@ -1,3 +1,4 @@ class Room < ActiveRecord::Base belongs_to :user + has_many :temperatures, dependent: :destroy end From 18d02ecdcdf3d97dfd41709c061366507fcaecf2 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Tue, 15 Dec 2015 21:26:02 +0900 Subject: [PATCH 332/358] add error code --- lib/error_codes.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/error_codes.rb b/lib/error_codes.rb index dc27eb6..ce9bba9 100644 --- a/lib/error_codes.rb +++ b/lib/error_codes.rb @@ -25,4 +25,5 @@ module ErrorCodes NOT_FOUND_SCHEDULE = 24 INVALID_PARAMS = 25 NOT_ACTIVATE_SCHEDULE = 26 + NOT_FOUND_ROOM = 27 end From 96a54183828b10cd2f8fbae96111f151783e0561 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Tue, 15 Dec 2015 21:26:13 +0900 Subject: [PATCH 333/358] update extra --- app/apis/api/v1/extra.rb | 56 +++++++++++++++++++++++++++++++++------- 1 file changed, 46 insertions(+), 10 deletions(-) diff --git a/app/apis/api/v1/extra.rb b/app/apis/api/v1/extra.rb index 1958281..da007cc 100644 --- a/app/apis/api/v1/extra.rb +++ b/app/apis/api/v1/extra.rb @@ -2,19 +2,55 @@ module API module V1 class Extra < Grape::API resource :extra do - desc 'ping', notes: <<-NOTE -

レスポンスの有無

+ desc '気温を取得する', notes: <<-NOTE +

ログを取得します

+

size - 取得数

- このURLにリクエストすることによって、アクセストークンを取得すること\ -ができます。
- アクセストークンは基本的にどんなリクエストをする時でも必要なので、\\ -値をキャッシュするようにしてください。 + null ・・・ すべての気温の取得
+ num ・・・ 最新num件の気温を取得

NOTE - get '/ping', jbuilder: 'api/v1/extra/ping' do - path = Rails.root.to_s - command = File.join(path, 'commands/temperature.rb') - `sudo ruby #{command} #{path}/data/extra/temperature.txt` + params do + requires :auth_token, type: String, desc: 'Auth token.' + optional :size, type: Integer, desc: 'Array size' + end + get '/temperatures', jbuilder: 'api/v1/extra/temperatures' do + if (token = AuthToken.find_by(token: params[:auth_token])) + if user.info.nil? + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.user_not_found'), + code: ErrorCodes::NOT_FOUND_USER + ] + }, response: {}) + else + @user = user + if user.room.nil? + if params[:size].nil? + @logs = user.room.temperatures.sort { |a, b| b <=> a } + else + @logs = user.room.temperatures.last(params[:size].to_i).sort { |a, b| b <=> a } + end + else + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.room_not_found'), + code: ErrorCodes::NOT_FOUND_ROOM + ] + }, response: {}) + end + end + else + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.invalid_token'), + code: ErrorCodes::INVALID_TOKEN + ] + }, response: {}) + end end end end From a56d675356180a5d1cc605c32f14407f4b9a548d Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Tue, 15 Dec 2015 21:28:46 +0900 Subject: [PATCH 334/358] update tempreture --- commands/temperature.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commands/temperature.rb b/commands/temperature.rb index f416f4c..df9c794 100644 --- a/commands/temperature.rb +++ b/commands/temperature.rb @@ -6,7 +6,7 @@ value = ((raw[0]<<8) + raw[1]) & 0x03FF end volt = (value * 3300)/1024 -degree = (volt - 500)/10 +degree = volt/10.0 File.open(ARGV[0], "w") do |file| file.print(volt) From 31cd0b1bc7369ff0a6ae9178e826def724791837 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Tue, 15 Dec 2015 21:48:40 +0900 Subject: [PATCH 335/358] remove task --- lib/tasks/room.rake | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 lib/tasks/room.rake diff --git a/lib/tasks/room.rake b/lib/tasks/room.rake deleted file mode 100644 index 4a53642..0000000 --- a/lib/tasks/room.rake +++ /dev/null @@ -1,7 +0,0 @@ -namespace :room do - task :temperature do - path = Rails.root.to_s - command = File.join(path, 'commands/temperature.rb') - `ruby #{command}` - end -end From 32e1d163faf5550878823949acc4b8f26c12b7dc Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Tue, 15 Dec 2015 21:48:46 +0900 Subject: [PATCH 336/358] create jbuilder --- app/views/apis/api/v1/extra/temperature_start.jbuilder | 6 ++++++ app/views/apis/api/v1/extra/temperatures.jbuilder | 7 +++++++ 2 files changed, 13 insertions(+) create mode 100644 app/views/apis/api/v1/extra/temperature_start.jbuilder create mode 100644 app/views/apis/api/v1/extra/temperatures.jbuilder diff --git a/app/views/apis/api/v1/extra/temperature_start.jbuilder b/app/views/apis/api/v1/extra/temperature_start.jbuilder new file mode 100644 index 0000000..3689643 --- /dev/null +++ b/app/views/apis/api/v1/extra/temperature_start.jbuilder @@ -0,0 +1,6 @@ +json.meta do + json.status 200 + json.message '気温取得を開始しました。' +end +json.response do +end diff --git a/app/views/apis/api/v1/extra/temperatures.jbuilder b/app/views/apis/api/v1/extra/temperatures.jbuilder new file mode 100644 index 0000000..1c47713 --- /dev/null +++ b/app/views/apis/api/v1/extra/temperatures.jbuilder @@ -0,0 +1,7 @@ +json.meta do + json.status 200 + json.message '気温情報を取得しました。' +end +json.response do + json.temperatures @temperatures +end From f9ae987ebef71db18fc5c3879cb68c333f54cd98 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Tue, 15 Dec 2015 21:48:51 +0900 Subject: [PATCH 337/358] create get job --- app/jobs/resque_temperature_get_job.rb | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 app/jobs/resque_temperature_get_job.rb diff --git a/app/jobs/resque_temperature_get_job.rb b/app/jobs/resque_temperature_get_job.rb new file mode 100644 index 0000000..2d83873 --- /dev/null +++ b/app/jobs/resque_temperature_get_job.rb @@ -0,0 +1,11 @@ +class ResqueTemperatureGetJob + @queue = :resque_temperature_get_job + def self.perform(user) + path = Rails.root.to_s + command = File.join(path, 'commands/temperature.rb') + `sudo ruby #{command} #{path}/data/extra/temperature.txt` + centigrade = File.read("#{path}/data/extra/temperature.txt") + user = User.find(user["id"]) + user.room.temperatures << Temperature.create(centigrade: centigrade) + end +end From 7c9fd05885e71d42220b5c899124efe1e796aab9 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Tue, 15 Dec 2015 21:55:36 +0900 Subject: [PATCH 338/358] cerate temperatures api --- app/apis/api/v1/extra.rb | 62 +++++++++++++++++++ .../api/v1/extra/temperature_remove.jbuilder | 6 ++ 2 files changed, 68 insertions(+) create mode 100644 app/views/apis/api/v1/extra/temperature_remove.jbuilder diff --git a/app/apis/api/v1/extra.rb b/app/apis/api/v1/extra.rb index da007cc..71a2216 100644 --- a/app/apis/api/v1/extra.rb +++ b/app/apis/api/v1/extra.rb @@ -2,6 +2,38 @@ module API module V1 class Extra < Grape::API resource :extra do + desc '気温を取得を始める', notes: <<-NOTE +

cronをまわします

+ NOTE + params do + requires :auth_token, type: String, desc: 'Auth token.' + end + post '/temperature/start', jbuilder: 'api/v1/extra/temperature_start' do + if (token = AuthToken.find_by(token: params[:auth_token])) + if user.info.nil? + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.user_not_found'), + code: ErrorCodes::NOT_FOUND_USER + ] + }, response: {}) + else + @user = user + job = "user_#{user.id}_temperature_get_cycle" + Resque.set_schedule(job, class: 'ResqueTemperatureGetJob', cron: "* * * * *", args: user) + end + else + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.invalid_token'), + code: ErrorCodes::INVALID_TOKEN + ] + }, response: {}) + end + end + desc '気温を取得する', notes: <<-NOTE

ログを取得します

size - 取得数

@@ -52,6 +84,36 @@ class Extra < Grape::API }, response: {}) end end + desc '気温取得ルーティンの停止', notes: <<-NOTE +

気温取得ルーティンを停止します

+ NOTE + params do + requires :auth_token, type: String, desc: 'Auth token.' + end + post '/temperature/remove', jbuilder: 'api/v1/extra/temperature_remove' do + if (token = AuthToken.find_by(token: params[:auth_token])) + if user.info.nil? + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.user_not_found'), + code: ErrorCodes::NOT_FOUND_USER + ] + }, response: {}) + else + job = "user_#{user.id}_temperature_get_cycle" + Resque.remove_schedule(job) + end + else + error!(meta: { + status: 400, + errors: [ + message: ('errors.messages.invalid_token'), + code: ErrorCodes::INVALID_TOKEN + ] + }, response: {}) + end + end end end end diff --git a/app/views/apis/api/v1/extra/temperature_remove.jbuilder b/app/views/apis/api/v1/extra/temperature_remove.jbuilder new file mode 100644 index 0000000..2d0039f --- /dev/null +++ b/app/views/apis/api/v1/extra/temperature_remove.jbuilder @@ -0,0 +1,6 @@ +json.meta do + json.status 200 + json.message '気温取得をやめました。' +end +json.response do +end From ca3ff7380ce77237704817c5b4b77773a7d3a234 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Tue, 15 Dec 2015 22:07:06 +0900 Subject: [PATCH 339/358] :bug: fix --- app/apis/api/v1/extra.rb | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/app/apis/api/v1/extra.rb b/app/apis/api/v1/extra.rb index 71a2216..95f6dd1 100644 --- a/app/apis/api/v1/extra.rb +++ b/app/apis/api/v1/extra.rb @@ -59,19 +59,12 @@ class Extra < Grape::API else @user = user if user.room.nil? - if params[:size].nil? - @logs = user.room.temperatures.sort { |a, b| b <=> a } - else - @logs = user.room.temperatures.last(params[:size].to_i).sort { |a, b| b <=> a } - end + user.create_room + end + if params[:size].nil? + @temperatures = user.room.temperatures.sort { |a, b| b <=> a } else - error!(meta: { - status: 400, - errors: [ - message: ('errors.messages.room_not_found'), - code: ErrorCodes::NOT_FOUND_ROOM - ] - }, response: {}) + @temperatures = user.room.temperatures.last(params[:size].to_i).sort { |a, b| b <=> a } end end else From 006c1d5b732bf504a1078f829acd5028f6f466fd Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Tue, 15 Dec 2015 22:10:00 +0900 Subject: [PATCH 340/358] :bug: --- app/jobs/resque_temperature_get_job.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/jobs/resque_temperature_get_job.rb b/app/jobs/resque_temperature_get_job.rb index 2d83873..33e16f9 100644 --- a/app/jobs/resque_temperature_get_job.rb +++ b/app/jobs/resque_temperature_get_job.rb @@ -6,6 +6,9 @@ def self.perform(user) `sudo ruby #{command} #{path}/data/extra/temperature.txt` centigrade = File.read("#{path}/data/extra/temperature.txt") user = User.find(user["id"]) + if user.room.nil? + user.create_room + end user.room.temperatures << Temperature.create(centigrade: centigrade) end end From 98e3fa3ce3329c37ebb5d18485d249081326a336 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Tue, 15 Dec 2015 22:12:05 +0900 Subject: [PATCH 341/358] fix status --- app/views/apis/api/v1/extra/temperature_start.jbuilder | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/apis/api/v1/extra/temperature_start.jbuilder b/app/views/apis/api/v1/extra/temperature_start.jbuilder index 3689643..75bb3fc 100644 --- a/app/views/apis/api/v1/extra/temperature_start.jbuilder +++ b/app/views/apis/api/v1/extra/temperature_start.jbuilder @@ -1,5 +1,5 @@ json.meta do - json.status 200 + json.status 201 json.message '気温取得を開始しました。' end json.response do From 8fb7e0c774bcb3aa6eeeb1f92b01de7eaf1fbf49 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Tue, 15 Dec 2015 22:15:06 +0900 Subject: [PATCH 342/358] fix degree printing --- commands/temperature.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commands/temperature.rb b/commands/temperature.rb index df9c794..69a2941 100644 --- a/commands/temperature.rb +++ b/commands/temperature.rb @@ -9,5 +9,5 @@ degree = volt/10.0 File.open(ARGV[0], "w") do |file| - file.print(volt) + file.print(degree) end \ No newline at end of file From 6ae3fb764d644ec16d9a88ba67a050f29f23ddfe Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Tue, 15 Dec 2015 22:19:56 +0900 Subject: [PATCH 343/358] change croning time --- app/apis/api/v1/extra.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/apis/api/v1/extra.rb b/app/apis/api/v1/extra.rb index 95f6dd1..1b795d3 100644 --- a/app/apis/api/v1/extra.rb +++ b/app/apis/api/v1/extra.rb @@ -21,7 +21,7 @@ class Extra < Grape::API else @user = user job = "user_#{user.id}_temperature_get_cycle" - Resque.set_schedule(job, class: 'ResqueTemperatureGetJob', cron: "* * * * *", args: user) + Resque.set_schedule(job, class: 'ResqueTemperatureGetJob', cron: "*/5 * * * *", args: user) end else error!(meta: { From db02b8a296b9d943e1ea98fe8bc5b6124e491fbf Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Wed, 16 Dec 2015 01:28:15 +0900 Subject: [PATCH 344/358] hot fix --- app/apis/api/v1/ir.rb | 4 ++-- erd.pdf | Bin 35347 -> 37046 bytes 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/apis/api/v1/ir.rb b/app/apis/api/v1/ir.rb index 459189a..15fecf1 100644 --- a/app/apis/api/v1/ir.rb +++ b/app/apis/api/v1/ir.rb @@ -65,7 +65,7 @@ class IR < Grape::API fname = "user_#{user.id}_ir_#{infrared.id}.txt" `#{command} #{path}/data/#{fname}` if File.read("#{path}/data/#{fname}").size == 0 - infrared.soft_destroy + infrared.destroy error!(meta: { status: 400, errors: [ @@ -81,7 +81,7 @@ class IR < Grape::API if group = user.infrared_groups.find_by(id: params[:group_id]) group.infrareds << infrared log = user.logs.create(name: "「#{infrared.name}」を「#{group.name}」に追加しました", status: :add_ir) - log.infrared = infrared + infrared.logs << log else error!(meta: { status: 400, diff --git a/erd.pdf b/erd.pdf index 22d948522803067c8c6c53a088c1364d8e761790..562c186a4f073765c2d214c423c7182eb2995602 100644 GIT binary patch delta 30726 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
%o_{bO*u3AdzWJpe@AqOziD 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 T9FCofm5T?Cl2SrR67GKh36ET4 delta 29051 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�;D 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 hRF_mx5W(5S(8 Date: Wed, 16 Dec 2015 04:23:35 +0900 Subject: [PATCH 345/358] :bug: hot fix --- app/apis/api/v1/infrared_group.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/apis/api/v1/infrared_group.rb b/app/apis/api/v1/infrared_group.rb index 572b15f..20c71b5 100644 --- a/app/apis/api/v1/infrared_group.rb +++ b/app/apis/api/v1/infrared_group.rb @@ -356,7 +356,7 @@ class InfraredGroup < Grape::API else if group = user.infrared_groups.find_by(id: params[:group_id]) @group = group - @infrareds = group.infrareds + @infrareds = group.infrareds.without_soft_destroyed.all else error!(meta: { status: 400, From be71b625bc3269c96dedfd6e0ebfb1511e0cad3c Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Wed, 16 Dec 2015 04:28:28 +0900 Subject: [PATCH 346/358] :bug: --- app/apis/api/v1/infrared_group.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/apis/api/v1/infrared_group.rb b/app/apis/api/v1/infrared_group.rb index 20c71b5..e3e1d05 100644 --- a/app/apis/api/v1/infrared_group.rb +++ b/app/apis/api/v1/infrared_group.rb @@ -356,7 +356,7 @@ class InfraredGroup < Grape::API else if group = user.infrared_groups.find_by(id: params[:group_id]) @group = group - @infrareds = group.infrareds.without_soft_destroyed.all + @infrareds = group.infrareds.without_soft_destroyed else error!(meta: { status: 400, From 4051cfa6f32d80278055ce7049cadc6c34a151d6 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Wed, 16 Dec 2015 04:46:46 +0900 Subject: [PATCH 347/358] :bug: fix --- app/views/apis/api/v1/group/ir/index.jbuilder | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/apis/api/v1/group/ir/index.jbuilder b/app/views/apis/api/v1/group/ir/index.jbuilder index 8b5f07b..7c1dd8a 100644 --- a/app/views/apis/api/v1/group/ir/index.jbuilder +++ b/app/views/apis/api/v1/group/ir/index.jbuilder @@ -4,6 +4,6 @@ json.meta do end json.response do json.group do - json.infrareds @group.infrareds + json.infrareds @infrareds end end From 4977406668ecfcae03da49f392182908b2e895fd Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Wed, 16 Dec 2015 11:16:20 +0900 Subject: [PATCH 348/358] rubocop -a --- app/apis/api/base.rb | 12 +- app/apis/api/v1/extra.rb | 10 +- app/apis/api/v1/infrared_group.rb | 16 +-- app/apis/api/v1/schedules.rb | 13 +- app/jobs/resque_temperature_get_job.rb | 6 +- app/models/log.rb | 1 - app/models/user.rb | 4 +- app/views/apis/api/v1/extra/ping.jbuilder | 2 +- commands/temperature.rb | 14 +- db/schema.rb | 166 +++++++++++----------- spec/factories/rooms.rb | 1 - spec/factories/temperatures.rb | 3 +- spec/models/room_spec.rb | 2 +- spec/models/temperature_spec.rb | 2 +- 14 files changed, 122 insertions(+), 130 deletions(-) diff --git a/app/apis/api/base.rb b/app/apis/api/base.rb index f0e2489..8768cf5 100644 --- a/app/apis/api/base.rb +++ b/app/apis/api/base.rb @@ -44,12 +44,12 @@ def user @user = token.user else error!(meta: { - status: 400, - errors: [ - message: ('errors.messages.invalid_auth_token'), - code: ErrorCodes::INVALID_TOKEN - ] - }, response: {}) + status: 400, + errors: [ + message: ('errors.messages.invalid_auth_token'), + code: ErrorCodes::INVALID_TOKEN + ] + }, response: {}) end else error!(meta: { diff --git a/app/apis/api/v1/extra.rb b/app/apis/api/v1/extra.rb index 1b795d3..d1b7986 100644 --- a/app/apis/api/v1/extra.rb +++ b/app/apis/api/v1/extra.rb @@ -8,7 +8,7 @@ class Extra < Grape::API params do requires :auth_token, type: String, desc: 'Auth token.' end - post '/temperature/start', jbuilder: 'api/v1/extra/temperature_start' do + post '/temperature/start', jbuilder: 'api/v1/extra/temperature_start' do if (token = AuthToken.find_by(token: params[:auth_token])) if user.info.nil? error!(meta: { @@ -21,7 +21,7 @@ class Extra < Grape::API else @user = user job = "user_#{user.id}_temperature_get_cycle" - Resque.set_schedule(job, class: 'ResqueTemperatureGetJob', cron: "*/5 * * * *", args: user) + Resque.set_schedule(job, class: 'ResqueTemperatureGetJob', cron: '*/5 * * * *', args: user) end else error!(meta: { @@ -58,9 +58,7 @@ class Extra < Grape::API }, response: {}) else @user = user - if user.room.nil? - user.create_room - end + user.create_room if user.room.nil? if params[:size].nil? @temperatures = user.room.temperatures.sort { |a, b| b <=> a } else @@ -110,4 +108,4 @@ class Extra < Grape::API end end end -end \ No newline at end of file +end diff --git a/app/apis/api/v1/infrared_group.rb b/app/apis/api/v1/infrared_group.rb index e3e1d05..edc184f 100644 --- a/app/apis/api/v1/infrared_group.rb +++ b/app/apis/api/v1/infrared_group.rb @@ -214,10 +214,10 @@ class InfraredGroup < Grape::API }, response: {}) end elsif params[:ir_id] =~ /^(([0-9]+)((\,||\-||\/)[0-9]+)*)$/ - infrareds = params[:ir_id].split(",") + infrareds = params[:ir_id].split(',') infrareds.each do |i| if infrared = user.infrareds.without_soft_destroyed.find_by(id: i.to_i) - if !group.infrareds.without_soft_destroyed.find_by(id: i.to_i) + unless group.infrareds.without_soft_destroyed.find_by(id: i.to_i) group.infrareds << infrared log = user.logs.create(name: "「#{infrared.name}」を「#{group.name}」に追加しました", status: :add_ir) infrared.logs << log @@ -236,12 +236,12 @@ class InfraredGroup < Grape::API end else error!(meta: { - status: 400, - errors: [ - message: ('errors.messages.invalid_params'), - code: ErrorCodes::INVALID_PARAMS - ] - }, response: {}) + status: 400, + errors: [ + message: ('errors.messages.invalid_params'), + code: ErrorCodes::INVALID_PARAMS + ] + }, response: {}) end else error!(meta: { diff --git a/app/apis/api/v1/schedules.rb b/app/apis/api/v1/schedules.rb index cc02943..fde0f4d 100644 --- a/app/apis/api/v1/schedules.rb +++ b/app/apis/api/v1/schedules.rb @@ -50,6 +50,7 @@ def cron_translator(array) invalid_cron end end + def cron_check_value(value, index) if value =~ /^(([0-9]+)((\,||\-||\/)[0-9]+)*||\*(\/[0-9]+)?)$/ if integer_string?(value) || value == '*' @@ -438,12 +439,12 @@ def cron_check_value(value, index) @schedule = schedule else error!(meta: { - status: 400, - errors: [ - message: ('errors.messages.schedule_not_activate'), - code: ErrorCodes::NOT_ACTIVATE_SCHEDULE - ] - }, response: {}) + status: 400, + errors: [ + message: ('errors.messages.schedule_not_activate'), + code: ErrorCodes::NOT_ACTIVATE_SCHEDULE + ] + }, response: {}) end else error!(meta: { diff --git a/app/jobs/resque_temperature_get_job.rb b/app/jobs/resque_temperature_get_job.rb index 33e16f9..ce0bdb3 100644 --- a/app/jobs/resque_temperature_get_job.rb +++ b/app/jobs/resque_temperature_get_job.rb @@ -5,10 +5,8 @@ def self.perform(user) command = File.join(path, 'commands/temperature.rb') `sudo ruby #{command} #{path}/data/extra/temperature.txt` centigrade = File.read("#{path}/data/extra/temperature.txt") - user = User.find(user["id"]) - if user.room.nil? - user.create_room - end + user = User.find(user['id']) + user.create_room if user.room.nil? user.room.temperatures << Temperature.create(centigrade: centigrade) end end diff --git a/app/models/log.rb b/app/models/log.rb index 9a82519..f753577 100644 --- a/app/models/log.rb +++ b/app/models/log.rb @@ -4,5 +4,4 @@ class Log < ActiveRecord::Base soft_deletable dependent_associations: [:loggable] enum status: %i(receive_ir send_ir update_ir destroy_ir add_ir remove_ir robot_send_ir remove_schedule create_schedule activate_schedule update_schedule delete_schedule) soft_deletable dependent_associations: [:user] - end diff --git a/app/models/user.rb b/app/models/user.rb index 5afcec7..a371417 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -12,10 +12,10 @@ class User < ActiveRecord::Base has_many :log_schedules, through: :logs, source: :loggable, source_type: 'Schedule' def schedule_logs - self.logs.where(loggable_type: "Schedule") + logs.where(loggable_type: 'Schedule') end def infrared_logs - self.logs.where(loggable_type: "Infrared") + logs.where(loggable_type: 'Infrared') end end diff --git a/app/views/apis/api/v1/extra/ping.jbuilder b/app/views/apis/api/v1/extra/ping.jbuilder index 40df9a2..70a5b74 100644 --- a/app/views/apis/api/v1/extra/ping.jbuilder +++ b/app/views/apis/api/v1/extra/ping.jbuilder @@ -1 +1 @@ -json.message "pong" \ No newline at end of file +json.message 'pong' diff --git a/commands/temperature.rb b/commands/temperature.rb index 69a2941..5964d00 100644 --- a/commands/temperature.rb +++ b/commands/temperature.rb @@ -2,12 +2,12 @@ value = 0 raw = 0 PiPiper::Spi.begin do |spi| - raw = spi.write [0b01101000,0] - value = ((raw[0]<<8) + raw[1]) & 0x03FF + raw = spi.write [0b01101000, 0] + value = ((raw[0] << 8) + raw[1]) & 0x03FF end -volt = (value * 3300)/1024 -degree = volt/10.0 +volt = (value * 3300) / 1024 +degree = volt / 10.0 -File.open(ARGV[0], "w") do |file| - file.print(degree) -end \ No newline at end of file +File.open(ARGV[0], 'w') do |file| + file.print(degree) +end diff --git a/db/schema.rb b/db/schema.rb index 17abf0b..740b284 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,114 +11,112 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20151215113239) do - - create_table "auth_tokens", force: :cascade do |t| - t.string "token" - t.integer "user_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false +ActiveRecord::Schema.define(version: 20_151_215_113_239) do + create_table 'auth_tokens', force: :cascade do |t| + t.string 'token' + t.integer 'user_id' + t.datetime 'created_at', null: false + t.datetime 'updated_at', null: false end - add_index "auth_tokens", ["user_id"], name: "index_auth_tokens_on_user_id" + add_index 'auth_tokens', ['user_id'], name: 'index_auth_tokens_on_user_id' - create_table "infrared_groups", force: :cascade do |t| - t.string "name" - t.integer "user_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + create_table 'infrared_groups', force: :cascade do |t| + t.string 'name' + t.integer 'user_id' + t.datetime 'created_at', null: false + t.datetime 'updated_at', null: false end - add_index "infrared_groups", ["user_id"], name: "index_infrared_groups_on_user_id" + add_index 'infrared_groups', ['user_id'], name: 'index_infrared_groups_on_user_id' - create_table "infrared_relationals", force: :cascade do |t| - t.integer "infrared_id" - t.integer "infrared_group_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + create_table 'infrared_relationals', force: :cascade do |t| + t.integer 'infrared_id' + t.integer 'infrared_group_id' + t.datetime 'created_at', null: false + t.datetime 'updated_at', null: false end - add_index "infrared_relationals", ["infrared_group_id"], name: "index_infrared_relationals_on_infrared_group_id" - add_index "infrared_relationals", ["infrared_id"], name: "index_infrared_relationals_on_infrared_id" - - create_table "infrareds", force: :cascade do |t| - t.string "name" - t.string "data" - t.integer "user_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.integer "count", default: 0 - t.datetime "soft_destroyed_at" + add_index 'infrared_relationals', ['infrared_group_id'], name: 'index_infrared_relationals_on_infrared_group_id' + add_index 'infrared_relationals', ['infrared_id'], name: 'index_infrared_relationals_on_infrared_id' + + create_table 'infrareds', force: :cascade do |t| + t.string 'name' + t.string 'data' + t.integer 'user_id' + t.datetime 'created_at', null: false + t.datetime 'updated_at', null: false + t.integer 'count', default: 0 + t.datetime 'soft_destroyed_at' end - add_index "infrareds", ["soft_destroyed_at"], name: "index_infrareds_on_soft_destroyed_at" - add_index "infrareds", ["user_id"], name: "index_infrareds_on_user_id" - - create_table "logs", force: :cascade do |t| - t.integer "user_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.string "name" - t.integer "status" - t.integer "loggable_id" - t.string "loggable_type" + add_index 'infrareds', ['soft_destroyed_at'], name: 'index_infrareds_on_soft_destroyed_at' + add_index 'infrareds', ['user_id'], name: 'index_infrareds_on_user_id' + + create_table 'logs', force: :cascade do |t| + t.integer 'user_id' + t.datetime 'created_at', null: false + t.datetime 'updated_at', null: false + t.string 'name' + t.integer 'status' + t.integer 'loggable_id' + t.string 'loggable_type' end - add_index "logs", ["loggable_id"], name: "index_logs_on_loggable_id" - add_index "logs", ["user_id"], name: "index_logs_on_user_id" + add_index 'logs', ['loggable_id'], name: 'index_logs_on_loggable_id' + add_index 'logs', ['user_id'], name: 'index_logs_on_user_id' - create_table "rooms", force: :cascade do |t| - t.integer "user_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + create_table 'rooms', force: :cascade do |t| + t.integer 'user_id' + t.datetime 'created_at', null: false + t.datetime 'updated_at', null: false end - add_index "rooms", ["user_id"], name: "index_rooms_on_user_id" - - create_table "schedules", force: :cascade do |t| - t.string "name" - t.text "description" - t.string "cron" - t.string "job_name" - t.integer "user_id" - t.integer "infrared_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.integer "status" - t.datetime "soft_destroyed_at" + add_index 'rooms', ['user_id'], name: 'index_rooms_on_user_id' + + create_table 'schedules', force: :cascade do |t| + t.string 'name' + t.text 'description' + t.string 'cron' + t.string 'job_name' + t.integer 'user_id' + t.integer 'infrared_id' + t.datetime 'created_at', null: false + t.datetime 'updated_at', null: false + t.integer 'status' + t.datetime 'soft_destroyed_at' end - add_index "schedules", ["infrared_id"], name: "index_schedules_on_infrared_id" - add_index "schedules", ["soft_destroyed_at"], name: "index_schedules_on_soft_destroyed_at" - add_index "schedules", ["user_id"], name: "index_schedules_on_user_id" + add_index 'schedules', ['infrared_id'], name: 'index_schedules_on_infrared_id' + add_index 'schedules', ['soft_destroyed_at'], name: 'index_schedules_on_soft_destroyed_at' + add_index 'schedules', ['user_id'], name: 'index_schedules_on_user_id' - create_table "temperatures", force: :cascade do |t| - t.integer "room_id" - t.string "centigrade" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + create_table 'temperatures', force: :cascade do |t| + t.integer 'room_id' + t.string 'centigrade' + t.datetime 'created_at', null: false + t.datetime 'updated_at', null: false end - add_index "temperatures", ["room_id"], name: "index_temperatures_on_room_id" + add_index 'temperatures', ['room_id'], name: 'index_temperatures_on_room_id' - create_table "user_infos", force: :cascade do |t| - t.string "screen_name" - t.string "hashed_password" - t.string "email" - t.string "email_for_index" - t.integer "user_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + create_table 'user_infos', force: :cascade do |t| + t.string 'screen_name' + t.string 'hashed_password' + t.string 'email' + t.string 'email_for_index' + t.integer 'user_id' + t.datetime 'created_at', null: false + t.datetime 'updated_at', null: false end - add_index "user_infos", ["user_id"], name: "index_user_infos_on_user_id" + add_index 'user_infos', ['user_id'], name: 'index_user_infos_on_user_id' - create_table "users", force: :cascade do |t| - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.datetime "soft_destroyed_at" + create_table 'users', force: :cascade do |t| + t.datetime 'created_at', null: false + t.datetime 'updated_at', null: false + t.datetime 'soft_destroyed_at' end - add_index "users", ["soft_destroyed_at"], name: "index_users_on_soft_destroyed_at" - + add_index 'users', ['soft_destroyed_at'], name: 'index_users_on_soft_destroyed_at' end diff --git a/spec/factories/rooms.rb b/spec/factories/rooms.rb index 0936608..f692efe 100644 --- a/spec/factories/rooms.rb +++ b/spec/factories/rooms.rb @@ -2,5 +2,4 @@ factory :room do user nil end - end diff --git a/spec/factories/temperatures.rb b/spec/factories/temperatures.rb index 7f0d602..0b6f09f 100644 --- a/spec/factories/temperatures.rb +++ b/spec/factories/temperatures.rb @@ -1,7 +1,6 @@ FactoryGirl.define do factory :temperature do room nil -centigrade "MyString" + centigrade 'MyString' end - end diff --git a/spec/models/room_spec.rb b/spec/models/room_spec.rb index 93fdd2c..dc75c5e 100644 --- a/spec/models/room_spec.rb +++ b/spec/models/room_spec.rb @@ -1,5 +1,5 @@ require 'rails_helper' -RSpec.describe Room, :type => :model do +RSpec.describe Room, type: :model do pending "add some examples to (or delete) #{__FILE__}" end diff --git a/spec/models/temperature_spec.rb b/spec/models/temperature_spec.rb index 888b548..68b7105 100644 --- a/spec/models/temperature_spec.rb +++ b/spec/models/temperature_spec.rb @@ -1,5 +1,5 @@ require 'rails_helper' -RSpec.describe Temperature, :type => :model do +RSpec.describe Temperature, type: :model do pending "add some examples to (or delete) #{__FILE__}" end From 02814443e539b4d4b8639588b1bab38fa0bb970e Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Wed, 16 Dec 2015 11:42:31 +0900 Subject: [PATCH 349/358] refactoring --- commands/receive.c | 44 +++++++++++++++++--------------------------- 1 file changed, 17 insertions(+), 27 deletions(-) diff --git a/commands/receive.c b/commands/receive.c index 877866a..24c5bde 100644 --- a/commands/receive.c +++ b/commands/receive.c @@ -1,8 +1,9 @@ #include #include -#include #include #include +#include + int readable = 1; // 非同期でイベントが発生した場合、コールバックにより0に設定される int pin = 7; // 入力ピン番号(wiringpiの番号) @@ -11,22 +12,8 @@ int bad_pin = 24; // bad led int span = 10; // 継続時間判定の間隔(us) int max_wait = 40000; // 最大継続時間(us) -void signalErrorCallBack(int sig) -{ - readable = 0; -} - -double getTime() //tv_sec : 指定する時間の1秒以上の部分,tv_usec : 指定する時間の1秒未満の部分 -{ - struct timeval tv; - gettimeofday(&tv, NULL); - return ((double)(tv.tv_sec) * 1000000 + (double)(tv.tv_usec)); -} - -int main(int argc, char *argv[]) -{ +int main(int argc, char *argv[]){ int result; - // スキャンデータを書きだすファイルのポインタを取得 FILE *fp; char *fileName = "irdata.txt"; @@ -36,8 +23,6 @@ int main(int argc, char *argv[]) } printf("write file: %s\n", fileName); - // signal関数は、シグナル(非同期イベント)が発生したときに、 - // そのシグナルを受信して、シグナル特有の処理を行うシグナル処理関数(シグナルハンドラ)を登録します。 if(signal(SIGINT, signalErrorCallBack) == SIG_ERR){ exit(1); } @@ -80,17 +65,25 @@ int main(int argc, char *argv[]) return 0; } -int scan(FILE *fp) -{ +void signalErrorCallBack(int sig){ + readable = 0; +} + +double getTime(){ //tv_sec : 指定する時間の1秒以上の部分,tv_usec : 指定する時間の1秒未満の部分 + struct timeval tv; + gettimeofday(&tv, NULL); + return ((double)(tv.tv_sec) * 1000000 + (double)(tv.tv_usec)); +} + +int scan(FILE *fp){ digitalWrite(good_pin, 1); digitalWrite(bad_pin, 1); - // 受光モジュールは受光するとLOWになる if(!digitalRead(pin)){ return 1; } int on, off, limit; limit = 0; - // 送信が開始されるまで待機 + while( readable && digitalRead(pin) && limit <= 50000000 ){ limit++; } @@ -102,7 +95,6 @@ int scan(FILE *fp) return 1; } - // 解析開始 while( readable ){ on = getActivateTime(0); off = getActivateTime(1); @@ -115,8 +107,7 @@ int scan(FILE *fp) return 0; } -int getActivateTime(int status) -{ +int getActivateTime(int status){ int count = 0; int max = max_wait / span; double start, end; @@ -133,7 +124,6 @@ int getActivateTime(int status) return getSpan(start, end); } -int getSpan(double t1, double t2) -{ +int getSpan(double t1, double t2){ return (int)(t2-t1); } From 4701dd22670e5851747a14eb9fe528519e7b8eec Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Wed, 16 Dec 2015 13:12:22 +0900 Subject: [PATCH 350/358] bundle exec erd --- erd.pdf | Bin 37046 -> 44022 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/erd.pdf b/erd.pdf index 562c186a4f073765c2d214c423c7182eb2995602..8243c08517dff070dee4bd7fb7a6ef7b9ae31e7f 100644 GIT binary patch delta 37838 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 delta 30839 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�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 Date: Thu, 17 Dec 2015 10:34:40 +0900 Subject: [PATCH 351/358] mv file --- app/assets/stylesheets/c3.min.css | 1 + lib/c3.min.js | 5 +++++ 2 files changed, 6 insertions(+) create mode 100755 app/assets/stylesheets/c3.min.css create mode 100755 lib/c3.min.js diff --git a/app/assets/stylesheets/c3.min.css b/app/assets/stylesheets/c3.min.css new file mode 100755 index 0000000..08e5084 --- /dev/null +++ b/app/assets/stylesheets/c3.min.css @@ -0,0 +1 @@ +.c3 svg{font:10px sans-serif}.c3 line,.c3 path{fill:none;stroke:#000}.c3 text{-webkit-user-select:none;-moz-user-select:none;user-select:none}.c3-bars path,.c3-event-rect,.c3-legend-item-tile,.c3-xgrid-focus,.c3-ygrid{shape-rendering:crispEdges}.c3-chart-arc path{stroke:#fff}.c3-chart-arc text{fill:#fff;font-size:13px}.c3-grid line{stroke:#aaa}.c3-grid text{fill:#aaa}.c3-xgrid,.c3-ygrid{stroke-dasharray:3 3}.c3-text.c3-empty{fill:gray;font-size:2em}.c3-line{stroke-width:1px}.c3-circle._expanded_{stroke-width:1px;stroke:#fff}.c3-selected-circle{fill:#fff;stroke-width:2px}.c3-bar{stroke-width:0}.c3-bar._expanded_{fill-opacity:.75}.c3-target.c3-focused{opacity:1}.c3-target.c3-focused path.c3-line,.c3-target.c3-focused path.c3-step{stroke-width:2px}.c3-target.c3-defocused{opacity:.3!important}.c3-region{fill:#4682b4;fill-opacity:.1}.c3-brush .extent{fill-opacity:.1}.c3-legend-item{font-size:12px}.c3-legend-item-hidden{opacity:.15}.c3-legend-background{opacity:.75;fill:#fff;stroke:#d3d3d3;stroke-width:1}.c3-tooltip-container{z-index:10}.c3-tooltip{border-collapse:collapse;border-spacing:0;background-color:#fff;empty-cells:show;-webkit-box-shadow:7px 7px 12px -9px #777;-moz-box-shadow:7px 7px 12px -9px #777;box-shadow:7px 7px 12px -9px #777;opacity:.9}.c3-tooltip tr{border:1px solid #CCC}.c3-tooltip th{background-color:#aaa;font-size:14px;padding:2px 5px;text-align:left;color:#FFF}.c3-tooltip td{font-size:13px;padding:3px 6px;background-color:#fff;border-left:1px dotted #999}.c3-tooltip td>span{display:inline-block;width:10px;height:10px;margin-right:6px}.c3-tooltip td.value{text-align:right}.c3-area{stroke-width:0;opacity:.2}.c3-chart-arcs-title{dominant-baseline:middle;font-size:1.3em}.c3-chart-arcs .c3-chart-arcs-background{fill:#e0e0e0;stroke:none}.c3-chart-arcs .c3-chart-arcs-gauge-unit{fill:#000;font-size:16px}.c3-chart-arcs .c3-chart-arcs-gauge-max,.c3-chart-arcs .c3-chart-arcs-gauge-min{fill:#777}.c3-chart-arc .c3-gauge-value{fill:#000} \ No newline at end of file diff --git a/lib/c3.min.js b/lib/c3.min.js new file mode 100755 index 0000000..d99c28b --- /dev/null +++ b/lib/c3.min.js @@ -0,0 +1,5 @@ +!function(a){"use strict";function b(a){this.owner=a}function c(a,b){if(Object.create)b.prototype=Object.create(a.prototype);else{var c=function(){};c.prototype=a.prototype,b.prototype=new c}return b.prototype.constructor=b,b}function d(a){var b=this.internal=new e(this);b.loadConfig(a),b.init(),function c(a,b,d){Object.keys(a).forEach(function(e){b[e]=a[e].bind(d),Object.keys(a[e]).length>0&&c(a[e],b[e],d)})}(h,this,this)}function e(b){var c=this;c.d3=a.d3?a.d3:"undefined"!=typeof require?require("d3"):void 0,c.api=b,c.config=c.getDefaultConfig(),c.data={},c.cache={},c.axes={}}function f(a){b.call(this,a)}function g(a,b){function c(a,b){a.attr("transform",function(a){return"translate("+Math.ceil(b(a)+u)+", 0)"})}function d(a,b){a.attr("transform",function(a){return"translate(0,"+Math.ceil(b(a))+")"})}function e(a){var b=a[0],c=a[a.length-1];return c>b?[b,c]:[c,b]}function f(a){var b,c,d=[];if(a.ticks)return a.ticks.apply(a,n);for(c=a.domain(),b=Math.ceil(c[0]);b0&&d[0]>0&&d.unshift(d[0]-(d[1]-d[0])),d}function g(){var a,c=p.copy();return b.isCategory&&(a=p.domain(),c.domain([a[0],a[1]-1])),c}function h(a){var b=m?m(a):a;return"undefined"!=typeof b?b:""}function i(a){if(z)return z;var b={h:11.5,w:5.5};return a.select("text").text(h).each(function(a){var c=this.getBoundingClientRect(),d=h(a),e=c.height,f=d?c.width/d.length:void 0;e&&f&&(b.h=e,b.w=f)}).text(""),z=b,b}function j(c){return b.withoutTransition?c:a.transition(c)}function k(m){m.each(function(){function m(a,c){function d(a,b){f=void 0;for(var h=1;hc)return d(a.concat(b.substr(0,f?f:h)),b.slice(f?f+1:h));return a.concat(b)}var e,f,g,i=h(a),j=[];return"[object Array]"===Object.prototype.toString.call(i)?i:((!c||0>=c)&&(c=X?95:b.isCategory?Math.ceil(F(G[1])-F(G[0]))-12:110),d(j,i+""))}function n(a,b){var c=U.h;return 0===b&&(c="left"===q||"right"===q?-((V[a.index]-1)*(U.h/2)-3):".71em"),c}function v(a){var b=p(a)+(o?0:u);return L[0]0?"start":"end":"middle"}function x(a){return a?"rotate("+a+")":""}function y(a){return a?8*Math.sin(Math.PI*(a/180)):0}function z(a){return a?11.5-2.5*(a/15)*(a>0?1:-1):W}var A,B,C,D=k.g=a.select(this),E=this.__chart__||p,F=this.__chart__=g(),G=t?t:f(F),H=D.selectAll(".tick").data(G,F),I=H.enter().insert("g",".domain").attr("class","tick").style("opacity",1e-6),J=H.exit().remove(),K=j(H).style("opacity",1),L=p.rangeExtent?p.rangeExtent():e(p.range()),M=D.selectAll(".domain").data([0]),N=(M.enter().append("path").attr("class","domain"),j(M));I.append("line"),I.append("text");var O=I.select("line"),P=K.select("line"),Q=I.select("text"),R=K.select("text");b.isCategory?(u=Math.ceil((F(1)-F(0))/2),B=o?0:u,C=o?u:0):u=B=0;var S,T,U=i(D.select(".tick")),V=[],W=Math.max(r,0)+s,X="left"===q||"right"===q;S=H.select("text"),T=S.selectAll("tspan").data(function(a,c){var d=b.tickMultiline?m(a,b.tickWidth):[].concat(h(a));return V[c]=d.length,d.map(function(a){return{index:c,splitted:a}})}),T.enter().append("tspan"),T.exit().remove(),T.text(function(a){return a.splitted});var Y=b.tickTextRotate;switch(q){case"bottom":A=c,O.attr("y2",r),Q.attr("y",W),P.attr("x1",B).attr("x2",B).attr("y2",v),R.attr("x",0).attr("y",z(Y)).style("text-anchor",w(Y)).attr("transform",x(Y)),T.attr("x",0).attr("dy",n).attr("dx",y(Y)),N.attr("d","M"+L[0]+","+l+"V0H"+L[1]+"V"+l);break;case"top":A=c,O.attr("y2",-r),Q.attr("y",-W),P.attr("x2",0).attr("y2",-r),R.attr("x",0).attr("y",-W),S.style("text-anchor","middle"),T.attr("x",0).attr("dy","0em"),N.attr("d","M"+L[0]+","+-l+"V0H"+L[1]+"V"+-l);break;case"left":A=d,O.attr("x2",-r),Q.attr("x",-W),P.attr("x2",-r).attr("y1",C).attr("y2",C),R.attr("x",-W).attr("y",u),S.style("text-anchor","end"),T.attr("x",-W).attr("dy",n),N.attr("d","M"+-l+","+L[0]+"H0V"+L[1]+"H"+-l);break;case"right":A=d,O.attr("x2",r),Q.attr("x",W),P.attr("x2",r).attr("y2",0),R.attr("x",W).attr("y",0),S.style("text-anchor","start"),T.attr("x",W).attr("dy",n),N.attr("d","M"+l+","+L[0]+"H0V"+L[1]+"H"+l)}if(F.rangeBand){var Z=F,$=Z.rangeBand()/2;E=F=function(a){return Z(a)+$}}else E.rangeBand?E=F:J.call(A,F);I.call(A,E),K.call(A,F)})}var l,m,n,o,p=a.scale.linear(),q="bottom",r=6,s=3,t=null,u=0,v=!0;return b=b||{},l=b.withOuterTick?6:0,k.scale=function(a){return arguments.length?(p=a,k):p},k.orient=function(a){return arguments.length?(q=a in{top:1,right:1,bottom:1,left:1}?a+"":"bottom",k):q},k.tickFormat=function(a){return arguments.length?(m=a,k):m},k.tickCentered=function(a){return arguments.length?(o=a,k):o},k.tickOffset=function(){return u},k.tickInterval=function(){var a,c;return b.isCategory?a=2*u:(c=k.g.select("path.domain").node().getTotalLength()-2*l,a=c/k.g.selectAll("line").size()),1/0===a?0:a},k.ticks=function(){return arguments.length?(n=arguments,k):n},k.tickCulling=function(a){return arguments.length?(v=a,k):v},k.tickValues=function(a){if("function"==typeof a)t=function(){return a(p.domain())};else{if(!arguments.length)return t;t=a}return k},k}var h,i,j,k={version:"0.4.10"};k.generate=function(a){return new d(a)},k.chart={fn:d.prototype,internal:{fn:e.prototype,axis:{fn:f.prototype}}},h=k.chart.fn,i=k.chart.internal.fn,j=k.chart.internal.axis.fn,i.init=function(){var a=this,b=a.config;if(a.initParams(),b.data_url)a.convertUrlToData(b.data_url,b.data_mimeType,b.data_keys,a.initWithData);else if(b.data_json)a.initWithData(a.convertJsonToData(b.data_json,b.data_keys));else if(b.data_rows)a.initWithData(a.convertRowsToData(b.data_rows));else{if(!b.data_columns)throw Error("url or json or rows or columns is required.");a.initWithData(a.convertColumnsToData(b.data_columns))}},i.initParams=function(){var a=this,b=a.d3,c=a.config;a.clipId="c3-"+ +new Date+"-clip",a.clipIdForXAxis=a.clipId+"-xaxis",a.clipIdForYAxis=a.clipId+"-yaxis",a.clipIdForGrid=a.clipId+"-grid",a.clipIdForSubchart=a.clipId+"-subchart",a.clipPath=a.getClipPath(a.clipId),a.clipPathForXAxis=a.getClipPath(a.clipIdForXAxis),a.clipPathForYAxis=a.getClipPath(a.clipIdForYAxis),a.clipPathForGrid=a.getClipPath(a.clipIdForGrid),a.clipPathForSubchart=a.getClipPath(a.clipIdForSubchart),a.dragStart=null,a.dragging=!1,a.flowing=!1,a.cancelClick=!1,a.mouseover=!1,a.transiting=!1,a.color=a.generateColor(),a.levelColor=a.generateLevelColor(),a.dataTimeFormat=c.data_xLocaltime?b.time.format:b.time.format.utc,a.axisTimeFormat=c.axis_x_localtime?b.time.format:b.time.format.utc,a.defaultAxisTimeFormat=a.axisTimeFormat.multi([[".%L",function(a){return a.getMilliseconds()}],[":%S",function(a){return a.getSeconds()}],["%I:%M",function(a){return a.getMinutes()}],["%I %p",function(a){return a.getHours()}],["%-m/%-d",function(a){return a.getDay()&&1!==a.getDate()}],["%-m/%-d",function(a){return 1!==a.getDate()}],["%-m/%-d",function(a){return a.getMonth()}],["%Y/%-m/%-d",function(){return!0}]]),a.hiddenTargetIds=[],a.hiddenLegendIds=[],a.focusedTargetIds=[],a.defocusedTargetIds=[],a.xOrient=c.axis_rotated?"left":"bottom",a.yOrient=c.axis_rotated?c.axis_y_inner?"top":"bottom":c.axis_y_inner?"right":"left",a.y2Orient=c.axis_rotated?c.axis_y2_inner?"bottom":"top":c.axis_y2_inner?"left":"right",a.subXOrient=c.axis_rotated?"left":"bottom",a.isLegendRight="right"===c.legend_position,a.isLegendInset="inset"===c.legend_position,a.isLegendTop="top-left"===c.legend_inset_anchor||"top-right"===c.legend_inset_anchor,a.isLegendLeft="top-left"===c.legend_inset_anchor||"bottom-left"===c.legend_inset_anchor,a.legendStep=0,a.legendItemWidth=0,a.legendItemHeight=0,a.currentMaxTickWidths={x:0,y:0,y2:0},a.rotated_padding_left=30,a.rotated_padding_right=c.axis_rotated&&!c.axis_x_show?0:30,a.rotated_padding_top=5,a.withoutFadeIn={},a.intervalForObserveInserted=void 0,a.axes.subx=b.selectAll([])},i.initChartElements=function(){this.initBar&&this.initBar(),this.initLine&&this.initLine(),this.initArc&&this.initArc(),this.initGauge&&this.initGauge(),this.initText&&this.initText()},i.initWithData=function(b){var c,d,e=this,g=e.d3,h=e.config,i=!0;e.axis=new f(e),e.initPie&&e.initPie(),e.initBrush&&e.initBrush(),e.initZoom&&e.initZoom(),e.selectChart=h.bindto?"function"==typeof h.bindto.node?h.bindto:g.select(h.bindto):g.selectAll([]),e.selectChart.empty()&&(e.selectChart=g.select(document.createElement("div")).style("opacity",0),e.observeInserted(e.selectChart),i=!1),e.selectChart.html("").classed("c3",!0),e.data.xs={},e.data.targets=e.convertDataToTargets(b),h.data_filter&&(e.data.targets=e.data.targets.filter(h.data_filter)),h.data_hide&&e.addHiddenTargetIds(h.data_hide===!0?e.mapToIds(e.data.targets):h.data_hide),h.legend_hide&&e.addHiddenLegendIds(h.legend_hide===!0?e.mapToIds(e.data.targets):h.legend_hide),e.hasType("gauge")&&(h.legend_show=!1),e.updateSizes(),e.updateScales(),e.x.domain(g.extent(e.getXDomain(e.data.targets))),e.y.domain(e.getYDomain(e.data.targets,"y")),e.y2.domain(e.getYDomain(e.data.targets,"y2")),e.subX.domain(e.x.domain()),e.subY.domain(e.y.domain()),e.subY2.domain(e.y2.domain()),e.orgXDomain=e.x.domain(),e.brush&&e.brush.scale(e.subX),h.zoom_enabled&&e.zoom.scale(e.x),e.svg=e.selectChart.append("svg").style("overflow","hidden").on("mouseenter",function(){return h.onmouseover.call(e)}).on("mouseleave",function(){return h.onmouseout.call(e)}),c=e.svg.append("defs"),e.clipChart=e.appendClip(c,e.clipId),e.clipXAxis=e.appendClip(c,e.clipIdForXAxis),e.clipYAxis=e.appendClip(c,e.clipIdForYAxis),e.clipGrid=e.appendClip(c,e.clipIdForGrid),e.clipSubchart=e.appendClip(c,e.clipIdForSubchart),e.updateSvgSize(),d=e.main=e.svg.append("g").attr("transform",e.getTranslate("main")),e.initSubchart&&e.initSubchart(),e.initTooltip&&e.initTooltip(),e.initLegend&&e.initLegend(),d.append("text").attr("class",l.text+" "+l.empty).attr("text-anchor","middle").attr("dominant-baseline","middle"),e.initRegion(),e.initGrid(),d.append("g").attr("clip-path",e.clipPath).attr("class",l.chart),h.grid_lines_front&&e.initGridLines(),e.initEventRect(),e.initChartElements(),d.insert("rect",h.zoom_privileged?null:"g."+l.regions).attr("class",l.zoomRect).attr("width",e.width).attr("height",e.height).style("opacity",0).on("dblclick.zoom",null),h.axis_x_extent&&e.brush.extent(e.getDefaultExtent()),e.axis.init(),e.updateTargets(e.data.targets),i&&(e.updateDimension(),e.config.oninit.call(e),e.redraw({withTransition:!1,withTransform:!0,withUpdateXDomain:!0,withUpdateOrgXDomain:!0,withTransitionForAxis:!1})),null==a.onresize&&(a.onresize=e.generateResize()),a.onresize.add&&(a.onresize.add(function(){h.onresize.call(e)}),a.onresize.add(function(){e.api.flush()}),a.onresize.add(function(){h.onresized.call(e)})),e.api.element=e.selectChart.node()},i.smoothLines=function(a,b){var c=this;"grid"===b&&a.each(function(){var a=c.d3.select(this),b=a.attr("x1"),d=a.attr("x2"),e=a.attr("y1"),f=a.attr("y2");a.attr({x1:Math.ceil(b),x2:Math.ceil(d),y1:Math.ceil(e),y2:Math.ceil(f)})})},i.updateSizes=function(){var a=this,b=a.config,c=a.legend?a.getLegendHeight():0,d=a.legend?a.getLegendWidth():0,e=a.isLegendRight||a.isLegendInset?0:c,f=a.hasArcType(),g=b.axis_rotated||f?0:a.getHorizontalAxisHeight("x"),h=b.subchart_show&&!f?b.subchart_size_height+g:0;a.currentWidth=a.getCurrentWidth(),a.currentHeight=a.getCurrentHeight(),a.margin=b.axis_rotated?{top:a.getHorizontalAxisHeight("y2")+a.getCurrentPaddingTop(),right:f?0:a.getCurrentPaddingRight(),bottom:a.getHorizontalAxisHeight("y")+e+a.getCurrentPaddingBottom(),left:h+(f?0:a.getCurrentPaddingLeft())}:{top:4+a.getCurrentPaddingTop(),right:f?0:a.getCurrentPaddingRight(),bottom:g+h+e+a.getCurrentPaddingBottom(),left:f?0:a.getCurrentPaddingLeft()},a.margin2=b.axis_rotated?{top:a.margin.top,right:0/0,bottom:20+e,left:a.rotated_padding_left}:{top:a.currentHeight-h-e,right:0/0,bottom:g+e,left:a.margin.left},a.margin3={top:0,right:0/0,bottom:0,left:0},a.updateSizeForLegend&&a.updateSizeForLegend(c,d),a.width=a.currentWidth-a.margin.left-a.margin.right,a.height=a.currentHeight-a.margin.top-a.margin.bottom,a.width<0&&(a.width=0),a.height<0&&(a.height=0),a.width2=b.axis_rotated?a.margin.left-a.rotated_padding_left-a.rotated_padding_right:a.width,a.height2=b.axis_rotated?a.height:a.currentHeight-a.margin2.top-a.margin2.bottom,a.width2<0&&(a.width2=0),a.height2<0&&(a.height2=0),a.arcWidth=a.width-(a.isLegendRight?d+10:0),a.arcHeight=a.height-(a.isLegendRight?0:10),a.hasType("gauge")&&(a.arcHeight+=a.height-a.getGaugeLabelHeight()),a.updateRadius&&a.updateRadius(),a.isLegendRight&&f&&(a.margin3.left=a.arcWidth/2+1.1*a.radiusExpanded)},i.updateTargets=function(a){var b=this;b.updateTargetsForText(a),b.updateTargetsForBar(a),b.updateTargetsForLine(a),b.hasArcType()&&b.updateTargetsForArc&&b.updateTargetsForArc(a),b.updateTargetsForSubchart&&b.updateTargetsForSubchart(a),b.showTargets()},i.showTargets=function(){var a=this;a.svg.selectAll("."+l.target).filter(function(b){return a.isTargetToShow(b.id)}).transition().duration(a.config.transition_duration).style("opacity",1)},i.redraw=function(a,b){var c,d,e,f,g,h,i,j,k,m,n,o,p,q,r,s,t,u,v,x,y,z,A,B,C,D,E,F,G,H=this,I=H.main,J=H.d3,K=H.config,L=H.getShapeIndices(H.isAreaType),M=H.getShapeIndices(H.isBarType),N=H.getShapeIndices(H.isLineType),O=H.hasArcType(),P=H.filterTargetsToShow(H.data.targets),Q=H.xv.bind(H);if(a=a||{},c=w(a,"withY",!0),d=w(a,"withSubchart",!0),e=w(a,"withTransition",!0),h=w(a,"withTransform",!1),i=w(a,"withUpdateXDomain",!1),j=w(a,"withUpdateOrgXDomain",!1),k=w(a,"withTrimXDomain",!0),p=w(a,"withUpdateXAxis",i),m=w(a,"withLegend",!1),n=w(a,"withEventRect",!0),o=w(a,"withDimension",!0),f=w(a,"withTransitionForExit",e),g=w(a,"withTransitionForAxis",e),v=e?K.transition_duration:0,x=f?v:0,y=g?v:0,b=b||H.axis.generateTransitions(y),m&&K.legend_show?H.updateLegend(H.mapToIds(H.data.targets),a,b):o&&H.updateDimension(!0),H.isCategorized()&&0===P.length&&H.x.domain([0,H.axes.x.selectAll(".tick").size()]),P.length?(H.updateXDomain(P,i,j,k),K.axis_x_tick_values||(B=H.axis.updateXAxisTickValues(P))):(H.xAxis.tickValues([]),H.subXAxis.tickValues([])),K.zoom_rescale&&!a.flow&&(E=H.x.orgDomain()),H.y.domain(H.getYDomain(P,"y",E)),H.y2.domain(H.getYDomain(P,"y2",E)),!K.axis_y_tick_values&&K.axis_y_tick_count&&H.yAxis.tickValues(H.axis.generateTickValues(H.y.domain(),K.axis_y_tick_count)),!K.axis_y2_tick_values&&K.axis_y2_tick_count&&H.y2Axis.tickValues(H.axis.generateTickValues(H.y2.domain(),K.axis_y2_tick_count)),H.axis.redraw(b,O),H.axis.updateLabels(e),(i||p)&&P.length)if(K.axis_x_tick_culling&&B){for(C=1;C=0&&J.select(this).style("display",b%D?"none":"block")})}else H.svg.selectAll("."+l.axisX+" .tick text").style("display","block");q=H.generateDrawArea?H.generateDrawArea(L,!1):void 0,r=H.generateDrawBar?H.generateDrawBar(M):void 0,s=H.generateDrawLine?H.generateDrawLine(N,!1):void 0,t=H.generateXYForText(L,M,N,!0),u=H.generateXYForText(L,M,N,!1),c&&(H.subY.domain(H.getYDomain(P,"y")),H.subY2.domain(H.getYDomain(P,"y2"))),H.tooltip.style("display","none"),H.updateXgridFocus(),I.select("text."+l.text+"."+l.empty).attr("x",H.width/2).attr("y",H.height/2).text(K.data_empty_label_text).transition().style("opacity",P.length?0:1),H.updateGrid(v),H.updateRegion(v),H.updateBar(x),H.updateLine(x),H.updateArea(x),H.updateCircle(),H.hasDataLabel()&&H.updateText(x),H.redrawArc&&H.redrawArc(v,x,h),H.redrawSubchart&&H.redrawSubchart(d,b,v,x,L,M,N),I.selectAll("."+l.selectedCircles).filter(H.isBarType.bind(H)).selectAll("circle").remove(),K.interaction_enabled&&!a.flow&&n&&(H.redrawEventRect(),H.updateZoom&&H.updateZoom()),H.updateCircleY(),F=(H.config.axis_rotated?H.circleY:H.circleX).bind(H),G=(H.config.axis_rotated?H.circleX:H.circleY).bind(H),a.flow&&(A=H.generateFlow({targets:P,flow:a.flow,duration:a.flow.duration,drawBar:r,drawLine:s,drawArea:q,cx:F,cy:G,xv:Q,xForText:t,yForText:u})),(v||A)&&H.isTabVisible()?J.transition().duration(v).each(function(){var b=[];[H.redrawBar(r,!0),H.redrawLine(s,!0),H.redrawArea(q,!0),H.redrawCircle(F,G,!0),H.redrawText(t,u,a.flow,!0),H.redrawRegion(!0),H.redrawGrid(!0)].forEach(function(a){a.forEach(function(a){b.push(a)})}),z=H.generateWait(),b.forEach(function(a){z.add(a)})}).call(z,function(){A&&A(),K.onrendered&&K.onrendered.call(H)}):(H.redrawBar(r),H.redrawLine(s),H.redrawArea(q),H.redrawCircle(F,G),H.redrawText(t,u,a.flow),H.redrawRegion(),H.redrawGrid(),K.onrendered&&K.onrendered.call(H)),H.mapToIds(H.data.targets).forEach(function(a){H.withoutFadeIn[a]=!0})},i.updateAndRedraw=function(a){var b,c=this,d=c.config;a=a||{},a.withTransition=w(a,"withTransition",!0),a.withTransform=w(a,"withTransform",!1),a.withLegend=w(a,"withLegend",!1),a.withUpdateXDomain=!0,a.withUpdateOrgXDomain=!0,a.withTransitionForExit=!1,a.withTransitionForTransform=w(a,"withTransitionForTransform",a.withTransition),c.updateSizes(),a.withLegend&&d.legend_show||(b=c.axis.generateTransitions(a.withTransitionForAxis?d.transition_duration:0),c.updateScales(),c.updateSvgSize(),c.transformAll(a.withTransitionForTransform,b)),c.redraw(a,b)},i.redrawWithoutRescale=function(){this.redraw({withY:!1,withSubchart:!1,withEventRect:!1,withTransitionForAxis:!1})},i.isTimeSeries=function(){return"timeseries"===this.config.axis_x_type},i.isCategorized=function(){return this.config.axis_x_type.indexOf("categor")>=0},i.isCustomX=function(){var a=this,b=a.config;return!a.isTimeSeries()&&(b.data_x||v(b.data_xs))},i.isTimeSeriesY=function(){return"timeseries"===this.config.axis_y_type},i.getTranslate=function(a){var b,c,d=this,e=d.config;return"main"===a?(b=s(d.margin.left),c=s(d.margin.top)):"context"===a?(b=s(d.margin2.left),c=s(d.margin2.top)):"legend"===a?(b=d.margin3.left,c=d.margin3.top):"x"===a?(b=0,c=e.axis_rotated?0:d.height):"y"===a?(b=0,c=e.axis_rotated?d.height:0):"y2"===a?(b=e.axis_rotated?0:d.width,c=e.axis_rotated?1:0):"subx"===a?(b=0,c=e.axis_rotated?0:d.height2):"arc"===a&&(b=d.arcWidth/2,c=d.arcHeight/2),"translate("+b+","+c+")"},i.initialOpacity=function(a){return null!==a.value&&this.withoutFadeIn[a.id]?1:0},i.initialOpacityForCircle=function(a){return null!==a.value&&this.withoutFadeIn[a.id]?this.opacityForCircle(a):0},i.opacityForCircle=function(a){var b=this.config.point_show?1:0;return m(a.value)?this.isScatterType(a)?.5:b:0},i.opacityForText=function(){return this.hasDataLabel()?1:0},i.xx=function(a){return a?this.x(a.x):null},i.xv=function(a){var b=this,c=a.value;return b.isTimeSeries()?c=b.parseDate(a.value):b.isCategorized()&&"string"==typeof a.value&&(c=b.config.axis_x_categories.indexOf(a.value)),Math.ceil(b.x(c))},i.yv=function(a){var b=this,c=a.axis&&"y2"===a.axis?b.y2:b.y;return Math.ceil(c(a.value))},i.subxx=function(a){return a?this.subX(a.x):null},i.transformMain=function(a,b){var c,d,e,f=this;b&&b.axisX?c=b.axisX:(c=f.main.select("."+l.axisX),a&&(c=c.transition())),b&&b.axisY?d=b.axisY:(d=f.main.select("."+l.axisY),a&&(d=d.transition())),b&&b.axisY2?e=b.axisY2:(e=f.main.select("."+l.axisY2),a&&(e=e.transition())),(a?f.main.transition():f.main).attr("transform",f.getTranslate("main")),c.attr("transform",f.getTranslate("x")),d.attr("transform",f.getTranslate("y")),e.attr("transform",f.getTranslate("y2")),f.main.select("."+l.chartArcs).attr("transform",f.getTranslate("arc"))},i.transformAll=function(a,b){var c=this;c.transformMain(a,b),c.config.subchart_show&&c.transformContext(a,b),c.legend&&c.transformLegend(a)},i.updateSvgSize=function(){var a=this,b=a.svg.select(".c3-brush .background");a.svg.attr("width",a.currentWidth).attr("height",a.currentHeight),a.svg.selectAll(["#"+a.clipId,"#"+a.clipIdForGrid]).select("rect").attr("width",a.width).attr("height",a.height),a.svg.select("#"+a.clipIdForXAxis).select("rect").attr("x",a.getXAxisClipX.bind(a)).attr("y",a.getXAxisClipY.bind(a)).attr("width",a.getXAxisClipWidth.bind(a)).attr("height",a.getXAxisClipHeight.bind(a)),a.svg.select("#"+a.clipIdForYAxis).select("rect").attr("x",a.getYAxisClipX.bind(a)).attr("y",a.getYAxisClipY.bind(a)).attr("width",a.getYAxisClipWidth.bind(a)).attr("height",a.getYAxisClipHeight.bind(a)),a.svg.select("#"+a.clipIdForSubchart).select("rect").attr("width",a.width).attr("height",b.size()?b.attr("height"):0),a.svg.select("."+l.zoomRect).attr("width",a.width).attr("height",a.height),a.selectChart.style("max-height",a.currentHeight+"px")},i.updateDimension=function(a){var b=this;a||(b.config.axis_rotated?(b.axes.x.call(b.xAxis),b.axes.subx.call(b.subXAxis)):(b.axes.y.call(b.yAxis),b.axes.y2.call(b.y2Axis))),b.updateSizes(),b.updateScales(),b.updateSvgSize(),b.transformAll(!1)},i.observeInserted=function(b){var c,d=this;return"undefined"==typeof MutationObserver?void a.console.error("MutationObserver not defined."):(c=new MutationObserver(function(e){e.forEach(function(e){"childList"===e.type&&e.previousSibling&&(c.disconnect(),d.intervalForObserveInserted=a.setInterval(function(){b.node().parentNode&&(a.clearInterval(d.intervalForObserveInserted),d.updateDimension(),d.config.oninit.call(d),d.redraw({withTransform:!0,withUpdateXDomain:!0,withUpdateOrgXDomain:!0,withTransition:!1,withTransitionForTransform:!1,withLegend:!0}),b.transition().style("opacity",1))},10))})}),void c.observe(b.node(),{attributes:!0,childList:!0,characterData:!0}))},i.generateResize=function(){function a(){b.forEach(function(a){a()})}var b=[];return a.add=function(a){b.push(a)},a},i.endall=function(a,b){var c=0;a.each(function(){++c}).each("end",function(){--c||b.apply(this,arguments)})},i.generateWait=function(){var a=[],b=function(b,c){var d=setInterval(function(){var b=0;a.forEach(function(a){if(a.empty())return void(b+=1);try{a.transition()}catch(c){b+=1}}),b===a.length&&(clearInterval(d),c&&c())},10)};return b.add=function(b){a.push(b)},b},i.parseDate=function(b){var c,d=this;return b instanceof Date?c=b:"string"==typeof b?c=d.dataTimeFormat(d.config.data_xFormat).parse(b):"number"!=typeof b&&isNaN(b)||(c=new Date(+b)),(!c||isNaN(+c))&&a.console.error("Failed to parse x '"+b+"' to Date object"),c},i.isTabVisible=function(){var a;return"undefined"!=typeof document.hidden?a="hidden":"undefined"!=typeof document.mozHidden?a="mozHidden":"undefined"!=typeof document.msHidden?a="msHidden":"undefined"!=typeof document.webkitHidden&&(a="webkitHidden"),document[a]?!1:!0},i.getDefaultConfig=function(){var a={bindto:"#chart",size_width:void 0,size_height:void 0,padding_left:void 0,padding_right:void 0,padding_top:void 0,padding_bottom:void 0,zoom_enabled:!1,zoom_extent:void 0,zoom_privileged:!1,zoom_rescale:!1,zoom_onzoom:function(){},zoom_onzoomstart:function(){},zoom_onzoomend:function(){},interaction_enabled:!0,onmouseover:function(){},onmouseout:function(){},onresize:function(){},onresized:function(){},oninit:function(){},onrendered:function(){},transition_duration:350,data_x:void 0,data_xs:{},data_xFormat:"%Y-%m-%d",data_xLocaltime:!0,data_xSort:!0,data_idConverter:function(a){return a},data_names:{},data_classes:{},data_groups:[],data_axes:{},data_type:void 0,data_types:{},data_labels:{},data_order:"desc",data_regions:{},data_color:void 0,data_colors:{},data_hide:!1,data_filter:void 0,data_selection_enabled:!1,data_selection_grouped:!1,data_selection_isselectable:function(){return!0},data_selection_multiple:!0,data_selection_draggable:!1,data_onclick:function(){},data_onmouseover:function(){},data_onmouseout:function(){},data_onselected:function(){},data_onunselected:function(){},data_url:void 0,data_json:void 0,data_rows:void 0,data_columns:void 0,data_mimeType:void 0,data_keys:void 0,data_empty_label_text:"",subchart_show:!1,subchart_size_height:60,subchart_onbrush:function(){},color_pattern:[],color_threshold:{},legend_show:!0,legend_hide:!1,legend_position:"bottom",legend_inset_anchor:"top-left",legend_inset_x:10,legend_inset_y:0,legend_inset_step:void 0,legend_item_onclick:void 0,legend_item_onmouseover:void 0,legend_item_onmouseout:void 0,legend_equally:!1,axis_rotated:!1,axis_x_show:!0,axis_x_type:"indexed",axis_x_localtime:!0,axis_x_categories:[],axis_x_tick_centered:!1,axis_x_tick_format:void 0,axis_x_tick_culling:{},axis_x_tick_culling_max:10,axis_x_tick_count:void 0,axis_x_tick_fit:!0,axis_x_tick_values:null,axis_x_tick_rotate:0,axis_x_tick_outer:!0,axis_x_tick_multiline:!0,axis_x_tick_width:null,axis_x_max:void 0,axis_x_min:void 0,axis_x_padding:{},axis_x_height:void 0,axis_x_extent:void 0,axis_x_label:{},axis_y_show:!0,axis_y_type:void 0,axis_y_max:void 0,axis_y_min:void 0,axis_y_inverted:!1,axis_y_center:void 0,axis_y_inner:void 0,axis_y_label:{},axis_y_tick_format:void 0,axis_y_tick_outer:!0,axis_y_tick_values:null,axis_y_tick_count:void 0,axis_y_tick_time_value:void 0,axis_y_tick_time_interval:void 0,axis_y_padding:{},axis_y_default:void 0,axis_y2_show:!1,axis_y2_max:void 0,axis_y2_min:void 0,axis_y2_inverted:!1,axis_y2_center:void 0,axis_y2_inner:void 0,axis_y2_label:{},axis_y2_tick_format:void 0,axis_y2_tick_outer:!0,axis_y2_tick_values:null,axis_y2_tick_count:void 0,axis_y2_padding:{},axis_y2_default:void 0,grid_x_show:!1,grid_x_type:"tick",grid_x_lines:[],grid_y_show:!1,grid_y_lines:[],grid_y_ticks:10,grid_focus_show:!0,grid_lines_front:!0,point_show:!0,point_r:2.5,point_focus_expand_enabled:!0,point_focus_expand_r:void 0,point_select_r:void 0,line_connectNull:!1,line_step_type:"step",bar_width:void 0,bar_width_ratio:.6,bar_width_max:void 0,bar_zerobased:!0,area_zerobased:!0,pie_label_show:!0,pie_label_format:void 0,pie_label_threshold:.05,pie_expand:!0,gauge_label_show:!0,gauge_label_format:void 0,gauge_expand:!0,gauge_min:0,gauge_max:100,gauge_units:void 0,gauge_width:void 0,donut_label_show:!0,donut_label_format:void 0,donut_label_threshold:.05,donut_width:void 0,donut_expand:!0,donut_title:"",regions:[],tooltip_show:!0,tooltip_grouped:!0,tooltip_format_title:void 0,tooltip_format_name:void 0,tooltip_format_value:void 0,tooltip_position:void 0,tooltip_contents:function(a,b,c,d){return this.getTooltipContent?this.getTooltipContent(a,b,c,d):""},tooltip_init_show:!1,tooltip_init_x:0,tooltip_init_position:{top:"0px",left:"50px"}};return Object.keys(this.additionalConfig).forEach(function(b){a[b]=this.additionalConfig[b]},this),a},i.additionalConfig={},i.loadConfig=function(a){function b(){var a=d.shift();return a&&c&&"object"==typeof c&&a in c?(c=c[a],b()):a?void 0:c}var c,d,e,f=this.config;Object.keys(f).forEach(function(g){c=a,d=g.split("_"),e=b(),q(e)&&(f[g]=e)})},i.getScale=function(a,b,c){return(c?this.d3.time.scale():this.d3.scale.linear()).range([a,b])},i.getX=function(a,b,c,d){var e,f=this,g=f.getScale(a,b,f.isTimeSeries()),h=c?g.domain(c):g;f.isCategorized()?(d=d||function(){return 0},g=function(a,b){var c=h(a)+d(a);return b?c:Math.ceil(c)}):g=function(a,b){var c=h(a);return b?c:Math.ceil(c)};for(e in h)g[e]=h[e];return g.orgDomain=function(){return h.domain()},f.isCategorized()&&(g.domain=function(a){return arguments.length?(h.domain(a),g):(a=this.orgDomain(),[a[0],a[1]+1])}),g},i.getY=function(a,b,c){var d=this.getScale(a,b,this.isTimeSeriesY());return c&&d.domain(c),d},i.getYScale=function(a){return"y2"===this.axis.getId(a)?this.y2:this.y},i.getSubYScale=function(a){return"y2"===this.axis.getId(a)?this.subY2:this.subY},i.updateScales=function(){var a=this,b=a.config,c=!a.x;a.xMin=b.axis_rotated?1:0,a.xMax=b.axis_rotated?a.height:a.width,a.yMin=b.axis_rotated?0:a.height,a.yMax=b.axis_rotated?a.width:1,a.subXMin=a.xMin,a.subXMax=a.xMax,a.subYMin=b.axis_rotated?0:a.height2,a.subYMax=b.axis_rotated?a.width2:1,a.x=a.getX(a.xMin,a.xMax,c?void 0:a.x.orgDomain(),function(){return a.xAxis.tickOffset()}),a.y=a.getY(a.yMin,a.yMax,c?b.axis_y_default:a.y.domain()),a.y2=a.getY(a.yMin,a.yMax,c?b.axis_y2_default:a.y2.domain()),a.subX=a.getX(a.xMin,a.xMax,a.orgXDomain,function(b){return b%1?0:a.subXAxis.tickOffset()}),a.subY=a.getY(a.subYMin,a.subYMax,c?b.axis_y_default:a.subY.domain()),a.subY2=a.getY(a.subYMin,a.subYMax,c?b.axis_y2_default:a.subY2.domain()),a.xAxisTickFormat=a.axis.getXAxisTickFormat(),a.xAxisTickValues=a.axis.getXAxisTickValues(),a.yAxisTickValues=a.axis.getYAxisTickValues(),a.y2AxisTickValues=a.axis.getY2AxisTickValues(),a.xAxis=a.axis.getXAxis(a.x,a.xOrient,a.xAxisTickFormat,a.xAxisTickValues,b.axis_x_tick_outer),a.subXAxis=a.axis.getXAxis(a.subX,a.subXOrient,a.xAxisTickFormat,a.xAxisTickValues,b.axis_x_tick_outer),a.yAxis=a.axis.getYAxis(a.y,a.yOrient,b.axis_y_tick_format,a.yAxisTickValues,b.axis_y_tick_outer),a.y2Axis=a.axis.getYAxis(a.y2,a.y2Orient,b.axis_y2_tick_format,a.y2AxisTickValues,b.axis_y2_tick_outer),c||(a.brush&&a.brush.scale(a.subX),b.zoom_enabled&&a.zoom.scale(a.x)),a.updateArc&&a.updateArc()},i.getYDomainMin=function(a){var b,c,d,e,f,g,h=this,i=h.config,j=h.mapToIds(a),k=h.getValuesAsIdKeyed(a);if(i.data_groups.length>0)for(g=h.hasNegativeValueInTargets(a),b=0;b=0}),0!==e.length)for(d=e[0],g&&k[d]&&k[d].forEach(function(a,b){k[d][b]=0>a?a:0}),c=1;c0||(k[d][b]+=+a)});return h.d3.min(Object.keys(k).map(function(a){return h.d3.min(k[a])}))},i.getYDomainMax=function(a){var b,c,d,e,f,g,h=this,i=h.config,j=h.mapToIds(a),k=h.getValuesAsIdKeyed(a);if(i.data_groups.length>0)for(g=h.hasPositiveValueInTargets(a),b=0;b=0}),0!==e.length)for(d=e[0],g&&k[d]&&k[d].forEach(function(a,b){k[d][b]=a>0?a:0}),c=1;c+a||(k[d][b]+=+a)});return h.d3.max(Object.keys(k).map(function(a){return h.d3.max(k[a])}))},i.getYDomain=function(a,b,c){var d,e,f,g,h,i,j,k,l,n,o,p=this,q=p.config,r=a.filter(function(a){return p.axis.getId(a.id)===b}),s=c?p.filterByXDomain(r,c):r,u="y2"===b?q.axis_y2_min:q.axis_y_min,w="y2"===b?q.axis_y2_max:q.axis_y_max,x=p.getYDomainMin(s),y=p.getYDomainMax(s),z="y2"===b?q.axis_y2_center:q.axis_y_center,A=p.hasType("bar",s)&&q.bar_zerobased||p.hasType("area",s)&&q.area_zerobased,B="y2"===b?q.axis_y2_inverted:q.axis_y_inverted,C=p.hasDataLabel()&&q.axis_rotated,D=p.hasDataLabel()&&!q.axis_rotated;return x=m(u)?u:m(w)?w>x?x:w-10:x,y=m(w)?w:m(u)?y>u?y:u+10:y,0===s.length?"y2"===b?p.y2.domain():p.y.domain():(isNaN(x)&&(x=0),isNaN(y)&&(y=x),x===y&&(0>x?y=0:x=0),n=x>=0&&y>=0,o=0>=x&&0>=y,(m(u)&&n||m(w)&&o)&&(A=!1),A&&(n&&(x=0),o&&(y=0)),e=Math.abs(y-x),f=g=h=.1*e,"undefined"!=typeof z&&(i=Math.max(Math.abs(x),Math.abs(y)),y=z+i,x=z-i),C?(j=p.getDataLabelLength(x,y,"width"),k=t(p.y.range()),l=[j[0]/k,j[1]/k],g+=e*(l[1]/(1-l[0]-l[1])),h+=e*(l[0]/(1-l[0]-l[1]))):D&&(j=p.getDataLabelLength(x,y,"height"),g+=p.axis.convertPixelsToAxisPadding(j[1],e),h+=p.axis.convertPixelsToAxisPadding(j[0],e)),"y"===b&&v(q.axis_y_padding)&&(g=p.axis.getPadding(q.axis_y_padding,"top",g,e),h=p.axis.getPadding(q.axis_y_padding,"bottom",h,e)),"y2"===b&&v(q.axis_y2_padding)&&(g=p.axis.getPadding(q.axis_y2_padding,"top",g,e),h=p.axis.getPadding(q.axis_y2_padding,"bottom",h,e)),A&&(n&&(h=x),o&&(g=-y)),d=[x-h,y+g],B?d.reverse():d)},i.getXDomainMin=function(a){var b=this,c=b.config;return q(c.axis_x_min)?b.isTimeSeries()?this.parseDate(c.axis_x_min):c.axis_x_min:b.d3.min(a,function(a){return b.d3.min(a.values,function(a){return a.x})})},i.getXDomainMax=function(a){var b=this,c=b.config;return q(c.axis_x_max)?b.isTimeSeries()?this.parseDate(c.axis_x_max):c.axis_x_max:b.d3.max(a,function(a){return b.d3.max(a.values,function(a){return a.x})})},i.getXDomainPadding=function(a){var b,c,d,e,f=this,g=f.config,h=a[1]-a[0];return f.isCategorized()?c=0:f.hasType("bar")?(b=f.getMaxDataCount(),c=b>1?h/(b-1)/2:.5):c=.01*h,"object"==typeof g.axis_x_padding&&v(g.axis_x_padding)?(d=m(g.axis_x_padding.left)?g.axis_x_padding.left:c,e=m(g.axis_x_padding.right)?g.axis_x_padding.right:c):d=e="number"==typeof g.axis_x_padding?g.axis_x_padding:c,{left:d,right:e}},i.getXDomain=function(a){var b=this,c=[b.getXDomainMin(a),b.getXDomainMax(a)],d=c[0],e=c[1],f=b.getXDomainPadding(c),g=0,h=0; +return d-e!==0||b.isCategorized()||(b.isTimeSeries()?(d=new Date(.5*d.getTime()),e=new Date(1.5*e.getTime())):(d=0===d?1:.5*d,e=0===e?-1:1.5*e)),(d||0===d)&&(g=b.isTimeSeries()?new Date(d.getTime()-f.left):d-f.left),(e||0===e)&&(h=b.isTimeSeries()?new Date(e.getTime()+f.right):e+f.right),[g,h]},i.updateXDomain=function(a,b,c,d,e){var f=this,g=f.config;return c&&(f.x.domain(e?e:f.d3.extent(f.getXDomain(a))),f.orgXDomain=f.x.domain(),g.zoom_enabled&&f.zoom.scale(f.x).updateScaleExtent(),f.subX.domain(f.x.domain()),f.brush&&f.brush.scale(f.subX)),b&&(f.x.domain(e?e:!f.brush||f.brush.empty()?f.orgXDomain:f.brush.extent()),g.zoom_enabled&&f.zoom.scale(f.x).updateScaleExtent()),d&&f.x.domain(f.trimXDomain(f.x.orgDomain())),f.x.domain()},i.trimXDomain=function(a){var b=this;return a[0]<=b.orgXDomain[0]&&(a[1]=+a[1]+(b.orgXDomain[0]-a[0]),a[0]=b.orgXDomain[0]),b.orgXDomain[1]<=a[1]&&(a[0]=+a[0]-(a[1]-b.orgXDomain[1]),a[1]=b.orgXDomain[1]),a},i.isX=function(a){var b=this,c=b.config;return c.data_x&&a===c.data_x||v(c.data_xs)&&x(c.data_xs,a)},i.isNotX=function(a){return!this.isX(a)},i.getXKey=function(a){var b=this,c=b.config;return c.data_x?c.data_x:v(c.data_xs)?c.data_xs[a]:null},i.getXValuesOfXKey=function(a,b){var c,d=this,e=b&&v(b)?d.mapToIds(b):[];return e.forEach(function(b){d.getXKey(b)===a&&(c=d.data.xs[b])}),c},i.getIndexByX=function(a){var b=this,c=b.filterByX(b.data.targets,a);return c.length?c[0].index:null},i.getXValue=function(a,b){var c=this;return a in c.data.xs&&c.data.xs[a]&&m(c.data.xs[a][b])?c.data.xs[a][b]:b},i.getOtherTargetXs=function(){var a=this,b=Object.keys(a.data.xs);return b.length?a.data.xs[b[0]]:null},i.getOtherTargetX=function(a){var b=this.getOtherTargetXs();return b&&a1},i.isMultipleX=function(){return v(this.config.data_xs)||!this.config.data_xSort||this.hasType("scatter")},i.addName=function(a){var b,c=this;return a&&(b=c.config.data_names[a.id],a.name=b?b:a.id),a},i.getValueOnIndex=function(a,b){var c=a.filter(function(a){return a.index===b});return c.length?c[0]:null},i.updateTargetX=function(a,b){var c=this;a.forEach(function(a){a.values.forEach(function(d,e){d.x=c.generateTargetX(b[e],a.id,e)}),c.data.xs[a.id]=b})},i.updateTargetXs=function(a,b){var c=this;a.forEach(function(a){b[a.id]&&c.updateTargetX([a],b[a.id])})},i.generateTargetX=function(a,b,c){var d,e=this;return d=e.isTimeSeries()?e.parseDate(a?a:e.getXValue(b,c)):e.isCustomX()&&!e.isCategorized()?m(a)?+a:e.getXValue(b,c):c},i.cloneTarget=function(a){return{id:a.id,id_org:a.id_org,values:a.values.map(function(a){return{x:a.x,value:a.value,id:a.id}})}},i.updateXs=function(){var a=this;a.data.targets.length&&(a.xs=[],a.data.targets[0].values.forEach(function(b){a.xs[b.index]=b.x}))},i.getPrevX=function(a){var b=this.xs[a-1];return"undefined"!=typeof b?b:null},i.getNextX=function(a){var b=this.xs[a+1];return"undefined"!=typeof b?b:null},i.getMaxDataCount=function(){var a=this;return a.d3.max(a.data.targets,function(a){return a.values.length})},i.getMaxDataCountTarget=function(a){var b,c=a.length,d=0;return c>1?a.forEach(function(a){a.values.length>d&&(b=a,d=a.values.length)}):b=c?a[0]:null,b},i.getEdgeX=function(a){var b=this;return a.length?[b.d3.min(a,function(a){return a.values[0].x}),b.d3.max(a,function(a){return a.values[a.values.length-1].x})]:[0,0]},i.mapToIds=function(a){return a.map(function(a){return a.id})},i.mapToTargetIds=function(a){var b=this;return a?o(a)?[a]:a:b.mapToIds(b.data.targets)},i.hasTarget=function(a,b){var c,d=this.mapToIds(a);for(c=0;ca})},i.hasPositiveValueInTargets=function(a){return this.checkValueInTargets(a,function(a){return a>0})},i.isOrderDesc=function(){var a=this.config;return"string"==typeof a.data_order&&"desc"===a.data_order.toLowerCase()},i.isOrderAsc=function(){var a=this.config;return"string"==typeof a.data_order&&"asc"===a.data_order.toLowerCase()},i.orderTargets=function(a){var b=this,c=b.config,d=b.isOrderAsc(),e=b.isOrderDesc();return d||e?a.sort(function(a,b){var c=function(a,b){return a+Math.abs(b.value)},e=a.values.reduce(c,0),f=b.values.reduce(c,0);return d?f-e:e-f}):n(c.data_order)&&a.sort(c.data_order),a},i.filterByX=function(a,b){return this.d3.merge(a.map(function(a){return a.values})).filter(function(a){return a.x-b===0})},i.filterRemoveNull=function(a){return a.filter(function(a){return m(a.value)})},i.filterByXDomain=function(a,b){return a.map(function(a){return{id:a.id,id_org:a.id_org,values:a.values.filter(function(a){return b[0]<=a.x&&a.x<=b[1]})}})},i.hasDataLabel=function(){var a=this.config;return"boolean"==typeof a.data_labels&&a.data_labels?!0:"object"==typeof a.data_labels&&v(a.data_labels)?!0:!1},i.getDataLabelLength=function(a,b,c){var d=this,e=[0,0],f=1.3;return d.selectChart.select("svg").selectAll(".dummy").data([a,b]).enter().append("text").text(function(a){return d.dataLabelFormat(a.id)(a)}).each(function(a,b){e[b]=this.getBoundingClientRect()[c]*f}).remove(),e},i.isNoneArc=function(a){return this.hasTarget(this.data.targets,a.id)},i.isArc=function(a){return"data"in a&&this.hasTarget(this.data.targets,a.data.id)},i.findSameXOfValues=function(a,b){var c,d=a[b].x,e=[];for(c=b-1;c>=0&&d===a[c].x;c--)e.push(a[c]);for(c=b;cf&&(e=f,c=a)}),c},i.dist=function(a,b){var c=this,d=c.config,e=d.axis_rotated?1:0,f=d.axis_rotated?0:1,g=c.circleY(a,a.index),h=c.x(a.x);return Math.pow(h-b[e],2)+Math.pow(g-b[f],2)},i.convertValuesToStep=function(a){var b,c=[].concat(a);if(!this.isCategorized())return a;for(b=a.length+1;b>0;b--)c[b]=c[b-1];return c[0]={x:c[0].x-1,value:c[0].value,id:c[0].id},c[a.length+1]={x:c[a.length].x+1,value:c[a.length].value,id:c[a.length].id},c},i.updateDataAttributes=function(a,b){var c=this,d=c.config,e=d["data_"+a];return"undefined"==typeof b?e:(Object.keys(b).forEach(function(a){e[a]=b[a]}),c.redraw({withLegend:!0}),e)},i.convertUrlToData=function(a,b,c,d){var e=this,f=b?b:"csv";e.d3.xhr(a,function(a,b){var g;if(!b)throw new Error(a.responseURL+" "+a.status+" ("+a.statusText+")");g="json"===f?e.convertJsonToData(JSON.parse(b.response),c):"tsv"===f?e.convertTsvToData(b.response):e.convertCsvToData(b.response),d.call(e,g)})},i.convertXsvToData=function(a,b){var c,d=b.parseRows(a);return 1===d.length?(c=[{}],d[0].forEach(function(a){c[0][a]=null})):c=b.parse(a),c},i.convertCsvToData=function(a){return this.convertXsvToData(a,this.d3.csv)},i.convertTsvToData=function(a){return this.convertXsvToData(a,this.d3.tsv)},i.convertJsonToData=function(a,b){var c,d,e=this,f=[];return b?(b.x?(c=b.value.concat(b.x),e.config.data_x=b.x):c=b.value,f.push(c),a.forEach(function(a){var b=[];c.forEach(function(c){var d=p(a[c])?null:a[c];b.push(d)}),f.push(b)}),d=e.convertRowsToData(f)):(Object.keys(a).forEach(function(b){f.push([b].concat(a[b]))}),d=e.convertColumnsToData(f)),d},i.convertRowsToData=function(a){var b,c,d=a[0],e={},f=[];for(b=1;b=0?d.data.xs[c]=(b&&d.data.xs[c]?d.data.xs[c]:[]).concat(a.map(function(a){return a[f]}).filter(m).map(function(a,b){return d.generateTargetX(a,c,b)})):e.data_x?d.data.xs[c]=d.getOtherTargetXs():v(e.data_xs)&&(d.data.xs[c]=d.getXValuesOfXKey(f,d.data.targets)):d.data.xs[c]=a.map(function(a,b){return b})}),f.forEach(function(a){if(!d.data.xs[a])throw new Error('x is not defined for id = "'+a+'".')}),c=f.map(function(b,c){var f=e.data_idConverter(b);return{id:f,id_org:b,values:a.map(function(a,g){var h=d.getXKey(b),i=a[h],j=d.generateTargetX(i,b,g);return d.isCustomX()&&d.isCategorized()&&0===c&&i&&(0===g&&(e.axis_x_categories=[]),e.axis_x_categories.push(i)),(p(a[b])||d.data.xs[b].length<=g)&&(j=void 0),{x:j,value:null===a[b]||isNaN(a[b])?null:+a[b],id:f}}).filter(function(a){return q(a.x)})}}),c.forEach(function(a){var b;e.data_xSort&&(a.values=a.values.sort(function(a,b){var c=a.x||0===a.x?a.x:1/0,d=b.x||0===b.x?b.x:1/0;return c-d})),b=0,a.values.forEach(function(a){a.index=b++}),d.data.xs[a.id].sort(function(a,b){return a-b})}),e.data_type&&d.setTargetType(d.mapToIds(c).filter(function(a){return!(a in e.data_types)}),e.data_type),c.forEach(function(a){d.addCache(a.id_org,a)}),c},i.load=function(a,b){var c=this;a&&(b.filter&&(a=a.filter(b.filter)),(b.type||b.types)&&a.forEach(function(a){var d=b.types&&b.types[a.id]?b.types[a.id]:b.type;c.setTargetType(a.id,d)}),c.data.targets.forEach(function(b){for(var c=0;c0?c:320/(a.hasType("gauge")?2:1)},i.getCurrentPaddingTop=function(){var a=this.config;return m(a.padding_top)?a.padding_top:0},i.getCurrentPaddingBottom=function(){var a=this.config;return m(a.padding_bottom)?a.padding_bottom:0},i.getCurrentPaddingLeft=function(a){var b=this,c=b.config;return m(c.padding_left)?c.padding_left:c.axis_rotated?c.axis_x_show?Math.max(r(b.getAxisWidthByAxisId("x",a)),40):1:!c.axis_y_show||c.axis_y_inner?b.axis.getYAxisLabelPosition().isOuter?30:1:r(b.getAxisWidthByAxisId("y",a))},i.getCurrentPaddingRight=function(){var a=this,b=a.config,c=10,d=a.isLegendRight?a.getLegendWidth()+20:0;return m(b.padding_right)?b.padding_right+1:b.axis_rotated?c+d:!b.axis_y2_show||b.axis_y2_inner?2+d+(a.axis.getY2AxisLabelPosition().isOuter?20:0):r(a.getAxisWidthByAxisId("y2"))+d},i.getParentRectValue=function(a){for(var b,c=this.selectChart.node();c&&"BODY"!==c.tagName;){try{b=c.getBoundingClientRect()[a]}catch(d){"width"===a&&(b=c.offsetWidth)}if(b)break;c=c.parentNode}return b},i.getParentWidth=function(){return this.getParentRectValue("width")},i.getParentHeight=function(){var a=this.selectChart.style("height");return a.indexOf("px")>0?+a.replace("px",""):0},i.getSvgLeft=function(a){var b=this,c=b.config,d=c.axis_rotated||!c.axis_rotated&&!c.axis_y_inner,e=c.axis_rotated?l.axisX:l.axisY,f=b.main.select("."+e).node(),g=f&&d?f.getBoundingClientRect():{right:0},h=b.selectChart.node().getBoundingClientRect(),i=b.hasArcType(),j=g.right-h.left-(i?0:b.getCurrentPaddingLeft(a));return j>0?j:0},i.getAxisWidthByAxisId=function(a,b){var c=this,d=c.axis.getLabelPositionById(a);return c.axis.getMaxTickWidth(a,b)+(d.isInner?20:40)},i.getHorizontalAxisHeight=function(a){var b=this,c=b.config,d=30;return"x"!==a||c.axis_x_show?"x"===a&&c.axis_x_height?c.axis_x_height:"y"!==a||c.axis_y_show?"y2"!==a||c.axis_y2_show?("x"===a&&!c.axis_rotated&&c.axis_x_tick_rotate&&(d=30+b.axis.getMaxTickWidth(a)*Math.cos(Math.PI*(90-c.axis_x_tick_rotate)/180)),d+(b.axis.getLabelPositionById(a).isInner?0:10)+("y2"===a?-10:0)):b.rotated_padding_top:!c.legend_show||b.isLegendRight||b.isLegendInset?1:10:8},i.getEventRectWidth=function(){return Math.max(0,this.xAxis.tickInterval())},i.getShapeIndices=function(a){var b,c,d=this,e=d.config,f={},g=0;return d.filterTargetsToShow(d.data.targets.filter(a,d)).forEach(function(a){for(b=0;b=0&&(j+=h(e[g].value)-i)}),j}},i.isWithinShape=function(a,b){var c,d=this,e=d.d3.select(a);return d.isTargetToShow(b.id)?"circle"===a.nodeName?c=d.isStepType(b)?d.isWithinStep(a,d.getYScale(b.id)(b.value)):d.isWithinCircle(a,1.5*d.pointSelectR(b)):"path"===a.nodeName&&(c=e.classed(l.bar)?d.isWithinBar(a):!0):c=!1,c},i.getInterpolate=function(a){var b=this;return b.isSplineType(a)?"cardinal":b.isStepType(a)?b.config.line_step_type:"linear"},i.initLine=function(){var a=this;a.main.select("."+l.chart).append("g").attr("class",l.chartLines)},i.updateTargetsForLine=function(a){var b,c,d=this,e=d.config,f=d.classChartLine.bind(d),g=d.classLines.bind(d),h=d.classAreas.bind(d),i=d.classCircles.bind(d),j=d.classFocus.bind(d);b=d.main.select("."+l.chartLines).selectAll("."+l.chartLine).data(a).attr("class",function(a){return f(a)+j(a)}),c=b.enter().append("g").attr("class",f).style("opacity",0).style("pointer-events","none"),c.append("g").attr("class",g),c.append("g").attr("class",h),c.append("g").attr("class",function(a){return d.generateClass(l.selectedCircles,a.id)}),c.append("g").attr("class",i).style("cursor",function(a){return e.data_selection_isselectable(a)?"pointer":null}),a.forEach(function(a){d.main.selectAll("."+l.selectedCircles+d.getTargetSelectorSuffix(a.id)).selectAll("."+l.selectedCircle).each(function(b){b.value=a.values[b.index].value})})},i.updateLine=function(a){var b=this;b.mainLine=b.main.selectAll("."+l.lines).selectAll("."+l.line).data(b.lineData.bind(b)),b.mainLine.enter().append("path").attr("class",b.classLine.bind(b)).style("stroke",b.color),b.mainLine.style("opacity",b.initialOpacity.bind(b)).style("shape-rendering",function(a){return b.isStepType(a)?"crispEdges":""}).attr("transform",null),b.mainLine.exit().transition().duration(a).style("opacity",0).remove()},i.redrawLine=function(a,b){return[(b?this.mainLine.transition():this.mainLine).attr("d",a).style("stroke",this.color).style("opacity",1)]},i.generateDrawLine=function(a,b){var c=this,d=c.config,e=c.d3.svg.line(),f=c.generateGetLinePoints(a,b),g=b?c.getSubYScale:c.getYScale,h=function(a){return(b?c.subxx:c.xx).call(c,a)},i=function(a,b){return d.data_groups.length>0?f(a,b)[0][1]:g.call(c,a.id)(a.value)};return e=d.axis_rotated?e.x(i).y(h):e.x(h).y(i),d.line_connectNull||(e=e.defined(function(a){return null!=a.value})),function(a){var f,h=d.line_connectNull?c.filterRemoveNull(a.values):a.values,i=b?c.x:c.subX,j=g.call(c,a.id),k=0,l=0;return c.isLineType(a)?d.data_regions[a.id]?f=c.lineWithRegions(h,i,j,d.data_regions[a.id]):(c.isStepType(a)&&(h=c.convertValuesToStep(h)),f=e.interpolate(c.getInterpolate(a))(h)):(h[0]&&(k=i(h[0].x),l=j(h[0].value)),f=d.axis_rotated?"M "+l+" "+k:"M "+k+" "+l),f?f:"M 0 0"}},i.generateGetLinePoints=function(a,b){var c=this,d=c.config,e=a.__max__+1,f=c.getShapeX(0,e,a,!!b),g=c.getShapeY(!!b),h=c.getShapeOffset(c.isLineType,a,!!b),i=b?c.getSubYScale:c.getYScale;return function(a,b){var e=i.call(c,a.id)(0),j=h(a,b)||e,k=f(a),l=g(a);return d.axis_rotated&&(0l||a.value<0&&l>e)&&(l=e),[[k,l-(e-j)],[k,l-(e-j)],[k,l-(e-j)],[k,l-(e-j)]]}},i.lineWithRegions=function(a,b,c,d){function e(a,b){var c;for(c=0;c=h;h+=r)x+=i(a[g-1],a[g],h,o);w=a[g].x}return x},i.updateArea=function(a){var b=this,c=b.d3;b.mainArea=b.main.selectAll("."+l.areas).selectAll("."+l.area).data(b.lineData.bind(b)),b.mainArea.enter().append("path").attr("class",b.classArea.bind(b)).style("fill",b.color).style("opacity",function(){return b.orgAreaOpacity=+c.select(this).style("opacity"),0}),b.mainArea.style("opacity",b.orgAreaOpacity),b.mainArea.exit().transition().duration(a).style("opacity",0).remove()},i.redrawArea=function(a,b){return[(b?this.mainArea.transition():this.mainArea).attr("d",a).style("fill",this.color).style("opacity",this.orgAreaOpacity)]},i.generateDrawArea=function(a,b){var c=this,d=c.config,e=c.d3.svg.area(),f=c.generateGetAreaPoints(a,b),g=b?c.getSubYScale:c.getYScale,h=function(a){return(b?c.subxx:c.xx).call(c,a)},i=function(a,b){return d.data_groups.length>0?f(a,b)[0][1]:g.call(c,a.id)(c.getAreaBaseValue(a.id))},j=function(a,b){return d.data_groups.length>0?f(a,b)[1][1]:g.call(c,a.id)(a.value)};return e=d.axis_rotated?e.x0(i).x1(j).y(h):e.x(h).y0(i).y1(j),d.line_connectNull||(e=e.defined(function(a){return null!==a.value})),function(a){var b,f=d.line_connectNull?c.filterRemoveNull(a.values):a.values,g=0,h=0;return c.isAreaType(a)?(c.isStepType(a)&&(f=c.convertValuesToStep(f)),b=e.interpolate(c.getInterpolate(a))(f)):(f[0]&&(g=c.x(f[0].x),h=c.getYScale(a.id)(f[0].value)),b=d.axis_rotated?"M "+h+" "+g:"M "+g+" "+h),b?b:"M 0 0"}},i.getAreaBaseValue=function(){return 0},i.generateGetAreaPoints=function(a,b){var c=this,d=c.config,e=a.__max__+1,f=c.getShapeX(0,e,a,!!b),g=c.getShapeY(!!b),h=c.getShapeOffset(c.isAreaType,a,!!b),i=b?c.getSubYScale:c.getYScale;return function(a,b){var e=i.call(c,a.id)(0),j=h(a,b)||e,k=f(a),l=g(a);return d.axis_rotated&&(0l||a.value<0&&l>e)&&(l=e),[[k,j],[k,l-(e-j)],[k,l-(e-j)],[k,j]]}},i.updateCircle=function(){var a=this;a.mainCircle=a.main.selectAll("."+l.circles).selectAll("."+l.circle).data(a.lineOrScatterData.bind(a)),a.mainCircle.enter().append("circle").attr("class",a.classCircle.bind(a)).attr("r",a.pointR.bind(a)).style("fill",a.color),a.mainCircle.style("opacity",a.initialOpacityForCircle.bind(a)),a.mainCircle.exit().remove()},i.redrawCircle=function(a,b,c){var d=this.main.selectAll("."+l.selectedCircle);return[(c?this.mainCircle.transition():this.mainCircle).style("opacity",this.opacityForCircle.bind(this)).style("fill",this.color).attr("cx",a).attr("cy",b),(c?d.transition():d).attr("cx",a).attr("cy",b)]},i.circleX=function(a){return a.x||0===a.x?this.x(a.x):null},i.updateCircleY=function(){var a,b,c=this;c.config.data_groups.length>0?(a=c.getShapeIndices(c.isLineType),b=c.generateGetLinePoints(a),c.circleY=function(a,c){return b(a,c)[0][1]}):c.circleY=function(a){return c.getYScale(a.id)(a.value)}},i.getCircles=function(a,b){var c=this;return(b?c.main.selectAll("."+l.circles+c.getTargetSelectorSuffix(b)):c.main).selectAll("."+l.circle+(m(a)?"-"+a:""))},i.expandCircles=function(a,b,c){var d=this,e=d.pointExpandedR.bind(d);c&&d.unexpandCircles(),d.getCircles(a,b).classed(l.EXPANDED,!0).attr("r",e)},i.unexpandCircles=function(a){var b=this,c=b.pointR.bind(b);b.getCircles(a).filter(function(){return b.d3.select(this).classed(l.EXPANDED)}).classed(l.EXPANDED,!1).attr("r",c)},i.pointR=function(a){var b=this,c=b.config;return b.isStepType(a)?0:n(c.point_r)?c.point_r(a):c.point_r},i.pointExpandedR=function(a){var b=this,c=b.config;return c.point_focus_expand_enabled?c.point_focus_expand_r?c.point_focus_expand_r:1.75*b.pointR(a):b.pointR(a)},i.pointSelectR=function(a){var b=this,c=b.config;return c.point_select_r?c.point_select_r:4*b.pointR(a)},i.isWithinCircle=function(a,b){var c=this.d3,d=c.mouse(a),e=c.select(a),f=+e.attr("cx"),g=+e.attr("cy");return Math.sqrt(Math.pow(f-d[0],2)+Math.pow(g-d[1],2))d.bar_width_max?d.bar_width_max:e},i.getBars=function(a,b){var c=this;return(b?c.main.selectAll("."+l.bars+c.getTargetSelectorSuffix(b)):c.main).selectAll("."+l.bar+(m(a)?"-"+a:""))},i.expandBars=function(a,b,c){var d=this;c&&d.unexpandBars(),d.getBars(a,b).classed(l.EXPANDED,!0)},i.unexpandBars=function(a){var b=this;b.getBars(a).classed(l.EXPANDED,!1)},i.generateDrawBar=function(a,b){var c=this,d=c.config,e=c.generateGetBarPoints(a,b);return function(a,b){var c=e(a,b),f=d.axis_rotated?1:0,g=d.axis_rotated?0:1,h="M "+c[0][f]+","+c[0][g]+" L"+c[1][f]+","+c[1][g]+" L"+c[2][f]+","+c[2][g]+" L"+c[3][f]+","+c[3][g]+" z";return h}},i.generateGetBarPoints=function(a,b){var c=this,d=b?c.subXAxis:c.xAxis,e=a.__max__+1,f=c.getBarW(d,e),g=c.getShapeX(f,e,a,!!b),h=c.getShapeY(!!b),i=c.getShapeOffset(c.isBarType,a,!!b),j=b?c.getSubYScale:c.getYScale; +return function(a,b){var d=j.call(c,a.id)(0),e=i(a,b)||d,k=g(a),l=h(a);return c.config.axis_rotated&&(0l||a.value<0&&l>d)&&(l=d),[[k,e],[k,l-(d-e)],[k+f,l-(d-e)],[k+f,e]]}},i.isWithinBar=function(a){var b=this.d3.mouse(a),c=a.getBoundingClientRect(),d=a.pathSegList.getItem(0),e=a.pathSegList.getItem(1),f=Math.min(d.x,e.x),g=Math.min(d.y,e.y),h=c.width,i=c.height,j=2,k=f-j,l=f+h+j,m=g+i+j,n=g-j;return kf.width?d=f.width-g.width:0>d&&(d=4)),d},i.getYForText=function(a,b,c){var d,e=this,f=c.getBoundingClientRect();return e.config.axis_rotated?d=(a[0][0]+a[2][0]+.6*f.height)/2:(d=a[2][1],b.value<0?(d+=f.height,e.isBarType(b)&&e.isSafari()?d-=3:!e.isBarType(b)&&e.isChrome()&&(d+=3)):d+=e.isBarType(b)?-3:-6),null!==b.value||e.config.axis_rotated||(dthis.height&&(d=this.height-4)),d},i.setTargetType=function(a,b){var c=this,d=c.config;c.mapToTargetIds(a).forEach(function(a){c.withoutFadeIn[a]=b===d.data_types[a],d.data_types[a]=b}),a||(d.data_type=b)},i.hasType=function(a,b){var c=this,d=c.config.data_types,e=!1;return b=b||c.data.targets,b&&b.length?b.forEach(function(b){var c=d[b.id];(c&&c.indexOf(a)>=0||!c&&"line"===a)&&(e=!0)}):Object.keys(d).length?Object.keys(d).forEach(function(b){d[b]===a&&(e=!0)}):e=c.config.data_type===a,e},i.hasArcType=function(a){return this.hasType("pie",a)||this.hasType("donut",a)||this.hasType("gauge",a)},i.isLineType=function(a){var b=this.config,c=o(a)?a:a.id;return!b.data_types[c]||["line","spline","area","area-spline","step","area-step"].indexOf(b.data_types[c])>=0},i.isStepType=function(a){var b=o(a)?a:a.id;return["step","area-step"].indexOf(this.config.data_types[b])>=0},i.isSplineType=function(a){var b=o(a)?a:a.id;return["spline","area-spline"].indexOf(this.config.data_types[b])>=0},i.isAreaType=function(a){var b=o(a)?a:a.id;return["area","area-spline","area-step"].indexOf(this.config.data_types[b])>=0},i.isBarType=function(a){var b=o(a)?a:a.id;return"bar"===this.config.data_types[b]},i.isScatterType=function(a){var b=o(a)?a:a.id;return"scatter"===this.config.data_types[b]},i.isPieType=function(a){var b=o(a)?a:a.id;return"pie"===this.config.data_types[b]},i.isGaugeType=function(a){var b=o(a)?a:a.id;return"gauge"===this.config.data_types[b]},i.isDonutType=function(a){var b=o(a)?a:a.id;return"donut"===this.config.data_types[b]},i.isArcType=function(a){return this.isPieType(a)||this.isDonutType(a)||this.isGaugeType(a)},i.lineData=function(a){return this.isLineType(a)?[a]:[]},i.arcData=function(a){return this.isArcType(a.data)?[a]:[]},i.barData=function(a){return this.isBarType(a)?a.values:[]},i.lineOrScatterData=function(a){return this.isLineType(a)||this.isScatterType(a)?a.values:[]},i.barOrLineData=function(a){return this.isBarType(a)||this.isLineType(a)?a.values:[]},i.initGrid=function(){var a=this,b=a.config,c=a.d3;a.grid=a.main.append("g").attr("clip-path",a.clipPathForGrid).attr("class",l.grid),b.grid_x_show&&a.grid.append("g").attr("class",l.xgrids),b.grid_y_show&&a.grid.append("g").attr("class",l.ygrids),b.grid_focus_show&&a.grid.append("g").attr("class",l.xgridFocus).append("line").attr("class",l.xgridFocus),a.xgrid=c.selectAll([]),b.grid_lines_front||a.initGridLines()},i.initGridLines=function(){var a=this,b=a.d3;a.gridLines=a.main.append("g").attr("clip-path",a.clipPathForGrid).attr("class",l.grid+" "+l.gridLines),a.gridLines.append("g").attr("class",l.xgridLines),a.gridLines.append("g").attr("class",l.ygridLines),a.xgridLines=b.selectAll([])},i.updateXGrid=function(a){var b=this,c=b.config,d=b.d3,e=b.generateGridData(c.grid_x_type,b.x),f=b.isCategorized()?b.xAxis.tickOffset():0;b.xgridAttr=c.axis_rotated?{x1:0,x2:b.width,y1:function(a){return b.x(a)-f},y2:function(a){return b.x(a)-f}}:{x1:function(a){return b.x(a)+f},x2:function(a){return b.x(a)+f},y1:0,y2:b.height},b.xgrid=b.main.select("."+l.xgrids).selectAll("."+l.xgrid).data(e),b.xgrid.enter().append("line").attr("class",l.xgrid),a||b.xgrid.attr(b.xgridAttr).style("opacity",function(){return+d.select(this).attr(c.axis_rotated?"y1":"x1")===(c.axis_rotated?b.height:0)?0:1}),b.xgrid.exit().remove()},i.updateYGrid=function(){var a=this,b=a.config,c=a.yAxis.tickValues()||a.y.ticks(b.grid_y_ticks);a.ygrid=a.main.select("."+l.ygrids).selectAll("."+l.ygrid).data(c),a.ygrid.enter().append("line").attr("class",l.ygrid),a.ygrid.attr("x1",b.axis_rotated?a.y:0).attr("x2",b.axis_rotated?a.y:a.width).attr("y1",b.axis_rotated?0:a.y).attr("y2",b.axis_rotated?a.height:a.y),a.ygrid.exit().remove(),a.smoothLines(a.ygrid,"grid")},i.gridTextAnchor=function(a){return a.position?a.position:"end"},i.gridTextDx=function(a){return"start"===a.position?4:"middle"===a.position?0:-4},i.xGridTextX=function(a){return"start"===a.position?-this.height:"middle"===a.position?-this.height/2:0},i.yGridTextX=function(a){return"start"===a.position?0:"middle"===a.position?this.width/2:this.width},i.updateGrid=function(a){var b,c,d,e=this,f=e.main,g=e.config;e.grid.style("visibility",e.hasArcType()?"hidden":"visible"),f.select("line."+l.xgridFocus).style("visibility","hidden"),g.grid_x_show&&e.updateXGrid(),e.xgridLines=f.select("."+l.xgridLines).selectAll("."+l.xgridLine).data(g.grid_x_lines),b=e.xgridLines.enter().append("g").attr("class",function(a){return l.xgridLine+(a["class"]?" "+a["class"]:"")}),b.append("line").style("opacity",0),b.append("text").attr("text-anchor",e.gridTextAnchor).attr("transform",g.axis_rotated?"":"rotate(-90)").attr("dx",e.gridTextDx).attr("dy",-5).style("opacity",0),e.xgridLines.exit().transition().duration(a).style("opacity",0).remove(),g.grid_y_show&&e.updateYGrid(),e.ygridLines=f.select("."+l.ygridLines).selectAll("."+l.ygridLine).data(g.grid_y_lines),c=e.ygridLines.enter().append("g").attr("class",function(a){return l.ygridLine+(a["class"]?" "+a["class"]:"")}),c.append("line").style("opacity",0),c.append("text").attr("text-anchor",e.gridTextAnchor).attr("transform",g.axis_rotated?"rotate(-90)":"").attr("dx",e.gridTextDx).attr("dy",-5).style("opacity",0),d=e.yv.bind(e),e.ygridLines.select("line").transition().duration(a).attr("x1",g.axis_rotated?d:0).attr("x2",g.axis_rotated?d:e.width).attr("y1",g.axis_rotated?0:d).attr("y2",g.axis_rotated?e.height:d).style("opacity",1),e.ygridLines.select("text").transition().duration(a).attr("x",g.axis_rotated?e.xGridTextX.bind(e):e.yGridTextX.bind(e)).attr("y",d).text(function(a){return a.text}).style("opacity",1),e.ygridLines.exit().transition().duration(a).style("opacity",0).remove()},i.redrawGrid=function(a){var b=this,c=b.config,d=b.xv.bind(b),e=b.xgridLines.select("line"),f=b.xgridLines.select("text");return[(a?e.transition():e).attr("x1",c.axis_rotated?0:d).attr("x2",c.axis_rotated?b.width:d).attr("y1",c.axis_rotated?d:0).attr("y2",c.axis_rotated?d:b.height).style("opacity",1),(a?f.transition():f).attr("x",c.axis_rotated?b.yGridTextX.bind(b):b.xGridTextX.bind(b)).attr("y",d).text(function(a){return a.text}).style("opacity",1)]},i.showXGridFocus=function(a){var b=this,c=b.config,d=a.filter(function(a){return a&&m(a.value)}),e=b.main.selectAll("line."+l.xgridFocus),f=b.xx.bind(b);c.tooltip_show&&(b.hasType("scatter")||b.hasArcType()||(e.style("visibility","visible").data([d[0]]).attr(c.axis_rotated?"y1":"x1",f).attr(c.axis_rotated?"y2":"x2",f),b.smoothLines(e,"grid")))},i.hideXGridFocus=function(){this.main.select("line."+l.xgridFocus).style("visibility","hidden")},i.updateXgridFocus=function(){var a=this,b=a.config;a.main.select("line."+l.xgridFocus).attr("x1",b.axis_rotated?0:-10).attr("x2",b.axis_rotated?a.width:-10).attr("y1",b.axis_rotated?-10:0).attr("y2",b.axis_rotated?-10:a.height)},i.generateGridData=function(a,b){var c,d,e,f,g=this,h=[],i=g.main.select("."+l.axisX).selectAll(".tick").size();if("year"===a)for(c=g.getXDomain(),d=c[0].getFullYear(),e=c[1].getFullYear(),f=d;e>=f;f++)h.push(new Date(f+"-01-01 00:00:00"));else h=b.ticks(10),h.length>i&&(h=h.filter(function(a){return(""+a).indexOf(".")<0}));return h},i.getGridFilterToRemove=function(a){return a?function(b){var c=!1;return[].concat(a).forEach(function(a){("value"in a&&b.value===a.value||"class"in a&&b["class"]===a["class"])&&(c=!0)}),c}:function(){return!0}},i.removeGridLines=function(a,b){var c=this,d=c.config,e=c.getGridFilterToRemove(a),f=function(a){return!e(a)},g=b?l.xgridLines:l.ygridLines,h=b?l.xgridLine:l.ygridLine;c.main.select("."+g).selectAll("."+h).filter(e).transition().duration(d.transition_duration).style("opacity",0).remove(),b?d.grid_x_lines=d.grid_x_lines.filter(f):d.grid_y_lines=d.grid_y_lines.filter(f)},i.initTooltip=function(){var a,b=this,c=b.config;if(b.tooltip=b.selectChart.style("position","relative").append("div").attr("class",l.tooltipContainer).style("position","absolute").style("pointer-events","none").style("display","none"),c.tooltip_init_show){if(b.isTimeSeries()&&o(c.tooltip_init_x)){for(c.tooltip_init_x=b.parseDate(c.tooltip_init_x),a=0;a"+(g||0===g?""+g+"":"")),h=p(a[f].value,a[f].ratio,a[f].id,a[f].index),void 0!==h&&(i=o(a[f].name,a[f].ratio,a[f].id,a[f].index),j=k.levelColor?k.levelColor(a[f].value):d(a[f].id),e+="",e+=""+i+"",e+=""+h+"",e+=""));return e+""},i.tooltipPosition=function(a,b,c,d){var e,f,g,h,i,j=this,k=j.config,l=j.d3,m=j.hasArcType(),n=l.mouse(d);return m?(f=(j.width-(j.isLegendRight?j.getLegendWidth():0))/2+n[0],h=j.height/2+n[1]+20):(e=j.getSvgLeft(!0),k.axis_rotated?(f=e+n[0]+100,g=f+b,i=j.currentWidth-j.getCurrentPaddingRight(),h=j.x(a[0].x)+20):(f=e+j.getCurrentPaddingLeft(!0)+j.x(a[0].x)+20,g=f+b,i=e+j.currentWidth-j.getCurrentPaddingRight(),h=n[1]+15),g>i&&(f-=g-i+20),h+c>j.currentHeight&&(h-=c+30)),0>h&&(h=0),{top:h,left:f}},i.showTooltip=function(a,b){var c,d,e,f=this,g=f.config,h=f.hasArcType(),j=a.filter(function(a){return a&&m(a.value)}),k=g.tooltip_position||i.tooltipPosition;0!==j.length&&g.tooltip_show&&(f.tooltip.html(g.tooltip_contents.call(f,a,f.axis.getXAxisTickFormat(),f.getYFormat(h),f.color)).style("display","block"),c=f.tooltip.property("offsetWidth"),d=f.tooltip.property("offsetHeight"),e=k.call(this,j,c,d,b),f.tooltip.style("top",e.top+"px").style("left",e.left+"px"))},i.hideTooltip=function(){this.tooltip.style("display","none")},i.initLegend=function(){var a=this;return a.legendItemTextBox={},a.legendHasRendered=!1,a.legend=a.svg.append("g").attr("transform",a.getTranslate("legend")),a.config.legend_show?void a.updateLegendWithDefaults():(a.legend.style("visibility","hidden"),void(a.hiddenLegendIds=a.mapToIds(a.data.targets)))},i.updateLegendWithDefaults=function(){var a=this;a.updateLegend(a.mapToIds(a.data.targets),{withTransform:!1,withTransitionForTransform:!1,withTransition:!1})},i.updateSizeForLegend=function(a,b){var c=this,d=c.config,e={top:c.isLegendTop?c.getCurrentPaddingTop()+d.legend_inset_y+5.5:c.currentHeight-a-c.getCurrentPaddingBottom()-d.legend_inset_y,left:c.isLegendLeft?c.getCurrentPaddingLeft()+d.legend_inset_x+.5:c.currentWidth-b-c.getCurrentPaddingRight()-d.legend_inset_x+.5};c.margin3={top:c.isLegendRight?0:c.isLegendInset?e.top:c.currentHeight-a,right:0/0,bottom:0,left:c.isLegendRight?c.currentWidth-b:c.isLegendInset?e.left:0}},i.transformLegend=function(a){var b=this;(a?b.legend.transition():b.legend).attr("transform",b.getTranslate("legend"))},i.updateLegendStep=function(a){this.legendStep=a},i.updateLegendItemWidth=function(a){this.legendItemWidth=a},i.updateLegendItemHeight=function(a){this.legendItemHeight=a},i.getLegendWidth=function(){var a=this;return a.config.legend_show?a.isLegendRight||a.isLegendInset?a.legendItemWidth*(a.legendStep+1):a.currentWidth:0},i.getLegendHeight=function(){var a=this,b=0;return a.config.legend_show&&(b=a.isLegendRight?a.currentHeight:Math.max(20,a.legendItemHeight)*(a.legendStep+1)),b},i.opacityForLegend=function(a){return a.classed(l.legendItemHidden)?null:1},i.opacityForUnfocusedLegend=function(a){return a.classed(l.legendItemHidden)?null:.3},i.toggleFocusLegend=function(a,b){var c=this;a=c.mapToTargetIds(a),c.legend.selectAll("."+l.legendItem).filter(function(b){return a.indexOf(b)>=0}).classed(l.legendItemFocused,b).transition().duration(100).style("opacity",function(){var a=b?c.opacityForLegend:c.opacityForUnfocusedLegend;return a.call(c,c.d3.select(this))})},i.revertLegend=function(){var a=this,b=a.d3;a.legend.selectAll("."+l.legendItem).classed(l.legendItemFocused,!1).transition().duration(100).style("opacity",function(){return a.opacityForLegend(b.select(this))})},i.showLegend=function(a){var b=this,c=b.config;c.legend_show||(c.legend_show=!0,b.legend.style("visibility","visible"),b.legendHasRendered||b.updateLegendWithDefaults()),b.removeHiddenLegendIds(a),b.legend.selectAll(b.selectorLegends(a)).style("visibility","visible").transition().style("opacity",function(){return b.opacityForLegend(b.d3.select(this))})},i.hideLegend=function(a){var b=this,c=b.config;c.legend_show&&u(a)&&(c.legend_show=!1,b.legend.style("visibility","hidden")),b.addHiddenLegendIds(a),b.legend.selectAll(b.selectorLegends(a)).style("opacity",0).style("visibility","hidden")},i.clearLegendItemTextBoxCache=function(){this.legendItemTextBox={}},i.updateLegend=function(a,b,c){function d(a,b){return u.legendItemTextBox[b]||(u.legendItemTextBox[b]=u.getTextRect(a.textContent,l.legendItem)),u.legendItemTextBox[b]}function e(b,c,e){function f(a,b){b||(g=(o-D-n)/2,B>g&&(g=(o-n)/2,D=0,J++)),I[a]=J,H[J]=u.isLegendInset?10:g,E[a]=D,D+=n}var g,h,i=0===e,j=e===a.length-1,k=d(b,c),l=k.width+C+(!j||u.isLegendRight||u.isLegendInset?y:0),m=k.height+x,n=u.isLegendRight||u.isLegendInset?m:l,o=u.isLegendRight||u.isLegendInset?u.getLegendHeight():u.getLegendWidth();return i&&(D=0,J=0,z=0,A=0),v.legend_show&&!u.isLegendToShow(c)?void(F[c]=G[c]=I[c]=E[c]=0):(F[c]=l,G[c]=m,(!z||l>=z)&&(z=l),(!A||m>=A)&&(A=m),h=u.isLegendRight||u.isLegendInset?A:z,void(v.legend_equally?(Object.keys(F).forEach(function(a){F[a]=z}),Object.keys(G).forEach(function(a){G[a]=A}),g=(o-h*a.length)/2,B>g?(D=0,J=0,a.forEach(function(a){f(a)})):f(c,!0)):f(c)))}var f,g,h,i,j,k,m,n,o,p,r,s,t,u=this,v=u.config,x=4,y=10,z=0,A=0,B=10,C=15,D=0,E={},F={},G={},H=[0],I={},J=0;b=b||{},n=w(b,"withTransition",!0),o=w(b,"withTransitionForTransform",!0),u.isLegendInset&&(J=v.legend_inset_step?v.legend_inset_step:a.length,u.updateLegendStep(J)),u.isLegendRight?(f=function(a){return z*I[a]},i=function(a){return H[I[a]]+E[a]}):u.isLegendInset?(f=function(a){return z*I[a]+10},i=function(a){return H[I[a]]+E[a]}):(f=function(a){return H[I[a]]+E[a]},i=function(a){return A*I[a]}),g=function(a,b){return f(a,b)+14},j=function(a,b){return i(a,b)+9},h=function(a,b){return f(a,b)},k=function(a,b){return i(a,b)-5},m=u.legend.selectAll("."+l.legendItem).data(a).enter().append("g").attr("class",function(a){return u.generateClass(l.legendItem,a)}).style("visibility",function(a){return u.isLegendToShow(a)?"visible":"hidden"}).style("cursor","pointer").on("click",function(a){v.legend_item_onclick?v.legend_item_onclick.call(u,a):u.d3.event.altKey?(u.api.hide(),u.api.show(a)):(u.api.toggle(a),u.isTargetToShow(a)?u.api.focus(a):u.api.revert())}).on("mouseover",function(a){u.d3.select(this).classed(l.legendItemFocused,!0),!u.transiting&&u.isTargetToShow(a)&&u.api.focus(a),v.legend_item_onmouseover&&v.legend_item_onmouseover.call(u,a)}).on("mouseout",function(a){u.d3.select(this).classed(l.legendItemFocused,!1),u.api.revert(),v.legend_item_onmouseout&&v.legend_item_onmouseout.call(u,a)}),m.append("text").text(function(a){return q(v.data_names[a])?v.data_names[a]:a}).each(function(a,b){e(this,a,b)}).style("pointer-events","none").attr("x",u.isLegendRight||u.isLegendInset?g:-200).attr("y",u.isLegendRight||u.isLegendInset?-200:j),m.append("rect").attr("class",l.legendItemEvent).style("fill-opacity",0).attr("x",u.isLegendRight||u.isLegendInset?h:-200).attr("y",u.isLegendRight||u.isLegendInset?-200:k),m.append("rect").attr("class",l.legendItemTile).style("pointer-events","none").style("fill",u.color).attr("x",u.isLegendRight||u.isLegendInset?g:-200).attr("y",u.isLegendRight||u.isLegendInset?-200:i).attr("width",10).attr("height",10),t=u.legend.select("."+l.legendBackground+" rect"),u.isLegendInset&&z>0&&0===t.size()&&(t=u.legend.insert("g","."+l.legendItem).attr("class",l.legendBackground).append("rect")),p=u.legend.selectAll("text").data(a).text(function(a){return q(v.data_names[a])?v.data_names[a]:a}).each(function(a,b){e(this,a,b)}),(n?p.transition():p).attr("x",g).attr("y",j),r=u.legend.selectAll("rect."+l.legendItemEvent).data(a),(n?r.transition():r).attr("width",function(a){return F[a]}).attr("height",function(a){return G[a]}).attr("x",h).attr("y",k),s=u.legend.selectAll("rect."+l.legendItemTile).data(a),(n?s.transition():s).style("fill",u.color).attr("x",f).attr("y",i),t&&(n?t.transition():t).attr("height",u.getLegendHeight()-12).attr("width",z*(J+1)+10),u.legend.selectAll("."+l.legendItem).classed(l.legendItemHidden,function(a){return!u.isTargetToShow(a)}),u.updateLegendItemWidth(z),u.updateLegendItemHeight(A),u.updateLegendStep(J),u.updateSizes(),u.updateScales(),u.updateSvgSize(),u.transformAll(o,c),u.legendHasRendered=!0},c(b,f),f.prototype.init=function(){var a=this.owner,b=a.config,c=a.main;a.axes.x=c.append("g").attr("class",l.axis+" "+l.axisX).attr("clip-path",a.clipPathForXAxis).attr("transform",a.getTranslate("x")).style("visibility",b.axis_x_show?"visible":"hidden"),a.axes.x.append("text").attr("class",l.axisXLabel).attr("transform",b.axis_rotated?"rotate(-90)":"").style("text-anchor",this.textAnchorForXAxisLabel.bind(this)),a.axes.y=c.append("g").attr("class",l.axis+" "+l.axisY).attr("clip-path",b.axis_y_inner?"":a.clipPathForYAxis).attr("transform",a.getTranslate("y")).style("visibility",b.axis_y_show?"visible":"hidden"),a.axes.y.append("text").attr("class",l.axisYLabel).attr("transform",b.axis_rotated?"":"rotate(-90)").style("text-anchor",this.textAnchorForYAxisLabel.bind(this)),a.axes.y2=c.append("g").attr("class",l.axis+" "+l.axisY2).attr("transform",a.getTranslate("y2")).style("visibility",b.axis_y2_show?"visible":"hidden"),a.axes.y2.append("text").attr("class",l.axisY2Label).attr("transform",b.axis_rotated?"":"rotate(-90)").style("text-anchor",this.textAnchorForY2AxisLabel.bind(this))},f.prototype.getXAxis=function(a,b,c,d,e,f,h){var i=this.owner,j=i.config,k={isCategory:i.isCategorized(),withOuterTick:e,tickMultiline:j.axis_x_tick_multiline,tickWidth:j.axis_x_tick_width,tickTextRotate:h?0:j.axis_x_tick_rotate,withoutTransition:f},l=g(i.d3,k).scale(a).orient(b);return i.isTimeSeries()&&d&&(d=d.map(function(a){return i.parseDate(a)})),l.tickFormat(c).tickValues(d),i.isCategorized()&&(l.tickCentered(j.axis_x_tick_centered),u(j.axis_x_tick_culling)&&(j.axis_x_tick_culling=!1)),l},f.prototype.updateXAxisTickValues=function(a,b){var c,d=this.owner,e=d.config;return(e.axis_x_tick_fit||e.axis_x_tick_count)&&(c=this.generateTickValues(d.mapTargetsToUniqueXs(a),e.axis_x_tick_count,d.isTimeSeries())),b?b.tickValues(c):(d.xAxis.tickValues(c),d.subXAxis.tickValues(c)),c},f.prototype.getYAxis=function(a,b,c,d,e,f){var h={withOuterTick:e,withoutTransition:f},i=this.owner,j=i.d3,k=i.config,l=g(j,h).scale(a).orient(b).tickFormat(c);return i.isTimeSeriesY()?l.ticks(j.time[k.axis_y_tick_time_value],k.axis_y_tick_time_interval):l.tickValues(d),l},f.prototype.getId=function(a){var b=this.owner.config;return a in b.data_axes?b.data_axes[a]:"y"},f.prototype.getXAxisTickFormat=function(){var a=this.owner,b=a.config,c=a.isTimeSeries()?a.defaultAxisTimeFormat:a.isCategorized()?a.categoryName:function(a){return 0>a?a.toFixed(0):a};return b.axis_x_tick_format&&(n(b.axis_x_tick_format)?c=b.axis_x_tick_format:a.isTimeSeries()&&(c=function(c){return c?a.axisTimeFormat(b.axis_x_tick_format)(c):""})),n(c)?function(b){return c.call(a,b)}:c},f.prototype.getTickValues=function(a,b){return a?a:b?b.tickValues():void 0},f.prototype.getXAxisTickValues=function(){return this.getTickValues(this.owner.config.axis_x_tick_values,this.owner.xAxis)},f.prototype.getYAxisTickValues=function(){return this.getTickValues(this.owner.config.axis_y_tick_values,this.owner.yAxis)},f.prototype.getY2AxisTickValues=function(){return this.getTickValues(this.owner.config.axis_y2_tick_values,this.owner.y2Axis)},f.prototype.getLabelOptionByAxisId=function(a){var b,c=this.owner,d=c.config;return"y"===a?b=d.axis_y_label:"y2"===a?b=d.axis_y2_label:"x"===a&&(b=d.axis_x_label),b},f.prototype.getLabelText=function(a){var b=this.getLabelOptionByAxisId(a);return o(b)?b:b?b.text:null},f.prototype.setLabelText=function(a,b){var c=this.owner,d=c.config,e=this.getLabelOptionByAxisId(a);o(e)?"y"===a?d.axis_y_label=b:"y2"===a?d.axis_y2_label=b:"x"===a&&(d.axis_x_label=b):e&&(e.text=b)},f.prototype.getLabelPosition=function(a,b){var c=this.getLabelOptionByAxisId(a),d=c&&"object"==typeof c&&c.position?c.position:b;return{isInner:d.indexOf("inner")>=0,isOuter:d.indexOf("outer")>=0,isLeft:d.indexOf("left")>=0,isCenter:d.indexOf("center")>=0,isRight:d.indexOf("right")>=0,isTop:d.indexOf("top")>=0,isMiddle:d.indexOf("middle")>=0,isBottom:d.indexOf("bottom")>=0}},f.prototype.getXAxisLabelPosition=function(){return this.getLabelPosition("x",this.owner.config.axis_rotated?"inner-top":"inner-right")},f.prototype.getYAxisLabelPosition=function(){return this.getLabelPosition("y",this.owner.config.axis_rotated?"inner-right":"inner-top")},f.prototype.getY2AxisLabelPosition=function(){return this.getLabelPosition("y2",this.owner.config.axis_rotated?"inner-right":"inner-top")},f.prototype.getLabelPositionById=function(a){return"y2"===a?this.getY2AxisLabelPosition():"y"===a?this.getYAxisLabelPosition():this.getXAxisLabelPosition()},f.prototype.textForXAxisLabel=function(){return this.getLabelText("x")},f.prototype.textForYAxisLabel=function(){return this.getLabelText("y")},f.prototype.textForY2AxisLabel=function(){return this.getLabelText("y2")},f.prototype.xForAxisLabel=function(a,b){var c=this.owner;return a?b.isLeft?0:b.isCenter?c.width/2:c.width:b.isBottom?-c.height:b.isMiddle?-c.height/2:0},f.prototype.dxForAxisLabel=function(a,b){return a?b.isLeft?"0.5em":b.isRight?"-0.5em":"0":b.isTop?"-0.5em":b.isBottom?"0.5em":"0"},f.prototype.textAnchorForAxisLabel=function(a,b){return a?b.isLeft?"start":b.isCenter?"middle":"end":b.isBottom?"start":b.isMiddle?"middle":"end"},f.prototype.xForXAxisLabel=function(){return this.xForAxisLabel(!this.owner.config.axis_rotated,this.getXAxisLabelPosition())},f.prototype.xForYAxisLabel=function(){return this.xForAxisLabel(this.owner.config.axis_rotated,this.getYAxisLabelPosition())},f.prototype.xForY2AxisLabel=function(){return this.xForAxisLabel(this.owner.config.axis_rotated,this.getY2AxisLabelPosition())},f.prototype.dxForXAxisLabel=function(){return this.dxForAxisLabel(!this.owner.config.axis_rotated,this.getXAxisLabelPosition())},f.prototype.dxForYAxisLabel=function(){return this.dxForAxisLabel(this.owner.config.axis_rotated,this.getYAxisLabelPosition())},f.prototype.dxForY2AxisLabel=function(){return this.dxForAxisLabel(this.owner.config.axis_rotated,this.getY2AxisLabelPosition())},f.prototype.dyForXAxisLabel=function(){var a=this.owner,b=a.config,c=this.getXAxisLabelPosition();return b.axis_rotated?c.isInner?"1.2em":-25-this.getMaxTickWidth("x"):c.isInner?"-0.5em":b.axis_x_height?b.axis_x_height-10:"3em"},f.prototype.dyForYAxisLabel=function(){var a=this.owner,b=this.getYAxisLabelPosition();return a.config.axis_rotated?b.isInner?"-0.5em":"3em":b.isInner?"1.2em":-10-(a.config.axis_y_inner?0:this.getMaxTickWidth("y")+10)},f.prototype.dyForY2AxisLabel=function(){var a=this.owner,b=this.getY2AxisLabelPosition();return a.config.axis_rotated?b.isInner?"1.2em":"-2.2em":b.isInner?"-0.5em":15+(a.config.axis_y2_inner?0:this.getMaxTickWidth("y2")+15)},f.prototype.textAnchorForXAxisLabel=function(){var a=this.owner;return this.textAnchorForAxisLabel(!a.config.axis_rotated,this.getXAxisLabelPosition())},f.prototype.textAnchorForYAxisLabel=function(){var a=this.owner;return this.textAnchorForAxisLabel(a.config.axis_rotated,this.getYAxisLabelPosition())},f.prototype.textAnchorForY2AxisLabel=function(){var a=this.owner;return this.textAnchorForAxisLabel(a.config.axis_rotated,this.getY2AxisLabelPosition())},f.prototype.getMaxTickWidth=function(a,b){var c,d,e,f,g,h=this.owner,i=h.config,j=0;return b&&h.currentMaxTickWidths[a]?h.currentMaxTickWidths[a]:(h.svg&&(c=h.filterTargetsToShow(h.data.targets),"y"===a?(d=h.y.copy().domain(h.getYDomain(c,"y")),e=this.getYAxis(d,h.yOrient,i.axis_y_tick_format,h.yAxisTickValues,!1,!0)):"y2"===a?(d=h.y2.copy().domain(h.getYDomain(c,"y2")),e=this.getYAxis(d,h.y2Orient,i.axis_y2_tick_format,h.y2AxisTickValues,!1,!0)):(d=h.x.copy().domain(h.getXDomain(c)),e=this.getXAxis(d,h.xOrient,h.xAxisTickFormat,h.xAxisTickValues,!1,!0,!0),this.updateXAxisTickValues(c,e)),f=h.d3.select("body").append("div").classed("c3",!0),g=f.append("svg").style("visibility","hidden").style("position","fixed").style("top",0).style("left",0),g.append("g").call(e).each(function(){h.d3.select(this).selectAll("text").each(function(){var a=this.getBoundingClientRect();j=j?h.currentMaxTickWidths[a]:j,h.currentMaxTickWidths[a])},f.prototype.updateLabels=function(a){var b=this.owner,c=b.main.select("."+l.axisX+" ."+l.axisXLabel),d=b.main.select("."+l.axisY+" ."+l.axisYLabel),e=b.main.select("."+l.axisY2+" ."+l.axisY2Label);(a?c.transition():c).attr("x",this.xForXAxisLabel.bind(this)).attr("dx",this.dxForXAxisLabel.bind(this)).attr("dy",this.dyForXAxisLabel.bind(this)).text(this.textForXAxisLabel.bind(this)),(a?d.transition():d).attr("x",this.xForYAxisLabel.bind(this)).attr("dx",this.dxForYAxisLabel.bind(this)).attr("dy",this.dyForYAxisLabel.bind(this)).text(this.textForYAxisLabel.bind(this)),(a?e.transition():e).attr("x",this.xForY2AxisLabel.bind(this)).attr("dx",this.dxForY2AxisLabel.bind(this)).attr("dy",this.dyForY2AxisLabel.bind(this)).text(this.textForY2AxisLabel.bind(this))},f.prototype.getPadding=function(a,b,c,d){return m(a[b])?"ratio"===a.unit?a[b]*d:this.convertPixelsToAxisPadding(a[b],d):c},f.prototype.convertPixelsToAxisPadding=function(a,b){var c=this.owner,d=c.config.axis_rotated?c.width:c.height;return b*(a/d)},f.prototype.generateTickValues=function(a,b,c){var d,e,f,g,h,i,j,k=a;if(b)if(d=n(b)?b():b,1===d)k=[a[0]];else if(2===d)k=[a[0],a[a.length-1]];else if(d>2){for(g=d-2,e=a[0],f=a[a.length-1],h=(f-e)/(g+1),k=[e],i=0;g>i;i++)j=+e+h*(i+1),k.push(c?new Date(j):j);k.push(f)}return c||(k=k.sort(function(a,b){return a-b})),k},f.prototype.generateTransitions=function(a){var b=this.owner,c=b.axes;return{axisX:a?c.x.transition().duration(a):c.x,axisY:a?c.y.transition().duration(a):c.y,axisY2:a?c.y2.transition().duration(a):c.y2,axisSubX:a?c.subx.transition().duration(a):c.subx}},f.prototype.redraw=function(a,b){var c=this.owner;c.axes.x.style("opacity",b?0:1),c.axes.y.style("opacity",b?0:1),c.axes.y2.style("opacity",b?0:1),c.axes.subx.style("opacity",b?0:1),a.axisX.call(c.xAxis),a.axisY.call(c.yAxis),a.axisY2.call(c.y2Axis),a.axisSubX.call(c.subXAxis)},i.getClipPath=function(b){var c=a.navigator.appVersion.toLowerCase().indexOf("msie 9.")>=0;return"url("+(c?"":document.URL.split("#")[0])+"#"+b+")"},i.appendClip=function(a,b){return a.append("clipPath").attr("id",b).append("rect")},i.getAxisClipX=function(a){var b=Math.max(30,this.margin.left);return a?-(1+b):-(b-1)},i.getAxisClipY=function(a){return a?-20:-this.margin.top},i.getXAxisClipX=function(){var a=this;return a.getAxisClipX(!a.config.axis_rotated)},i.getXAxisClipY=function(){var a=this;return a.getAxisClipY(!a.config.axis_rotated)},i.getYAxisClipX=function(){var a=this;return a.config.axis_y_inner?-1:a.getAxisClipX(a.config.axis_rotated)},i.getYAxisClipY=function(){var a=this;return a.getAxisClipY(a.config.axis_rotated)},i.getAxisClipWidth=function(a){var b=this,c=Math.max(30,b.margin.left),d=Math.max(30,b.margin.right);return a?b.width+2+c+d:b.margin.left+20},i.getAxisClipHeight=function(a){return(a?this.margin.bottom:this.margin.top+this.height)+20},i.getXAxisClipWidth=function(){var a=this;return a.getAxisClipWidth(!a.config.axis_rotated)},i.getXAxisClipHeight=function(){var a=this;return a.getAxisClipHeight(!a.config.axis_rotated)},i.getYAxisClipWidth=function(){var a=this;return a.getAxisClipWidth(a.config.axis_rotated)+(a.config.axis_y_inner?20:0)},i.getYAxisClipHeight=function(){var a=this;return a.getAxisClipHeight(a.config.axis_rotated)},i.initPie=function(){var a=this,b=a.d3,c=a.config;a.pie=b.layout.pie().value(function(a){return a.values.reduce(function(a,b){return a+b.value},0)}),c.data_order||a.pie.sort(null)},i.updateRadius=function(){var a=this,b=a.config,c=b.gauge_width||b.donut_width;a.radiusExpanded=Math.min(a.arcWidth,a.arcHeight)/2,a.radius=.95*a.radiusExpanded,a.innerRadiusRatio=c?(a.radius-c)/a.radius:.6,a.innerRadius=a.hasType("donut")||a.hasType("gauge")?a.radius*a.innerRadiusRatio:0},i.updateArc=function(){var a=this;a.svgArc=a.getSvgArc(),a.svgArcExpanded=a.getSvgArcExpanded(),a.svgArcExpandedSub=a.getSvgArcExpanded(.98)},i.updateAngle=function(a){var b,c,d=this,e=d.config,f=!1,g=0,h=e.gauge_min,i=e.gauge_max; +return d.pie(d.filterTargetsToShow(d.data.targets)).forEach(function(b){f||b.data.id!==a.data.id||(f=!0,a=b,a.index=g),g++}),isNaN(a.startAngle)&&(a.startAngle=0),isNaN(a.endAngle)&&(a.endAngle=a.startAngle),d.isGaugeType(a.data)&&(b=Math.PI/(i-h),c=a.value.375?1.175-36/g.radius:.8)*g.radius/e:0,i="translate("+c*f+","+d*f+")"),i},i.getArcRatio=function(a){var b=this,c=b.hasType("gauge")?Math.PI:2*Math.PI;return a?(a.endAngle-a.startAngle)/c:null},i.convertToArcData=function(a){return this.addName({id:a.data.id,value:a.value,ratio:this.getArcRatio(a),index:a.index})},i.textForArcLabel=function(a){var b,c,d,e,f,g=this;return g.shouldShowArcLabel()?(b=g.updateAngle(a),c=b?b.value:null,d=g.getArcRatio(b),e=a.data.id,g.hasType("gauge")||g.meetsArcLabelThreshold(d)?(f=g.getArcLabelFormat(),f?f(c,d,e):g.defaultArcValueFormat(c,d)):""):""},i.expandArc=function(b){var c,d=this;return d.transiting?void(c=a.setInterval(function(){d.transiting||(a.clearInterval(c),d.legend.selectAll(".c3-legend-item-focused").size()>0&&d.expandArc(b))},10)):(b=d.mapToTargetIds(b),void d.svg.selectAll(d.selectorTargets(b,"."+l.chartArc)).each(function(a){d.shouldExpand(a.data.id)&&d.d3.select(this).selectAll("path").transition().duration(50).attr("d",d.svgArcExpanded).transition().duration(100).attr("d",d.svgArcExpandedSub).each(function(a){d.isDonutType(a.data)})}))},i.unexpandArc=function(a){var b=this;b.transiting||(a=b.mapToTargetIds(a),b.svg.selectAll(b.selectorTargets(a,"."+l.chartArc)).selectAll("path").transition().duration(50).attr("d",b.svgArc),b.svg.selectAll("."+l.arc).style("opacity",1))},i.shouldExpand=function(a){var b=this,c=b.config;return b.isDonutType(a)&&c.donut_expand||b.isGaugeType(a)&&c.gauge_expand||b.isPieType(a)&&c.pie_expand},i.shouldShowArcLabel=function(){var a=this,b=a.config,c=!0;return a.hasType("donut")?c=b.donut_label_show:a.hasType("pie")&&(c=b.pie_label_show),c},i.meetsArcLabelThreshold=function(a){var b=this,c=b.config,d=b.hasType("donut")?c.donut_label_threshold:c.pie_label_threshold;return a>=d},i.getArcLabelFormat=function(){var a=this,b=a.config,c=b.pie_label_format;return a.hasType("gauge")?c=b.gauge_label_format:a.hasType("donut")&&(c=b.donut_label_format),c},i.getArcTitle=function(){var a=this;return a.hasType("donut")?a.config.donut_title:""},i.updateTargetsForArc=function(a){var b,c,d=this,e=d.main,f=d.classChartArc.bind(d),g=d.classArcs.bind(d),h=d.classFocus.bind(d);b=e.select("."+l.chartArcs).selectAll("."+l.chartArc).data(d.pie(a)).attr("class",function(a){return f(a)+h(a.data)}),c=b.enter().append("g").attr("class",f),c.append("g").attr("class",g),c.append("text").attr("dy",d.hasType("gauge")?"-.1em":".35em").style("opacity",0).style("text-anchor","middle").style("pointer-events","none")},i.initArc=function(){var a=this;a.arcs=a.main.select("."+l.chart).append("g").attr("class",l.chartArcs).attr("transform",a.getTranslate("arc")),a.arcs.append("text").attr("class",l.chartArcsTitle).style("text-anchor","middle").text(a.getArcTitle())},i.redrawArc=function(a,b,c){var d,e=this,f=e.d3,g=e.config,h=e.main;d=h.selectAll("."+l.arcs).selectAll("."+l.arc).data(e.arcData.bind(e)),d.enter().append("path").attr("class",e.classArc.bind(e)).style("fill",function(a){return e.color(a.data)}).style("cursor",function(a){return g.interaction_enabled&&g.data_selection_isselectable(a)?"pointer":null}).style("opacity",0).each(function(a){e.isGaugeType(a.data)&&(a.startAngle=a.endAngle=-1*(Math.PI/2)),this._current=a}),d.attr("transform",function(a){return!e.isGaugeType(a.data)&&c?"scale(0)":""}).style("opacity",function(a){return a===this._current?0:1}).on("mouseover",g.interaction_enabled?function(a){var b,c;e.transiting||(b=e.updateAngle(a),c=e.convertToArcData(b),e.expandArc(b.data.id),e.api.focus(b.data.id),e.toggleFocusLegend(b.data.id,!0),e.config.data_onmouseover(c,this))}:null).on("mousemove",g.interaction_enabled?function(a){var b=e.updateAngle(a),c=e.convertToArcData(b),d=[c];e.showTooltip(d,this)}:null).on("mouseout",g.interaction_enabled?function(a){var b,c;e.transiting||(b=e.updateAngle(a),c=e.convertToArcData(b),e.unexpandArc(b.data.id),e.api.revert(),e.revertLegend(),e.hideTooltip(),e.config.data_onmouseout(c,this))}:null).on("click",g.interaction_enabled?function(a,b){var c=e.updateAngle(a),d=e.convertToArcData(c);e.toggleShape&&e.toggleShape(this,d,b),e.config.data_onclick.call(e.api,d,this)}:null).each(function(){e.transiting=!0}).transition().duration(a).attrTween("d",function(a){var b,c=e.updateAngle(a);return c?(isNaN(this._current.startAngle)&&(this._current.startAngle=0),isNaN(this._current.endAngle)&&(this._current.endAngle=this._current.startAngle),b=f.interpolate(this._current,c),this._current=b(0),function(c){var d=b(c);return d.data=a.data,e.getArc(d,!0)}):function(){return"M 0 0"}}).attr("transform",c?"scale(1)":"").style("fill",function(a){return e.levelColor?e.levelColor(a.data.values[0].value):e.color(a.data.id)}).style("opacity",1).call(e.endall,function(){e.transiting=!1}),d.exit().transition().duration(b).style("opacity",0).remove(),h.selectAll("."+l.chartArc).select("text").style("opacity",0).attr("class",function(a){return e.isGaugeType(a.data)?l.gaugeValue:""}).text(e.textForArcLabel.bind(e)).attr("transform",e.transformForArcLabel.bind(e)).style("font-size",function(a){return e.isGaugeType(a.data)?Math.round(e.radius/5)+"px":""}).transition().duration(a).style("opacity",function(a){return e.isTargetToShow(a.data.id)&&e.isArcType(a.data)?1:0}),h.select("."+l.chartArcsTitle).style("opacity",e.hasType("donut")||e.hasType("gauge")?1:0),e.hasType("gauge")&&(e.arcs.select("."+l.chartArcsBackground).attr("d",function(){var a={data:[{value:g.gauge_max}],startAngle:-1*(Math.PI/2),endAngle:Math.PI/2};return e.getArc(a,!0,!0)}),e.arcs.select("."+l.chartArcsGaugeUnit).attr("dy",".75em").text(g.gauge_label_show?g.gauge_units:""),e.arcs.select("."+l.chartArcsGaugeMin).attr("dx",-1*(e.innerRadius+(e.radius-e.innerRadius)/2)+"px").attr("dy","1.2em").text(g.gauge_label_show?g.gauge_min:""),e.arcs.select("."+l.chartArcsGaugeMax).attr("dx",e.innerRadius+(e.radius-e.innerRadius)/2+"px").attr("dy","1.2em").text(g.gauge_label_show?g.gauge_max:""))},i.initGauge=function(){var a=this.arcs;this.hasType("gauge")&&(a.append("path").attr("class",l.chartArcsBackground),a.append("text").attr("class",l.chartArcsGaugeUnit).style("text-anchor","middle").style("pointer-events","none"),a.append("text").attr("class",l.chartArcsGaugeMin).style("text-anchor","middle").style("pointer-events","none"),a.append("text").attr("class",l.chartArcsGaugeMax).style("text-anchor","middle").style("pointer-events","none"))},i.getGaugeLabelHeight=function(){return this.config.gauge_label_show?20:0},i.initRegion=function(){var a=this;a.region=a.main.append("g").attr("clip-path",a.clipPath).attr("class",l.regions)},i.updateRegion=function(a){var b=this,c=b.config;b.region.style("visibility",b.hasArcType()?"hidden":"visible"),b.mainRegion=b.main.select("."+l.regions).selectAll("."+l.region).data(c.regions),b.mainRegion.enter().append("g").attr("class",b.classRegion.bind(b)).append("rect").style("fill-opacity",0),b.mainRegion.exit().transition().duration(a).style("opacity",0).remove()},i.redrawRegion=function(a){var b=this,c=b.mainRegion.selectAll("rect"),d=b.regionX.bind(b),e=b.regionY.bind(b),f=b.regionWidth.bind(b),g=b.regionHeight.bind(b);return[(a?c.transition():c).attr("x",d).attr("y",e).attr("width",f).attr("height",g).style("fill-opacity",function(a){return m(a.opacity)?a.opacity:.1})]},i.regionX=function(a){var b,c=this,d=c.config,e="y"===a.axis?c.y:c.y2;return b="y"===a.axis||"y2"===a.axis?d.axis_rotated&&"start"in a?e(a.start):0:d.axis_rotated?0:"start"in a?c.x(c.isTimeSeries()?c.parseDate(a.start):a.start):0},i.regionY=function(a){var b,c=this,d=c.config,e="y"===a.axis?c.y:c.y2;return b="y"===a.axis||"y2"===a.axis?d.axis_rotated?0:"end"in a?e(a.end):0:d.axis_rotated&&"start"in a?c.x(c.isTimeSeries()?c.parseDate(a.start):a.start):0},i.regionWidth=function(a){var b,c=this,d=c.config,e=c.regionX(a),f="y"===a.axis?c.y:c.y2;return b="y"===a.axis||"y2"===a.axis?d.axis_rotated&&"end"in a?f(a.end):c.width:d.axis_rotated?c.width:"end"in a?c.x(c.isTimeSeries()?c.parseDate(a.end):a.end):c.width,e>b?0:b-e},i.regionHeight=function(a){var b,c=this,d=c.config,e=this.regionY(a),f="y"===a.axis?c.y:c.y2;return b="y"===a.axis||"y2"===a.axis?d.axis_rotated?c.height:"start"in a?f(a.start):c.height:d.axis_rotated&&"end"in a?c.x(c.isTimeSeries()?c.parseDate(a.end):a.end):c.height,e>b?0:b-e},i.isRegionOnX=function(a){return!a.axis||"x"===a.axis},i.drag=function(a){var b,c,d,e,f,g,h,i,j=this,k=j.config,m=j.main,n=j.d3;j.hasArcType()||k.data_selection_enabled&&(!k.zoom_enabled||j.zoom.altDomain)&&k.data_selection_multiple&&(b=j.dragStart[0],c=j.dragStart[1],d=a[0],e=a[1],f=Math.min(b,d),g=Math.max(b,d),h=k.data_selection_grouped?j.margin.top:Math.min(c,e),i=k.data_selection_grouped?j.height:Math.max(c,e),m.select("."+l.dragarea).attr("x",f).attr("y",h).attr("width",g-f).attr("height",i-h),m.selectAll("."+l.shapes).selectAll("."+l.shape).filter(function(a){return k.data_selection_isselectable(a)}).each(function(a,b){var c,d,e,k,m,o,p=n.select(this),q=p.classed(l.SELECTED),r=p.classed(l.INCLUDED),s=!1;if(p.classed(l.circle))c=1*p.attr("cx"),d=1*p.attr("cy"),m=j.togglePoint,s=c>f&&g>c&&d>h&&i>d;else{if(!p.classed(l.bar))return;o=y(this),c=o.x,d=o.y,e=o.width,k=o.height,m=j.togglePath,s=!(c>g||f>c+e||d>i||h>d+k)}s^r&&(p.classed(l.INCLUDED,!r),p.classed(l.SELECTED,!q),m.call(j,!q,p,a,b))}))},i.dragstart=function(a){var b=this,c=b.config;b.hasArcType()||c.data_selection_enabled&&(b.dragStart=a,b.main.select("."+l.chart).append("rect").attr("class",l.dragarea).style("opacity",.1),b.dragging=!0)},i.dragend=function(){var a=this,b=a.config;a.hasArcType()||b.data_selection_enabled&&(a.main.select("."+l.dragarea).transition().duration(100).style("opacity",0).remove(),a.main.selectAll("."+l.shape).classed(l.INCLUDED,!1),a.dragging=!1)},i.selectPoint=function(a,b,c){var d=this,e=d.config,f=(e.axis_rotated?d.circleY:d.circleX).bind(d),g=(e.axis_rotated?d.circleX:d.circleY).bind(d),h=d.pointSelectR.bind(d);e.data_onselected.call(d.api,b,a.node()),d.main.select("."+l.selectedCircles+d.getTargetSelectorSuffix(b.id)).selectAll("."+l.selectedCircle+"-"+c).data([b]).enter().append("circle").attr("class",function(){return d.generateClass(l.selectedCircle,c)}).attr("cx",f).attr("cy",g).attr("stroke",function(){return d.color(b)}).attr("r",function(a){return 1.4*d.pointSelectR(a)}).transition().duration(100).attr("r",h)},i.unselectPoint=function(a,b,c){var d=this;d.config.data_onunselected(b,a.node()),d.main.select("."+l.selectedCircles+d.getTargetSelectorSuffix(b.id)).selectAll("."+l.selectedCircle+"-"+c).transition().duration(100).attr("r",0).remove()},i.togglePoint=function(a,b,c,d){a?this.selectPoint(b,c,d):this.unselectPoint(b,c,d)},i.selectPath=function(a,b){var c=this;c.config.data_onselected.call(c,b,a.node()),a.transition().duration(100).style("fill",function(){return c.d3.rgb(c.color(b)).brighter(.75)})},i.unselectPath=function(a,b){var c=this;c.config.data_onunselected.call(c,b,a.node()),a.transition().duration(100).style("fill",function(){return c.color(b)})},i.togglePath=function(a,b,c,d){a?this.selectPath(b,c,d):this.unselectPath(b,c,d)},i.getToggle=function(a,b){var c,d=this;return"circle"===a.nodeName?c=d.isStepType(b)?function(){}:d.togglePoint:"path"===a.nodeName&&(c=d.togglePath),c},i.toggleShape=function(a,b,c){var d=this,e=d.d3,f=d.config,g=e.select(a),h=g.classed(l.SELECTED),i=d.getToggle(a,b).bind(d);f.data_selection_enabled&&f.data_selection_isselectable(b)&&(f.data_selection_multiple||d.main.selectAll("."+l.shapes+(f.data_selection_grouped?d.getTargetSelectorSuffix(b.id):"")).selectAll("."+l.shape).each(function(a,b){var c=e.select(this);c.classed(l.SELECTED)&&i(!1,c.classed(l.SELECTED,!1),a,b)}),g.classed(l.SELECTED,!h),i(!h,g,b,c))},i.initBrush=function(){var a=this,b=a.d3;a.brush=b.svg.brush().on("brush",function(){a.redrawForBrush()}),a.brush.update=function(){return a.context&&a.context.select("."+l.brush).call(this),this},a.brush.scale=function(b){return a.config.axis_rotated?this.y(b):this.x(b)}},i.initSubchart=function(){var a=this,b=a.config,c=a.context=a.svg.append("g").attr("transform",a.getTranslate("context"));c.style("visibility",b.subchart_show?"visible":"hidden"),c.append("g").attr("clip-path",a.clipPathForSubchart).attr("class",l.chart),c.select("."+l.chart).append("g").attr("class",l.chartBars),c.select("."+l.chart).append("g").attr("class",l.chartLines),c.append("g").attr("clip-path",a.clipPath).attr("class",l.brush).call(a.brush),a.axes.subx=c.append("g").attr("class",l.axisX).attr("transform",a.getTranslate("subx")).attr("clip-path",b.axis_rotated?"":a.clipPathForXAxis)},i.updateTargetsForSubchart=function(a){var b,c,d,e,f=this,g=f.context,h=f.config,i=f.classChartBar.bind(f),j=f.classBars.bind(f),k=f.classChartLine.bind(f),m=f.classLines.bind(f),n=f.classAreas.bind(f);h.subchart_show&&(e=g.select("."+l.chartBars).selectAll("."+l.chartBar).data(a).attr("class",i),d=e.enter().append("g").style("opacity",0).attr("class",i),d.append("g").attr("class",j),c=g.select("."+l.chartLines).selectAll("."+l.chartLine).data(a).attr("class",k),b=c.enter().append("g").style("opacity",0).attr("class",k),b.append("g").attr("class",m),b.append("g").attr("class",n),g.selectAll("."+l.brush+" rect").attr(h.axis_rotated?"width":"height",h.axis_rotated?f.width2:f.height2))},i.updateBarForSubchart=function(a){var b=this;b.contextBar=b.context.selectAll("."+l.bars).selectAll("."+l.bar).data(b.barData.bind(b)),b.contextBar.enter().append("path").attr("class",b.classBar.bind(b)).style("stroke","none").style("fill",b.color),b.contextBar.style("opacity",b.initialOpacity.bind(b)),b.contextBar.exit().transition().duration(a).style("opacity",0).remove()},i.redrawBarForSubchart=function(a,b,c){(b?this.contextBar.transition().duration(c):this.contextBar).attr("d",a).style("opacity",1)},i.updateLineForSubchart=function(a){var b=this;b.contextLine=b.context.selectAll("."+l.lines).selectAll("."+l.line).data(b.lineData.bind(b)),b.contextLine.enter().append("path").attr("class",b.classLine.bind(b)).style("stroke",b.color),b.contextLine.style("opacity",b.initialOpacity.bind(b)),b.contextLine.exit().transition().duration(a).style("opacity",0).remove()},i.redrawLineForSubchart=function(a,b,c){(b?this.contextLine.transition().duration(c):this.contextLine).attr("d",a).style("opacity",1)},i.updateAreaForSubchart=function(a){var b=this,c=b.d3;b.contextArea=b.context.selectAll("."+l.areas).selectAll("."+l.area).data(b.lineData.bind(b)),b.contextArea.enter().append("path").attr("class",b.classArea.bind(b)).style("fill",b.color).style("opacity",function(){return b.orgAreaOpacity=+c.select(this).style("opacity"),0}),b.contextArea.style("opacity",0),b.contextArea.exit().transition().duration(a).style("opacity",0).remove()},i.redrawAreaForSubchart=function(a,b,c){(b?this.contextArea.transition().duration(c):this.contextArea).attr("d",a).style("fill",this.color).style("opacity",this.orgAreaOpacity)},i.redrawSubchart=function(a,b,c,d,e,f,g){var h,i,j,k=this,l=k.d3,m=k.config;k.context.style("visibility",m.subchart_show?"visible":"hidden"),m.subchart_show&&(l.event&&"zoom"===l.event.type&&k.brush.extent(k.x.orgDomain()).update(),a&&(k.brush.empty()||k.brush.extent(k.x.orgDomain()).update(),h=k.generateDrawArea(e,!0),i=k.generateDrawBar(f,!0),j=k.generateDrawLine(g,!0),k.updateBarForSubchart(c),k.updateLineForSubchart(c),k.updateAreaForSubchart(c),k.redrawBarForSubchart(i,c,c),k.redrawLineForSubchart(j,c,c),k.redrawAreaForSubchart(h,c,c)))},i.redrawForBrush=function(){var a=this,b=a.x;a.redraw({withTransition:!1,withY:a.config.zoom_rescale,withSubchart:!1,withUpdateXDomain:!0,withDimension:!1}),a.config.subchart_onbrush.call(a.api,b.orgDomain())},i.transformContext=function(a,b){var c,d=this;b&&b.axisSubX?c=b.axisSubX:(c=d.context.select("."+l.axisX),a&&(c=c.transition())),d.context.attr("transform",d.getTranslate("context")),c.attr("transform",d.getTranslate("subx"))},i.getDefaultExtent=function(){var a=this,b=a.config,c=n(b.axis_x_extent)?b.axis_x_extent(a.getXDomain(a.data.targets)):b.axis_x_extent;return a.isTimeSeries()&&(c=[a.parseDate(c[0]),a.parseDate(c[1])]),c},i.initZoom=function(){var a,b=this,c=b.d3,d=b.config;b.zoom=c.behavior.zoom().on("zoomstart",function(){a=c.event.sourceEvent,b.zoom.altDomain=c.event.sourceEvent.altKey?b.x.orgDomain():null,d.zoom_onzoomstart.call(b.api,c.event.sourceEvent)}).on("zoom",function(){b.redrawForZoom.call(b)}).on("zoomend",function(){var e=c.event.sourceEvent;e&&a.clientX===e.clientX&&a.clientY===e.clientY||(b.redrawEventRect(),b.updateZoom(),d.zoom_onzoomend.call(b.api,b.x.orgDomain()))}),b.zoom.scale=function(a){return d.axis_rotated?this.y(a):this.x(a)},b.zoom.orgScaleExtent=function(){var a=d.zoom_extent?d.zoom_extent:[1,10];return[a[0],Math.max(b.getMaxDataCount()/a[1],a[1])]},b.zoom.updateScaleExtent=function(){var a=t(b.x.orgDomain())/t(b.orgXDomain),c=this.orgScaleExtent();return this.scaleExtent([c[0]*a,c[1]*a]),this}},i.updateZoom=function(){var a=this,b=a.config.zoom_enabled?a.zoom:function(){};a.main.select("."+l.zoomRect).call(b).on("dblclick.zoom",null),a.main.selectAll("."+l.eventRect).call(b).on("dblclick.zoom",null)},i.redrawForZoom=function(){var a=this,b=a.d3,c=a.config,d=a.zoom,e=a.x;if(c.zoom_enabled&&0!==a.filterTargetsToShow(a.data.targets).length){if("mousemove"===b.event.sourceEvent.type&&d.altDomain)return e.domain(d.altDomain),void d.scale(e).updateScaleExtent();a.isCategorized()&&e.orgDomain()[0]===a.orgXDomain[0]&&e.domain([a.orgXDomain[0]-1e-10,e.orgDomain()[1]]),a.redraw({withTransition:!1,withY:c.zoom_rescale,withSubchart:!1,withEventRect:!1,withDimension:!1}),"mousemove"===b.event.sourceEvent.type&&(a.cancelClick=!0),c.zoom_onzoom.call(a.api,e.orgDomain())}},i.generateColor=function(){var a=this,b=a.config,c=a.d3,d=b.data_colors,e=v(b.color_pattern)?b.color_pattern:c.scale.category10().range(),f=b.data_color,g=[];return function(a){var b,c=a.id||a.data&&a.data.id||a;return d[c]instanceof Function?b=d[c](a):d[c]?b=d[c]:(g.indexOf(c)<0&&g.push(c),b=e[g.indexOf(c)%e.length],d[c]=b),f instanceof Function?f(b,a):b}},i.generateLevelColor=function(){var a=this,b=a.config,c=b.color_pattern,d=b.color_threshold,e="value"===d.unit,f=d.values&&d.values.length?d.values:[],g=d.max||100;return v(b.color_threshold)?function(a){var b,d,h=c[c.length-1];for(b=0;b=0?l.focused:"")},i.classDefocused=function(a){return" "+(this.defocusedTargetIds.indexOf(a.id)>=0?l.defocused:"")},i.classChartText=function(a){return l.chartText+this.classTarget(a.id)},i.classChartLine=function(a){return l.chartLine+this.classTarget(a.id)},i.classChartBar=function(a){return l.chartBar+this.classTarget(a.id)},i.classChartArc=function(a){return l.chartArc+this.classTarget(a.data.id)},i.getTargetSelectorSuffix=function(a){return a||0===a?("-"+a).replace(/[\s?!@#$%^&*()_=+,.<>'":;\[\]\/|~`{}\\]/g,"-"):""},i.selectorTarget=function(a,b){return(b||"")+"."+l.target+this.getTargetSelectorSuffix(a)},i.selectorTargets=function(a,b){var c=this;return a=a||[],a.length?a.map(function(a){return c.selectorTarget(a,b)}):null},i.selectorLegend=function(a){return"."+l.legendItem+this.getTargetSelectorSuffix(a)},i.selectorLegends=function(a){var b=this;return a&&a.length?a.map(function(a){return b.selectorLegend(a)}):null};var m=i.isValue=function(a){return a||0===a},n=i.isFunction=function(a){return"function"==typeof a},o=i.isString=function(a){return"string"==typeof a},p=i.isUndefined=function(a){return"undefined"==typeof a},q=i.isDefined=function(a){return"undefined"!=typeof a},r=i.ceil10=function(a){return 10*Math.ceil(a/10)},s=i.asHalfPixel=function(a){return Math.ceil(a)+.5},t=i.diffDomain=function(a){return a[1]-a[0]},u=i.isEmpty=function(a){return!a||o(a)&&0===a.length||"object"==typeof a&&0===Object.keys(a).length},v=i.notEmpty=function(a){return Object.keys(a).length>0},w=i.getOption=function(a,b,c){return q(a[b])?a[b]:c},x=i.hasValue=function(a,b){var c=!1;return Object.keys(a).forEach(function(d){a[d]===b&&(c=!0)}),c},y=i.getPathBox=function(a){var b=a.getBoundingClientRect(),c=[a.pathSegList.getItem(0),a.pathSegList.getItem(1)],d=c[0].x,e=Math.min(c[0].y,c[1].y);return{x:d,y:e,width:b.width,height:b.height}};h.focus=function(a){var b,c=this.internal;a=c.mapToTargetIds(a),b=c.svg.selectAll(c.selectorTargets(a.filter(c.isTargetToShow,c))),this.revert(),this.defocus(),b.classed(l.focused,!0).classed(l.defocused,!1),c.hasArcType()&&c.expandArc(a),c.toggleFocusLegend(a,!0),c.focusedTargetIds=a,c.defocusedTargetIds=c.defocusedTargetIds.filter(function(b){return a.indexOf(b)<0})},h.defocus=function(a){var b,c=this.internal;a=c.mapToTargetIds(a),b=c.svg.selectAll(c.selectorTargets(a.filter(c.isTargetToShow,c))),b.classed(l.focused,!1).classed(l.defocused,!0),c.hasArcType()&&c.unexpandArc(a),c.toggleFocusLegend(a,!1),c.focusedTargetIds=c.focusedTargetIds.filter(function(b){return a.indexOf(b)<0}),c.defocusedTargetIds=a},h.revert=function(a){var b,c=this.internal;a=c.mapToTargetIds(a),b=c.svg.selectAll(c.selectorTargets(a)),b.classed(l.focused,!1).classed(l.defocused,!1),c.hasArcType()&&c.unexpandArc(a),c.config.legend_show&&(c.showLegend(a.filter(c.isLegendToShow.bind(c))),c.legend.selectAll(c.selectorLegends(a)).filter(function(){return c.d3.select(this).classed(l.legendItemFocused)}).classed(l.legendItemFocused,!1)),c.focusedTargetIds=[],c.defocusedTargetIds=[]},h.show=function(a,b){var c,d=this.internal;a=d.mapToTargetIds(a),b=b||{},d.removeHiddenTargetIds(a),c=d.svg.selectAll(d.selectorTargets(a)),c.transition().style("opacity",1,"important").call(d.endall,function(){c.style("opacity",null).style("opacity",1)}),b.withLegend&&d.showLegend(a),d.redraw({withUpdateOrgXDomain:!0,withUpdateXDomain:!0,withLegend:!0})},h.hide=function(a,b){var c,d=this.internal;a=d.mapToTargetIds(a),b=b||{},d.addHiddenTargetIds(a),c=d.svg.selectAll(d.selectorTargets(a)),c.transition().style("opacity",0,"important").call(d.endall,function(){c.style("opacity",null).style("opacity",0)}),b.withLegend&&d.hideLegend(a),d.redraw({withUpdateOrgXDomain:!0,withUpdateXDomain:!0,withLegend:!0})},h.toggle=function(a,b){var c=this,d=this.internal;d.mapToTargetIds(a).forEach(function(a){d.isTargetToShow(a)?c.hide(a,b):c.show(a,b)})},h.zoom=function(a){var b=this.internal;return a&&(b.isTimeSeries()&&(a=a.map(function(a){return b.parseDate(a)})),b.brush.extent(a),b.redraw({withUpdateXDomain:!0,withY:b.config.zoom_rescale}),b.config.zoom_onzoom.call(this,b.x.orgDomain())),b.brush.extent()},h.zoom.enable=function(a){var b=this.internal;b.config.zoom_enabled=a,b.updateAndRedraw()},h.unzoom=function(){var a=this.internal;a.brush.clear().update(),a.redraw({withUpdateXDomain:!0})},h.load=function(a){var b=this.internal,c=b.config;return a.xs&&b.addXs(a.xs),"classes"in a&&Object.keys(a.classes).forEach(function(b){c.data_classes[b]=a.classes[b]}),"categories"in a&&b.isCategorized()&&(c.axis_x_categories=a.categories),"axes"in a&&Object.keys(a.axes).forEach(function(b){c.data_axes[b]=a.axes[b]}),"colors"in a&&Object.keys(a.colors).forEach(function(b){c.data_colors[b]=a.colors[b]}),"cacheIds"in a&&b.hasCaches(a.cacheIds)?void b.load(b.getCaches(a.cacheIds),a.done):void("unload"in a?b.unload(b.mapToTargetIds("boolean"==typeof a.unload&&a.unload?null:a.unload),function(){b.loadFromArgs(a)}):b.loadFromArgs(a))},h.unload=function(a){var b=this.internal;a=a||{},a instanceof Array?a={ids:a}:"string"==typeof a&&(a={ids:[a]}),b.unload(b.mapToTargetIds(a.ids),function(){b.redraw({withUpdateOrgXDomain:!0,withUpdateXDomain:!0,withLegend:!0}),a.done&&a.done()})},h.flow=function(a){var b,c,d,e,f,g,h,i,j=this.internal,k=[],l=j.getMaxDataCount(),n=0,o=0;if(a.json)c=j.convertJsonToData(a.json,a.keys);else if(a.rows)c=j.convertRowsToData(a.rows);else{if(!a.columns)return;c=j.convertColumnsToData(a.columns)}b=j.convertDataToTargets(c,!0),j.data.targets.forEach(function(a){var c,d,e=!1;for(c=0;cd;d++)b[c].values[d].index=o+d,j.isTimeSeries()||(b[c].values[d].x=o+d);a.values=a.values.concat(b[c].values),b.splice(c,1);break}e||k.push(a.id)}),j.data.targets.forEach(function(a){var b,c;for(b=0;bc;c++)a.values.push({id:a.id,index:o+c,x:j.isTimeSeries()?j.getOtherTargetX(o+c):o+c,value:null})}),j.data.targets.length&&b.forEach(function(a){var b,c=[];for(b=j.data.targets[0].values[0].index;o>b;b++)c.push({id:a.id,index:b,x:j.isTimeSeries()?j.getOtherTargetX(b):b,value:null});a.values.forEach(function(a){a.index+=o,j.isTimeSeries()||(a.x+=o)}),a.values=c.concat(a.values)}),j.data.targets=j.data.targets.concat(b),d=j.getMaxDataCount(),f=j.data.targets[0],g=f.values[0],q(a.to)?(n=0,i=j.isTimeSeries()?j.parseDate(a.to):a.to,f.values.forEach(function(a){a.x1?f.values[f.values.length-1].x-g.x:g.x-j.getXDomain(j.data.targets)[0]:1,e=[g.x-h,g.x],j.updateXDomain(null,!0,!0,!1,e)),j.updateTargets(j.data.targets),j.redraw({flow:{index:g.index,length:n,duration:m(a.duration)?a.duration:j.config.transition_duration,done:a.done,orgDataCount:l},withLegend:!0,withTransition:l>1,withTrimXDomain:!1,withUpdateXAxis:!0})},i.generateFlow=function(a){var b=this,c=b.config,d=b.d3;return function(){var e,f,g,h=a.targets,i=a.flow,j=a.drawBar,k=a.drawLine,m=a.drawArea,n=a.cx,o=a.cy,p=a.xv,q=a.xForText,r=a.yForText,s=a.duration,u=1,v=i.index,w=i.length,x=b.getValueOnIndex(b.data.targets[0].values,v),y=b.getValueOnIndex(b.data.targets[0].values,v+w),z=b.x.domain(),A=i.duration||s,B=i.done||function(){},C=b.generateWait(),D=b.xgrid||d.selectAll([]),E=b.xgridLines||d.selectAll([]),F=b.mainRegion||d.selectAll([]),G=b.mainText||d.selectAll([]),H=b.mainBar||d.selectAll([]),I=b.mainLine||d.selectAll([]),J=b.mainArea||d.selectAll([]),K=b.mainCircle||d.selectAll([]);b.flowing=!0,b.data.targets.forEach(function(a){a.values.splice(0,w)}),g=b.updateXDomain(h,!0,!0),b.updateXGrid&&b.updateXGrid(!0),i.orgDataCount?e=1===i.orgDataCount||x.x===y.x?b.x(z[0])-b.x(g[0]):b.isTimeSeries()?b.x(z[0])-b.x(g[0]):b.x(x.x)-b.x(y.x):1!==b.data.targets[0].values.length?e=b.x(z[0])-b.x(g[0]):b.isTimeSeries()?(x=b.getValueOnIndex(b.data.targets[0].values,0),y=b.getValueOnIndex(b.data.targets[0].values,b.data.targets[0].values.length-1),e=b.x(x.x)-b.x(y.x)):e=t(g)/2,u=t(z)/t(g),f="translate("+e+",0) scale("+u+",1)",b.hideXGridFocus(),b.hideTooltip(),d.transition().ease("linear").duration(A).each(function(){C.add(b.axes.x.transition().call(b.xAxis)),C.add(H.transition().attr("transform",f)),C.add(I.transition().attr("transform",f)),C.add(J.transition().attr("transform",f)),C.add(K.transition().attr("transform",f)),C.add(G.transition().attr("transform",f)),C.add(F.filter(b.isRegionOnX).transition().attr("transform",f)),C.add(D.transition().attr("transform",f)),C.add(E.transition().attr("transform",f)) +}).call(C,function(){var a,d=[],e=[],f=[];if(w){for(a=0;w>a;a++)d.push("."+l.shape+"-"+(v+a)),e.push("."+l.text+"-"+(v+a)),f.push("."+l.eventRect+"-"+(v+a));b.svg.selectAll("."+l.shapes).selectAll(d).remove(),b.svg.selectAll("."+l.texts).selectAll(e).remove(),b.svg.selectAll("."+l.eventRects).selectAll(f).remove(),b.svg.select("."+l.xgrid).remove()}D.attr("transform",null).attr(b.xgridAttr),E.attr("transform",null),E.select("line").attr("x1",c.axis_rotated?0:p).attr("x2",c.axis_rotated?b.width:p),E.select("text").attr("x",c.axis_rotated?b.width:0).attr("y",p),H.attr("transform",null).attr("d",j),I.attr("transform",null).attr("d",k),J.attr("transform",null).attr("d",m),K.attr("transform",null).attr("cx",n).attr("cy",o),G.attr("transform",null).attr("x",q).attr("y",r).style("fill-opacity",b.opacityForText.bind(b)),F.attr("transform",null),F.select("rect").filter(b.isRegionOnX).attr("x",b.regionX.bind(b)).attr("width",b.regionWidth.bind(b)),c.interaction_enabled&&b.redrawEventRect(),B(),b.flowing=!1})}},h.selected=function(a){var b=this.internal,c=b.d3;return c.merge(b.main.selectAll("."+l.shapes+b.getTargetSelectorSuffix(a)).selectAll("."+l.shape).filter(function(){return c.select(this).classed(l.SELECTED)}).map(function(a){return a.map(function(a){var b=a.__data__;return b.data?b.data:b})}))},h.select=function(a,b,c){var d=this.internal,e=d.d3,f=d.config;f.data_selection_enabled&&d.main.selectAll("."+l.shapes).selectAll("."+l.shape).each(function(g,h){var i=e.select(this),j=g.data?g.data.id:g.id,k=d.getToggle(this,g).bind(d),m=f.data_selection_grouped||!a||a.indexOf(j)>=0,n=!b||b.indexOf(h)>=0,o=i.classed(l.SELECTED);i.classed(l.line)||i.classed(l.area)||(m&&n?f.data_selection_isselectable(g)&&!o&&k(!0,i.classed(l.SELECTED,!0),g,h):q(c)&&c&&o&&k(!1,i.classed(l.SELECTED,!1),g,h))})},h.unselect=function(a,b){var c=this.internal,d=c.d3,e=c.config;e.data_selection_enabled&&c.main.selectAll("."+l.shapes).selectAll("."+l.shape).each(function(f,g){var h=d.select(this),i=f.data?f.data.id:f.id,j=c.getToggle(this,f).bind(c),k=e.data_selection_grouped||!a||a.indexOf(i)>=0,m=!b||b.indexOf(g)>=0,n=h.classed(l.SELECTED);h.classed(l.line)||h.classed(l.area)||k&&m&&e.data_selection_isselectable(f)&&n&&j(!1,h.classed(l.SELECTED,!1),f,g)})},h.transform=function(a,b){var c=this.internal,d=["pie","donut"].indexOf(a)>=0?{withTransform:!0}:null;c.transformTo(b,a,d)},i.transformTo=function(a,b,c){var d=this,e=!d.hasArcType(),f=c||{withTransitionForAxis:e};f.withTransitionForTransform=!1,d.transiting=!1,d.setTargetType(a,b),d.updateTargets(d.data.targets),d.updateAndRedraw(f)},h.groups=function(a){var b=this.internal,c=b.config;return p(a)?c.data_groups:(c.data_groups=a,b.redraw(),c.data_groups)},h.xgrids=function(a){var b=this.internal,c=b.config;return a?(c.grid_x_lines=a,b.redrawWithoutRescale(),c.grid_x_lines):c.grid_x_lines},h.xgrids.add=function(a){var b=this.internal;return this.xgrids(b.config.grid_x_lines.concat(a?a:[]))},h.xgrids.remove=function(a){var b=this.internal;b.removeGridLines(a,!0)},h.ygrids=function(a){var b=this.internal,c=b.config;return a?(c.grid_y_lines=a,b.redrawWithoutRescale(),c.grid_y_lines):c.grid_y_lines},h.ygrids.add=function(a){var b=this.internal;return this.ygrids(b.config.grid_y_lines.concat(a?a:[]))},h.ygrids.remove=function(a){var b=this.internal;b.removeGridLines(a,!1)},h.regions=function(a){var b=this.internal,c=b.config;return a?(c.regions=a,b.redrawWithoutRescale(),c.regions):c.regions},h.regions.add=function(a){var b=this.internal,c=b.config;return a?(c.regions=c.regions.concat(a),b.redrawWithoutRescale(),c.regions):c.regions},h.regions.remove=function(a){var b,c,d,e=this.internal,f=e.config;return a=a||{},b=e.getOption(a,"duration",f.transition_duration),c=e.getOption(a,"classes",[l.region]),d=e.main.select("."+l.regions).selectAll(c.map(function(a){return"."+a})),(b?d.transition().duration(b):d).style("opacity",0).remove(),f.regions=f.regions.filter(function(a){var b=!1;return a["class"]?(a["class"].split(" ").forEach(function(a){c.indexOf(a)>=0&&(b=!0)}),!b):!0}),f.regions},h.data=function(a){var b=this.internal.data.targets;return"undefined"==typeof a?b:b.filter(function(b){return[].concat(a).indexOf(b.id)>=0})},h.data.shown=function(a){return this.internal.filterTargetsToShow(this.data(a))},h.data.values=function(a){var b,c=null;return a&&(b=this.data(a),c=b[0]?b[0].values.map(function(a){return a.value}):null),c},h.data.names=function(a){return this.internal.clearLegendItemTextBoxCache(),this.internal.updateDataAttributes("names",a)},h.data.colors=function(a){return this.internal.updateDataAttributes("colors",a)},h.data.axes=function(a){return this.internal.updateDataAttributes("axes",a)},h.category=function(a,b){var c=this.internal,d=c.config;return arguments.length>1&&(d.axis_x_categories[a]=b,c.redraw()),d.axis_x_categories[a]},h.categories=function(a){var b=this.internal,c=b.config;return arguments.length?(c.axis_x_categories=a,b.redraw(),c.axis_x_categories):c.axis_x_categories},h.color=function(a){var b=this.internal;return b.color(a)},h.x=function(a){var b=this.internal;return arguments.length&&(b.updateTargetX(b.data.targets,a),b.redraw({withUpdateOrgXDomain:!0,withUpdateXDomain:!0})),b.data.xs},h.xs=function(a){var b=this.internal;return arguments.length&&(b.updateTargetXs(b.data.targets,a),b.redraw({withUpdateOrgXDomain:!0,withUpdateXDomain:!0})),b.data.xs},h.axis=function(){},h.axis.labels=function(a){var b=this.internal;arguments.length&&(Object.keys(a).forEach(function(c){b.axis.setLabelText(c,a[c])}),b.axis.updateLabels())},h.axis.max=function(a){var b=this.internal,c=b.config;return arguments.length?("object"==typeof a?(m(a.x)&&(c.axis_x_max=a.x),m(a.y)&&(c.axis_y_max=a.y),m(a.y2)&&(c.axis_y2_max=a.y2)):c.axis_y_max=c.axis_y2_max=a,void b.redraw({withUpdateOrgXDomain:!0,withUpdateXDomain:!0})):{x:c.axis_x_max,y:c.axis_y_max,y2:c.axis_y2_max}},h.axis.min=function(a){var b=this.internal,c=b.config;return arguments.length?("object"==typeof a?(m(a.x)&&(c.axis_x_min=a.x),m(a.y)&&(c.axis_y_min=a.y),m(a.y2)&&(c.axis_y2_min=a.y2)):c.axis_y_min=c.axis_y2_min=a,void b.redraw({withUpdateOrgXDomain:!0,withUpdateXDomain:!0})):{x:c.axis_x_min,y:c.axis_y_min,y2:c.axis_y2_min}},h.axis.range=function(a){return arguments.length?(q(a.max)&&this.axis.max(a.max),void(q(a.min)&&this.axis.min(a.min))):{max:this.axis.max(),min:this.axis.min()}},h.legend=function(){},h.legend.show=function(a){var b=this.internal;b.showLegend(b.mapToTargetIds(a)),b.updateAndRedraw({withLegend:!0})},h.legend.hide=function(a){var b=this.internal;b.hideLegend(b.mapToTargetIds(a)),b.updateAndRedraw({withLegend:!0})},h.resize=function(a){var b=this.internal,c=b.config;c.size_width=a?a.width:null,c.size_height=a?a.height:null,this.flush()},h.flush=function(){var a=this.internal;a.updateAndRedraw({withLegend:!0,withTransition:!1,withTransitionForTransform:!1})},h.destroy=function(){var b=this.internal;return a.clearInterval(b.intervalForObserveInserted),a.onresize=null,b.selectChart.classed("c3",!1).html(""),Object.keys(b).forEach(function(a){b[a]=null}),null},h.tooltip=function(){},h.tooltip.show=function(a){var b,c,d=this.internal;a.mouse&&(c=a.mouse),a.data?d.isMultipleX()?(c=[d.x(a.data.x),d.getYScale(a.data.id)(a.data.value)],b=null):b=m(a.data.index)?a.data.index:d.getIndexByX(a.data.x):"undefined"!=typeof a.x?b=d.getIndexByX(a.x):"undefined"!=typeof a.index&&(b=a.index),d.dispatchEvent("mouseover",b,c),d.dispatchEvent("mousemove",b,c)},h.tooltip.hide=function(){this.internal.dispatchEvent("mouseout",0)};var z;i.isSafari=function(){var b=a.navigator.userAgent;return b.indexOf("Safari")>=0&&b.indexOf("Chrome")<0},i.isChrome=function(){var b=a.navigator.userAgent;return b.indexOf("Chrome")>=0},Function.prototype.bind||(Function.prototype.bind=function(a){if("function"!=typeof this)throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");var b=Array.prototype.slice.call(arguments,1),c=this,d=function(){},e=function(){return c.apply(this instanceof d?this:a,b.concat(Array.prototype.slice.call(arguments)))};return d.prototype=this.prototype,e.prototype=new d,e}),"function"==typeof define&&define.amd?define("c3",["d3"],k):"undefined"!=typeof exports&&"undefined"!=typeof module?module.exports=k:a.c3=k}(window); \ No newline at end of file From 985578f252aa81a2b62f914a462611ed90d75264 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Thu, 17 Dec 2015 10:35:14 +0900 Subject: [PATCH 352/358] rails g controller temperatures index --- app/assets/javascripts/temperatures.coffee | 3 +++ app/assets/stylesheets/temperatures.scss | 3 +++ app/controllers/temperatures_controller.rb | 4 ++++ app/helpers/temperatures_helper.rb | 2 ++ app/views/temperatures/index.html.haml | 2 ++ config/routes.rb | 2 ++ spec/controllers/temperatures_controller_spec.rb | 12 ++++++++++++ spec/helpers/temperatures_helper_spec.rb | 15 +++++++++++++++ spec/views/temperatures/index.html.haml_spec.rb | 5 +++++ 9 files changed, 48 insertions(+) create mode 100644 app/assets/javascripts/temperatures.coffee create mode 100644 app/assets/stylesheets/temperatures.scss create mode 100644 app/controllers/temperatures_controller.rb create mode 100644 app/helpers/temperatures_helper.rb create mode 100644 app/views/temperatures/index.html.haml create mode 100644 spec/controllers/temperatures_controller_spec.rb create mode 100644 spec/helpers/temperatures_helper_spec.rb create mode 100644 spec/views/temperatures/index.html.haml_spec.rb diff --git a/app/assets/javascripts/temperatures.coffee b/app/assets/javascripts/temperatures.coffee new file mode 100644 index 0000000..24f83d1 --- /dev/null +++ b/app/assets/javascripts/temperatures.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://coffeescript.org/ diff --git a/app/assets/stylesheets/temperatures.scss b/app/assets/stylesheets/temperatures.scss new file mode 100644 index 0000000..4096831 --- /dev/null +++ b/app/assets/stylesheets/temperatures.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the temperatures controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/controllers/temperatures_controller.rb b/app/controllers/temperatures_controller.rb new file mode 100644 index 0000000..311ad69 --- /dev/null +++ b/app/controllers/temperatures_controller.rb @@ -0,0 +1,4 @@ +class TemperaturesController < ApplicationController + def index + end +end diff --git a/app/helpers/temperatures_helper.rb b/app/helpers/temperatures_helper.rb new file mode 100644 index 0000000..932123e --- /dev/null +++ b/app/helpers/temperatures_helper.rb @@ -0,0 +1,2 @@ +module TemperaturesHelper +end diff --git a/app/views/temperatures/index.html.haml b/app/views/temperatures/index.html.haml new file mode 100644 index 0000000..30e760a --- /dev/null +++ b/app/views/temperatures/index.html.haml @@ -0,0 +1,2 @@ +%h1 Temperatures#index +%p Find me in app/views/temperatures/index.html.haml diff --git a/config/routes.rb b/config/routes.rb index 27e253e..af5097f 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,6 +1,8 @@ require 'resque/server' Rails.application.routes.draw do + get 'temperatures/index' + mount Resque::Server.new, at: '/resque' mount API::Base => '/' diff --git a/spec/controllers/temperatures_controller_spec.rb b/spec/controllers/temperatures_controller_spec.rb new file mode 100644 index 0000000..e83de56 --- /dev/null +++ b/spec/controllers/temperatures_controller_spec.rb @@ -0,0 +1,12 @@ +require 'rails_helper' + +RSpec.describe TemperaturesController, :type => :controller do + + describe "GET index" do + it "returns http success" do + get :index + expect(response).to be_success + end + end + +end diff --git a/spec/helpers/temperatures_helper_spec.rb b/spec/helpers/temperatures_helper_spec.rb new file mode 100644 index 0000000..c363ec0 --- /dev/null +++ b/spec/helpers/temperatures_helper_spec.rb @@ -0,0 +1,15 @@ +require 'rails_helper' + +# Specs in this file have access to a helper object that includes +# the TemperaturesHelper. For example: +# +# describe TemperaturesHelper do +# describe "string concat" do +# it "concats two strings with spaces" do +# expect(helper.concat_strings("this","that")).to eq("this that") +# end +# end +# end +RSpec.describe TemperaturesHelper, :type => :helper do + pending "add some examples to (or delete) #{__FILE__}" +end diff --git a/spec/views/temperatures/index.html.haml_spec.rb b/spec/views/temperatures/index.html.haml_spec.rb new file mode 100644 index 0000000..a89ba3e --- /dev/null +++ b/spec/views/temperatures/index.html.haml_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe "temperatures/index.html.haml", :type => :view do + pending "add some examples to (or delete) #{__FILE__}" +end From 72f186d596524de8a715ca28f46ff5f35a0b24a2 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Thu, 17 Dec 2015 10:39:11 +0900 Subject: [PATCH 353/358] :construction: chart --- app/views/temperatures/index.html.haml | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/app/views/temperatures/index.html.haml b/app/views/temperatures/index.html.haml index 30e760a..575a89d 100644 --- a/app/views/temperatures/index.html.haml +++ b/app/views/temperatures/index.html.haml @@ -1,2 +1,16 @@ -%h1 Temperatures#index -%p Find me in app/views/temperatures/index.html.haml += stylesheet_link_tag 'c3.min', plugin: 'redmine_timetable' += javascript_include_tag 'lib/d3.min', plugin: 'redmine_timetable' + +%div#chart + + +:javascript + var chart = c3.generate({ + bindto: '#chart', + data: { + columns: [ + ['data1', 30, 200, 100, 400, 150, 250], + ['data2', 50, 20, 10, 40, 15, 25] + ] + } + }); \ No newline at end of file From 21bad8b9b0ca4f26192ef8774e38b8a302de82bb Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Thu, 17 Dec 2015 10:39:17 +0900 Subject: [PATCH 354/358] add routes --- config/routes.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/routes.rb b/config/routes.rb index af5097f..3fe3f4d 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,7 +1,7 @@ require 'resque/server' Rails.application.routes.draw do - get 'temperatures/index' + resources :temperatures, only: [:index] mount Resque::Server.new, at: '/resque' mount API::Base => '/' From 8d2e5d5f1eaea70ded683d2a2092f5ee88c01c42 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Thu, 17 Dec 2015 10:52:37 +0900 Subject: [PATCH 355/358] add graph library --- {lib => app/assets/javascripts}/c3.min.js | 0 app/assets/javascripts/d3.min.js | 5 +++++ 2 files changed, 5 insertions(+) rename {lib => app/assets/javascripts}/c3.min.js (100%) create mode 100644 app/assets/javascripts/d3.min.js diff --git a/lib/c3.min.js b/app/assets/javascripts/c3.min.js similarity index 100% rename from lib/c3.min.js rename to app/assets/javascripts/c3.min.js diff --git a/app/assets/javascripts/d3.min.js b/app/assets/javascripts/d3.min.js new file mode 100644 index 0000000..a8ab53b --- /dev/null +++ b/app/assets/javascripts/d3.min.js @@ -0,0 +1,5 @@ +!function(){function n(n){return n&&(n.ownerDocument||n.document||n).documentElement}function t(n){return n&&(n.ownerDocument&&n.ownerDocument.defaultView||n.document&&n||n.defaultView)}function e(n,t){return t>n?-1:n>t?1:n>=t?0:NaN}function r(n){return null===n?NaN:+n}function u(n){return!isNaN(n)}function i(n){return{left:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;n(t[i],e)<0?r=i+1:u=i}return r},right:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;n(t[i],e)>0?u=i:r=i+1}return r}}}function a(n){return n.length}function o(n){for(var t=1;n*t%1;)t*=10;return t}function l(n,t){for(var e in t)Object.defineProperty(n.prototype,e,{value:t[e],enumerable:!1})}function c(){this._=Object.create(null)}function s(n){return(n+="")===xa||n[0]===ba?ba+n:n}function f(n){return(n+="")[0]===ba?n.slice(1):n}function h(n){return s(n)in this._}function g(n){return(n=s(n))in this._&&delete this._[n]}function p(){var n=[];for(var t in this._)n.push(f(t));return n}function v(){var n=0;for(var t in this._)++n;return n}function d(){for(var n in this._)return!1;return!0}function m(){this._=Object.create(null)}function y(n){return n}function M(n,t,e){return function(){var r=e.apply(t,arguments);return r===t?n:r}}function x(n,t){if(t in n)return t;t=t.charAt(0).toUpperCase()+t.slice(1);for(var e=0,r=_a.length;r>e;++e){var u=_a[e]+t;if(u in n)return u}}function b(){}function _(){}function w(n){function t(){for(var t,r=e,u=-1,i=r.length;++ue;e++)for(var u,i=n[e],a=0,o=i.length;o>a;a++)(u=i[a])&&t(u,a,e);return n}function Z(n){return Sa(n,za),n}function V(n){var t,e;return function(r,u,i){var a,o=n[i].update,l=o.length;for(i!=e&&(e=i,t=0),u>=t&&(t=u+1);!(a=o[t])&&++t0&&(n=n.slice(0,o));var c=La.get(n);return c&&(n=c,l=B),o?t?u:r:t?b:i}function $(n,t){return function(e){var r=oa.event;oa.event=e,t[0]=this.__data__;try{n.apply(this,t)}finally{oa.event=r}}}function B(n,t){var e=$(n,t);return function(n){var t=this,r=n.relatedTarget;r&&(r===t||8&r.compareDocumentPosition(t))||e.call(t,n)}}function W(e){var r=".dragsuppress-"+ ++Ta,u="click"+r,i=oa.select(t(e)).on("touchmove"+r,S).on("dragstart"+r,S).on("selectstart"+r,S);if(null==qa&&(qa="onselectstart"in e?!1:x(e.style,"userSelect")),qa){var a=n(e).style,o=a[qa];a[qa]="none"}return function(n){if(i.on(r,null),qa&&(a[qa]=o),n){var t=function(){i.on(u,null)};i.on(u,function(){S(),t()},!0),setTimeout(t,0)}}}function J(n,e){e.changedTouches&&(e=e.changedTouches[0]);var r=n.ownerSVGElement||n;if(r.createSVGPoint){var u=r.createSVGPoint();if(0>Ra){var i=t(n);if(i.scrollX||i.scrollY){r=oa.select("body").append("svg").style({position:"absolute",top:0,left:0,margin:0,padding:0,border:"none"},"important");var a=r[0][0].getScreenCTM();Ra=!(a.f||a.e),r.remove()}}return Ra?(u.x=e.pageX,u.y=e.pageY):(u.x=e.clientX,u.y=e.clientY),u=u.matrixTransform(n.getScreenCTM().inverse()),[u.x,u.y]}var o=n.getBoundingClientRect();return[e.clientX-o.left-n.clientLeft,e.clientY-o.top-n.clientTop]}function G(){return oa.event.changedTouches[0].identifier}function K(n){return n>0?1:0>n?-1:0}function Q(n,t,e){return(t[0]-n[0])*(e[1]-n[1])-(t[1]-n[1])*(e[0]-n[0])}function nn(n){return n>1?0:-1>n?ja:Math.acos(n)}function tn(n){return n>1?Ha:-1>n?-Ha:Math.asin(n)}function en(n){return((n=Math.exp(n))-1/n)/2}function rn(n){return((n=Math.exp(n))+1/n)/2}function un(n){return((n=Math.exp(2*n))-1)/(n+1)}function an(n){return(n=Math.sin(n/2))*n}function on(){}function ln(n,t,e){return this instanceof ln?(this.h=+n,this.s=+t,void(this.l=+e)):arguments.length<2?n instanceof ln?new ln(n.h,n.s,n.l):_n(""+n,wn,ln):new ln(n,t,e)}function cn(n,t,e){function r(n){return n>360?n-=360:0>n&&(n+=360),60>n?i+(a-i)*n/60:180>n?a:240>n?i+(a-i)*(240-n)/60:i}function u(n){return Math.round(255*r(n))}var i,a;return n=isNaN(n)?0:(n%=360)<0?n+360:n,t=isNaN(t)?0:0>t?0:t>1?1:t,e=0>e?0:e>1?1:e,a=.5>=e?e*(1+t):e+t-e*t,i=2*e-a,new yn(u(n+120),u(n),u(n-120))}function sn(n,t,e){return this instanceof sn?(this.h=+n,this.c=+t,void(this.l=+e)):arguments.length<2?n instanceof sn?new sn(n.h,n.c,n.l):n instanceof hn?pn(n.l,n.a,n.b):pn((n=Sn((n=oa.rgb(n)).r,n.g,n.b)).l,n.a,n.b):new sn(n,t,e)}function fn(n,t,e){return isNaN(n)&&(n=0),isNaN(t)&&(t=0),new hn(e,Math.cos(n*=Oa)*t,Math.sin(n)*t)}function hn(n,t,e){return this instanceof hn?(this.l=+n,this.a=+t,void(this.b=+e)):arguments.length<2?n instanceof hn?new hn(n.l,n.a,n.b):n instanceof sn?fn(n.h,n.c,n.l):Sn((n=yn(n)).r,n.g,n.b):new hn(n,t,e)}function gn(n,t,e){var r=(n+16)/116,u=r+t/500,i=r-e/200;return u=vn(u)*Ka,r=vn(r)*Qa,i=vn(i)*no,new yn(mn(3.2404542*u-1.5371385*r-.4985314*i),mn(-.969266*u+1.8760108*r+.041556*i),mn(.0556434*u-.2040259*r+1.0572252*i))}function pn(n,t,e){return n>0?new sn(Math.atan2(e,t)*Ia,Math.sqrt(t*t+e*e),n):new sn(NaN,NaN,n)}function vn(n){return n>.206893034?n*n*n:(n-4/29)/7.787037}function dn(n){return n>.008856?Math.pow(n,1/3):7.787037*n+4/29}function mn(n){return Math.round(255*(.00304>=n?12.92*n:1.055*Math.pow(n,1/2.4)-.055))}function yn(n,t,e){return this instanceof yn?(this.r=~~n,this.g=~~t,void(this.b=~~e)):arguments.length<2?n instanceof yn?new yn(n.r,n.g,n.b):_n(""+n,yn,cn):new yn(n,t,e)}function Mn(n){return new yn(n>>16,n>>8&255,255&n)}function xn(n){return Mn(n)+""}function bn(n){return 16>n?"0"+Math.max(0,n).toString(16):Math.min(255,n).toString(16)}function _n(n,t,e){var r,u,i,a=0,o=0,l=0;if(r=/([a-z]+)\((.*)\)/.exec(n=n.toLowerCase()))switch(u=r[2].split(","),r[1]){case"hsl":return e(parseFloat(u[0]),parseFloat(u[1])/100,parseFloat(u[2])/100);case"rgb":return t(Nn(u[0]),Nn(u[1]),Nn(u[2]))}return(i=ro.get(n))?t(i.r,i.g,i.b):(null==n||"#"!==n.charAt(0)||isNaN(i=parseInt(n.slice(1),16))||(4===n.length?(a=(3840&i)>>4,a=a>>4|a,o=240&i,o=o>>4|o,l=15&i,l=l<<4|l):7===n.length&&(a=(16711680&i)>>16,o=(65280&i)>>8,l=255&i)),t(a,o,l))}function wn(n,t,e){var r,u,i=Math.min(n/=255,t/=255,e/=255),a=Math.max(n,t,e),o=a-i,l=(a+i)/2;return o?(u=.5>l?o/(a+i):o/(2-a-i),r=n==a?(t-e)/o+(e>t?6:0):t==a?(e-n)/o+2:(n-t)/o+4,r*=60):(r=NaN,u=l>0&&1>l?0:r),new ln(r,u,l)}function Sn(n,t,e){n=kn(n),t=kn(t),e=kn(e);var r=dn((.4124564*n+.3575761*t+.1804375*e)/Ka),u=dn((.2126729*n+.7151522*t+.072175*e)/Qa),i=dn((.0193339*n+.119192*t+.9503041*e)/no);return hn(116*u-16,500*(r-u),200*(u-i))}function kn(n){return(n/=255)<=.04045?n/12.92:Math.pow((n+.055)/1.055,2.4)}function Nn(n){var t=parseFloat(n);return"%"===n.charAt(n.length-1)?Math.round(2.55*t):t}function En(n){return"function"==typeof n?n:function(){return n}}function An(n){return function(t,e,r){return 2===arguments.length&&"function"==typeof e&&(r=e,e=null),Cn(t,e,n,r)}}function Cn(n,t,e,r){function u(){var n,t=l.status;if(!t&&Ln(l)||t>=200&&300>t||304===t){try{n=e.call(i,l)}catch(r){return void a.error.call(i,r)}a.load.call(i,n)}else a.error.call(i,l)}var i={},a=oa.dispatch("beforesend","progress","load","error"),o={},l=new XMLHttpRequest,c=null;return!this.XDomainRequest||"withCredentials"in l||!/^(http(s)?:)?\/\//.test(n)||(l=new XDomainRequest),"onload"in l?l.onload=l.onerror=u:l.onreadystatechange=function(){l.readyState>3&&u()},l.onprogress=function(n){var t=oa.event;oa.event=n;try{a.progress.call(i,l)}finally{oa.event=t}},i.header=function(n,t){return n=(n+"").toLowerCase(),arguments.length<2?o[n]:(null==t?delete o[n]:o[n]=t+"",i)},i.mimeType=function(n){return arguments.length?(t=null==n?null:n+"",i):t},i.responseType=function(n){return arguments.length?(c=n,i):c},i.response=function(n){return e=n,i},["get","post"].forEach(function(n){i[n]=function(){return i.send.apply(i,[n].concat(ca(arguments)))}}),i.send=function(e,r,u){if(2===arguments.length&&"function"==typeof r&&(u=r,r=null),l.open(e,n,!0),null==t||"accept"in o||(o.accept=t+",*/*"),l.setRequestHeader)for(var s in o)l.setRequestHeader(s,o[s]);return null!=t&&l.overrideMimeType&&l.overrideMimeType(t),null!=c&&(l.responseType=c),null!=u&&i.on("error",u).on("load",function(n){u(null,n)}),a.beforesend.call(i,l),l.send(null==r?null:r),i},i.abort=function(){return l.abort(),i},oa.rebind(i,a,"on"),null==r?i:i.get(zn(r))}function zn(n){return 1===n.length?function(t,e){n(null==t?e:null)}:n}function Ln(n){var t=n.responseType;return t&&"text"!==t?n.response:n.responseText}function qn(n,t,e){var r=arguments.length;2>r&&(t=0),3>r&&(e=Date.now());var u=e+t,i={c:n,t:u,n:null};return io?io.n=i:uo=i,io=i,ao||(oo=clearTimeout(oo),ao=1,lo(Tn)),i}function Tn(){var n=Rn(),t=Dn()-n;t>24?(isFinite(t)&&(clearTimeout(oo),oo=setTimeout(Tn,t)),ao=0):(ao=1,lo(Tn))}function Rn(){for(var n=Date.now(),t=uo;t;)n>=t.t&&t.c(n-t.t)&&(t.c=null),t=t.n;return n}function Dn(){for(var n,t=uo,e=1/0;t;)t.c?(t.t8?function(n){return n/e}:function(n){return n*e},symbol:n}}function Un(n){var t=n.decimal,e=n.thousands,r=n.grouping,u=n.currency,i=r&&e?function(n,t){for(var u=n.length,i=[],a=0,o=r[0],l=0;u>0&&o>0&&(l+o+1>t&&(o=Math.max(1,t-l)),i.push(n.substring(u-=o,u+o)),!((l+=o+1)>t));)o=r[a=(a+1)%r.length];return i.reverse().join(e)}:y;return function(n){var e=so.exec(n),r=e[1]||" ",a=e[2]||">",o=e[3]||"-",l=e[4]||"",c=e[5],s=+e[6],f=e[7],h=e[8],g=e[9],p=1,v="",d="",m=!1,y=!0;switch(h&&(h=+h.substring(1)),(c||"0"===r&&"="===a)&&(c=r="0",a="="),g){case"n":f=!0,g="g";break;case"%":p=100,d="%",g="f";break;case"p":p=100,d="%",g="r";break;case"b":case"o":case"x":case"X":"#"===l&&(v="0"+g.toLowerCase());case"c":y=!1;case"d":m=!0,h=0;break;case"s":p=-1,g="r"}"$"===l&&(v=u[0],d=u[1]),"r"!=g||h||(g="g"),null!=h&&("g"==g?h=Math.max(1,Math.min(21,h)):("e"==g||"f"==g)&&(h=Math.max(0,Math.min(20,h)))),g=fo.get(g)||Fn;var M=c&&f;return function(n){var e=d;if(m&&n%1)return"";var u=0>n||0===n&&0>1/n?(n=-n,"-"):"-"===o?"":o;if(0>p){var l=oa.formatPrefix(n,h);n=l.scale(n),e=l.symbol+d}else n*=p;n=g(n,h);var x,b,_=n.lastIndexOf(".");if(0>_){var w=y?n.lastIndexOf("e"):-1;0>w?(x=n,b=""):(x=n.substring(0,w),b=n.substring(w))}else x=n.substring(0,_),b=t+n.substring(_+1);!c&&f&&(x=i(x,1/0));var S=v.length+x.length+b.length+(M?0:u.length),k=s>S?new Array(S=s-S+1).join(r):"";return M&&(x=i(k+x,k.length?s-b.length:1/0)),u+=v,n=x+b,("<"===a?u+n+k:">"===a?k+u+n:"^"===a?k.substring(0,S>>=1)+u+n+k.substring(S):u+(M?n:k+n))+e}}}function Fn(n){return n+""}function Hn(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function On(n,t,e){function r(t){var e=n(t),r=i(e,1);return r-t>t-e?e:r}function u(e){return t(e=n(new go(e-1)),1),e}function i(n,e){return t(n=new go(+n),e),n}function a(n,r,i){var a=u(n),o=[];if(i>1)for(;r>a;)e(a)%i||o.push(new Date(+a)),t(a,1);else for(;r>a;)o.push(new Date(+a)),t(a,1);return o}function o(n,t,e){try{go=Hn;var r=new Hn;return r._=n,a(r,t,e)}finally{go=Date}}n.floor=n,n.round=r,n.ceil=u,n.offset=i,n.range=a;var l=n.utc=In(n);return l.floor=l,l.round=In(r),l.ceil=In(u),l.offset=In(i),l.range=o,n}function In(n){return function(t,e){try{go=Hn;var r=new Hn;return r._=t,n(r,e)._}finally{go=Date}}}function Yn(n){function t(n){function t(t){for(var e,u,i,a=[],o=-1,l=0;++oo;){if(r>=c)return-1;if(u=t.charCodeAt(o++),37===u){if(a=t.charAt(o++),i=C[a in vo?t.charAt(o++):a],!i||(r=i(n,e,r))<0)return-1}else if(u!=e.charCodeAt(r++))return-1}return r}function r(n,t,e){_.lastIndex=0;var r=_.exec(t.slice(e));return r?(n.w=w.get(r[0].toLowerCase()),e+r[0].length):-1}function u(n,t,e){x.lastIndex=0;var r=x.exec(t.slice(e));return r?(n.w=b.get(r[0].toLowerCase()),e+r[0].length):-1}function i(n,t,e){N.lastIndex=0;var r=N.exec(t.slice(e));return r?(n.m=E.get(r[0].toLowerCase()),e+r[0].length):-1}function a(n,t,e){S.lastIndex=0;var r=S.exec(t.slice(e));return r?(n.m=k.get(r[0].toLowerCase()),e+r[0].length):-1}function o(n,t,r){return e(n,A.c.toString(),t,r)}function l(n,t,r){return e(n,A.x.toString(),t,r)}function c(n,t,r){return e(n,A.X.toString(),t,r)}function s(n,t,e){var r=M.get(t.slice(e,e+=2).toLowerCase());return null==r?-1:(n.p=r,e)}var f=n.dateTime,h=n.date,g=n.time,p=n.periods,v=n.days,d=n.shortDays,m=n.months,y=n.shortMonths;t.utc=function(n){function e(n){try{go=Hn;var t=new go;return t._=n,r(t)}finally{go=Date}}var r=t(n);return e.parse=function(n){try{go=Hn;var t=r.parse(n);return t&&t._}finally{go=Date}},e.toString=r.toString,e},t.multi=t.utc.multi=ct;var M=oa.map(),x=Vn(v),b=Xn(v),_=Vn(d),w=Xn(d),S=Vn(m),k=Xn(m),N=Vn(y),E=Xn(y);p.forEach(function(n,t){M.set(n.toLowerCase(),t)});var A={a:function(n){return d[n.getDay()]},A:function(n){return v[n.getDay()]},b:function(n){return y[n.getMonth()]},B:function(n){return m[n.getMonth()]},c:t(f),d:function(n,t){return Zn(n.getDate(),t,2)},e:function(n,t){return Zn(n.getDate(),t,2)},H:function(n,t){return Zn(n.getHours(),t,2)},I:function(n,t){return Zn(n.getHours()%12||12,t,2)},j:function(n,t){return Zn(1+ho.dayOfYear(n),t,3)},L:function(n,t){return Zn(n.getMilliseconds(),t,3)},m:function(n,t){return Zn(n.getMonth()+1,t,2)},M:function(n,t){return Zn(n.getMinutes(),t,2)},p:function(n){return p[+(n.getHours()>=12)]},S:function(n,t){return Zn(n.getSeconds(),t,2)},U:function(n,t){return Zn(ho.sundayOfYear(n),t,2)},w:function(n){return n.getDay()},W:function(n,t){return Zn(ho.mondayOfYear(n),t,2)},x:t(h),X:t(g),y:function(n,t){return Zn(n.getFullYear()%100,t,2)},Y:function(n,t){return Zn(n.getFullYear()%1e4,t,4)},Z:ot,"%":function(){return"%"}},C={a:r,A:u,b:i,B:a,c:o,d:tt,e:tt,H:rt,I:rt,j:et,L:at,m:nt,M:ut,p:s,S:it,U:Bn,w:$n,W:Wn,x:l,X:c,y:Gn,Y:Jn,Z:Kn,"%":lt};return t}function Zn(n,t,e){var r=0>n?"-":"",u=(r?-n:n)+"",i=u.length;return r+(e>i?new Array(e-i+1).join(t)+u:u)}function Vn(n){return new RegExp("^(?:"+n.map(oa.requote).join("|")+")","i")}function Xn(n){for(var t=new c,e=-1,r=n.length;++e68?1900:2e3)}function nt(n,t,e){mo.lastIndex=0;var r=mo.exec(t.slice(e,e+2));return r?(n.m=r[0]-1,e+r[0].length):-1}function tt(n,t,e){mo.lastIndex=0;var r=mo.exec(t.slice(e,e+2));return r?(n.d=+r[0],e+r[0].length):-1}function et(n,t,e){mo.lastIndex=0;var r=mo.exec(t.slice(e,e+3));return r?(n.j=+r[0],e+r[0].length):-1}function rt(n,t,e){mo.lastIndex=0;var r=mo.exec(t.slice(e,e+2));return r?(n.H=+r[0],e+r[0].length):-1}function ut(n,t,e){mo.lastIndex=0;var r=mo.exec(t.slice(e,e+2));return r?(n.M=+r[0],e+r[0].length):-1}function it(n,t,e){mo.lastIndex=0;var r=mo.exec(t.slice(e,e+2));return r?(n.S=+r[0],e+r[0].length):-1}function at(n,t,e){mo.lastIndex=0;var r=mo.exec(t.slice(e,e+3));return r?(n.L=+r[0],e+r[0].length):-1}function ot(n){var t=n.getTimezoneOffset(),e=t>0?"-":"+",r=Ma(t)/60|0,u=Ma(t)%60;return e+Zn(r,"0",2)+Zn(u,"0",2)}function lt(n,t,e){yo.lastIndex=0;var r=yo.exec(t.slice(e,e+1));return r?e+r[0].length:-1}function ct(n){for(var t=n.length,e=-1;++e=0?1:-1,o=a*e,l=Math.cos(t),c=Math.sin(t),s=i*c,f=u*l+s*Math.cos(o),h=s*a*Math.sin(o);So.add(Math.atan2(h,f)),r=n,u=l,i=c}var t,e,r,u,i;ko.point=function(a,o){ko.point=n,r=(t=a)*Oa,u=Math.cos(o=(e=o)*Oa/2+ja/4),i=Math.sin(o)},ko.lineEnd=function(){n(t,e)}}function dt(n){var t=n[0],e=n[1],r=Math.cos(e);return[r*Math.cos(t),r*Math.sin(t),Math.sin(e)]}function mt(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]}function yt(n,t){return[n[1]*t[2]-n[2]*t[1],n[2]*t[0]-n[0]*t[2],n[0]*t[1]-n[1]*t[0]]}function Mt(n,t){n[0]+=t[0],n[1]+=t[1],n[2]+=t[2]}function xt(n,t){return[n[0]*t,n[1]*t,n[2]*t]}function bt(n){var t=Math.sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);n[0]/=t,n[1]/=t,n[2]/=t}function _t(n){return[Math.atan2(n[1],n[0]),tn(n[2])]}function wt(n,t){return Ma(n[0]-t[0])o;++o)u.point((e=n[o])[0],e[1]);return void u.lineEnd()}var l=new Tt(e,n,null,!0),c=new Tt(e,null,l,!1);l.o=c,i.push(l),a.push(c),l=new Tt(r,n,null,!1),c=new Tt(r,null,l,!0),l.o=c,i.push(l),a.push(c)}}),a.sort(t),qt(i),qt(a),i.length){for(var o=0,l=e,c=a.length;c>o;++o)a[o].e=l=!l;for(var s,f,h=i[0];;){for(var g=h,p=!0;g.v;)if((g=g.n)===h)return;s=g.z,u.lineStart();do{if(g.v=g.o.v=!0,g.e){if(p)for(var o=0,c=s.length;c>o;++o)u.point((f=s[o])[0],f[1]);else r(g.x,g.n.x,1,u);g=g.n}else{if(p){s=g.p.z;for(var o=s.length-1;o>=0;--o)u.point((f=s[o])[0],f[1])}else r(g.x,g.p.x,-1,u);g=g.p}g=g.o,s=g.z,p=!p}while(!g.v);u.lineEnd()}}}function qt(n){if(t=n.length){for(var t,e,r=0,u=n[0];++r0){for(b||(i.polygonStart(),b=!0),i.lineStart();++a1&&2&t&&e.push(e.pop().concat(e.shift())),g.push(e.filter(Dt))}var g,p,v,d=t(i),m=u.invert(r[0],r[1]),y={point:a,lineStart:l,lineEnd:c,polygonStart:function(){y.point=s,y.lineStart=f,y.lineEnd=h,g=[],p=[]},polygonEnd:function(){y.point=a,y.lineStart=l,y.lineEnd=c,g=oa.merge(g);var n=Ot(m,p);g.length?(b||(i.polygonStart(),b=!0),Lt(g,jt,n,e,i)):n&&(b||(i.polygonStart(),b=!0),i.lineStart(),e(null,null,1,i),i.lineEnd()),b&&(i.polygonEnd(),b=!1),g=p=null},sphere:function(){i.polygonStart(),i.lineStart(),e(null,null,1,i),i.lineEnd(),i.polygonEnd()}},M=Pt(),x=t(M),b=!1;return y}}function Dt(n){return n.length>1}function Pt(){var n,t=[];return{lineStart:function(){t.push(n=[])},point:function(t,e){n.push([t,e])},lineEnd:b,buffer:function(){var e=t;return t=[],n=null,e},rejoin:function(){t.length>1&&t.push(t.pop().concat(t.shift()))}}}function jt(n,t){return((n=n.x)[0]<0?n[1]-Ha-Da:Ha-n[1])-((t=t.x)[0]<0?t[1]-Ha-Da:Ha-t[1])}function Ut(n){var t,e=NaN,r=NaN,u=NaN;return{lineStart:function(){n.lineStart(),t=1},point:function(i,a){var o=i>0?ja:-ja,l=Ma(i-e);Ma(l-ja)0?Ha:-Ha),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(o,r),n.point(i,r),t=0):u!==o&&l>=ja&&(Ma(e-u)Da?Math.atan((Math.sin(t)*(i=Math.cos(r))*Math.sin(e)-Math.sin(r)*(u=Math.cos(t))*Math.sin(n))/(u*i*a)):(t+r)/2}function Ht(n,t,e,r){var u;if(null==n)u=e*Ha,r.point(-ja,u),r.point(0,u),r.point(ja,u),r.point(ja,0),r.point(ja,-u),r.point(0,-u),r.point(-ja,-u),r.point(-ja,0),r.point(-ja,u);else if(Ma(n[0]-t[0])>Da){var i=n[0]o;++o){var c=t[o],s=c.length;if(s)for(var f=c[0],h=f[0],g=f[1]/2+ja/4,p=Math.sin(g),v=Math.cos(g),d=1;;){d===s&&(d=0),n=c[d];var m=n[0],y=n[1]/2+ja/4,M=Math.sin(y),x=Math.cos(y),b=m-h,_=b>=0?1:-1,w=_*b,S=w>ja,k=p*M;if(So.add(Math.atan2(k*_*Math.sin(w),v*x+k*Math.cos(w))),i+=S?b+_*Ua:b,S^h>=e^m>=e){var N=yt(dt(f),dt(n));bt(N);var E=yt(u,N);bt(E);var A=(S^b>=0?-1:1)*tn(E[2]);(r>A||r===A&&(N[0]||N[1]))&&(a+=S^b>=0?1:-1)}if(!d++)break;h=m,p=M,v=x,f=n}}return(-Da>i||Da>i&&0>So)^1&a}function It(n){function t(n,t){return Math.cos(n)*Math.cos(t)>i}function e(n){var e,i,l,c,s;return{lineStart:function(){c=l=!1,s=1},point:function(f,h){var g,p=[f,h],v=t(f,h),d=a?v?0:u(f,h):v?u(f+(0>f?ja:-ja),h):0;if(!e&&(c=l=v)&&n.lineStart(),v!==l&&(g=r(e,p),(wt(e,g)||wt(p,g))&&(p[0]+=Da,p[1]+=Da,v=t(p[0],p[1]))),v!==l)s=0,v?(n.lineStart(),g=r(p,e),n.point(g[0],g[1])):(g=r(e,p),n.point(g[0],g[1]),n.lineEnd()),e=g;else if(o&&e&&a^v){var m;d&i||!(m=r(p,e,!0))||(s=0,a?(n.lineStart(),n.point(m[0][0],m[0][1]),n.point(m[1][0],m[1][1]),n.lineEnd()):(n.point(m[1][0],m[1][1]),n.lineEnd(),n.lineStart(),n.point(m[0][0],m[0][1])))}!v||e&&wt(e,p)||n.point(p[0],p[1]),e=p,l=v,i=d},lineEnd:function(){l&&n.lineEnd(),e=null},clean:function(){return s|(c&&l)<<1}}}function r(n,t,e){var r=dt(n),u=dt(t),a=[1,0,0],o=yt(r,u),l=mt(o,o),c=o[0],s=l-c*c;if(!s)return!e&&n;var f=i*l/s,h=-i*c/s,g=yt(a,o),p=xt(a,f),v=xt(o,h);Mt(p,v);var d=g,m=mt(p,d),y=mt(d,d),M=m*m-y*(mt(p,p)-1);if(!(0>M)){var x=Math.sqrt(M),b=xt(d,(-m-x)/y);if(Mt(b,p),b=_t(b),!e)return b;var _,w=n[0],S=t[0],k=n[1],N=t[1];w>S&&(_=w,w=S,S=_);var E=S-w,A=Ma(E-ja)E;if(!A&&k>N&&(_=k,k=N,N=_),C?A?k+N>0^b[1]<(Ma(b[0]-w)ja^(w<=b[0]&&b[0]<=S)){var z=xt(d,(-m+x)/y);return Mt(z,p),[b,_t(z)]}}}function u(t,e){var r=a?n:ja-n,u=0;return-r>t?u|=1:t>r&&(u|=2),-r>e?u|=4:e>r&&(u|=8),u}var i=Math.cos(n),a=i>0,o=Ma(i)>Da,l=ve(n,6*Oa);return Rt(t,e,l,a?[0,-n]:[-ja,n-ja])}function Yt(n,t,e,r){return function(u){var i,a=u.a,o=u.b,l=a.x,c=a.y,s=o.x,f=o.y,h=0,g=1,p=s-l,v=f-c;if(i=n-l,p||!(i>0)){if(i/=p,0>p){if(h>i)return;g>i&&(g=i)}else if(p>0){if(i>g)return;i>h&&(h=i)}if(i=e-l,p||!(0>i)){if(i/=p,0>p){if(i>g)return;i>h&&(h=i)}else if(p>0){if(h>i)return;g>i&&(g=i)}if(i=t-c,v||!(i>0)){if(i/=v,0>v){if(h>i)return;g>i&&(g=i)}else if(v>0){if(i>g)return;i>h&&(h=i)}if(i=r-c,v||!(0>i)){if(i/=v,0>v){if(i>g)return;i>h&&(h=i)}else if(v>0){if(h>i)return;g>i&&(g=i)}return h>0&&(u.a={x:l+h*p,y:c+h*v}),1>g&&(u.b={x:l+g*p,y:c+g*v}),u}}}}}}function Zt(n,t,e,r){function u(r,u){return Ma(r[0]-n)0?0:3:Ma(r[0]-e)0?2:1:Ma(r[1]-t)0?1:0:u>0?3:2}function i(n,t){return a(n.x,t.x)}function a(n,t){var e=u(n,1),r=u(t,1);return e!==r?e-r:0===e?t[1]-n[1]:1===e?n[0]-t[0]:2===e?n[1]-t[1]:t[0]-n[0]}return function(o){function l(n){for(var t=0,e=d.length,r=n[1],u=0;e>u;++u)for(var i,a=1,o=d[u],l=o.length,c=o[0];l>a;++a)i=o[a],c[1]<=r?i[1]>r&&Q(c,i,n)>0&&++t:i[1]<=r&&Q(c,i,n)<0&&--t,c=i;return 0!==t}function c(i,o,l,c){var s=0,f=0;if(null==i||(s=u(i,l))!==(f=u(o,l))||a(i,o)<0^l>0){do c.point(0===s||3===s?n:e,s>1?r:t);while((s=(s+l+4)%4)!==f)}else c.point(o[0],o[1])}function s(u,i){return u>=n&&e>=u&&i>=t&&r>=i}function f(n,t){s(n,t)&&o.point(n,t)}function h(){C.point=p,d&&d.push(m=[]),S=!0,w=!1,b=_=NaN}function g(){v&&(p(y,M),x&&w&&E.rejoin(),v.push(E.buffer())),C.point=f,w&&o.lineEnd()}function p(n,t){n=Math.max(-Fo,Math.min(Fo,n)),t=Math.max(-Fo,Math.min(Fo,t));var e=s(n,t);if(d&&m.push([n,t]),S)y=n,M=t,x=e,S=!1,e&&(o.lineStart(),o.point(n,t));else if(e&&w)o.point(n,t);else{var r={a:{x:b,y:_},b:{x:n,y:t}};A(r)?(w||(o.lineStart(),o.point(r.a.x,r.a.y)),o.point(r.b.x,r.b.y),e||o.lineEnd(),k=!1):e&&(o.lineStart(),o.point(n,t),k=!1)}b=n,_=t,w=e}var v,d,m,y,M,x,b,_,w,S,k,N=o,E=Pt(),A=Yt(n,t,e,r),C={point:f,lineStart:h,lineEnd:g,polygonStart:function(){o=E,v=[],d=[],k=!0},polygonEnd:function(){o=N,v=oa.merge(v);var t=l([n,r]),e=k&&t,u=v.length;(e||u)&&(o.polygonStart(),e&&(o.lineStart(),c(null,null,1,o),o.lineEnd()),u&&Lt(v,i,t,c,o),o.polygonEnd()),v=d=m=null}};return C}}function Vt(n){var t=0,e=ja/3,r=oe(n),u=r(t,e);return u.parallels=function(n){return arguments.length?r(t=n[0]*ja/180,e=n[1]*ja/180):[t/ja*180,e/ja*180]},u}function Xt(n,t){function e(n,t){var e=Math.sqrt(i-2*u*Math.sin(t))/u;return[e*Math.sin(n*=u),a-e*Math.cos(n)]}var r=Math.sin(n),u=(r+Math.sin(t))/2,i=1+r*(2*u-r),a=Math.sqrt(i)/u;return e.invert=function(n,t){var e=a-t;return[Math.atan2(n,e)/u,tn((i-(n*n+e*e)*u*u)/(2*u))]},e}function $t(){function n(n,t){Oo+=u*n-r*t,r=n,u=t}var t,e,r,u;Xo.point=function(i,a){Xo.point=n,t=r=i,e=u=a},Xo.lineEnd=function(){n(t,e)}}function Bt(n,t){Io>n&&(Io=n),n>Zo&&(Zo=n),Yo>t&&(Yo=t),t>Vo&&(Vo=t)}function Wt(){function n(n,t){a.push("M",n,",",t,i)}function t(n,t){a.push("M",n,",",t),o.point=e}function e(n,t){a.push("L",n,",",t)}function r(){o.point=n}function u(){a.push("Z")}var i=Jt(4.5),a=[],o={point:n,lineStart:function(){o.point=t},lineEnd:r,polygonStart:function(){o.lineEnd=u},polygonEnd:function(){o.lineEnd=r,o.point=n},pointRadius:function(n){return i=Jt(n),o},result:function(){if(a.length){var n=a.join("");return a=[],n}}};return o}function Jt(n){return"m0,"+n+"a"+n+","+n+" 0 1,1 0,"+-2*n+"a"+n+","+n+" 0 1,1 0,"+2*n+"z"}function Gt(n,t){Ao+=n,Co+=t,++zo}function Kt(){function n(n,r){var u=n-t,i=r-e,a=Math.sqrt(u*u+i*i);Lo+=a*(t+n)/2,qo+=a*(e+r)/2,To+=a,Gt(t=n,e=r)}var t,e;Bo.point=function(r,u){Bo.point=n,Gt(t=r,e=u)}}function Qt(){Bo.point=Gt}function ne(){function n(n,t){var e=n-r,i=t-u,a=Math.sqrt(e*e+i*i);Lo+=a*(r+n)/2,qo+=a*(u+t)/2,To+=a,a=u*n-r*t,Ro+=a*(r+n),Do+=a*(u+t),Po+=3*a,Gt(r=n,u=t)}var t,e,r,u;Bo.point=function(i,a){Bo.point=n,Gt(t=r=i,e=u=a)},Bo.lineEnd=function(){n(t,e)}}function te(n){function t(t,e){n.moveTo(t+a,e),n.arc(t,e,a,0,Ua)}function e(t,e){n.moveTo(t,e),o.point=r}function r(t,e){n.lineTo(t,e)}function u(){o.point=t}function i(){n.closePath()}var a=4.5,o={point:t,lineStart:function(){o.point=e},lineEnd:u,polygonStart:function(){o.lineEnd=i},polygonEnd:function(){o.lineEnd=u,o.point=t},pointRadius:function(n){return a=n,o},result:b};return o}function ee(n){function t(n){return(o?r:e)(n)}function e(t){return ie(t,function(e,r){e=n(e,r),t.point(e[0],e[1])})}function r(t){function e(e,r){e=n(e,r),t.point(e[0],e[1])}function r(){M=NaN,S.point=i,t.lineStart()}function i(e,r){var i=dt([e,r]),a=n(e,r);u(M,x,y,b,_,w,M=a[0],x=a[1],y=e,b=i[0],_=i[1],w=i[2],o,t),t.point(M,x)}function a(){S.point=e,t.lineEnd()}function l(){r(),S.point=c,S.lineEnd=s}function c(n,t){ +i(f=n,h=t),g=M,p=x,v=b,d=_,m=w,S.point=i}function s(){u(M,x,y,b,_,w,g,p,f,v,d,m,o,t),S.lineEnd=a,a()}var f,h,g,p,v,d,m,y,M,x,b,_,w,S={point:e,lineStart:r,lineEnd:a,polygonStart:function(){t.polygonStart(),S.lineStart=l},polygonEnd:function(){t.polygonEnd(),S.lineStart=r}};return S}function u(t,e,r,o,l,c,s,f,h,g,p,v,d,m){var y=s-t,M=f-e,x=y*y+M*M;if(x>4*i&&d--){var b=o+g,_=l+p,w=c+v,S=Math.sqrt(b*b+_*_+w*w),k=Math.asin(w/=S),N=Ma(Ma(w)-1)i||Ma((y*z+M*L)/x-.5)>.3||a>o*g+l*p+c*v)&&(u(t,e,r,o,l,c,A,C,N,b/=S,_/=S,w,d,m),m.point(A,C),u(A,C,N,b,_,w,s,f,h,g,p,v,d,m))}}var i=.5,a=Math.cos(30*Oa),o=16;return t.precision=function(n){return arguments.length?(o=(i=n*n)>0&&16,t):Math.sqrt(i)},t}function re(n){var t=ee(function(t,e){return n([t*Ia,e*Ia])});return function(n){return le(t(n))}}function ue(n){this.stream=n}function ie(n,t){return{point:t,sphere:function(){n.sphere()},lineStart:function(){n.lineStart()},lineEnd:function(){n.lineEnd()},polygonStart:function(){n.polygonStart()},polygonEnd:function(){n.polygonEnd()}}}function ae(n){return oe(function(){return n})()}function oe(n){function t(n){return n=o(n[0]*Oa,n[1]*Oa),[n[0]*h+l,c-n[1]*h]}function e(n){return n=o.invert((n[0]-l)/h,(c-n[1])/h),n&&[n[0]*Ia,n[1]*Ia]}function r(){o=Ct(a=fe(m,M,x),i);var n=i(v,d);return l=g-n[0]*h,c=p+n[1]*h,u()}function u(){return s&&(s.valid=!1,s=null),t}var i,a,o,l,c,s,f=ee(function(n,t){return n=i(n,t),[n[0]*h+l,c-n[1]*h]}),h=150,g=480,p=250,v=0,d=0,m=0,M=0,x=0,b=Uo,_=y,w=null,S=null;return t.stream=function(n){return s&&(s.valid=!1),s=le(b(a,f(_(n)))),s.valid=!0,s},t.clipAngle=function(n){return arguments.length?(b=null==n?(w=n,Uo):It((w=+n)*Oa),u()):w},t.clipExtent=function(n){return arguments.length?(S=n,_=n?Zt(n[0][0],n[0][1],n[1][0],n[1][1]):y,u()):S},t.scale=function(n){return arguments.length?(h=+n,r()):h},t.translate=function(n){return arguments.length?(g=+n[0],p=+n[1],r()):[g,p]},t.center=function(n){return arguments.length?(v=n[0]%360*Oa,d=n[1]%360*Oa,r()):[v*Ia,d*Ia]},t.rotate=function(n){return arguments.length?(m=n[0]%360*Oa,M=n[1]%360*Oa,x=n.length>2?n[2]%360*Oa:0,r()):[m*Ia,M*Ia,x*Ia]},oa.rebind(t,f,"precision"),function(){return i=n.apply(this,arguments),t.invert=i.invert&&e,r()}}function le(n){return ie(n,function(t,e){n.point(t*Oa,e*Oa)})}function ce(n,t){return[n,t]}function se(n,t){return[n>ja?n-Ua:-ja>n?n+Ua:n,t]}function fe(n,t,e){return n?t||e?Ct(ge(n),pe(t,e)):ge(n):t||e?pe(t,e):se}function he(n){return function(t,e){return t+=n,[t>ja?t-Ua:-ja>t?t+Ua:t,e]}}function ge(n){var t=he(n);return t.invert=he(-n),t}function pe(n,t){function e(n,t){var e=Math.cos(t),o=Math.cos(n)*e,l=Math.sin(n)*e,c=Math.sin(t),s=c*r+o*u;return[Math.atan2(l*i-s*a,o*r-c*u),tn(s*i+l*a)]}var r=Math.cos(n),u=Math.sin(n),i=Math.cos(t),a=Math.sin(t);return e.invert=function(n,t){var e=Math.cos(t),o=Math.cos(n)*e,l=Math.sin(n)*e,c=Math.sin(t),s=c*i-l*a;return[Math.atan2(l*i+c*a,o*r+s*u),tn(s*r-o*u)]},e}function ve(n,t){var e=Math.cos(n),r=Math.sin(n);return function(u,i,a,o){var l=a*t;null!=u?(u=de(e,u),i=de(e,i),(a>0?i>u:u>i)&&(u+=a*Ua)):(u=n+a*Ua,i=n-.5*l);for(var c,s=u;a>0?s>i:i>s;s-=l)o.point((c=_t([e,-r*Math.cos(s),-r*Math.sin(s)]))[0],c[1])}}function de(n,t){var e=dt(t);e[0]-=n,bt(e);var r=nn(-e[1]);return((-e[2]<0?-r:r)+2*Math.PI-Da)%(2*Math.PI)}function me(n,t,e){var r=oa.range(n,t-Da,e).concat(t);return function(n){return r.map(function(t){return[n,t]})}}function ye(n,t,e){var r=oa.range(n,t-Da,e).concat(t);return function(n){return r.map(function(t){return[t,n]})}}function Me(n){return n.source}function xe(n){return n.target}function be(n,t,e,r){var u=Math.cos(t),i=Math.sin(t),a=Math.cos(r),o=Math.sin(r),l=u*Math.cos(n),c=u*Math.sin(n),s=a*Math.cos(e),f=a*Math.sin(e),h=2*Math.asin(Math.sqrt(an(r-t)+u*a*an(e-n))),g=1/Math.sin(h),p=h?function(n){var t=Math.sin(n*=h)*g,e=Math.sin(h-n)*g,r=e*l+t*s,u=e*c+t*f,a=e*i+t*o;return[Math.atan2(u,r)*Ia,Math.atan2(a,Math.sqrt(r*r+u*u))*Ia]}:function(){return[n*Ia,t*Ia]};return p.distance=h,p}function _e(){function n(n,u){var i=Math.sin(u*=Oa),a=Math.cos(u),o=Ma((n*=Oa)-t),l=Math.cos(o);Wo+=Math.atan2(Math.sqrt((o=a*Math.sin(o))*o+(o=r*i-e*a*l)*o),e*i+r*a*l),t=n,e=i,r=a}var t,e,r;Jo.point=function(u,i){t=u*Oa,e=Math.sin(i*=Oa),r=Math.cos(i),Jo.point=n},Jo.lineEnd=function(){Jo.point=Jo.lineEnd=b}}function we(n,t){function e(t,e){var r=Math.cos(t),u=Math.cos(e),i=n(r*u);return[i*u*Math.sin(t),i*Math.sin(e)]}return e.invert=function(n,e){var r=Math.sqrt(n*n+e*e),u=t(r),i=Math.sin(u),a=Math.cos(u);return[Math.atan2(n*i,r*a),Math.asin(r&&e*i/r)]},e}function Se(n,t){function e(n,t){a>0?-Ha+Da>t&&(t=-Ha+Da):t>Ha-Da&&(t=Ha-Da);var e=a/Math.pow(u(t),i);return[e*Math.sin(i*n),a-e*Math.cos(i*n)]}var r=Math.cos(n),u=function(n){return Math.tan(ja/4+n/2)},i=n===t?Math.sin(n):Math.log(r/Math.cos(t))/Math.log(u(t)/u(n)),a=r*Math.pow(u(n),i)/i;return i?(e.invert=function(n,t){var e=a-t,r=K(i)*Math.sqrt(n*n+e*e);return[Math.atan2(n,e)/i,2*Math.atan(Math.pow(a/r,1/i))-Ha]},e):Ne}function ke(n,t){function e(n,t){var e=i-t;return[e*Math.sin(u*n),i-e*Math.cos(u*n)]}var r=Math.cos(n),u=n===t?Math.sin(n):(r-Math.cos(t))/(t-n),i=r/u+n;return Ma(u)u;u++){for(;r>1&&Q(n[e[r-2]],n[e[r-1]],n[u])<=0;)--r;e[r++]=u}return e.slice(0,r)}function qe(n,t){return n[0]-t[0]||n[1]-t[1]}function Te(n,t,e){return(e[0]-t[0])*(n[1]-t[1])<(e[1]-t[1])*(n[0]-t[0])}function Re(n,t,e,r){var u=n[0],i=e[0],a=t[0]-u,o=r[0]-i,l=n[1],c=e[1],s=t[1]-l,f=r[1]-c,h=(o*(l-c)-f*(u-i))/(f*a-o*s);return[u+h*a,l+h*s]}function De(n){var t=n[0],e=n[n.length-1];return!(t[0]-e[0]||t[1]-e[1])}function Pe(){rr(this),this.edge=this.site=this.circle=null}function je(n){var t=ll.pop()||new Pe;return t.site=n,t}function Ue(n){Be(n),il.remove(n),ll.push(n),rr(n)}function Fe(n){var t=n.circle,e=t.x,r=t.cy,u={x:e,y:r},i=n.P,a=n.N,o=[n];Ue(n);for(var l=i;l.circle&&Ma(e-l.circle.x)s;++s)c=o[s],l=o[s-1],nr(c.edge,l.site,c.site,u);l=o[0],c=o[f-1],c.edge=Ke(l.site,c.site,null,u),$e(l),$e(c)}function He(n){for(var t,e,r,u,i=n.x,a=n.y,o=il._;o;)if(r=Oe(o,a)-i,r>Da)o=o.L;else{if(u=i-Ie(o,a),!(u>Da)){r>-Da?(t=o.P,e=o):u>-Da?(t=o,e=o.N):t=e=o;break}if(!o.R){t=o;break}o=o.R}var l=je(n);if(il.insert(t,l),t||e){if(t===e)return Be(t),e=je(t.site),il.insert(l,e),l.edge=e.edge=Ke(t.site,l.site),$e(t),void $e(e);if(!e)return void(l.edge=Ke(t.site,l.site));Be(t),Be(e);var c=t.site,s=c.x,f=c.y,h=n.x-s,g=n.y-f,p=e.site,v=p.x-s,d=p.y-f,m=2*(h*d-g*v),y=h*h+g*g,M=v*v+d*d,x={x:(d*y-g*M)/m+s,y:(h*M-v*y)/m+f};nr(e.edge,c,p,x),l.edge=Ke(c,n,null,x),e.edge=Ke(n,p,null,x),$e(t),$e(e)}}function Oe(n,t){var e=n.site,r=e.x,u=e.y,i=u-t;if(!i)return r;var a=n.P;if(!a)return-(1/0);e=a.site;var o=e.x,l=e.y,c=l-t;if(!c)return o;var s=o-r,f=1/i-1/c,h=s/c;return f?(-h+Math.sqrt(h*h-2*f*(s*s/(-2*c)-l+c/2+u-i/2)))/f+r:(r+o)/2}function Ie(n,t){var e=n.N;if(e)return Oe(e,t);var r=n.site;return r.y===t?r.x:1/0}function Ye(n){this.site=n,this.edges=[]}function Ze(n){for(var t,e,r,u,i,a,o,l,c,s,f=n[0][0],h=n[1][0],g=n[0][1],p=n[1][1],v=ul,d=v.length;d--;)if(i=v[d],i&&i.prepare())for(o=i.edges,l=o.length,a=0;l>a;)s=o[a].end(),r=s.x,u=s.y,c=o[++a%l].start(),t=c.x,e=c.y,(Ma(r-t)>Da||Ma(u-e)>Da)&&(o.splice(a,0,new tr(Qe(i.site,s,Ma(r-f)Da?{x:f,y:Ma(t-f)Da?{x:Ma(e-p)Da?{x:h,y:Ma(t-h)Da?{x:Ma(e-g)=-Pa)){var g=l*l+c*c,p=s*s+f*f,v=(f*g-c*p)/h,d=(l*p-s*g)/h,f=d+o,m=cl.pop()||new Xe;m.arc=n,m.site=u,m.x=v+a,m.y=f+Math.sqrt(v*v+d*d),m.cy=f,n.circle=m;for(var y=null,M=ol._;M;)if(m.yd||d>=o)return;if(h>p){if(i){if(i.y>=c)return}else i={x:d,y:l};e={x:d,y:c}}else{if(i){if(i.yr||r>1)if(h>p){if(i){if(i.y>=c)return}else i={x:(l-u)/r,y:l};e={x:(c-u)/r,y:c}}else{if(i){if(i.yg){if(i){if(i.x>=o)return}else i={x:a,y:r*a+u};e={x:o,y:r*o+u}}else{if(i){if(i.xi||f>a||r>h||u>g)){if(p=n.point){var p,v=t-n.x,d=e-n.y,m=v*v+d*d;if(l>m){var y=Math.sqrt(l=m);r=t-y,u=e-y,i=t+y,a=e+y,o=p}}for(var M=n.nodes,x=.5*(s+h),b=.5*(f+g),_=t>=x,w=e>=b,S=w<<1|_,k=S+4;k>S;++S)if(n=M[3&S])switch(3&S){case 0:c(n,s,f,x,b);break;case 1:c(n,x,f,h,b);break;case 2:c(n,s,b,x,g);break;case 3:c(n,x,b,h,g)}}}(n,r,u,i,a),o}function vr(n,t){n=oa.rgb(n),t=oa.rgb(t);var e=n.r,r=n.g,u=n.b,i=t.r-e,a=t.g-r,o=t.b-u;return function(n){return"#"+bn(Math.round(e+i*n))+bn(Math.round(r+a*n))+bn(Math.round(u+o*n))}}function dr(n,t){var e,r={},u={};for(e in n)e in t?r[e]=Mr(n[e],t[e]):u[e]=n[e];for(e in t)e in n||(u[e]=t[e]);return function(n){for(e in r)u[e]=r[e](n);return u}}function mr(n,t){return n=+n,t=+t,function(e){return n*(1-e)+t*e}}function yr(n,t){var e,r,u,i=fl.lastIndex=hl.lastIndex=0,a=-1,o=[],l=[];for(n+="",t+="";(e=fl.exec(n))&&(r=hl.exec(t));)(u=r.index)>i&&(u=t.slice(i,u),o[a]?o[a]+=u:o[++a]=u),(e=e[0])===(r=r[0])?o[a]?o[a]+=r:o[++a]=r:(o[++a]=null,l.push({i:a,x:mr(e,r)})),i=hl.lastIndex;return ir;++r)o[(e=l[r]).i]=e.x(n);return o.join("")})}function Mr(n,t){for(var e,r=oa.interpolators.length;--r>=0&&!(e=oa.interpolators[r](n,t)););return e}function xr(n,t){var e,r=[],u=[],i=n.length,a=t.length,o=Math.min(n.length,t.length);for(e=0;o>e;++e)r.push(Mr(n[e],t[e]));for(;i>e;++e)u[e]=n[e];for(;a>e;++e)u[e]=t[e];return function(n){for(e=0;o>e;++e)u[e]=r[e](n);return u}}function br(n){return function(t){return 0>=t?0:t>=1?1:n(t)}}function _r(n){return function(t){return 1-n(1-t)}}function wr(n){return function(t){return.5*(.5>t?n(2*t):2-n(2-2*t))}}function Sr(n){return n*n}function kr(n){return n*n*n}function Nr(n){if(0>=n)return 0;if(n>=1)return 1;var t=n*n,e=t*n;return 4*(.5>n?e:3*(n-t)+e-.75)}function Er(n){return function(t){return Math.pow(t,n)}}function Ar(n){return 1-Math.cos(n*Ha)}function Cr(n){return Math.pow(2,10*(n-1))}function zr(n){return 1-Math.sqrt(1-n*n)}function Lr(n,t){var e;return arguments.length<2&&(t=.45),arguments.length?e=t/Ua*Math.asin(1/n):(n=1,e=t/4),function(r){return 1+n*Math.pow(2,-10*r)*Math.sin((r-e)*Ua/t)}}function qr(n){return n||(n=1.70158),function(t){return t*t*((n+1)*t-n)}}function Tr(n){return 1/2.75>n?7.5625*n*n:2/2.75>n?7.5625*(n-=1.5/2.75)*n+.75:2.5/2.75>n?7.5625*(n-=2.25/2.75)*n+.9375:7.5625*(n-=2.625/2.75)*n+.984375}function Rr(n,t){n=oa.hcl(n),t=oa.hcl(t);var e=n.h,r=n.c,u=n.l,i=t.h-e,a=t.c-r,o=t.l-u;return isNaN(a)&&(a=0,r=isNaN(r)?t.c:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return fn(e+i*n,r+a*n,u+o*n)+""}}function Dr(n,t){n=oa.hsl(n),t=oa.hsl(t);var e=n.h,r=n.s,u=n.l,i=t.h-e,a=t.s-r,o=t.l-u;return isNaN(a)&&(a=0,r=isNaN(r)?t.s:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return cn(e+i*n,r+a*n,u+o*n)+""}}function Pr(n,t){n=oa.lab(n),t=oa.lab(t);var e=n.l,r=n.a,u=n.b,i=t.l-e,a=t.a-r,o=t.b-u;return function(n){return gn(e+i*n,r+a*n,u+o*n)+""}}function jr(n,t){return t-=n,function(e){return Math.round(n+t*e)}}function Ur(n){var t=[n.a,n.b],e=[n.c,n.d],r=Hr(t),u=Fr(t,e),i=Hr(Or(e,t,-u))||0;t[0]*e[1]180?t+=360:t-n>180&&(n+=360),r.push({i:e.push(Ir(e)+"rotate(",null,")")-2,x:mr(n,t)})):t&&e.push(Ir(e)+"rotate("+t+")")}function Vr(n,t,e,r){n!==t?r.push({i:e.push(Ir(e)+"skewX(",null,")")-2,x:mr(n,t)}):t&&e.push(Ir(e)+"skewX("+t+")")}function Xr(n,t,e,r){if(n[0]!==t[0]||n[1]!==t[1]){var u=e.push(Ir(e)+"scale(",null,",",null,")");r.push({i:u-4,x:mr(n[0],t[0])},{i:u-2,x:mr(n[1],t[1])})}else(1!==t[0]||1!==t[1])&&e.push(Ir(e)+"scale("+t+")")}function $r(n,t){var e=[],r=[];return n=oa.transform(n),t=oa.transform(t),Yr(n.translate,t.translate,e,r),Zr(n.rotate,t.rotate,e,r),Vr(n.skew,t.skew,e,r),Xr(n.scale,t.scale,e,r),n=t=null,function(n){for(var t,u=-1,i=r.length;++u=0;)e.push(u[r])}function au(n,t){for(var e=[n],r=[];null!=(n=e.pop());)if(r.push(n),(i=n.children)&&(u=i.length))for(var u,i,a=-1;++ae;++e)(t=n[e][1])>u&&(r=e,u=t);return r}function mu(n){return n.reduce(yu,0)}function yu(n,t){return n+t[1]}function Mu(n,t){return xu(n,Math.ceil(Math.log(t.length)/Math.LN2+1))}function xu(n,t){for(var e=-1,r=+n[0],u=(n[1]-r)/t,i=[];++e<=t;)i[e]=u*e+r;return i}function bu(n){return[oa.min(n),oa.max(n)]}function _u(n,t){return n.value-t.value}function wu(n,t){var e=n._pack_next;n._pack_next=t,t._pack_prev=n,t._pack_next=e,e._pack_prev=t}function Su(n,t){n._pack_next=t,t._pack_prev=n}function ku(n,t){var e=t.x-n.x,r=t.y-n.y,u=n.r+t.r;return.999*u*u>e*e+r*r}function Nu(n){function t(n){s=Math.min(n.x-n.r,s),f=Math.max(n.x+n.r,f),h=Math.min(n.y-n.r,h),g=Math.max(n.y+n.r,g)}if((e=n.children)&&(c=e.length)){var e,r,u,i,a,o,l,c,s=1/0,f=-(1/0),h=1/0,g=-(1/0);if(e.forEach(Eu),r=e[0],r.x=-r.r,r.y=0,t(r),c>1&&(u=e[1],u.x=u.r,u.y=0,t(u),c>2))for(i=e[2],zu(r,u,i),t(i),wu(r,i),r._pack_prev=i,wu(i,u),u=r._pack_next,a=3;c>a;a++){zu(r,u,i=e[a]);var p=0,v=1,d=1;for(o=u._pack_next;o!==u;o=o._pack_next,v++)if(ku(o,i)){p=1;break}if(1==p)for(l=r._pack_prev;l!==o._pack_prev&&!ku(l,i);l=l._pack_prev,d++);p?(d>v||v==d&&u.ra;a++)i=e[a],i.x-=m,i.y-=y,M=Math.max(M,i.r+Math.sqrt(i.x*i.x+i.y*i.y));n.r=M,e.forEach(Au)}}function Eu(n){n._pack_next=n._pack_prev=n}function Au(n){delete n._pack_next,delete n._pack_prev}function Cu(n,t,e,r){var u=n.children;if(n.x=t+=r*n.x,n.y=e+=r*n.y,n.r*=r,u)for(var i=-1,a=u.length;++i=0;)t=u[i],t.z+=e,t.m+=e,e+=t.s+(r+=t.c)}function Pu(n,t,e){return n.a.parent===t.parent?n.a:e}function ju(n){return 1+oa.max(n,function(n){return n.y})}function Uu(n){return n.reduce(function(n,t){return n+t.x},0)/n.length}function Fu(n){var t=n.children;return t&&t.length?Fu(t[0]):n}function Hu(n){var t,e=n.children;return e&&(t=e.length)?Hu(e[t-1]):n}function Ou(n){return{x:n.x,y:n.y,dx:n.dx,dy:n.dy}}function Iu(n,t){var e=n.x+t[3],r=n.y+t[0],u=n.dx-t[1]-t[3],i=n.dy-t[0]-t[2];return 0>u&&(e+=u/2,u=0),0>i&&(r+=i/2,i=0),{x:e,y:r,dx:u,dy:i}}function Yu(n){var t=n[0],e=n[n.length-1];return e>t?[t,e]:[e,t]}function Zu(n){return n.rangeExtent?n.rangeExtent():Yu(n.range())}function Vu(n,t,e,r){var u=e(n[0],n[1]),i=r(t[0],t[1]);return function(n){return i(u(n))}}function Xu(n,t){var e,r=0,u=n.length-1,i=n[r],a=n[u];return i>a&&(e=r,r=u,u=e,e=i,i=a,a=e),n[r]=t.floor(i),n[u]=t.ceil(a),n}function $u(n){return n?{floor:function(t){return Math.floor(t/n)*n},ceil:function(t){return Math.ceil(t/n)*n}}:wl}function Bu(n,t,e,r){var u=[],i=[],a=0,o=Math.min(n.length,t.length)-1;for(n[o]2?Bu:Vu,l=r?Wr:Br;return a=u(n,t,l,e),o=u(t,n,l,Mr),i}function i(n){return a(n)}var a,o;return i.invert=function(n){return o(n)},i.domain=function(t){return arguments.length?(n=t.map(Number),u()):n},i.range=function(n){return arguments.length?(t=n,u()):t},i.rangeRound=function(n){return i.range(n).interpolate(jr)},i.clamp=function(n){return arguments.length?(r=n,u()):r},i.interpolate=function(n){return arguments.length?(e=n,u()):e},i.ticks=function(t){return Qu(n,t)},i.tickFormat=function(t,e){return ni(n,t,e)},i.nice=function(t){return Gu(n,t),u()},i.copy=function(){return Wu(n,t,e,r)},u()}function Ju(n,t){return oa.rebind(n,t,"range","rangeRound","interpolate","clamp")}function Gu(n,t){return Xu(n,$u(Ku(n,t)[2]))}function Ku(n,t){null==t&&(t=10);var e=Yu(n),r=e[1]-e[0],u=Math.pow(10,Math.floor(Math.log(r/t)/Math.LN10)),i=t/r*u;return.15>=i?u*=10:.35>=i?u*=5:.75>=i&&(u*=2),e[0]=Math.ceil(e[0]/u)*u,e[1]=Math.floor(e[1]/u)*u+.5*u,e[2]=u,e}function Qu(n,t){return oa.range.apply(oa,Ku(n,t))}function ni(n,t,e){var r=Ku(n,t);if(e){var u=so.exec(e);if(u.shift(),"s"===u[8]){var i=oa.formatPrefix(Math.max(Ma(r[0]),Ma(r[1])));return u[7]||(u[7]="."+ti(i.scale(r[2]))),u[8]="f",e=oa.format(u.join("")),function(n){return e(i.scale(n))+i.symbol}}u[7]||(u[7]="."+ei(u[8],r)),e=u.join("")}else e=",."+ti(r[2])+"f";return oa.format(e)}function ti(n){return-Math.floor(Math.log(n)/Math.LN10+.01)}function ei(n,t){var e=ti(t[2]);return n in Sl?Math.abs(e-ti(Math.max(Ma(t[0]),Ma(t[1]))))+ +("e"!==n):e-2*("%"===n)}function ri(n,t,e,r){function u(n){return(e?Math.log(0>n?0:n):-Math.log(n>0?0:-n))/Math.log(t)}function i(n){return e?Math.pow(t,n):-Math.pow(t,-n)}function a(t){return n(u(t))}return a.invert=function(t){return i(n.invert(t))},a.domain=function(t){return arguments.length?(e=t[0]>=0,n.domain((r=t.map(Number)).map(u)),a):r},a.base=function(e){return arguments.length?(t=+e,n.domain(r.map(u)),a):t},a.nice=function(){var t=Xu(r.map(u),e?Math:Nl);return n.domain(t),r=t.map(i),a},a.ticks=function(){var n=Yu(r),a=[],o=n[0],l=n[1],c=Math.floor(u(o)),s=Math.ceil(u(l)),f=t%1?2:t;if(isFinite(s-c)){if(e){for(;s>c;c++)for(var h=1;f>h;h++)a.push(i(c)*h);a.push(i(c))}else for(a.push(i(c));c++0;h--)a.push(i(c)*h);for(c=0;a[c]l;s--);a=a.slice(c,s)}return a},a.tickFormat=function(n,e){if(!arguments.length)return kl;arguments.length<2?e=kl:"function"!=typeof e&&(e=oa.format(e));var r=Math.max(1,t*n/a.ticks().length);return function(n){var a=n/i(Math.round(u(n)));return t-.5>a*t&&(a*=t),r>=a?e(n):""}},a.copy=function(){return ri(n.copy(),t,e,r)},Ju(a,n)}function ui(n,t,e){function r(t){return n(u(t))}var u=ii(t),i=ii(1/t);return r.invert=function(t){return i(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain((e=t.map(Number)).map(u)),r):e},r.ticks=function(n){return Qu(e,n)},r.tickFormat=function(n,t){return ni(e,n,t)},r.nice=function(n){return r.domain(Gu(e,n))},r.exponent=function(a){return arguments.length?(u=ii(t=a),i=ii(1/t),n.domain(e.map(u)),r):t},r.copy=function(){return ui(n.copy(),t,e)},Ju(r,n)}function ii(n){return function(t){return 0>t?-Math.pow(-t,n):Math.pow(t,n)}}function ai(n,t){function e(e){return i[((u.get(e)||("range"===t.t?u.set(e,n.push(e)):NaN))-1)%i.length]}function r(t,e){return oa.range(n.length).map(function(n){return t+e*n})}var u,i,a;return e.domain=function(r){if(!arguments.length)return n;n=[],u=new c;for(var i,a=-1,o=r.length;++ae?[NaN,NaN]:[e>0?o[e-1]:n[0],et?NaN:t/i+n,[t,t+1/i]},r.copy=function(){return li(n,t,e)},u()}function ci(n,t){function e(e){return e>=e?t[oa.bisect(n,e)]:void 0}return e.domain=function(t){return arguments.length?(n=t,e):n},e.range=function(n){return arguments.length?(t=n,e):t},e.invertExtent=function(e){return e=t.indexOf(e),[n[e-1],n[e]]},e.copy=function(){return ci(n,t)},e}function si(n){function t(n){return+n}return t.invert=t,t.domain=t.range=function(e){return arguments.length?(n=e.map(t),t):n},t.ticks=function(t){return Qu(n,t)},t.tickFormat=function(t,e){return ni(n,t,e)},t.copy=function(){return si(n)},t}function fi(){return 0}function hi(n){return n.innerRadius}function gi(n){return n.outerRadius}function pi(n){return n.startAngle}function vi(n){return n.endAngle}function di(n){return n&&n.padAngle}function mi(n,t,e,r){return(n-e)*t-(t-r)*n>0?0:1}function yi(n,t,e,r,u){var i=n[0]-t[0],a=n[1]-t[1],o=(u?r:-r)/Math.sqrt(i*i+a*a),l=o*a,c=-o*i,s=n[0]+l,f=n[1]+c,h=t[0]+l,g=t[1]+c,p=(s+h)/2,v=(f+g)/2,d=h-s,m=g-f,y=d*d+m*m,M=e-r,x=s*g-h*f,b=(0>m?-1:1)*Math.sqrt(Math.max(0,M*M*y-x*x)),_=(x*m-d*b)/y,w=(-x*d-m*b)/y,S=(x*m+d*b)/y,k=(-x*d+m*b)/y,N=_-p,E=w-v,A=S-p,C=k-v;return N*N+E*E>A*A+C*C&&(_=S,w=k),[[_-l,w-c],[_*e/M,w*e/M]]}function Mi(n){function t(t){function a(){c.push("M",i(n(s),o))}for(var l,c=[],s=[],f=-1,h=t.length,g=En(e),p=En(r);++f1?n.join("L"):n+"Z"}function bi(n){return n.join("L")+"Z"}function _i(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t1&&u.push("H",r[0]),u.join("")}function wi(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t1){o=t[1],i=n[l],l++,r+="C"+(u[0]+a[0])+","+(u[1]+a[1])+","+(i[0]-o[0])+","+(i[1]-o[1])+","+i[0]+","+i[1];for(var c=2;c9&&(u=3*t/Math.sqrt(u),a[o]=u*e,a[o+1]=u*r));for(o=-1;++o<=l;)u=(n[Math.min(l,o+1)][0]-n[Math.max(0,o-1)][0])/(6*(1+a[o]*a[o])),i.push([u||0,a[o]*u||0]);return i}function Fi(n){return n.length<3?xi(n):n[0]+Ai(n,Ui(n))}function Hi(n){for(var t,e,r,u=-1,i=n.length;++u=t?a(n-t):void(s.c=a)}function a(e){var u=p.active,i=p[u];i&&(i.timer.c=null,i.timer.t=NaN,--p.count,delete p[u],i.event&&i.event.interrupt.call(n,n.__data__,i.index));for(var a in p)if(r>+a){var c=p[a];c.timer.c=null,c.timer.t=NaN,--p.count,delete p[a]}s.c=o,qn(function(){return s.c&&o(e||1)&&(s.c=null,s.t=NaN),1},0,l),p.active=r,v.event&&v.event.start.call(n,n.__data__,t),g=[],v.tween.forEach(function(e,r){(r=r.call(n,n.__data__,t))&&g.push(r)}),h=v.ease,f=v.duration}function o(u){for(var i=u/f,a=h(i),o=g.length;o>0;)g[--o].call(n,a);return i>=1?(v.event&&v.event.end.call(n,n.__data__,t),--p.count?delete p[r]:delete n[e],1):void 0}var l,s,f,h,g,p=n[e]||(n[e]={active:0,count:0}),v=p[r];v||(l=u.time,s=qn(i,0,l),v=p[r]={tween:new c,time:l,timer:s,delay:u.delay,duration:u.duration,ease:u.ease,index:t},u=null,++p.count)}function na(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate("+(isFinite(r)?r:e(n))+",0)"})}function ta(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate(0,"+(isFinite(r)?r:e(n))+")"})}function ea(n){return n.toISOString()}function ra(n,t,e){function r(t){return n(t)}function u(n,e){var r=n[1]-n[0],u=r/e,i=oa.bisect(Gl,u);return i==Gl.length?[t.year,Ku(n.map(function(n){return n/31536e6}),e)[2]]:i?t[u/Gl[i-1]1?{floor:function(t){for(;e(t=n.floor(t));)t=ua(t-1);return t},ceil:function(t){for(;e(t=n.ceil(t));)t=ua(+t+1);return t}}:n))},r.ticks=function(n,t){var e=Yu(r.domain()),i=null==n?u(e,10):"number"==typeof n?u(e,n):!n.range&&[{range:n},t];return i&&(n=i[0],t=i[1]),n.range(e[0],ua(+e[1]+1),1>t?1:t)},r.tickFormat=function(){return e},r.copy=function(){return ra(n.copy(),t,e)},Ju(r,n)}function ua(n){return new Date(n)}function ia(n){return JSON.parse(n.responseText)}function aa(n){var t=sa.createRange();return t.selectNode(sa.body),t.createContextualFragment(n.responseText)}var oa={version:"3.5.11"},la=[].slice,ca=function(n){return la.call(n)},sa=this.document;if(sa)try{ca(sa.documentElement.childNodes)[0].nodeType}catch(fa){ca=function(n){for(var t=n.length,e=new Array(t);t--;)e[t]=n[t];return e}}if(Date.now||(Date.now=function(){return+new Date}),sa)try{sa.createElement("DIV").style.setProperty("opacity",0,"")}catch(ha){var ga=this.Element.prototype,pa=ga.setAttribute,va=ga.setAttributeNS,da=this.CSSStyleDeclaration.prototype,ma=da.setProperty;ga.setAttribute=function(n,t){pa.call(this,n,t+"")},ga.setAttributeNS=function(n,t,e){va.call(this,n,t,e+"")},da.setProperty=function(n,t,e){ma.call(this,n,t+"",e)}}oa.ascending=e,oa.descending=function(n,t){return n>t?-1:t>n?1:t>=n?0:NaN},oa.min=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u=r){e=r;break}for(;++ur&&(e=r)}else{for(;++u=r){e=r;break}for(;++ur&&(e=r)}return e},oa.max=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u=r){e=r;break}for(;++ue&&(e=r)}else{for(;++u=r){e=r;break}for(;++ue&&(e=r)}return e},oa.extent=function(n,t){var e,r,u,i=-1,a=n.length;if(1===arguments.length){for(;++i=r){e=u=r;break}for(;++ir&&(e=r),r>u&&(u=r))}else{for(;++i=r){e=u=r;break}for(;++ir&&(e=r),r>u&&(u=r))}return[e,u]},oa.sum=function(n,t){var e,r=0,i=n.length,a=-1;if(1===arguments.length)for(;++a1?l/(s-1):void 0},oa.deviation=function(){var n=oa.variance.apply(this,arguments);return n?Math.sqrt(n):n};var ya=i(e);oa.bisectLeft=ya.left,oa.bisect=oa.bisectRight=ya.right,oa.bisector=function(n){return i(1===n.length?function(t,r){return e(n(t),r)}:n)},oa.shuffle=function(n,t,e){(i=arguments.length)<3&&(e=n.length,2>i&&(t=0));for(var r,u,i=e-t;i;)u=Math.random()*i--|0,r=n[i+t],n[i+t]=n[u+t],n[u+t]=r;return n},oa.permute=function(n,t){for(var e=t.length,r=new Array(e);e--;)r[e]=n[t[e]];return r},oa.pairs=function(n){for(var t,e=0,r=n.length-1,u=n[0],i=new Array(0>r?0:r);r>e;)i[e]=[t=u,u=n[++e]];return i},oa.zip=function(){if(!(r=arguments.length))return[];for(var n=-1,t=oa.min(arguments,a),e=new Array(t);++n=0;)for(r=n[u],t=r.length;--t>=0;)e[--a]=r[t];return e};var Ma=Math.abs;oa.range=function(n,t,e){if(arguments.length<3&&(e=1,arguments.length<2&&(t=n,n=0)),(t-n)/e===1/0)throw new Error("infinite range");var r,u=[],i=o(Ma(e)),a=-1;if(n*=i,t*=i,e*=i,0>e)for(;(r=n+e*++a)>t;)u.push(r/i);else for(;(r=n+e*++a)=i.length)return r?r.call(u,a):e?a.sort(e):a;for(var l,s,f,h,g=-1,p=a.length,v=i[o++],d=new c;++g=i.length)return n;var r=[],u=a[e++];return n.forEach(function(n,u){r.push({key:n,values:t(u,e)})}),u?r.sort(function(n,t){return u(n.key,t.key)}):r}var e,r,u={},i=[],a=[];return u.map=function(t,e){return n(e,t,0)},u.entries=function(e){return t(n(oa.map,e,0),0)},u.key=function(n){return i.push(n),u},u.sortKeys=function(n){return a[i.length-1]=n,u},u.sortValues=function(n){return e=n,u},u.rollup=function(n){return r=n,u},u},oa.set=function(n){var t=new m;if(n)for(var e=0,r=n.length;r>e;++e)t.add(n[e]);return t},l(m,{has:h,add:function(n){return this._[s(n+="")]=!0,n},remove:g,values:p,size:v,empty:d,forEach:function(n){for(var t in this._)n.call(this,f(t))}}),oa.behavior={},oa.rebind=function(n,t){for(var e,r=1,u=arguments.length;++r=0&&(r=n.slice(e+1),n=n.slice(0,e)),n)return arguments.length<2?this[n].on(r):this[n].on(r,t);if(2===arguments.length){if(null==t)for(n in this)this.hasOwnProperty(n)&&this[n].on(r,null);return this}},oa.event=null,oa.requote=function(n){return n.replace(wa,"\\$&")};var wa=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g,Sa={}.__proto__?function(n,t){n.__proto__=t}:function(n,t){for(var e in t)n[e]=t[e]},ka=function(n,t){return t.querySelector(n)},Na=function(n,t){return t.querySelectorAll(n)},Ea=function(n,t){var e=n.matches||n[x(n,"matchesSelector")];return(Ea=function(n,t){return e.call(n,t)})(n,t)};"function"==typeof Sizzle&&(ka=function(n,t){return Sizzle(n,t)[0]||null},Na=Sizzle,Ea=Sizzle.matchesSelector),oa.selection=function(){return oa.select(sa.documentElement)};var Aa=oa.selection.prototype=[];Aa.select=function(n){var t,e,r,u,i=[];n=A(n);for(var a=-1,o=this.length;++a=0&&"xmlns"!==(e=n.slice(0,t))&&(n=n.slice(t+1)),Ca.hasOwnProperty(e)?{space:Ca[e],local:n}:n}},Aa.attr=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node();return n=oa.ns.qualify(n),n.local?e.getAttributeNS(n.space,n.local):e.getAttribute(n)}for(t in n)this.each(z(t,n[t]));return this}return this.each(z(n,t))},Aa.classed=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node(),r=(n=T(n)).length,u=-1;if(t=e.classList){for(;++uu){if("string"!=typeof n){2>u&&(e="");for(r in n)this.each(P(r,n[r],e));return this}if(2>u){var i=this.node();return t(i).getComputedStyle(i,null).getPropertyValue(n)}r=""}return this.each(P(n,e,r))},Aa.property=function(n,t){if(arguments.length<2){if("string"==typeof n)return this.node()[n];for(t in n)this.each(j(t,n[t]));return this}return this.each(j(n,t))},Aa.text=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.textContent=null==t?"":t}:null==n?function(){this.textContent=""}:function(){this.textContent=n}):this.node().textContent},Aa.html=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.innerHTML=null==t?"":t}:null==n?function(){this.innerHTML=""}:function(){this.innerHTML=n}):this.node().innerHTML},Aa.append=function(n){return n=U(n),this.select(function(){return this.appendChild(n.apply(this,arguments))})},Aa.insert=function(n,t){return n=U(n),t=A(t),this.select(function(){return this.insertBefore(n.apply(this,arguments),t.apply(this,arguments)||null)})},Aa.remove=function(){return this.each(F)},Aa.data=function(n,t){function e(n,e){var r,u,i,a=n.length,f=e.length,h=Math.min(a,f),g=new Array(f),p=new Array(f),v=new Array(a);if(t){var d,m=new c,y=new Array(a);for(r=-1;++rr;++r)p[r]=H(e[r]);for(;a>r;++r)v[r]=n[r]}p.update=g,p.parentNode=g.parentNode=v.parentNode=n.parentNode,o.push(p),l.push(g),s.push(v)}var r,u,i=-1,a=this.length;if(!arguments.length){for(n=new Array(a=(r=this[0]).length);++ii;i++){u.push(t=[]),t.parentNode=(e=this[i]).parentNode;for(var o=0,l=e.length;l>o;o++)(r=e[o])&&n.call(r,r.__data__,o,i)&&t.push(r)}return E(u)},Aa.order=function(){for(var n=-1,t=this.length;++n=0;)(e=r[u])&&(i&&i!==e.nextSibling&&i.parentNode.insertBefore(e,i),i=e);return this},Aa.sort=function(n){n=I.apply(this,arguments);for(var t=-1,e=this.length;++tn;n++)for(var e=this[n],r=0,u=e.length;u>r;r++){var i=e[r];if(i)return i}return null},Aa.size=function(){var n=0;return Y(this,function(){++n}),n};var za=[];oa.selection.enter=Z,oa.selection.enter.prototype=za,za.append=Aa.append,za.empty=Aa.empty,za.node=Aa.node,za.call=Aa.call,za.size=Aa.size,za.select=function(n){for(var t,e,r,u,i,a=[],o=-1,l=this.length;++or){if("string"!=typeof n){2>r&&(t=!1);for(e in n)this.each(X(e,n[e],t));return this}if(2>r)return(r=this.node()["__on"+n])&&r._;e=!1}return this.each(X(n,t,e))};var La=oa.map({mouseenter:"mouseover",mouseleave:"mouseout"});sa&&La.forEach(function(n){"on"+n in sa&&La.remove(n)});var qa,Ta=0;oa.mouse=function(n){return J(n,k())};var Ra=this.navigator&&/WebKit/.test(this.navigator.userAgent)?-1:0;oa.touch=function(n,t,e){if(arguments.length<3&&(e=t,t=k().changedTouches),t)for(var r,u=0,i=t.length;i>u;++u)if((r=t[u]).identifier===e)return J(n,r)},oa.behavior.drag=function(){function n(){this.on("mousedown.drag",i).on("touchstart.drag",a)}function e(n,t,e,i,a){return function(){function o(){var n,e,r=t(h,v);r&&(n=r[0]-M[0],e=r[1]-M[1],p|=n|e,M=r,g({type:"drag",x:r[0]+c[0],y:r[1]+c[1],dx:n,dy:e}))}function l(){t(h,v)&&(m.on(i+d,null).on(a+d,null),y(p),g({type:"dragend"}))}var c,s=this,f=oa.event.target,h=s.parentNode,g=r.of(s,arguments),p=0,v=n(),d=".drag"+(null==v?"":"-"+v),m=oa.select(e(f)).on(i+d,o).on(a+d,l),y=W(f),M=t(h,v);u?(c=u.apply(s,arguments),c=[c.x-M[0],c.y-M[1]]):c=[0,0],g({type:"dragstart"})}}var r=N(n,"drag","dragstart","dragend"),u=null,i=e(b,oa.mouse,t,"mousemove","mouseup"),a=e(G,oa.touch,y,"touchmove","touchend");return n.origin=function(t){return arguments.length?(u=t,n):u},oa.rebind(n,r,"on")},oa.touches=function(n,t){return arguments.length<2&&(t=k().touches),t?ca(t).map(function(t){var e=J(n,t);return e.identifier=t.identifier,e}):[]};var Da=1e-6,Pa=Da*Da,ja=Math.PI,Ua=2*ja,Fa=Ua-Da,Ha=ja/2,Oa=ja/180,Ia=180/ja,Ya=Math.SQRT2,Za=2,Va=4;oa.interpolateZoom=function(n,t){var e,r,u=n[0],i=n[1],a=n[2],o=t[0],l=t[1],c=t[2],s=o-u,f=l-i,h=s*s+f*f;if(Pa>h)r=Math.log(c/a)/Ya,e=function(n){return[u+n*s,i+n*f,a*Math.exp(Ya*n*r)]};else{var g=Math.sqrt(h),p=(c*c-a*a+Va*h)/(2*a*Za*g),v=(c*c-a*a-Va*h)/(2*c*Za*g),d=Math.log(Math.sqrt(p*p+1)-p),m=Math.log(Math.sqrt(v*v+1)-v);r=(m-d)/Ya,e=function(n){var t=n*r,e=rn(d),o=a/(Za*g)*(e*un(Ya*t+d)-en(d));return[u+o*s,i+o*f,a*e/rn(Ya*t+d)]}}return e.duration=1e3*r,e},oa.behavior.zoom=function(){function n(n){n.on(L,f).on($a+".zoom",g).on("dblclick.zoom",p).on(R,h)}function e(n){return[(n[0]-k.x)/k.k,(n[1]-k.y)/k.k]}function r(n){return[n[0]*k.k+k.x,n[1]*k.k+k.y]}function u(n){k.k=Math.max(A[0],Math.min(A[1],n))}function i(n,t){t=r(t),k.x+=n[0]-t[0],k.y+=n[1]-t[1]}function a(t,e,r,a){t.__chart__={x:k.x,y:k.y,k:k.k},u(Math.pow(2,a)),i(d=e,r),t=oa.select(t),C>0&&(t=t.transition().duration(C)),t.call(n.event)}function o(){b&&b.domain(x.range().map(function(n){return(n-k.x)/k.k}).map(x.invert)),w&&w.domain(_.range().map(function(n){return(n-k.y)/k.k}).map(_.invert))}function l(n){z++||n({type:"zoomstart"})}function c(n){o(),n({type:"zoom",scale:k.k,translate:[k.x,k.y]})}function s(n){--z||(n({type:"zoomend"}),d=null)}function f(){function n(){o=1,i(oa.mouse(u),h),c(a)}function r(){f.on(q,null).on(T,null),g(o),s(a)}var u=this,a=D.of(u,arguments),o=0,f=oa.select(t(u)).on(q,n).on(T,r),h=e(oa.mouse(u)),g=W(u);Ol.call(u),l(a)}function h(){function n(){var n=oa.touches(p);return g=k.k,n.forEach(function(n){n.identifier in d&&(d[n.identifier]=e(n))}),n}function t(){var t=oa.event.target;oa.select(t).on(x,r).on(b,o),_.push(t);for(var e=oa.event.changedTouches,u=0,i=e.length;i>u;++u)d[e[u].identifier]=null;var l=n(),c=Date.now();if(1===l.length){if(500>c-M){var s=l[0];a(p,s,d[s.identifier],Math.floor(Math.log(k.k)/Math.LN2)+1),S()}M=c}else if(l.length>1){var s=l[0],f=l[1],h=s[0]-f[0],g=s[1]-f[1];m=h*h+g*g}}function r(){var n,t,e,r,a=oa.touches(p);Ol.call(p);for(var o=0,l=a.length;l>o;++o,r=null)if(e=a[o],r=d[e.identifier]){if(t)break;n=e,t=r}if(r){var s=(s=e[0]-n[0])*s+(s=e[1]-n[1])*s,f=m&&Math.sqrt(s/m);n=[(n[0]+e[0])/2,(n[1]+e[1])/2],t=[(t[0]+r[0])/2,(t[1]+r[1])/2],u(f*g)}M=null,i(n,t),c(v)}function o(){if(oa.event.touches.length){for(var t=oa.event.changedTouches,e=0,r=t.length;r>e;++e)delete d[t[e].identifier];for(var u in d)return void n()}oa.selectAll(_).on(y,null),w.on(L,f).on(R,h),N(),s(v)}var g,p=this,v=D.of(p,arguments),d={},m=0,y=".zoom-"+oa.event.changedTouches[0].identifier,x="touchmove"+y,b="touchend"+y,_=[],w=oa.select(p),N=W(p);t(),l(v),w.on(L,null).on(R,t)}function g(){var n=D.of(this,arguments);y?clearTimeout(y):(Ol.call(this),v=e(d=m||oa.mouse(this)),l(n)),y=setTimeout(function(){y=null,s(n)},50),S(),u(Math.pow(2,.002*Xa())*k.k),i(d,v),c(n)}function p(){var n=oa.mouse(this),t=Math.log(k.k)/Math.LN2;a(this,n,e(n),oa.event.shiftKey?Math.ceil(t)-1:Math.floor(t)+1)}var v,d,m,y,M,x,b,_,w,k={x:0,y:0,k:1},E=[960,500],A=Ba,C=250,z=0,L="mousedown.zoom",q="mousemove.zoom",T="mouseup.zoom",R="touchstart.zoom",D=N(n,"zoomstart","zoom","zoomend");return $a||($a="onwheel"in sa?(Xa=function(){return-oa.event.deltaY*(oa.event.deltaMode?120:1)},"wheel"):"onmousewheel"in sa?(Xa=function(){return oa.event.wheelDelta},"mousewheel"):(Xa=function(){return-oa.event.detail},"MozMousePixelScroll")),n.event=function(n){n.each(function(){var n=D.of(this,arguments),t=k;Fl?oa.select(this).transition().each("start.zoom",function(){k=this.__chart__||{x:0,y:0,k:1},l(n)}).tween("zoom:zoom",function(){var e=E[0],r=E[1],u=d?d[0]:e/2,i=d?d[1]:r/2,a=oa.interpolateZoom([(u-k.x)/k.k,(i-k.y)/k.k,e/k.k],[(u-t.x)/t.k,(i-t.y)/t.k,e/t.k]);return function(t){var r=a(t),o=e/r[2];this.__chart__=k={x:u-r[0]*o,y:i-r[1]*o,k:o},c(n)}}).each("interrupt.zoom",function(){s(n)}).each("end.zoom",function(){s(n)}):(this.__chart__=k,l(n),c(n),s(n))})},n.translate=function(t){return arguments.length?(k={x:+t[0],y:+t[1],k:k.k},o(),n):[k.x,k.y]},n.scale=function(t){return arguments.length?(k={x:k.x,y:k.y,k:null},u(+t),o(),n):k.k},n.scaleExtent=function(t){return arguments.length?(A=null==t?Ba:[+t[0],+t[1]],n):A},n.center=function(t){return arguments.length?(m=t&&[+t[0],+t[1]],n):m},n.size=function(t){return arguments.length?(E=t&&[+t[0],+t[1]],n):E},n.duration=function(t){return arguments.length?(C=+t,n):C},n.x=function(t){return arguments.length?(b=t,x=t.copy(),k={x:0,y:0,k:1},n):b},n.y=function(t){return arguments.length?(w=t,_=t.copy(),k={x:0,y:0,k:1},n):w},oa.rebind(n,D,"on")};var Xa,$a,Ba=[0,1/0];oa.color=on,on.prototype.toString=function(){return this.rgb()+""},oa.hsl=ln;var Wa=ln.prototype=new on;Wa.brighter=function(n){return n=Math.pow(.7,arguments.length?n:1),new ln(this.h,this.s,this.l/n)},Wa.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new ln(this.h,this.s,n*this.l)},Wa.rgb=function(){return cn(this.h,this.s,this.l)},oa.hcl=sn;var Ja=sn.prototype=new on;Ja.brighter=function(n){return new sn(this.h,this.c,Math.min(100,this.l+Ga*(arguments.length?n:1)))},Ja.darker=function(n){return new sn(this.h,this.c,Math.max(0,this.l-Ga*(arguments.length?n:1)))},Ja.rgb=function(){return fn(this.h,this.c,this.l).rgb()},oa.lab=hn;var Ga=18,Ka=.95047,Qa=1,no=1.08883,to=hn.prototype=new on;to.brighter=function(n){return new hn(Math.min(100,this.l+Ga*(arguments.length?n:1)),this.a,this.b)},to.darker=function(n){return new hn(Math.max(0,this.l-Ga*(arguments.length?n:1)),this.a,this.b)},to.rgb=function(){return gn(this.l,this.a,this.b)},oa.rgb=yn;var eo=yn.prototype=new on;eo.brighter=function(n){n=Math.pow(.7,arguments.length?n:1);var t=this.r,e=this.g,r=this.b,u=30;return t||e||r?(t&&u>t&&(t=u),e&&u>e&&(e=u),r&&u>r&&(r=u),new yn(Math.min(255,t/n),Math.min(255,e/n),Math.min(255,r/n))):new yn(u,u,u)},eo.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new yn(n*this.r,n*this.g,n*this.b)},eo.hsl=function(){return wn(this.r,this.g,this.b)},eo.toString=function(){return"#"+bn(this.r)+bn(this.g)+bn(this.b)};var ro=oa.map({aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074});ro.forEach(function(n,t){ro.set(n,Mn(t))}),oa.functor=En,oa.xhr=An(y),oa.dsv=function(n,t){function e(n,e,i){arguments.length<3&&(i=e,e=null);var a=Cn(n,t,null==e?r:u(e),i);return a.row=function(n){return arguments.length?a.response(null==(e=n)?r:u(n)):e},a}function r(n){return e.parse(n.responseText)}function u(n){return function(t){return e.parse(t.responseText,n)}}function i(t){return t.map(a).join(n)}function a(n){return o.test(n)?'"'+n.replace(/\"/g,'""')+'"':n}var o=new RegExp('["'+n+"\n]"),l=n.charCodeAt(0);return e.parse=function(n,t){var r;return e.parseRows(n,function(n,e){if(r)return r(n,e-1);var u=new Function("d","return {"+n.map(function(n,t){return JSON.stringify(n)+": d["+t+"]"}).join(",")+"}");r=t?function(n,e){return t(u(n),e)}:u})},e.parseRows=function(n,t){function e(){if(s>=c)return a;if(u)return u=!1,i;var t=s;if(34===n.charCodeAt(t)){for(var e=t;e++s;){var r=n.charCodeAt(s++),o=1;if(10===r)u=!0;else if(13===r)u=!0,10===n.charCodeAt(s)&&(++s,++o);else if(r!==l)continue;return n.slice(t,s-o)}return n.slice(t)}for(var r,u,i={},a={},o=[],c=n.length,s=0,f=0;(r=e())!==a;){for(var h=[];r!==i&&r!==a;)h.push(r),r=e();t&&null==(h=t(h,f++))||o.push(h)}return o},e.format=function(t){if(Array.isArray(t[0]))return e.formatRows(t);var r=new m,u=[];return t.forEach(function(n){for(var t in n)r.has(t)||u.push(r.add(t))}),[u.map(a).join(n)].concat(t.map(function(t){return u.map(function(n){return a(t[n])}).join(n)})).join("\n")},e.formatRows=function(n){return n.map(i).join("\n")},e},oa.csv=oa.dsv(",","text/csv"),oa.tsv=oa.dsv(" ","text/tab-separated-values");var uo,io,ao,oo,lo=this[x(this,"requestAnimationFrame")]||function(n){setTimeout(n,17)};oa.timer=function(){qn.apply(this,arguments)},oa.timer.flush=function(){Rn(),Dn()},oa.round=function(n,t){return t?Math.round(n*(t=Math.pow(10,t)))/t:Math.round(n)};var co=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"].map(jn);oa.formatPrefix=function(n,t){var e=0;return(n=+n)&&(0>n&&(n*=-1),t&&(n=oa.round(n,Pn(n,t))),e=1+Math.floor(1e-12+Math.log(n)/Math.LN10),e=Math.max(-24,Math.min(24,3*Math.floor((e-1)/3)))),co[8+e/3]};var so=/(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i,fo=oa.map({b:function(n){return n.toString(2)},c:function(n){return String.fromCharCode(n)},o:function(n){return n.toString(8)},x:function(n){return n.toString(16)},X:function(n){return n.toString(16).toUpperCase()},g:function(n,t){return n.toPrecision(t)},e:function(n,t){return n.toExponential(t)},f:function(n,t){return n.toFixed(t)},r:function(n,t){return(n=oa.round(n,Pn(n,t))).toFixed(Math.max(0,Math.min(20,Pn(n*(1+1e-15),t))))}}),ho=oa.time={},go=Date;Hn.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){po.setUTCDate.apply(this._,arguments)},setDay:function(){po.setUTCDay.apply(this._,arguments)},setFullYear:function(){po.setUTCFullYear.apply(this._,arguments)},setHours:function(){po.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){po.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){po.setUTCMinutes.apply(this._,arguments)},setMonth:function(){po.setUTCMonth.apply(this._,arguments)},setSeconds:function(){po.setUTCSeconds.apply(this._,arguments)},setTime:function(){po.setTime.apply(this._,arguments)}};var po=Date.prototype;ho.year=On(function(n){return n=ho.day(n),n.setMonth(0,1),n},function(n,t){n.setFullYear(n.getFullYear()+t)},function(n){return n.getFullYear()}),ho.years=ho.year.range,ho.years.utc=ho.year.utc.range,ho.day=On(function(n){var t=new go(2e3,0);return t.setFullYear(n.getFullYear(),n.getMonth(),n.getDate()),t},function(n,t){n.setDate(n.getDate()+t)},function(n){return n.getDate()-1}),ho.days=ho.day.range,ho.days.utc=ho.day.utc.range,ho.dayOfYear=function(n){var t=ho.year(n);return Math.floor((n-t-6e4*(n.getTimezoneOffset()-t.getTimezoneOffset()))/864e5)},["sunday","monday","tuesday","wednesday","thursday","friday","saturday"].forEach(function(n,t){t=7-t;var e=ho[n]=On(function(n){return(n=ho.day(n)).setDate(n.getDate()-(n.getDay()+t)%7),n},function(n,t){n.setDate(n.getDate()+7*Math.floor(t))},function(n){var e=ho.year(n).getDay();return Math.floor((ho.dayOfYear(n)+(e+t)%7)/7)-(e!==t)});ho[n+"s"]=e.range,ho[n+"s"].utc=e.utc.range,ho[n+"OfYear"]=function(n){var e=ho.year(n).getDay();return Math.floor((ho.dayOfYear(n)+(e+t)%7)/7)}}),ho.week=ho.sunday,ho.weeks=ho.sunday.range,ho.weeks.utc=ho.sunday.utc.range,ho.weekOfYear=ho.sundayOfYear;var vo={"-":"",_:" ",0:"0"},mo=/^\s*\d+/,yo=/^%/;oa.locale=function(n){return{numberFormat:Un(n),timeFormat:Yn(n)}};var Mo=oa.locale({decimal:".",thousands:",",grouping:[3],currency:["$",""],dateTime:"%a %b %e %X %Y",date:"%m/%d/%Y",time:"%H:%M:%S",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"], +shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});oa.format=Mo.numberFormat,oa.geo={},st.prototype={s:0,t:0,add:function(n){ft(n,this.t,xo),ft(xo.s,this.s,this),this.s?this.t+=xo.t:this.s=xo.t},reset:function(){this.s=this.t=0},valueOf:function(){return this.s}};var xo=new st;oa.geo.stream=function(n,t){n&&bo.hasOwnProperty(n.type)?bo[n.type](n,t):ht(n,t)};var bo={Feature:function(n,t){ht(n.geometry,t)},FeatureCollection:function(n,t){for(var e=n.features,r=-1,u=e.length;++rn?4*ja+n:n,ko.lineStart=ko.lineEnd=ko.point=b}};oa.geo.bounds=function(){function n(n,t){M.push(x=[s=n,h=n]),f>t&&(f=t),t>g&&(g=t)}function t(t,e){var r=dt([t*Oa,e*Oa]);if(m){var u=yt(m,r),i=[u[1],-u[0],0],a=yt(i,u);bt(a),a=_t(a);var l=t-p,c=l>0?1:-1,v=a[0]*Ia*c,d=Ma(l)>180;if(d^(v>c*p&&c*t>v)){var y=a[1]*Ia;y>g&&(g=y)}else if(v=(v+360)%360-180,d^(v>c*p&&c*t>v)){var y=-a[1]*Ia;f>y&&(f=y)}else f>e&&(f=e),e>g&&(g=e);d?p>t?o(s,t)>o(s,h)&&(h=t):o(t,h)>o(s,h)&&(s=t):h>=s?(s>t&&(s=t),t>h&&(h=t)):t>p?o(s,t)>o(s,h)&&(h=t):o(t,h)>o(s,h)&&(s=t)}else n(t,e);m=r,p=t}function e(){b.point=t}function r(){x[0]=s,x[1]=h,b.point=n,m=null}function u(n,e){if(m){var r=n-p;y+=Ma(r)>180?r+(r>0?360:-360):r}else v=n,d=e;ko.point(n,e),t(n,e)}function i(){ko.lineStart()}function a(){u(v,d),ko.lineEnd(),Ma(y)>Da&&(s=-(h=180)),x[0]=s,x[1]=h,m=null}function o(n,t){return(t-=n)<0?t+360:t}function l(n,t){return n[0]-t[0]}function c(n,t){return t[0]<=t[1]?t[0]<=n&&n<=t[1]:nSo?(s=-(h=180),f=-(g=90)):y>Da?g=90:-Da>y&&(f=-90),x[0]=s,x[1]=h}};return function(n){g=h=-(s=f=1/0),M=[],oa.geo.stream(n,b);var t=M.length;if(t){M.sort(l);for(var e,r=1,u=M[0],i=[u];t>r;++r)e=M[r],c(e[0],u)||c(e[1],u)?(o(u[0],e[1])>o(u[0],u[1])&&(u[1]=e[1]),o(e[0],u[1])>o(u[0],u[1])&&(u[0]=e[0])):i.push(u=e);for(var a,e,p=-(1/0),t=i.length-1,r=0,u=i[t];t>=r;u=e,++r)e=i[r],(a=o(u[1],e[0]))>p&&(p=a,s=e[0],h=u[1])}return M=x=null,s===1/0||f===1/0?[[NaN,NaN],[NaN,NaN]]:[[s,f],[h,g]]}}(),oa.geo.centroid=function(n){No=Eo=Ao=Co=zo=Lo=qo=To=Ro=Do=Po=0,oa.geo.stream(n,jo);var t=Ro,e=Do,r=Po,u=t*t+e*e+r*r;return Pa>u&&(t=Lo,e=qo,r=To,Da>Eo&&(t=Ao,e=Co,r=zo),u=t*t+e*e+r*r,Pa>u)?[NaN,NaN]:[Math.atan2(e,t)*Ia,tn(r/Math.sqrt(u))*Ia]};var No,Eo,Ao,Co,zo,Lo,qo,To,Ro,Do,Po,jo={sphere:b,point:St,lineStart:Nt,lineEnd:Et,polygonStart:function(){jo.lineStart=At},polygonEnd:function(){jo.lineStart=Nt}},Uo=Rt(zt,Ut,Ht,[-ja,-ja/2]),Fo=1e9;oa.geo.clipExtent=function(){var n,t,e,r,u,i,a={stream:function(n){return u&&(u.valid=!1),u=i(n),u.valid=!0,u},extent:function(o){return arguments.length?(i=Zt(n=+o[0][0],t=+o[0][1],e=+o[1][0],r=+o[1][1]),u&&(u.valid=!1,u=null),a):[[n,t],[e,r]]}};return a.extent([[0,0],[960,500]])},(oa.geo.conicEqualArea=function(){return Vt(Xt)}).raw=Xt,oa.geo.albers=function(){return oa.geo.conicEqualArea().rotate([96,0]).center([-.6,38.7]).parallels([29.5,45.5]).scale(1070)},oa.geo.albersUsa=function(){function n(n){var i=n[0],a=n[1];return t=null,e(i,a),t||(r(i,a),t)||u(i,a),t}var t,e,r,u,i=oa.geo.albers(),a=oa.geo.conicEqualArea().rotate([154,0]).center([-2,58.5]).parallels([55,65]),o=oa.geo.conicEqualArea().rotate([157,0]).center([-3,19.9]).parallels([8,18]),l={point:function(n,e){t=[n,e]}};return n.invert=function(n){var t=i.scale(),e=i.translate(),r=(n[0]-e[0])/t,u=(n[1]-e[1])/t;return(u>=.12&&.234>u&&r>=-.425&&-.214>r?a:u>=.166&&.234>u&&r>=-.214&&-.115>r?o:i).invert(n)},n.stream=function(n){var t=i.stream(n),e=a.stream(n),r=o.stream(n);return{point:function(n,u){t.point(n,u),e.point(n,u),r.point(n,u)},sphere:function(){t.sphere(),e.sphere(),r.sphere()},lineStart:function(){t.lineStart(),e.lineStart(),r.lineStart()},lineEnd:function(){t.lineEnd(),e.lineEnd(),r.lineEnd()},polygonStart:function(){t.polygonStart(),e.polygonStart(),r.polygonStart()},polygonEnd:function(){t.polygonEnd(),e.polygonEnd(),r.polygonEnd()}}},n.precision=function(t){return arguments.length?(i.precision(t),a.precision(t),o.precision(t),n):i.precision()},n.scale=function(t){return arguments.length?(i.scale(t),a.scale(.35*t),o.scale(t),n.translate(i.translate())):i.scale()},n.translate=function(t){if(!arguments.length)return i.translate();var c=i.scale(),s=+t[0],f=+t[1];return e=i.translate(t).clipExtent([[s-.455*c,f-.238*c],[s+.455*c,f+.238*c]]).stream(l).point,r=a.translate([s-.307*c,f+.201*c]).clipExtent([[s-.425*c+Da,f+.12*c+Da],[s-.214*c-Da,f+.234*c-Da]]).stream(l).point,u=o.translate([s-.205*c,f+.212*c]).clipExtent([[s-.214*c+Da,f+.166*c+Da],[s-.115*c-Da,f+.234*c-Da]]).stream(l).point,n},n.scale(1070)};var Ho,Oo,Io,Yo,Zo,Vo,Xo={point:b,lineStart:b,lineEnd:b,polygonStart:function(){Oo=0,Xo.lineStart=$t},polygonEnd:function(){Xo.lineStart=Xo.lineEnd=Xo.point=b,Ho+=Ma(Oo/2)}},$o={point:Bt,lineStart:b,lineEnd:b,polygonStart:b,polygonEnd:b},Bo={point:Gt,lineStart:Kt,lineEnd:Qt,polygonStart:function(){Bo.lineStart=ne},polygonEnd:function(){Bo.point=Gt,Bo.lineStart=Kt,Bo.lineEnd=Qt}};oa.geo.path=function(){function n(n){return n&&("function"==typeof o&&i.pointRadius(+o.apply(this,arguments)),a&&a.valid||(a=u(i)),oa.geo.stream(n,a)),i.result()}function t(){return a=null,n}var e,r,u,i,a,o=4.5;return n.area=function(n){return Ho=0,oa.geo.stream(n,u(Xo)),Ho},n.centroid=function(n){return Ao=Co=zo=Lo=qo=To=Ro=Do=Po=0,oa.geo.stream(n,u(Bo)),Po?[Ro/Po,Do/Po]:To?[Lo/To,qo/To]:zo?[Ao/zo,Co/zo]:[NaN,NaN]},n.bounds=function(n){return Zo=Vo=-(Io=Yo=1/0),oa.geo.stream(n,u($o)),[[Io,Yo],[Zo,Vo]]},n.projection=function(n){return arguments.length?(u=(e=n)?n.stream||re(n):y,t()):e},n.context=function(n){return arguments.length?(i=null==(r=n)?new Wt:new te(n),"function"!=typeof o&&i.pointRadius(o),t()):r},n.pointRadius=function(t){return arguments.length?(o="function"==typeof t?t:(i.pointRadius(+t),+t),n):o},n.projection(oa.geo.albersUsa()).context(null)},oa.geo.transform=function(n){return{stream:function(t){var e=new ue(t);for(var r in n)e[r]=n[r];return e}}},ue.prototype={point:function(n,t){this.stream.point(n,t)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}},oa.geo.projection=ae,oa.geo.projectionMutator=oe,(oa.geo.equirectangular=function(){return ae(ce)}).raw=ce.invert=ce,oa.geo.rotation=function(n){function t(t){return t=n(t[0]*Oa,t[1]*Oa),t[0]*=Ia,t[1]*=Ia,t}return n=fe(n[0]%360*Oa,n[1]*Oa,n.length>2?n[2]*Oa:0),t.invert=function(t){return t=n.invert(t[0]*Oa,t[1]*Oa),t[0]*=Ia,t[1]*=Ia,t},t},se.invert=ce,oa.geo.circle=function(){function n(){var n="function"==typeof r?r.apply(this,arguments):r,t=fe(-n[0]*Oa,-n[1]*Oa,0).invert,u=[];return e(null,null,1,{point:function(n,e){u.push(n=t(n,e)),n[0]*=Ia,n[1]*=Ia}}),{type:"Polygon",coordinates:[u]}}var t,e,r=[0,0],u=6;return n.origin=function(t){return arguments.length?(r=t,n):r},n.angle=function(r){return arguments.length?(e=ve((t=+r)*Oa,u*Oa),n):t},n.precision=function(r){return arguments.length?(e=ve(t*Oa,(u=+r)*Oa),n):u},n.angle(90)},oa.geo.distance=function(n,t){var e,r=(t[0]-n[0])*Oa,u=n[1]*Oa,i=t[1]*Oa,a=Math.sin(r),o=Math.cos(r),l=Math.sin(u),c=Math.cos(u),s=Math.sin(i),f=Math.cos(i);return Math.atan2(Math.sqrt((e=f*a)*e+(e=c*s-l*f*o)*e),l*s+c*f*o)},oa.geo.graticule=function(){function n(){return{type:"MultiLineString",coordinates:t()}}function t(){return oa.range(Math.ceil(i/d)*d,u,d).map(h).concat(oa.range(Math.ceil(c/m)*m,l,m).map(g)).concat(oa.range(Math.ceil(r/p)*p,e,p).filter(function(n){return Ma(n%d)>Da}).map(s)).concat(oa.range(Math.ceil(o/v)*v,a,v).filter(function(n){return Ma(n%m)>Da}).map(f))}var e,r,u,i,a,o,l,c,s,f,h,g,p=10,v=p,d=90,m=360,y=2.5;return n.lines=function(){return t().map(function(n){return{type:"LineString",coordinates:n}})},n.outline=function(){return{type:"Polygon",coordinates:[h(i).concat(g(l).slice(1),h(u).reverse().slice(1),g(c).reverse().slice(1))]}},n.extent=function(t){return arguments.length?n.majorExtent(t).minorExtent(t):n.minorExtent()},n.majorExtent=function(t){return arguments.length?(i=+t[0][0],u=+t[1][0],c=+t[0][1],l=+t[1][1],i>u&&(t=i,i=u,u=t),c>l&&(t=c,c=l,l=t),n.precision(y)):[[i,c],[u,l]]},n.minorExtent=function(t){return arguments.length?(r=+t[0][0],e=+t[1][0],o=+t[0][1],a=+t[1][1],r>e&&(t=r,r=e,e=t),o>a&&(t=o,o=a,a=t),n.precision(y)):[[r,o],[e,a]]},n.step=function(t){return arguments.length?n.majorStep(t).minorStep(t):n.minorStep()},n.majorStep=function(t){return arguments.length?(d=+t[0],m=+t[1],n):[d,m]},n.minorStep=function(t){return arguments.length?(p=+t[0],v=+t[1],n):[p,v]},n.precision=function(t){return arguments.length?(y=+t,s=me(o,a,90),f=ye(r,e,y),h=me(c,l,90),g=ye(i,u,y),n):y},n.majorExtent([[-180,-90+Da],[180,90-Da]]).minorExtent([[-180,-80-Da],[180,80+Da]])},oa.geo.greatArc=function(){function n(){return{type:"LineString",coordinates:[t||r.apply(this,arguments),e||u.apply(this,arguments)]}}var t,e,r=Me,u=xe;return n.distance=function(){return oa.geo.distance(t||r.apply(this,arguments),e||u.apply(this,arguments))},n.source=function(e){return arguments.length?(r=e,t="function"==typeof e?null:e,n):r},n.target=function(t){return arguments.length?(u=t,e="function"==typeof t?null:t,n):u},n.precision=function(){return arguments.length?n:0},n},oa.geo.interpolate=function(n,t){return be(n[0]*Oa,n[1]*Oa,t[0]*Oa,t[1]*Oa)},oa.geo.length=function(n){return Wo=0,oa.geo.stream(n,Jo),Wo};var Wo,Jo={sphere:b,point:b,lineStart:_e,lineEnd:b,polygonStart:b,polygonEnd:b},Go=we(function(n){return Math.sqrt(2/(1+n))},function(n){return 2*Math.asin(n/2)});(oa.geo.azimuthalEqualArea=function(){return ae(Go)}).raw=Go;var Ko=we(function(n){var t=Math.acos(n);return t&&t/Math.sin(t)},y);(oa.geo.azimuthalEquidistant=function(){return ae(Ko)}).raw=Ko,(oa.geo.conicConformal=function(){return Vt(Se)}).raw=Se,(oa.geo.conicEquidistant=function(){return Vt(ke)}).raw=ke;var Qo=we(function(n){return 1/n},Math.atan);(oa.geo.gnomonic=function(){return ae(Qo)}).raw=Qo,Ne.invert=function(n,t){return[n,2*Math.atan(Math.exp(t))-Ha]},(oa.geo.mercator=function(){return Ee(Ne)}).raw=Ne;var nl=we(function(){return 1},Math.asin);(oa.geo.orthographic=function(){return ae(nl)}).raw=nl;var tl=we(function(n){return 1/(1+n)},function(n){return 2*Math.atan(n)});(oa.geo.stereographic=function(){return ae(tl)}).raw=tl,Ae.invert=function(n,t){return[-t,2*Math.atan(Math.exp(n))-Ha]},(oa.geo.transverseMercator=function(){var n=Ee(Ae),t=n.center,e=n.rotate;return n.center=function(n){return n?t([-n[1],n[0]]):(n=t(),[n[1],-n[0]])},n.rotate=function(n){return n?e([n[0],n[1],n.length>2?n[2]+90:90]):(n=e(),[n[0],n[1],n[2]-90])},e([0,0,90])}).raw=Ae,oa.geom={},oa.geom.hull=function(n){function t(n){if(n.length<3)return[];var t,u=En(e),i=En(r),a=n.length,o=[],l=[];for(t=0;a>t;t++)o.push([+u.call(this,n[t],t),+i.call(this,n[t],t),t]);for(o.sort(qe),t=0;a>t;t++)l.push([o[t][0],-o[t][1]]);var c=Le(o),s=Le(l),f=s[0]===c[0],h=s[s.length-1]===c[c.length-1],g=[];for(t=c.length-1;t>=0;--t)g.push(n[o[c[t]][2]]);for(t=+f;t=r&&c.x<=i&&c.y>=u&&c.y<=a?[[r,a],[i,a],[i,u],[r,u]]:[];s.point=n[o]}),t}function e(n){return n.map(function(n,t){return{x:Math.round(i(n,t)/Da)*Da,y:Math.round(a(n,t)/Da)*Da,i:t}})}var r=Ce,u=ze,i=r,a=u,o=sl;return n?t(n):(t.links=function(n){return or(e(n)).edges.filter(function(n){return n.l&&n.r}).map(function(t){return{source:n[t.l.i],target:n[t.r.i]}})},t.triangles=function(n){var t=[];return or(e(n)).cells.forEach(function(e,r){for(var u,i,a=e.site,o=e.edges.sort(Ve),l=-1,c=o.length,s=o[c-1].edge,f=s.l===a?s.r:s.l;++l=c,h=r>=s,g=h<<1|f;n.leaf=!1,n=n.nodes[g]||(n.nodes[g]=hr()),f?u=c:o=c,h?a=s:l=s,i(n,t,e,r,u,a,o,l)}var s,f,h,g,p,v,d,m,y,M=En(o),x=En(l);if(null!=t)v=t,d=e,m=r,y=u;else if(m=y=-(v=d=1/0),f=[],h=[],p=n.length,a)for(g=0;p>g;++g)s=n[g],s.xm&&(m=s.x),s.y>y&&(y=s.y),f.push(s.x),h.push(s.y);else for(g=0;p>g;++g){var b=+M(s=n[g],g),_=+x(s,g);v>b&&(v=b),d>_&&(d=_),b>m&&(m=b),_>y&&(y=_),f.push(b),h.push(_)}var w=m-v,S=y-d;w>S?y=d+w:m=v+S;var k=hr();if(k.add=function(n){i(k,n,+M(n,++g),+x(n,g),v,d,m,y)},k.visit=function(n){gr(n,k,v,d,m,y)},k.find=function(n){return pr(k,n[0],n[1],v,d,m,y)},g=-1,null==t){for(;++g=0?n.slice(0,t):n,r=t>=0?n.slice(t+1):"in";return e=pl.get(e)||gl,r=vl.get(r)||y,br(r(e.apply(null,la.call(arguments,1))))},oa.interpolateHcl=Rr,oa.interpolateHsl=Dr,oa.interpolateLab=Pr,oa.interpolateRound=jr,oa.transform=function(n){var t=sa.createElementNS(oa.ns.prefix.svg,"g");return(oa.transform=function(n){if(null!=n){t.setAttribute("transform",n);var e=t.transform.baseVal.consolidate()}return new Ur(e?e.matrix:dl)})(n)},Ur.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var dl={a:1,b:0,c:0,d:1,e:0,f:0};oa.interpolateTransform=$r,oa.layout={},oa.layout.bundle=function(){return function(n){for(var t=[],e=-1,r=n.length;++eo*o/m){if(v>l){var c=t.charge/l;n.px-=i*c,n.py-=a*c}return!0}if(t.point&&l&&v>l){var c=t.pointCharge/l;n.px-=i*c,n.py-=a*c}}return!t.charge}}function t(n){n.px=oa.event.x,n.py=oa.event.y,l.resume()}var e,r,u,i,a,o,l={},c=oa.dispatch("start","tick","end"),s=[1,1],f=.9,h=ml,g=yl,p=-30,v=Ml,d=.1,m=.64,M=[],x=[];return l.tick=function(){if((u*=.99)<.005)return e=null,c.end({type:"end",alpha:u=0}),!0;var t,r,l,h,g,v,m,y,b,_=M.length,w=x.length;for(r=0;w>r;++r)l=x[r],h=l.source,g=l.target,y=g.x-h.x,b=g.y-h.y,(v=y*y+b*b)&&(v=u*a[r]*((v=Math.sqrt(v))-i[r])/v,y*=v,b*=v,g.x-=y*(m=h.weight+g.weight?h.weight/(h.weight+g.weight):.5),g.y-=b*m,h.x+=y*(m=1-m),h.y+=b*m);if((m=u*d)&&(y=s[0]/2,b=s[1]/2,r=-1,m))for(;++r<_;)l=M[r],l.x+=(y-l.x)*m,l.y+=(b-l.y)*m;if(p)for(ru(t=oa.geom.quadtree(M),u,o),r=-1;++r<_;)(l=M[r]).fixed||t.visit(n(l));for(r=-1;++r<_;)l=M[r],l.fixed?(l.x=l.px,l.y=l.py):(l.x-=(l.px-(l.px=l.x))*f,l.y-=(l.py-(l.py=l.y))*f);c.tick({type:"tick",alpha:u})},l.nodes=function(n){return arguments.length?(M=n,l):M},l.links=function(n){return arguments.length?(x=n,l):x},l.size=function(n){return arguments.length?(s=n,l):s},l.linkDistance=function(n){return arguments.length?(h="function"==typeof n?n:+n,l):h},l.distance=l.linkDistance,l.linkStrength=function(n){return arguments.length?(g="function"==typeof n?n:+n,l):g},l.friction=function(n){return arguments.length?(f=+n,l):f},l.charge=function(n){return arguments.length?(p="function"==typeof n?n:+n,l):p},l.chargeDistance=function(n){return arguments.length?(v=n*n,l):Math.sqrt(v)},l.gravity=function(n){return arguments.length?(d=+n,l):d},l.theta=function(n){return arguments.length?(m=n*n,l):Math.sqrt(m)},l.alpha=function(n){return arguments.length?(n=+n,u?n>0?u=n:(e.c=null,e.t=NaN,e=null,c.end({type:"end",alpha:u=0})):n>0&&(c.start({type:"start",alpha:u=n}),e=qn(l.tick)),l):u},l.start=function(){function n(n,r){if(!e){for(e=new Array(u),l=0;u>l;++l)e[l]=[];for(l=0;c>l;++l){var i=x[l];e[i.source.index].push(i.target),e[i.target.index].push(i.source)}}for(var a,o=e[t],l=-1,s=o.length;++lt;++t)(r=M[t]).index=t,r.weight=0;for(t=0;c>t;++t)r=x[t],"number"==typeof r.source&&(r.source=M[r.source]),"number"==typeof r.target&&(r.target=M[r.target]),++r.source.weight,++r.target.weight;for(t=0;u>t;++t)r=M[t],isNaN(r.x)&&(r.x=n("x",f)),isNaN(r.y)&&(r.y=n("y",v)),isNaN(r.px)&&(r.px=r.x),isNaN(r.py)&&(r.py=r.y);if(i=[],"function"==typeof h)for(t=0;c>t;++t)i[t]=+h.call(this,x[t],t);else for(t=0;c>t;++t)i[t]=h;if(a=[],"function"==typeof g)for(t=0;c>t;++t)a[t]=+g.call(this,x[t],t);else for(t=0;c>t;++t)a[t]=g;if(o=[],"function"==typeof p)for(t=0;u>t;++t)o[t]=+p.call(this,M[t],t);else for(t=0;u>t;++t)o[t]=p;return l.resume()},l.resume=function(){return l.alpha(.1)},l.stop=function(){return l.alpha(0)},l.drag=function(){return r||(r=oa.behavior.drag().origin(y).on("dragstart.force",Qr).on("drag.force",t).on("dragend.force",nu)),arguments.length?void this.on("mouseover.force",tu).on("mouseout.force",eu).call(r):r},oa.rebind(l,c,"on")};var ml=20,yl=1,Ml=1/0;oa.layout.hierarchy=function(){function n(u){var i,a=[u],o=[];for(u.depth=0;null!=(i=a.pop());)if(o.push(i),(c=e.call(n,i,i.depth))&&(l=c.length)){for(var l,c,s;--l>=0;)a.push(s=c[l]),s.parent=i,s.depth=i.depth+1;r&&(i.value=0),i.children=c}else r&&(i.value=+r.call(n,i,i.depth)||0),delete i.children;return au(u,function(n){var e,u;t&&(e=n.children)&&e.sort(t),r&&(u=n.parent)&&(u.value+=n.value)}),o}var t=cu,e=ou,r=lu;return n.sort=function(e){return arguments.length?(t=e,n):t},n.children=function(t){return arguments.length?(e=t,n):e},n.value=function(t){return arguments.length?(r=t,n):r},n.revalue=function(t){return r&&(iu(t,function(n){n.children&&(n.value=0)}),au(t,function(t){var e;t.children||(t.value=+r.call(n,t,t.depth)||0),(e=t.parent)&&(e.value+=t.value)})),t},n},oa.layout.partition=function(){function n(t,e,r,u){var i=t.children;if(t.x=e,t.y=t.depth*u,t.dx=r,t.dy=u,i&&(a=i.length)){var a,o,l,c=-1;for(r=t.value?r/t.value:0;++cf?-1:1),p=oa.sum(c),v=p?(f-l*g)/p:0,d=oa.range(l),m=[];return null!=e&&d.sort(e===xl?function(n,t){return c[t]-c[n]}:function(n,t){return e(a[n],a[t])}),d.forEach(function(n){m[n]={data:a[n],value:o=c[n],startAngle:s,endAngle:s+=o*v+g,padAngle:h}}),m}var t=Number,e=xl,r=0,u=Ua,i=0;return n.value=function(e){return arguments.length?(t=e,n):t},n.sort=function(t){return arguments.length?(e=t,n):e},n.startAngle=function(t){return arguments.length?(r=t,n):r},n.endAngle=function(t){return arguments.length?(u=t,n):u},n.padAngle=function(t){return arguments.length?(i=t,n):i},n};var xl={};oa.layout.stack=function(){function n(o,l){if(!(h=o.length))return o;var c=o.map(function(e,r){return t.call(n,e,r)}),s=c.map(function(t){return t.map(function(t,e){return[i.call(n,t,e),a.call(n,t,e)]})}),f=e.call(n,s,l);c=oa.permute(c,f),s=oa.permute(s,f);var h,g,p,v,d=r.call(n,s,l),m=c[0].length;for(p=0;m>p;++p)for(u.call(n,c[0][p],v=d[p],s[0][p][1]),g=1;h>g;++g)u.call(n,c[g][p],v+=s[g-1][p][1],s[g][p][1]);return o}var t=y,e=pu,r=vu,u=gu,i=fu,a=hu;return n.values=function(e){return arguments.length?(t=e,n):t},n.order=function(t){return arguments.length?(e="function"==typeof t?t:bl.get(t)||pu,n):e},n.offset=function(t){return arguments.length?(r="function"==typeof t?t:_l.get(t)||vu,n):r},n.x=function(t){return arguments.length?(i=t,n):i},n.y=function(t){return arguments.length?(a=t,n):a},n.out=function(t){return arguments.length?(u=t,n):u},n};var bl=oa.map({"inside-out":function(n){var t,e,r=n.length,u=n.map(du),i=n.map(mu),a=oa.range(r).sort(function(n,t){return u[n]-u[t]}),o=0,l=0,c=[],s=[];for(t=0;r>t;++t)e=a[t],l>o?(o+=i[e],c.push(e)):(l+=i[e],s.push(e));return s.reverse().concat(c)},reverse:function(n){return oa.range(n.length).reverse()},"default":pu}),_l=oa.map({silhouette:function(n){var t,e,r,u=n.length,i=n[0].length,a=[],o=0,l=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];r>o&&(o=r),a.push(r)}for(e=0;i>e;++e)l[e]=(o-a[e])/2;return l},wiggle:function(n){var t,e,r,u,i,a,o,l,c,s=n.length,f=n[0],h=f.length,g=[];for(g[0]=l=c=0,e=1;h>e;++e){for(t=0,u=0;s>t;++t)u+=n[t][e][1];for(t=0,i=0,o=f[e][0]-f[e-1][0];s>t;++t){for(r=0,a=(n[t][e][1]-n[t][e-1][1])/(2*o);t>r;++r)a+=(n[r][e][1]-n[r][e-1][1])/o;i+=a*n[t][e][1]}g[e]=l-=u?i/u*o:0,c>l&&(c=l)}for(e=0;h>e;++e)g[e]-=c;return g},expand:function(n){var t,e,r,u=n.length,i=n[0].length,a=1/u,o=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];if(r)for(t=0;u>t;t++)n[t][e][1]/=r;else for(t=0;u>t;t++)n[t][e][1]=a}for(e=0;i>e;++e)o[e]=0;return o},zero:vu});oa.layout.histogram=function(){function n(n,i){for(var a,o,l=[],c=n.map(e,this),s=r.call(this,c,i),f=u.call(this,s,c,i),i=-1,h=c.length,g=f.length-1,p=t?1:1/h;++i0)for(i=-1;++i=s[0]&&o<=s[1]&&(a=l[oa.bisect(f,o,1,g)-1],a.y+=p,a.push(n[i]));return l}var t=!0,e=Number,r=bu,u=Mu;return n.value=function(t){return arguments.length?(e=t,n):e},n.range=function(t){return arguments.length?(r=En(t),n):r},n.bins=function(t){return arguments.length?(u="number"==typeof t?function(n){return xu(n,t)}:En(t),n):u},n.frequency=function(e){return arguments.length?(t=!!e,n):t},n},oa.layout.pack=function(){function n(n,i){var a=e.call(this,n,i),o=a[0],l=u[0],c=u[1],s=null==t?Math.sqrt:"function"==typeof t?t:function(){return t};if(o.x=o.y=0,au(o,function(n){n.r=+s(n.value)}),au(o,Nu),r){var f=r*(t?1:Math.max(2*o.r/l,2*o.r/c))/2;au(o,function(n){n.r+=f}),au(o,Nu),au(o,function(n){n.r-=f})}return Cu(o,l/2,c/2,t?1:1/Math.max(2*o.r/l,2*o.r/c)),a}var t,e=oa.layout.hierarchy().sort(_u),r=0,u=[1,1];return n.size=function(t){return arguments.length?(u=t,n):u},n.radius=function(e){return arguments.length?(t=null==e||"function"==typeof e?e:+e,n):t},n.padding=function(t){return arguments.length?(r=+t,n):r},uu(n,e)},oa.layout.tree=function(){function n(n,u){var s=a.call(this,n,u),f=s[0],h=t(f);if(au(h,e),h.parent.m=-h.z,iu(h,r),c)iu(f,i);else{var g=f,p=f,v=f;iu(f,function(n){n.xp.x&&(p=n),n.depth>v.depth&&(v=n)});var d=o(g,p)/2-g.x,m=l[0]/(p.x+o(p,g)/2+d),y=l[1]/(v.depth||1);iu(f,function(n){n.x=(n.x+d)*m,n.y=n.depth*y})}return s}function t(n){for(var t,e={A:null,children:[n]},r=[e];null!=(t=r.pop());)for(var u,i=t.children,a=0,o=i.length;o>a;++a)r.push((i[a]=u={_:i[a],parent:t,children:(u=i[a].children)&&u.slice()||[],A:null,a:null,z:0,m:0,c:0,s:0,t:null,i:a}).a=u);return e.children[0]}function e(n){var t=n.children,e=n.parent.children,r=n.i?e[n.i-1]:null;if(t.length){Du(n);var i=(t[0].z+t[t.length-1].z)/2;r?(n.z=r.z+o(n._,r._),n.m=n.z-i):n.z=i}else r&&(n.z=r.z+o(n._,r._));n.parent.A=u(n,r,n.parent.A||e[0])}function r(n){n._.x=n.z+n.parent.m,n.m+=n.parent.m}function u(n,t,e){if(t){for(var r,u=n,i=n,a=t,l=u.parent.children[0],c=u.m,s=i.m,f=a.m,h=l.m;a=Tu(a),u=qu(u),a&&u;)l=qu(l),i=Tu(i),i.a=n,r=a.z+f-u.z-c+o(a._,u._),r>0&&(Ru(Pu(a,n,e),n,r),c+=r,s+=r),f+=a.m,c+=u.m,h+=l.m,s+=i.m;a&&!Tu(i)&&(i.t=a,i.m+=f-s),u&&!qu(l)&&(l.t=u,l.m+=c-h,e=n)}return e}function i(n){n.x*=l[0],n.y=n.depth*l[1]}var a=oa.layout.hierarchy().sort(null).value(null),o=Lu,l=[1,1],c=null;return n.separation=function(t){return arguments.length?(o=t,n):o},n.size=function(t){return arguments.length?(c=null==(l=t)?i:null,n):c?null:l},n.nodeSize=function(t){return arguments.length?(c=null==(l=t)?null:i,n):c?l:null},uu(n,a)},oa.layout.cluster=function(){function n(n,i){var a,o=t.call(this,n,i),l=o[0],c=0;au(l,function(n){var t=n.children;t&&t.length?(n.x=Uu(t),n.y=ju(t)):(n.x=a?c+=e(n,a):0,n.y=0,a=n)});var s=Fu(l),f=Hu(l),h=s.x-e(s,f)/2,g=f.x+e(f,s)/2;return au(l,u?function(n){n.x=(n.x-l.x)*r[0],n.y=(l.y-n.y)*r[1]}:function(n){n.x=(n.x-h)/(g-h)*r[0],n.y=(1-(l.y?n.y/l.y:1))*r[1]}),o}var t=oa.layout.hierarchy().sort(null).value(null),e=Lu,r=[1,1],u=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(u=null==(r=t),n):u?null:r},n.nodeSize=function(t){return arguments.length?(u=null!=(r=t),n):u?r:null},uu(n,t)},oa.layout.treemap=function(){function n(n,t){for(var e,r,u=-1,i=n.length;++ut?0:t),e.area=isNaN(r)||0>=r?0:r}function t(e){var i=e.children;if(i&&i.length){var a,o,l,c=f(e),s=[],h=i.slice(),p=1/0,v="slice"===g?c.dx:"dice"===g?c.dy:"slice-dice"===g?1&e.depth?c.dy:c.dx:Math.min(c.dx,c.dy);for(n(h,c.dx*c.dy/e.value),s.area=0;(l=h.length)>0;)s.push(a=h[l-1]),s.area+=a.area,"squarify"!==g||(o=r(s,v))<=p?(h.pop(),p=o):(s.area-=s.pop().area,u(s,v,c,!1),v=Math.min(c.dx,c.dy),s.length=s.area=0,p=1/0);s.length&&(u(s,v,c,!0),s.length=s.area=0),i.forEach(t)}}function e(t){var r=t.children;if(r&&r.length){var i,a=f(t),o=r.slice(),l=[];for(n(o,a.dx*a.dy/t.value),l.area=0;i=o.pop();)l.push(i),l.area+=i.area,null!=i.z&&(u(l,i.z?a.dx:a.dy,a,!o.length),l.length=l.area=0);r.forEach(e)}}function r(n,t){for(var e,r=n.area,u=0,i=1/0,a=-1,o=n.length;++ae&&(i=e),e>u&&(u=e));return r*=r,t*=t,r?Math.max(t*u*p/r,r/(t*i*p)):1/0}function u(n,t,e,r){var u,i=-1,a=n.length,o=e.x,c=e.y,s=t?l(n.area/t):0; +if(t==e.dx){for((r||s>e.dy)&&(s=e.dy);++ie.dx)&&(s=e.dx);++ie&&(t=1),1>e&&(n=0),function(){var e,r,u;do e=2*Math.random()-1,r=2*Math.random()-1,u=e*e+r*r;while(!u||u>1);return n+t*e*Math.sqrt(-2*Math.log(u)/u)}},logNormal:function(){var n=oa.random.normal.apply(oa,arguments);return function(){return Math.exp(n())}},bates:function(n){var t=oa.random.irwinHall(n);return function(){return t()/n}},irwinHall:function(n){return function(){for(var t=0,e=0;n>e;e++)t+=Math.random();return t}}},oa.scale={};var wl={floor:y,ceil:y};oa.scale.linear=function(){return Wu([0,1],[0,1],Mr,!1)};var Sl={s:1,g:1,p:1,r:1,e:1};oa.scale.log=function(){return ri(oa.scale.linear().domain([0,1]),10,!0,[1,10])};var kl=oa.format(".0e"),Nl={floor:function(n){return-Math.ceil(-n)},ceil:function(n){return-Math.floor(-n)}};oa.scale.pow=function(){return ui(oa.scale.linear(),1,[0,1])},oa.scale.sqrt=function(){return oa.scale.pow().exponent(.5)},oa.scale.ordinal=function(){return ai([],{t:"range",a:[[]]})},oa.scale.category10=function(){return oa.scale.ordinal().range(El)},oa.scale.category20=function(){return oa.scale.ordinal().range(Al)},oa.scale.category20b=function(){return oa.scale.ordinal().range(Cl)},oa.scale.category20c=function(){return oa.scale.ordinal().range(zl)};var El=[2062260,16744206,2924588,14034728,9725885,9197131,14907330,8355711,12369186,1556175].map(xn),Al=[2062260,11454440,16744206,16759672,2924588,10018698,14034728,16750742,9725885,12955861,9197131,12885140,14907330,16234194,8355711,13092807,12369186,14408589,1556175,10410725].map(xn),Cl=[3750777,5395619,7040719,10264286,6519097,9216594,11915115,13556636,9202993,12426809,15186514,15190932,8666169,11356490,14049643,15177372,8077683,10834324,13528509,14589654].map(xn),zl=[3244733,7057110,10406625,13032431,15095053,16616764,16625259,16634018,3253076,7652470,10607003,13101504,7695281,10394312,12369372,14342891,6513507,9868950,12434877,14277081].map(xn);oa.scale.quantile=function(){return oi([],[])},oa.scale.quantize=function(){return li(0,1,[0,1])},oa.scale.threshold=function(){return ci([.5],[0,1])},oa.scale.identity=function(){return si([0,1])},oa.svg={},oa.svg.arc=function(){function n(){var n=Math.max(0,+e.apply(this,arguments)),c=Math.max(0,+r.apply(this,arguments)),s=a.apply(this,arguments)-Ha,f=o.apply(this,arguments)-Ha,h=Math.abs(f-s),g=s>f?0:1;if(n>c&&(p=c,c=n,n=p),h>=Fa)return t(c,g)+(n?t(n,1-g):"")+"Z";var p,v,d,m,y,M,x,b,_,w,S,k,N=0,E=0,A=[];if((m=(+l.apply(this,arguments)||0)/2)&&(d=i===Ll?Math.sqrt(n*n+c*c):+i.apply(this,arguments),g||(E*=-1),c&&(E=tn(d/c*Math.sin(m))),n&&(N=tn(d/n*Math.sin(m)))),c){y=c*Math.cos(s+E),M=c*Math.sin(s+E),x=c*Math.cos(f-E),b=c*Math.sin(f-E);var C=Math.abs(f-s-2*E)<=ja?0:1;if(E&&mi(y,M,x,b)===g^C){var z=(s+f)/2;y=c*Math.cos(z),M=c*Math.sin(z),x=b=null}}else y=M=0;if(n){_=n*Math.cos(f-N),w=n*Math.sin(f-N),S=n*Math.cos(s+N),k=n*Math.sin(s+N);var L=Math.abs(s-f+2*N)<=ja?0:1;if(N&&mi(_,w,S,k)===1-g^L){var q=(s+f)/2;_=n*Math.cos(q),w=n*Math.sin(q),S=k=null}}else _=w=0;if(h>Da&&(p=Math.min(Math.abs(c-n)/2,+u.apply(this,arguments)))>.001){v=c>n^g?0:1;var T=p,R=p;if(ja>h){var D=null==S?[_,w]:null==x?[y,M]:Re([y,M],[S,k],[x,b],[_,w]),P=y-D[0],j=M-D[1],U=x-D[0],F=b-D[1],H=1/Math.sin(Math.acos((P*U+j*F)/(Math.sqrt(P*P+j*j)*Math.sqrt(U*U+F*F)))/2),O=Math.sqrt(D[0]*D[0]+D[1]*D[1]);R=Math.min(p,(n-O)/(H-1)),T=Math.min(p,(c-O)/(H+1))}if(null!=x){var I=yi(null==S?[_,w]:[S,k],[y,M],c,T,g),Y=yi([x,b],[_,w],c,T,g);p===T?A.push("M",I[0],"A",T,",",T," 0 0,",v," ",I[1],"A",c,",",c," 0 ",1-g^mi(I[1][0],I[1][1],Y[1][0],Y[1][1]),",",g," ",Y[1],"A",T,",",T," 0 0,",v," ",Y[0]):A.push("M",I[0],"A",T,",",T," 0 1,",v," ",Y[0])}else A.push("M",y,",",M);if(null!=S){var Z=yi([y,M],[S,k],n,-R,g),V=yi([_,w],null==x?[y,M]:[x,b],n,-R,g);p===R?A.push("L",V[0],"A",R,",",R," 0 0,",v," ",V[1],"A",n,",",n," 0 ",g^mi(V[1][0],V[1][1],Z[1][0],Z[1][1]),",",1-g," ",Z[1],"A",R,",",R," 0 0,",v," ",Z[0]):A.push("L",V[0],"A",R,",",R," 0 0,",v," ",Z[0])}else A.push("L",_,",",w)}else A.push("M",y,",",M),null!=x&&A.push("A",c,",",c," 0 ",C,",",g," ",x,",",b),A.push("L",_,",",w),null!=S&&A.push("A",n,",",n," 0 ",L,",",1-g," ",S,",",k);return A.push("Z"),A.join("")}function t(n,t){return"M0,"+n+"A"+n+","+n+" 0 1,"+t+" 0,"+-n+"A"+n+","+n+" 0 1,"+t+" 0,"+n}var e=hi,r=gi,u=fi,i=Ll,a=pi,o=vi,l=di;return n.innerRadius=function(t){return arguments.length?(e=En(t),n):e},n.outerRadius=function(t){return arguments.length?(r=En(t),n):r},n.cornerRadius=function(t){return arguments.length?(u=En(t),n):u},n.padRadius=function(t){return arguments.length?(i=t==Ll?Ll:En(t),n):i},n.startAngle=function(t){return arguments.length?(a=En(t),n):a},n.endAngle=function(t){return arguments.length?(o=En(t),n):o},n.padAngle=function(t){return arguments.length?(l=En(t),n):l},n.centroid=function(){var n=(+e.apply(this,arguments)+ +r.apply(this,arguments))/2,t=(+a.apply(this,arguments)+ +o.apply(this,arguments))/2-Ha;return[Math.cos(t)*n,Math.sin(t)*n]},n};var Ll="auto";oa.svg.line=function(){return Mi(y)};var ql=oa.map({linear:xi,"linear-closed":bi,step:_i,"step-before":wi,"step-after":Si,basis:zi,"basis-open":Li,"basis-closed":qi,bundle:Ti,cardinal:Ei,"cardinal-open":ki,"cardinal-closed":Ni,monotone:Fi});ql.forEach(function(n,t){t.key=n,t.closed=/-closed$/.test(n)});var Tl=[0,2/3,1/3,0],Rl=[0,1/3,2/3,0],Dl=[0,1/6,2/3,1/6];oa.svg.line.radial=function(){var n=Mi(Hi);return n.radius=n.x,delete n.x,n.angle=n.y,delete n.y,n},wi.reverse=Si,Si.reverse=wi,oa.svg.area=function(){return Oi(y)},oa.svg.area.radial=function(){var n=Oi(Hi);return n.radius=n.x,delete n.x,n.innerRadius=n.x0,delete n.x0,n.outerRadius=n.x1,delete n.x1,n.angle=n.y,delete n.y,n.startAngle=n.y0,delete n.y0,n.endAngle=n.y1,delete n.y1,n},oa.svg.chord=function(){function n(n,o){var l=t(this,i,n,o),c=t(this,a,n,o);return"M"+l.p0+r(l.r,l.p1,l.a1-l.a0)+(e(l,c)?u(l.r,l.p1,l.r,l.p0):u(l.r,l.p1,c.r,c.p0)+r(c.r,c.p1,c.a1-c.a0)+u(c.r,c.p1,l.r,l.p0))+"Z"}function t(n,t,e,r){var u=t.call(n,e,r),i=o.call(n,u,r),a=l.call(n,u,r)-Ha,s=c.call(n,u,r)-Ha;return{r:i,a0:a,a1:s,p0:[i*Math.cos(a),i*Math.sin(a)],p1:[i*Math.cos(s),i*Math.sin(s)]}}function e(n,t){return n.a0==t.a0&&n.a1==t.a1}function r(n,t,e){return"A"+n+","+n+" 0 "+ +(e>ja)+",1 "+t}function u(n,t,e,r){return"Q 0,0 "+r}var i=Me,a=xe,o=Ii,l=pi,c=vi;return n.radius=function(t){return arguments.length?(o=En(t),n):o},n.source=function(t){return arguments.length?(i=En(t),n):i},n.target=function(t){return arguments.length?(a=En(t),n):a},n.startAngle=function(t){return arguments.length?(l=En(t),n):l},n.endAngle=function(t){return arguments.length?(c=En(t),n):c},n},oa.svg.diagonal=function(){function n(n,u){var i=t.call(this,n,u),a=e.call(this,n,u),o=(i.y+a.y)/2,l=[i,{x:i.x,y:o},{x:a.x,y:o},a];return l=l.map(r),"M"+l[0]+"C"+l[1]+" "+l[2]+" "+l[3]}var t=Me,e=xe,r=Yi;return n.source=function(e){return arguments.length?(t=En(e),n):t},n.target=function(t){return arguments.length?(e=En(t),n):e},n.projection=function(t){return arguments.length?(r=t,n):r},n},oa.svg.diagonal.radial=function(){var n=oa.svg.diagonal(),t=Yi,e=n.projection;return n.projection=function(n){return arguments.length?e(Zi(t=n)):t},n},oa.svg.symbol=function(){function n(n,r){return(Pl.get(t.call(this,n,r))||$i)(e.call(this,n,r))}var t=Xi,e=Vi;return n.type=function(e){return arguments.length?(t=En(e),n):t},n.size=function(t){return arguments.length?(e=En(t),n):e},n};var Pl=oa.map({circle:$i,cross:function(n){var t=Math.sqrt(n/5)/2;return"M"+-3*t+","+-t+"H"+-t+"V"+-3*t+"H"+t+"V"+-t+"H"+3*t+"V"+t+"H"+t+"V"+3*t+"H"+-t+"V"+t+"H"+-3*t+"Z"},diamond:function(n){var t=Math.sqrt(n/(2*Ul)),e=t*Ul;return"M0,"+-t+"L"+e+",0 0,"+t+" "+-e+",0Z"},square:function(n){var t=Math.sqrt(n)/2;return"M"+-t+","+-t+"L"+t+","+-t+" "+t+","+t+" "+-t+","+t+"Z"},"triangle-down":function(n){var t=Math.sqrt(n/jl),e=t*jl/2;return"M0,"+e+"L"+t+","+-e+" "+-t+","+-e+"Z"},"triangle-up":function(n){var t=Math.sqrt(n/jl),e=t*jl/2;return"M0,"+-e+"L"+t+","+e+" "+-t+","+e+"Z"}});oa.svg.symbolTypes=Pl.keys();var jl=Math.sqrt(3),Ul=Math.tan(30*Oa);Aa.transition=function(n){for(var t,e,r=Fl||++Yl,u=Ki(n),i=[],a=Hl||{time:Date.now(),ease:Nr,delay:0,duration:250},o=-1,l=this.length;++oi;i++){u.push(t=[]);for(var e=this[i],o=0,l=e.length;l>o;o++)(r=e[o])&&n.call(r,r.__data__,o,i)&&t.push(r)}return Wi(u,this.namespace,this.id)},Il.tween=function(n,t){var e=this.id,r=this.namespace;return arguments.length<2?this.node()[r][e].tween.get(n):Y(this,null==t?function(t){t[r][e].tween.remove(n)}:function(u){u[r][e].tween.set(n,t)})},Il.attr=function(n,t){function e(){this.removeAttribute(o)}function r(){this.removeAttributeNS(o.space,o.local)}function u(n){return null==n?e:(n+="",function(){var t,e=this.getAttribute(o);return e!==n&&(t=a(e,n),function(n){this.setAttribute(o,t(n))})})}function i(n){return null==n?r:(n+="",function(){var t,e=this.getAttributeNS(o.space,o.local);return e!==n&&(t=a(e,n),function(n){this.setAttributeNS(o.space,o.local,t(n))})})}if(arguments.length<2){for(t in n)this.attr(t,n[t]);return this}var a="transform"==n?$r:Mr,o=oa.ns.qualify(n);return Ji(this,"attr."+n,t,o.local?i:u)},Il.attrTween=function(n,t){function e(n,e){var r=t.call(this,n,e,this.getAttribute(u));return r&&function(n){this.setAttribute(u,r(n))}}function r(n,e){var r=t.call(this,n,e,this.getAttributeNS(u.space,u.local));return r&&function(n){this.setAttributeNS(u.space,u.local,r(n))}}var u=oa.ns.qualify(n);return this.tween("attr."+n,u.local?r:e)},Il.style=function(n,e,r){function u(){this.style.removeProperty(n)}function i(e){return null==e?u:(e+="",function(){var u,i=t(this).getComputedStyle(this,null).getPropertyValue(n);return i!==e&&(u=Mr(i,e),function(t){this.style.setProperty(n,u(t),r)})})}var a=arguments.length;if(3>a){if("string"!=typeof n){2>a&&(e="");for(r in n)this.style(r,n[r],e);return this}r=""}return Ji(this,"style."+n,e,i)},Il.styleTween=function(n,e,r){function u(u,i){var a=e.call(this,u,i,t(this).getComputedStyle(this,null).getPropertyValue(n));return a&&function(t){this.style.setProperty(n,a(t),r)}}return arguments.length<3&&(r=""),this.tween("style."+n,u)},Il.text=function(n){return Ji(this,"text",n,Gi)},Il.remove=function(){var n=this.namespace;return this.each("end.transition",function(){var t;this[n].count<2&&(t=this.parentNode)&&t.removeChild(this)})},Il.ease=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].ease:("function"!=typeof n&&(n=oa.ease.apply(oa,arguments)),Y(this,function(r){r[e][t].ease=n}))},Il.delay=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].delay:Y(this,"function"==typeof n?function(r,u,i){r[e][t].delay=+n.call(r,r.__data__,u,i)}:(n=+n,function(r){r[e][t].delay=n}))},Il.duration=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].duration:Y(this,"function"==typeof n?function(r,u,i){r[e][t].duration=Math.max(1,n.call(r,r.__data__,u,i))}:(n=Math.max(1,n),function(r){r[e][t].duration=n}))},Il.each=function(n,t){var e=this.id,r=this.namespace;if(arguments.length<2){var u=Hl,i=Fl;try{Fl=e,Y(this,function(t,u,i){Hl=t[r][e],n.call(t,t.__data__,u,i)})}finally{Hl=u,Fl=i}}else Y(this,function(u){var i=u[r][e];(i.event||(i.event=oa.dispatch("start","end","interrupt"))).on(n,t)});return this},Il.transition=function(){for(var n,t,e,r,u=this.id,i=++Yl,a=this.namespace,o=[],l=0,c=this.length;c>l;l++){o.push(n=[]);for(var t=this[l],s=0,f=t.length;f>s;s++)(e=t[s])&&(r=e[a][u],Qi(e,s,a,i,{time:r.time,ease:r.ease,delay:r.delay+r.duration,duration:r.duration})),n.push(e)}return Wi(o,a,i)},oa.svg.axis=function(){function n(n){n.each(function(){var n,c=oa.select(this),s=this.__chart__||e,f=this.__chart__=e.copy(),h=null==l?f.ticks?f.ticks.apply(f,o):f.domain():l,g=null==t?f.tickFormat?f.tickFormat.apply(f,o):y:t,p=c.selectAll(".tick").data(h,f),v=p.enter().insert("g",".domain").attr("class","tick").style("opacity",Da),d=oa.transition(p.exit()).style("opacity",Da).remove(),m=oa.transition(p.order()).style("opacity",1),M=Math.max(u,0)+a,x=Zu(f),b=c.selectAll(".domain").data([0]),_=(b.enter().append("path").attr("class","domain"),oa.transition(b));v.append("line"),v.append("text");var w,S,k,N,E=v.select("line"),A=m.select("line"),C=p.select("text").text(g),z=v.select("text"),L=m.select("text"),q="top"===r||"left"===r?-1:1;if("bottom"===r||"top"===r?(n=na,w="x",k="y",S="x2",N="y2",C.attr("dy",0>q?"0em":".71em").style("text-anchor","middle"),_.attr("d","M"+x[0]+","+q*i+"V0H"+x[1]+"V"+q*i)):(n=ta,w="y",k="x",S="y2",N="x2",C.attr("dy",".32em").style("text-anchor",0>q?"end":"start"),_.attr("d","M"+q*i+","+x[0]+"H0V"+x[1]+"H"+q*i)),E.attr(N,q*u),z.attr(k,q*M),A.attr(S,0).attr(N,q*u),L.attr(w,0).attr(k,q*M),f.rangeBand){var T=f,R=T.rangeBand()/2;s=f=function(n){return T(n)+R}}else s.rangeBand?s=f:d.call(n,f,s);v.call(n,s,f),m.call(n,f,f)})}var t,e=oa.scale.linear(),r=Zl,u=6,i=6,a=3,o=[10],l=null;return n.scale=function(t){return arguments.length?(e=t,n):e},n.orient=function(t){return arguments.length?(r=t in Vl?t+"":Zl,n):r},n.ticks=function(){return arguments.length?(o=ca(arguments),n):o},n.tickValues=function(t){return arguments.length?(l=t,n):l},n.tickFormat=function(e){return arguments.length?(t=e,n):t},n.tickSize=function(t){var e=arguments.length;return e?(u=+t,i=+arguments[e-1],n):u},n.innerTickSize=function(t){return arguments.length?(u=+t,n):u},n.outerTickSize=function(t){return arguments.length?(i=+t,n):i},n.tickPadding=function(t){return arguments.length?(a=+t,n):a},n.tickSubdivide=function(){return arguments.length&&n},n};var Zl="bottom",Vl={top:1,right:1,bottom:1,left:1};oa.svg.brush=function(){function n(t){t.each(function(){var t=oa.select(this).style("pointer-events","all").style("-webkit-tap-highlight-color","rgba(0,0,0,0)").on("mousedown.brush",i).on("touchstart.brush",i),a=t.selectAll(".background").data([0]);a.enter().append("rect").attr("class","background").style("visibility","hidden").style("cursor","crosshair"),t.selectAll(".extent").data([0]).enter().append("rect").attr("class","extent").style("cursor","move");var o=t.selectAll(".resize").data(v,y);o.exit().remove(),o.enter().append("g").attr("class",function(n){return"resize "+n}).style("cursor",function(n){return Xl[n]}).append("rect").attr("x",function(n){return/[ew]$/.test(n)?-3:null}).attr("y",function(n){return/^[ns]/.test(n)?-3:null}).attr("width",6).attr("height",6).style("visibility","hidden"),o.style("display",n.empty()?"none":null);var l,f=oa.transition(t),h=oa.transition(a);c&&(l=Zu(c),h.attr("x",l[0]).attr("width",l[1]-l[0]),r(f)),s&&(l=Zu(s),h.attr("y",l[0]).attr("height",l[1]-l[0]),u(f)),e(f)})}function e(n){n.selectAll(".resize").attr("transform",function(n){return"translate("+f[+/e$/.test(n)]+","+h[+/^s/.test(n)]+")"})}function r(n){n.select(".extent").attr("x",f[0]),n.selectAll(".extent,.n>rect,.s>rect").attr("width",f[1]-f[0])}function u(n){n.select(".extent").attr("y",h[0]),n.selectAll(".extent,.e>rect,.w>rect").attr("height",h[1]-h[0])}function i(){function i(){32==oa.event.keyCode&&(C||(M=null,L[0]-=f[1],L[1]-=h[1],C=2),S())}function v(){32==oa.event.keyCode&&2==C&&(L[0]+=f[1],L[1]+=h[1],C=0,S())}function d(){var n=oa.mouse(b),t=!1;x&&(n[0]+=x[0],n[1]+=x[1]),C||(oa.event.altKey?(M||(M=[(f[0]+f[1])/2,(h[0]+h[1])/2]),L[0]=f[+(n[0]s?(u=r,r=s):u=s),v[0]!=r||v[1]!=u?(e?o=null:a=null,v[0]=r,v[1]=u,!0):void 0}function y(){d(),k.style("pointer-events","all").selectAll(".resize").style("display",n.empty()?"none":null),oa.select("body").style("cursor",null),q.on("mousemove.brush",null).on("mouseup.brush",null).on("touchmove.brush",null).on("touchend.brush",null).on("keydown.brush",null).on("keyup.brush",null),z(),w({type:"brushend"})}var M,x,b=this,_=oa.select(oa.event.target),w=l.of(b,arguments),k=oa.select(b),N=_.datum(),E=!/^(n|s)$/.test(N)&&c,A=!/^(e|w)$/.test(N)&&s,C=_.classed("extent"),z=W(b),L=oa.mouse(b),q=oa.select(t(b)).on("keydown.brush",i).on("keyup.brush",v);if(oa.event.changedTouches?q.on("touchmove.brush",d).on("touchend.brush",y):q.on("mousemove.brush",d).on("mouseup.brush",y),k.interrupt().selectAll("*").interrupt(),C)L[0]=f[0]-L[0],L[1]=h[0]-L[1];else if(N){var T=+/w$/.test(N),R=+/^n/.test(N);x=[f[1-T]-L[0],h[1-R]-L[1]],L[0]=f[T],L[1]=h[R]}else oa.event.altKey&&(M=L.slice());k.style("pointer-events","none").selectAll(".resize").style("display",null),oa.select("body").style("cursor",_.style("cursor")),w({type:"brushstart"}),d()}var a,o,l=N(n,"brushstart","brush","brushend"),c=null,s=null,f=[0,0],h=[0,0],g=!0,p=!0,v=$l[0];return n.event=function(n){n.each(function(){var n=l.of(this,arguments),t={x:f,y:h,i:a,j:o},e=this.__chart__||t;this.__chart__=t,Fl?oa.select(this).transition().each("start.brush",function(){a=e.i,o=e.j,f=e.x,h=e.y,n({type:"brushstart"})}).tween("brush:brush",function(){var e=xr(f,t.x),r=xr(h,t.y);return a=o=null,function(u){f=t.x=e(u),h=t.y=r(u),n({type:"brush",mode:"resize"})}}).each("end.brush",function(){a=t.i,o=t.j,n({type:"brush",mode:"resize"}),n({type:"brushend"})}):(n({type:"brushstart"}),n({type:"brush",mode:"resize"}),n({type:"brushend"}))})},n.x=function(t){return arguments.length?(c=t,v=$l[!c<<1|!s],n):c},n.y=function(t){return arguments.length?(s=t,v=$l[!c<<1|!s],n):s},n.clamp=function(t){return arguments.length?(c&&s?(g=!!t[0],p=!!t[1]):c?g=!!t:s&&(p=!!t),n):c&&s?[g,p]:c?g:s?p:null},n.extent=function(t){var e,r,u,i,l;return arguments.length?(c&&(e=t[0],r=t[1],s&&(e=e[0],r=r[0]),a=[e,r],c.invert&&(e=c(e),r=c(r)),e>r&&(l=e,e=r,r=l),(e!=f[0]||r!=f[1])&&(f=[e,r])),s&&(u=t[0],i=t[1],c&&(u=u[1],i=i[1]),o=[u,i],s.invert&&(u=s(u),i=s(i)),u>i&&(l=u,u=i,i=l),(u!=h[0]||i!=h[1])&&(h=[u,i])),n):(c&&(a?(e=a[0],r=a[1]):(e=f[0],r=f[1],c.invert&&(e=c.invert(e),r=c.invert(r)),e>r&&(l=e,e=r,r=l))),s&&(o?(u=o[0],i=o[1]):(u=h[0],i=h[1],s.invert&&(u=s.invert(u),i=s.invert(i)),u>i&&(l=u,u=i,i=l))),c&&s?[[e,u],[r,i]]:c?[e,r]:s&&[u,i])},n.clear=function(){return n.empty()||(f=[0,0],h=[0,0],a=o=null),n},n.empty=function(){return!!c&&f[0]==f[1]||!!s&&h[0]==h[1]},oa.rebind(n,l,"on")};var Xl={n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},$l=[["n","e","s","w","nw","ne","se","sw"],["e","w"],["n","s"],[]],Bl=ho.format=Mo.timeFormat,Wl=Bl.utc,Jl=Wl("%Y-%m-%dT%H:%M:%S.%LZ");Bl.iso=Date.prototype.toISOString&&+new Date("2000-01-01T00:00:00.000Z")?ea:Jl,ea.parse=function(n){var t=new Date(n);return isNaN(t)?null:t},ea.toString=Jl.toString,ho.second=On(function(n){return new go(1e3*Math.floor(n/1e3))},function(n,t){n.setTime(n.getTime()+1e3*Math.floor(t))},function(n){return n.getSeconds()}),ho.seconds=ho.second.range,ho.seconds.utc=ho.second.utc.range,ho.minute=On(function(n){return new go(6e4*Math.floor(n/6e4))},function(n,t){n.setTime(n.getTime()+6e4*Math.floor(t))},function(n){return n.getMinutes()}),ho.minutes=ho.minute.range,ho.minutes.utc=ho.minute.utc.range,ho.hour=On(function(n){var t=n.getTimezoneOffset()/60;return new go(36e5*(Math.floor(n/36e5-t)+t))},function(n,t){n.setTime(n.getTime()+36e5*Math.floor(t))},function(n){return n.getHours()}),ho.hours=ho.hour.range,ho.hours.utc=ho.hour.utc.range,ho.month=On(function(n){return n=ho.day(n),n.setDate(1),n},function(n,t){n.setMonth(n.getMonth()+t)},function(n){return n.getMonth()}),ho.months=ho.month.range,ho.months.utc=ho.month.utc.range;var Gl=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],Kl=[[ho.second,1],[ho.second,5],[ho.second,15],[ho.second,30],[ho.minute,1],[ho.minute,5],[ho.minute,15],[ho.minute,30],[ho.hour,1],[ho.hour,3],[ho.hour,6],[ho.hour,12],[ho.day,1],[ho.day,2],[ho.week,1],[ho.month,1],[ho.month,3],[ho.year,1]],Ql=Bl.multi([[".%L",function(n){return n.getMilliseconds()}],[":%S",function(n){return n.getSeconds()}],["%I:%M",function(n){return n.getMinutes()}],["%I %p",function(n){return n.getHours()}],["%a %d",function(n){return n.getDay()&&1!=n.getDate()}],["%b %d",function(n){return 1!=n.getDate()}],["%B",function(n){return n.getMonth()}],["%Y",zt]]),nc={range:function(n,t,e){return oa.range(Math.ceil(n/e)*e,+t,e).map(ua)},floor:y,ceil:y};Kl.year=ho.year,ho.scale=function(){return ra(oa.scale.linear(),Kl,Ql)};var tc=Kl.map(function(n){return[n[0].utc,n[1]]}),ec=Wl.multi([[".%L",function(n){return n.getUTCMilliseconds()}],[":%S",function(n){return n.getUTCSeconds()}],["%I:%M",function(n){return n.getUTCMinutes()}],["%I %p",function(n){return n.getUTCHours()}],["%a %d",function(n){return n.getUTCDay()&&1!=n.getUTCDate()}],["%b %d",function(n){return 1!=n.getUTCDate()}],["%B",function(n){return n.getUTCMonth()}],["%Y",zt]]);tc.year=ho.year.utc,ho.scale.utc=function(){return ra(oa.scale.linear(),tc,ec)},oa.text=An(function(n){return n.responseText}),oa.json=function(n,t){return Cn(n,"application/json",ia,t)},oa.html=function(n,t){return Cn(n,"text/html",aa,t)},oa.xml=An(function(n){return n.responseXML}),"function"==typeof define&&define.amd?(this.d3=oa,define(oa)):"object"==typeof module&&module.exports?module.exports=oa:this.d3=oa}(); \ No newline at end of file From 48b4f28c93f309a47f30b3edc890aad6b8433d1c Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Thu, 17 Dec 2015 10:52:42 +0900 Subject: [PATCH 356/358] remove --- app/views/temperatures/index.html.haml | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/views/temperatures/index.html.haml b/app/views/temperatures/index.html.haml index 575a89d..5e87e3f 100644 --- a/app/views/temperatures/index.html.haml +++ b/app/views/temperatures/index.html.haml @@ -1,6 +1,3 @@ -= stylesheet_link_tag 'c3.min', plugin: 'redmine_timetable' -= javascript_include_tag 'lib/d3.min', plugin: 'redmine_timetable' - %div#chart From b397d26deea8753107382aa3f4521b6c2a5e2487 Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Thu, 17 Dec 2015 10:54:34 +0900 Subject: [PATCH 357/358] bundle install gon --- Gemfile | 1 + Gemfile.lock | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/Gemfile b/Gemfile index 347eaea..56fd077 100644 --- a/Gemfile +++ b/Gemfile @@ -42,6 +42,7 @@ gem 'resque' gem 'resque-scheduler' gem 'rubocop', group: :development gem 'kakurenbo-puti' +gem 'gon' group :development, :test do gem 'byebug' diff --git a/Gemfile.lock b/Gemfile.lock index 4f256fa..16b0591 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -82,6 +82,11 @@ GEM i18n (~> 0.5) globalid (0.3.6) activesupport (>= 4.1.0) + gon (6.0.1) + actionpack (>= 3.0) + json + multi_json + request_store (>= 1.0) grape (0.13.0) activesupport builder @@ -213,6 +218,7 @@ GEM redis-namespace (1.5.2) redis (~> 3.0, >= 3.0.4) ref (2.0.0) + request_store (1.2.1) resque (1.25.2) mono_logger (~> 1.0) multi_json (~> 1.0) @@ -323,6 +329,7 @@ DEPENDENCIES database_cleaner factory_girl_rails faker + gon grape grape-jbuilder grape-swagger From 65b944b85ccc3502db3c88897b861769890a77ce Mon Sep 17 00:00:00 2001 From: "j.taneichi" Date: Thu, 17 Dec 2015 11:27:57 +0900 Subject: [PATCH 358/358] add temperature --- app/controllers/temperatures_controller.rb | 8 ++++++++ app/views/temperatures/index.html.haml | 18 +++++++++++++----- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/app/controllers/temperatures_controller.rb b/app/controllers/temperatures_controller.rb index 311ad69..8c283f6 100644 --- a/app/controllers/temperatures_controller.rb +++ b/app/controllers/temperatures_controller.rb @@ -1,4 +1,12 @@ class TemperaturesController < ApplicationController def index + @temperatures = Temperature.last(10) + dates = ['x'] + degree = ['気温'] + @temperatures.each do |data| + dates << "#{data.created_at.strftime('%d %M')}" + degree << data.centigrade + end + gon.ttevents = [dates, degree] end end diff --git a/app/views/temperatures/index.html.haml b/app/views/temperatures/index.html.haml index 5e87e3f..7fffe24 100644 --- a/app/views/temperatures/index.html.haml +++ b/app/views/temperatures/index.html.haml @@ -1,3 +1,5 @@ += Gon::Base.render_data({}) + %div#chart @@ -5,9 +7,15 @@ var chart = c3.generate({ bindto: '#chart', data: { - columns: [ - ['data1', 30, 200, 100, 400, 150, 250], - ['data2', 50, 20, 10, 40, 15, 25] - ] + x: 'x', + xFormat: '%d %M', + columns: gon.ttevents, + type: 'line', + }, + axis: { + x : { + type: 'timeseries' + } } - }); \ No newline at end of file + }); +