Skip to content

Commit

Permalink
Basic feeds
Browse files Browse the repository at this point in the history
  • Loading branch information
mattyoho committed May 15, 2012
1 parent a6a7e1a commit b5a0b7b
Show file tree
Hide file tree
Showing 51 changed files with 1,012 additions and 244 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@
# Ignore all logfiles and tempfiles.
/log/*.log
/tmp
.rvmrc
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
source 'https://rubygems.org'

gem 'rails', '3.2.3'
gem 'sorcery'
gem 'jbuilder'
gem 'simple_form'
gem 'jquery-rails'
Expand Down
13 changes: 13 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ GEM
i18n (~> 0.6)
multi_json (~> 1.0)
arel (3.0.2)
bcrypt-ruby (3.0.1)
blankslate (2.1.2.4)
builder (3.0.0)
coffee-rails (3.2.2)
Expand All @@ -42,6 +43,8 @@ GEM
erubis (2.7.0)
execjs (1.3.2)
multi_json (~> 1.0)
faraday (0.8.0)
multipart-post (~> 1.1)
haml (3.1.5)
haml-rails (0.3.4)
actionpack (~> 3.0)
Expand Down Expand Up @@ -72,6 +75,11 @@ GEM
treetop (~> 1.4.8)
mime-types (1.18)
multi_json (1.3.5)
multipart-post (1.1.5)
oauth (0.4.6)
oauth2 (0.5.2)
faraday (~> 0.7)
multi_json (~> 1.0)
polyglot (0.3.3)
rack (1.4.1)
rack-cache (1.2)
Expand Down Expand Up @@ -106,6 +114,10 @@ GEM
simple_form (2.0.2)
actionpack (~> 3.0)
activemodel (~> 3.0)
sorcery (0.7.12)
bcrypt-ruby (~> 3.0.0)
oauth (~> 0.4.4)
oauth2 (~> 0.5.1)
sprockets (2.1.3)
hike (~> 1.2)
rack (~> 1.0)
Expand Down Expand Up @@ -135,6 +147,7 @@ DEPENDENCIES
rails (= 3.2.3)
sass-rails (~> 3.2.3)
simple_form
sorcery
sqlite3
therubyracer
uglifier (>= 1.0.3)
12 changes: 12 additions & 0 deletions app/assets/javascripts/feed_items.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
$(document).ready(function() {
$("#feed_item_kind").change(function(e) {
$("input[data-enable-on]").each(function() {
$(this).attr('disabled', 'disabled');
});

$("input[data-enable-on="+$(e.target).val()+"]").removeAttr('disabled');
});

var enable = $("#feed_item_kind").val();
$("input[data-enable-on="+enable+"]").removeAttr('disabled');
});
4 changes: 4 additions & 0 deletions app/assets/stylesheets/application.css
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,7 @@
*= require_self
*= require_tree .
*/

div.feed-item { margin: 20px 20px; }
div.feed-item img { display: block; max-width: 300px; margin: 0 auto; }
div.feed-item p { margin-top: 20px; }
9 changes: 9 additions & 0 deletions app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
class ApplicationController < ActionController::Base
protect_from_forgery

before_filter :require_login

protected

def not_authenticated
redirect_to root_path, :alert => "Please login first."
end

end
55 changes: 55 additions & 0 deletions app/controllers/feed_items_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
class FeedItemsController < ApplicationController
before_filter :require_login, :except => [:index]

def new
@feed_item = FeedItem.new

respond_to do |format|
format.html
format.json { render json: @feed_item }
end
end

def edit
@feed_item = current_user.feed.feed_items.find(params[:id])
end

def create
kind = params[:feed_item].delete(:kind)
@feed_item = current_user.feed.feed_item_of(kind).new(params[:feed_item])

respond_to do |format|
if @feed_item.save
format.html { redirect_to current_user.feed, notice: 'Feed item was successfully created.' }
format.json { render json: @feed_item, status: :created, location: @feed_item }
else
format.html { render action: "new" }
format.json { render json: @feed_item.errors, status: :unprocessable_entity }
end
end
end

def update
@feed_item = current_user.feed.feed_items.find(params[:id])

respond_to do |format|
if @feed_item.update_attributes(params[:feed_item])
format.html { redirect_to current_user.feed, notice: 'Feed item was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: @feed_item.errors, status: :unprocessable_entity }
end
end
end

def destroy
@feed_item = current_user.feed.feed_items.find(params[:id])
@feed_item.destroy

respond_to do |format|
format.html { redirect_to root_url }
format.json { head :no_content }
end
end
end
22 changes: 22 additions & 0 deletions app/controllers/feeds_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
class FeedsController < ApplicationController
before_filter :require_login, :except => [:index]

def index
@feed_items = FeedItem.last_first

respond_to do |format|
format.html { render action: :show }
format.json { render json: @feed_items }
end
end

def show
@feed_items = Feed.find_by_name!(params[:id]).feed_items.last_first

respond_to do |format|
format.html
format.json { render json: @feed }
end
end

end
23 changes: 23 additions & 0 deletions app/controllers/sessions_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
class SessionsController < ApplicationController
skip_before_filter :require_login, :except => [:destroy]

def new
@user = User.new
end

def create
respond_to do |format|
if @user = login(params[:username], params[:password])
format.html { redirect_back_or_to(:feed_items, :notice => 'Login successful.') }
else
format.html { flash.now[:alert] = "Login failed."; render :action => "new" }
end
end
end

def destroy
logout
redirect_to(:feed_items, :notice => 'Logged out!')
end

end
26 changes: 26 additions & 0 deletions app/controllers/users_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
class UsersController < ApplicationController
skip_before_filter :require_login, :only => [:new, :create]

def new
@user = User.new

respond_to do |format|
format.html
end
end

def create
@user = User.new(params[:user])

respond_to do |format|
if @user.save
auto_login(@user)
format.html { redirect_to(login_path, :notice => 'Creation successful.') }
else
format.html { render :action => "new" }
end
end
end

end

2 changes: 2 additions & 0 deletions app/helpers/feed_items_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
module FeedItemsHelper
end
17 changes: 17 additions & 0 deletions app/models/feed.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
class Feed < ActiveRecord::Base
belongs_to :user, inverse_of: :feed
has_many :feed_items, inverse_of: :feed
has_many :image_items
has_many :text_items
has_many :link_items

delegate :gravatar, to: :user

def feed_item_of(kind)
send(kind.tableize.to_sym)
end

def to_param
name
end
end
16 changes: 16 additions & 0 deletions app/models/feed_item.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
class FeedItem < ActiveRecord::Base
belongs_to :feed, inverse_of: :feed_items

def self.last_first
order("created_at DESC")
end

def kind
read_attribute(:type) || "TextItem"
end

def username
feed.name
end

end
11 changes: 11 additions & 0 deletions app/models/image_item.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class ImageItem < FeedItem
attr_accessible :title, :body, :image_url

validates :image_url, presence: true, format: /^https?:\/\/.+\.(?:jpg|jpeg|gif|png)$/i, length: {maximum: 2048}
validates :body, length: {minumum: 1, maximum: 256}

def to_partial_path
'feed_items/image_item'
end

end
11 changes: 11 additions & 0 deletions app/models/link_item.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class LinkItem < FeedItem
attr_accessible :title, :body, :link_url

validates :link_url, presence: true, format: /^https?:\/\/.+$/i, length: {maximum: 2048}
validates :body, presence: true, length: {minumum: 1, maximum: 256}

def to_partial_path
'feed_items/link_item'
end

end
10 changes: 10 additions & 0 deletions app/models/text_item.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
class TextItem < FeedItem
attr_accessible :body, :title

validates :body, presence: true, length: {minumum: 1, maximum: 256}

def to_partial_path
'feed_items/text_item'
end

end
36 changes: 36 additions & 0 deletions app/models/user.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
require 'digest/md5'

class User < ActiveRecord::Base
has_one :feed, inverse_of: :user
attr_accessible :email, :password, :password_confirmation
authenticates_with_sorcery!

validates :username, presence: true, format: /^[\d\w]+$/,length: {minimum: 2, message: "password must be at least 2 characters long"}
validates_length_of :password, :minimum => 6, :message => "password must be at least 6 characters long", :if => :password
validates_confirmation_of :password, :message => "should match confirmation", :if => :password

before_validation :clean_email
before_create :setup_feed

def created?(item)
item.feed == feed
end

def gravatar(s='40')
@gravatar ||= {}
@gravatar[s] ||= "http://www.gravatar.com/avatar/#{Digest::MD5.hexdigest(email)}?s=#{s}"
end

private

def setup_feed
build_feed
feed.name = username
end

def clean_email
if email.respond_to? :trim
email.trim!.downcase!
end
end
end
12 changes: 12 additions & 0 deletions app/views/feed_items/_form.html.haml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
.well
- form_url = @feed_item.new_record? ? feed_items_path : feed_item_path(@feed_item)
= simple_form_for(@feed_item, as: :feed_item, url: form_url, html: {class: "form-horizontal"}) do |f|
= f.error_notification

.form-inputs
= f.input :kind, as: :select, collection: [%w(Text TextItem), %w(Image ImageItem), %w(Link LinkItem)], disabled: !@feed_item.new_record?
= f.input :link_url, disabled: true, input_html: {data: {'enable-on' => 'LinkItem'}}
= f.input :image_url, disabled: true, input_html: {data: {'enable-on' => 'ImageItem'}}
= f.input :body, input_html: {rows: 10}

= f.button :submit
4 changes: 4 additions & 0 deletions app/views/feed_items/_image_item.html.haml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
%img{class: "feed_item", src: feed_item.image_url}
%p
%i(class="icon-eye-open")
= feed_item.body
2 changes: 2 additions & 0 deletions app/views/feed_items/_link_item.html.haml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
%i(class="icon-tags")
= link_to feed_item.body, feed_item.link_url
2 changes: 2 additions & 0 deletions app/views/feed_items/_text_item.html.haml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
%i(class="icon-comment")
= feed_item.body
5 changes: 5 additions & 0 deletions app/views/feed_items/edit.html.haml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
%h1 Edit item

= render 'form'

= link_to 'Back', feed_items_path
5 changes: 5 additions & 0 deletions app/views/feed_items/new.html.haml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
%h1 New item

= render 'form'

= link_to 'Back', feed_items_path
14 changes: 14 additions & 0 deletions app/views/feeds/show.html.haml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
- if logged_in?
= link_to 'Add to the feed', new_feed_item_path, class: "btn btn-primary pull-right"
- @feed_items.each do |feed_item|
.row
.span6.offset3.well
%div
%img{src: feed_item.feed.gravatar}
%strong= link_to(feed_item.username, feed_item.feed)
= distance_of_time_in_words_to_now(feed_item.created_at) + " ago"
%div.feed-item= render partial: feed_item, as: :feed_item
- if current_user.created?(feed_item)
= link_to 'Edit', edit_feed_item_path(feed_item), class: "btn"
= link_to 'Destroy', feed_item_path(feed_item), :confirm => 'Are you sure?', :method => :delete, class: "btn btn-danger"

Loading

0 comments on commit b5a0b7b

Please sign in to comment.