* Missing files

* Work on post exploration code by traversing dates
This commit is contained in:
albert
2010-10-27 20:16:43 -04:00
parent f9cdcef2c0
commit fc0a076aca
32 changed files with 371 additions and 189 deletions

View File

@@ -1,5 +1,9 @@
class CommentVotesController < ApplicationController
def create
@comment = Comment.find(params[:comment_id])
@comment.vote!(params[:score])
rescue CommentVote::Error => x
@error = x
end
def destroy

View File

@@ -15,8 +15,6 @@ class CommentsController < ApplicationController
def create
@comment = Comment.new(params[:comment])
@comment.post_id = params[:comment][:post_id]
@comment.creator_id = CurrentUser.user.id
@comment.ip_addr = request.remote_ip
@comment.score = 0
@comment.save
respond_with(@comment) do |format|

View File

@@ -1,5 +1,9 @@
class PostVotesController < ApplicationController
def create
@post = Post.find(params[:post_id])
@post.vote!(params[:score])
rescue PostVote::Error => x
@error = x
end
def destroy

View File

@@ -23,6 +23,16 @@ module ApplicationHelper
end
end
def compact_time(time)
if time > Time.now.beginning_of_day
time.strftime("%H:%M")
elsif time > Time.now.beginning_of_year
time.strftime("%b %e")
else
time.strftime("%b %e, %Y")
end
end
protected
def nav_link_match(controller, url)
url =~ case controller

72
app/logical/date_tag.rb Normal file
View File

@@ -0,0 +1,72 @@
class DateTag
attr_accessor :tag, :start_date, :end_date
def self.new_from_range(start, stop)
new("#{start.to_formatted_s(:db)}..#{stop.to_formatted_s(:db)}")
end
def initialize(tag)
@tag = tag
end
def is_single_day?
tag =~ /^\d+-\d+-\d+$/
end
def is_range?
!is_single_day
end
def start_date
return date if is_single_day?
extract_ranges
start_date
end
def end_date
return date if is_single_day?
extract_ranges
end_date
end
def previous_week
DateTag.new_from_range(1.week.ago(start_date), 1.week.ago(end_date))
end
def next_week
DateTag.new_from_range(1.week.since(start_date)), 1.week.since(end_date)
end
def previous_month
DateTag.new_from_range(1.month.ago(start_date), 1.month.ago(end_date))
end
def next_month
DateTag.new_from_range(1.month.since(start_date)), 1.month.since(end_date)
end
def date
Date.parse(tag)
end
private
def extract_ranges
case tag
when /\A(.+?)\.\.(.+)/
self.start_date = Date.parse($1)
self.end_date = Date.parse($2)
when /\A<(.+)/, /\A<=(.+)/, /\A\.\.(.+)/
self.start_date = 20.years.ago
self.end_date = Date.parse($1)
when /\A>(.+)/, /\A>=(.+)/, /\A(.+)\.\.\Z/
self.start_date = Date.parse($1)
self.end_date = Date.today
else
self.start_date = Date.today
self.end_date = Date.today
end
end
end

View File

@@ -43,6 +43,10 @@ class PostSet
tag_array.size == 1
end
def date_tag
tag_array.grep(/date:/).first
end
def load_associations
if is_single_tag?
@wiki_page = WikiPage.find_by_title(tags)

View File

@@ -4,6 +4,7 @@ class Comment < ActiveRecord::Base
belongs_to :post
belongs_to :creator, :class_name => "User"
has_many :votes, :class_name => "CommentVote", :dependent => :destroy
before_validation :initialize_creator, :on => :create
after_save :update_last_commented_at
attr_accessible :body
attr_accessor :do_not_bump_post
@@ -12,6 +13,11 @@ class Comment < ActiveRecord::Base
scope :search_body, lambda {|query| where("body_index @@ plainto_tsquery(?)", query).order("comments.id DESC")}
scope :hidden, lambda {|user| where("score < ?", user.comment_threshold)}
def initialize_creator
self.creator_id = CurrentUser.user.id
self.ip_addr = CurrentUser.ip_addr
end
def creator_name
User.id_to_name(creator_id)
end
@@ -26,20 +32,21 @@ class Comment < ActiveRecord::Base
end
end
def vote!(is_positive)
def vote!(score)
if !CurrentUser.user.can_comment_vote?
raise CommentVote::Error.new("You can only vote ten times an hour on comments")
elsif !is_positive && creator.is_janitor_or_higher?
elsif score == "down" && creator.is_janitor?
raise CommentVote::Error.new("You cannot downvote janitor/moderator/admin comments")
elsif votes.find_by_user_id(CurrentUser.user.id).nil?
if is_positive
update_attribute(:score, score + 1)
else
update_attribute(:score, score - 1)
if score == "up"
increment!(:score)
elsif score == "down"
decrement!(:score)
end
votes.create(:user_id => CurrentUser.user.id)
votes.create
else
raise CommentVote::Error.new("You have already voted for this comment")

View File

@@ -1,11 +1,16 @@
class CommentVote < ActiveRecord::Base
class Error < Exception ; end
attr_accessor :is_positive
belongs_to :comment
belongs_to :user
before_validation :initialize_user, :on => :create
validates_presence_of :user_id, :comment_id
def self.prune!
destroy_all(["created_at < ?", 14.days.ago])
end
def initialize_user
self.user_id = CurrentUser.user.id
end
end

View File

@@ -644,15 +644,15 @@ class Post < ActiveRecord::Base
!votes.exists?(["user_id = ?", user.id])
end
def vote!(user, is_positive)
if can_be_voted_by?(user)
if is_positive
def vote!(score)
if can_be_voted_by?(CurrentUser.user)
if score == "up"
increment!(:score)
else
elsif score == "down"
decrement!(:score)
end
votes.create(:user_id => user.id)
votes.create(:score => score)
else
raise PostVote::Error.new("You have already voted for this comment")
end

View File

@@ -1,6 +1,20 @@
class PostVote < ActiveRecord::Base
class Error < Exception ; end
attr_accessor :is_positive
belongs_to :post
before_validation :initialize_user, :on => :create
validates_presence_of :post_id, :user_id, :score
validates_inclusion_of :score, :in => [1, -1]
def score=(x)
if x == "up"
write_attribute(:score, 1)
elsif x == "down"
write_attribute(:score, -1)
end
end
def initialize_user
self.user_id = CurrentUser.user.id
end
end

View File

@@ -53,7 +53,7 @@ module Paginators
elsif page == current_page
html << page.to_s
else
html << link(template, page)
html << paginated_link(template, page)
end
html << "</li>"
html.html_safe

View File

@@ -3,6 +3,6 @@
- @posts.each do |post|
%div{:class => "post"}
%div{:class => "preview"}
= image_tag(post.preview_file_url)
= render :partial => "comments/partials/index/list", :locals => {:post => post, :comments => post.comments.recent.reverse}
= link_to image_tag(post.preview_file_url), post_path(post)
= render :partial => "comments/partials/index/list", :locals => {:post => post, :comments => post.comments.recent.reverse, :show_header => true}
%div{:class => "clearfix"}

View File

@@ -12,32 +12,18 @@
%span{:class => "info"}
%strong Score
%span{:id => "score-for-post-#{post.id}"}
= post.score
<div class="header">
<div>
<span class="info"><strong>Date</strong> <%= compact_time(post.created_at) %></span>
<span class="info"><strong>User</strong> <%= fast_link_to h(post.author), :controller => "user", :action => "show", :id => post.user_id %></span>
<span class="info"><strong>Rating</strong> <%= post.pretty_rating %></span>
<span class="info">
<strong>Score</strong> <span id="post-score-<%= post.id %>"><%= post.score %></span>
<% if @current_user.is_privileged_or_higher? %>
(vote <%= link_to_function "up", "Post.vote(1, #{post.id})" %>/<%= link_to_function "down", "Post.vote(-1, #{post.id})" %>)
<% end %>
</span>
</div>
<div class="tags">
<strong>Tags</strong>
<% post.cached_tags.split(/ /).each do |name| %>
<span class="tag-type-<%= Tag.type_name(name) %>">
<%= fast_link_to h(name.tr("_", " ")), :controller => "post", :action => "index", :tags => name %>
</span>
<% end %>
</div>
<div style="margin-top: 1em;">
<% if post.comments.count > 6 %>
<span class="info" id="hidden-comments-notice-for-<%= post.id %>"><%= link_to_remote "#{pluralize post.comments.size - 6, 'comment'} hidden", :url => {:controller => "comment", :action => "index_hidden", :post_id => post.id} %>.</span>
<% end %>
<%= render :partial => "threshold_notice", :locals => {:post => post} %>
%span= post.score
- if CurrentUser.user.is_privileged?
== (vote #{link_to("up", post_votes_path(:score => "up", :post_id => post.id), :remote => true, :method => :post)}/#{link_to("down", post_votes_path(:score => "down", :post_id => post.id), :remote => true, :method => :post)})
%div{:class => "row list-of-tags"}
%strong Tags
- post.tag_array.each do |tag_name|
%span{:class => "tag-type-#{Tag.category_for(tag_name)}"}
= link_to(tag_name.tr("_", " "), posts_path(:tags => tag_name))
%div{:class => "row notices"}
- if post.comments.count > 6
%span{:class => "info", :id => "hidden-comments-notice-for-#{post.id}"}
== #{link_to "#{pluralize(post.comments.size - 6, 'comment')} hidden", comments_path(:post_id => post.id), :remote => true}.
- if post.comments.hidden(CurrentUser.user).count > 0
%span{:class => "info", :id => "threshold-comments-notice-for-#{post.id}"}
== #{link_to "#{pluralize(post.comments.hidden(CurrentUser.user).count, 'comment')} below threshold", comments_path(:post_id => post.id, :include_hidden => true), :remote => true}.

View File

@@ -1,4 +1,6 @@
%div{:class => "comments-for-post", "data-post-id" => post.id}
- if show_header
= render :partial => "comments/partials/index/header", :locals => {:post => post}
%div{:class => "list-of-comments"}
= render :partial => "comments/partials/show/comment", :collection => comments
%div{:class => "clearfix"}

View File

@@ -11,6 +11,6 @@
%span{:class => "link"} Reply
- if CurrentUser.user.is_janitor? || CurrentUser.user.id == comment.creator_id
%li= link_to "Delete", comment_path(comment.id), :confirm => "Do you really want to delete this comment?", :method => :delete
%li= link_to "Vote up", comment_vote_path(comment.id, :is_positive => true), :method => :post
%li= link_to "Vote down", comment_vote_path(comment.id, :is_positive => false), :method => :post
%li= link_to "Vote up", comment_votes_path(:comment_id => comment.id, :score => "up"), :method => :post, :remote => true
%li= link_to "Vote down", comment_votes_path(:comment_id => comment.id, :score => "down"), :method => :post, :remote => true
%div{:class => "clearfix"}

View File

@@ -1 +1,5 @@
page["#score-for-post-#{@post.id} span"].val(@post.score)
if @error
page.alert(@error.to_s)
else
page["#score-for-post-#{@post.id} span"].text(@post.score)
end

View File

@@ -9,7 +9,7 @@
<aside id="sidebar">
<section id="search-box">
<h1>Search</h1>
<% form_tag(posts_path, :method => "get") do %>
<%= form_tag(posts_path, :method => "get") do %>
<%= text_field_tag("tags", params[:tags], :size => 20) %>
<%= submit_tag "Go" %>
<% end %>
@@ -17,28 +17,7 @@
<% if CurrentUser.user.is_privileged? %>
<section id="mode-box">
<h1>Mode</h1>
<form action="/">
<select name="mode">
<option value="view">View</option>
<option value="edit">Edit</option>
<option value="add-fav">Favorite</option>
<option value="remove-fav">Unfavorite</option>
<option value="rating-s">Rate safe</option>
<option value="rating-q">Rate questionable</option>
<option value="rating-e">Rate explicit</option>
<option value="vote-up">Vote up</option>
<option value="vote-down">Vote down</option>
<option value="lock-rating">Lock rating</option>
<option value="lock-note">Lock notes</option>
<option value="edit-tag-script">Edit tag script</option>
<option value="apply-tag-script">Apply tag script</option>
<% if CurrentUser.user.is_janitor? %>
<option value="approve">Approve</option>
<% end %>
<option value="unapprove">Unapprove</option>
</select>
</form>
<%= render :partial => "posts/partials/index/mode_menu" %>
</section>
<% end %>
@@ -48,6 +27,8 @@
<ul>
</ul>
</section>
<%= render :partial => "posts/partials/index/explore", :locals => {:post_set => @post_set} %>
<section id="tag-and-wiki-box">
<menu>

View File

@@ -0,0 +1,10 @@
<% if post_set.date_tag %>
<section>
<h1>Explore</h1>
<ul>
<li>&laquo; Day &raquo;</li>
<li>&laquo; Week &raquo;</li>
<li>&laquo; Month &raquo;</li>
</ul>
</section>
<% end %>

View File

@@ -0,0 +1,22 @@
<h1>Mode</h1>
<form action="/">
<select name="mode">
<option value="view">View</option>
<option value="edit">Edit</option>
<option value="add-fav">Favorite</option>
<option value="remove-fav">Unfavorite</option>
<option value="rating-s">Rate safe</option>
<option value="rating-q">Rate questionable</option>
<option value="rating-e">Rate explicit</option>
<option value="vote-up">Vote up</option>
<option value="vote-down">Vote down</option>
<option value="lock-rating">Lock rating</option>
<option value="lock-note">Lock notes</option>
<option value="edit-tag-script">Edit tag script</option>
<option value="apply-tag-script">Apply tag script</option>
<% if CurrentUser.user.is_janitor? %>
<option value="approve">Approve</option>
<% end %>
<option value="unapprove">Unapprove</option>
</select>
</form>

View File

@@ -38,7 +38,7 @@
<section id="comments">
<h2>Comments</h2>
<%= render :partial => "comments/partials/index/list", :locals => {:comments => @post.comments, :post => @post} %>
<%= render :partial => "comments/partials/index/list", :locals => {:comments => @post.comments, :post => @post, :show_header => false} %>
</section>
<section id="notes">

View File

@@ -1,100 +1,102 @@
<div id="users-new">
<h1>Registration</h1>
<div id="p1">
<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>
<div class="users">
<div class="new">
<h1>Registration</h1>
<p>Registration for a basic account is free but comes with some limitations.</p>
<div id="p1">
<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>
<div id="account-comparison">
<section>
<h1>Basic</h1>
<ul>
<li>Free</li>
<li>Uploads limited</li>
<li>Search up to 2 tags at once</li>
<li>Some hidden posts</li>
<li>Ads visible</li>
<li>Create and edit posts, favorites, forum posts, comments, wiki pages, pools, artists, and dmails</li>
</ul>
</section>
<p>Registration for a basic account is free but comes with some limitations.</p>
<section>
<h1>Privileged</h1>
<ul>
<li>One time $20 fee</li>
<li>Uploads limited</li>
<li>Search up to 6 tags at once</li>
<li>No hidden posts</li>
<li>No ads</li>
<li>Tag subscriptions</li>
</ul>
</section>
<div id="account-comparison">
<section>
<h1>Basic</h1>
<ul>
<li>Free</li>
<li>Uploads limited</li>
<li>Search up to 2 tags at once</li>
<li>Some hidden posts</li>
<li>Ads visible</li>
<li>Create and edit posts, favorites, forum posts, comments, wiki pages, pools, artists, and dmails</li>
</ul>
</section>
<section>
<h1>Contributor</h1>
<ul>
<li>Invitation only</li>
<li>No upload limits</li>
</ul>
</section>
<section>
<h1>Privileged</h1>
<ul>
<li>One time $20 fee</li>
<li>Uploads limited</li>
<li>Search up to 6 tags at once</li>
<li>No hidden posts</li>
<li>No ads</li>
<li>Tag subscriptions</li>
</ul>
</section>
<div class="clearfix"></div>
<section>
<h1>Contributor</h1>
<ul>
<li>Invitation only</li>
<li>No upload limits</li>
</ul>
</section>
<div class="clearfix"></div>
</div>
<footer class="nav-links">
<%= link_to "Continue &raquo;".html_safe, new_user_path(:anchor => "p2") %>
</footer>
</div>
<footer class="nav-links">
<%= link_to "Continue &raquo;".html_safe, new_user_path(:anchor => "p2") %>
</footer>
</div>
<div id="p2">
<p>There are some restrictions on names:</p>
<ul>
<li><strong>Name</strong>: Your name must be at least 2 characters and at most 20 characters long. It cannot contain spaces, commas, colons, or semi-colons. All characters must be US-ASCII.</li>
<li><strong>Password</strong>: Your password must be at least 5 characters long.</li>
<li>
<strong>Email</strong>:
<% 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 %>
</li>
</ul>
<% form_for(@user) do |f| %>
<%= error_messages_for("user") %>
<div id="p2">
<p>There are some restrictions on names:</p>
<table width="100%">
<tbody>
<tr>
<th width="15%"><%= f.label :name %></th>
<td width="85%"><%= f.text_field :name %></td>
</tr>
<tr>
<th><%= f.label :password %></th>
<td><%= f.password_field :password %></td>
</tr>
<tr>
<th><%= f.label :password_confirmation %></th>
<td><%= f.password_field :password_confirmation %></td>
</tr>
<tr>
<th><%= f.label :email %></th>
<td><%= f.text_field :email %></td>
</tr>
<tr>
<td></td>
<td><%= submit_tag "Submit" %></td>
</tr>
</tbody>
</table>
<% end %>
<footer class="nav-links">
<%= link_to "&laquo; Back".html_safe, new_user_path(:anchor => "p1") %>
</footer>
<ul>
<li><strong>Name</strong>: Your name must be at least 2 characters and at most 20 characters long. It cannot contain spaces, commas, colons, or semi-colons. All characters must be US-ASCII.</li>
<li><strong>Password</strong>: Your password must be at least 5 characters long.</li>
<li>
<strong>Email</strong>:
<% 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 %>
</li>
</ul>
<% form_for(@user) do |f| %>
<%= error_messages_for("user") %>
<table width="100%">
<tbody>
<tr>
<th width="15%"><%= f.label :name %></th>
<td width="85%"><%= f.text_field :name %></td>
</tr>
<tr>
<th><%= f.label :password %></th>
<td><%= f.password_field :password %></td>
</tr>
<tr>
<th><%= f.label :password_confirmation %></th>
<td><%= f.password_field :password_confirmation %></td>
</tr>
<tr>
<th><%= f.label :email %></th>
<td><%= f.text_field :email %></td>
</tr>
<tr>
<td></td>
<td><%= submit_tag "Submit" %></td>
</tr>
</tbody>
</table>
<% end %>
<footer class="nav-links">
<%= link_to "&laquo; Back".html_safe, new_user_path(:anchor => "p1") %>
</footer>
</div>
</div>
</div>