rails 5 + api v2 + raml api docs (#593)

* update Gemfile to rails 5 and ruby 2.3.0

* fiddle with javascripts and add sprockets manifest file

* update config directory for rails 5

* fix some errors with controllers/serializers

* fix travis and rspec

* new serializers renamed to serializers

* module Api::V1

* reusable embedding code

* add index/collections/paging. overriding most of snorlax now |:)

* raml api documentation + rspec tests to verify schemas/examples

* add sorting by ?sort and searching by ?q. Add pagination Link headers

* api v1 => v2

* fill out synapse api

* alphabetize map policy

* fix page thing

* fill out maps api

* formParameters => properties, and fiddle with map api

* more raml 1.0 stuff i'm learning about

* deprecate v1 api

* rails 5 uses ApplicationRecord class for app-wide model config

* Update topic spec for api v2

* workaround for user_preference.rb issue

* get ready for token api docs. also TODO is mapping api docs

* spec out mapping api

* map/mapping/synapse spec, plus other bugs

* awesome, token specs/apis are done

* add sanity checks to the api tests

* more cleanup

* devise fix

* fix starred map error
This commit is contained in:
Devin Howard 2016-09-22 01:22:40 +08:00 committed by Connor Turland
parent aace6796f5
commit 3843cab643
148 changed files with 2506 additions and 694 deletions

20
Gemfile
View file

@ -1,28 +1,27 @@
source 'https://rubygems.org' source 'https://rubygems.org'
ruby '2.3.0' ruby '2.3.0'
gem 'rails' gem 'rails', '~> 5.0.0'
gem 'active_model_serializers', '~> 0.8.1' gem 'active_model_serializers'
gem 'aws-sdk', '< 2.0' gem 'aws-sdk', '< 2.0'
gem 'best_in_place' # in-place editing gem 'best_in_place'
gem 'delayed_job', '~> 4.0.2' gem 'delayed_job'
gem 'delayed_job_active_record', '~> 4.0.1' gem 'delayed_job_active_record'
gem 'devise' gem 'devise'
gem 'doorkeeper' gem 'doorkeeper', '~> 4.0.0.rc4'
gem 'dotenv-rails' gem 'dotenv-rails'
gem 'exception_notification' gem 'exception_notification'
gem 'formtastic' gem 'formtastic'
gem 'formula' gem 'formula'
gem 'httparty' gem 'httparty'
gem 'json' gem 'json'
gem 'kaminari' # pagination gem 'kaminari'
gem 'paperclip' gem 'paperclip', '~> 4.3.6'
gem 'pg' gem 'pg'
gem 'pundit' gem 'pundit'
gem 'pundit_extra' gem 'pundit_extra'
gem 'rack-cors' gem 'rack-cors'
gem 'rails3-jquery-autocomplete'
gem 'redis' gem 'redis'
gem 'slack-notifier' gem 'slack-notifier'
gem 'snorlax' gem 'snorlax'
@ -31,12 +30,12 @@ gem 'uservoice-ruby'
gem 'jquery-rails' gem 'jquery-rails'
gem 'jquery-ui-rails' gem 'jquery-ui-rails'
gem 'jbuilder' gem 'jbuilder'
gem 'rails3-jquery-autocomplete'
group :assets do group :assets do
gem 'coffee-rails' gem 'coffee-rails'
gem 'sass-rails' gem 'sass-rails'
gem 'uglifier' gem 'uglifier'
# gem 'therubyracer'
end end
group :production do group :production do
@ -57,7 +56,6 @@ group :development, :test do
gem 'binding_of_caller' gem 'binding_of_caller'
gem 'pry-byebug' gem 'pry-byebug'
gem 'pry-rails' gem 'pry-rails'
gem 'quiet_assets'
gem 'tunemygc' gem 'tunemygc'
gem 'rubocop' gem 'rubocop'
end end

View file

@ -1,45 +1,50 @@
GEM GEM
remote: https://rubygems.org/ remote: https://rubygems.org/
specs: specs:
actionmailer (4.2.6) actioncable (5.0.0)
actionpack (= 4.2.6) actionpack (= 5.0.0)
actionview (= 4.2.6) nio4r (~> 1.2)
activejob (= 4.2.6) websocket-driver (~> 0.6.1)
actionmailer (5.0.0)
actionpack (= 5.0.0)
actionview (= 5.0.0)
activejob (= 5.0.0)
mail (~> 2.5, >= 2.5.4) mail (~> 2.5, >= 2.5.4)
rails-dom-testing (~> 1.0, >= 1.0.5) rails-dom-testing (~> 2.0)
actionpack (4.2.6) actionpack (5.0.0)
actionview (= 4.2.6) actionview (= 5.0.0)
activesupport (= 4.2.6) activesupport (= 5.0.0)
rack (~> 1.6) rack (~> 2.0)
rack-test (~> 0.6.2) rack-test (~> 0.6.3)
rails-dom-testing (~> 1.0, >= 1.0.5) rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.0.2) rails-html-sanitizer (~> 1.0, >= 1.0.2)
actionview (4.2.6) actionview (5.0.0)
activesupport (= 4.2.6) activesupport (= 5.0.0)
builder (~> 3.1) builder (~> 3.1)
erubis (~> 2.7.0) erubis (~> 2.7.0)
rails-dom-testing (~> 1.0, >= 1.0.5) rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.0.2) rails-html-sanitizer (~> 1.0, >= 1.0.2)
active_model_serializers (0.8.3) active_model_serializers (0.10.1)
activemodel (>= 3.0) actionpack (>= 4.1, < 6)
activejob (4.2.6) activemodel (>= 4.1, < 6)
activesupport (= 4.2.6) jsonapi (~> 0.1.1.beta2)
globalid (>= 0.3.0) railties (>= 4.1, < 6)
activemodel (4.2.6) activejob (5.0.0)
activesupport (= 4.2.6) activesupport (= 5.0.0)
builder (~> 3.1) globalid (>= 0.3.6)
activerecord (4.2.6) activemodel (5.0.0)
activemodel (= 4.2.6) activesupport (= 5.0.0)
activesupport (= 4.2.6) activerecord (5.0.0)
arel (~> 6.0) activemodel (= 5.0.0)
activesupport (4.2.6) activesupport (= 5.0.0)
arel (~> 7.0)
activesupport (5.0.0)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (~> 0.7) i18n (~> 0.7)
json (~> 1.7, >= 1.7.7)
minitest (~> 5.1) minitest (~> 5.1)
thread_safe (~> 0.3, >= 0.3.4)
tzinfo (~> 1.1) tzinfo (~> 1.1)
addressable (2.3.8) addressable (2.3.8)
arel (6.0.3) arel (7.1.1)
ast (2.3.0) ast (2.3.0)
aws-sdk (1.66.0) aws-sdk (1.66.0)
aws-sdk-v1 (= 1.66.0) aws-sdk-v1 (= 1.66.0)
@ -56,7 +61,7 @@ GEM
rack (>= 0.9.0) rack (>= 0.9.0)
binding_of_caller (0.7.2) binding_of_caller (0.7.2)
debug_inspector (>= 0.0.1) debug_inspector (>= 0.0.1)
brakeman (3.3.2) brakeman (3.3.3)
builder (3.2.2) builder (3.2.2)
byebug (9.0.5) byebug (9.0.5)
climate_control (0.0.3) climate_control (0.0.3)
@ -64,21 +69,21 @@ GEM
cocaine (0.5.8) cocaine (0.5.8)
climate_control (>= 0.0.3, < 1.0) climate_control (>= 0.0.3, < 1.0)
coderay (1.1.1) coderay (1.1.1)
coffee-rails (4.1.1) coffee-rails (4.2.1)
coffee-script (>= 2.2.0) coffee-script (>= 2.2.0)
railties (>= 4.0.0, < 5.1.x) railties (>= 4.0.0, < 5.2.x)
coffee-script (2.4.1) coffee-script (2.4.1)
coffee-script-source coffee-script-source
execjs execjs
coffee-script-source (1.10.0) coffee-script-source (1.10.0)
concurrent-ruby (1.0.2) concurrent-ruby (1.0.2)
debug_inspector (0.0.2) debug_inspector (0.0.2)
delayed_job (4.0.6) delayed_job (4.1.2)
activesupport (>= 3.0, < 5.0) activesupport (>= 3.0, < 5.1)
delayed_job_active_record (4.0.3) delayed_job_active_record (4.1.1)
activerecord (>= 3.0, < 5.0) activerecord (>= 3.0, < 5.1)
delayed_job (>= 3.0, < 4.1) delayed_job (>= 3.0, < 5)
devise (4.1.1) devise (4.2.0)
bcrypt (~> 3.0) bcrypt (~> 3.0)
orm_adapter (~> 0.1) orm_adapter (~> 0.1)
railties (>= 4.1.0, < 5.1) railties (>= 4.1.0, < 5.1)
@ -86,16 +91,16 @@ GEM
warden (~> 1.2.3) warden (~> 1.2.3)
diff-lcs (1.2.5) diff-lcs (1.2.5)
docile (1.1.5) docile (1.1.5)
doorkeeper (3.1.0) doorkeeper (4.0.0)
railties (>= 3.2) railties (>= 4.2)
dotenv (2.1.1) dotenv (2.1.1)
dotenv-rails (2.1.1) dotenv-rails (2.1.1)
dotenv (= 2.1.1) dotenv (= 2.1.1)
railties (>= 4.0, < 5.1) railties (>= 4.0, < 5.1)
erubis (2.7.0) erubis (2.7.0)
exception_notification (4.1.4) exception_notification (4.2.1)
actionmailer (~> 4.0) actionmailer (>= 4.0, < 6)
activesupport (~> 4.0) activesupport (>= 4.0, < 6)
execjs (2.7.0) execjs (2.7.0)
ezcrypto (0.7.2) ezcrypto (0.7.2)
factory_girl (4.7.0) factory_girl (4.7.0)
@ -107,13 +112,12 @@ GEM
actionpack (>= 3.2.13) actionpack (>= 3.2.13)
formula (1.1.1) formula (1.1.1)
rails (> 3.0.0) rails (> 3.0.0)
globalid (0.3.6) globalid (0.3.7)
activesupport (>= 4.1.0) activesupport (>= 4.1.0)
httparty (0.13.7) httparty (0.14.0)
json (~> 1.8)
multi_xml (>= 0.5.2) multi_xml (>= 0.5.2)
i18n (0.7.0) i18n (0.7.0)
jbuilder (2.5.0) jbuilder (2.6.0)
activesupport (>= 3.0.0, < 5.1) activesupport (>= 3.0.0, < 5.1)
multi_json (~> 1.2) multi_json (~> 1.2)
jquery-rails (4.1.1) jquery-rails (4.1.1)
@ -125,6 +129,8 @@ GEM
json (1.8.3) json (1.8.3)
json-schema (2.6.2) json-schema (2.6.2)
addressable (~> 2.3.8) addressable (~> 2.3.8)
jsonapi (0.1.1.beta2)
json (~> 1.8)
kaminari (0.17.0) kaminari (0.17.0)
actionpack (>= 3.0.0) actionpack (>= 3.0.0)
activesupport (>= 3.0.0) activesupport (>= 3.0.0)
@ -141,6 +147,7 @@ GEM
minitest (5.9.0) minitest (5.9.0)
multi_json (1.12.1) multi_json (1.12.1)
multi_xml (0.5.5) multi_xml (0.5.5)
nio4r (1.2.1)
nokogiri (1.6.8) nokogiri (1.6.8)
mini_portile2 (~> 2.1.0) mini_portile2 (~> 2.1.0)
pkg-config (~> 1.1.7) pkg-config (~> 1.1.7)
@ -157,7 +164,7 @@ GEM
pg (0.18.4) pg (0.18.4)
pkg-config (1.1.7) pkg-config (1.1.7)
powerpack (0.1.1) powerpack (0.1.1)
pry (0.10.3) pry (0.10.4)
coderay (~> 1.1.0) coderay (~> 1.1.0)
method_source (~> 0.8.1) method_source (~> 0.8.1)
slop (~> 3.4) slop (~> 3.4)
@ -169,29 +176,25 @@ GEM
pundit (1.1.0) pundit (1.1.0)
activesupport (>= 3.0.0) activesupport (>= 3.0.0)
pundit_extra (0.2.0) pundit_extra (0.2.0)
quiet_assets (1.1.0) rack (2.0.1)
railties (>= 3.1, < 5.0)
rack (1.6.4)
rack-cors (0.4.0) rack-cors (0.4.0)
rack-test (0.6.3) rack-test (0.6.3)
rack (>= 1.0) rack (>= 1.0)
rails (4.2.6) rails (5.0.0)
actionmailer (= 4.2.6) actioncable (= 5.0.0)
actionpack (= 4.2.6) actionmailer (= 5.0.0)
actionview (= 4.2.6) actionpack (= 5.0.0)
activejob (= 4.2.6) actionview (= 5.0.0)
activemodel (= 4.2.6) activejob (= 5.0.0)
activerecord (= 4.2.6) activemodel (= 5.0.0)
activesupport (= 4.2.6) activerecord (= 5.0.0)
activesupport (= 5.0.0)
bundler (>= 1.3.0, < 2.0) bundler (>= 1.3.0, < 2.0)
railties (= 4.2.6) railties (= 5.0.0)
sprockets-rails sprockets-rails (>= 2.0.0)
rails-deprecated_sanitizer (1.0.3) rails-dom-testing (2.0.1)
activesupport (>= 4.2.0.alpha) activesupport (>= 4.2.0, < 6.0)
rails-dom-testing (1.0.7)
activesupport (>= 4.2.0.beta, < 5.0)
nokogiri (~> 1.6.0) nokogiri (~> 1.6.0)
rails-deprecated_sanitizer (>= 1.0.1)
rails-html-sanitizer (1.0.3) rails-html-sanitizer (1.0.3)
loofah (~> 2.0) loofah (~> 2.0)
rails3-jquery-autocomplete (1.0.15) rails3-jquery-autocomplete (1.0.15)
@ -201,34 +204,35 @@ GEM
rails_stdout_logging rails_stdout_logging
rails_serve_static_assets (0.0.5) rails_serve_static_assets (0.0.5)
rails_stdout_logging (0.0.5) rails_stdout_logging (0.0.5)
railties (4.2.6) railties (5.0.0)
actionpack (= 4.2.6) actionpack (= 5.0.0)
activesupport (= 4.2.6) activesupport (= 5.0.0)
method_source
rake (>= 0.8.7) rake (>= 0.8.7)
thor (>= 0.18.1, < 2.0) thor (>= 0.18.1, < 2.0)
rainbow (2.1.0) rainbow (2.1.0)
rake (11.2.2) rake (11.2.2)
redis (3.3.0) redis (3.3.1)
responders (2.2.0) responders (2.2.0)
railties (>= 4.2.0, < 5.1) railties (>= 4.2.0, < 5.1)
rspec-core (3.4.4) rspec-core (3.5.2)
rspec-support (~> 3.4.0) rspec-support (~> 3.5.0)
rspec-expectations (3.4.0) rspec-expectations (3.5.0)
diff-lcs (>= 1.2.0, < 2.0) diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.4.0) rspec-support (~> 3.5.0)
rspec-mocks (3.4.1) rspec-mocks (3.5.0)
diff-lcs (>= 1.2.0, < 2.0) diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.4.0) rspec-support (~> 3.5.0)
rspec-rails (3.4.2) rspec-rails (3.5.1)
actionpack (>= 3.0, < 4.3) actionpack (>= 3.0)
activesupport (>= 3.0, < 4.3) activesupport (>= 3.0)
railties (>= 3.0, < 4.3) railties (>= 3.0)
rspec-core (~> 3.4.0) rspec-core (~> 3.5.0)
rspec-expectations (~> 3.4.0) rspec-expectations (~> 3.5.0)
rspec-mocks (~> 3.4.0) rspec-mocks (~> 3.5.0)
rspec-support (~> 3.4.0) rspec-support (~> 3.5.0)
rspec-support (3.4.1) rspec-support (3.5.0)
rubocop (0.41.1) rubocop (0.42.0)
parser (>= 2.3.1.1, < 3.0) parser (>= 2.3.1.1, < 3.0)
powerpack (~> 0.1) powerpack (~> 0.1)
rainbow (>= 1.99.1, < 3.0) rainbow (>= 1.99.1, < 3.0)
@ -236,8 +240,8 @@ GEM
unicode-display_width (~> 1.0, >= 1.0.1) unicode-display_width (~> 1.0, >= 1.0.1)
ruby-progressbar (1.8.1) ruby-progressbar (1.8.1)
sass (3.4.22) sass (3.4.22)
sass-rails (5.0.4) sass-rails (5.0.5)
railties (>= 4.0.0, < 5.0) railties (>= 4.0.0, < 6)
sass (~> 3.1) sass (~> 3.1)
sprockets (>= 2.8, < 4.0) sprockets (>= 2.8, < 4.0)
sprockets-rails (>= 2.0, < 4.0) sprockets-rails (>= 2.0, < 4.0)
@ -253,20 +257,20 @@ GEM
slop (3.6.0) slop (3.6.0)
snorlax (0.1.6) snorlax (0.1.6)
rails (> 4.1) rails (> 4.1)
sprockets (3.6.0) sprockets (3.6.2)
concurrent-ruby (~> 1.0) concurrent-ruby (~> 1.0)
rack (> 1, < 3) rack (> 1, < 3)
sprockets-rails (3.0.4) sprockets-rails (3.1.1)
actionpack (>= 4.0) actionpack (>= 4.0)
activesupport (>= 4.0) activesupport (>= 4.0)
sprockets (>= 3.0.0) sprockets (>= 3.0.0)
thor (0.19.1) thor (0.19.1)
thread_safe (0.3.5) thread_safe (0.3.5)
tilt (2.0.5) tilt (2.0.5)
tunemygc (1.0.65) tunemygc (1.0.68)
tzinfo (1.2.2) tzinfo (1.2.2)
thread_safe (~> 0.1) thread_safe (~> 0.1)
uglifier (3.0.0) uglifier (3.0.1)
execjs (>= 0.3.0, < 3) execjs (>= 0.3.0, < 3)
unicode-display_width (1.1.0) unicode-display_width (1.1.0)
uservoice-ruby (0.0.11) uservoice-ruby (0.0.11)
@ -275,22 +279,25 @@ GEM
oauth (>= 0.4.7) oauth (>= 0.4.7)
warden (1.2.6) warden (1.2.6)
rack (>= 1.0) rack (>= 1.0)
websocket-driver (0.6.4)
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.2)
PLATFORMS PLATFORMS
ruby ruby
DEPENDENCIES DEPENDENCIES
active_model_serializers (~> 0.8.1) active_model_serializers
aws-sdk (< 2.0) aws-sdk (< 2.0)
best_in_place best_in_place
better_errors better_errors
binding_of_caller binding_of_caller
brakeman brakeman
coffee-rails coffee-rails
delayed_job (~> 4.0.2) delayed_job
delayed_job_active_record (~> 4.0.1) delayed_job_active_record
devise devise
doorkeeper doorkeeper (~> 4.0.0.rc4)
dotenv-rails dotenv-rails
exception_notification exception_notification
factory_girl_rails factory_girl_rails
@ -303,15 +310,14 @@ DEPENDENCIES
json json
json-schema json-schema
kaminari kaminari
paperclip paperclip (~> 4.3.6)
pg pg
pry-byebug pry-byebug
pry-rails pry-rails
pundit pundit
pundit_extra pundit_extra
quiet_assets
rack-cors rack-cors
rails rails (~> 5.0.0)
rails3-jquery-autocomplete rails3-jquery-autocomplete
rails_12factor rails_12factor
redis redis
@ -326,5 +332,8 @@ DEPENDENCIES
uglifier uglifier
uservoice-ruby uservoice-ruby
RUBY VERSION
ruby 2.3.0p0
BUNDLED WITH BUNDLED WITH
1.11.2 1.12.5

View file

@ -0,0 +1,6 @@
// JS and CSS bundles
//= link_directory ../javascripts .js
//= link_directory ../stylesheets .css
// Other
//= link_tree ../images

View file

@ -1,2 +0,0 @@
class Api::MappingsController < API::RestfulController
end

View file

@ -1,2 +0,0 @@
class Api::MapsController < API::RestfulController
end

View file

@ -1,50 +0,0 @@
class API::RestfulController < ActionController::Base
include Pundit
include PunditExtra
snorlax_used_rest!
load_and_authorize_resource only: [:show, :update, :destroy]
def create
instantiate_resource
resource.user = current_user
authorize resource
create_action
respond_with_resource
end
private
def resource_serializer
"new_#{resource_name}_serializer".camelize.constantize
end
def accessible_records
if current_user
visible_records
else
public_records
end
end
def current_user
super || token_user || doorkeeper_user || nil
end
def token_user
token = params[:access_token]
access_token = Token.find_by_token(token)
@token_user ||= access_token.user if access_token
end
def doorkeeper_user
return unless doorkeeper_token.present?
doorkeeper_render_error unless valid_doorkeeper_token?
@doorkeeper_user ||= User.find(doorkeeper_token.resource_owner_id)
end
def permitted_params
@permitted_params ||= PermittedParams.new(params)
end
end

View file

@ -1,2 +0,0 @@
class Api::SynapsesController < API::RestfulController
end

View file

@ -1,17 +0,0 @@
class Api::TokensController < API::RestfulController
def my_tokens
raise Pundit::NotAuthorizedError unless current_user
instantiate_collection page_collection: false, timeframe_collection: false
respond_with_collection
end
private
def resource_serializer
"#{resource_name}_serializer".camelize.constantize
end
def visible_records
current_user.tokens
end
end

View file

@ -1,2 +0,0 @@
class Api::TopicsController < API::RestfulController
end

View file

@ -0,0 +1,9 @@
module Api
module V1
class DeprecatedController < ApplicationController
def method_missing
render json: { error: "/api/v1 is deprecated! Please use /api/v2 instead." }
end
end
end
end

View file

@ -0,0 +1,6 @@
module Api
module V1
class MappingsController < DeprecatedController
end
end
end

View file

@ -0,0 +1,6 @@
module Api
module V1
class MapsController < DeprecatedController
end
end
end

View file

@ -0,0 +1,6 @@
module Api
module V1
class SynapsesController < DeprecatedController
end
end
end

View file

@ -0,0 +1,6 @@
module Api
module V1
class TokensController < DeprecatedController
end
end
end

View file

@ -0,0 +1,6 @@
module Api
module V1
class TopicsController < DeprecatedController
end
end
end

View file

@ -0,0 +1,6 @@
module Api
module V2
class MappingsController < RestfulController
end
end
end

View file

@ -0,0 +1,9 @@
module Api
module V2
class MapsController < RestfulController
def searchable_columns
[:name, :desc]
end
end
end
end

View file

@ -0,0 +1,179 @@
module Api
module V2
class RestfulController < ActionController::Base
include Pundit
include PunditExtra
snorlax_used_rest!
before_action :load_resource, only: [:show, :update, :destroy]
after_action :verify_authorized
def index
authorize resource_class
instantiate_collection
respond_with_collection
end
def create
instantiate_resource
resource.user = current_user if current_user.present?
authorize resource
create_action
respond_with_resource
end
def destroy
destroy_action
head :no_content
end
private
def accessible_records
if current_user
visible_records
else
public_records
end
end
def current_user
super || token_user || doorkeeper_user || nil
end
def load_resource
super
authorize resource
end
def resource_serializer
"Api::V2::#{resource_name.camelize}Serializer".constantize
end
def respond_with_resource(scope: default_scope, serializer: resource_serializer, root: serializer_root)
if resource.errors.empty?
render json: resource, scope: scope, serializer: serializer, root: root
else
respond_with_errors
end
end
def respond_with_collection(resources: collection, scope: default_scope, serializer: resource_serializer, root: serializer_root)
render json: resources, scope: scope, each_serializer: serializer, root: root, meta: pagination(resources), meta_key: :page
end
def default_scope
{
embeds: embeds
}
end
def embeds
(params[:embed] || '').split(',').map(&:to_sym)
end
def token_user
token = params[:access_token]
access_token = Token.find_by_token(token)
@token_user ||= access_token.user if access_token
end
def doorkeeper_user
return unless doorkeeper_token.present?
doorkeeper_render_error unless valid_doorkeeper_token?
@doorkeeper_user ||= User.find(doorkeeper_token.resource_owner_id)
end
def permitted_params
@permitted_params ||= PermittedParams.new(params)
end
def serializer_root
'data'
end
def pagination(collection)
per = (params[:per] || 25).to_i
current_page = (params[:page] || 1).to_i
total_pages = (collection.total_count.to_f / per).ceil
prev_page = current_page > 1 ? current_page - 1 : 0
next_page = current_page < total_pages ? current_page + 1 : 0
base_url = request.base_url + request.path
nxt = request.query_parameters.merge(page: next_page).map{|x| x.join('=')}.join('&')
prev = request.query_parameters.merge(page: prev_page).map{|x| x.join('=')}.join('&')
last = request.query_parameters.merge(page: total_pages).map{|x| x.join('=')}.join('&')
response.headers['Link'] = [
%(<#{base_url}?#{nxt}>; rel="next"),
%(<#{base_url}?#{prev}>; rel="prev"),
%(<#{base_url}?#{last}>; rel="last")
].join(',')
response.headers['X-Total-Pages'] = collection.total_pages.to_s
response.headers['X-Total-Count'] = collection.total_count.to_s
response.headers['X-Per-Page'] = per.to_s
{
current_page: current_page,
next_page: next_page,
prev_page: prev_page,
total_pages: total_pages,
total_count: collection.total_count,
per: per
}
end
def instantiate_collection
collection = accessible_records
collection = yield collection if block_given?
collection = search_by_q(collection) if params[:q]
collection = order_by_sort(collection) if params[:sort]
collection = collection.page(params[:page]).per(params[:per])
self.collection = collection
end
# override this method to explicitly set searchable columns
def searchable_columns
columns = resource_class.columns.select do |column|
column.type == :text || column.type == :string
end
columns.map(&:name)
end
# thanks to http://stackoverflow.com/questions/4430578
def search_by_q(collection)
table = resource_class.arel_table
safe_query = "%#{params[:q].gsub(/[%_]/, '\\\\\0')}%"
search_column = -> (column) { table[column].matches(safe_query) }
condition = searchable_columns.reduce(nil) do |prev, column|
next search_column.(column) if prev.nil?
search_column.(column).or(prev)
end
puts collection.where(condition).to_sql
collection.where(condition)
end
def order_by_sort(collection)
builder = collection
sorts = params[:sort].split(',')
sorts.each do |sort|
direction = sort.starts_with?('-') ? 'desc' : 'asc'
sort = sort.sub(/^-/, '')
if resource_class.columns.map(&:name).include?(sort)
builder = builder.order(sort => direction)
end
end
return builder
end
def visible_records
policy_scope(resource_class)
end
def public_records
policy_scope(resource_class)
end
end
end
end

View file

@ -0,0 +1,20 @@
module Api
module V2
class SessionsController < ApplicationController
def create
@user = User.find_by(email: params[:email])
if @user && @user.valid_password(params[:password])
sign_in(@user)
render json: @user
else
render json: { error: 'Error' }
end
end
def destroy
sign_out
head :no_content
end
end
end
end

View file

@ -0,0 +1,9 @@
module Api
module V2
class SynapsesController < RestfulController
def searchable_columns
[:desc]
end
end
end
end

View file

@ -0,0 +1,11 @@
module Api
module V2
class TokensController < RestfulController
def my_tokens
authorize resource_class
instantiate_collection
respond_with_collection
end
end
end
end

View file

@ -0,0 +1,6 @@
module Api
module V2
class TopicsController < RestfulController
end
end
end

View file

@ -163,8 +163,8 @@ class MainController < ApplicationController
@synapses = [] @synapses = []
end end
# limit to 5 results #limit to 5 results
@synapses = @synapses.slice(0, 5) @synapses = @synapses.to_a.slice(0,5)
render json: autocomplete_synapse_array_json(@synapses) render json: autocomplete_synapse_array_json(@synapses)
end end

View file

@ -1,6 +1,6 @@
class MapsController < ApplicationController class MapsController < ApplicationController
before_action :require_user, only: [:create, :update, :access, :star, :unstar, :screenshot, :events, :destroy] before_action :require_user, only: [:create, :update, :access, :star, :unstar, :screenshot, :events, :destroy]
after_action :verify_authorized, except: [:activemaps, :featuredmaps, :mymaps, :sharedmaps, :starredmaps, :usermaps, :events] after_action :verify_authorized, except: [:activemaps, :featuredmaps, :mymaps, :sharedmaps, :starredmaps, :usermaps]
after_action :verify_policy_scoped, only: [:activemaps, :featuredmaps, :mymaps, :sharedmaps, :starredmaps, :usermaps] after_action :verify_policy_scoped, only: [:activemaps, :featuredmaps, :mymaps, :sharedmaps, :starredmaps, :usermaps]
respond_to :html, :json, :csv respond_to :html, :json, :csv

View file

@ -15,11 +15,10 @@ class Users::RegistrationsController < Devise::RegistrationsController
private private
def configure_sign_up_params def configure_sign_up_params
devise_parameter_sanitizer.for(:sign_up) << [:name, :joinedwithcode] devise_parameter_sanitizer.permit(:sign_up, keys: [:name, :joinedwithcode])
end end
def configure_account_update_params def configure_account_update_params
puts devise_parameter_sanitizer_for(:account_update) devise_parameter_sanitizer.permit(:account_update, keys: [:image])
devise_parameter_sanitizer.for(:account_update) << [:image]
end end
end end

View file

@ -0,0 +1,3 @@
class ApplicationRecord < ActiveRecord::Base
self.abstract_class = true
end

View file

@ -1,4 +1,4 @@
class Event < ActiveRecord::Base class Event < ApplicationRecord
KINDS = %w(user_present_on_map conversation_started_on_map topic_added_to_map synapse_added_to_map).freeze KINDS = %w(user_present_on_map conversation_started_on_map topic_added_to_map synapse_added_to_map).freeze
# has_many :notifications, dependent: :destroy # has_many :notifications, dependent: :destroy

View file

@ -1,4 +1,4 @@
class InMetacodeSet < ActiveRecord::Base class InMetacodeSet < ApplicationRecord
belongs_to :metacode, class_name: 'Metacode', foreign_key: 'metacode_id' belongs_to :metacode, class_name: 'Metacode', foreign_key: 'metacode_id'
belongs_to :metacode_set, class_name: 'MetacodeSet', foreign_key: 'metacode_set_id' belongs_to :metacode_set, class_name: 'MetacodeSet', foreign_key: 'metacode_set_id'
end end

View file

@ -1,4 +1,4 @@
class Map < ActiveRecord::Base class Map < ApplicationRecord
belongs_to :user belongs_to :user
has_many :topicmappings, -> { Mapping.topicmapping }, class_name: :Mapping, dependent: :destroy has_many :topicmappings, -> { Mapping.topicmapping }, class_name: :Mapping, dependent: :destroy

View file

@ -1,4 +1,4 @@
class Mapping < ActiveRecord::Base class Mapping < ApplicationRecord
scope :topicmapping, -> { where(mappable_type: :Topic) } scope :topicmapping, -> { where(mappable_type: :Topic) }
scope :synapsemapping, -> { where(mappable_type: :Synapse) } scope :synapsemapping, -> { where(mappable_type: :Synapse) }

View file

@ -1,4 +1,4 @@
class Message < ActiveRecord::Base class Message < ApplicationRecord
belongs_to :user belongs_to :user
belongs_to :resource, polymorphic: true belongs_to :resource, polymorphic: true

View file

@ -1,4 +1,4 @@
class Metacode < ActiveRecord::Base class Metacode < ApplicationRecord
has_many :in_metacode_sets has_many :in_metacode_sets
has_many :metacode_sets, through: :in_metacode_sets has_many :metacode_sets, through: :in_metacode_sets
has_many :topics has_many :topics

View file

@ -1,4 +1,4 @@
class MetacodeSet < ActiveRecord::Base class MetacodeSet < ApplicationRecord
belongs_to :user belongs_to :user
has_many :in_metacode_sets has_many :in_metacode_sets
has_many :metacodes, through: :in_metacode_sets has_many :metacodes, through: :in_metacode_sets

View file

@ -1,4 +1,4 @@
class Synapse < ActiveRecord::Base class Synapse < ApplicationRecord
belongs_to :user belongs_to :user
belongs_to :defer_to_map, class_name: 'Map', foreign_key: 'defer_to_map_id' belongs_to :defer_to_map, class_name: 'Map', foreign_key: 'defer_to_map_id'

View file

@ -1,4 +1,4 @@
class Token < ActiveRecord::Base class Token < ApplicationRecord
belongs_to :user belongs_to :user
before_create :assign_token before_create :assign_token

View file

@ -1,4 +1,4 @@
class Topic < ActiveRecord::Base class Topic < ApplicationRecord
include TopicsHelper include TopicsHelper
belongs_to :user belongs_to :user

View file

@ -1,6 +1,6 @@
require 'open-uri' require 'open-uri'
class User < ActiveRecord::Base class User < ApplicationRecord
has_many :topics has_many :topics
has_many :synapses has_many :synapses
has_many :maps has_many :maps
@ -80,7 +80,7 @@ class User < ActiveRecord::Base
end end
def starred_map?(map) def starred_map?(map)
return !!self.stars.index{|s| s.map_id == map.id } return self.stars.where(map_id: map.id).exists?
end end
def settings def settings

View file

@ -1,4 +1,4 @@
class UserMap < ActiveRecord::Base class UserMap < ApplicationRecord
belongs_to :map belongs_to :map
belongs_to :user belongs_to :user
end end

View file

@ -4,8 +4,14 @@ class UserPreference
def initialize def initialize
array = [] array = []
%w(Action Aim Idea Question Note Wildcard Subject).each do |m| %w(Action Aim Idea Question Note Wildcard Subject).each do |m|
metacode = Metacode.find_by_name(m) begin
array.push(metacode.id.to_s) if metacode metacode = Metacode.find_by_name(m)
array.push(metacode.id.to_s) if metacode
rescue ActiveRecord::StatementInvalid
if m == 'Action'
Rails.logger.warn("TODO: remove this travis workaround in user_preference.rb")
end
end
end end
@metacodes = array @metacodes = array
end end

View file

@ -1,4 +1,4 @@
class Webhook < ActiveRecord::Base class Webhook < ApplicationRecord
belongs_to :hookable, polymorphic: true belongs_to :hookable, polymorphic: true
validates :uri, presence: true validates :uri, presence: true

View file

@ -12,19 +12,7 @@ class MapPolicy < ApplicationPolicy
end end
end end
def activemaps? def index?
user.blank? # redirect to root url if authenticated for some reason
end
def featuredmaps?
true
end
def mymaps?
user.present?
end
def usermaps?
true true
end end
@ -32,18 +20,6 @@ class MapPolicy < ApplicationPolicy
record.permission == 'commons' || record.permission == 'public' || record.collaborators.include?(user) || record.user == user record.permission == 'commons' || record.permission == 'public' || record.collaborators.include?(user) || record.user == user
end end
def export?
show?
end
def events?
show?
end
def contains?
show?
end
def create? def create?
user.present? user.present?
end end
@ -52,11 +28,39 @@ class MapPolicy < ApplicationPolicy
user.present? && (record.permission == 'commons' || record.collaborators.include?(user) || record.user == user) user.present? && (record.permission == 'commons' || record.collaborators.include?(user) || record.user == user)
end end
def destroy?
record.user == user || admin_override
end
def access? def access?
# note that this is to edit access # note that this is to edit access
user.present? && record.user == user user.present? && record.user == user
end end
def activemaps?
user.blank? # redirect to root url if authenticated for some reason
end
def contains?
show?
end
def events?
show?
end
def export?
show?
end
def featuredmaps?
true
end
def mymaps?
user.present?
end
def star? def star?
unstar? unstar?
end end
@ -69,7 +73,7 @@ class MapPolicy < ApplicationPolicy
update? update?
end end
def destroy? def usermaps?
record.user == user || admin_override true
end end
end end

View file

@ -8,13 +8,17 @@ class MappingPolicy < ApplicationPolicy
visible = %w(public commons) visible = %w(public commons)
permission = 'maps.permission IN (?)' permission = 'maps.permission IN (?)'
if user if user
scope.joins(:maps).where(permission + ' OR maps.user_id = ?', visible, user.id) scope.joins(:map).where(permission, visible).or(scope.joins(:map).where(user_id: user.id))
else else
scope.where(permission, visible) scope.joins(:map).where(permission, visible)
end end
end end
end end
def index?
true
end
def show? def show?
map_policy.show? && mappable_policy.try(:show?) map_policy.show? && mappable_policy.try(:show?)
end end

View file

@ -11,6 +11,10 @@ class SynapsePolicy < ApplicationPolicy
end end
end end
def index?
true # really only for the API. should be policy scoped!
end
def create? def create?
user.present? user.present?
# TODO: add validation against whether you can see both topics # TODO: add validation against whether you can see both topics

View file

@ -11,6 +11,10 @@ class TopicPolicy < ApplicationPolicy
end end
end end
def index?
user.present?
end
def create? def create?
user.present? user.present?
end end

View file

@ -0,0 +1,29 @@
module Api
module V2
class ApplicationSerializer < ActiveModel::Serializer
def self.embeddable
{}
end
def embeds
@embeds ||= (scope[:embeds] || []).select { |e| self.class.embeddable.keys.include?(e) }
end
def self.embed_dat
embeddable.each_pair do |key, opts|
attr = opts.delete(:attr) || key
if attr.to_s.pluralize == attr.to_s
attribute "#{attr.to_s.singularize}_ids".to_sym, opts.merge(unless: -> { embeds.include?(key) }) do
object.send(attr).map(&:id)
end
has_many attr, opts.merge(if: -> { embeds.include?(key) })
else
id_opts = opts.merge(key: "#{key}_id")
attribute "#{attr}_id".to_sym, id_opts.merge(unless: -> { embeds.include?(key) })
attribute key, opts.merge(if: -> { embeds.include?(key) })
end
end
end
end
end
end

View file

@ -0,0 +1,18 @@
module Api
module V2
class EventSerializer < ApplicationSerializer
attributes :id, :sequence_id, :kind, :map_id, :created_at
has_one :actor, serializer: UserSerializer, root: 'users'
has_one :map, serializer: MapSerializer
def actor
object.user || object.eventable.try(:user)
end
def map
object.eventable.try(:map) || object.eventable.map
end
end
end
end

View file

@ -0,0 +1,28 @@
module Api
module V2
class MapSerializer < ApplicationSerializer
attributes :id,
:name,
:desc,
:permission,
:screenshot,
:created_at,
:updated_at
def self.embeddable
{
user: {},
topics: {},
synapses: {},
mappings: {},
contributors: { serializer: UserSerializer },
collaborators: { serializer: UserSerializer }
}
end
self.class_eval do
embed_dat
end
end
end
end

View file

@ -0,0 +1,25 @@
module Api
module V2
class MappingSerializer < ApplicationSerializer
attributes :id,
:created_at,
:updated_at,
:mappable_id,
:mappable_type
attribute :xloc, if: -> { object.mappable_type == 'Topic' }
attribute :yloc, if: -> { object.mappable_type == 'Topic' }
def self.embeddable
{
user: {},
map: {}
}
end
self.class_eval do
embed_dat
end
end
end
end

View file

@ -0,0 +1,11 @@
module Api
module V2
class MetacodeSerializer < ApplicationSerializer
attributes :id,
:name,
:manual_icon,
:color,
:aws_icon
end
end
end

View file

@ -0,0 +1,24 @@
module Api
module V2
class SynapseSerializer < ApplicationSerializer
attributes :id,
:desc,
:category,
:permission,
:created_at,
:updated_at
def self.embeddable
{
topic1: { attr: :node1, serializer: TopicSerializer },
topic2: { attr: :node2, serializer: TopicSerializer },
user: {}
}
end
self.class_eval do
embed_dat
end
end
end
end

View file

@ -0,0 +1,10 @@
module Api
module V2
class TokenSerializer < ApplicationSerializer
attributes :id,
:token,
:description,
:created_at
end
end
end

View file

@ -0,0 +1,24 @@
module Api
module V2
class TopicSerializer < ApplicationSerializer
attributes :id,
:name,
:desc,
:link,
:permission,
:created_at,
:updated_at
def self.embeddable
{
user: {},
metacode: {}
}
end
self.class_eval do
embed_dat
end
end
end
end

View file

@ -0,0 +1,19 @@
module Api
module V2
class UserSerializer < ApplicationSerializer
attributes :id,
:name,
:avatar,
:is_admin,
:generation
def avatar
object.image.url(:sixtyfour)
end
def is_admin
object.admin
end
end
end
end

View file

@ -0,0 +1,7 @@
module Api
module V2
class WebhookSerializer < ApplicationSerializer
attributes :text, :username, :icon_url # , :attachments
end
end
end

View file

@ -1,15 +0,0 @@
class EventSerializer < ActiveModel::Serializer
embed :ids, include: true
attributes :id, :sequence_id, :kind, :map_id, :created_at
has_one :actor, serializer: NewUserSerializer, root: 'users'
has_one :map, serializer: NewMapSerializer
def actor
object.user || object.eventable.try(:user)
end
def map
object.eventable.try(:map) || object.eventable.map
end
end

View file

@ -1,16 +0,0 @@
class NewMapSerializer < ActiveModel::Serializer
embed :ids, include: true
attributes :id,
:name,
:desc,
:permission,
:screenshot,
:created_at,
:updated_at
has_many :topics, serializer: NewTopicSerializer
has_many :synapses, serializer: NewSynapseSerializer
has_many :mappings, serializer: NewMappingSerializer
has_many :contributors, root: :users, serializer: NewUserSerializer
has_many :collaborators, root: :users, serializer: NewUserSerializer
end

View file

@ -1,19 +0,0 @@
class NewMappingSerializer < ActiveModel::Serializer
embed :ids, include: true
attributes :id,
:xloc,
:yloc,
:created_at,
:updated_at,
:mappable_id,
:mappable_type
has_one :user, serializer: NewUserSerializer
has_one :map, serializer: NewMapSerializer
def filter(keys)
keys.delete(:xloc) unless object.mappable_type == 'Topic'
keys.delete(:yloc) unless object.mappable_type == 'Topic'
keys
end
end

View file

@ -1,7 +0,0 @@
class NewMetacodeSerializer < ActiveModel::Serializer
attributes :id,
:name,
:manual_icon,
:color,
:aws_icon
end

View file

@ -1,14 +0,0 @@
class NewSynapseSerializer < ActiveModel::Serializer
embed :ids, include: true
attributes :id,
:desc,
:category,
:weight,
:permission,
:created_at,
:updated_at
has_one :topic1, root: :topics, serializer: NewTopicSerializer
has_one :topic2, root: :topics, serializer: NewTopicSerializer
has_one :user, serializer: NewUserSerializer
end

View file

@ -1,13 +0,0 @@
class NewTopicSerializer < ActiveModel::Serializer
embed :ids, include: true
attributes :id,
:name,
:desc,
:link,
:permission,
:created_at,
:updated_at
has_one :user, serializer: NewUserSerializer
has_one :metacode, serializer: NewMetacodeSerializer
end

View file

@ -1,15 +0,0 @@
class NewUserSerializer < ActiveModel::Serializer
attributes :id,
:name,
:avatar,
:is_admin,
:generation
def avatar
object.image.url(:sixtyfour)
end
def is_admin
object.admin
end
end

View file

@ -1,7 +0,0 @@
class TokenSerializer < ActiveModel::Serializer
attributes :id,
:token,
:description,
:created_at,
:updated_at
end

View file

@ -1,3 +0,0 @@
class WebhookSerializer < ActiveModel::Serializer
attributes :text, :username, :icon_url # , :attachments
end

View file

@ -1,4 +1,4 @@
require File.expand_path('../boot', __FILE__) require_relative 'boot'
require 'csv' require 'csv'
require 'rails/all' require 'rails/all'
@ -15,21 +15,6 @@ module Metamaps
# Custom directories with classes and modules you want to be autoloadable. # Custom directories with classes and modules you want to be autoloadable.
config.autoload_paths << Rails.root.join('app', 'services') config.autoload_paths << Rails.root.join('app', 'services')
# Only load the plugins named here, in the order given (default is alphabetical).
# :all can be used as a placeholder for all plugins not explicitly named.
# config.plugins = [ :exception_notification, :ssl_requirement, :all ]
# Activate observers that should always be running.
# config.active_record.observers = :cacher, :garbage_collector, :forum_observer
# 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)'
# 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]
# config.i18n.default_locale = :de
# Configure the default encoding used in templates for Ruby 1.9. # Configure the default encoding used in templates for Ruby 1.9.
config.encoding = 'utf-8' config.encoding = 'utf-8'
@ -43,11 +28,6 @@ module Metamaps
# Configure sensitive parameters which will be filtered from the log file. # Configure sensitive parameters which will be filtered from the log file.
config.filter_parameters += [:password] config.filter_parameters += [:password]
# Use SQL instead of Active Record's schema dumper when creating the database.
# This is necessary if your schema can't be completely dumped by the schema dumper,
# like if you have constraints or database-specific column types
# config.active_record.schema_format = :sql
# Enable the asset pipeline # Enable the asset pipeline
config.assets.initialize_on_precompile = false config.assets.initialize_on_precompile = false
@ -57,7 +37,6 @@ module Metamaps
config.generators do |g| config.generators do |g|
g.test_framework :rspec g.test_framework :rspec
end end
config.active_record.raise_in_transactional_callbacks = true
# pundit errors return 403 FORBIDDEN # pundit errors return 403 FORBIDDEN
config.action_dispatch.rescue_responses['Pundit::NotAuthorizedError'] = :forbidden config.action_dispatch.rescue_responses['Pundit::NotAuthorizedError'] = :forbidden

View file

@ -1,5 +1,6 @@
require 'rubygems' require 'rubygems'
require 'rails/commands/server' require 'rails/commands/server'
module Rails module Rails
class Server class Server
def default_options def default_options
@ -9,6 +10,6 @@ module Rails
end end
# Set up gems listed in the Gemfile. # Set up gems listed in the Gemfile.
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE']) require 'bundler/setup'

9
config/cable.yml Normal file
View file

@ -0,0 +1,9 @@
development:
adapter: async
test:
adapter: async
production:
adapter: redis
url: redis://localhost:6379/1

View file

@ -1,5 +1,5 @@
# Load the rails application # Load the Rails application.
require File.expand_path('../application', __FILE__) require_relative 'application'
# Initialize the rails application # Initialize the Rails application.
Metamaps::Application.initialize! Rails.application.initialize!

View file

@ -1,9 +1,8 @@
Metamaps::Application.configure do Rails.application.configure do
# Settings specified here will take precedence over those in config/application.rb # Settings specified here will take precedence over those in config/application.rb
config.log_level = :warn config.log_level = :warn
config.eager_load = true config.eager_load = true
config.assets.js_compressor = :uglifier
# Code is not reloaded between requests # Code is not reloaded between requests
config.cache_classes = true config.cache_classes = true
@ -13,12 +12,12 @@ Metamaps::Application.configure do
config.action_controller.perform_caching = true config.action_controller.perform_caching = true
# Disable Rails's static asset server (Apache or nginx will already do this) # Disable Rails's static asset server (Apache or nginx will already do this)
config.serve_static_files = true config.public_file_server.enabled = false
# Don't fallback to assets pipeline if a precompiled asset is missed
config.assets.compile = false config.assets.compile = false
# Compress JavaScripts and CSS config.assets.js_compressor = :uglifier
config.assets.compress = true
# S3 file storage # S3 file storage
config.paperclip_defaults = { config.paperclip_defaults = {
@ -37,7 +36,6 @@ Metamaps::Application.configure do
port: ENV['SMTP_PORT'], port: ENV['SMTP_PORT'],
user_name: ENV['SMTP_USERNAME'], user_name: ENV['SMTP_USERNAME'],
password: ENV['SMTP_PASSWORD'], password: ENV['SMTP_PASSWORD'],
# domain: ENV['SMTP_DOMAIN']
authentication: 'plain', authentication: 'plain',
enable_starttls_auto: true, enable_starttls_auto: true,
openssl_verify_mode: 'none' openssl_verify_mode: 'none'
@ -46,54 +44,13 @@ Metamaps::Application.configure do
# Don't care if the mailer can't send # Don't care if the mailer can't send
config.action_mailer.raise_delivery_errors = true config.action_mailer.raise_delivery_errors = true
# Don't fallback to assets pipeline if a precompiled asset is missed
config.assets.compile = false
# Generate digests for assets URLs # Generate digests for assets URLs
config.assets.digest = true config.assets.digest = true
# Defaults to Rails.root.join("public/assets")
# config.assets.manifest = YOUR_PATH
# Specifies the header that your server uses for sending files
# config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache
# config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx
# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
# config.force_ssl = true
# See everything in the log (default is :info)
# config.log_level = :debug
# Prepend all log lines with the following tags
# config.log_tags = [ :subdomain, :uuid ]
# Use a different logger for distributed setups
# config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new)
# Use a different cache store in production
# config.cache_store = :mem_cache_store
# Enable serving of images, stylesheets, and JavaScripts from an asset server
# config.action_controller.asset_host = "http://assets.example.com"
# Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added)
# config.assets.precompile += %w( )
# Disable delivery errors, bad email addresses will be ignored
# config.action_mailer.raise_delivery_errors = false
# Enable threaded mode
# config.threadsafe!
# Enable locale fallbacks for I18n (makes lookups for any locale fall back to # Enable locale fallbacks for I18n (makes lookups for any locale fall back to
# the I18n.default_locale when a translation can not be found) # the I18n.default_locale when a translation can not be found)
config.i18n.fallbacks = true config.i18n.fallbacks = true
# Send deprecation notices to registered listeners # Send deprecation notices to registered listeners
config.active_support.deprecation = :notify config.active_support.deprecation = :notify
# Log the query plan for queries taking more than this (works
# with SQLite, MySQL, and PostgreSQL)
# config.active_record.auto_explain_threshold_in_seconds = 0.5
end end

View file

@ -10,8 +10,10 @@ Metamaps::Application.configure do
config.cache_classes = true config.cache_classes = true
# Configure static asset server for tests with Cache-Control for performance # Configure static asset server for tests with Cache-Control for performance
config.serve_static_files = true config.public_file_server.enabled = true
config.static_cache_control = 'public, max-age=3600' config.public_file_server.headers = {
'Cache-Control' => 'public, max-age=3600'
}
# Show full error reports and disable caching # Show full error reports and disable caching
config.consider_all_requests_local = true config.consider_all_requests_local = true

View file

@ -1,4 +1,4 @@
$codes = [] $codes = []
if ActiveRecord::Base.connection.table_exists? 'users' if ActiveRecord::Base.connection.data_source_exists? 'users'
$codes = ActiveRecord::Base.connection.execute('SELECT code FROM users').map { |user| user['code'] } $codes = ActiveRecord::Base.connection.execute('SELECT code FROM users').map { |user| user['code'] }
end end

View file

@ -0,0 +1 @@
ActiveModelSerializers.config.adapter = :json

View file

@ -0,0 +1,6 @@
# Be sure to restart your server when you modify this file.
# ApplicationController.renderer.defaults.merge!(
# http_host: 'example.org',
# https: false
# )

View file

@ -1 +1,12 @@
# Be sure to restart your server when you modify this file.
# Version of your assets, change this if you want to expire all your assets.
Rails.application.config.assets.version = '2.0'
Rails.application.config.assets.quiet = true
# Add additional assets to the asset load path
# Rails.application.config.assets.paths << Emoji.images_path
# Precompile additional assets.
# application.js, application.css, and all non-JS/CSS in app/assets folder are already added.
Rails.application.config.assets.precompile += %w( webpacked/metamaps.bundle.js ) Rails.application.config.assets.precompile += %w( webpacked/metamaps.bundle.js )

View file

@ -0,0 +1,5 @@
# Be sure to restart your server when you modify this file.
# Specify a serializer for the signed and encrypted cookie jars.
# Valid options are :json, :marshal, and :hybrid.
Rails.application.config.action_dispatch.cookies_serializer = :hybrid

View file

@ -0,0 +1,4 @@
# Be sure to restart your server when you modify this file.
# Configure sensitive parameters which will be filtered from the log file.
Rails.application.config.filter_parameters += [:password]

View file

@ -1,15 +1,16 @@
# Be sure to restart your server when you modify this file. # Be sure to restart your server when you modify this file.
# Add new inflection rules using the following format # Add new inflection rules using the following format. Inflections
# (all these examples are active by default): # are locale specific, and you may define rules for as many different
# ActiveSupport::Inflector.inflections do |inflect| # locales as you wish. All of these examples are active by default:
# ActiveSupport::Inflector.inflections(:en) do |inflect|
# inflect.plural /^(ox)$/i, '\1en' # inflect.plural /^(ox)$/i, '\1en'
# inflect.singular /^(ox)en/i, '\1' # inflect.singular /^(ox)en/i, '\1'
# inflect.irregular 'person', 'people' # inflect.irregular 'person', 'people'
# inflect.uncountable %w( fish sheep ) # inflect.uncountable %w( fish sheep )
# end # end
#
# These inflection rules are supported but not enabled by default: # These inflection rules are supported but not enabled by default:
# ActiveSupport::Inflector.inflections do |inflect| # ActiveSupport::Inflector.inflections(:en) do |inflect|
# inflect.acronym 'RESTful' # inflect.acronym 'RESTful'
# end # end

View file

@ -0,0 +1,10 @@
Kaminari.configure do |config|
# config.default_per_page = 25
# config.max_per_page = nil
# config.window = 4
# config.outer_window = 0
# config.left = 0
# config.right = 0
# config.page_method_name = :page
# config.param_name = :page
end

View file

@ -2,6 +2,5 @@
# Add new mime types for use in respond_to blocks: # Add new mime types for use in respond_to blocks:
# Mime::Type.register "text/richtext", :rtf # Mime::Type.register "text/richtext", :rtf
# Mime::Type.register_alias "text/html", :iphone
Mime::Type.register 'application/xls', :xls Mime::Type.register 'application/xls', :xls

View file

@ -0,0 +1,24 @@
# Be sure to restart your server when you modify this file.
#
# This file contains migration options to ease your Rails 5.0 upgrade.
#
# Read the Rails 5.0 release notes for more info on each option.
# Enable per-form CSRF tokens. Previous versions had false.
Rails.application.config.action_controller.per_form_csrf_tokens = true
# Enable origin-checking CSRF mitigation. Previous versions had false.
Rails.application.config.action_controller.forgery_protection_origin_check = true
# Make Ruby 2.4 preserve the timezone of the receiver when calling `to_time`.
# Previous versions had false.
ActiveSupport.to_time_preserves_timezone = true
# Require `belongs_to` associations by default. Previous versions had false.
Rails.application.config.active_record.belongs_to_required_by_default = true
# Do not halt callback chains when a callback returns false. Previous versions had true.
ActiveSupport.halt_callback_chains_on_return_false = false
# Configure SSL options to enable HSTS with subdomains. Previous versions had false.
Rails.application.config.ssl_options = { hsts: { subdomains: true } }

View file

@ -4,4 +4,4 @@
# If you change this key, all old signed cookies will become invalid! # If you change this key, all old signed cookies will become invalid!
# Make sure the secret is at least 30 characters and all random, # Make sure the secret is at least 30 characters and all random,
# no regular words or you'll be exposed to dictionary attacks. # no regular words or you'll be exposed to dictionary attacks.
Metamaps::Application.config.secret_key_base = ENV['SECRET_KEY_BASE'] Rails.application.config.secret_key_base = ENV['SECRET_KEY_BASE']

View file

@ -1,8 +1,8 @@
# Be sure to restart your server when you modify this file. # Be sure to restart your server when you modify this file.
Metamaps::Application.config.session_store :cookie_store, key: '_Metamaps_session' Rails.application.config.session_store :cookie_store, key: '_Metamaps_session'
# Use the database for sessions instead of the cookie-based default, # Use the database for sessions instead of the cookie-based default,
# which shouldn't be used to store highly confidential information # which shouldn't be used to store highly confidential information
# (create the session table with "rails generate session_migration") # (create the session table with "rails generate session_migration")
# Metamaps::Application.config.session_store :active_record_store # Rails.application.config.session_store :active_record_store

View file

@ -8,7 +8,7 @@ ActiveSupport.on_load(:action_controller) do
wrap_parameters format: [:json] wrap_parameters format: [:json]
end end
# Disable root element in JSON by default. # To enable root element in JSON for ActiveRecord objects.
ActiveSupport.on_load(:active_record) do # ActiveSupport.on_load(:active_record) do
self.include_root_in_json = false # self.include_root_in_json = true
end # end

47
config/puma.rb Normal file
View file

@ -0,0 +1,47 @@
# Puma can serve each request in a thread from an internal thread pool.
# The `threads` method setting takes two numbers a minimum and maximum.
# Any libraries that use thread pools should be configured to match
# the maximum value specified for Puma. Default is set to 5 threads for minimum
# and maximum, this matches the default thread size of Active Record.
#
threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }.to_i
threads threads_count, threads_count
# Specifies the `port` that Puma will listen on to receive requests, default is 3000.
#
port ENV.fetch("PORT") { 3000 }
# Specifies the `environment` that Puma will run in.
#
environment ENV.fetch("RAILS_ENV") { "development" }
# Specifies the number of `workers` to boot in clustered mode.
# Workers are forked webserver processes. If using threads and workers together
# the concurrency of the application would be max `threads` * `workers`.
# Workers do not work on JRuby or Windows (both of which do not support
# processes).
#
# workers ENV.fetch("WEB_CONCURRENCY") { 2 }
# Use the `preload_app!` method when specifying a `workers` number.
# This directive tells Puma to first boot the application and load code
# before forking the application. This takes advantage of Copy On Write
# process behavior so workers use less memory. If you use this option
# you need to make sure to reconnect any threads in the `on_worker_boot`
# block.
#
# preload_app!
# The code in the `on_worker_boot` will be called if you are using
# clustered mode by specifying a number of `workers`. After each worker
# process is booted this block will be run, if you are using `preload_app!`
# option you will want to use this block to reconnect to any threads
# or connections that may have been created at application boot, Ruby
# cannot share connections between processes.
#
# on_worker_boot do
# ActiveRecord::Base.establish_connection if defined?(ActiveRecord)
# end
# Allow puma to be restarted by `rails restart` command.
plugin :tmp_restart

View file

@ -9,13 +9,26 @@ Metamaps::Application.routes.draw do
get 'search/mappers', to: 'main#searchmappers', as: :searchmappers get 'search/mappers', to: 'main#searchmappers', as: :searchmappers
get 'search/synapses', to: 'main#searchsynapses', as: :searchsynapses get 'search/synapses', to: 'main#searchsynapses', as: :searchsynapses
namespace :api, path: '/api/v1', defaults: { format: :json } do namespace :api, path: '/api', default: { format: :json } do
resources :maps, only: [:create, :show, :update, :destroy] namespace :v2, path: '/v2' do
resources :synapses, only: [:create, :show, :update, :destroy] resources :maps, only: [:index, :create, :show, :update, :destroy]
resources :topics, only: [:create, :show, :update, :destroy] resources :synapses, only: [:index, :create, :show, :update, :destroy]
resources :mappings, only: [:create, :show, :update, :destroy] resources :topics, only: [:index, :create, :show, :update, :destroy]
resources :tokens, only: [:create, :destroy] do resources :mappings, only: [:index, :create, :show, :update, :destroy]
get :my_tokens, on: :collection resources :tokens, only: [:create, :destroy] do
get :my_tokens, on: :collection
end
end
namespace :v1, path: '/v1' do
# api v1 routes all lead to a deprecation error method
# see app/controllers/api/v1/deprecated_controller.rb
resources :maps, only: [:create, :show, :update, :destroy]
resources :synapses, only: [:create, :show, :update, :destroy]
resources :topics, only: [:create, :show, :update, :destroy]
resources :mappings, only: [:create, :show, :update, :destroy]
resources :tokens, only: [:create, :destroy] do
get :my_tokens, on: :collection
end
end end
end end

7
config/spring.rb Normal file
View file

@ -0,0 +1,7 @@
%w(
.ruby-version
.ruby-gemset
.rbenv-vars
tmp/restart.txt
tmp/caching-dev.txt
).each { |path| Spring.watch(path) }

View file

@ -1,4 +1,3 @@
# encoding: UTF-8
# This file is auto-generated from the current state of the database. Instead # This file is auto-generated from the current state of the database. Instead
# of editing this file, please use the migrations feature of Active Record to # of editing this file, please use the migrations feature of Active Record to
# incrementally modify your database, and then regenerate this schema definition. # incrementally modify your database, and then regenerate this schema definition.
@ -28,10 +27,9 @@ ActiveRecord::Schema.define(version: 20160820231717) do
t.string "queue" t.string "queue"
t.datetime "created_at" t.datetime "created_at"
t.datetime "updated_at" t.datetime "updated_at"
t.index ["priority", "run_at"], name: "delayed_jobs_priority", using: :btree
end end
add_index "delayed_jobs", ["priority", "run_at"], name: "delayed_jobs_priority", using: :btree
create_table "events", force: :cascade do |t| create_table "events", force: :cascade do |t|
t.string "kind", limit: 255 t.string "kind", limit: 255
t.integer "eventable_id" t.integer "eventable_id"
@ -41,24 +39,22 @@ ActiveRecord::Schema.define(version: 20160820231717) do
t.integer "sequence_id" t.integer "sequence_id"
t.datetime "created_at" t.datetime "created_at"
t.datetime "updated_at" t.datetime "updated_at"
t.index ["eventable_type", "eventable_id"], name: "index_events_on_eventable_type_and_eventable_id", using: :btree
t.index ["map_id", "sequence_id"], name: "index_events_on_map_id_and_sequence_id", unique: true, using: :btree
t.index ["map_id"], name: "index_events_on_map_id", using: :btree
t.index ["sequence_id"], name: "index_events_on_sequence_id", using: :btree
t.index ["user_id"], name: "index_events_on_user_id", using: :btree
end end
add_index "events", ["eventable_type", "eventable_id"], name: "index_events_on_eventable_type_and_eventable_id", using: :btree
add_index "events", ["map_id", "sequence_id"], name: "index_events_on_map_id_and_sequence_id", unique: true, using: :btree
add_index "events", ["map_id"], name: "index_events_on_map_id", using: :btree
add_index "events", ["sequence_id"], name: "index_events_on_sequence_id", using: :btree
add_index "events", ["user_id"], name: "index_events_on_user_id", using: :btree
create_table "in_metacode_sets", force: :cascade do |t| create_table "in_metacode_sets", force: :cascade do |t|
t.integer "metacode_id" t.integer "metacode_id"
t.integer "metacode_set_id" t.integer "metacode_set_id"
t.datetime "created_at", null: false t.datetime "created_at", null: false
t.datetime "updated_at", null: false t.datetime "updated_at", null: false
t.index ["metacode_id"], name: "index_in_metacode_sets_on_metacode_id", using: :btree
t.index ["metacode_set_id"], name: "index_in_metacode_sets_on_metacode_set_id", using: :btree
end end
add_index "in_metacode_sets", ["metacode_id"], name: "index_in_metacode_sets_on_metacode_id", using: :btree
add_index "in_metacode_sets", ["metacode_set_id"], name: "index_in_metacode_sets_on_metacode_set_id", using: :btree
create_table "mappings", force: :cascade do |t| create_table "mappings", force: :cascade do |t|
t.text "category" t.text "category"
t.integer "xloc" t.integer "xloc"
@ -71,14 +67,13 @@ ActiveRecord::Schema.define(version: 20160820231717) do
t.datetime "updated_at", null: false t.datetime "updated_at", null: false
t.integer "mappable_id" t.integer "mappable_id"
t.string "mappable_type" t.string "mappable_type"
t.index ["map_id", "synapse_id"], name: "index_mappings_on_map_id_and_synapse_id", using: :btree
t.index ["map_id", "topic_id"], name: "index_mappings_on_map_id_and_topic_id", using: :btree
t.index ["map_id"], name: "index_mappings_on_map_id", using: :btree
t.index ["mappable_id", "mappable_type"], name: "index_mappings_on_mappable_id_and_mappable_type", using: :btree
t.index ["user_id"], name: "index_mappings_on_user_id", using: :btree
end end
add_index "mappings", ["map_id", "synapse_id"], name: "index_mappings_on_map_id_and_synapse_id", using: :btree
add_index "mappings", ["map_id", "topic_id"], name: "index_mappings_on_map_id_and_topic_id", using: :btree
add_index "mappings", ["map_id"], name: "index_mappings_on_map_id", using: :btree
add_index "mappings", ["mappable_id", "mappable_type"], name: "index_mappings_on_mappable_id_and_mappable_type", using: :btree
add_index "mappings", ["user_id"], name: "index_mappings_on_user_id", using: :btree
create_table "maps", force: :cascade do |t| create_table "maps", force: :cascade do |t|
t.text "name" t.text "name"
t.boolean "arranged" t.boolean "arranged"
@ -92,10 +87,9 @@ ActiveRecord::Schema.define(version: 20160820231717) do
t.string "screenshot_content_type" t.string "screenshot_content_type"
t.integer "screenshot_file_size" t.integer "screenshot_file_size"
t.datetime "screenshot_updated_at" t.datetime "screenshot_updated_at"
t.index ["user_id"], name: "index_maps_on_user_id", using: :btree
end end
add_index "maps", ["user_id"], name: "index_maps_on_user_id", using: :btree
create_table "messages", force: :cascade do |t| create_table "messages", force: :cascade do |t|
t.text "message" t.text "message"
t.integer "user_id" t.integer "user_id"
@ -103,12 +97,11 @@ ActiveRecord::Schema.define(version: 20160820231717) do
t.string "resource_type" t.string "resource_type"
t.datetime "created_at" t.datetime "created_at"
t.datetime "updated_at" t.datetime "updated_at"
t.index ["resource_id"], name: "index_messages_on_resource_id", using: :btree
t.index ["resource_type"], name: "index_messages_on_resource_type", using: :btree
t.index ["user_id"], name: "index_messages_on_user_id", using: :btree
end end
add_index "messages", ["resource_id"], name: "index_messages_on_resource_id", using: :btree
add_index "messages", ["resource_type"], name: "index_messages_on_resource_type", using: :btree
add_index "messages", ["user_id"], name: "index_messages_on_user_id", using: :btree
create_table "metacode_sets", force: :cascade do |t| create_table "metacode_sets", force: :cascade do |t|
t.string "name" t.string "name"
t.text "desc" t.text "desc"
@ -116,10 +109,9 @@ ActiveRecord::Schema.define(version: 20160820231717) do
t.boolean "mapperContributed" t.boolean "mapperContributed"
t.datetime "created_at", null: false t.datetime "created_at", null: false
t.datetime "updated_at", null: false t.datetime "updated_at", null: false
t.index ["user_id"], name: "index_metacode_sets_on_user_id", using: :btree
end end
add_index "metacode_sets", ["user_id"], name: "index_metacode_sets_on_user_id", using: :btree
create_table "metacodes", force: :cascade do |t| create_table "metacodes", force: :cascade do |t|
t.text "name" t.text "name"
t.string "manual_icon" t.string "manual_icon"
@ -141,10 +133,9 @@ ActiveRecord::Schema.define(version: 20160820231717) do
t.datetime "created_at", null: false t.datetime "created_at", null: false
t.datetime "revoked_at" t.datetime "revoked_at"
t.string "scopes" t.string "scopes"
t.index ["token"], name: "index_oauth_access_grants_on_token", unique: true, using: :btree
end end
add_index "oauth_access_grants", ["token"], name: "index_oauth_access_grants_on_token", unique: true, using: :btree
create_table "oauth_access_tokens", force: :cascade do |t| create_table "oauth_access_tokens", force: :cascade do |t|
t.integer "resource_owner_id" t.integer "resource_owner_id"
t.integer "application_id" t.integer "application_id"
@ -154,12 +145,11 @@ ActiveRecord::Schema.define(version: 20160820231717) do
t.datetime "revoked_at" t.datetime "revoked_at"
t.datetime "created_at", null: false t.datetime "created_at", null: false
t.string "scopes" t.string "scopes"
t.index ["refresh_token"], name: "index_oauth_access_tokens_on_refresh_token", unique: true, using: :btree
t.index ["resource_owner_id"], name: "index_oauth_access_tokens_on_resource_owner_id", using: :btree
t.index ["token"], name: "index_oauth_access_tokens_on_token", unique: true, using: :btree
end end
add_index "oauth_access_tokens", ["refresh_token"], name: "index_oauth_access_tokens_on_refresh_token", unique: true, using: :btree
add_index "oauth_access_tokens", ["resource_owner_id"], name: "index_oauth_access_tokens_on_resource_owner_id", using: :btree
add_index "oauth_access_tokens", ["token"], name: "index_oauth_access_tokens_on_token", unique: true, using: :btree
create_table "oauth_applications", force: :cascade do |t| create_table "oauth_applications", force: :cascade do |t|
t.string "name", null: false t.string "name", null: false
t.string "uid", null: false t.string "uid", null: false
@ -168,20 +158,18 @@ ActiveRecord::Schema.define(version: 20160820231717) do
t.string "scopes", default: "", null: false t.string "scopes", default: "", null: false
t.datetime "created_at" t.datetime "created_at"
t.datetime "updated_at" t.datetime "updated_at"
t.index ["uid"], name: "index_oauth_applications_on_uid", unique: true, using: :btree
end end
add_index "oauth_applications", ["uid"], name: "index_oauth_applications_on_uid", unique: true, using: :btree
create_table "stars", force: :cascade do |t| create_table "stars", force: :cascade do |t|
t.integer "user_id" t.integer "user_id"
t.integer "map_id" t.integer "map_id"
t.datetime "created_at" t.datetime "created_at"
t.datetime "updated_at" t.datetime "updated_at"
t.index ["map_id"], name: "index_stars_on_map_id", using: :btree
t.index ["user_id"], name: "index_stars_on_user_id", using: :btree
end end
add_index "stars", ["map_id"], name: "index_stars_on_map_id", using: :btree
add_index "stars", ["user_id"], name: "index_stars_on_user_id", using: :btree
create_table "synapses", force: :cascade do |t| create_table "synapses", force: :cascade do |t|
t.text "desc" t.text "desc"
t.text "category" t.text "category"
@ -193,24 +181,22 @@ ActiveRecord::Schema.define(version: 20160820231717) do
t.datetime "created_at", null: false t.datetime "created_at", null: false
t.datetime "updated_at", null: false t.datetime "updated_at", null: false
t.integer "defer_to_map_id" t.integer "defer_to_map_id"
t.index ["node1_id", "node1_id"], name: "index_synapses_on_node1_id_and_node1_id", using: :btree
t.index ["node1_id"], name: "index_synapses_on_node1_id", using: :btree
t.index ["node2_id", "node2_id"], name: "index_synapses_on_node2_id_and_node2_id", using: :btree
t.index ["node2_id"], name: "index_synapses_on_node2_id", using: :btree
t.index ["user_id"], name: "index_synapses_on_user_id", using: :btree
end end
add_index "synapses", ["node1_id", "node1_id"], name: "index_synapses_on_node1_id_and_node1_id", using: :btree
add_index "synapses", ["node1_id"], name: "index_synapses_on_node1_id", using: :btree
add_index "synapses", ["node2_id", "node2_id"], name: "index_synapses_on_node2_id_and_node2_id", using: :btree
add_index "synapses", ["node2_id"], name: "index_synapses_on_node2_id", using: :btree
add_index "synapses", ["user_id"], name: "index_synapses_on_user_id", using: :btree
create_table "tokens", force: :cascade do |t| create_table "tokens", force: :cascade do |t|
t.string "token" t.string "token"
t.string "description" t.string "description"
t.integer "user_id" t.integer "user_id"
t.datetime "created_at", null: false t.datetime "created_at", null: false
t.datetime "updated_at", null: false t.datetime "updated_at", null: false
t.index ["user_id"], name: "index_tokens_on_user_id", using: :btree
end end
add_index "tokens", ["user_id"], name: "index_tokens_on_user_id", using: :btree
create_table "topics", force: :cascade do |t| create_table "topics", force: :cascade do |t|
t.text "name" t.text "name"
t.text "desc" t.text "desc"
@ -229,21 +215,19 @@ ActiveRecord::Schema.define(version: 20160820231717) do
t.integer "audio_file_size" t.integer "audio_file_size"
t.datetime "audio_updated_at" t.datetime "audio_updated_at"
t.integer "defer_to_map_id" t.integer "defer_to_map_id"
t.index ["metacode_id"], name: "index_topics_on_metacode_id", using: :btree
t.index ["user_id"], name: "index_topics_on_user_id", using: :btree
end end
add_index "topics", ["metacode_id"], name: "index_topics_on_metacode_id", using: :btree
add_index "topics", ["user_id"], name: "index_topics_on_user_id", using: :btree
create_table "user_maps", force: :cascade do |t| create_table "user_maps", force: :cascade do |t|
t.integer "user_id" t.integer "user_id"
t.integer "map_id" t.integer "map_id"
t.datetime "created_at" t.datetime "created_at"
t.datetime "updated_at" t.datetime "updated_at"
t.index ["map_id"], name: "index_user_maps_on_map_id", using: :btree
t.index ["user_id"], name: "index_user_maps_on_user_id", using: :btree
end end
add_index "user_maps", ["map_id"], name: "index_user_maps_on_map_id", using: :btree
add_index "user_maps", ["user_id"], name: "index_user_maps_on_user_id", using: :btree
create_table "users", force: :cascade do |t| create_table "users", force: :cascade do |t|
t.string "name" t.string "name"
t.string "email" t.string "email"
@ -272,19 +256,17 @@ ActiveRecord::Schema.define(version: 20160820231717) do
t.integer "image_file_size" t.integer "image_file_size"
t.datetime "image_updated_at" t.datetime "image_updated_at"
t.integer "generation" t.integer "generation"
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true, using: :btree
end end
add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true, using: :btree
create_table "webhooks", force: :cascade do |t| create_table "webhooks", force: :cascade do |t|
t.integer "hookable_id" t.integer "hookable_id"
t.string "hookable_type" t.string "hookable_type"
t.string "kind", null: false t.string "kind", null: false
t.string "uri", null: false t.string "uri", null: false
t.text "event_types", default: [], array: true t.text "event_types", default: [], array: true
t.index ["hookable_type", "hookable_id"], name: "index_webhooks_on_hookable_type_and_hookable_id", using: :btree
end end
add_index "webhooks", ["hookable_type", "hookable_id"], name: "index_webhooks_on_hookable_type_and_hookable_id", using: :btree
add_foreign_key "tokens", "users" add_foreign_key "tokens", "users"
end end

39
doc/api/api.raml Normal file
View file

@ -0,0 +1,39 @@
#%RAML 1.0
---
title: Metamaps
version: v2
baseUri: http://metamaps.cc/api/v2
mediaType: application/json
securitySchemes:
- oauth_2_0:
description: |
OAuth 2.0 implementation
type: OAuth 2.0
settings:
authorizationUri: https://metamaps.cc/api/v2/oauth/authorize
accessTokenUri: https://metamaps.cc/api/v2/oauth/token
authorizationGrants: [ authorization_code, password, client_credentials, implicit, refresh_token ]
traits:
- pageable: !include traits/pageable.raml
- orderable: !include traits/orderable.raml
- searchable: !include traits/searchable.raml
schemas:
- topic: !include schemas/_topic.json
- synapse: !include schemas/_synapse.json
- map: !include schemas/_map.json
- mapping: !include schemas/_mapping.json
- token: !include schemas/_token.json
resourceTypes:
- base: !include resourceTypes/base.raml
- item: !include resourceTypes/item.raml
- collection: !include resourceTypes/collection.raml
/topics: !include apis/topics.raml
/synapses: !include apis/synapses.raml
/maps: !include apis/maps.raml
/mappings: !include apis/mappings.raml
/tokens: !include apis/tokens.raml

View file

@ -0,0 +1,68 @@
type: collection
get:
responses:
200:
body:
application/json:
example: !include ../examples/mappings.json
post:
body:
application/json:
properties:
mappable_id:
description: id of the topic/synapse to be mapped
mappable_type:
description: Topic or Synapse
map_id:
description: id of the map
xloc:
description: (for Topic mappings only) x location on the canvas
yloc:
description: (for Topic mappings only) y location on the canvas
responses:
201:
body:
application/json:
example: !include ../examples/mapping.json
/{id}:
type: item
get:
responses:
200:
body:
application/json:
example: !include ../examples/mapping.json
put:
body:
application/json:
properties:
mappable_id:
description: id of the topic/synapse to be mapped
mappable_type:
description: Topic or Synapse
map_id:
description: id of the map
responses:
200:
body:
application/json:
example: !include ../examples/mapping.json
patch:
body:
application/json:
properties:
mappable_id:
description: id of the topic/synapse to be mapped
mappable_type:
description: Topic or Synapse
map_id:
description: id of the map
responses:
200:
body:
application/json:
example: !include ../examples/mapping.json
delete:
responses:
204:
description: No content

82
doc/api/apis/maps.raml Normal file
View file

@ -0,0 +1,82 @@
type: collection
get:
responses:
200:
body:
application/json:
example: !include ../examples/maps.json
post:
body:
application/json:
properties:
name:
description: name
desc:
description: description
permission:
description: commons, public, or private
screenshot:
description: url to a screenshot of the map
contributor_ids:
description: the topic being linked from
collaborator_ids:
description: the topic being linked to
responses:
201:
body:
application/json:
example: !include ../examples/map.json
/{id}:
type: item
get:
responses:
200:
body:
application/json:
example: !include ../examples/map.json
put:
body:
application/json:
properties:
name:
description: name
desc:
description: description
permission:
description: commons, public, or private
screenshot:
description: url to a screenshot of the map
contributor_ids:
description: the topic being linked from
collaborator_ids:
description: the topic being linked to
responses:
200:
body:
application/json:
example: !include ../examples/map.json
patch:
body:
application/json:
properties:
name:
description: name
desc:
description: description
permission:
description: commons, public, or private
screenshot:
description: url to a screenshot of the map
contributor_ids:
description: the topic being linked from
collaborator_ids:
description: the topic being linked to
responses:
200:
body:
application/json:
example: !include ../examples/map.json
delete:
responses:
204:
description: No content

View file

@ -0,0 +1,82 @@
type: collection
get:
responses:
200:
body:
application/json:
example: !include ../examples/synapses.json
post:
body:
application/json:
properties:
desc:
description: name
category:
description: from to or both
permission:
description: commons, public, or private
topic1_id:
description: the topic being linked from
topic2_id:
description: the topic being linked to
user_id:
description: the creator of the topic
responses:
201:
body:
application/json:
example: !include ../examples/synapse.json
/{id}:
type: item
get:
responses:
200:
body:
application/json:
example: !include ../examples/synapse.json
put:
body:
application/json:
properties:
desc:
description: name
category:
description: from-to or both
permission:
description: commons, public, or private
topic1_id:
description: the topic being linked from
topic2_id:
description: the topic being linked to
user_id:
description: the creator of the topic
responses:
200:
body:
application/json:
example: !include ../examples/synapse.json
patch:
body:
application/json:
properties:
desc:
description: name
category:
description: from-to or both
permission:
description: commons, public, or private
topic1_id:
description: the topic being linked from
topic2_id:
description: the topic being linked to
user_id:
description: the creator of the topic
responses:
200:
body:
application/json:
example: !include ../examples/synapse.json
delete:
responses:
204:
description: No content

25
doc/api/apis/tokens.raml Normal file
View file

@ -0,0 +1,25 @@
type: collection
post:
body:
application/json:
properties:
description:
description: short string describing this token
responses:
201:
body:
application/json:
example: !include ../examples/token.json
/my_tokens:
get:
responses:
200:
body:
application/json:
example: !include ../examples/tokens.json
/{id}:
type: item
delete:
responses:
204:
description: No content

72
doc/api/apis/topics.raml Normal file
View file

@ -0,0 +1,72 @@
type: collection
get:
responses:
200:
body:
application/json:
example: !include ../examples/topics.json
post:
body:
application/json:
properties:
name:
description: name
desc:
description: description
link:
description: (optional) link to content on the web
permission:
description: commons, public, or private
metacode_id:
description: Topic's metacode
responses:
201:
body:
application/json:
example: !include ../examples/topic.json
/{id}:
type: item
get:
responses:
200:
body:
application/json:
example: !include ../examples/topic.json
put:
body:
application/json:
properties:
name:
description: name
desc:
description: description
link:
description: (optional) link to content on the web
permission:
description: commons, public, or private
responses:
200:
body:
application/json:
example: !include ../examples/topic.json
patch:
body:
application/json:
properties:
name:
description: name
desc:
description: description
link:
description: (optional) link to content on the web
permission:
description: commons, public, or private
responses:
200:
body:
application/json:
example: !include ../examples/topic.json
delete:
responses:
204:
description: No content

27
doc/api/examples/map.json Normal file
View file

@ -0,0 +1,27 @@
{
"data": {
"id": 2,
"name": "Emergent Network Phenomena",
"desc": "Example map for the API",
"permission": "commons",
"screenshot": "https://s3.amazonaws.com/metamaps-assets/site/missing-map.png",
"created_at": "2016-03-26T08:02:05.379Z",
"updated_at": "2016-03-27T07:20:18.047Z",
"topic_ids": [
58,
59
],
"synapse_ids": [
2
],
"mapping_ids": [
94,
95,
96
],
"collaborator_ids": [],
"contributor_ids": [
2
]
}
}

View file

@ -0,0 +1,11 @@
{
"data": {
"id": 4,
"created_at": "2016-03-25T08:44:21.337Z",
"updated_at": "2016-03-25T08:44:21.337Z",
"mappable_id": 1,
"mappable_type": "Synapse",
"user_id": 1,
"map_id": 1
}
}

View file

@ -0,0 +1,54 @@
{
"data": [
{
"created_at": "2016-03-25T08:44:07.152Z",
"id": 1,
"map_id": 1,
"mappable_id": 1,
"mappable_type": "Topic",
"updated_at": "2016-03-25T08:44:07.152Z",
"user_id": 1,
"xloc": -271,
"yloc": 22
},
{
"created_at": "2016-03-25T08:44:13.907Z",
"id": 2,
"map_id": 1,
"mappable_id": 2,
"mappable_type": "Topic",
"updated_at": "2016-03-25T08:44:13.907Z",
"user_id": 1,
"xloc": -12,
"yloc": 61
},
{
"created_at": "2016-03-25T08:44:19.333Z",
"id": 3,
"map_id": 1,
"mappable_id": 3,
"mappable_type": "Topic",
"updated_at": "2016-03-25T08:44:19.333Z",
"user_id": 1,
"xloc": -93,
"yloc": -90
},
{
"created_at": "2016-03-25T08:44:21.337Z",
"id": 4,
"map_id": 1,
"mappable_id": 1,
"mappable_type": "Synapse",
"updated_at": "2016-03-25T08:44:21.337Z",
"user_id": 1
}
],
"page": {
"current_page": 1,
"next_page": 2,
"per": 4,
"prev_page": 0,
"total_count": 303,
"total_pages": 76
}
}

View file

@ -0,0 +1,37 @@
{
"data": [
{
"id": 2,
"name": "Emergent Network Phenomena",
"desc": "Example map for the API",
"permission": "commons",
"screenshot": "https://s3.amazonaws.com/metamaps-assets/site/missing-map.png",
"created_at": "2016-03-26T08:02:05.379Z",
"updated_at": "2016-03-27T07:20:18.047Z",
"topic_ids": [
58,
59
],
"synapse_ids": [
2
],
"mapping_ids": [
94,
95,
96
],
"collaborator_ids": [],
"contributor_ids": [
2
]
}
],
"page": {
"current_page": 1,
"next_page": 2,
"prev_page": 0,
"total_pages": 5,
"total_count": 5,
"per": 1
}
}

View file

@ -0,0 +1,13 @@
{
"data": {
"id": 2,
"desc": "hello",
"category": "from-to",
"permission": "commons",
"created_at": "2016-03-26T08:02:17.994Z",
"updated_at": "2016-03-26T08:02:17.994Z",
"topic1_id": 5,
"topic2_id": 6,
"user_id": 2
}
}

View file

@ -0,0 +1,34 @@
{
"data": [
{
"id": 2,
"desc": "hello",
"category": "from-to",
"permission": "commons",
"created_at": "2016-03-26T08:02:17.994Z",
"updated_at": "2016-03-26T08:02:17.994Z",
"topic1_id": 1,
"topic2_id": 2,
"user_id": 2
},
{
"id": 6,
"desc": "nice",
"category": "both",
"permission": "public",
"created_at": "2016-03-26T08:05:31.563Z",
"updated_at": "2016-03-26T08:05:31.563Z",
"topic1_id": 2,
"topic2_id": 3,
"user_id": 2
}
],
"page": {
"current_page": 1,
"next_page": 2,
"prev_page": 0,
"total_pages": 71,
"total_count": 142,
"per": 2
}
}

View file

@ -0,0 +1,8 @@
{
"data": {
"id": 1,
"token": "VeI0qAe2bf2ytnrTRxmywsH0VSwuyjK5",
"description": "Personal token for in-browser testing",
"created_at": "2016-09-06T03:47:56.553Z"
}
}

View file

@ -0,0 +1,18 @@
{
"data": [
{
"id": 1,
"token": "VeI0qAe2bf2ytnrTRxmywsH0VSwuyjK5",
"description": "Personal token for in-browser testing",
"created_at": "2016-09-06T03:47:56.553Z"
}
],
"page": {
"current_page": 1,
"next_page": 0,
"prev_page": 0,
"total_pages": 1,
"total_count": 1,
"per": 25
}
}

Some files were not shown because too many files have changed in this diff Show more