* 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 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

View File

@@ -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|

View File

@@ -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

View File

@@ -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
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 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)

View File

@@ -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")

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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"}

View File

@@ -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} %>

View File

@@ -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"}

View File

@@ -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"}

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"> <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>

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"> <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">

View File

@@ -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 &raquo;".html_safe, new_user_path(:anchor => "p2") %>
</footer>
</div> </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| %> <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 "&laquo; 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 "&laquo; Back".html_safe, new_user_path(:anchor => "p1") %>
</footer>
</div>
</div> </div>
</div> </div>

View File

@@ -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

View File

@@ -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
); );

View File

@@ -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

View File

@@ -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();
}
});

View File

@@ -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();
}); });

View File

@@ -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 ***/

View File

@@ -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 {

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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