Skip to content

Commit

Permalink
Merge branch 'nokogiri' of git@github.com:nakajima/aintablog
Browse files Browse the repository at this point in the history
  • Loading branch information
nakajima committed Feb 2, 2009
2 parents 3c59ca2 + 2ecbd95 commit e2252ba
Show file tree
Hide file tree
Showing 1,569 changed files with 36,254 additions and 186,474 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
*~
log/*
tmp/*
db/*.sqlite3
Expand All @@ -7,7 +8,8 @@ config/defensio.yml
.DS_Store
./**/.DS_Store
Capfile
*.tmproj
public/cache
public/cache/**
public/javascripts/all.js
public/stylesheets/all.css
public/stylesheets/all.css
17 changes: 8 additions & 9 deletions README.textile
Original file line number Diff line number Diff line change
Expand Up @@ -14,27 +14,26 @@ h3. Feature Requests/Bugs

I've set up a Lighthouse project for Aintablog here: "http://nakajima.lighthouseapp.com/projects/14585-aintablog":http://nakajima.lighthouseapp.com/projects/14585-aintablog

h3. REQUIREMENTS
h3. Requirements

You're going to need the feed-normalizer and hpricot gems.
You're going to need a few gems to start things off.

sudo gem install feed-normalizer hpricot
sudo gem install feed-normalizer hpricot RedCloth

If you want to run the test suite, you'll need the mocha gem.
or

sudo gem install mocha
sudo rake gems:install

I think that's about it.
If you want to run the test suite, you'll need the mocha gem.

You can run @rake gems:install@ to do it all in one fell swoop if you'd like.
sudo gem install mocha

h4. Defensio Spam Protection

Aintablog now has built-in Defensio Spam protection. You need to get API keys from "defensio.com":http://defensio.com, then put them into @config/defensio.yml@. If you don't want to use Defensio, you can set the "use_defensio" option to false in config/settings.yml.

h3. TODO

* Put together a better regex for the spanify_links helper
* -Page titles!-
* -Page caching-
* More control over posts (publish_at, -commentable?-)
* More control over posts (publish_at, -commentable?-)
22 changes: 3 additions & 19 deletions app/controllers/admin/posts_controller.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
class Admin::PostsController < ApplicationController
POST_TYPE_PATTERN = /\/(articles|tweets|quotes|pictures|links|snippets|posts)(\.rss)?\/?/i

rescue_from ActiveRecord::RecordNotFound, :with => :not_found

before_filter :login_required
Expand All @@ -23,7 +21,7 @@ def index
# GET /posts/1.xml
def show
@post = Post.find_by_permalink(params[:id], :include => :comments) || Post.find(params[:id])
redirect_to '/' and return unless @post.type.match(/Article|Snippet/)
redirect_to admin_posts_path and return unless @post.type.match(/Article|Snippet/)
@comment = flash[:comment] || @post.comments.build
respond_to do |format|
format.html # show.html.erb
Expand Down Expand Up @@ -55,7 +53,7 @@ def create
respond_to do |format|
if @post.save
flash[:notice] = 'Post was successfully created.'
format.html { redirect_to @post.link }
format.html { redirect_to admin_post_path(@post) }
format.xml { render :xml => @post, :status => :created, :location => @post }
else
flash[:error] = @post.errors.full_messages
Expand All @@ -74,7 +72,7 @@ def update
if @post.update_attributes(params[:post])
expire_fragment(@post.permalink)
flash[:notice] = 'Post was successfully updated.'
format.html { redirect_to @post.link }
format.html { redirect_to admin_post_path(@post) }
format.js { render :json => @post }
format.xml { head :ok }
else
Expand All @@ -99,20 +97,6 @@ def destroy
end

private
def post_repo
@post_type = params[:posts_type] || request.path.split('/admin').last.gsub(POST_TYPE_PATTERN, '\1')
return @post_type.classify.constantize
rescue => e
logger.info(e)
@post_type = 'posts'
@post_type.classify.constantize
end

def not_found
flash[:error] = "Sorry but that post could not be found."
redirect_to '/' and return
end

def expire_post!
expire_path("#{@post.link}.html")
end
Expand Down
25 changes: 25 additions & 0 deletions app/controllers/application.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,34 @@ class ApplicationController < ActionController::Base

skip_before_filter :verify_authenticity_token # Page caching screws up forgery protection stuff

POST_TYPES = %w(articles links pictures quotes snippets tweets gists)
POST_TYPE_PATTERN = /\/(#{POST_TYPES.join('|')})(\.rss)?\/?/i

def expire_path(file)
file = RAILS_ROOT + '/public' + file
FileUtils.rm_rf(file) if File.exists?(file)
logger.info("Expired cache: #{file}")
end

protected
def post_repo

# two replaces, but it's better than duped code.
@post_type = params[:posts_type] || request.path.gsub(/^\/admin/, '/').gsub(POST_TYPE_PATTERN, '\1')

# for some reason '/' this gets classified as '::', which is an Object. Adding a check for that.
throw NameError if @post_type.eql?('/')

return @post_type.classify.constantize
rescue => e
logger.info(e)
@post_type = 'posts'
return @post_type.classify.constantize
end

def not_found
cookies[:error] = "Sorry but that post could not be found."
redirect_to root_path and return
end

end
2 changes: 1 addition & 1 deletion app/controllers/feeds_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ def expire_index!
expire_path("/#{@feed.class.entry_type}.rss")
expire_path("/#{@feed.class.entry_type}")
else
%w(articles links pictures quotes snippets tweets).each do |entry_type|
POST_TYPES.each do |entry_type|
expire_path("/#{entry_type}.html")
expire_path("/#{entry_type}.rss")
expire_path("/#{entry_type}")
Expand Down
20 changes: 2 additions & 18 deletions app/controllers/posts_controller.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
class PostsController < ApplicationController
POST_TYPE_PATTERN = /\/(articles|tweets|quotes|pictures|links|snippets|posts)(\.rss)?\/?/i

rescue_from ActiveRecord::RecordNotFound, :with => :not_found

before_filter :redirect_to_admin, :if => :logged_in?
Expand All @@ -23,7 +21,7 @@ def index
# GET /posts/1.xml
def show
@post = Post.find_by_permalink(params[:id], :include => :comments) || Post.find(params[:id])
redirect_to '/' and return unless @post.type.match(/Article|Snippet/)
redirect_to root_path and return unless @post.type.match(/Article|Snippet/)
@comment = flash[:comment] || @post.comments.build
respond_to do |format|
format.html # show.html.erb
Expand All @@ -32,21 +30,7 @@ def show
end

private
def post_repo
@post_type = params[:posts_type] || request.path.gsub(POST_TYPE_PATTERN, '\1')
return @post_type.classify.constantize
rescue => e
logger.info(e)
@post_type = 'posts'
return @post_type.classify.constantize
end

def not_found
cookies[:error] = "Sorry but that post could not be found."
redirect_to '/' and return
end

def redirect_to_admin
redirect_to "/admin" + request.path
redirect_to admin_root_path + request.path
end
end
5 changes: 3 additions & 2 deletions app/controllers/sessions_controller.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# -*- coding: utf-8 -*-
# This controller handles the login/logout function of the site.
class SessionsController < ApplicationController

Expand All @@ -20,7 +21,7 @@ def create
self.current_user.remember_me
cookies[:auth_token] = { :value => self.current_user.remember_token , :expires => self.current_user.remember_token_expires_at }
end
redirect_back_or_default('/admin')
redirect_back_or_default(admin_root_path)
cookies[:notice] = "You’ve logged in successfully."
else
render :action => 'new'
Expand All @@ -32,6 +33,6 @@ def destroy
cookies.delete :auth_token
reset_session
cookies[:notice] = "You have been logged out."
redirect_back_or_default('/')
redirect_back_or_default(root_path)
end
end
4 changes: 2 additions & 2 deletions app/controllers/users_controller.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
class UsersController < ApplicationController
# render new.rhtml
def new
redirect_to '/' if (User.count >= 1) && !logged_in?
redirect_to root_path if (User.count >= 1) && !logged_in?
@user = User.new
end

Expand All @@ -15,7 +15,7 @@ def create
@user.save
if @user.errors.empty?
self.current_user = @user
redirect_back_or_default('/')
redirect_back_or_default(root_path)
cookies[:notice] = "Thanks for signing up! Choose one of the links at the top to do something interesting."
else
render :action => 'new'
Expand Down
35 changes: 22 additions & 13 deletions app/helpers/application_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,15 @@ def spanned_link(*args)
end

def spanify_links(text)
text.gsub(/<a\s+(.*)>(.*)<\/a>/i, '<a \1><span>\2</span></a>')
if text.is_a?(Nokogiri::HTML::Document)
doc = text
else
doc = Nokogiri::HTML(text)
end
doc.search("a/text()").wrap("<span></span>")
unless text.is_a?(Nokogiri::HTML::Document)
text = doc.at("body").inner_html
end
end

def partial_for(post)
Expand All @@ -22,22 +30,19 @@ def comments_link_for(post)
link_to text, "#{path}#comments"
end

# TODO This method sucks. Learn about regex and fix it.
def twitterize(string)
string.gsub!(/\b(((http:|https:|file:)\/\/)?([a-z]+\.)?(\w+\.com|net|org)(\/.*)?)\b/) do
"<a href='#{"http://" unless $1.include?('http://')}#{$1}'><span>#{$1}</span></a>"
end
string.gsub!(/@(\w*)/, '@<a href="http://twitter.com/\1"><span>\1</span></a>')
string.gsub!(/@(\w*)/, '@<a href="http://twitter.com/\1">\1</a>')
string = auto_link(string)
string = RubyPants.new(string).to_html
spanify_links(string)
end

def clean_content_for(post)
text = post.content
text.gsub!(/<(script|noscript|object|embed|style|frameset|frame|iframe)[>\s\S]*<\/\1>/, '') if post.from_feed?
text = RedCloth.new(text, [:filter_styles, :no_span_caps]).to_html
text = spanify_links(text)
text = post.to_html
doc = Nokogiri::HTML(text)
doc.search("script","noscript","object","embed","style","frameset","frame","iframe").unlink if post.from_feed?
spanify_links(doc)
text = doc.at("body").inner_html
end


Expand Down Expand Up @@ -69,6 +74,10 @@ def host_helper
end
end

def relative_url_helper
ActionController::Base.respond_to?('relative_url_root=') ? ActionController::Base.relative_url_root : ActionController::AbstractRequest.relative_url_root
end

def feed_url_for(post)
case post
when Tweet, Link
Expand All @@ -79,10 +88,10 @@ def feed_url_for(post)
end

def feed_tag(name, options={})
name_str = (name || @post_type).to_s
name_str = (name || @post_type).to_s.gsub('/','')
options[:format] ||= :rss
options[:title] ||= "#{name_str.titleize} Only (#{options[:format].to_s.titleize})"
options[:url] ||= SITE_SETTINGS[:feedburner][(name || 'all')] || "http://#{host_helper}/#{name_str}.rss"
options[:title] ||= "#{name_str.titleize} Only (#{options[:format].to_s.upcase})"
options[:url] ||= SITE_SETTINGS[:feedburner][(name || 'all')] || "http://#{host_helper}#{relative_url_helper}/#{name_str}.rss"
auto_discovery_link_tag options[:format], options[:url], :title => options[:title]
end

Expand Down
32 changes: 28 additions & 4 deletions app/models/feed.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
class Feed < ActiveRecord::Base

acts_as_feed
class_inheritable_accessor :entry_type

has_many :posts

Expand All @@ -13,6 +13,30 @@ class << self
def refresh_all!
find(:all).each(&:refresh!)
end

def types
# Loading all of the subclasses so we can have a list of the various types.
Dir["#{RAILS_ROOT}/app/models/feeds/*.rb"].each { |f| require_dependency f }

self.subclasses.collect(&:to_s).sort
end

def entries_become(entry_type, &block)
self.entry_type = entry_type
has_many entry_type, :foreign_key => :feed_id, :dependent => :destroy
define_method(:refresh!) do
logger.debug "=> creating #{entry_type} from #{uri}"
entries.each { |entry| block.call(send(entry_type).build, entry) }
self.updated_at = Time.now
self.save
end
end
end

def fetch_feed
with_indifferent_io do |io|
FeedNormalizer::FeedNormalizer.parse(io)
end
end

def refresh=(res)
Expand All @@ -21,18 +45,18 @@ def refresh=(res)
end

def learn_attributes!
self.title = fetched_feed.title
self.title = fetched_feed.title
self.description = fetched_feed.description
self.url = fetched_feed.urls.first
self.update_timestamp
self.update_timestamp!
self.save
end

def type
attributes['type']
end

def update_timestamp
def update_timestamp!
self.last_updated_at = fetched_feed.last_updated || fetched_feed.entries.sort_by(&:date_published).last.date_published
end

Expand Down
21 changes: 9 additions & 12 deletions app/models/feeds/blog.rb
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
class Blog < Feed

entries_become :articles

def refresh!
entries.each do |entry|
article = articles.build :content => entry.content, :header => entry.title
article.permalink = entry.urls.first
article.created_at = entry.try(:date_published)
article.updated_at = entry.try(:last_updated)
article.save
end
update_attribute :updated_at, Time.now
entries_become :articles do |article, entry|
article.header = entry.title
article.content = entry.content
article.permalink = entry.urls.first
article.created_at = entry.try(:date_published)
article.updated_at = entry.try(:last_updated)
article.format = 'HTML'
article.save
end

end
end
Loading

0 comments on commit e2252ba

Please sign in to comment.