diff --git a/.gitignore b/.gitignore index 03f3ce7..edd0586 100644 --- a/.gitignore +++ b/.gitignore @@ -63,3 +63,7 @@ build-iPhoneSimulator/ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this: .rvmrc + +/.env + +config/initializers/yelp.rb diff --git a/Gemfile b/Gemfile index 288bb87..9b7f1e7 100644 --- a/Gemfile +++ b/Gemfile @@ -23,23 +23,47 @@ gem 'sdoc', '~> 0.4.0', group: :doc # Use ActiveModel has_secure_password # gem 'bcrypt', '~> 3.1.7' - +gem 'httparty' # Use Unicorn as the app server # gem 'unicorn' # Use Capistrano for deployment # gem 'capistrano-rails', group: :development +gem 'yelp', require: 'yelp' +gem 'rspotify', require: 'rspotify' + +gem 'rest-client' +gem "omniauth" +gem 'omniauth-spotify' +gem 'omniauth-oauth2', '~> 1.3.1' + + group :development, :test do # Call 'byebug' anywhere in the code to stop execution and get a debugger console gem 'byebug' + gem 'dotenv-rails' + gem 'pry-rails' + gem 'minitest-vcr' + gem 'minitest-reporters' + gem 'webmock' + gem 'simplecov' + end group :development do # Access an IRB console on exception pages or by using <%= console %> in views gem 'web-console', '~> 2.0' - + gem 'better_errors' + gem 'pry-rails' + gem 'erd' + gem 'bootstrap-sass', '~>3.2.0' + gem "binding_of_caller" + gem "rest-client" # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring gem 'spring' end +group :production do + gem 'rails_12factor' +end diff --git a/Gemfile.lock b/Gemfile.lock index 6ff0f39..f5ffd9b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -36,11 +36,21 @@ GEM minitest (~> 5.1) thread_safe (~> 0.3, >= 0.3.4) tzinfo (~> 1.1) + addressable (2.4.0) + ansi (1.5.0) arel (6.0.3) + 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.2.0.2) + sass (~> 3.2) builder (3.2.2) - byebug (8.2.5) + byebug (9.0.3) + choice (0.2.0) + coderay (1.1.1) coffee-rails (4.1.1) coffee-script (>= 2.2.0) railties (>= 4.0.0, < 5.1.x) @@ -49,11 +59,34 @@ GEM execjs coffee-script-source (1.10.0) concurrent-ruby (1.0.2) + crack (0.4.3) + safe_yaml (~> 1.0.0) debug_inspector (0.0.2) + docile (1.1.5) + domain_name (0.5.20160310) + unf (>= 0.0.5, < 1.0.0) + dotenv (2.1.1) + dotenv-rails (2.1.1) + dotenv (= 2.1.1) + railties (>= 4.0, < 5.1) + erd (0.4.0) + nokogiri + rails-erd (>= 0.4.5) erubis (2.7.0) execjs (2.6.0) + faraday (0.9.2) + multipart-post (>= 1.2, < 3) + faraday_middleware (0.10.0) + faraday (>= 0.7.4, < 0.10) globalid (0.3.6) activesupport (>= 4.1.0) + hashdiff (0.3.0) + hashie (3.4.4) + http-cookie (1.0.2) + domain_name (~> 0.5) + httparty (0.13.7) + json (~> 1.8) + multi_xml (>= 0.5.2) i18n (0.7.0) jbuilder (2.4.1) activesupport (>= 3.0.0, < 5.1) @@ -63,19 +96,53 @@ GEM railties (>= 4.2.0) thor (>= 0.14, < 2.0) json (1.8.3) + jwt (1.5.1) loofah (2.0.3) nokogiri (>= 1.5.9) mail (2.6.4) mime-types (>= 1.16, < 4) - mime-types (3.0) - mime-types-data (~> 3.2015) - mime-types-data (3.2016.0221) + method_source (0.8.2) + mime-types (2.99.1) mini_portile2 (2.0.0) - minitest (5.8.4) - multi_json (1.12.0) + minispec-metadata (2.0.0) + minitest + minitest (5.9.0) + minitest-reporters (1.1.9) + ansi + builder + minitest (>= 5.0) + ruby-progressbar + minitest-vcr (1.4.0) + minispec-metadata (~> 2.0) + minitest (>= 4.7.5) + vcr (>= 2.9) + multi_json (1.12.1) + multi_xml (0.5.5) + multipart-post (2.0.0) + netrc (0.11.0) nokogiri (1.6.7.2) mini_portile2 (~> 2.0.0.rc2) + oauth2 (1.1.0) + faraday (>= 0.8, < 0.10) + jwt (~> 1.0, < 1.5.2) + multi_json (~> 1.3) + multi_xml (~> 0.5) + rack (>= 1.2, < 3) + omniauth (1.3.1) + hashie (>= 1.2, < 4) + rack (>= 1.0, < 3) + omniauth-oauth2 (1.3.1) + oauth2 (~> 1.0) + omniauth (~> 1.2) + omniauth-spotify (0.0.9) + omniauth-oauth2 (~> 1.1) pg (0.18.4) + pry (0.10.3) + coderay (~> 1.1.0) + method_source (~> 0.8.1) + slop (~> 3.4) + pry-rails (0.3.4) + pry (>= 0.9.10) rack (1.6.4) rack-test (0.6.3) rack (>= 1.0) @@ -96,8 +163,18 @@ GEM activesupport (>= 4.2.0.beta, < 5.0) nokogiri (~> 1.6.0) rails-deprecated_sanitizer (>= 1.0.1) + rails-erd (1.4.7) + activerecord (>= 3.2) + activesupport (>= 3.2) + choice (~> 0.2.0) + ruby-graphviz (~> 1.2) rails-html-sanitizer (1.0.3) loofah (~> 2.0) + rails_12factor (0.0.3) + rails_serve_static_assets + rails_stdout_logging + rails_serve_static_assets (0.0.5) + rails_stdout_logging (0.0.5) railties (4.2.6) actionpack (= 4.2.6) activesupport (= 4.2.6) @@ -106,6 +183,16 @@ GEM rake (11.1.2) rdoc (4.2.2) json (~> 1.4) + rest-client (1.8.0) + http-cookie (>= 1.0.2, < 2.0) + mime-types (>= 1.16, < 3.0) + netrc (~> 0.7) + rspotify (1.18.0) + omniauth-oauth2 (~> 1.3.1) + rest-client (~> 1.7) + ruby-graphviz (1.2.2) + ruby-progressbar (1.8.1) + safe_yaml (1.0.4) sass (3.4.22) sass-rails (5.0.4) railties (>= 4.0.0, < 5.0) @@ -116,6 +203,13 @@ GEM sdoc (0.4.1) json (~> 1.7, >= 1.7.7) rdoc (~> 4.0) + simple_oauth (0.3.1) + simplecov (0.11.2) + docile (~> 1.1.0) + json (~> 1.8) + simplecov-html (~> 0.10.0) + simplecov-html (0.10.0) + slop (3.6.0) spring (1.7.1) sprockets (3.6.0) concurrent-ruby (~> 1.0) @@ -126,32 +220,65 @@ GEM sprockets (>= 3.0.0) thor (0.19.1) thread_safe (0.3.5) - tilt (2.0.2) + tilt (2.0.4) tzinfo (1.2.2) thread_safe (~> 0.1) uglifier (3.0.0) execjs (>= 0.3.0, < 3) + unf (0.1.4) + unf_ext + unf_ext (0.0.7.2) + vcr (3.0.3) web-console (2.3.0) activemodel (>= 4.0) binding_of_caller (>= 0.7.2) railties (>= 4.0) sprockets-rails (>= 2.0, < 4.0) + webmock (2.0.3) + addressable (>= 2.3.6) + crack (>= 0.3.2) + hashdiff + yelp (2.1.2) + faraday (~> 0.8, >= 0.8.0) + faraday_middleware (~> 0.8, >= 0.8.0) + simple_oauth (~> 0.3.1) PLATFORMS ruby DEPENDENCIES + better_errors + binding_of_caller + bootstrap-sass (~> 3.2.0) byebug coffee-rails (~> 4.1.0) + dotenv-rails + erd + httparty jbuilder (~> 2.0) jquery-rails + minitest-reporters + minitest-vcr + omniauth + omniauth-oauth2 (~> 1.3.1) + omniauth-spotify pg (~> 0.15) + pry-rails rails (= 4.2.6) + rails_12factor + rest-client + rspotify sass-rails (~> 5.0) sdoc (~> 0.4.0) + simplecov spring uglifier (>= 1.3.0) web-console (~> 2.0) + webmock + yelp + +RUBY VERSION + ruby 2.3.1p112 BUNDLED WITH - 1.12.3 + 1.12.4 diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 646c5ab..4f6c679 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -13,3 +13,71 @@ //= require jquery //= require jquery_ujs //= require_tree . +$(document).ready(function() { +$(".btn-pref .btn").click(function () { + $(".btn-pref .btn").removeClass("btn-primary").addClass("btn-default"); + // $(".tab").addClass("active"); // instead of this do the below + $(this).removeClass("btn-default").addClass("btn-primary"); +}); +}); + +(function() { + + function login(callback) { + var CLIENT_ID = '6b284830006843e7ae7b170725715aed'; + var REDIRECT_URI = 'http://jmperezperez.com/spotify-oauth-jsfiddle-proxy/'; + function getLoginURL(scopes) { + return 'https://accounts.spotify.com/authorize?client_id=' + CLIENT_ID + + '&redirect_uri=' + encodeURIComponent(REDIRECT_URI) + + '&scope=' + encodeURIComponent(scopes.join(' ')) + + '&response_type=token'; + } + + var url = getLoginURL([ + 'user-read-email' + ]); + + var width = 450, + height = 730, + left = (screen.width / 2) - (width / 2), + top = (screen.height / 2) - (height / 2); + + window.addEventListener("message", function(event) { + var hash = JSON.parse(event.data); + if (hash.type == 'access_token') { + callback(hash.access_token); + } + }, false); + + var w = window.open(url, + 'Spotify', + 'menubar=no,location=no,resizable=no,scrollbars=no,status=no, width=' + width + ', height=' + height + ', top=' + top + ', left=' + left + ); + + } + + function getUserData(accessToken) { + return $.ajax({ + url: 'https://api.spotify.com/v1/me', + headers: { + 'Authorization': 'Bearer ' + accessToken + } + }); + } + + var templateSource = document.getElementById('result-template').innerHTML, + template = Handlebars.compile(templateSource), + resultsPlaceholder = document.getElementById('result'), + loginButton = document.getElementById('btn-login'); + + loginButton.addEventListener('click', function() { + login(function(accessToken) { + getUserData(accessToken) + .then(function(response) { + loginButton.style.display = 'none'; + resultsPlaceholder.innerHTML = template(response); + }); + }); + }); + +})(); diff --git a/app/assets/javascripts/home.coffee b/app/assets/javascripts/home.coffee new file mode 100644 index 0000000..24f83d1 --- /dev/null +++ b/app/assets/javascripts/home.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..380e2e7 --- /dev/null +++ b/app/assets/javascripts/sessions.coffee @@ -0,0 +1,64 @@ +# 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/ + +(function() { + + function login(callback) { + var CLIENT_ID = '6b284830006843e7ae7b170725715aed'; + var REDIRECT_URI = 'http://jmperezperez.com/spotify-oauth-jsfiddle-proxy/'; + function getLoginURL(scopes) { + return 'https://accounts.spotify.com/authorize?client_id=' + CLIENT_ID + + '&redirect_uri=' + encodeURIComponent(REDIRECT_URI) + + '&scope=' + encodeURIComponent(scopes.join(' ')) + + '&response_type=token'; + } + + var url = getLoginURL([ + 'user-read-email' + ]); + + var width = 450, + height = 730, + left = (screen.width / 2) - (width / 2), + top = (screen.height / 2) - (height / 2); + + window.addEventListener("message", function(event) { + var hash = JSON.parse(event.data); + if (hash.type == 'access_token') { + callback(hash.access_token); + } + }, false); + + var w = window.open(url, + 'Spotify', + 'menubar=no,location=no,resizable=no,scrollbars=no,status=no, width=' + width + ', height=' + height + ', top=' + top + ', left=' + left + ); + + } + + function getUserData(accessToken) { + return $.ajax({ + url: 'https://api.spotify.com/v1/me', + headers: { + 'Authorization': 'Bearer ' + accessToken + } + }); + } + + var templateSource = document.getElementById('result-template').innerHTML, + template = Handlebars.compile(templateSource), + resultsPlaceholder = document.getElementById('result'), + loginButton = document.getElementById('btn-login'); + + loginButton.addEventListener('click', function() { + login(function(accessToken) { + getUserData(accessToken) + .then(function(response) { + loginButton.style.display = 'none'; + resultsPlaceholder.innerHTML = template(response); + }); + }); + }); + +})(); diff --git a/app/assets/javascripts/suggestions.coffee b/app/assets/javascripts/suggestions.coffee new file mode 100644 index 0000000..24f83d1 --- /dev/null +++ b/app/assets/javascripts/suggestions.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/user.coffee b/app/assets/javascripts/user.coffee new file mode 100644 index 0000000..24f83d1 --- /dev/null +++ b/app/assets/javascripts/user.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 b/app/assets/stylesheets/application.css index f9cd5b3..e08be1c 100644 --- a/app/assets/stylesheets/application.css +++ b/app/assets/stylesheets/application.css @@ -13,3 +13,14 @@ *= require_tree . *= require_self */ + .album-picture{ + width: 20%; + margin: 0; + + + } + + img{ + width: 20%; + padding: 0; + } diff --git a/app/assets/stylesheets/home.scss b/app/assets/stylesheets/home.scss new file mode 100644 index 0000000..cb52089 --- /dev/null +++ b/app/assets/stylesheets/home.scss @@ -0,0 +1,35 @@ +// 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/ + + + +.album-picture img{ + float: none; + margin: 0 auto; + width: 20%; + height: 20%; + -webkit-border-radius: 10% !important; + -moz-border-radius: 10% !important; + border-radius: 10% !important; +} + +.ranking{ + text-align: left; + padding: 0; +} + +.title { + text-transform: uppercase; + color: cadetblue; +} + + + img { + vertical-align: middle; + width: 20%; + +} +.image{ + width: 20%; +} diff --git a/app/assets/stylesheets/sessions.scss b/app/assets/stylesheets/sessions.scss new file mode 100644 index 0000000..d8e2c26 --- /dev/null +++ b/app/assets/stylesheets/sessions.scss @@ -0,0 +1,117 @@ +// 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/ + +.spotify_logo img{ + width: 100%; +} + +body{ + position:absolute; + width:100%; + height:100%; + margin:0; + padding:0; + background-image:url(http://www.matthewlewicki.com/codefest/images/spotify-background.jpg);} +h1{ + margin:0 0 .5em 0; + padding:0; + color:#fff; + font-family:helvetica; + font-size:30px; + font-weight:100; + letter-spacing:1px; + text-align:center; + text-shadow: 0 1px 2px rgba(0,0,0,1);} +section{ + position:relative; + top:50%; + width:300px; + max-width:96%; + margin:0 auto; + padding-top:120px; + -webkit-transform:translateY(-50%); + -ms-transform:translateY(-50%); + transform:translateY(-50%); + background-image:url(http://www.matthewlewicki.com/codefest/images/spotify-logo-small.png); + background-position:top center; + background-repeat:no-repeat; + background-size:100px;} +form{ + padding:0; + border-radius: 4px; + background-color:rgba(255,255,255,.75); + box-shadow: 0 2px 5px 0px rgba(38,38,38,0.5);} +fieldset{ + display: block; + width:100%; + margin:0 auto; + padding:1em 0 1em 0; + border: none; + border-bottom: 1px solid #ccc;} +fieldset:first-child{ + margin-bottom:0;} +fieldset:last-child{ + border-bottom: none; + margin-top:0; + padding:0;} +input{ + display:block; + width: 90%; + height:20px; + margin:0 auto; + padding: 5px 0; + color: #81b71a; + border: 1px solid #ccc; + text-align:center; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + -o-border-radius: 4px; + border-radius: 4px;} +input[type="submit"]{ + display: block; + -webkit-appearance: none; + -moz-appearance: none; + width:100%; + max-width:100% !important; + height:3em; + margin: 0 auto; + padding: 7px 5px 5px 5px; + background-color:#262626; + font-family: helvetica, arial, sans-serif; + font-size: 1em; + text-transform: uppercase; + text-align:center; + color:#81b71a; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border:none; + border-radius: 0 0 4px 4px; + -webkit-transition: all 0.5s ease-out; + -moz-transition: all 0.5s ease-out; + -o-transition: all 0.5s ease-out; + transition: all 0.5s ease-out;} +input[type="submit"]:hover{ + background-color: #333; + text-shadow:none;} +input::-webkit-input-placeholder{ + -webkit-transition: all 0.5s ease; + -moz-transition: all 0.5s ease; + -o-transition: all 0.5s ease; + transition: all 0.5s ease;} +input:hover::-webkit-input-placeholder{ + color:#81b71a;} +input:focus::-webkit-input-placeholder{ + opacity:0;} +input[type="text"]:focus,input[type="text"]:active,[type="password"]:focus,input[type="password"]:active{ + outline:0; + -webkit-appearance: none; + -moz-appearance: none; + border-image:none; + -moz-box-shadow: 0 0 20px rgba(129,183,26,0.5); + box-shadow: 0 0 20px rgba(129,183,26,0.5); + -webkit-animation: shadow-pulse 3s infinite ease-in-out;} +@-webkit-keyframes shadow-pulse { + 0% {-webkit-box-shadow: 0 0 20px rgba(129,183,26,0);} + 50% {-webkit-box-shadow: 0 0 20px rgba(129,183,26,1);} + 100% {-webkit-box-shadow: 0 0 20px rgba(129,183,26,0);}} diff --git a/app/assets/stylesheets/suggestions.scss b/app/assets/stylesheets/suggestions.scss new file mode 100644 index 0000000..efbd90d --- /dev/null +++ b/app/assets/stylesheets/suggestions.scss @@ -0,0 +1,148 @@ +// Place all the styles related to the suggestions controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ +/* -------------------------------------------------- + :: General + -------------------------------------------------- */ +body { + font-family: 'Open Sans', sans-serif; + color: #353535; +} +.content h1 { + text-align: center; +} +.content .content-footer p { + color: #6d6d6d; + font-size: 12px; + text-align: center; +} +.content .content-footer p a { + color: inherit; + font-weight: bold; +} + +/* -------------------------------------------------- + :: Table Filter + -------------------------------------------------- */ +.panel { + border: 1px solid #ddd; + background-color: #fcfcfc; +} +.panel .btn-group { + margin: 15px 0 30px; +} +.panel .btn-group .btn { + transition: background-color .3s ease; +} +.table-filter { + background-color: #fff; + border-bottom: 1px solid #eee; +} +.table-filter tbody tr:hover { + cursor: pointer; + background-color: #eee; +} +.table-filter tbody tr td { + padding: 10px; + vertical-align: middle; + border-top-color: #eee; +} +.table-filter tbody tr.selected td { + background-color: #eee; +} +.table-filter tr td:first-child { + width: 38px; +} +.table-filter tr td:nth-child(2) { + width: 35px; +} +.ckbox { + position: relative; +} +.ckbox input[type="checkbox"] { + opacity: 0; +} +.ckbox label { + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} +.ckbox label:before { + content: ''; + top: 1px; + left: 0; + width: 18px; + height: 18px; + display: block; + position: absolute; + border-radius: 2px; + border: 1px solid #bbb; + background-color: #fff; +} +.ckbox input[type="checkbox"]:checked + label:before { + border-color: #2BBCDE; + background-color: #2BBCDE; +} +.ckbox input[type="checkbox"]:checked + label:after { + top: 3px; + left: 3.5px; + content: '\e013'; + color: #fff; + font-size: 11px; + font-family: 'Glyphicons Halflings'; + position: absolute; +} +.table-filter .star { + color: #ccc; + text-align: center; + display: block; +} +.table-filter .star.star-checked { + color: #F0AD4E; +} +.table-filter .star:hover { + color: #ccc; +} +.table-filter .star.star-checked:hover { + color: #F0AD4E; +} +.table-filter .media-photo { + width: 35px; +} +.table-filter .media-body { + display: block; + /* Had to use this style to force the div to expand (wasn't necessary with my bootstrap version 3.3.6) */ +} +.table-filter .media-meta { + font-size: 11px; + color: #999; +} +.table-filter .media .title { + color: #2BBCDE; + font-size: 14px; + font-weight: bold; + line-height: normal; + margin: 0; +} +.table-filter .media .title span { + font-size: .8em; + margin-right: 20px; +} +.table-filter .media .title span.pagado { + color: #5cb85c; +} +.table-filter .media .title span.pendiente { + color: #f0ad4e; +} +.table-filter .media .title span.cancelado { + color: #d9534f; +} +.table-filter .media .summary { + font-size: 14px; +} + +img{ + width: 20%; + +} diff --git a/app/assets/stylesheets/user.scss b/app/assets/stylesheets/user.scss new file mode 100644 index 0000000..9d9d94b --- /dev/null +++ b/app/assets/stylesheets/user.scss @@ -0,0 +1,104 @@ +// Place all the styles related to the user controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ +/* USER PROFILE PAGE */ + + +.col-sm-6 { + width: 100%; +} + + .card { + margin-top: 20px; + padding: 30px; + background-color: rgba(214, 224, 226, 0.2); + -webkit-border-top-left-radius:5px; + -moz-border-top-left-radius:5px; + border-top-left-radius:5px; + -webkit-border-top-right-radius:5px; + -moz-border-top-right-radius:5px; + border-top-right-radius:5px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +.card.hovercard { + position: relative; + padding-top: 0; + overflow: hidden; + text-align: center; + background-color: #fff; + background-color: rgba(255, 255, 255, 1); +} +.card.hovercard .card-background { + height: 130px; +} +.card-background img { + -webkit-filter: blur(25px); + -moz-filter: blur(25px); + -o-filter: blur(25px); + -ms-filter: blur(25px); + filter: blur(25px); + margin-left: -100px; + margin-top: -200px; + // min-width: 130%; +} +.card.hovercard .useravatar { + position: absolute; + top: 15px; + left: 0; + right: 0; +} +.card.hovercard .useravatar img { + width: 100px; + height: 100px; + max-width: 100px; + max-height: 100px; + -webkit-border-radius: 50%; + -moz-border-radius: 50%; + border-radius: 50%; + border: 5px solid rgba(255, 255, 255, 0.5); +} +.card.hovercard .card-info { + position: absolute; + bottom: 14px; + left: 0; + right: 0; +} +.card.hovercard .card-info .card-title { + padding:0 5px; + font-size: 20px; + line-height: 1; + color: #262626; + background-color: rgba(255, 255, 255, 0.1); + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +.card.hovercard .card-info { + overflow: hidden; + font-size: 12px; + line-height: 20px; + color: #737373; + text-overflow: ellipsis; +} +.card.hovercard .bottom { + padding: 0 20px; + margin-bottom: 17px; +} +.btn-pref .btn { + -webkit-border-radius:0 !important; +} + +.user-header-image{ + width: 20%; +} +.image_style{ + width: 20%; +} + +.db{ + height: 80px; + position: relative; + border: 1px solid #282828; +} diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index d83690e..a0ba5e3 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,5 +1,21 @@ 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 + helper_method :current_user + + before_action :require_login + + def current_user + @user ||= User.find_by(id: session[:user_id]) + end + + def require_login + if current_user.nil? + flash[:error] = "You must be logged in to view this section" + redirect_to login_path + end + end end diff --git a/app/controllers/home_controller.rb b/app/controllers/home_controller.rb new file mode 100644 index 0000000..cd15f8b --- /dev/null +++ b/app/controllers/home_controller.rb @@ -0,0 +1,7 @@ +class HomeController < ApplicationController + skip_before_action :require_login, only: [:index] + + def index + @top_twenty = TunesTakeout.top_suggestions(20) + end +end diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb new file mode 100644 index 0000000..266fa1e --- /dev/null +++ b/app/controllers/sessions_controller.rb @@ -0,0 +1,24 @@ +class SessionsController < ApplicationController + skip_before_action :require_login, only: [:new, :create] + + def new + end + + def create + auth_hash = request.env['omniauth.auth'] + raise + user = User.find_or_create_from_omniauth(auth_hash) + if user + session[:user_id] = user.id + redirect_to "/user/#{user.id}" + else + redirect_to root_path, notice: "Failed to save the user" + end + end + + + def destroy + session.delete :user_id + redirect_to root_path + end +end diff --git a/app/controllers/suggestions_controller.rb b/app/controllers/suggestions_controller.rb new file mode 100644 index 0000000..77c5f0e --- /dev/null +++ b/app/controllers/suggestions_controller.rb @@ -0,0 +1,24 @@ +class SuggestionsController < ApplicationController + def index + # shows top 20 suggestions, ranked by total number of favorites + end + + def search + @result = TunesTakeout.search_results(params["search"]) + redirect_to user_path(id: params["id"], suggestions_search: params["search"]) + end + + def favorites + @result = TunesTakeout.favorites_by_user_id(params["user_id"]) + redirect_to user_favorites_path(params["user_id"]) + + end + + def favorite + # adds a suggestion into the favorite list for the signed-in User. This requires interaction with the Tunes & Takeout API. + end + + def unfavorite + # removes a suggestion from the favorite list for the signed-in User. This requires interaction with theTunes & Takeout API. + end +end diff --git a/app/controllers/user_controller.rb b/app/controllers/user_controller.rb new file mode 100644 index 0000000..eb528a4 --- /dev/null +++ b/app/controllers/user_controller.rb @@ -0,0 +1,11 @@ +class UserController < ApplicationController + + def new + @user = User.new + end + + def show + end + + +end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index de6be79..852623f 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -1,2 +1,5 @@ module ApplicationHelper + def music_by_type + pairing = TunesTakeout.top_limit(20) + end end diff --git a/app/helpers/home_helper.rb b/app/helpers/home_helper.rb new file mode 100644 index 0000000..23de56a --- /dev/null +++ b/app/helpers/home_helper.rb @@ -0,0 +1,2 @@ +module HomeHelper +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/suggestions_helper.rb b/app/helpers/suggestions_helper.rb new file mode 100644 index 0000000..0e358dd --- /dev/null +++ b/app/helpers/suggestions_helper.rb @@ -0,0 +1,2 @@ +module SuggestionsHelper +end diff --git a/app/helpers/user_helper.rb b/app/helpers/user_helper.rb new file mode 100644 index 0000000..0147c3f --- /dev/null +++ b/app/helpers/user_helper.rb @@ -0,0 +1,2 @@ +module UserHelper +end diff --git a/app/models/food.rb b/app/models/food.rb new file mode 100644 index 0000000..eeccf93 --- /dev/null +++ b/app/models/food.rb @@ -0,0 +1,15 @@ +require 'httparty' +require 'yelp' +require "erb" + + +class Food + + + def self.yelp_find_by_business(id) + id = ERB::Util.url_encode(id) + data = Yelp.client.business(id).business + end + + +end diff --git a/app/models/music.rb b/app/models/music.rb new file mode 100644 index 0000000..9c5e935 --- /dev/null +++ b/app/models/music.rb @@ -0,0 +1,30 @@ +require 'httparty' +require 'rspotify' + +class Music + BASE_URL = "https://api.spotify.com" + ALBUM_PICTURE = "http://marcoscolamedia.com/wp-content/uploads/2015/12/Music-Album-Blank-.jpg" + attr_reader :item_id, :type, :name, :url, :image_url + + def self.find(type, id) + result = "RSpotify::#{type}".constantize.find(id) + end + + def self.user_info + data = HTTParty.get("https://api.spotify.com/v1/me").parsed_response + end + + def self.picture?(image) + if image.nil? + return ALBUM_PICTURE + elsif image[0].nil? + return ALBUM_PICTURE + else + image[0]["url"] + end + end + + + private + +end diff --git a/app/models/user.rb b/app/models/user.rb new file mode 100644 index 0000000..38e60bb --- /dev/null +++ b/app/models/user.rb @@ -0,0 +1,24 @@ +require 'httparty' + +class User < ActiveRecord::Base + + validates :uid, :provider, presence: true + + def self.find_or_create_from_omniauth(auth_hash) + # find or create a user + user = User.find_by(uid: auth_hash["uid"], provider: auth_hash["provider"]) + if user + return user + else + # no user found + user = User.new + user.uid = auth_hash["uid"] + user.provider = auth_hash["provider"] + if user.save + return user + else + return nil + end + end + end +end diff --git a/app/views/home/index.html.erb b/app/views/home/index.html.erb new file mode 100644 index 0000000..993e01f --- /dev/null +++ b/app/views/home/index.html.erb @@ -0,0 +1,49 @@ +
Ranking | +Music | +Release Date | +|
---|---|---|---|
<%= count %> | +
+
+ <% album_picture = music.images if music.type == "album" %>
+ <% album_picture = music.images if music.type == "artist" %>
+ <% album_picture = music.album.images if music.type == "track" %>
+
+ <%= link_to( image_tag(Music.picture?(album_picture)), image_path( music.external_urls["spotify"] )) %>
+
+
+ <%= music.name%>
+
+ |
+
+
+
+
+ <%= link_to( image_tag(food.image_url), image_path(food.url)) %>
+
+
+ <%= food.name%>
+
+ |
+ + <% count += 1 %> + |
Log in with your Spotify account
+ + <%= link_to '/auth/spotify' do%> + + Sign in + <% end %> + + +Log in with your Spotify account
+ + <%= form_for :session, url: sign_in_path, class: "form" do |f| %> + + + + + <% end %> +Type an artist name and click on "Search". Then, click on any album from the results to play 30 seconds of its first track.
+ + +