* Missing files
* Work on post exploration code by traversing dates
This commit is contained in:
@@ -1,5 +1,9 @@
|
|||||||
class CommentVotesController < ApplicationController
|
class CommentVotesController < ApplicationController
|
||||||
def create
|
def create
|
||||||
|
@comment = Comment.find(params[:comment_id])
|
||||||
|
@comment.vote!(params[:score])
|
||||||
|
rescue CommentVote::Error => x
|
||||||
|
@error = x
|
||||||
end
|
end
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
|
|||||||
@@ -15,8 +15,6 @@ class CommentsController < ApplicationController
|
|||||||
def create
|
def create
|
||||||
@comment = Comment.new(params[:comment])
|
@comment = Comment.new(params[:comment])
|
||||||
@comment.post_id = params[:comment][:post_id]
|
@comment.post_id = params[:comment][:post_id]
|
||||||
@comment.creator_id = CurrentUser.user.id
|
|
||||||
@comment.ip_addr = request.remote_ip
|
|
||||||
@comment.score = 0
|
@comment.score = 0
|
||||||
@comment.save
|
@comment.save
|
||||||
respond_with(@comment) do |format|
|
respond_with(@comment) do |format|
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
class PostVotesController < ApplicationController
|
class PostVotesController < ApplicationController
|
||||||
def create
|
def create
|
||||||
|
@post = Post.find(params[:post_id])
|
||||||
|
@post.vote!(params[:score])
|
||||||
|
rescue PostVote::Error => x
|
||||||
|
@error = x
|
||||||
end
|
end
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
|
|||||||
@@ -23,6 +23,16 @@ module ApplicationHelper
|
|||||||
end
|
end
|
||||||
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
|
protected
|
||||||
def nav_link_match(controller, url)
|
def nav_link_match(controller, url)
|
||||||
url =~ case controller
|
url =~ case controller
|
||||||
|
|||||||
72
app/logical/date_tag.rb
Normal file
72
app/logical/date_tag.rb
Normal 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
|
||||||
@@ -43,6 +43,10 @@ class PostSet
|
|||||||
tag_array.size == 1
|
tag_array.size == 1
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def date_tag
|
||||||
|
tag_array.grep(/date:/).first
|
||||||
|
end
|
||||||
|
|
||||||
def load_associations
|
def load_associations
|
||||||
if is_single_tag?
|
if is_single_tag?
|
||||||
@wiki_page = WikiPage.find_by_title(tags)
|
@wiki_page = WikiPage.find_by_title(tags)
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ class Comment < ActiveRecord::Base
|
|||||||
belongs_to :post
|
belongs_to :post
|
||||||
belongs_to :creator, :class_name => "User"
|
belongs_to :creator, :class_name => "User"
|
||||||
has_many :votes, :class_name => "CommentVote", :dependent => :destroy
|
has_many :votes, :class_name => "CommentVote", :dependent => :destroy
|
||||||
|
before_validation :initialize_creator, :on => :create
|
||||||
after_save :update_last_commented_at
|
after_save :update_last_commented_at
|
||||||
attr_accessible :body
|
attr_accessible :body
|
||||||
attr_accessor :do_not_bump_post
|
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 :search_body, lambda {|query| where("body_index @@ plainto_tsquery(?)", query).order("comments.id DESC")}
|
||||||
scope :hidden, lambda {|user| where("score < ?", user.comment_threshold)}
|
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
|
def creator_name
|
||||||
User.id_to_name(creator_id)
|
User.id_to_name(creator_id)
|
||||||
end
|
end
|
||||||
@@ -26,20 +32,21 @@ class Comment < ActiveRecord::Base
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def vote!(is_positive)
|
def vote!(score)
|
||||||
if !CurrentUser.user.can_comment_vote?
|
if !CurrentUser.user.can_comment_vote?
|
||||||
raise CommentVote::Error.new("You can only vote ten times an hour on comments")
|
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")
|
raise CommentVote::Error.new("You cannot downvote janitor/moderator/admin comments")
|
||||||
|
|
||||||
elsif votes.find_by_user_id(CurrentUser.user.id).nil?
|
elsif votes.find_by_user_id(CurrentUser.user.id).nil?
|
||||||
if is_positive
|
if score == "up"
|
||||||
update_attribute(:score, score + 1)
|
increment!(:score)
|
||||||
else
|
elsif score == "down"
|
||||||
update_attribute(:score, score - 1)
|
decrement!(:score)
|
||||||
end
|
end
|
||||||
votes.create(:user_id => CurrentUser.user.id)
|
|
||||||
|
votes.create
|
||||||
|
|
||||||
else
|
else
|
||||||
raise CommentVote::Error.new("You have already voted for this comment")
|
raise CommentVote::Error.new("You have already voted for this comment")
|
||||||
|
|||||||
@@ -1,11 +1,16 @@
|
|||||||
class CommentVote < ActiveRecord::Base
|
class CommentVote < ActiveRecord::Base
|
||||||
class Error < Exception ; end
|
class Error < Exception ; end
|
||||||
|
|
||||||
attr_accessor :is_positive
|
|
||||||
belongs_to :comment
|
belongs_to :comment
|
||||||
belongs_to :user
|
belongs_to :user
|
||||||
|
before_validation :initialize_user, :on => :create
|
||||||
|
validates_presence_of :user_id, :comment_id
|
||||||
|
|
||||||
def self.prune!
|
def self.prune!
|
||||||
destroy_all(["created_at < ?", 14.days.ago])
|
destroy_all(["created_at < ?", 14.days.ago])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def initialize_user
|
||||||
|
self.user_id = CurrentUser.user.id
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -644,15 +644,15 @@ class Post < ActiveRecord::Base
|
|||||||
!votes.exists?(["user_id = ?", user.id])
|
!votes.exists?(["user_id = ?", user.id])
|
||||||
end
|
end
|
||||||
|
|
||||||
def vote!(user, is_positive)
|
def vote!(score)
|
||||||
if can_be_voted_by?(user)
|
if can_be_voted_by?(CurrentUser.user)
|
||||||
if is_positive
|
if score == "up"
|
||||||
increment!(:score)
|
increment!(:score)
|
||||||
else
|
elsif score == "down"
|
||||||
decrement!(:score)
|
decrement!(:score)
|
||||||
end
|
end
|
||||||
|
|
||||||
votes.create(:user_id => user.id)
|
votes.create(:score => score)
|
||||||
else
|
else
|
||||||
raise PostVote::Error.new("You have already voted for this comment")
|
raise PostVote::Error.new("You have already voted for this comment")
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,6 +1,20 @@
|
|||||||
class PostVote < ActiveRecord::Base
|
class PostVote < ActiveRecord::Base
|
||||||
class Error < Exception ; end
|
class Error < Exception ; end
|
||||||
|
|
||||||
attr_accessor :is_positive
|
|
||||||
belongs_to :post
|
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
|
end
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ module Paginators
|
|||||||
elsif page == current_page
|
elsif page == current_page
|
||||||
html << page.to_s
|
html << page.to_s
|
||||||
else
|
else
|
||||||
html << link(template, page)
|
html << paginated_link(template, page)
|
||||||
end
|
end
|
||||||
html << "</li>"
|
html << "</li>"
|
||||||
html.html_safe
|
html.html_safe
|
||||||
|
|||||||
@@ -3,6 +3,6 @@
|
|||||||
- @posts.each do |post|
|
- @posts.each do |post|
|
||||||
%div{:class => "post"}
|
%div{:class => "post"}
|
||||||
%div{:class => "preview"}
|
%div{:class => "preview"}
|
||||||
= image_tag(post.preview_file_url)
|
= 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}
|
= render :partial => "comments/partials/index/list", :locals => {:post => post, :comments => post.comments.recent.reverse, :show_header => true}
|
||||||
%div{:class => "clearfix"}
|
%div{:class => "clearfix"}
|
||||||
@@ -12,32 +12,18 @@
|
|||||||
%span{:class => "info"}
|
%span{:class => "info"}
|
||||||
%strong Score
|
%strong Score
|
||||||
%span{:id => "score-for-post-#{post.id}"}
|
%span{:id => "score-for-post-#{post.id}"}
|
||||||
= post.score
|
%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="header">
|
%div{:class => "row list-of-tags"}
|
||||||
<div>
|
%strong Tags
|
||||||
<span class="info"><strong>Date</strong> <%= compact_time(post.created_at) %></span>
|
- post.tag_array.each do |tag_name|
|
||||||
<span class="info"><strong>User</strong> <%= fast_link_to h(post.author), :controller => "user", :action => "show", :id => post.user_id %></span>
|
%span{:class => "tag-type-#{Tag.category_for(tag_name)}"}
|
||||||
<span class="info"><strong>Rating</strong> <%= post.pretty_rating %></span>
|
= link_to(tag_name.tr("_", " "), posts_path(:tags => tag_name))
|
||||||
<span class="info">
|
%div{:class => "row notices"}
|
||||||
<strong>Score</strong> <span id="post-score-<%= post.id %>"><%= post.score %></span>
|
- if post.comments.count > 6
|
||||||
<% if @current_user.is_privileged_or_higher? %>
|
%span{:class => "info", :id => "hidden-comments-notice-for-#{post.id}"}
|
||||||
(vote <%= link_to_function "up", "Post.vote(1, #{post.id})" %>/<%= link_to_function "down", "Post.vote(-1, #{post.id})" %>)
|
== #{link_to "#{pluralize(post.comments.size - 6, 'comment')} hidden", comments_path(:post_id => post.id), :remote => true}.
|
||||||
<% end %>
|
- if post.comments.hidden(CurrentUser.user).count > 0
|
||||||
</span>
|
%span{:class => "info", :id => "threshold-comments-notice-for-#{post.id}"}
|
||||||
</div>
|
== #{link_to "#{pluralize(post.comments.hidden(CurrentUser.user).count, 'comment')} below threshold", comments_path(:post_id => post.id, :include_hidden => true), :remote => true}.
|
||||||
<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} %>
|
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
%div{:class => "comments-for-post", "data-post-id" => post.id}
|
%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"}
|
%div{:class => "list-of-comments"}
|
||||||
= render :partial => "comments/partials/show/comment", :collection => comments
|
= render :partial => "comments/partials/show/comment", :collection => comments
|
||||||
%div{:class => "clearfix"}
|
%div{:class => "clearfix"}
|
||||||
|
|||||||
@@ -11,6 +11,6 @@
|
|||||||
%span{:class => "link"} Reply
|
%span{:class => "link"} Reply
|
||||||
- if CurrentUser.user.is_janitor? || CurrentUser.user.id == comment.creator_id
|
- 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 "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 up", comment_votes_path(:comment_id => comment.id, :score => "up"), :method => :post, :remote => true
|
||||||
%li= link_to "Vote down", comment_vote_path(comment.id, :is_positive => false), :method => :post
|
%li= link_to "Vote down", comment_votes_path(:comment_id => comment.id, :score => "down"), :method => :post, :remote => true
|
||||||
%div{:class => "clearfix"}
|
%div{:class => "clearfix"}
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
<aside id="sidebar">
|
<aside id="sidebar">
|
||||||
<section id="search-box">
|
<section id="search-box">
|
||||||
<h1>Search</h1>
|
<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) %>
|
<%= text_field_tag("tags", params[:tags], :size => 20) %>
|
||||||
<%= submit_tag "Go" %>
|
<%= submit_tag "Go" %>
|
||||||
<% end %>
|
<% end %>
|
||||||
@@ -17,28 +17,7 @@
|
|||||||
|
|
||||||
<% if CurrentUser.user.is_privileged? %>
|
<% if CurrentUser.user.is_privileged? %>
|
||||||
<section id="mode-box">
|
<section id="mode-box">
|
||||||
<h1>Mode</h1>
|
<%= render :partial => "posts/partials/index/mode_menu" %>
|
||||||
<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>
|
|
||||||
</section>
|
</section>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
@@ -48,6 +27,8 @@
|
|||||||
<ul>
|
<ul>
|
||||||
</ul>
|
</ul>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<%= render :partial => "posts/partials/index/explore", :locals => {:post_set => @post_set} %>
|
||||||
|
|
||||||
<section id="tag-and-wiki-box">
|
<section id="tag-and-wiki-box">
|
||||||
<menu>
|
<menu>
|
||||||
|
|||||||
10
app/views/posts/partials/index/_explore.html.erb
Normal file
10
app/views/posts/partials/index/_explore.html.erb
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<% if post_set.date_tag %>
|
||||||
|
<section>
|
||||||
|
<h1>Explore</h1>
|
||||||
|
<ul>
|
||||||
|
<li>« Day »</li>
|
||||||
|
<li>« Week »</li>
|
||||||
|
<li>« Month »</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
<% end %>
|
||||||
22
app/views/posts/partials/index/_mode_menu.html.erb
Normal file
22
app/views/posts/partials/index/_mode_menu.html.erb
Normal 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>
|
||||||
@@ -38,7 +38,7 @@
|
|||||||
|
|
||||||
<section id="comments">
|
<section id="comments">
|
||||||
<h2>Comments</h2>
|
<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>
|
||||||
|
|
||||||
<section id="notes">
|
<section id="notes">
|
||||||
|
|||||||
@@ -1,100 +1,102 @@
|
|||||||
<div id="users-new">
|
<div class="users">
|
||||||
<h1>Registration</h1>
|
<div class="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>
|
|
||||||
|
|
||||||
<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">
|
<p>Registration for a basic account is free but comes with some limitations.</p>
|
||||||
<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>
|
<div id="account-comparison">
|
||||||
<h1>Privileged</h1>
|
<section>
|
||||||
<ul>
|
<h1>Basic</h1>
|
||||||
<li>One time $20 fee</li>
|
<ul>
|
||||||
<li>Uploads limited</li>
|
<li>Free</li>
|
||||||
<li>Search up to 6 tags at once</li>
|
<li>Uploads limited</li>
|
||||||
<li>No hidden posts</li>
|
<li>Search up to 2 tags at once</li>
|
||||||
<li>No ads</li>
|
<li>Some hidden posts</li>
|
||||||
<li>Tag subscriptions</li>
|
<li>Ads visible</li>
|
||||||
</ul>
|
<li>Create and edit posts, favorites, forum posts, comments, wiki pages, pools, artists, and dmails</li>
|
||||||
</section>
|
</ul>
|
||||||
|
</section>
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
<h1>Contributor</h1>
|
<h1>Privileged</h1>
|
||||||
<ul>
|
<ul>
|
||||||
<li>Invitation only</li>
|
<li>One time $20 fee</li>
|
||||||
<li>No upload limits</li>
|
<li>Uploads limited</li>
|
||||||
</ul>
|
<li>Search up to 6 tags at once</li>
|
||||||
</section>
|
<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 »".html_safe, new_user_path(:anchor => "p2") %>
|
||||||
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<footer class="nav-links">
|
|
||||||
<%= link_to "Continue »".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| %>
|
<div id="p2">
|
||||||
<%= error_messages_for("user") %>
|
<p>There are some restrictions on names:</p>
|
||||||
|
|
||||||
<table width="100%">
|
<ul>
|
||||||
<tbody>
|
<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>
|
||||||
<tr>
|
<li><strong>Password</strong>: Your password must be at least 5 characters long.</li>
|
||||||
<th width="15%"><%= f.label :name %></th>
|
<li>
|
||||||
<td width="85%"><%= f.text_field :name %></td>
|
<strong>Email</strong>:
|
||||||
</tr>
|
<% if Danbooru.config.enable_email_verification? %>
|
||||||
<tr>
|
You must enter a valid email address. You will need to verify your email address after registering.
|
||||||
<th><%= f.label :password %></th>
|
<% else %>
|
||||||
<td><%= f.password_field :password %></td>
|
You can optionally enter an email address. Although optional, you will not be able to reset your password without an email address.
|
||||||
</tr>
|
<% end %>
|
||||||
<tr>
|
</li>
|
||||||
<th><%= f.label :password_confirmation %></th>
|
</ul>
|
||||||
<td><%= f.password_field :password_confirmation %></td>
|
|
||||||
</tr>
|
<% form_for(@user) do |f| %>
|
||||||
<tr>
|
<%= error_messages_for("user") %>
|
||||||
<th><%= f.label :email %></th>
|
|
||||||
<td><%= f.text_field :email %></td>
|
<table width="100%">
|
||||||
</tr>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td></td>
|
<th width="15%"><%= f.label :name %></th>
|
||||||
<td><%= submit_tag "Submit" %></td>
|
<td width="85%"><%= f.text_field :name %></td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
<tr>
|
||||||
</table>
|
<th><%= f.label :password %></th>
|
||||||
<% end %>
|
<td><%= f.password_field :password %></td>
|
||||||
|
</tr>
|
||||||
<footer class="nav-links">
|
<tr>
|
||||||
<%= link_to "« Back".html_safe, new_user_path(:anchor => "p1") %>
|
<th><%= f.label :password_confirmation %></th>
|
||||||
</footer>
|
<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 "« Back".html_safe, new_user_path(:anchor => "p1") %>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -176,7 +176,7 @@ module Danbooru
|
|||||||
|
|
||||||
# If enabled, users must verify their email addresses.
|
# If enabled, users must verify their email addresses.
|
||||||
def enable_email_verification?
|
def enable_email_verification?
|
||||||
true
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
# Any custom code you want to insert into the default layout without
|
# Any custom code you want to insert into the default layout without
|
||||||
|
|||||||
@@ -1089,6 +1089,7 @@ CREATE TABLE post_votes (
|
|||||||
id integer NOT NULL,
|
id integer NOT NULL,
|
||||||
post_id integer NOT NULL,
|
post_id integer NOT NULL,
|
||||||
user_id integer NOT NULL,
|
user_id integer NOT NULL,
|
||||||
|
score integer NOT NULL,
|
||||||
created_at timestamp without time zone,
|
created_at timestamp without time zone,
|
||||||
updated_at timestamp without time zone
|
updated_at timestamp without time zone
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ class CreatePostVotes < ActiveRecord::Migration
|
|||||||
create_table :post_votes do |t|
|
create_table :post_votes do |t|
|
||||||
t.column :post_id, :integer, :null => false
|
t.column :post_id, :integer, :null => false
|
||||||
t.column :user_id, :integer, :null => false
|
t.column :user_id, :integer, :null => false
|
||||||
|
t.column :score, :integer, :null => false
|
||||||
t.timestamps
|
t.timestamps
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1095,3 +1095,16 @@ $(document).ready(function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
$(document).ready(function() {
|
||||||
|
$("footer.nav-links a").click(function(event) {
|
||||||
|
$("div.users div.new > div").hide();
|
||||||
|
$(event.target.hash).show();
|
||||||
|
});
|
||||||
|
|
||||||
|
if ($("meta[name=errors]").attr("content")) {
|
||||||
|
$("#p1").hide();
|
||||||
|
$("#notice").hide();
|
||||||
|
} else {
|
||||||
|
$("#p2").hide();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
$("footer.nav-links a").click(function(event) {
|
$("footer.nav-links a").click(function(event) {
|
||||||
$("div#users-new > div").hide();
|
$("div.users div.new > div").hide();
|
||||||
$(event.target.hash).show();
|
$(event.target.hash).show();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -285,6 +285,17 @@ div.comment-list > article > div {
|
|||||||
float: left;
|
float: left;
|
||||||
width: 40em; }
|
width: 40em; }
|
||||||
|
|
||||||
|
div.comments div.index div.header span.info {
|
||||||
|
margin-right: 1.5em; }
|
||||||
|
div.comments div.index div.header strong, div.comments div.index div.header time {
|
||||||
|
margin-right: 0.3em; }
|
||||||
|
div.comments div.index div.header time {
|
||||||
|
font-weight: bold; }
|
||||||
|
div.comments div.index div.header div.list-of-tags a {
|
||||||
|
margin-right: 0.5em; }
|
||||||
|
div.comments div.index div.header div.notices {
|
||||||
|
margin: 1em 0; }
|
||||||
|
|
||||||
/*** Sessions ***/
|
/*** Sessions ***/
|
||||||
div#sessions div#new section {
|
div#sessions div#new section {
|
||||||
width: 30em;
|
width: 30em;
|
||||||
@@ -315,30 +326,30 @@ div#artists div#show {
|
|||||||
font-style: italic; }
|
font-style: italic; }
|
||||||
|
|
||||||
/*** Users ***/
|
/*** Users ***/
|
||||||
div#users div#new {
|
div.users div.new {
|
||||||
max-width: 60em; }
|
max-width: 60em; }
|
||||||
div#users div#new h1 {
|
div.users div.new h1 {
|
||||||
margin-bottom: 0.5em; }
|
margin-bottom: 0.5em; }
|
||||||
div#users div#new p {
|
div.users div.new p {
|
||||||
margin-bottom: 1em; }
|
margin-bottom: 1em; }
|
||||||
div#users div#new li {
|
div.users div.new li {
|
||||||
margin-left: 1em; }
|
margin-left: 1em; }
|
||||||
div#users div#new div#account-comparison h1 {
|
div.users div.new div#account-comparison h1 {
|
||||||
font-size: 1.4em;
|
font-size: 1.4em;
|
||||||
margin-bottom: 3px; }
|
margin-bottom: 3px; }
|
||||||
div#users div#new div#account-comparison li {
|
div.users div.new div#account-comparison li {
|
||||||
font-size: 0.9em;
|
font-size: 0.9em;
|
||||||
line-height: 1.5em; }
|
line-height: 1.5em; }
|
||||||
div#users div#new div#account-comparison section {
|
div.users div.new div#account-comparison section {
|
||||||
width: 18em;
|
width: 18em;
|
||||||
float: left;
|
float: left;
|
||||||
padding: 1em; }
|
padding: 1em; }
|
||||||
div#users div#new footer.nav-links {
|
div.users div.new footer.nav-links {
|
||||||
font-size: 1.5em;
|
font-size: 1.5em;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
display: block; }
|
display: block; }
|
||||||
div#users div#new div#p2 ul {
|
div.users div.new div#p2 ul {
|
||||||
margin-bottom: 2em; }
|
margin-bottom: 2em; }
|
||||||
|
|
||||||
/*** Uploads ***/
|
/*** Uploads ***/
|
||||||
|
|||||||
@@ -444,6 +444,34 @@ div.comment-list > article > div {
|
|||||||
width: 40em;
|
width: 40em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
div.comments {
|
||||||
|
div.index {
|
||||||
|
div.header {
|
||||||
|
span.info {
|
||||||
|
margin-right: 1.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
strong, time {
|
||||||
|
margin-right: 0.3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
time {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.list-of-tags {
|
||||||
|
a {
|
||||||
|
margin-right: 0.5em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
div.notices {
|
||||||
|
margin: 1em 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*** Sessions ***/
|
/*** Sessions ***/
|
||||||
div#sessions {
|
div#sessions {
|
||||||
@@ -497,8 +525,8 @@ div#artists {
|
|||||||
|
|
||||||
|
|
||||||
/*** Users ***/
|
/*** Users ***/
|
||||||
div#users {
|
div.users {
|
||||||
div#new {
|
div.new {
|
||||||
max-width: 60em;
|
max-width: 60em;
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
|
|||||||
@@ -11,3 +11,4 @@ cat public/javascripts/src/app/application.js >> public/javascripts/compiled/def
|
|||||||
cat public/javascripts/src/app/posts.js >> public/javascripts/compiled/default.js
|
cat public/javascripts/src/app/posts.js >> public/javascripts/compiled/default.js
|
||||||
cat public/javascripts/src/app/comments.js >> public/javascripts/compiled/default.js
|
cat public/javascripts/src/app/comments.js >> public/javascripts/compiled/default.js
|
||||||
cat public/javascripts/src/app/uploads.js >> public/javascripts/compiled/default.js
|
cat public/javascripts/src/app/uploads.js >> public/javascripts/compiled/default.js
|
||||||
|
cat public/javascripts/src/app/users.js >> public/javascripts/compiled/default.js
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
Factory.define(:comment) do |f|
|
Factory.define(:comment) do |f|
|
||||||
f.creator {|x| x.association(:user)}
|
|
||||||
f.post {|x| x.association(:post)}
|
f.post {|x| x.association(:post)}
|
||||||
f.body {Faker::Lorem.sentences}
|
f.body {Faker::Lorem.sentences}
|
||||||
f.ip_addr "127.0.0.1"
|
|
||||||
f.score 0
|
f.score 0
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ require_relative '../test_helper'
|
|||||||
|
|
||||||
class IpBanTest < ActiveSupport::TestCase
|
class IpBanTest < ActiveSupport::TestCase
|
||||||
setup do
|
setup do
|
||||||
user = Factory.create(:user)
|
@user = Factory.create(:user)
|
||||||
CurrentUser.user = user
|
CurrentUser.user = @user
|
||||||
CurrentUser.ip_addr = "127.0.0.1"
|
CurrentUser.ip_addr = "127.0.0.1"
|
||||||
MEMCACHE.flush_all
|
MEMCACHE.flush_all
|
||||||
end
|
end
|
||||||
@@ -20,8 +20,10 @@ class IpBanTest < ActiveSupport::TestCase
|
|||||||
end
|
end
|
||||||
|
|
||||||
should "be able to count any updates from a user, groupiny by IP address" do
|
should "be able to count any updates from a user, groupiny by IP address" do
|
||||||
comment = Factory.create(:comment, :ip_addr => "1.2.3.4", :body => "aaa")
|
CurrentUser.scoped(@user, "1.2.3.4") do
|
||||||
counts = IpBan.search([comment.creator_id])
|
comment = Factory.create(:comment, :body => "aaa")
|
||||||
assert_equal([{"ip_addr" => "1.2.3.4", "count" => "1"}], counts["comments"])
|
counts = IpBan.search([comment.creator_id])
|
||||||
|
assert_equal([{"ip_addr" => "1.2.3.4", "count" => "1"}], counts["comments"])
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -589,11 +589,13 @@ class PostTest < ActiveSupport::TestCase
|
|||||||
should "not allow duplicate votes" do
|
should "not allow duplicate votes" do
|
||||||
user = Factory.create(:user)
|
user = Factory.create(:user)
|
||||||
post = Factory.create(:post)
|
post = Factory.create(:post)
|
||||||
assert_nothing_raised {post.vote!(user, true)}
|
CurrentUser.scoped(user, "127.0.0.1") do
|
||||||
assert_raise(PostVote::Error) {post.vote!(user, true)}
|
assert_nothing_raised {post.vote!("up")}
|
||||||
post.reload
|
assert_raise(PostVote::Error) {post.vote!("up")}
|
||||||
assert_equal(1, PostVote.count)
|
post.reload
|
||||||
assert_equal(1, post.score)
|
assert_equal(1, PostVote.count)
|
||||||
|
assert_equal(1, post.score)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user