diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..4655283 Binary files /dev/null and b/.DS_Store differ diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9b7ebd4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,20 @@ +# See https://help.github.com/articles/ignoring-files for more about ignoring files. +# +# If you find yourself ignoring temporary files generated by your text editor +# or operating system, you probably want to add a global ignore instead: +# git config --global core.excludesfile '~/.gitignore_global' + +# Ignore bundler config. +/.bundle + +# Ignore the default SQLite database. +/db/*.sqlite3 +/db/*.sqlite3-journal + +# Ignore all logfiles and tempfiles. +/log/* +!/log/.keep +/tmp + +coverage/* +.env 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/.ruby-gemset b/.ruby-gemset new file mode 100644 index 0000000..22f33b8 --- /dev/null +++ b/.ruby-gemset @@ -0,0 +1 @@ +seemore diff --git a/.ruby-version b/.ruby-version new file mode 100644 index 0000000..5859406 --- /dev/null +++ b/.ruby-version @@ -0,0 +1 @@ +2.2.3 diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..e20fa3b --- /dev/null +++ b/Gemfile @@ -0,0 +1,55 @@ +source 'https://rubygems.org' + + +gem 'rails', '4.2.5' +gem 'sass-rails', '~> 5.0' +gem 'uglifier', '>= 1.3.0' +gem 'coffee-rails', '~> 4.1.0' +gem 'jquery-rails' +gem 'turbolinks' +# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder +gem 'jbuilder', '~> 2.0' +# bundle exec rake doc:rails generates the API under doc/api. +gem 'sdoc', '~> 0.4.0', group: :doc + +# bootstrap for styling +gem 'bootstrap-sass' + +# Use ActiveModel has_secure_password +# gem 'bcrypt', '~> 3.1.7' + +gem 'omniauth' +gem 'omniauth-oauth2', '~> 1.3.1' +gem "omniauth-vimeo" +gem 'omniauth-twitter' + +gem 'httparty' +gem 'twitter' +gem 'will_paginate', '~> 3.0.5' + +group :development, :test do + gem 'byebug' + gem 'dotenv-rails' + gem 'sqlite3' + gem 'pry' + gem 'simplecov' +end + +group :production do + gem 'pg' + gem 'rails_12factor' +end + +group :test do + gem 'shoulda-matchers', '~> 3.0' + gem "factory_girl_rails", "~> 4.0" +end + +group :development do + gem 'httplog' + gem 'web-console', '~> 2.0' + gem 'spring' + gem 'better_errors' + gem 'binding_of_caller' + gem 'rspec-rails' +end diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 0000000..89fb524 --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,300 @@ +GEM + remote: https://rubygems.org/ + specs: + actionmailer (4.2.5) + actionpack (= 4.2.5) + actionview (= 4.2.5) + activejob (= 4.2.5) + mail (~> 2.5, >= 2.5.4) + rails-dom-testing (~> 1.0, >= 1.0.5) + actionpack (4.2.5) + actionview (= 4.2.5) + activesupport (= 4.2.5) + rack (~> 1.6) + rack-test (~> 0.6.2) + rails-dom-testing (~> 1.0, >= 1.0.5) + rails-html-sanitizer (~> 1.0, >= 1.0.2) + actionview (4.2.5) + activesupport (= 4.2.5) + builder (~> 3.1) + erubis (~> 2.7.0) + rails-dom-testing (~> 1.0, >= 1.0.5) + rails-html-sanitizer (~> 1.0, >= 1.0.2) + activejob (4.2.5) + activesupport (= 4.2.5) + globalid (>= 0.3.0) + activemodel (4.2.5) + activesupport (= 4.2.5) + builder (~> 3.1) + activerecord (4.2.5) + activemodel (= 4.2.5) + activesupport (= 4.2.5) + arel (~> 6.0) + activesupport (4.2.5) + i18n (~> 0.7) + json (~> 1.7, >= 1.7.7) + minitest (~> 5.1) + thread_safe (~> 0.3, >= 0.3.4) + tzinfo (~> 1.1) + addressable (2.4.0) + arel (6.0.3) + autoprefixer-rails (6.2.3) + execjs + json + better_errors (2.1.1) + coderay (>= 1.0.0) + erubis (>= 2.6.6) + rack (>= 0.9.0) + binding_of_caller (0.7.2) + debug_inspector (>= 0.0.1) + bootstrap-sass (3.3.6) + autoprefixer-rails (>= 5.2.1) + sass (>= 3.3.4) + buftok (0.2.0) + builder (3.2.2) + byebug (8.2.1) + coderay (1.1.0) + coffee-rails (4.1.1) + coffee-script (>= 2.2.0) + railties (>= 4.0.0, < 5.1.x) + coffee-script (2.4.1) + coffee-script-source + execjs + coffee-script-source (1.10.0) + concurrent-ruby (1.0.0) + debug_inspector (0.0.2) + diff-lcs (1.2.5) + docile (1.1.5) + domain_name (0.5.25) + unf (>= 0.0.5, < 1.0.0) + dotenv (2.0.2) + dotenv-rails (2.0.2) + dotenv (= 2.0.2) + railties (~> 4.0) + equalizer (0.0.10) + 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) + faraday (0.9.2) + multipart-post (>= 1.2, < 3) + globalid (0.3.6) + activesupport (>= 4.1.0) + hashie (3.4.3) + http (0.9.8) + addressable (~> 2.3) + http-cookie (~> 1.0) + http-form_data (~> 1.0.1) + http_parser.rb (~> 0.6.0) + http-cookie (1.0.2) + domain_name (~> 0.5) + http-form_data (1.0.1) + http_parser.rb (0.6.0) + httparty (0.13.7) + json (~> 1.8) + multi_xml (>= 0.5.2) + httplog (0.2.13) + i18n (0.7.0) + jbuilder (2.4.0) + activesupport (>= 3.0.0, < 5.1) + multi_json (~> 1.2) + jquery-rails (4.0.5) + rails-dom-testing (~> 1.0) + railties (>= 4.2.0) + thor (>= 0.14, < 2.0) + json (1.8.3) + jwt (1.5.2) + loofah (2.0.3) + nokogiri (>= 1.5.9) + mail (2.6.3) + mime-types (>= 1.16, < 3) + memoizable (0.4.2) + thread_safe (~> 0.3, >= 0.3.1) + method_source (0.8.2) + mime-types (2.99) + mini_portile2 (2.0.0) + minitest (5.8.3) + multi_json (1.11.2) + multi_xml (0.5.5) + multipart-post (2.0.0) + naught (1.1.0) + nokogiri (1.6.7.1) + mini_portile2 (~> 2.0.0.rc2) + oauth (0.4.7) + oauth2 (1.0.0) + faraday (>= 0.8, < 0.10) + jwt (~> 1.0) + multi_json (~> 1.3) + multi_xml (~> 0.5) + rack (~> 1.2) + omniauth (1.3.1) + hashie (>= 1.2, < 4) + rack (>= 1.0, < 3) + omniauth-oauth (1.1.0) + oauth + omniauth (~> 1.0) + omniauth-oauth2 (1.3.1) + oauth2 (~> 1.0) + omniauth (~> 1.2) + omniauth-twitter (1.2.1) + json (~> 1.3) + omniauth-oauth (~> 1.1) + omniauth-vimeo (2.0.0) + omniauth-oauth2 + pg (0.18.4) + pry (0.10.3) + coderay (~> 1.1.0) + method_source (~> 0.8.1) + slop (~> 3.4) + rack (1.6.4) + rack-test (0.6.3) + rack (>= 1.0) + rails (4.2.5) + actionmailer (= 4.2.5) + actionpack (= 4.2.5) + actionview (= 4.2.5) + activejob (= 4.2.5) + activemodel (= 4.2.5) + activerecord (= 4.2.5) + activesupport (= 4.2.5) + bundler (>= 1.3.0, < 2.0) + railties (= 4.2.5) + sprockets-rails + rails-deprecated_sanitizer (1.0.3) + activesupport (>= 4.2.0.alpha) + rails-dom-testing (1.0.7) + activesupport (>= 4.2.0.beta, < 5.0) + nokogiri (~> 1.6.0) + rails-deprecated_sanitizer (>= 1.0.1) + rails-html-sanitizer (1.0.2) + loofah (~> 2.0) + rails_12factor (0.0.3) + rails_serve_static_assets + rails_stdout_logging + rails_serve_static_assets (0.0.4) + rails_stdout_logging (0.0.4) + railties (4.2.5) + actionpack (= 4.2.5) + activesupport (= 4.2.5) + rake (>= 0.8.7) + thor (>= 0.18.1, < 2.0) + rake (10.4.2) + rdoc (4.2.1) + json (~> 1.4) + rspec-core (3.4.1) + rspec-support (~> 3.4.0) + rspec-expectations (3.4.0) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.4.0) + rspec-mocks (3.4.0) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.4.0) + rspec-rails (3.4.0) + actionpack (>= 3.0, < 4.3) + activesupport (>= 3.0, < 4.3) + railties (>= 3.0, < 4.3) + rspec-core (~> 3.4.0) + rspec-expectations (~> 3.4.0) + rspec-mocks (~> 3.4.0) + rspec-support (~> 3.4.0) + rspec-support (3.4.1) + sass (3.4.20) + sass-rails (5.0.4) + railties (>= 4.0.0, < 5.0) + sass (~> 3.1) + sprockets (>= 2.8, < 4.0) + sprockets-rails (>= 2.0, < 4.0) + tilt (>= 1.1, < 3) + sdoc (0.4.1) + json (~> 1.7, >= 1.7.7) + rdoc (~> 4.0) + shoulda-matchers (3.0.1) + activesupport (>= 4.0.0) + simple_oauth (0.3.1) + simplecov (0.11.1) + docile (~> 1.1.0) + json (~> 1.8) + simplecov-html (~> 0.10.0) + simplecov-html (0.10.0) + slop (3.6.0) + spring (1.6.1) + sprockets (3.5.2) + concurrent-ruby (~> 1.0) + rack (> 1, < 3) + sprockets-rails (3.0.0) + actionpack (>= 4.0) + activesupport (>= 4.0) + sprockets (>= 3.0.0) + sqlite3 (1.3.11) + thor (0.19.1) + thread_safe (0.3.5) + tilt (2.0.2) + turbolinks (2.5.3) + coffee-rails + twitter (5.15.0) + addressable (~> 2.3) + buftok (~> 0.2.0) + equalizer (= 0.0.10) + faraday (~> 0.9.0) + http (>= 0.4, < 0.10) + http_parser.rb (~> 0.6.0) + json (~> 1.8) + memoizable (~> 0.4.0) + naught (~> 1.0) + simple_oauth (~> 0.3.0) + tzinfo (1.2.2) + thread_safe (~> 0.1) + uglifier (2.7.2) + execjs (>= 0.3.0) + json (>= 1.8.0) + unf (0.1.4) + unf_ext + unf_ext (0.0.7.1) + web-console (2.2.1) + activemodel (>= 4.0) + binding_of_caller (>= 0.7.2) + railties (>= 4.0) + sprockets-rails (>= 2.0, < 4.0) + will_paginate (3.0.7) + +PLATFORMS + ruby + +DEPENDENCIES + better_errors + binding_of_caller + bootstrap-sass + byebug + coffee-rails (~> 4.1.0) + dotenv-rails + factory_girl_rails (~> 4.0) + httparty + httplog + jbuilder (~> 2.0) + jquery-rails + omniauth + omniauth-oauth2 (~> 1.3.1) + omniauth-twitter + omniauth-vimeo + pg + pry + rails (= 4.2.5) + rails_12factor + rspec-rails + sass-rails (~> 5.0) + sdoc (~> 0.4.0) + shoulda-matchers (~> 3.0) + simplecov + spring + sqlite3 + turbolinks + twitter + uglifier (>= 1.3.0) + web-console (~> 2.0) + will_paginate (~> 3.0.5) + +BUNDLED WITH + 1.11.2 diff --git a/README.rdoc b/README.rdoc new file mode 100644 index 0000000..dd4e97e --- /dev/null +++ b/README.rdoc @@ -0,0 +1,28 @@ +== README + +This README would normally document whatever steps are necessary to get the +application up and running. + +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. diff --git a/Rakefile b/Rakefile new file mode 100644 index 0000000..ba6b733 --- /dev/null +++ b/Rakefile @@ -0,0 +1,6 @@ +# Add your own tasks in files placed in lib/tasks ending in .rake, +# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. + +require File.expand_path('../config/application', __FILE__) + +Rails.application.load_tasks diff --git a/app/assets/images/.keep b/app/assets/images/.keep new file mode 100644 index 0000000..e69de29 diff --git a/app/assets/images/favicon.ico b/app/assets/images/favicon.ico new file mode 100644 index 0000000..79e54dc Binary files /dev/null and b/app/assets/images/favicon.ico differ diff --git a/app/assets/images/galaxy.jpeg b/app/assets/images/galaxy.jpeg new file mode 100644 index 0000000..af1667d Binary files /dev/null and b/app/assets/images/galaxy.jpeg differ diff --git a/app/assets/images/illuminapeye.jpg b/app/assets/images/illuminapeye.jpg new file mode 100644 index 0000000..b5036aa Binary files /dev/null and b/app/assets/images/illuminapeye.jpg differ diff --git a/app/assets/images/illuminapeye.png b/app/assets/images/illuminapeye.png new file mode 100644 index 0000000..9279497 Binary files /dev/null and b/app/assets/images/illuminapeye.png differ diff --git a/app/assets/images/illuminapeye_small.png b/app/assets/images/illuminapeye_small.png new file mode 100644 index 0000000..8ec105d Binary files /dev/null and b/app/assets/images/illuminapeye_small.png differ diff --git a/app/assets/images/illuminapeye_very_small.png b/app/assets/images/illuminapeye_very_small.png new file mode 100644 index 0000000..983884d Binary files /dev/null and b/app/assets/images/illuminapeye_very_small.png differ diff --git a/app/assets/images/noimage.png b/app/assets/images/noimage.png new file mode 100644 index 0000000..6e1ebff Binary files /dev/null and b/app/assets/images/noimage.png differ diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js new file mode 100644 index 0000000..7995227 --- /dev/null +++ b/app/assets/javascripts/application.js @@ -0,0 +1,42 @@ +// This is a manifest file that'll be compiled into application.js, which will include all the files +// listed below. +// +// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts, +// or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path. +// +// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the +// compiled file. +// +// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details +// about supported directives. +// +//= require jquery +//= require jquery_ujs +//= require_tree . +//= require bootstrap-sprockets + + +$(function(){ + $('#nav').affix({ + offset: { + top: $('header').height() + } + }); +}); + +/** + * Listen to scroll to change header opacity class + */ +function checkScroll(){ + var startY = $('.navbar').height(); //The point where the navbar changes in px + if($(window).scrollTop() > startY || $(window).width() < 768){ + $('.navbar').addClass("scrolled"); + } + else{ + $('.navbar').removeClass("scrolled"); + } +} +// +// $(window).on("scroll resize", function(){ +// checkScroll(); +// }); diff --git a/app/assets/javascripts/creators.coffee b/app/assets/javascripts/creators.coffee new file mode 100644 index 0000000..24f83d1 --- /dev/null +++ b/app/assets/javascripts/creators.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/javascripts/sessions.coffee b/app/assets/javascripts/sessions.coffee new file mode 100644 index 0000000..24f83d1 --- /dev/null +++ b/app/assets/javascripts/sessions.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/javascripts/users.coffee b/app/assets/javascripts/users.coffee new file mode 100644 index 0000000..24f83d1 --- /dev/null +++ b/app/assets/javascripts/users.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/application.css.scss b/app/assets/stylesheets/application.css.scss new file mode 100644 index 0000000..0830d45 --- /dev/null +++ b/app/assets/stylesheets/application.css.scss @@ -0,0 +1,366 @@ +/* + * This is a manifest file that'll be compiled into application.css, which will include all the files + * listed below. + * + * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets, + * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path. + * + * You're free to add application-wide styles to this file and they'll appear at the bottom of the + * compiled file so the styles you add here take precedence over styles defined in any styles + * defined in the other CSS/SCSS files in this directory. It is generally better to create a new + * file per style scope. + * + *= require_tree . + *= require_self + */ + @import "bootstrap-sprockets"; + @import "bootstrap"; + +#nav.affix { + position: fixed; + top: 0; + width: 100%; + z-index:10; +} + +.navbar.scrolled { + background: rgb(255, 255, 255); //IE + background: rgba(248, 248, 248, 0.9); //NON-IE + -webkit-transition: all 0.6s ease; + -moz-transition: all 0.6s ease; + -o-transition: all 0.6s ease; + -ms-transition: all 0.6s ease; + transition: all 0.6s ease; +} + +.nav-center { + margin:0; + float:none; +} + +.navbar-inner{ + text-align:center; +} + +.navbar { + position: relative; + background: #FFFFFF; + -webkit-transition: all 0.6s ease; + -moz-transition: all 0.6s ease; + -o-transition: all 0.6s ease; + -ms-transition: all 0.6s ease; + transition: all 0.6s ease; +} + +.navbar-right { + margin-right: 0px; +} + +.brand { + position: absolute; + left: 50%; + margin-left: -275px !important; /* 50% of your logo width */ + margin-top: -52px; + display: block; +} + +.jumbotron { + height: 200px; + background: #FFFFFF; + margin-bottom: 0px; +} + +.logo { + position: absolute; + left: 0px; + top: 24px; +} + +.main-content { + background: #000000; + background-image: image-url("galaxy.jpeg"); + background-size: cover; + background-attachment: fixed; +} + +.video { + text-align: center; + margin-bottom: 10px; + iframe { + border-left: 0px; + border-right: 0px; + margin-left: -25px; + } +} + +.row-centered { + text-align: center; + margin-left: 25px; +} + +.fm-row-centered { + text-align: center; +} + +@media (min-width: 1200px){ + .fm-row-centered { + margin-left: 90px; + } +} + +.c-search { + background-color: rgba(255, 255, 255, 0.9); + border-radius: 15px; + margin: 15px; + padding: 10px; + text-align: center; + display:inline-block; + width: 240px; + overflow: scroll; +} + +@media (min-width: 992px){ + .c-search { + height: 145px; + } +} + +.display-img { + border-radius: 50%; +} + +.form-control:focus { + border-color: #EDA83C; + box-shadow: 0px 1px 1px #EDA83C inset, 0px 0px 8px #EDA83C; +} + +:focus { + outline: 0 !important; + outline-color: #EDA83C; + border-color: #EDA83C; + box-shadow: 0px 1px 1px #EDA83C inset, 0px 0px 8px #EDA83C; +} + +a:focus { + outline-color: none; + border-color: #EDA83C; + box-shadow: 0px 1px 1px #EDA83C inset, 0px 0px 8px #EDA83C; +} + +.login { + margin-top: 50px; + text-align: center; +} + +.twitter-color { + color: #55acee; +} + +.vimeo-color { + color: #1ab7ea; +} + +.feed-manager { + background-color: rgba(255, 255, 255, 0.9); + border-radius: 15px; + margin: 15px; + padding: 10px; + text-align: center; + display:inline-block; + width: 270px; +} + +h3 { + margin-top: 120px; + color: white; + text-align: center; + font-family: 'Lato', sans-serif; + font-size: 30px; +} + +// CSS Loader +#floatingCirclesG{ + position:relative; + width:125px; + height:125px; + margin:auto; + transform:scale(0.6); + -o-transform:scale(0.6); + -ms-transform:scale(0.6); + -webkit-transform:scale(0.6); + -moz-transform:scale(0.6); +} + +.f_circleG{ + position:absolute; + background-color:rgb(255,255,255); + height:22px; + width:22px; + border-radius:12px; + -o-border-radius:12px; + -ms-border-radius:12px; + -webkit-border-radius:12px; + -moz-border-radius:12px; + animation-name:f_fadeG; + -o-animation-name:f_fadeG; + -ms-animation-name:f_fadeG; + -webkit-animation-name:f_fadeG; + -moz-animation-name:f_fadeG; + animation-duration:1.2s; + -o-animation-duration:1.2s; + -ms-animation-duration:1.2s; + -webkit-animation-duration:1.2s; + -moz-animation-duration:1.2s; + animation-iteration-count:infinite; + -o-animation-iteration-count:infinite; + -ms-animation-iteration-count:infinite; + -webkit-animation-iteration-count:infinite; + -moz-animation-iteration-count:infinite; + animation-direction:normal; + -o-animation-direction:normal; + -ms-animation-direction:normal; + -webkit-animation-direction:normal; + -moz-animation-direction:normal; +} + +#frotateG_01{ + left:0; + top:51px; + animation-delay:0.45s; + -o-animation-delay:0.45s; + -ms-animation-delay:0.45s; + -webkit-animation-delay:0.45s; + -moz-animation-delay:0.45s; +} + +#frotateG_02{ + left:15px; + top:15px; + animation-delay:0.6s; + -o-animation-delay:0.6s; + -ms-animation-delay:0.6s; + -webkit-animation-delay:0.6s; + -moz-animation-delay:0.6s; +} + +#frotateG_03{ + left:51px; + top:0; + animation-delay:0.75s; + -o-animation-delay:0.75s; + -ms-animation-delay:0.75s; + -webkit-animation-delay:0.75s; + -moz-animation-delay:0.75s; +} + +#frotateG_04{ + right:15px; + top:15px; + animation-delay:0.9s; + -o-animation-delay:0.9s; + -ms-animation-delay:0.9s; + -webkit-animation-delay:0.9s; + -moz-animation-delay:0.9s; +} + +#frotateG_05{ + right:0; + top:51px; + animation-delay:1.05s; + -o-animation-delay:1.05s; + -ms-animation-delay:1.05s; + -webkit-animation-delay:1.05s; + -moz-animation-delay:1.05s; +} + +#frotateG_06{ + right:15px; + bottom:15px; + animation-delay:1.2s; + -o-animation-delay:1.2s; + -ms-animation-delay:1.2s; + -webkit-animation-delay:1.2s; + -moz-animation-delay:1.2s; +} + +#frotateG_07{ + left:51px; + bottom:0; + animation-delay:1.35s; + -o-animation-delay:1.35s; + -ms-animation-delay:1.35s; + -webkit-animation-delay:1.35s; + -moz-animation-delay:1.35s; +} + +#frotateG_08{ + left:15px; + bottom:15px; + animation-delay:1.5s; + -o-animation-delay:1.5s; + -ms-animation-delay:1.5s; + -webkit-animation-delay:1.5s; + -moz-animation-delay:1.5s; +} + + + +@keyframes f_fadeG{ + 0%{ + background-color:rgb(0,0,0); + } + + 100%{ + background-color:rgb(255,255,255); + } +} + +@-o-keyframes f_fadeG{ + 0%{ + background-color:rgb(0,0,0); + } + + 100%{ + background-color:rgb(255,255,255); + } +} + +@-ms-keyframes f_fadeG{ + 0%{ + background-color:rgb(0,0,0); + } + + 100%{ + background-color:rgb(255,255,255); + } +} + +@-webkit-keyframes f_fadeG{ + 0%{ + background-color:rgb(0,0,0); + } + + 100%{ + background-color:rgb(255,255,255); + } +} + +@-moz-keyframes f_fadeG{ + 0%{ + background-color:rgb(0,0,0); + } + + 100%{ + background-color:rgb(255,255,255); + } +} + +.pagination { + color: white; + text-align: center; + +} + +.pagination a:visted { + color: #F1F1F1; +} diff --git a/app/assets/stylesheets/bootstrap-social.css b/app/assets/stylesheets/bootstrap-social.css new file mode 100644 index 0000000..662a736 --- /dev/null +++ b/app/assets/stylesheets/bootstrap-social.css @@ -0,0 +1,147 @@ +/* + * Social Buttons for Bootstrap + * + * Copyright 2013-2015 Panayiotis Lipiridis + * Licensed under the MIT License + * + * https://github.com/lipis/bootstrap-social + */ + +.btn-social{position:relative;padding-left:44px;text-align:left;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.btn-social>:first-child{position:absolute;left:0;top:0;bottom:0;width:32px;line-height:34px;font-size:1.6em;text-align:center;border-right:1px solid rgba(0,0,0,0.2)} +.btn-social.btn-lg{padding-left:61px}.btn-social.btn-lg>:first-child{line-height:45px;width:45px;font-size:1.8em} +.btn-social.btn-sm{padding-left:38px}.btn-social.btn-sm>:first-child{line-height:28px;width:28px;font-size:1.4em} +.btn-social.btn-xs{padding-left:30px}.btn-social.btn-xs>:first-child{line-height:20px;width:20px;font-size:1.2em} +.btn-social-icon{position:relative;padding-left:44px;text-align:left;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;height:34px;width:34px;padding:0}.btn-social-icon>:first-child{position:absolute;left:0;top:0;bottom:0;width:32px;line-height:34px;font-size:1.6em;text-align:center;border-right:1px solid rgba(0,0,0,0.2)} +.btn-social-icon.btn-lg{padding-left:61px}.btn-social-icon.btn-lg>:first-child{line-height:45px;width:45px;font-size:1.8em} +.btn-social-icon.btn-sm{padding-left:38px}.btn-social-icon.btn-sm>:first-child{line-height:28px;width:28px;font-size:1.4em} +.btn-social-icon.btn-xs{padding-left:30px}.btn-social-icon.btn-xs>:first-child{line-height:20px;width:20px;font-size:1.2em} +.btn-social-icon>:first-child{border:none;text-align:center;width:100% !important} +.btn-social-icon.btn-lg{height:45px;width:45px;padding-left:0;padding-right:0} +.btn-social-icon.btn-sm{height:30px;width:30px;padding-left:0;padding-right:0} +.btn-social-icon.btn-xs{height:22px;width:22px;padding-left:0;padding-right:0} +.btn-adn{color:#fff;background-color:#d87a68;border-color:rgba(0,0,0,0.2)}.btn-adn:focus,.btn-adn.focus{color:#fff;background-color:#ce563f;border-color:rgba(0,0,0,0.2)} +.btn-adn:hover{color:#fff;background-color:#ce563f;border-color:rgba(0,0,0,0.2)} +.btn-adn:active,.btn-adn.active,.open>.dropdown-toggle.btn-adn{color:#fff;background-color:#ce563f;border-color:rgba(0,0,0,0.2)}.btn-adn:active:hover,.btn-adn.active:hover,.open>.dropdown-toggle.btn-adn:hover,.btn-adn:active:focus,.btn-adn.active:focus,.open>.dropdown-toggle.btn-adn:focus,.btn-adn:active.focus,.btn-adn.active.focus,.open>.dropdown-toggle.btn-adn.focus{color:#fff;background-color:#b94630;border-color:rgba(0,0,0,0.2)} +.btn-adn:active,.btn-adn.active,.open>.dropdown-toggle.btn-adn{background-image:none} +.btn-adn.disabled,.btn-adn[disabled],fieldset[disabled] .btn-adn,.btn-adn.disabled:hover,.btn-adn[disabled]:hover,fieldset[disabled] .btn-adn:hover,.btn-adn.disabled:focus,.btn-adn[disabled]:focus,fieldset[disabled] .btn-adn:focus,.btn-adn.disabled.focus,.btn-adn[disabled].focus,fieldset[disabled] .btn-adn.focus,.btn-adn.disabled:active,.btn-adn[disabled]:active,fieldset[disabled] .btn-adn:active,.btn-adn.disabled.active,.btn-adn[disabled].active,fieldset[disabled] .btn-adn.active{background-color:#d87a68;border-color:rgba(0,0,0,0.2)} +.btn-adn .badge{color:#d87a68;background-color:#fff} +.btn-bitbucket{color:#fff;background-color:#205081;border-color:rgba(0,0,0,0.2)}.btn-bitbucket:focus,.btn-bitbucket.focus{color:#fff;background-color:#163758;border-color:rgba(0,0,0,0.2)} +.btn-bitbucket:hover{color:#fff;background-color:#163758;border-color:rgba(0,0,0,0.2)} +.btn-bitbucket:active,.btn-bitbucket.active,.open>.dropdown-toggle.btn-bitbucket{color:#fff;background-color:#163758;border-color:rgba(0,0,0,0.2)}.btn-bitbucket:active:hover,.btn-bitbucket.active:hover,.open>.dropdown-toggle.btn-bitbucket:hover,.btn-bitbucket:active:focus,.btn-bitbucket.active:focus,.open>.dropdown-toggle.btn-bitbucket:focus,.btn-bitbucket:active.focus,.btn-bitbucket.active.focus,.open>.dropdown-toggle.btn-bitbucket.focus{color:#fff;background-color:#0f253c;border-color:rgba(0,0,0,0.2)} +.btn-bitbucket:active,.btn-bitbucket.active,.open>.dropdown-toggle.btn-bitbucket{background-image:none} +.btn-bitbucket.disabled,.btn-bitbucket[disabled],fieldset[disabled] .btn-bitbucket,.btn-bitbucket.disabled:hover,.btn-bitbucket[disabled]:hover,fieldset[disabled] .btn-bitbucket:hover,.btn-bitbucket.disabled:focus,.btn-bitbucket[disabled]:focus,fieldset[disabled] .btn-bitbucket:focus,.btn-bitbucket.disabled.focus,.btn-bitbucket[disabled].focus,fieldset[disabled] .btn-bitbucket.focus,.btn-bitbucket.disabled:active,.btn-bitbucket[disabled]:active,fieldset[disabled] .btn-bitbucket:active,.btn-bitbucket.disabled.active,.btn-bitbucket[disabled].active,fieldset[disabled] .btn-bitbucket.active{background-color:#205081;border-color:rgba(0,0,0,0.2)} +.btn-bitbucket .badge{color:#205081;background-color:#fff} +.btn-dropbox{color:#fff;background-color:#1087dd;border-color:rgba(0,0,0,0.2)}.btn-dropbox:focus,.btn-dropbox.focus{color:#fff;background-color:#0d6aad;border-color:rgba(0,0,0,0.2)} +.btn-dropbox:hover{color:#fff;background-color:#0d6aad;border-color:rgba(0,0,0,0.2)} +.btn-dropbox:active,.btn-dropbox.active,.open>.dropdown-toggle.btn-dropbox{color:#fff;background-color:#0d6aad;border-color:rgba(0,0,0,0.2)}.btn-dropbox:active:hover,.btn-dropbox.active:hover,.open>.dropdown-toggle.btn-dropbox:hover,.btn-dropbox:active:focus,.btn-dropbox.active:focus,.open>.dropdown-toggle.btn-dropbox:focus,.btn-dropbox:active.focus,.btn-dropbox.active.focus,.open>.dropdown-toggle.btn-dropbox.focus{color:#fff;background-color:#0a568c;border-color:rgba(0,0,0,0.2)} +.btn-dropbox:active,.btn-dropbox.active,.open>.dropdown-toggle.btn-dropbox{background-image:none} +.btn-dropbox.disabled,.btn-dropbox[disabled],fieldset[disabled] .btn-dropbox,.btn-dropbox.disabled:hover,.btn-dropbox[disabled]:hover,fieldset[disabled] .btn-dropbox:hover,.btn-dropbox.disabled:focus,.btn-dropbox[disabled]:focus,fieldset[disabled] .btn-dropbox:focus,.btn-dropbox.disabled.focus,.btn-dropbox[disabled].focus,fieldset[disabled] .btn-dropbox.focus,.btn-dropbox.disabled:active,.btn-dropbox[disabled]:active,fieldset[disabled] .btn-dropbox:active,.btn-dropbox.disabled.active,.btn-dropbox[disabled].active,fieldset[disabled] .btn-dropbox.active{background-color:#1087dd;border-color:rgba(0,0,0,0.2)} +.btn-dropbox .badge{color:#1087dd;background-color:#fff} +.btn-facebook{color:#fff;background-color:#3b5998;border-color:rgba(0,0,0,0.2)}.btn-facebook:focus,.btn-facebook.focus{color:#fff;background-color:#2d4373;border-color:rgba(0,0,0,0.2)} +.btn-facebook:hover{color:#fff;background-color:#2d4373;border-color:rgba(0,0,0,0.2)} +.btn-facebook:active,.btn-facebook.active,.open>.dropdown-toggle.btn-facebook{color:#fff;background-color:#2d4373;border-color:rgba(0,0,0,0.2)}.btn-facebook:active:hover,.btn-facebook.active:hover,.open>.dropdown-toggle.btn-facebook:hover,.btn-facebook:active:focus,.btn-facebook.active:focus,.open>.dropdown-toggle.btn-facebook:focus,.btn-facebook:active.focus,.btn-facebook.active.focus,.open>.dropdown-toggle.btn-facebook.focus{color:#fff;background-color:#23345a;border-color:rgba(0,0,0,0.2)} +.btn-facebook:active,.btn-facebook.active,.open>.dropdown-toggle.btn-facebook{background-image:none} +.btn-facebook.disabled,.btn-facebook[disabled],fieldset[disabled] .btn-facebook,.btn-facebook.disabled:hover,.btn-facebook[disabled]:hover,fieldset[disabled] .btn-facebook:hover,.btn-facebook.disabled:focus,.btn-facebook[disabled]:focus,fieldset[disabled] .btn-facebook:focus,.btn-facebook.disabled.focus,.btn-facebook[disabled].focus,fieldset[disabled] .btn-facebook.focus,.btn-facebook.disabled:active,.btn-facebook[disabled]:active,fieldset[disabled] .btn-facebook:active,.btn-facebook.disabled.active,.btn-facebook[disabled].active,fieldset[disabled] .btn-facebook.active{background-color:#3b5998;border-color:rgba(0,0,0,0.2)} +.btn-facebook .badge{color:#3b5998;background-color:#fff} +.btn-flickr{color:#fff;background-color:#ff0084;border-color:rgba(0,0,0,0.2)}.btn-flickr:focus,.btn-flickr.focus{color:#fff;background-color:#cc006a;border-color:rgba(0,0,0,0.2)} +.btn-flickr:hover{color:#fff;background-color:#cc006a;border-color:rgba(0,0,0,0.2)} +.btn-flickr:active,.btn-flickr.active,.open>.dropdown-toggle.btn-flickr{color:#fff;background-color:#cc006a;border-color:rgba(0,0,0,0.2)}.btn-flickr:active:hover,.btn-flickr.active:hover,.open>.dropdown-toggle.btn-flickr:hover,.btn-flickr:active:focus,.btn-flickr.active:focus,.open>.dropdown-toggle.btn-flickr:focus,.btn-flickr:active.focus,.btn-flickr.active.focus,.open>.dropdown-toggle.btn-flickr.focus{color:#fff;background-color:#a80057;border-color:rgba(0,0,0,0.2)} +.btn-flickr:active,.btn-flickr.active,.open>.dropdown-toggle.btn-flickr{background-image:none} +.btn-flickr.disabled,.btn-flickr[disabled],fieldset[disabled] .btn-flickr,.btn-flickr.disabled:hover,.btn-flickr[disabled]:hover,fieldset[disabled] .btn-flickr:hover,.btn-flickr.disabled:focus,.btn-flickr[disabled]:focus,fieldset[disabled] .btn-flickr:focus,.btn-flickr.disabled.focus,.btn-flickr[disabled].focus,fieldset[disabled] .btn-flickr.focus,.btn-flickr.disabled:active,.btn-flickr[disabled]:active,fieldset[disabled] .btn-flickr:active,.btn-flickr.disabled.active,.btn-flickr[disabled].active,fieldset[disabled] .btn-flickr.active{background-color:#ff0084;border-color:rgba(0,0,0,0.2)} +.btn-flickr .badge{color:#ff0084;background-color:#fff} +.btn-foursquare{color:#fff;background-color:#f94877;border-color:rgba(0,0,0,0.2)}.btn-foursquare:focus,.btn-foursquare.focus{color:#fff;background-color:#f71752;border-color:rgba(0,0,0,0.2)} +.btn-foursquare:hover{color:#fff;background-color:#f71752;border-color:rgba(0,0,0,0.2)} +.btn-foursquare:active,.btn-foursquare.active,.open>.dropdown-toggle.btn-foursquare{color:#fff;background-color:#f71752;border-color:rgba(0,0,0,0.2)}.btn-foursquare:active:hover,.btn-foursquare.active:hover,.open>.dropdown-toggle.btn-foursquare:hover,.btn-foursquare:active:focus,.btn-foursquare.active:focus,.open>.dropdown-toggle.btn-foursquare:focus,.btn-foursquare:active.focus,.btn-foursquare.active.focus,.open>.dropdown-toggle.btn-foursquare.focus{color:#fff;background-color:#e30742;border-color:rgba(0,0,0,0.2)} +.btn-foursquare:active,.btn-foursquare.active,.open>.dropdown-toggle.btn-foursquare{background-image:none} +.btn-foursquare.disabled,.btn-foursquare[disabled],fieldset[disabled] .btn-foursquare,.btn-foursquare.disabled:hover,.btn-foursquare[disabled]:hover,fieldset[disabled] .btn-foursquare:hover,.btn-foursquare.disabled:focus,.btn-foursquare[disabled]:focus,fieldset[disabled] .btn-foursquare:focus,.btn-foursquare.disabled.focus,.btn-foursquare[disabled].focus,fieldset[disabled] .btn-foursquare.focus,.btn-foursquare.disabled:active,.btn-foursquare[disabled]:active,fieldset[disabled] .btn-foursquare:active,.btn-foursquare.disabled.active,.btn-foursquare[disabled].active,fieldset[disabled] .btn-foursquare.active{background-color:#f94877;border-color:rgba(0,0,0,0.2)} +.btn-foursquare .badge{color:#f94877;background-color:#fff} +.btn-github{color:#fff;background-color:#444;border-color:rgba(0,0,0,0.2)}.btn-github:focus,.btn-github.focus{color:#fff;background-color:#2b2b2b;border-color:rgba(0,0,0,0.2)} +.btn-github:hover{color:#fff;background-color:#2b2b2b;border-color:rgba(0,0,0,0.2)} +.btn-github:active,.btn-github.active,.open>.dropdown-toggle.btn-github{color:#fff;background-color:#2b2b2b;border-color:rgba(0,0,0,0.2)}.btn-github:active:hover,.btn-github.active:hover,.open>.dropdown-toggle.btn-github:hover,.btn-github:active:focus,.btn-github.active:focus,.open>.dropdown-toggle.btn-github:focus,.btn-github:active.focus,.btn-github.active.focus,.open>.dropdown-toggle.btn-github.focus{color:#fff;background-color:#191919;border-color:rgba(0,0,0,0.2)} +.btn-github:active,.btn-github.active,.open>.dropdown-toggle.btn-github{background-image:none} +.btn-github.disabled,.btn-github[disabled],fieldset[disabled] .btn-github,.btn-github.disabled:hover,.btn-github[disabled]:hover,fieldset[disabled] .btn-github:hover,.btn-github.disabled:focus,.btn-github[disabled]:focus,fieldset[disabled] .btn-github:focus,.btn-github.disabled.focus,.btn-github[disabled].focus,fieldset[disabled] .btn-github.focus,.btn-github.disabled:active,.btn-github[disabled]:active,fieldset[disabled] .btn-github:active,.btn-github.disabled.active,.btn-github[disabled].active,fieldset[disabled] .btn-github.active{background-color:#444;border-color:rgba(0,0,0,0.2)} +.btn-github .badge{color:#444;background-color:#fff} +.btn-google{color:#fff;background-color:#dd4b39;border-color:rgba(0,0,0,0.2)}.btn-google:focus,.btn-google.focus{color:#fff;background-color:#c23321;border-color:rgba(0,0,0,0.2)} +.btn-google:hover{color:#fff;background-color:#c23321;border-color:rgba(0,0,0,0.2)} +.btn-google:active,.btn-google.active,.open>.dropdown-toggle.btn-google{color:#fff;background-color:#c23321;border-color:rgba(0,0,0,0.2)}.btn-google:active:hover,.btn-google.active:hover,.open>.dropdown-toggle.btn-google:hover,.btn-google:active:focus,.btn-google.active:focus,.open>.dropdown-toggle.btn-google:focus,.btn-google:active.focus,.btn-google.active.focus,.open>.dropdown-toggle.btn-google.focus{color:#fff;background-color:#a32b1c;border-color:rgba(0,0,0,0.2)} +.btn-google:active,.btn-google.active,.open>.dropdown-toggle.btn-google{background-image:none} +.btn-google.disabled,.btn-google[disabled],fieldset[disabled] .btn-google,.btn-google.disabled:hover,.btn-google[disabled]:hover,fieldset[disabled] .btn-google:hover,.btn-google.disabled:focus,.btn-google[disabled]:focus,fieldset[disabled] .btn-google:focus,.btn-google.disabled.focus,.btn-google[disabled].focus,fieldset[disabled] .btn-google.focus,.btn-google.disabled:active,.btn-google[disabled]:active,fieldset[disabled] .btn-google:active,.btn-google.disabled.active,.btn-google[disabled].active,fieldset[disabled] .btn-google.active{background-color:#dd4b39;border-color:rgba(0,0,0,0.2)} +.btn-google .badge{color:#dd4b39;background-color:#fff} +.btn-instagram{color:#fff;background-color:#3f729b;border-color:rgba(0,0,0,0.2)}.btn-instagram:focus,.btn-instagram.focus{color:#fff;background-color:#305777;border-color:rgba(0,0,0,0.2)} +.btn-instagram:hover{color:#fff;background-color:#305777;border-color:rgba(0,0,0,0.2)} +.btn-instagram:active,.btn-instagram.active,.open>.dropdown-toggle.btn-instagram{color:#fff;background-color:#305777;border-color:rgba(0,0,0,0.2)}.btn-instagram:active:hover,.btn-instagram.active:hover,.open>.dropdown-toggle.btn-instagram:hover,.btn-instagram:active:focus,.btn-instagram.active:focus,.open>.dropdown-toggle.btn-instagram:focus,.btn-instagram:active.focus,.btn-instagram.active.focus,.open>.dropdown-toggle.btn-instagram.focus{color:#fff;background-color:#26455d;border-color:rgba(0,0,0,0.2)} +.btn-instagram:active,.btn-instagram.active,.open>.dropdown-toggle.btn-instagram{background-image:none} +.btn-instagram.disabled,.btn-instagram[disabled],fieldset[disabled] .btn-instagram,.btn-instagram.disabled:hover,.btn-instagram[disabled]:hover,fieldset[disabled] .btn-instagram:hover,.btn-instagram.disabled:focus,.btn-instagram[disabled]:focus,fieldset[disabled] .btn-instagram:focus,.btn-instagram.disabled.focus,.btn-instagram[disabled].focus,fieldset[disabled] .btn-instagram.focus,.btn-instagram.disabled:active,.btn-instagram[disabled]:active,fieldset[disabled] .btn-instagram:active,.btn-instagram.disabled.active,.btn-instagram[disabled].active,fieldset[disabled] .btn-instagram.active{background-color:#3f729b;border-color:rgba(0,0,0,0.2)} +.btn-instagram .badge{color:#3f729b;background-color:#fff} +.btn-linkedin{color:#fff;background-color:#007bb6;border-color:rgba(0,0,0,0.2)}.btn-linkedin:focus,.btn-linkedin.focus{color:#fff;background-color:#005983;border-color:rgba(0,0,0,0.2)} +.btn-linkedin:hover{color:#fff;background-color:#005983;border-color:rgba(0,0,0,0.2)} +.btn-linkedin:active,.btn-linkedin.active,.open>.dropdown-toggle.btn-linkedin{color:#fff;background-color:#005983;border-color:rgba(0,0,0,0.2)}.btn-linkedin:active:hover,.btn-linkedin.active:hover,.open>.dropdown-toggle.btn-linkedin:hover,.btn-linkedin:active:focus,.btn-linkedin.active:focus,.open>.dropdown-toggle.btn-linkedin:focus,.btn-linkedin:active.focus,.btn-linkedin.active.focus,.open>.dropdown-toggle.btn-linkedin.focus{color:#fff;background-color:#00405f;border-color:rgba(0,0,0,0.2)} +.btn-linkedin:active,.btn-linkedin.active,.open>.dropdown-toggle.btn-linkedin{background-image:none} +.btn-linkedin.disabled,.btn-linkedin[disabled],fieldset[disabled] .btn-linkedin,.btn-linkedin.disabled:hover,.btn-linkedin[disabled]:hover,fieldset[disabled] .btn-linkedin:hover,.btn-linkedin.disabled:focus,.btn-linkedin[disabled]:focus,fieldset[disabled] .btn-linkedin:focus,.btn-linkedin.disabled.focus,.btn-linkedin[disabled].focus,fieldset[disabled] .btn-linkedin.focus,.btn-linkedin.disabled:active,.btn-linkedin[disabled]:active,fieldset[disabled] .btn-linkedin:active,.btn-linkedin.disabled.active,.btn-linkedin[disabled].active,fieldset[disabled] .btn-linkedin.active{background-color:#007bb6;border-color:rgba(0,0,0,0.2)} +.btn-linkedin .badge{color:#007bb6;background-color:#fff} +.btn-microsoft{color:#fff;background-color:#2672ec;border-color:rgba(0,0,0,0.2)}.btn-microsoft:focus,.btn-microsoft.focus{color:#fff;background-color:#125acd;border-color:rgba(0,0,0,0.2)} +.btn-microsoft:hover{color:#fff;background-color:#125acd;border-color:rgba(0,0,0,0.2)} +.btn-microsoft:active,.btn-microsoft.active,.open>.dropdown-toggle.btn-microsoft{color:#fff;background-color:#125acd;border-color:rgba(0,0,0,0.2)}.btn-microsoft:active:hover,.btn-microsoft.active:hover,.open>.dropdown-toggle.btn-microsoft:hover,.btn-microsoft:active:focus,.btn-microsoft.active:focus,.open>.dropdown-toggle.btn-microsoft:focus,.btn-microsoft:active.focus,.btn-microsoft.active.focus,.open>.dropdown-toggle.btn-microsoft.focus{color:#fff;background-color:#0f4bac;border-color:rgba(0,0,0,0.2)} +.btn-microsoft:active,.btn-microsoft.active,.open>.dropdown-toggle.btn-microsoft{background-image:none} +.btn-microsoft.disabled,.btn-microsoft[disabled],fieldset[disabled] .btn-microsoft,.btn-microsoft.disabled:hover,.btn-microsoft[disabled]:hover,fieldset[disabled] .btn-microsoft:hover,.btn-microsoft.disabled:focus,.btn-microsoft[disabled]:focus,fieldset[disabled] .btn-microsoft:focus,.btn-microsoft.disabled.focus,.btn-microsoft[disabled].focus,fieldset[disabled] .btn-microsoft.focus,.btn-microsoft.disabled:active,.btn-microsoft[disabled]:active,fieldset[disabled] .btn-microsoft:active,.btn-microsoft.disabled.active,.btn-microsoft[disabled].active,fieldset[disabled] .btn-microsoft.active{background-color:#2672ec;border-color:rgba(0,0,0,0.2)} +.btn-microsoft .badge{color:#2672ec;background-color:#fff} +.btn-odnoklassniki{color:#fff;background-color:#f4731c;border-color:rgba(0,0,0,0.2)}.btn-odnoklassniki:focus,.btn-odnoklassniki.focus{color:#fff;background-color:#d35b0a;border-color:rgba(0,0,0,0.2)} +.btn-odnoklassniki:hover{color:#fff;background-color:#d35b0a;border-color:rgba(0,0,0,0.2)} +.btn-odnoklassniki:active,.btn-odnoklassniki.active,.open>.dropdown-toggle.btn-odnoklassniki{color:#fff;background-color:#d35b0a;border-color:rgba(0,0,0,0.2)}.btn-odnoklassniki:active:hover,.btn-odnoklassniki.active:hover,.open>.dropdown-toggle.btn-odnoklassniki:hover,.btn-odnoklassniki:active:focus,.btn-odnoklassniki.active:focus,.open>.dropdown-toggle.btn-odnoklassniki:focus,.btn-odnoklassniki:active.focus,.btn-odnoklassniki.active.focus,.open>.dropdown-toggle.btn-odnoklassniki.focus{color:#fff;background-color:#b14c09;border-color:rgba(0,0,0,0.2)} +.btn-odnoklassniki:active,.btn-odnoklassniki.active,.open>.dropdown-toggle.btn-odnoklassniki{background-image:none} +.btn-odnoklassniki.disabled,.btn-odnoklassniki[disabled],fieldset[disabled] .btn-odnoklassniki,.btn-odnoklassniki.disabled:hover,.btn-odnoklassniki[disabled]:hover,fieldset[disabled] .btn-odnoklassniki:hover,.btn-odnoklassniki.disabled:focus,.btn-odnoklassniki[disabled]:focus,fieldset[disabled] .btn-odnoklassniki:focus,.btn-odnoklassniki.disabled.focus,.btn-odnoklassniki[disabled].focus,fieldset[disabled] .btn-odnoklassniki.focus,.btn-odnoklassniki.disabled:active,.btn-odnoklassniki[disabled]:active,fieldset[disabled] .btn-odnoklassniki:active,.btn-odnoklassniki.disabled.active,.btn-odnoklassniki[disabled].active,fieldset[disabled] .btn-odnoklassniki.active{background-color:#f4731c;border-color:rgba(0,0,0,0.2)} +.btn-odnoklassniki .badge{color:#f4731c;background-color:#fff} +.btn-openid{color:#fff;background-color:#f7931e;border-color:rgba(0,0,0,0.2)}.btn-openid:focus,.btn-openid.focus{color:#fff;background-color:#da7908;border-color:rgba(0,0,0,0.2)} +.btn-openid:hover{color:#fff;background-color:#da7908;border-color:rgba(0,0,0,0.2)} +.btn-openid:active,.btn-openid.active,.open>.dropdown-toggle.btn-openid{color:#fff;background-color:#da7908;border-color:rgba(0,0,0,0.2)}.btn-openid:active:hover,.btn-openid.active:hover,.open>.dropdown-toggle.btn-openid:hover,.btn-openid:active:focus,.btn-openid.active:focus,.open>.dropdown-toggle.btn-openid:focus,.btn-openid:active.focus,.btn-openid.active.focus,.open>.dropdown-toggle.btn-openid.focus{color:#fff;background-color:#b86607;border-color:rgba(0,0,0,0.2)} +.btn-openid:active,.btn-openid.active,.open>.dropdown-toggle.btn-openid{background-image:none} +.btn-openid.disabled,.btn-openid[disabled],fieldset[disabled] .btn-openid,.btn-openid.disabled:hover,.btn-openid[disabled]:hover,fieldset[disabled] .btn-openid:hover,.btn-openid.disabled:focus,.btn-openid[disabled]:focus,fieldset[disabled] .btn-openid:focus,.btn-openid.disabled.focus,.btn-openid[disabled].focus,fieldset[disabled] .btn-openid.focus,.btn-openid.disabled:active,.btn-openid[disabled]:active,fieldset[disabled] .btn-openid:active,.btn-openid.disabled.active,.btn-openid[disabled].active,fieldset[disabled] .btn-openid.active{background-color:#f7931e;border-color:rgba(0,0,0,0.2)} +.btn-openid .badge{color:#f7931e;background-color:#fff} +.btn-pinterest{color:#fff;background-color:#cb2027;border-color:rgba(0,0,0,0.2)}.btn-pinterest:focus,.btn-pinterest.focus{color:#fff;background-color:#9f191f;border-color:rgba(0,0,0,0.2)} +.btn-pinterest:hover{color:#fff;background-color:#9f191f;border-color:rgba(0,0,0,0.2)} +.btn-pinterest:active,.btn-pinterest.active,.open>.dropdown-toggle.btn-pinterest{color:#fff;background-color:#9f191f;border-color:rgba(0,0,0,0.2)}.btn-pinterest:active:hover,.btn-pinterest.active:hover,.open>.dropdown-toggle.btn-pinterest:hover,.btn-pinterest:active:focus,.btn-pinterest.active:focus,.open>.dropdown-toggle.btn-pinterest:focus,.btn-pinterest:active.focus,.btn-pinterest.active.focus,.open>.dropdown-toggle.btn-pinterest.focus{color:#fff;background-color:#801419;border-color:rgba(0,0,0,0.2)} +.btn-pinterest:active,.btn-pinterest.active,.open>.dropdown-toggle.btn-pinterest{background-image:none} +.btn-pinterest.disabled,.btn-pinterest[disabled],fieldset[disabled] .btn-pinterest,.btn-pinterest.disabled:hover,.btn-pinterest[disabled]:hover,fieldset[disabled] .btn-pinterest:hover,.btn-pinterest.disabled:focus,.btn-pinterest[disabled]:focus,fieldset[disabled] .btn-pinterest:focus,.btn-pinterest.disabled.focus,.btn-pinterest[disabled].focus,fieldset[disabled] .btn-pinterest.focus,.btn-pinterest.disabled:active,.btn-pinterest[disabled]:active,fieldset[disabled] .btn-pinterest:active,.btn-pinterest.disabled.active,.btn-pinterest[disabled].active,fieldset[disabled] .btn-pinterest.active{background-color:#cb2027;border-color:rgba(0,0,0,0.2)} +.btn-pinterest .badge{color:#cb2027;background-color:#fff} +.btn-reddit{color:#000;background-color:#eff7ff;border-color:rgba(0,0,0,0.2)}.btn-reddit:focus,.btn-reddit.focus{color:#000;background-color:#bcddff;border-color:rgba(0,0,0,0.2)} +.btn-reddit:hover{color:#000;background-color:#bcddff;border-color:rgba(0,0,0,0.2)} +.btn-reddit:active,.btn-reddit.active,.open>.dropdown-toggle.btn-reddit{color:#000;background-color:#bcddff;border-color:rgba(0,0,0,0.2)}.btn-reddit:active:hover,.btn-reddit.active:hover,.open>.dropdown-toggle.btn-reddit:hover,.btn-reddit:active:focus,.btn-reddit.active:focus,.open>.dropdown-toggle.btn-reddit:focus,.btn-reddit:active.focus,.btn-reddit.active.focus,.open>.dropdown-toggle.btn-reddit.focus{color:#000;background-color:#98ccff;border-color:rgba(0,0,0,0.2)} +.btn-reddit:active,.btn-reddit.active,.open>.dropdown-toggle.btn-reddit{background-image:none} +.btn-reddit.disabled,.btn-reddit[disabled],fieldset[disabled] .btn-reddit,.btn-reddit.disabled:hover,.btn-reddit[disabled]:hover,fieldset[disabled] .btn-reddit:hover,.btn-reddit.disabled:focus,.btn-reddit[disabled]:focus,fieldset[disabled] .btn-reddit:focus,.btn-reddit.disabled.focus,.btn-reddit[disabled].focus,fieldset[disabled] .btn-reddit.focus,.btn-reddit.disabled:active,.btn-reddit[disabled]:active,fieldset[disabled] .btn-reddit:active,.btn-reddit.disabled.active,.btn-reddit[disabled].active,fieldset[disabled] .btn-reddit.active{background-color:#eff7ff;border-color:rgba(0,0,0,0.2)} +.btn-reddit .badge{color:#eff7ff;background-color:#000} +.btn-soundcloud{color:#fff;background-color:#f50;border-color:rgba(0,0,0,0.2)}.btn-soundcloud:focus,.btn-soundcloud.focus{color:#fff;background-color:#c40;border-color:rgba(0,0,0,0.2)} +.btn-soundcloud:hover{color:#fff;background-color:#c40;border-color:rgba(0,0,0,0.2)} +.btn-soundcloud:active,.btn-soundcloud.active,.open>.dropdown-toggle.btn-soundcloud{color:#fff;background-color:#c40;border-color:rgba(0,0,0,0.2)}.btn-soundcloud:active:hover,.btn-soundcloud.active:hover,.open>.dropdown-toggle.btn-soundcloud:hover,.btn-soundcloud:active:focus,.btn-soundcloud.active:focus,.open>.dropdown-toggle.btn-soundcloud:focus,.btn-soundcloud:active.focus,.btn-soundcloud.active.focus,.open>.dropdown-toggle.btn-soundcloud.focus{color:#fff;background-color:#a83800;border-color:rgba(0,0,0,0.2)} +.btn-soundcloud:active,.btn-soundcloud.active,.open>.dropdown-toggle.btn-soundcloud{background-image:none} +.btn-soundcloud.disabled,.btn-soundcloud[disabled],fieldset[disabled] .btn-soundcloud,.btn-soundcloud.disabled:hover,.btn-soundcloud[disabled]:hover,fieldset[disabled] .btn-soundcloud:hover,.btn-soundcloud.disabled:focus,.btn-soundcloud[disabled]:focus,fieldset[disabled] .btn-soundcloud:focus,.btn-soundcloud.disabled.focus,.btn-soundcloud[disabled].focus,fieldset[disabled] .btn-soundcloud.focus,.btn-soundcloud.disabled:active,.btn-soundcloud[disabled]:active,fieldset[disabled] .btn-soundcloud:active,.btn-soundcloud.disabled.active,.btn-soundcloud[disabled].active,fieldset[disabled] .btn-soundcloud.active{background-color:#f50;border-color:rgba(0,0,0,0.2)} +.btn-soundcloud .badge{color:#f50;background-color:#fff} +.btn-tumblr{color:#fff;background-color:#2c4762;border-color:rgba(0,0,0,0.2)}.btn-tumblr:focus,.btn-tumblr.focus{color:#fff;background-color:#1c2d3f;border-color:rgba(0,0,0,0.2)} +.btn-tumblr:hover{color:#fff;background-color:#1c2d3f;border-color:rgba(0,0,0,0.2)} +.btn-tumblr:active,.btn-tumblr.active,.open>.dropdown-toggle.btn-tumblr{color:#fff;background-color:#1c2d3f;border-color:rgba(0,0,0,0.2)}.btn-tumblr:active:hover,.btn-tumblr.active:hover,.open>.dropdown-toggle.btn-tumblr:hover,.btn-tumblr:active:focus,.btn-tumblr.active:focus,.open>.dropdown-toggle.btn-tumblr:focus,.btn-tumblr:active.focus,.btn-tumblr.active.focus,.open>.dropdown-toggle.btn-tumblr.focus{color:#fff;background-color:#111c26;border-color:rgba(0,0,0,0.2)} +.btn-tumblr:active,.btn-tumblr.active,.open>.dropdown-toggle.btn-tumblr{background-image:none} +.btn-tumblr.disabled,.btn-tumblr[disabled],fieldset[disabled] .btn-tumblr,.btn-tumblr.disabled:hover,.btn-tumblr[disabled]:hover,fieldset[disabled] .btn-tumblr:hover,.btn-tumblr.disabled:focus,.btn-tumblr[disabled]:focus,fieldset[disabled] .btn-tumblr:focus,.btn-tumblr.disabled.focus,.btn-tumblr[disabled].focus,fieldset[disabled] .btn-tumblr.focus,.btn-tumblr.disabled:active,.btn-tumblr[disabled]:active,fieldset[disabled] .btn-tumblr:active,.btn-tumblr.disabled.active,.btn-tumblr[disabled].active,fieldset[disabled] .btn-tumblr.active{background-color:#2c4762;border-color:rgba(0,0,0,0.2)} +.btn-tumblr .badge{color:#2c4762;background-color:#fff} +.btn-twitter{color:#fff;background-color:#55acee;border-color:rgba(0,0,0,0.2)}.btn-twitter:focus,.btn-twitter.focus{color:#fff;background-color:#2795e9;border-color:rgba(0,0,0,0.2)} +.btn-twitter:hover{color:#fff;background-color:#2795e9;border-color:rgba(0,0,0,0.2)} +.btn-twitter:active,.btn-twitter.active,.open>.dropdown-toggle.btn-twitter{color:#fff;background-color:#2795e9;border-color:rgba(0,0,0,0.2)}.btn-twitter:active:hover,.btn-twitter.active:hover,.open>.dropdown-toggle.btn-twitter:hover,.btn-twitter:active:focus,.btn-twitter.active:focus,.open>.dropdown-toggle.btn-twitter:focus,.btn-twitter:active.focus,.btn-twitter.active.focus,.open>.dropdown-toggle.btn-twitter.focus{color:#fff;background-color:#1583d7;border-color:rgba(0,0,0,0.2)} +.btn-twitter:active,.btn-twitter.active,.open>.dropdown-toggle.btn-twitter{background-image:none} +.btn-twitter.disabled,.btn-twitter[disabled],fieldset[disabled] .btn-twitter,.btn-twitter.disabled:hover,.btn-twitter[disabled]:hover,fieldset[disabled] .btn-twitter:hover,.btn-twitter.disabled:focus,.btn-twitter[disabled]:focus,fieldset[disabled] .btn-twitter:focus,.btn-twitter.disabled.focus,.btn-twitter[disabled].focus,fieldset[disabled] .btn-twitter.focus,.btn-twitter.disabled:active,.btn-twitter[disabled]:active,fieldset[disabled] .btn-twitter:active,.btn-twitter.disabled.active,.btn-twitter[disabled].active,fieldset[disabled] .btn-twitter.active{background-color:#55acee;border-color:rgba(0,0,0,0.2)} +.btn-twitter .badge{color:#55acee;background-color:#fff} +.btn-vimeo{color:#fff;background-color:#1ab7ea;border-color:rgba(0,0,0,0.2)}.btn-vimeo:focus,.btn-vimeo.focus{color:#fff;background-color:#1295bf;border-color:rgba(0,0,0,0.2)} +.btn-vimeo:hover{color:#fff;background-color:#1295bf;border-color:rgba(0,0,0,0.2)} +.btn-vimeo:active,.btn-vimeo.active,.open>.dropdown-toggle.btn-vimeo{color:#fff;background-color:#1295bf;border-color:rgba(0,0,0,0.2)}.btn-vimeo:active:hover,.btn-vimeo.active:hover,.open>.dropdown-toggle.btn-vimeo:hover,.btn-vimeo:active:focus,.btn-vimeo.active:focus,.open>.dropdown-toggle.btn-vimeo:focus,.btn-vimeo:active.focus,.btn-vimeo.active.focus,.open>.dropdown-toggle.btn-vimeo.focus{color:#fff;background-color:#0f7b9f;border-color:rgba(0,0,0,0.2)} +.btn-vimeo:active,.btn-vimeo.active,.open>.dropdown-toggle.btn-vimeo{background-image:none} +.btn-vimeo.disabled,.btn-vimeo[disabled],fieldset[disabled] .btn-vimeo,.btn-vimeo.disabled:hover,.btn-vimeo[disabled]:hover,fieldset[disabled] .btn-vimeo:hover,.btn-vimeo.disabled:focus,.btn-vimeo[disabled]:focus,fieldset[disabled] .btn-vimeo:focus,.btn-vimeo.disabled.focus,.btn-vimeo[disabled].focus,fieldset[disabled] .btn-vimeo.focus,.btn-vimeo.disabled:active,.btn-vimeo[disabled]:active,fieldset[disabled] .btn-vimeo:active,.btn-vimeo.disabled.active,.btn-vimeo[disabled].active,fieldset[disabled] .btn-vimeo.active{background-color:#1ab7ea;border-color:rgba(0,0,0,0.2)} +.btn-vimeo .badge{color:#1ab7ea;background-color:#fff} +.btn-vk{color:#fff;background-color:#587ea3;border-color:rgba(0,0,0,0.2)}.btn-vk:focus,.btn-vk.focus{color:#fff;background-color:#466482;border-color:rgba(0,0,0,0.2)} +.btn-vk:hover{color:#fff;background-color:#466482;border-color:rgba(0,0,0,0.2)} +.btn-vk:active,.btn-vk.active,.open>.dropdown-toggle.btn-vk{color:#fff;background-color:#466482;border-color:rgba(0,0,0,0.2)}.btn-vk:active:hover,.btn-vk.active:hover,.open>.dropdown-toggle.btn-vk:hover,.btn-vk:active:focus,.btn-vk.active:focus,.open>.dropdown-toggle.btn-vk:focus,.btn-vk:active.focus,.btn-vk.active.focus,.open>.dropdown-toggle.btn-vk.focus{color:#fff;background-color:#3a526b;border-color:rgba(0,0,0,0.2)} +.btn-vk:active,.btn-vk.active,.open>.dropdown-toggle.btn-vk{background-image:none} +.btn-vk.disabled,.btn-vk[disabled],fieldset[disabled] .btn-vk,.btn-vk.disabled:hover,.btn-vk[disabled]:hover,fieldset[disabled] .btn-vk:hover,.btn-vk.disabled:focus,.btn-vk[disabled]:focus,fieldset[disabled] .btn-vk:focus,.btn-vk.disabled.focus,.btn-vk[disabled].focus,fieldset[disabled] .btn-vk.focus,.btn-vk.disabled:active,.btn-vk[disabled]:active,fieldset[disabled] .btn-vk:active,.btn-vk.disabled.active,.btn-vk[disabled].active,fieldset[disabled] .btn-vk.active{background-color:#587ea3;border-color:rgba(0,0,0,0.2)} +.btn-vk .badge{color:#587ea3;background-color:#fff} +.btn-yahoo{color:#fff;background-color:#720e9e;border-color:rgba(0,0,0,0.2)}.btn-yahoo:focus,.btn-yahoo.focus{color:#fff;background-color:#500a6f;border-color:rgba(0,0,0,0.2)} +.btn-yahoo:hover{color:#fff;background-color:#500a6f;border-color:rgba(0,0,0,0.2)} +.btn-yahoo:active,.btn-yahoo.active,.open>.dropdown-toggle.btn-yahoo{color:#fff;background-color:#500a6f;border-color:rgba(0,0,0,0.2)}.btn-yahoo:active:hover,.btn-yahoo.active:hover,.open>.dropdown-toggle.btn-yahoo:hover,.btn-yahoo:active:focus,.btn-yahoo.active:focus,.open>.dropdown-toggle.btn-yahoo:focus,.btn-yahoo:active.focus,.btn-yahoo.active.focus,.open>.dropdown-toggle.btn-yahoo.focus{color:#fff;background-color:#39074e;border-color:rgba(0,0,0,0.2)} +.btn-yahoo:active,.btn-yahoo.active,.open>.dropdown-toggle.btn-yahoo{background-image:none} +.btn-yahoo.disabled,.btn-yahoo[disabled],fieldset[disabled] .btn-yahoo,.btn-yahoo.disabled:hover,.btn-yahoo[disabled]:hover,fieldset[disabled] .btn-yahoo:hover,.btn-yahoo.disabled:focus,.btn-yahoo[disabled]:focus,fieldset[disabled] .btn-yahoo:focus,.btn-yahoo.disabled.focus,.btn-yahoo[disabled].focus,fieldset[disabled] .btn-yahoo.focus,.btn-yahoo.disabled:active,.btn-yahoo[disabled]:active,fieldset[disabled] .btn-yahoo:active,.btn-yahoo.disabled.active,.btn-yahoo[disabled].active,fieldset[disabled] .btn-yahoo.active{background-color:#720e9e;border-color:rgba(0,0,0,0.2)} +.btn-yahoo .badge{color:#720e9e;background-color:#fff} diff --git a/app/assets/stylesheets/creators.scss b/app/assets/stylesheets/creators.scss new file mode 100644 index 0000000..f148bb6 --- /dev/null +++ b/app/assets/stylesheets/creators.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the creators controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/assets/stylesheets/sessions.scss b/app/assets/stylesheets/sessions.scss new file mode 100644 index 0000000..7bef9cf --- /dev/null +++ b/app/assets/stylesheets/sessions.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the sessions controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/assets/stylesheets/users.scss b/app/assets/stylesheets/users.scss new file mode 100644 index 0000000..1efc835 --- /dev/null +++ b/app/assets/stylesheets/users.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the users 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/application_controller.rb b/app/controllers/application_controller.rb new file mode 100644 index 0000000..440f3b8 --- /dev/null +++ b/app/controllers/application_controller.rb @@ -0,0 +1,23 @@ +require 'will_paginate/array' +class ApplicationController < ActionController::Base + # Prevent CSRF attacks by raising an exception. + # For APIs, you may want to use :null_session instead. + protect_from_forgery with: :exception + before_action :require_login + before_action :current_user + + def current_user + @current_user ||= User.find(session[:user_id]) if session[:user_id] + end + + helper_method :current_user + # The helper_method line allows us to use @current_user in our view files. + + def require_login + unless current_user + flash[:error] = "Please log in." + redirect_to login_path + end + end + +end diff --git a/app/controllers/concerns/.keep b/app/controllers/concerns/.keep new file mode 100644 index 0000000..e69de29 diff --git a/app/controllers/creators_controller.rb b/app/controllers/creators_controller.rb new file mode 100644 index 0000000..27f0b35 --- /dev/null +++ b/app/controllers/creators_controller.rb @@ -0,0 +1,42 @@ +class CreatorsController < ApplicationController + include HTTParty + LIMIT_PER_PAGE = 10 + + #use private methods to determine which api to search + def search + query = params[:query].gsub(/\W/, "") + if query == "" + flash["error"] = "Invalid search term." + redirect_to root_path + elsif params[:provider] == "vimeo" + @creators = vimeo_search(query).paginate(:page => params[:page], :per_page => 10) + render :search + else + @creators = twitter_search(query).paginate(:page => params[:page], :per_page => 10) + render :search + end + end + + private + def vimeo_search(query) + response = HTTParty.get("https://api.vimeo.com/users?per_page=#{LIMIT_PER_PAGE}&query=#{query}", headers: {"Authorization" => "bearer #{ENV['VIMEO_ACCESS_TOKEN']}"}) + json_res = convert_to_json(response) + vimeo_users = json_res["data"] + Creator.make_vimeo_creators(vimeo_users) + end + + def convert_to_json(httparty_response) + return JSON.parse(httparty_response.parsed_response) + end + + #method to configure twitter + def twit + Seemore::Application.config.twitter + end + + def twitter_search(query) + #searches for users + twitter_users = twit.user_search(query) + Creator.make_twitter_creators(twitter_users) + end +end diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb new file mode 100644 index 0000000..b8d80f5 --- /dev/null +++ b/app/controllers/sessions_controller.rb @@ -0,0 +1,28 @@ +class SessionsController < ApplicationController + #this line is for the omniauth developer strategy login. + skip_before_filter :verify_authenticity_token, only: :create + skip_before_action :require_login, only: [:new, :create, :destroy] + + def create + #can sign in with twitter or vimeo + auth_hash = request.env['omniauth.auth'] + if auth_hash["uid"] + @user = User.find_or_create_from_omniauth(auth_hash) + if @user + session[:user_id] = @user.id + else + flash[:notice] = "Failed to save the user" + end + else + flash[:notice] = "Failed to authenticate" + end + redirect_to root_path + end + + def new; end + + def destroy + session[:user_id] = nil + redirect_to login_path + end +end diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb new file mode 100644 index 0000000..270771a --- /dev/null +++ b/app/controllers/users_controller.rb @@ -0,0 +1,67 @@ + +class UsersController < ApplicationController + skip_before_action :require_login,only: [:feed] + + def show + @creators = current_user.creators + end + + def feed + #user not logged in + if session[:user_id].nil? + redirect_to login_path + else + # check for new content from all the creators + current_user.creators.each do |creator| + # update creator from api if last updated more than 6 hours ago + if creator.last_updated.nil? || creator.last_updated < 6.hours.ago + creator.get_content + end + end + @contents = current_user.content.flatten + @contents = @contents.flatten.sort_by! { |content| content[:create_time] }.reverse + @contents = @contents.paginate(:page => params[:page], :per_page => 10) + render "feed" + end + end + + def delete; end + + def create; end + + # adds a creator to the user's list + def update + creator, following = current_user.following(params["provider"], params["p_id"]) + if !following + if creator.nil? + # if the creator does not exist, create creator + creator = Creator.create(creator_hash(params)) + creator.get_content + end + current_user.creators << creator + flash[:notice] = "#{creator.username} has been added to your feed!" + end + redirect_to root_path + end + + #remove a creator from a user's follow list + def delete_creator + # find creator from params + creator = Creator.find_by(provider: params["provider"], p_id: params["p_id"]) + # remove creator from user's list + current_user.creators.delete(creator) + # if the creator is no longer followed, delete it + creator.delete if creator.users.nil? + redirect_to current_user + end + + private + def creator_hash(params) + creator_hash = {} + creator_hash[:p_id] = params["p_id"] + creator_hash[:username] = params["username"] + creator_hash[:avatar_url] = params["avatar_url"] + creator_hash[:provider] = params["provider"] + return creator_hash + end +end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb new file mode 100644 index 0000000..6806371 --- /dev/null +++ b/app/helpers/application_helper.rb @@ -0,0 +1,16 @@ +module ApplicationHelper + def bootstrap_class_for flash_type + case flash_type + when "success" + "alert-success" + when "error" + "alert-danger" + when "alert" + "alert-block" + when "notice" + "alert-info" + else + flash_type.to_s + end + end +end diff --git a/app/helpers/creators_helper.rb b/app/helpers/creators_helper.rb new file mode 100644 index 0000000..069187e --- /dev/null +++ b/app/helpers/creators_helper.rb @@ -0,0 +1,3 @@ +module CreatorsHelper + +end diff --git a/app/helpers/sessions_helper.rb b/app/helpers/sessions_helper.rb new file mode 100644 index 0000000..309f8b2 --- /dev/null +++ b/app/helpers/sessions_helper.rb @@ -0,0 +1,2 @@ +module SessionsHelper +end diff --git a/app/helpers/users_helper.rb b/app/helpers/users_helper.rb new file mode 100644 index 0000000..2310a24 --- /dev/null +++ b/app/helpers/users_helper.rb @@ -0,0 +1,2 @@ +module UsersHelper +end diff --git a/app/mailers/.keep b/app/mailers/.keep new file mode 100644 index 0000000..e69de29 diff --git a/app/models/.keep b/app/models/.keep new file mode 100644 index 0000000..e69de29 diff --git a/app/models/concerns/.keep b/app/models/concerns/.keep new file mode 100644 index 0000000..e69de29 diff --git a/app/models/content.rb b/app/models/content.rb new file mode 100644 index 0000000..0fb6e82 --- /dev/null +++ b/app/models/content.rb @@ -0,0 +1,5 @@ +class Content < ActiveRecord::Base + belongs_to :creator + validates :content_id, :text, :create_time, :creator_id, presence: true + +end diff --git a/app/models/creator.rb b/app/models/creator.rb new file mode 100644 index 0000000..e85f3f8 --- /dev/null +++ b/app/models/creator.rb @@ -0,0 +1,115 @@ +class Creator < ActiveRecord::Base + has_many :content + has_and_belongs_to_many :users + validates :p_id, :provider, :username, presence: true + + include HTTParty + LIMIT_PER_PAGE = 10 + + #method to configure twitter + def twit + Seemore::Application.config.twitter + end + + def has_image? + if avatar_url.nil? + false + else + true + end + end + +#calls methods for each provider + def get_content + if provider == "twitter" + get_tweets + elsif provider == "vimeo" + get_videos + else + raise "Content provider provided is not recognized (vimeo, twitter)." + end + self.last_updated = DateTime.now + self.save + end + +#method to call api for tweets and save to database + def get_tweets + tweet_array = twit.user_timeline(self.username) + save_tweets(tweet_array) + end + + def save_tweets(tweet_array) + tweet_array.each do |tweet| + #checks to see if that content already exists in the database + content = Content.find_by(content_id: tweet.id.to_s) + #creates new content if it does not exist + if content.nil? + Content.create( + content_id: tweet.id.to_s, + text: tweet.text, + create_time: DateTime.parse(tweet.created_at.to_s), + favorites: tweet.favorited?, + retweet_count: tweet.retweet_count, + creator_id: self.id, + provider: "twitter" + ) + end + end + end + + def get_videos + response = HTTParty.get("https://api.vimeo.com/users/#{self.p_id}/videos?per_page=#{LIMIT_PER_PAGE}", headers: {"Authorization" => "bearer #{ENV['VIMEO_ACCESS_TOKEN']}"}) + parsed_response = JSON.parse(response) + videos = parsed_response["data"] + save_videos(videos) + end + + def save_videos(videos) + videos.each do |vid| + #checks to see if content already exists + content = Content.find_by(content_id: vid["uri"].gsub(/[^\d]/, '')) + #if it doesn't exist, create new content with the vimeo data + if content.nil? + Content.create( + content_id: vid["uri"].gsub(/[^\d]/, ''), + text: vid["description"], + create_time: DateTime.parse(vid["created_time"].to_s), + favorites: vid["metadata"]["connections"]["likes"]["total"], + creator_id: self.id, + provider: "vimeo" + ) + end + end + end + + def self.make_vimeo_creators(vimeo_users) + videographers = [] + vimeo_users.each do |user| + videographer = Creator.new + videographer.p_id = user["uri"].sub("/users/", "") + videographer.provider = "vimeo" + videographer.username = user["name"] + videographer.avatar_url = user["pictures"]["sizes"][2]["link"] if user["pictures"] + # purposely do not save the videographer objects to the database, + # as this is only for displaying + videographers << videographer + end + return videographers + end + + def self.make_twitter_creators(twitter_users) + tweeters = [] + #makes a new creator for each returned object from twitter query + twitter_users.each do |user| + tweeter = Creator.new( + p_id: user.id, + provider: "twitter", + avatar_url: user.profile_image_url(size = :original), + username: user.screen_name, + ) + tweeters << tweeter + end + #returns an array of twitter creators + return tweeters + end +end diff --git a/app/models/user.rb b/app/models/user.rb new file mode 100644 index 0000000..3754f4a --- /dev/null +++ b/app/models/user.rb @@ -0,0 +1,38 @@ +class User < ActiveRecord::Base + validates :name, :uid, :provider, presence: true + has_and_belongs_to_many :creators + has_many :content, :through => :creators + + def self.find_or_create_from_omniauth(auth_hash) + user = self.find_by(uid: auth_hash["uid"], provider: auth_hash["provider"]) + if !user.nil? + return user + else + user = User.new + user.uid = auth_hash["uid"] + user.provider = auth_hash["provider"] + user.name = auth_hash["info"]["name"] + if user.save + user + else + nil + end + end + end + + # method checks if the user is already following the creator + # returns creator object/nil and boolean indicating whether user is already following creator + def following(provider, p_id) + creator = Creator.where("provider = ? AND p_id = ?", provider, p_id).first + if creator.nil? + # creator does not exist and user is not following it + return nil, false + elsif creators.include?(creator) + # creator exists and user is following it + return creator, true + else + # creator exists but user not following it + return creator, false + end + end +end diff --git a/app/views/creators/search.html.erb b/app/views/creators/search.html.erb new file mode 100644 index 0000000..aa82be0 --- /dev/null +++ b/app/views/creators/search.html.erb @@ -0,0 +1,37 @@ +
+ <% if @creators.length == 0 %> +

Sorry, your search did not come up with any results.

+ <% end %> + + <% @creators.each do |creator| %> + + <% end %> +
+
<%= will_paginate @creaters %>
diff --git a/app/views/layouts/_header.html.erb b/app/views/layouts/_header.html.erb new file mode 100644 index 0000000..687b880 --- /dev/null +++ b/app/views/layouts/_header.html.erb @@ -0,0 +1,5 @@ +
+
+ <%= link_to image_tag("illuminapeye.png"), root_path, class: "navbar brand" %> +
+
diff --git a/app/views/layouts/_navbar.html.erb b/app/views/layouts/_navbar.html.erb new file mode 100644 index 0000000..12d1d8b --- /dev/null +++ b/app/views/layouts/_navbar.html.erb @@ -0,0 +1,32 @@ + + diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb new file mode 100644 index 0000000..69f2bfe --- /dev/null +++ b/app/views/layouts/application.html.erb @@ -0,0 +1,22 @@ + + + + <%= favicon_link_tag 'favicon.ico' %> + + IlluminAPI + + <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %> + <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %> + <%= csrf_meta_tags %> + + + <%= render 'layouts/header' %> + <% if @current_user %> + <%= render 'layouts/navbar' %> + <% end %> +
+ <%= render partial: "shared/flash_messages", flash: flash %> + <%= yield %> +
+ + diff --git a/app/views/sessions/new.html.erb b/app/views/sessions/new.html.erb new file mode 100644 index 0000000..e0168d5 --- /dev/null +++ b/app/views/sessions/new.html.erb @@ -0,0 +1,10 @@ +
+ <%= link_to '/auth/twitter', class: "btn btn-lg btn-social btn-twitter" do %> + Sign in with Twitter + <% end %> +
+
+ <%= link_to '/auth/vimeo', class: "btn btn-lg btn-social btn-vimeo" do %> + Sign in with Vimeo + <% end %> +
diff --git a/app/views/shared/_flash_messages.html.erb b/app/views/shared/_flash_messages.html.erb new file mode 100644 index 0000000..23a1905 --- /dev/null +++ b/app/views/shared/_flash_messages.html.erb @@ -0,0 +1,6 @@ +<% flash.each do |type, message| %> +
+ + <%= message %> +
+<% end %> diff --git a/app/views/users/feed.html.erb b/app/views/users/feed.html.erb new file mode 100644 index 0000000..749afaa --- /dev/null +++ b/app/views/users/feed.html.erb @@ -0,0 +1,53 @@ +<% if @contents.length == 0 %> +

Use the illuminate search bar above to begin!

+<% end %> + + + + + +
+
+
+
+
+
+
+
+
+
+
+
+ + diff --git a/app/views/users/show.html.erb b/app/views/users/show.html.erb new file mode 100644 index 0000000..648317e --- /dev/null +++ b/app/views/users/show.html.erb @@ -0,0 +1,24 @@ +
+ <% if @creators.length == 0 %> +

You are not currently following any accounts -
Use the illuminate search bar above to begin!

+ <% end %> + + <% @creators.each do |creator| %> +
+ <% if creator.has_image?%> + <%= image_tag(creator.avatar_url, size:"100x100", class:"display-img") %> + <% else %> + <%= image_tag("noimage.png", size:"100x100") %> + <% end %> +

+ <% if creator.provider == "twitter" %> + + <% elsif creator.provider == "vimeo" %> + + <% end %> + <%= creator.username %> +
+ <%= link_to "✖︎", delete_creator_user_path(@current_user, provider: creator.provider, p_id: creator.p_id), class:"btn btn-sm btn-danger" %> +
+ <% end %> +
diff --git a/bin/bundle b/bin/bundle new file mode 100755 index 0000000..66e9889 --- /dev/null +++ b/bin/bundle @@ -0,0 +1,3 @@ +#!/usr/bin/env ruby +ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) +load Gem.bin_path('bundler', 'bundle') diff --git a/bin/rails b/bin/rails new file mode 100755 index 0000000..0138d79 --- /dev/null +++ b/bin/rails @@ -0,0 +1,9 @@ +#!/usr/bin/env ruby +begin + load File.expand_path('../spring', __FILE__) +rescue LoadError => e + raise unless e.message.include?('spring') +end +APP_PATH = File.expand_path('../../config/application', __FILE__) +require_relative '../config/boot' +require 'rails/commands' diff --git a/bin/rake b/bin/rake new file mode 100755 index 0000000..d87d5f5 --- /dev/null +++ b/bin/rake @@ -0,0 +1,9 @@ +#!/usr/bin/env ruby +begin + load File.expand_path('../spring', __FILE__) +rescue LoadError => e + raise unless e.message.include?('spring') +end +require_relative '../config/boot' +require 'rake' +Rake.application.run diff --git a/bin/setup b/bin/setup new file mode 100755 index 0000000..acdb2c1 --- /dev/null +++ b/bin/setup @@ -0,0 +1,29 @@ +#!/usr/bin/env ruby +require 'pathname' + +# path to your application root. +APP_ROOT = Pathname.new File.expand_path('../../', __FILE__) + +Dir.chdir APP_ROOT do + # This script is a starting point to setup your application. + # Add necessary setup steps to this file: + + puts "== Installing dependencies ==" + system "gem install bundler --conservative" + system "bundle check || bundle install" + + # puts "\n== Copying sample files ==" + # unless File.exist?("config/database.yml") + # system "cp config/database.yml.sample config/database.yml" + # end + + puts "\n== Preparing database ==" + system "bin/rake db:setup" + + puts "\n== Removing old logs and tempfiles ==" + system "rm -f log/*" + system "rm -rf tmp/cache" + + puts "\n== Restarting application server ==" + system "touch tmp/restart.txt" +end diff --git a/bin/spring b/bin/spring new file mode 100755 index 0000000..62ec28f --- /dev/null +++ b/bin/spring @@ -0,0 +1,15 @@ +#!/usr/bin/env ruby + +# This file loads spring without using Bundler, in order to be fast. +# It gets overwritten when you run the `spring binstub` command. + +unless defined?(Spring) + require 'rubygems' + require 'bundler' + + if (match = Bundler.default_lockfile.read.match(/^GEM$.*?^ (?: )*spring \((.*?)\)$.*?^$/m)) + Gem.paths = { 'GEM_PATH' => [Bundler.bundle_path.to_s, *Gem.path].uniq } + gem 'spring', match[1] + require 'spring/binstub' + end +end diff --git a/config.ru b/config.ru new file mode 100644 index 0000000..bd83b25 --- /dev/null +++ b/config.ru @@ -0,0 +1,4 @@ +# This file is used by Rack-based servers to start the application. + +require ::File.expand_path('../config/environment', __FILE__) +run Rails.application diff --git a/config/application.rb b/config/application.rb new file mode 100644 index 0000000..a6d8eb9 --- /dev/null +++ b/config/application.rb @@ -0,0 +1,35 @@ +require File.expand_path('../boot', __FILE__) + +require "rails" +# Pick the frameworks you want: +require "active_model/railtie" +require "active_job/railtie" +require "active_record/railtie" +require "action_controller/railtie" +require "action_mailer/railtie" +require "action_view/railtie" +require "sprockets/railtie" +# require "rails/test_unit/railtie" + +# Require the gems listed in Gemfile, including any gems +# you've limited to :test, :development, or :production. +Bundler.require(*Rails.groups) + +module Seemore + class Application < Rails::Application + # 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. + + # 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 + + # Do not swallow errors in after_commit/after_rollback callbacks. + config.active_record.raise_in_transactional_callbacks = true + end +end diff --git a/config/boot.rb b/config/boot.rb new file mode 100644 index 0000000..6b750f0 --- /dev/null +++ b/config/boot.rb @@ -0,0 +1,3 @@ +ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) + +require 'bundler/setup' # Set up gems listed in the Gemfile. diff --git a/config/database.yml b/config/database.yml new file mode 100644 index 0000000..1c1a37c --- /dev/null +++ b/config/database.yml @@ -0,0 +1,25 @@ +# SQLite version 3.x +# gem install sqlite3 +# +# Ensure the SQLite 3 gem is defined in your Gemfile +# gem 'sqlite3' +# +default: &default + adapter: sqlite3 + pool: 5 + timeout: 5000 + +development: + <<: *default + database: db/development.sqlite3 + +# Warning: The database defined as "test" will be erased and +# re-generated from your development database when you run "rake". +# Do not set this db to the same as development or production. +test: + <<: *default + database: db/test.sqlite3 + +production: + <<: *default + database: db/production.sqlite3 diff --git a/config/environment.rb b/config/environment.rb new file mode 100644 index 0000000..ee8d90d --- /dev/null +++ b/config/environment.rb @@ -0,0 +1,5 @@ +# Load the Rails application. +require File.expand_path('../application', __FILE__) + +# Initialize the Rails application. +Rails.application.initialize! diff --git a/config/environments/development.rb b/config/environments/development.rb new file mode 100644 index 0000000..b55e214 --- /dev/null +++ b/config/environments/development.rb @@ -0,0 +1,41 @@ +Rails.application.configure do + # Settings specified here will take precedence over those in config/application.rb. + + # In the development environment your application's code is reloaded on + # every request. This slows down response time but is perfect for development + # since you don't have to restart the web server when you make code changes. + config.cache_classes = false + + # Do not eager load code on boot. + config.eager_load = false + + # Show full error reports and disable caching. + config.consider_all_requests_local = true + config.action_controller.perform_caching = false + + # Don't care if the mailer can't send. + config.action_mailer.raise_delivery_errors = false + + # Print deprecation notices to the Rails logger. + config.active_support.deprecation = :log + + # Raise an error on page load if there are pending migrations. + config.active_record.migration_error = :page_load + + # Debug mode disables concatenation and preprocessing of assets. + # This option may cause significant delays in view rendering with a large + # number of complex assets. + config.assets.debug = true + + # Asset digests allow you to set far-future HTTP expiration dates on all assets, + # yet still be able to expire them through the digest params. + config.assets.digest = true + + # Adds additional error checking when serving assets at runtime. + # Checks for improperly declared sprockets dependencies. + # Raises helpful error messages. + config.assets.raise_runtime_errors = true + + # Raises error for missing translations + # config.action_view.raise_on_missing_translations = true +end diff --git a/config/environments/production.rb b/config/environments/production.rb new file mode 100644 index 0000000..5c1b32e --- /dev/null +++ b/config/environments/production.rb @@ -0,0 +1,79 @@ +Rails.application.configure do + # Settings specified here will take precedence over those in config/application.rb. + + # Code is not reloaded between requests. + config.cache_classes = true + + # Eager load code on boot. This eager loads most of Rails and + # your application in memory, allowing both threaded web servers + # and those relying on copy on write to perform better. + # Rake tasks automatically ignore this option for performance. + config.eager_load = true + + # Full error reports are disabled and caching is turned on. + config.consider_all_requests_local = false + config.action_controller.perform_caching = true + + # Enable Rack::Cache to put a simple HTTP cache in front of your application + # Add `rack-cache` to your Gemfile before enabling this. + # For large-scale production use, consider using a caching reverse proxy like + # NGINX, varnish or squid. + # config.action_dispatch.rack_cache = true + + # Disable serving static files from the `/public` folder by default since + # Apache or NGINX already handles this. + config.serve_static_files = ENV['RAILS_SERVE_STATIC_FILES'].present? + + # Compress JavaScripts and CSS. + config.assets.js_compressor = :uglifier + # config.assets.css_compressor = :sass + + # Do not fallback to assets pipeline if a precompiled asset is missed. + config.assets.compile = false + + # Asset digests allow you to set far-future HTTP expiration dates on all assets, + # yet still be able to expire them through the digest params. + config.assets.digest = true + + # `config.assets.precompile` and `config.assets.version` have moved to config/initializers/assets.rb + + # 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 + + # Use the lowest log level to ensure availability of diagnostic information + # when problems arise. + 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' + + # Ignore bad email addresses and do not raise email delivery errors. + # Set this to true and configure the email server for immediate delivery to raise delivery errors. + # config.action_mailer.raise_delivery_errors = false + + # Enable locale fallbacks for I18n (makes lookups for any locale fall back to + # the I18n.default_locale when a translation cannot be found). + config.i18n.fallbacks = true + + # Send deprecation notices to registered listeners. + config.active_support.deprecation = :notify + + # Use default logging formatter so that PID and timestamp are not suppressed. + config.log_formatter = ::Logger::Formatter.new + + # Do not dump schema after migrations. + config.active_record.dump_schema_after_migration = false +end diff --git a/config/environments/test.rb b/config/environments/test.rb new file mode 100644 index 0000000..1c19f08 --- /dev/null +++ b/config/environments/test.rb @@ -0,0 +1,42 @@ +Rails.application.configure do + # Settings specified here will take precedence over those in config/application.rb. + + # The test environment is used exclusively to run your application's + # test suite. You never need to work with it otherwise. Remember that + # your test database is "scratch space" for the test suite and is wiped + # and recreated between test runs. Don't rely on the data there! + config.cache_classes = true + + # Do not eager load code on boot. This avoids loading your whole application + # just for the purpose of running a single test. If you are using a tool that + # preloads Rails for running tests, you may have to set it to true. + config.eager_load = false + + # Configure static file server for tests with Cache-Control for performance. + config.serve_static_files = true + config.static_cache_control = 'public, max-age=3600' + + # Show full error reports and disable caching. + config.consider_all_requests_local = true + config.action_controller.perform_caching = false + + # Raise exceptions instead of rendering exception templates. + config.action_dispatch.show_exceptions = false + + # Disable request forgery protection in test environment. + config.action_controller.allow_forgery_protection = false + + # Tell Action Mailer not to deliver emails to the real world. + # The :test delivery method accumulates sent emails in the + # ActionMailer::Base.deliveries array. + config.action_mailer.delivery_method = :test + + # Randomize the order test cases are executed. + config.active_support.test_order = :random + + # Print deprecation notices to the stderr. + config.active_support.deprecation = :stderr + + # Raises error for missing translations + # config.action_view.raise_on_missing_translations = true +end diff --git a/config/initializers/assets.rb b/config/initializers/assets.rb new file mode 100644 index 0000000..6ca3105 --- /dev/null +++ b/config/initializers/assets.rb @@ -0,0 +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 = '1.0' + +# 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( search.js ) +Rails.application.config.assets.precompile += %w( favicon.ico ) diff --git a/config/initializers/backtrace_silencers.rb b/config/initializers/backtrace_silencers.rb new file mode 100644 index 0000000..59385cd --- /dev/null +++ b/config/initializers/backtrace_silencers.rb @@ -0,0 +1,7 @@ +# Be sure to restart your server when you modify this file. + +# You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. +# Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } + +# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. +# Rails.backtrace_cleaner.remove_silencers! diff --git a/config/initializers/cookies_serializer.rb b/config/initializers/cookies_serializer.rb new file mode 100644 index 0000000..7f70458 --- /dev/null +++ b/config/initializers/cookies_serializer.rb @@ -0,0 +1,3 @@ +# Be sure to restart your server when you modify this file. + +Rails.application.config.action_dispatch.cookies_serializer = :json diff --git a/config/initializers/filter_parameter_logging.rb b/config/initializers/filter_parameter_logging.rb new file mode 100644 index 0000000..4a994e1 --- /dev/null +++ b/config/initializers/filter_parameter_logging.rb @@ -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] diff --git a/config/initializers/inflections.rb b/config/initializers/inflections.rb new file mode 100644 index 0000000..ac033bf --- /dev/null +++ b/config/initializers/inflections.rb @@ -0,0 +1,16 @@ +# Be sure to restart your server when you modify this file. + +# Add new inflection rules using the following format. Inflections +# are locale specific, and you may define rules for as many different +# locales as you wish. All of these examples are active by default: +# ActiveSupport::Inflector.inflections(:en) do |inflect| +# inflect.plural /^(ox)$/i, '\1en' +# inflect.singular /^(ox)en/i, '\1' +# inflect.irregular 'person', 'people' +# inflect.uncountable %w( fish sheep ) +# end + +# These inflection rules are supported but not enabled by default: +# ActiveSupport::Inflector.inflections(:en) do |inflect| +# inflect.acronym 'RESTful' +# end diff --git a/config/initializers/mime_types.rb b/config/initializers/mime_types.rb new file mode 100644 index 0000000..dc18996 --- /dev/null +++ b/config/initializers/mime_types.rb @@ -0,0 +1,4 @@ +# Be sure to restart your server when you modify this file. + +# Add new mime types for use in respond_to blocks: +# Mime::Type.register "text/richtext", :rtf diff --git a/config/initializers/omniauth.rb b/config/initializers/omniauth.rb new file mode 100644 index 0000000..a61752b --- /dev/null +++ b/config/initializers/omniauth.rb @@ -0,0 +1,7 @@ +Rails.application.config.middleware.use OmniAuth::Builder do + provider :developer, + :fields => [:name, :uid], + :uid_field => :uid if Rails.env.development? + provider :vimeo, ENV['VIMEO_KEY'], ENV['VIMEO_SECRET'] + provider :twitter, ENV['TWITTER_KEY'], ENV['TWITTER_SECRET'] +end diff --git a/config/initializers/session_store.rb b/config/initializers/session_store.rb new file mode 100644 index 0000000..64e76c9 --- /dev/null +++ b/config/initializers/session_store.rb @@ -0,0 +1,3 @@ +# Be sure to restart your server when you modify this file. + +Rails.application.config.session_store :cookie_store, key: '_seemore_session' diff --git a/config/initializers/twitter.rb b/config/initializers/twitter.rb new file mode 100644 index 0000000..c197dfd --- /dev/null +++ b/config/initializers/twitter.rb @@ -0,0 +1,14 @@ +require 'twitter' + +class TwitterClient + def self.connect + client = Twitter::REST::Client.new do |config| + config.consumer_key = ENV["TWITTER_KEY"] + config.consumer_secret = ENV["TWITTER_SECRET"] + config.access_token = ENV["TWITTER_ACCESS_TOKEN"] + config.access_token_secret = ENV["TWITTER_ACCESS_TOKEN_SECRET"] + end + end +end + +Seemore::Application.config.twitter = TwitterClient.connect diff --git a/config/initializers/wrap_parameters.rb b/config/initializers/wrap_parameters.rb new file mode 100644 index 0000000..33725e9 --- /dev/null +++ b/config/initializers/wrap_parameters.rb @@ -0,0 +1,14 @@ +# Be sure to restart your server when you modify this file. + +# This file contains settings for ActionController::ParamsWrapper which +# is enabled by default. + +# Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. +ActiveSupport.on_load(:action_controller) do + wrap_parameters format: [:json] if respond_to?(:wrap_parameters) +end + +# To enable root element in JSON for ActiveRecord objects. +# ActiveSupport.on_load(:active_record) do +# self.include_root_in_json = true +# end diff --git a/config/locales/en.yml b/config/locales/en.yml new file mode 100644 index 0000000..0653957 --- /dev/null +++ b/config/locales/en.yml @@ -0,0 +1,23 @@ +# Files in the config/locales directory are used for internationalization +# and are automatically loaded by Rails. If you want to use locales other +# than English, add the necessary files in this directory. +# +# To use the locales, use `I18n.t`: +# +# I18n.t 'hello' +# +# In views, this is aliased to just `t`: +# +# <%= t('hello') %> +# +# To use a different locale, set it with `I18n.locale`: +# +# I18n.locale = :es +# +# This would use the information in config/locales/es.yml. +# +# To learn more, please read the Rails Internationalization guide +# available at http://guides.rubyonrails.org/i18n.html. + +en: + hello: "Hello world" diff --git a/config/routes.rb b/config/routes.rb new file mode 100644 index 0000000..91d0c2e --- /dev/null +++ b/config/routes.rb @@ -0,0 +1,14 @@ +Rails.application.routes.draw do + + root 'users#feed' + + match "/auth/:provider/callback" => "sessions#create", via: [:get, :post] + get "/login" => "sessions#new", as: :login + delete "/logout/" => "sessions#destroy", as: :logout + get "/search/" => "creators#search" + resources :users, only: [:show, :delete, :create, :update] do + get 'delete_creator', on: :member # with member, the url looks like: /users/:id/delete_creator + end + + +end diff --git a/config/secrets.yml b/config/secrets.yml new file mode 100644 index 0000000..6911b93 --- /dev/null +++ b/config/secrets.yml @@ -0,0 +1,22 @@ +# Be sure to restart your server when you modify this file. + +# Your secret key is used for verifying the integrity of signed cookies. +# If you change this key, all old signed cookies will become invalid! + +# Make sure the secret is at least 30 characters and all random, +# no regular words or you'll be exposed to dictionary attacks. +# You can use `rake secret` to generate a secure secret key. + +# Make sure the secrets in this file are kept private +# if you're sharing your code publicly. + +development: + secret_key_base: aafd3e1c62e2d26a7fd67bfea345208b5a9f957dabebc619539207ac5d4265ac7bddf98bcf2296eba58bf5176cb6ed2b62d88ba5189dc731c1fafbf7574c9bf4 + +test: + secret_key_base: d8dcf2fdcb98f18152e7e6ea52a4c6a0957829a173b0bd6432aa4a65dca3979adeb4d949fb75ce9a84de168a75f9db278b22c15e2852f5178c0abf99a621442c + +# Do not keep production secrets in the repository, +# instead read values from the environment. +production: + secret_key_base: <%= ENV["SECRET_KEY_BASE"] %> diff --git a/db/migrate/20160107184005_create_users.rb b/db/migrate/20160107184005_create_users.rb new file mode 100644 index 0000000..10eb3b3 --- /dev/null +++ b/db/migrate/20160107184005_create_users.rb @@ -0,0 +1,11 @@ +class CreateUsers < ActiveRecord::Migration + def change + create_table :users do |t| + t.string :uid + t.string :provider + t.string :name + + t.timestamps null: false + end + end +end diff --git a/db/migrate/20160108225319_create_creators.rb b/db/migrate/20160108225319_create_creators.rb new file mode 100644 index 0000000..60f5333 --- /dev/null +++ b/db/migrate/20160108225319_create_creators.rb @@ -0,0 +1,12 @@ +class CreateCreators < ActiveRecord::Migration + def change + create_table :creators do |t| + t.integer :p_id + t.string :provider + t.string :avatar_url + t.string :username + + t.timestamps null: false + end + end +end diff --git a/db/migrate/20160108225555_create_contents.rb b/db/migrate/20160108225555_create_contents.rb new file mode 100644 index 0000000..276eca2 --- /dev/null +++ b/db/migrate/20160108225555_create_contents.rb @@ -0,0 +1,16 @@ +class CreateContents < ActiveRecord::Migration + def change + create_table :contents do |t| + t.integer :content_id + t.string :text + t.string :create_time + t.integer :favorites + t.string :embed_code + t.integer :retweet_count + t.integer :p_id + + t.timestamps null: false + end + add_index :contents, :p_id + end +end diff --git a/db/migrate/20160108230950_remove_pid_from_content.rb b/db/migrate/20160108230950_remove_pid_from_content.rb new file mode 100644 index 0000000..a79b713 --- /dev/null +++ b/db/migrate/20160108230950_remove_pid_from_content.rb @@ -0,0 +1,7 @@ +class RemovePidFromContent < ActiveRecord::Migration + def change + remove_column :contents, :p_id + add_column :contents, :creator_id, :integer + add_index :contents, :creator_id + end +end diff --git a/db/migrate/20160111192700_users_creators.rb b/db/migrate/20160111192700_users_creators.rb new file mode 100644 index 0000000..0ab5721 --- /dev/null +++ b/db/migrate/20160111192700_users_creators.rb @@ -0,0 +1,8 @@ +class UsersCreators < ActiveRecord::Migration + def change + create_table :users_creators, id: false do |t| + t.belongs_to :user, index: true + t.belongs_to :creator, index: true + end + end +end diff --git a/db/migrate/20160111193034_users_models.rb b/db/migrate/20160111193034_users_models.rb new file mode 100644 index 0000000..c6a722e --- /dev/null +++ b/db/migrate/20160111193034_users_models.rb @@ -0,0 +1,8 @@ +class UsersModels < ActiveRecord::Migration + def change + create_table :creators_users, id: false do |t| + t.belongs_to :creator, index: true + t.belongs_to :user, index: true + end + end +end diff --git a/db/migrate/20160112171348_change_id_type.rb b/db/migrate/20160112171348_change_id_type.rb new file mode 100644 index 0000000..bd14872 --- /dev/null +++ b/db/migrate/20160112171348_change_id_type.rb @@ -0,0 +1,5 @@ +class ChangeIdType < ActiveRecord::Migration + def change + change_column :contents, :content_id, :string + end +end diff --git a/db/migrate/20160112175253_add_columns_to_contents.rb b/db/migrate/20160112175253_add_columns_to_contents.rb new file mode 100644 index 0000000..b5cb25e --- /dev/null +++ b/db/migrate/20160112175253_add_columns_to_contents.rb @@ -0,0 +1,5 @@ +class AddColumnsToContents < ActiveRecord::Migration + def change + add_column :contents, :provider, :string + end +end diff --git a/db/migrate/20160113180525_change_creator.rb b/db/migrate/20160113180525_change_creator.rb new file mode 100644 index 0000000..ea40838 --- /dev/null +++ b/db/migrate/20160113180525_change_creator.rb @@ -0,0 +1,5 @@ +class ChangeCreator < ActiveRecord::Migration + def change + change_column :creators, :p_id, :string + end +end diff --git a/db/migrate/20160114171839_add_last_updated_to_creators.rb b/db/migrate/20160114171839_add_last_updated_to_creators.rb new file mode 100644 index 0000000..c5189b1 --- /dev/null +++ b/db/migrate/20160114171839_add_last_updated_to_creators.rb @@ -0,0 +1,5 @@ +class AddLastUpdatedToCreators < ActiveRecord::Migration + def change + add_column :creators, :last_updated, :datetime + end +end diff --git a/db/schema.rb b/db/schema.rb new file mode 100644 index 0000000..b87e797 --- /dev/null +++ b/db/schema.rb @@ -0,0 +1,65 @@ +# encoding: UTF-8 +# 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 +# incrementally modify your database, and then regenerate this schema definition. +# +# Note that this schema.rb definition is the authoritative source for your +# database schema. If you need to create the application database on another +# system, you should be using db:schema:load, not running all the migrations +# from scratch. The latter is a flawed and unsustainable approach (the more migrations +# you'll amass, the slower it'll run and the greater likelihood for issues). +# +# It's strongly recommended that you check this file into your version control system. + +ActiveRecord::Schema.define(version: 20160114171839) do + + create_table "contents", force: :cascade do |t| + t.string "content_id" + t.string "text" + t.string "create_time" + t.integer "favorites" + t.string "embed_code" + t.integer "retweet_count" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.integer "creator_id" + t.string "provider" + end + + add_index "contents", ["creator_id"], name: "index_contents_on_creator_id" + + create_table "creators", force: :cascade do |t| + t.string "p_id" + t.string "provider" + t.string "avatar_url" + t.string "username" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.datetime "last_updated" + end + + create_table "creators_users", id: false, force: :cascade do |t| + t.integer "creator_id" + t.integer "user_id" + end + + add_index "creators_users", ["creator_id"], name: "index_creators_users_on_creator_id" + add_index "creators_users", ["user_id"], name: "index_creators_users_on_user_id" + + create_table "users", force: :cascade do |t| + t.string "uid" + t.string "provider" + t.string "name" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + create_table "users_creators", id: false, force: :cascade do |t| + t.integer "user_id" + t.integer "creator_id" + end + + add_index "users_creators", ["creator_id"], name: "index_users_creators_on_creator_id" + add_index "users_creators", ["user_id"], name: "index_users_creators_on_user_id" + +end diff --git a/db/seeds.rb b/db/seeds.rb new file mode 100644 index 0000000..4edb1e8 --- /dev/null +++ b/db/seeds.rb @@ -0,0 +1,7 @@ +# This file should contain all the record creation needed to seed the database with its default values. +# The data can then be loaded with the rake db:seed (or created alongside the db with db:setup). +# +# Examples: +# +# cities = City.create([{ name: 'Chicago' }, { name: 'Copenhagen' }]) +# Mayor.create(name: 'Emanuel', city: cities.first) diff --git a/lib/assets/.keep b/lib/assets/.keep new file mode 100644 index 0000000..e69de29 diff --git a/lib/tasks/.keep b/lib/tasks/.keep new file mode 100644 index 0000000..e69de29 diff --git a/log/.keep b/log/.keep new file mode 100644 index 0000000..e69de29 diff --git a/public/404.html b/public/404.html new file mode 100644 index 0000000..b612547 --- /dev/null +++ b/public/404.html @@ -0,0 +1,67 @@ + + + + The page you were looking for doesn't exist (404) + + + + + + +
+
+

The page you were looking for doesn't exist.

+

You may have mistyped the address or the page may have moved.

+
+

If you are the application owner check the logs for more information.

+
+ + diff --git a/public/422.html b/public/422.html new file mode 100644 index 0000000..a21f82b --- /dev/null +++ b/public/422.html @@ -0,0 +1,67 @@ + + + + The change you wanted was rejected (422) + + + + + + +
+
+

The change you wanted was rejected.

+

Maybe you tried to change something you didn't have access to.

+
+

If you are the application owner check the logs for more information.

+
+ + diff --git a/public/500.html b/public/500.html new file mode 100644 index 0000000..061abc5 --- /dev/null +++ b/public/500.html @@ -0,0 +1,66 @@ + + + + We're sorry, but something went wrong (500) + + + + + + +
+
+

We're sorry, but something went wrong.

+
+

If you are the application owner check the logs for more information.

+
+ + diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000..e69de29 diff --git a/public/robots.txt b/public/robots.txt new file mode 100644 index 0000000..3c9c7c0 --- /dev/null +++ b/public/robots.txt @@ -0,0 +1,5 @@ +# See http://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file +# +# To ban all spiders from the entire site uncomment the next two lines: +# User-agent: * +# Disallow: / diff --git a/spec/controllers/creators_controller_spec.rb b/spec/controllers/creators_controller_spec.rb new file mode 100644 index 0000000..6a3d088 --- /dev/null +++ b/spec/controllers/creators_controller_spec.rb @@ -0,0 +1,45 @@ +require 'rails_helper' + +RSpec.describe CreatorsController, type: :controller do + + describe "GET#search" do + let (:vimeo_search_params) { + { query: "Hello", + provider: "vimeo" } + } + let (:twitter_search_params) { + { query: "Hello", + provider: "twitter" } + } + let (:invalid_search_params) { + { query: "" } + } + let (:user) { create(:user) } + + context "blank search" do + it "creates a flash message" do + get :search, invalid_search_params + expect(flash["error"]).to_not be_nil + end + + it "redirects to root_path" do + get :search, invalid_search_params, user_id: user.id + expect(subject).to redirect_to root_path + end + end + + context "vimeo query" do + it "redirects to search page" do + get :search, vimeo_search_params, user_id: user.id + expect(subject).to render_template :search + end + end + + context "twitter query" do + it "returns an array of Creators from twitter" do + get :search, twitter_search_params, user_id: user.id + expect(subject).to render_template :search + end + end + end +end diff --git a/spec/controllers/sessions_controller_spec.rb b/spec/controllers/sessions_controller_spec.rb new file mode 100644 index 0000000..07f7d49 --- /dev/null +++ b/spec/controllers/sessions_controller_spec.rb @@ -0,0 +1,16 @@ +require 'rails_helper' +require './spec/support/shared_tests' + +RSpec.describe SessionsController, type: :controller do + context "when using twitter authentication" do + it_behaves_like "an auth controller" do + let(:auth_provider) { :twitter } + end + end + + context "when using vimeo authentication" do + it_behaves_like "an auth controller" do + let(:auth_provider) { :vimeo } + end + end +end diff --git a/spec/controllers/users_controller_spec.rb b/spec/controllers/users_controller_spec.rb new file mode 100644 index 0000000..6cc5834 --- /dev/null +++ b/spec/controllers/users_controller_spec.rb @@ -0,0 +1,79 @@ +require 'rails_helper' + +RSpec.describe UsersController, type: :controller do + # before { request.env["omniauth.auth"] = OmniAuth.config.mock_auth[:twitter] } + let(:user) { create(:developer_user) } + let(:creator) { create(:twitter_creator) } + + describe "GET #show" do + it "renders the show view" do + get :show, {id: user.id}, user_id: user.id + expect(subject).to render_template :show + end + it "assigns current user's creators as @creators" do + user.creators << creator + creators = user.creators + get :show, {id: user.id}, user_id: user.id + expect(assigns(:creators)).to eq creators + end + end + + describe "GET #feed" do + context "user is logged in" do + let (:params) do + {p_id: "154915030", + username: "stillkidrauhl", + avatar_url: "avatar_url.com", + provider: "twitter", + id: user.id} + end + it "renders feed template" do + get :feed, {id: user.id}, user_id: user.id + expect(subject).to render_template :feed + end + end + end + + describe "PATCH #update" do + context "creator does not exist" do + let (:params) do + {p_id: "154915030", + username: "stillkidrauhl", + avatar_url: "avatar_url.com", + provider: "twitter", + id: user.id} + end + # test needs to have user logged in for a creator to be created or assigned + it "makes a new creator" do + @count = user.creators.all.count + # session[:user_id] = user.id + patch :update, params, user_id: user.id + expect(user.creators.all.count).to eq(@count + 1) + end + it "gets the content for the new creator" do + patch :update, params, user_id: user.id + expect(Creator.last.content[0]).is_a?(Content) + end + end + end + + describe "GET #delete_creator" do + context "creator is no longer followed" do + let (:params) do + {p_id: "154915030", + username: "stillkidrauhl", + avatar_url: "avatar_url.com", + provider: "twitter", + id: user.id} + end + before :each do + patch :update, params, user_id: user.id + end + it "deletes the creator" do + @count = user.creators.all.count + get :delete_creator, params, user_id: user.id + expect(user.creators.all.count).to eq(@count - 1) + end + end + end +end diff --git a/spec/factories.rb b/spec/factories.rb new file mode 100644 index 0000000..4fd820c --- /dev/null +++ b/spec/factories.rb @@ -0,0 +1,25 @@ +FactoryGirl.define do + factory :twitter_creator, class: Creator do + p_id 1621062337 + username "adaacademy" + provider "twitter" + end + + factory :vimeo_creator, class: Creator do + p_id 9573882 + username "Sleepy Puppies" + provider "vimeo" + end + + factory :developer_user, class: User do + name "Ada Lovelace" + uid 1234 + provider "developer" + end + + factory :user, class: User do + name "Ada" + uid "1234" + provider "twitter" + end +end diff --git a/spec/helpers/creators_helper_spec.rb b/spec/helpers/creators_helper_spec.rb new file mode 100644 index 0000000..b3dae36 --- /dev/null +++ b/spec/helpers/creators_helper_spec.rb @@ -0,0 +1,14 @@ +require 'rails_helper' + +# Specs in this file have access to a helper object that includes +# the CreatorsHelper. For example: +# +# describe CreatorsHelper 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 CreatorsHelper, type: :helper do +end diff --git a/spec/helpers/sessions_helper_spec.rb b/spec/helpers/sessions_helper_spec.rb new file mode 100644 index 0000000..38c13fc --- /dev/null +++ b/spec/helpers/sessions_helper_spec.rb @@ -0,0 +1,14 @@ +require 'rails_helper' + +# Specs in this file have access to a helper object that includes +# the SessionsHelper. For example: +# +# describe SessionsHelper 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 SessionsHelper, type: :helper do +end diff --git a/spec/helpers/users_helper_spec.rb b/spec/helpers/users_helper_spec.rb new file mode 100644 index 0000000..890768c --- /dev/null +++ b/spec/helpers/users_helper_spec.rb @@ -0,0 +1,14 @@ +require 'rails_helper' + +# Specs in this file have access to a helper object that includes +# the UsersHelper. For example: +# +# describe UsersHelper 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 UsersHelper, type: :helper do +end diff --git a/spec/models/content_spec.rb b/spec/models/content_spec.rb new file mode 100644 index 0000000..4513013 --- /dev/null +++ b/spec/models/content_spec.rb @@ -0,0 +1,8 @@ +require 'rails_helper' + +RSpec.describe Content, type: :model do + it { is_expected.to validate_presence_of(:content_id) } + it { is_expected.to validate_presence_of(:text) } + it { is_expected.to validate_presence_of(:create_time) } + it { is_expected.to validate_presence_of(:creator_id) } +end diff --git a/spec/models/creator_spec.rb b/spec/models/creator_spec.rb new file mode 100644 index 0000000..369a78e --- /dev/null +++ b/spec/models/creator_spec.rb @@ -0,0 +1,55 @@ +require 'rails_helper' + +RSpec.describe Creator, type: :model do + it { is_expected.to validate_presence_of(:p_id) } + it { is_expected.to validate_presence_of(:provider) } + it { is_expected.to validate_presence_of(:username) } + + describe "has_image?" do + context "creator is from twitter" do + let(:creator) { build(:twitter_creator) } + it "returns true when creator object has image" do + creator.avatar_url = "abc" + expect(creator.has_image?).to be true + end + it "returns false when creator object has no image" do + expect(creator.has_image?).to be false + end + end + context "creator is from vimeo" do + let(:creator) { build(:vimeo_creator) } + it "returns true when creator object has image" do + creator.avatar_url = "abc" + expect(creator.has_image?).to be true + end + it "returns false when creator object has no image" do + expect(creator.has_image?).to be false + end + end + end + + describe "get_content" do + context "creator is from twitter" do + let(:twitter_creator){ create(:twitter_creator) } + it "saves content from twitter to Content database" do + count = twitter_creator.content.count + expect(twitter_creator.get_content).to be true + expect(twitter_creator.content.count).to_not be count + end + end + context "creator is from vimeo" do + let(:vimeo_creator) { create(:vimeo_creator) } + it "saves content from vimeo to Content database" do + count = vimeo_creator.content.count + expect(vimeo_creator.get_content).to be true + expect(vimeo_creator.content.count).to_not be count + end + end + context "creator is not recognized" do + let(:invalid_creator) { build(:vimeo_creator, provider: "random") } + it "raises an error" do + expect{invalid_creator.get_content}.to raise_error(RuntimeError, "Content provider provided is not recognized (vimeo, twitter).") + end + end + end +end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb new file mode 100644 index 0000000..b813321 --- /dev/null +++ b/spec/models/user_spec.rb @@ -0,0 +1,59 @@ +require 'rails_helper' + +RSpec.describe User, type: :model do + it { is_expected.to validate_presence_of(:name) } + it { is_expected.to validate_presence_of(:uid) } + it { is_expected.to validate_presence_of(:provider) } + + describe ".initialize_from_omniauth" do + let(:user) { User.find_or_create_from_omniauth(OmniAuth.config.mock_auth[:vimeo]) } + + it "creates a valid user" do + expect(user).to be_valid + end + + context "when it's invalid" do + it "returns nil" do + user = User.find_or_create_from_omniauth({"uid" => "123", "info" => {}}) + expect(user).to be_nil + end + end + + context "when the user has already logged in" do + it "returns user" do + user + user = User.find_or_create_from_omniauth(OmniAuth.config.mock_auth[:vimeo]) + expect(user).to be_an_instance_of(User) + end + end + end + + describe "following" do + let(:user) { create(:developer_user) } + context "creator does not exist" do + it "returns nil for creator and false for following" do + creator, following = user.following("twitter", 1234) + expect(creator).to be_nil + expect(following).to be false + end + end + context "creator exists" do + let!(:twitter_creator) { create(:twitter_creator) } + context "user not following" do + it "returns creator and false for following" do + creator, following = user.following(twitter_creator.provider, twitter_creator.p_id) + expect(creator).to eq twitter_creator + expect(following).to be false + end + end + context "user following" do + it "returns creator and true for following" do + user.creators << twitter_creator + creator, following = user.following(twitter_creator.provider, twitter_creator.p_id) + expect(creator).to eq twitter_creator + expect(following).to be true + end + end + end + end +end diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb new file mode 100644 index 0000000..55e1f0f --- /dev/null +++ b/spec/rails_helper.rb @@ -0,0 +1,72 @@ +require 'simplecov' + +SimpleCov.start('rails') do + add_filter 'spec/' + add_filter '/helpers/' +end + +# This file is copied to spec/ when you run 'rails generate rspec:install' +ENV['RAILS_ENV'] ||= 'test' +require File.expand_path('../../config/environment', __FILE__) +# Prevent database truncation if the environment is production +abort("The Rails environment is running in production mode!") if Rails.env.production? +require 'spec_helper' +require 'rspec/rails' +require 'shoulda-matchers' +# 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 migration and applies them 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! + + # Filter lines from Rails gems in backtraces. + config.filter_rails_from_backtrace! + # arbitrary gems may also be filtered via: + # config.filter_gems_from_backtrace("gem name") +end + +Shoulda::Matchers.configure do |config| + config.integrate do |with| + with.test_framework :rspec + with.library :rails + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb new file mode 100644 index 0000000..ec7825f --- /dev/null +++ b/spec/spec_helper.rb @@ -0,0 +1,121 @@ +require 'rails_helper' +require 'factory_girl' + +# 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| + config.before(:suite) do + # Once you have enabled test mode, all requests + # to OmniAuth will be short circuited + # to use the mock authentication hash. + # A request to /auth/provider will redirect + # immediately to /auth/provider/callback. + + OmniAuth.config.test_mode = true + +# The mock_auth configuration allows you to + # set per-provider (or default) authentication + # hashes to return during testing. + + OmniAuth.config.mock_auth[:twitter] = OmniAuth::AuthHash.new( + { :provider => 'twitter', :uid => '123545', info: + {email: "a@b.com", name: "Ada"} + }) + + OmniAuth.config.mock_auth[:vimeo] = OmniAuth::AuthHash.new( + { :provider => 'vimeo', :uid => '123545', info: + { email: "a@b.com", name: "Ada" } + }) + end + + # 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 + + 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 + # 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 + + # Allows RSpec to persist some state between runs in order to support + # the `--only-failures` and `--next-failure` CLI options. We recommend + # you configure your source control system to ignore this file. + config.example_status_persistence_file_path = "spec/examples.txt" + + # Limits the available syntax to the non-monkey patched syntax that is + # recommended. For more details, see: + # - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/ + # - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/ + # - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode + 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/support/shared_tests.rb b/spec/support/shared_tests.rb new file mode 100644 index 0000000..6604d1b --- /dev/null +++ b/spec/support/shared_tests.rb @@ -0,0 +1,75 @@ +include Rails.application.routes.url_helpers + +shared_examples_for "an auth controller" do + context "when using auth_provider authentication" do + context "is successful" do + before { request.env["omniauth.auth"] = OmniAuth.config.mock_auth[auth_provider] } + + it "redirects to home page" do + get :create, provider: auth_provider + expect(response).to redirect_to root_path + end + + it "creates a user" do + expect { get :create, provider: auth_provider }.to change(User, :count).by(1) + end + + it "assigns the @user var" do + get :create, provider: auth_provider + expect(assigns(:user)).to be_an_instance_of User + end + + it "assigns the session[:user_id]" do + get :create, provider: auth_provider + expect(session[:user_id]).to eq assigns(:user).id + end + end + + context "when the user has already signed up" do + before { request.env["omniauth.auth"] = OmniAuth.config.mock_auth[auth_provider] } + let!(:user) { User.find_or_create_from_omniauth(OmniAuth.config.mock_auth[auth_provider]) } + + it "doesn't create another user" do + expect { get :create, provider: auth_provider }.to change(User, :count).by(0) + end + + it "assigns the session[:user_id]" do + get :create, provider: auth_provider + expect(session[:user_id]).to eq user.id + end + end + + context "fails on auth_provider" do + before { request.env["omniauth.auth"] = :invalid_credential } + + it "redirect to home with flash error" do + get :create, provider: auth_provider + expect(response).to redirect_to root_path + expect(flash[:notice]).to include "Failed to authenticate" + end + end + + context "when failing to save the user" do + before { + request.env["omniauth.auth"] = {"uid" => "1234", "info" => {}} + } + + it "redirect to home with flash error" do + get :create, provider: auth_provider + expect(response).to redirect_to root_path + expect(flash[:notice]).to include "Failed to save the user" + end + end + + describe "destroy" do + it "removes user_id from session" do + delete :destroy + expect(session[:user_id]).to be_nil + end + it "redirects to login_path" do + delete :destroy + expect(subject).to redirect_to login_path + end + end + end +end diff --git a/vendor/assets/javascripts/.keep b/vendor/assets/javascripts/.keep new file mode 100644 index 0000000..e69de29 diff --git a/vendor/assets/stylesheets/.keep b/vendor/assets/stylesheets/.keep new file mode 100644 index 0000000..e69de29