work on controllers/views started

This commit is contained in:
albert
2010-03-11 19:42:04 -05:00
parent ac98d7db37
commit 15c134b270
34 changed files with 720 additions and 7543 deletions

View File

@@ -1,2 +1,7 @@
class Admin::UsersController < ApplicationController
def edit
end
def update
end
end

View File

@@ -2,6 +2,7 @@ class ApplicationController < ActionController::Base
protect_from_forgery
before_filter :set_current_user
before_filter :initialize_cookies
layout "default"
protected
def access_denied
@@ -25,25 +26,15 @@ protected
end
def set_current_user
if @current_user == nil && session[:user_id]
if session[:user_id]
@current_user = User.find_by_id(session[:user_id])
end
if @current_user == nil && params[:user]
@current_user = User.authenticate(params[:user][:name], params[:user][:password])
end
if @current_user == nil && params[:api]
@current_user = User.authenticate(params[:api][:key], params[:api][:hash])
end
if @current_user
if @current_user.is_banned? && @current_user.ban && @current_user.ban.expires_at < Time.now
@current_user.update_attribute(:is_banned, false)
Ban.destroy_all("user_id = #{@current_user.id}")
end
session[:user_id] = @current_user.id
else
@current_user = AnonymousUser.new
end

View File

@@ -1,16 +1,39 @@
class PostsController < ApplicationController
before_filter :member_only, :except => [:show, :index]
after_filter :save_recent_tags, :only => [:create, :update]
after_filter :save_recent_tags, :only => [:update]
respond_to :html, :xml, :json
def index
@post_set = PostSet.new(params[:tags], params[:page], @current_user, params[:before_id])
respond_with(@post_set) do |fmt|
fmt.js
end
end
def show
@post = Post.find(params[:id])
respond_with(@post)
end
def update
@post = Post.find(params[:id])
@post.update_attributes(params[:post].merge(:updater_id => @current_user.id, :updater_ip_addr => request.remote_ip))
respond_with(@post)
end
def revert
@post = Post.find(params[:id])
@version = PostVersion.find(params[:version_id])
@post.revert_to!(@version, @current_user.id, request.remote_ip)
respond_width(@post)
end
private
def save_recent_tags
if params[:tags] || (params[:post] && params[:post][:tags])
tags = Tag.scan_tags(params[:tags] || params[:post][:tags])
tags = TagAlias.to_aliased(tags) + Tag.scan_tags(session[:recent_tags])
session[:recent_tags] = tags.uniq.slice(0, 40).join(" ")
end
end
end

View File

@@ -1,10 +1,22 @@
class SessionsController < ApplicationController
before_filter :member_only, :only => [:destroy]
def new
@user = User.new
end
def create
if User.authenticate(params[:name], params[:password])
@user = User.find_by_name(params[:name])
session[:user_id] = @user.id
redirect_to(params[:url] || posts_path, :notice => "You have logged in")
else
render :action => "edit", :flash => "Password was incorrect"
end
end
def destroy
session[:user_id] = nil
redirect_to(posts_path, :notice => "You have logged out")
end
end

View File

@@ -0,0 +1,10 @@
class UserMaintenanceController < ApplicationController
def delete_account
end
def login_reminder
end
def reset_password
end
end

View File

@@ -1,17 +1,28 @@
class UsersController < ApplicationController
respond_to :html, :xml, :json
def new
@user = User.new
end
def edit
@user = User.find(params[:id])
unless @current_user.is_admin?
@user = @current_user
end
end
def index
end
def show
@user = User.find(params[:id])
end
def create
@user = User.new(params[:user])
flash[:notice] = "You have succesfully created a new account." if @user.save
respond_with(@user)
end
def update

View File

@@ -1,12 +1,12 @@
module ApplicationHelper
def nav_link_to(text, options, html_options = nil)
if options[:controller] == params[:controller] || (%w(tag_alias tag_implication).include?(params[:controller]) && options[:controller] == "tag")
def nav_link_to(text, url, html_options = nil)
if url.include?(params[:controller]) || (%w(tag_alias tag_implication).include?(params[:controller]) && url =~ /\/tag/)
klass = "current-page"
else
klass = nil
end
%{<li class="#{klass}">} + fast_link_to(text, options, html_options) + "</li>"
(%{<li class="#{klass}">} + link_to(text, url, html_options) + "</li>").html_safe
end
def format_text(text, options = {})
@@ -22,7 +22,7 @@ module ApplicationHelper
def tag_header(tags)
unless tags.blank?
'/' + Tag.scan_query(tags).map {|t| link_to(h(t.tr("_", " ")), posts_path(:tags => t)}.join("+")
'/' + Tag.scan_query(tags).map {|t| link_to(h(t.tr("_", " ")), posts_path(:tags => t))}.join("+")
end
end

View File

@@ -0,0 +1,106 @@
# This is a proxy class to make various nil checks unnecessary
class AnonymousUser
def id
nil
end
def level
0
end
def comment_threshold
0
end
def created_at
Time.now
end
def updated_at
Time.now
end
def name
"Anonymous"
end
def pretty_name
"Anonymous"
end
def is_anonymous?
true
end
def has_mail?
false
end
def has_forum_been_updated?
false
end
def has_permission?(obj, foreign_key = :user_id)
false
end
def ban
false
end
def always_resize_images?
false
end
def show_samples?
true
end
def tag_subscriptions
[]
end
def upload_limit
0
end
def base_upload_limit
0
end
def uploaded_tags
""
end
def uploaded_tags_with_types
[]
end
def recent_tags
""
end
def recent_tags_with_types
[]
end
def can_upload?
false
end
def can_comment?
false
end
def can_remove_from_pools?
false
end
%w(banned privileged contributor janitor moderator admin).each do |name, value|
normalized_name = name.downcase.gsub(/ /, "_")
define_method("is_#{normalized_name}?") do
false
end
end
end

105
app/logical/post_set.rb Normal file
View File

@@ -0,0 +1,105 @@
class PostSet
class Error < Exception ; end
attr_accessor :tags, :page, :current_user, :before_id, :errors
attr_accessor :wiki_page, :artist, :posts, :suggestions
def initialize(tags, page, current_user, before_id = nil)
@tags = Tag.normalize(tags)
@page = page.to_i
@current_user = current_user
@before_id = before_id
@errors = []
load_associations
load_paginator
validate
end
def has_errors?
errors.any?
end
def offset
x = (page - 1) * 20
if x < 0
x = 0
end
x
end
def limit
20
end
def is_single_tag?
tag_array.size == 1
end
def load_associations
if is_single_tag?
@wiki_page = WikiPage.find_by_title(tags)
@artist = Artist.find_by_name(tags)
end
end
def load_paginator
if before_id
load_sequential_paginator
else
load_paginated_paginator
end
end
def load_paginated_paginator
@posts = Post.find_by_tags(tags, :before_id => before_id).all(:order => "posts.id desc", :limit => limit, :offset => offset)
end
def load_sequential_paginator
count = Post.fast_count(tags)
@posts = WillPaginate::Collection.create(page, limit, count) do |pager|
pager.replace(Post.find_by_sql(tags).all(:order => "posts.id desc", :limit => pager.per_page, :offset => pager.offset))
end
load_suggestions(count)
end
def load_suggestions(count)
@suggestions = Tag.find_suggestions(tags) if count < 20 && is_single_tag?
end
def tag_array
@tag_arary ||= Tag.scan_query(tags)
end
def validate
begin
validate_page
validate_query_count
rescue Error => x
@errors << x.to_s
end
end
def validate_page
if page > 1_000
raise Error.new("You cannot explicitly specify the page after page 1000")
end
end
def validate_query_count
if !current_user.is_privileged? && tag_array.size > 2
raise Error.new("You can only search up to two tags at once with a basic account")
end
if tag_array.size > 6
raise Error.new("You can only search up to six tags at once")
end
end
def to_xml
posts.to_xml
end
def to_json
posts.to_json
end
end

View File

@@ -120,12 +120,16 @@ class Tag < ActiveRecord::Base
end
module ParseMethods
def normalize(query)
query.to_s.downcase.strip
end
def scan_query(query)
query.to_s.downcase.scan(/\S+/).uniq
normalize(query).scan(/\S+/).uniq
end
def scan_tags(tags)
tags.to_s.downcase.gsub(/[,;*]/, "_").scan(/\S+/).uniq
normalize(tags).gsub(/[,;*]/, "_").scan(/\S+/).uniq
end
def parse_cast(object, type)
@@ -334,10 +338,25 @@ class Tag < ActiveRecord::Base
end
end
module SuggestionMethods
def find_suggestions(query)
query_tokens = query.split(/_/)
if query_tokens.size == 2
search_for = query_tokens.reverse.join("_").to_escaped_for_sql_like
else
search_for = "%" + query.to_escaped_for_sql_like + "%"
end
Tag.where(["name LIKE ? ESCAPE E'\\\\' AND post_count > 0 AND name <> ?", search_for, query]).all(:order => "post_count DESC", :limit => 6, :select => "name").map(&:name).sort
end
end
extend ViewCountMethods
include CategoryMethods
extend StatisticsMethods
include NameMethods
extend UpdateMethods
extend ParseMethods
extend SuggestionMethods
end

View File

@@ -4,16 +4,18 @@ class User < ActiveRecord::Base
class Error < Exception ; end
attr_accessor :password
attr_accessible :password_hash, :email, :last_logged_in_at, :last_forum_read_at, :has_mail, :receive_email_notifications, :comment_threshold, :always_resize_images, :favorite_tags, :blacklisted_tags
attr_accessible :password, :password_confirmation, :password_hash, :email, :last_logged_in_at, :last_forum_read_at, :has_mail, :receive_email_notifications, :comment_threshold, :always_resize_images, :favorite_tags, :blacklisted_tags, :name
validates_length_of :name, :within => 2..20, :on => :create
validates_format_of :name, :with => /\A[^\s;,]+\Z/, :on => :create, :message => "cannot have whitespace, commas, or semicolons"
validates_uniqueness_of :name, :case_sensitive => false, :on => :create
validates_uniqueness_of :email, :case_sensitive => false, :on => :create, :if => lambda {|rec| !rec.email.blank?}
validates_length_of :password, :minimum => 5, :if => lambda {|rec| rec.password}
validates_length_of :password, :minimum => 5, :if => lambda {|rec| rec.new_record? || rec.password}
validates_inclusion_of :default_image_size, :in => %w(medium large original)
validates_confirmation_of :password
validates_presence_of :email, :if => lambda {|rec| rec.new_record? && Danbooru.config.enable_email_verification?}
before_save :encrypt_password
after_save :update_cache
before_create :promote_to_admin_if_first_user
before_create :normalize_level
has_many :feedback, :class_name => "UserFeedback", :dependent => :destroy
belongs_to :inviter, :class_name => "User"
@@ -27,6 +29,10 @@ class User < ActiveRecord::Base
end
end
def find_by_name(name)
where(["lower(name) = ?", name.downcase]).first
end
def find_pretty_name(user_id)
find_name.tr("_", " ")
end
@@ -102,6 +108,12 @@ class User < ActiveRecord::Base
end
module LevelMethods
def promote_to_admin_if_first_user
if User.count == 0
self.is_admin = true
end
end
def normalize_level
if is_admin?
self.is_moderator = true
@@ -147,6 +159,15 @@ class User < ActiveRecord::Base
end
end
module ForumMethods
def has_forum_been_updated?
return false unless is_privileged?
newest_topic = ForumPost.first(:order => "updated_at desc", :select => "updated_at")
return false if newest_topic.nil?
return newest_topic.updated_at > user.last_forum_read_at
end
end
include NameMethods
include PasswordMethods
extend AuthenticationMethods
@@ -154,6 +175,7 @@ class User < ActiveRecord::Base
include LevelMethods
include EmailVerificationMethods
include BlacklistMethods
include ForumMethods
def can_update?(object, foreign_key = :user_id)
is_moderator? || is_admin? || object.__send__(foreign_key) == id

View File

@@ -1,23 +1,23 @@
<!doctype html>
<html>
<head>
<title><%= yield :page_title %></title>
<title><%= yield(:page_title) || Danbooru.config.app_name %></title>
<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
<link rel="top" title="<%= Danbooru.config.app_name %>" href="/">
<%= auto_discovery_link_tag :atom, posts_path(:format => "atom", :tags => params[:tags]) %>
<%= stylesheet_link_tag "default" %>
<%= javascript_include_tag "application" %>
<%= javascript_include_tag "http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js" %>
<%= Danbooru.config.custom_html_header_content %>
<%= yield :html_header_content %>
</head>
<body>
<div id="header">
<h2 id="site-title"><%= link_to(Danbooru.config.app_name, "/") %><%= tag_header(params[:tags]) %></h2>
<ul class="flat-list" id="nav">
<% if @current_user.is_member_or_higher? %>
<%= nav_link_to("My Account", user_path(@current_user)) %>
<nav>
<h1><%= link_to(Danbooru.config.app_name, "/") %><%= yield :page_header %></h1>
<ul>
<% if @current_user.is_anonymous? %>
<%= nav_link_to("Login", new_session_path) %>
<% else %>
<%= nav_link_to("Login/Signup", new_session_path) %>
<%= nav_link_to("My Account", user_path(@current_user)) %>
<% end %>
<%= nav_link_to("Posts", posts_path) %>
<%= nav_link_to("Comments", comments_path) %>
@@ -25,15 +25,15 @@
<%= nav_link_to("Artists", artists_path(:order => "date")) %>
<%= nav_link_to("Tags", tags_path(:order => "date")) %>
<%= nav_link_to("Pools", pools_path) %>
<%= nav_link_to("Wiki", wiki_page_path(:title => "help:home")) %>
<%= nav_link_to("Wiki", wiki_page_path(:id => "help:home")) %>
<%= nav_link_to("Forum", forum_topics_path, :class => (@current_user.has_forum_been_updated? ? "forum-updated" : nil)) %>
<%= nav_link_to("&raquo;", site_map_help_path) %>
<%= nav_link_to("&raquo;".html_safe, site_map_path) %>
</ul>
<%= yield :secondary_nav_links %>
</div>
</nav>
<% if flash[:notice] %>
<div id="notice"><%= h flash[:notice] %></div>
<div id="notice"><%= flash[:notice] %></div>
<% else %>
<div id="notice" style="display: none;"></div>
<% end %>
@@ -46,8 +46,8 @@
<% if !@current_user.is_privileged? %>
<div id="upgrade-account" style="display: none;">
<%= link_to "Upgrade your account for only $20", users_help_path %>
<%= link_to_function "No thanks", "$('upgrade-account').hide(); Cookie.put('hide-upgrade-account', '1', 7)", :id => "hide-upgrade-account-link" %>
<%= link_to "Upgrade your account for only $20", wiki_page_path(:id => "help:users") %>
<%= link_to "No thanks", "#", :id => "hide-upgrade-account-link" %>
</div>
<% end %>
@@ -55,21 +55,15 @@
<div id="ban-reason">
You have been banned.
<% if @current_user.ban %>
Reason: <%= h @current_user.ban.reason %>.
Reason: <%= @current_user.ban.reason %>.
Expires: <%= @current_user.ban.expires_at.strftime('%Y-%m-%d') %>
<% end %>
</div>
<% end %>
<div id="content">
<section id="content">
<%= yield :layout %>
</div>
<script type="text/javascript">
<%= yield :blacklist %>
Post.init_blacklisted();
Cookie.setup()
</script>
</section>
<%= yield :page_footer_content %>
</body>

View File

View File

View File

@@ -0,0 +1,28 @@
<% form_tag(sessions_path) do %>
<fieldset>
<legend>Login</legend>
<p>
<%= label_tag "name", "Name" %>
<%= text_field_tag "name" %>
</p>
<p>
<%= label_tag "password", "Password" %>
<%= password_field_tag "password" %>
</p>
<p>
<%= submit_tag "Submit" %>
</p>
</fieldset>
<% end %>
<aside>
<h2>Help</h2>
<ul>
<li><%= link_to "I don't have an account", new_user_path %></li>
<li><%= link_to "I forgot my password", reset_password_info_path %></li>
<li><%= link_to "I forgot my login", login_reminder_info_path %></li>
<li><%= link_to "I want to delete my account", delete_account_info_path %></li>
</ul>
</aside>

View File

@@ -0,0 +1,5 @@
<h1>Delete My Account</h1>
<p>In order to maintain accountability, accounts cannot be deleted on this site. If you're worried about someone searching for your name, you can rename your account. But any existing dmail, forum post, comment, or post will still be attributed to you.</p>
<p>Exceptions will be made for cases of extreme harassment. This harassment must have occurred on this site, whether through dmails, comments, or forum posts. Please send a dmail to an admin with details and evidence of harassment.</p>

View File

@@ -0,0 +1,5 @@
<h1>I Forgot My Login</h1>
<p>If you supplied an email address when signing up, <%= Danbooru.config.app_name %> can email you your login information. Password details will not be provided and will not be changed.</p>
<p>If you didn't supply a valid email address, you are out of luck.</p>

View File

@@ -0,0 +1,5 @@
<h1>I Forgot My Password</h1>
<p>If you supplied an email address when signing up, <%= Danbooru.config.app_name %> can reset your password and email you the new one. You are strongly advised to change your password once you log on again.</p>
<p>If you didn't supply a valid email address, you are out of luck.</p>

View File

@@ -0,0 +1,3 @@
<% content_for(:page_header) do %>
/ <%= @user.name %> / Settings
<% end %>

View File

@@ -0,0 +1,96 @@
<p><%= Danbooru.config.app_name %> is ad-sponsored and does not require an account to view. But in order to start uploading, editing, or creating content on this site, you will need to register. <em>Make sure you read and agree to the <%= link_to "terms of service", terms_of_service_path %> before registering. <strong>This site is open to web crawlers, therefore any name you choose will be public!</strong></em></p>
<p>Registration for a basic account is free but comes with some limitations.</p>
<div>
<div>
<h1>Basic</h1>
<ul>
<li>Free</li>
<li>Create and edit posts, favorites, forums, comments, wiki pages, pools, artists, and dmails</li>
<li>Search up to 2 tags at once</li>
<li>Some hidden posts</li>
<li>Ads visible</li>
<li>Uploads limited</li>
</ul>
</div>
<div>
<h1>Privileged</h1>
<ul>
<li>One time $20 fee</li>
<li>Search up to 6 tags at once</li>
<li>No hidden posts</li>
<li>No ads</li>
<li>Uploads limited</li>
<li>Tag subscriptions</li>
</ul>
</div>
<div>
<h1>Contributor</h1>
<ul>
<li>No upload limits</li>
<li>By invitation only</li>
</ul>
</div>
</div>
<% form_tag(users_path) do %>
<%= error_messages_for(@user) %>
<fieldset>
<legend>Signup</legend>
<p>
<%= label "user", "name" %>
<%= text_field "user", "name" %>
</p>
<p>
<%= label "user", "password" %>
<%= password_field "user", "password" %>
</p>
<p>
<%= label "user", "password_confirmation" %>
<%= password_field "user", "password_confirmation" %>
</p>
<p>
<%= label "user", "email" %>
<%= text_field "user", "email" %>
</p>
<%= submit_tag "Submit" %>
</fieldset>
<% end %>
<aside id="form-help">
<section>
Your name must be at least 2 characters and at most 20 characters long. It cannot contain spaces, commas, colons, or semi-colons.
</section>
<section>
Your password must be at least 5 characters long.
</section>
<section>
<% if Danbooru.config.enable_email_verification? %>
You must enter a valid email address. You will need to verify your email address after registering.
<% else %>
You can optionally enter an email address. Although optional, you will not be able to reset your password without an email address.
<% end %>
</section>
</aside>
<script type="text/javascript" charset="utf-8">
$(document).ready(function() {
$("#user_name").focus(function() {
$("#description").append("Your name must be between 2 and 20 characters, and cannot contain whitespace, commas, semicolons, or colons.");
});
$("#user_name").blur(function() {
$("#description").empty();
});
});
</script>

View File

@@ -0,0 +1,11 @@
<h1><%= @user.name %></h1>
<nav>
<ul>
<li><%= link_to "Settings", edit_user_path(@user) %></li>
</ul>
</nav>
<% content_for(:page_header) do %>
/ <%= @user.name %>
<% end %>