diff --git a/source/Gemfile b/source/Gemfile index 9627b8b..a2c043e 100644 --- a/source/Gemfile +++ b/source/Gemfile @@ -1,6 +1,6 @@ source 'https://rubygems.org' - +gem 'httparty', '~> 0.13.5' # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' gem 'rails', '4.1.6' # Use sqlite3 as the database for Active Record @@ -35,7 +35,7 @@ gem 'spring', group: :development # Use Capistrano for deployment # gem 'capistrano-rails', group: :development -# Use debugger -# gem 'debugger', group: [:development, :test] +gem 'pry', group: [:development, :test] +gem 'pry-rails', group: [:development, :test] gem 'rspec-rails', group: [:development, :test] diff --git a/source/Gemfile.lock b/source/Gemfile.lock index fcf8b98..416b1ff 100644 --- a/source/Gemfile.lock +++ b/source/Gemfile.lock @@ -29,6 +29,7 @@ GEM tzinfo (~> 1.1) arel (5.0.1.20140414130214) builder (3.2.2) + coderay (1.1.0) coffee-rails (4.0.1) coffee-script (>= 2.2.0) railties (>= 4.0.0, < 5.0) @@ -40,6 +41,9 @@ GEM erubis (2.7.0) execjs (2.2.1) hike (1.2.3) + httparty (0.13.5) + json (~> 1.8) + multi_xml (>= 0.5.2) i18n (0.6.11) jbuilder (2.2.2) activesupport (>= 3.0.0, < 5) @@ -50,9 +54,17 @@ GEM json (1.8.1) mail (2.6.1) mime-types (>= 1.16, < 3) + method_source (0.8.2) mime-types (2.4.1) minitest (5.4.2) multi_json (1.10.1) + multi_xml (0.5.5) + pry (0.10.1) + coderay (~> 1.1.0) + method_source (~> 0.8.1) + slop (~> 3.4) + pry-rails (0.3.4) + pry (>= 0.9.10) rack (1.5.2) rack-test (0.6.2) rack (>= 1.0) @@ -99,6 +111,7 @@ GEM sdoc (0.4.1) json (~> 1.7, >= 1.7.7) rdoc (~> 4.0) + slop (3.6.0) spring (1.1.3) sprockets (2.11.0) hike (~> 1.2) @@ -126,8 +139,11 @@ PLATFORMS DEPENDENCIES coffee-rails (~> 4.0.0) + httparty (~> 0.13.5) jbuilder (~> 2.0) jquery-rails + pry + pry-rails rails (= 4.1.6) rspec-rails sass-rails (~> 4.0.3) diff --git a/source/app/assets/stylesheets/scaffolds.css.scss b/source/app/assets/stylesheets/scaffolds.css.scss new file mode 100644 index 0000000..6ec6a8f --- /dev/null +++ b/source/app/assets/stylesheets/scaffolds.css.scss @@ -0,0 +1,69 @@ +body { + background-color: #fff; + color: #333; + font-family: verdana, arial, helvetica, sans-serif; + font-size: 13px; + line-height: 18px; +} + +p, ol, ul, td { + font-family: verdana, arial, helvetica, sans-serif; + font-size: 13px; + line-height: 18px; +} + +pre { + background-color: #eee; + padding: 10px; + font-size: 11px; +} + +a { + color: #000; + &:visited { + color: #666; + } + &:hover { + color: #fff; + background-color: #000; + } +} + +div { + &.field, &.actions { + margin-bottom: 10px; + } +} + +#notice { + color: green; +} + +.field_with_errors { + padding: 2px; + background-color: red; + display: table; +} + +#error_explanation { + width: 450px; + border: 2px solid red; + padding: 7px; + padding-bottom: 0; + margin-bottom: 20px; + background-color: #f0f0f0; + h2 { + text-align: left; + font-weight: bold; + padding: 5px 5px 5px 15px; + font-size: 12px; + margin: -7px; + margin-bottom: 0px; + background-color: #c00; + color: #fff; + } + ul li { + font-size: 12px; + list-style: square; + } +} diff --git a/source/app/controllers/urls_controller.rb b/source/app/controllers/urls_controller.rb index ef26710..897e7e5 100644 --- a/source/app/controllers/urls_controller.rb +++ b/source/app/controllers/urls_controller.rb @@ -1,2 +1,62 @@ class UrlsController < ApplicationController + before_action :set_url, only: [:edit, :update, :destroy] + before_action :set_url_by_shortened, only: [:show] + + def index + @urls = Url.all + end + + def show + @url.increment(:click_count); @url.save + redirect_to @url.original + end + + def new + @url = Url.new + end + + def edit + end + + def create + @url = Url.new(url_params) + + respond_to do |format| + if @url.save + format.html { redirect_to urls_path, notice: 'Url was successfully created.' } + else + format.html { render :new } + end + end + end + + def update + respond_to do |format| + if @url.update(url_params) + format.html { redirect_to urls_path, notice: 'Url was successfully updated.' } + else + format.html { render :edit } + end + end + end + + def destroy + @url.destroy + respond_to do |format| + format.html { redirect_to urls_path, notice: 'Url was successfully destroyed.' } + end + end + + private + def set_url + @url = Url.find(params[:id]) + end + + def set_url_by_shortened + @url = Url.find_by(shortened: params[:shortened]) + end + + def url_params + params.require(:url).permit(:shortened, :original) + end end diff --git a/source/app/models/url.rb b/source/app/models/url.rb new file mode 100644 index 0000000..251c38a --- /dev/null +++ b/source/app/models/url.rb @@ -0,0 +1,22 @@ +class Url < ActiveRecord::Base + before_save :shorten + + validates :shortened, uniqueness: true + validate :protocol_check, :resolvable_check + + def shorten + self.shortened ||= SecureRandom.urlsafe_base64(5) + end + + def protocol_check + errors[:original] << "URL must begin with http:// or https://" unless original.match(/^https?:\/\//) + end + + def resolvable_check + begin + HTTParty.get(original).code == 200 + rescue + errors[:original] << "not resolvable" + end + end +end diff --git a/source/app/views/urls/_form.html.erb b/source/app/views/urls/_form.html.erb new file mode 100644 index 0000000..041a1ef --- /dev/null +++ b/source/app/views/urls/_form.html.erb @@ -0,0 +1,21 @@ +<%= form_for(@url) do |f| %> + <% if @url.errors.any? %> +
| Clicks | +Shortened | +Original | ++ | ||
|---|---|---|---|---|---|
| <%= url.click_count %> | +<%= link_to url.shortened, shortened_path(url.shortened) %> | +<%= url.original %> | +<%= link_to 'Edit', edit_url_path(url) %> | +<%= link_to 'Destroy', url, method: :delete, data: { confirm: 'Are you sure?' } %> | +|