master
Alexander Negoda 2012-07-29 02:33:03 +04:00
parent 0ab5ab468f
commit 954e3b68ae
54 changed files with 769 additions and 283 deletions

View File

@ -5,6 +5,7 @@ gem 'rails', '3.2.6'
gem 'mime-types', :require => 'mime/types'
gem 'carrierwave', '0.6.2'
gem 'dynamic_form'
gem 'kaminari', :git => 'git://github.com/amatsuda/kaminari.git'
gem 'princely'
gem 'jquery-rails'
gem 'jquery-ui-rails'
@ -12,7 +13,8 @@ gem 'twitter-bootstrap-rails', :git => 'git://github.com/seyhunak/twitter-bootst
gem 'ajaxful_rating_jquery', :git => 'git://github.com/baxang/ajaxful_rating_jquery.git'#, :branch => 'rails3'
gem 'configatron', :git => 'git://github.com/markbates/configatron.git'
gem 'plupload-rails', :git => 'git://github.com/bryanmig/plupload-rails.git'
gem 'sequel', :git => 'git://github.com/jeremyevans/sequel.git'
#gem 'sequel', :git => 'git://github.com/jeremyevans/sequel.git'
gem 'breadcrumbs_on_rails', :git => 'git://github.com/lloydk/breadcrumbs_on_rails.git'
gem 'russian', :git => 'git://github.com/yaroslav/russian.git'
gem "devise_omniauth_engine", :git=>"git://github.com/greendog/devise_omniauth_engine.git"

View File

@ -1,3 +1,11 @@
GIT
remote: git://github.com/amatsuda/kaminari.git
revision: 82a38e07db1ca1598c8daf073a8f6be22ae714d6
specs:
kaminari (0.13.0)
actionpack (>= 3.0.0)
activesupport (>= 3.0.0)
GIT
remote: git://github.com/baxang/ajaxful_rating_jquery.git
revision: b4a2c760cdbad9cd865fb18667d14045018287ed
@ -21,10 +29,10 @@ GIT
yettings
GIT
remote: git://github.com/jeremyevans/sequel.git
revision: 4b3396b47fdec748a4ed8fae8f6745d2fb5f1f71
remote: git://github.com/lloydk/breadcrumbs_on_rails.git
revision: 310c40186b97dc816e22e9be7aac3b43dcef040b
specs:
sequel (3.37.0)
breadcrumbs_on_rails (2.2.0)
GIT
remote: git://github.com/mamantoha/omniauth-vkontakte.git
@ -258,6 +266,7 @@ PLATFORMS
DEPENDENCIES
ajaxful_rating_jquery!
breadcrumbs_on_rails!
cancan
carrierwave (= 0.6.2)
coffee-rails
@ -268,6 +277,7 @@ DEPENDENCIES
fog
jquery-rails
jquery-ui-rails
kaminari!
machinist
mime-types
mini_exiftool
@ -282,7 +292,6 @@ DEPENDENCIES
rails (= 3.2.6)
russian!
sass-rails
sequel!
sqlite3
twitter-bootstrap-rails!
uglifier

View File

@ -8,6 +8,11 @@
//= require jquery_ujs
//= require jquery.easing.1.3
//= require jquery.noisy.min
//= require jquery.mousewheel
//= require fancybox/jquery.fancybox.pack
//= require fancybox/helpers/jquery.fancybox-buttons
//= require fancybox/helpers/jquery.fancybox-media
//= require fancybox/helpers/jquery.fancybox-thumbs
//= require twitter/bootstrap
//= require plupload
//= require jquery.plupload.queue
@ -24,9 +29,31 @@ $(document).ready(function () {
$('body').noisy({
'intensity':10,
'size':200,
'opacity':0.320,
'opacity':0.120,
'fallback':'',
'monochrome':false
}).css('background-color', '#fefefe');
$('.icon-popover').popover()
$(".fancybox-thumb").fancybox({
prevEffect : 'none',
nextEffect : 'none',
helpers : {
title : {
type: 'outside'
},
overlay : {
opacity : 0.8,
css : {
'background-color' : '#000'
}
},
thumbs : {
width : 50,
height : 50
}
}
});
});

View File

@ -0,0 +1,2 @@
// Place all the behaviors and hooks related to the matching controller here.
// All this logic will automatically be available in application.js.

View File

@ -1,51 +1,55 @@
/*
*= require_self
*= require_tree .
*= require jquery.plupload.queue
*= require bootstrap_and_overrides
*= require fancybox/jquery.fancybox
*= require fancybox/helpers/jquery.fancybox-buttons
*= require fancybox/helpers/jquery.fancybox-thumbs
*= require_self
*/
*{
text-shadow: 1px 1px 1px #fff;
* {
text-shadow: 1px 1px 1px #999;
/*text-shadow: 0 1px 0 rgba(255, 255, 255, 0.1), 0 0 30px rgba(255, 255, 255, 0.125);*/
font-family: 'Nunito', 'Istok Web', sans-serif;
color: #959494;
color: #333;
}
body {
padding-top: 90px;
padding-bottom: 40px;
}
h1, h2, h3, h4, h5, h6 {
color: #666;
}
.navbar-inner {
background-color: #FAFAFA;
background-image: -moz-linear-gradient(center top, #FAFAFA, #EAEAEA);
background-image: -ms-linear-gradient(center top, #FAFAFA, #EAEAEA);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#FAFAFA), to(#EAEAEA));
background-image: -webkit-linear-gradient(center top, #FAFAFA, #EAEAEA);
background-image: -o-linear-gradient(center top, #FAFAFA, #EAEAEA);
background-image: linear-gradient(top, #FAFAFA, #EAEAEA);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr = '#FAFAFA', endColorstr = '#EAEAEA', GradientType = 0);
background-color: #FAFAFA !important;
background-image: -moz-linear-gradient(center top, #FAFAFA, #EAEAEA) !important;
background-image: -ms-linear-gradient(center top, #FAFAFA, #EAEAEA) !important;
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#FAFAFA), to(#EAEAEA)) !important;
background-image: -webkit-linear-gradient(center top, #FAFAFA, #EAEAEA) !important;
background-image: -o-linear-gradient(center top, #FAFAFA, #EAEAEA) !important;
background-image: linear-gradient(top, #FAFAFA, #EAEAEA) !important;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr = '#FAFAFA', endColorstr = '#EAEAEA', GradientType = 0) !important;
}
.navbar .brand {
color: #000;
font-weight: bold;
padding-bottom: 5px;
color: #000 !important;
font-weight: bold !important;
padding-bottom: 5px !important;
padding: 10px 20px 12px;
/*text-shadow: 0 1px 0 rgba(255, 255, 255, 0.1), 0 0 30px rgba(255, 255, 255, 0.125);*/
}
navbar .nav .dropdown-toggle .caret, .navbar .nav .open.dropdown .caret {
.navbar .nav .dropdown-toggle .caret, .navbar .nav .open.dropdown .caret {
border-top-color: #000000;
}
.navbar .nav {
margin-top: 15px;
margin-top: 5px;
margin-bottom: 10px;
}
.navbar .nav > li {
@ -54,7 +58,6 @@ navbar .nav .dropdown-toggle .caret, .navbar .nav .open.dropdown .caret {
.navbar .nav .divider-vertical {
padding: 0;
height: 61px;
}
.navbar .nav > li > a {
@ -107,17 +110,21 @@ navbar .nav .dropdown-toggle .caret, .navbar .nav .open.dropdown .caret {
box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.5), 0 1px 0px rgba(255, 255, 255, 0.75);
transition: none;
}
.navbar-search .search-query :-moz-placeholder {
color: #666;
}
.navbar-search .search-query::-webkit-input-placeholder {
color: #666;
}
.navbar-search .search-query:hover {
color: #333;
background-color: #999999;
background-color: rgba(255, 255, 255, 0.5);
}
.navbar-search .search-query:focus, .navbar-search .search-query.focused {
padding: 5px 10px;
color: #333333;
@ -128,10 +135,57 @@ navbar .nav .dropdown-toggle .caret, .navbar .nav .open.dropdown .caret {
outline: 0;
}
.ajaxful-rating-wrapper{
.ajaxful-rating-wrapper {
float: right;
}
.view-btn{
.view-btn {
display: inline;
padding: 5px;
float: left;
}
.anythingSlider {
padding: 0 0 28px 0;
}
.thumbnail {
background: none repeat scroll 0 0 #FFFFFF;
border: 0 none;
border-radius: 7px 7px 7px 7px;
box-shadow: 1px 1px 3px #D9D9D9;
display: block;
height: 340px;
}
.caption {
position: relative;
bottom: 0px;
height: 150px;
}
.caption .title {
padding: 5px 0 5px 0;
font-size: 13px;
text-align: center;
}
.caption .descr {
display: block;
padding: 10px 0 0 0;
}
.caption .controls {
position: absolute;
bottom: 5px;
width: 250px;
}
.caption .controls .tooltips{
float: left;
width: 15px;
padding: 5px;
}
.icon-popover{
cursor: pointer;
}

View File

@ -0,0 +1,3 @@
// Place all the styles related to the home controller here.
// They will automatically be included in application.css.
// You can use Less here: http://lesscss.org/

View File

@ -20,7 +20,7 @@ class AlbumsController < ApplicationController
end
}
else
@albums = Album.order('albums.title')
@albums = Album.popular.page(@page).per(@per_page)
end
respond_to do |format|
format.html
@ -40,6 +40,8 @@ class AlbumsController < ApplicationController
def show
@album = Album.find( params[:id])
@photos = @album.photos.popular
respond_to do |format|
format.html
format.json { render :json => @album }
@ -98,5 +100,11 @@ class AlbumsController < ApplicationController
redirect_to @album
end
end
def rate
@album = Album.find(params[:id])
@album.rate(params[:stars], current_user, params[:dimension])
render :json => {:id => @album.wrapper_dom_id(params), :width => 125}
end
end

View File

@ -6,8 +6,9 @@ class ApplicationController < ActionController::Base
helper :all # include all helpers, all the time
protect_from_forgery # See ActionController::RequestForgeryProtection for details
before_filter :set_locale
before_filter :authenticate_user!, :set_current_user
before_filter :setup
before_filter :setup, :set_pagination_params
private
# This hack is needed to access the current user in models. See http://rails-bestpractices.com/posts/47-fetch-current-user-in-models
@ -31,4 +32,20 @@ class ApplicationController < ActionController::Base
redirect_to(session[:return_to] || default)
session[:return_to] = nil
end
private
def set_pagination_params
@page = params[:page]
@per_page = params[:per_page]
end
def set_locale
I18n.locale = session[:locale]
if params[:locale] && I18n.available_locales.include?(params[:locale].to_sym)
session[:locale] = I18n.locale = params[:locale].to_sym
end
end
end

View File

@ -1,11 +1,13 @@
class CollectionsController < ApplicationController
before_filter :check_public_access
skip_before_filter :authenticate_user!, :only => [:index, :show]
add_breadcrumb I18n.t('home_page'), :root_path, :title => I18n.t('home_page')
def index
@collections = Collection.includes(:albums => :photos).where("photos.id NOT NULL").group_for.order('collections.title')
@popular_photos = Photo.visible.order('rating_average asc').limit(10)
add_breadcrumb t('activerecord.models.collection.popular'), collections_path, :title => t('activerecord.models.collection.popular')
add_breadcrumb t('activerecord.actions.create', :model => I18n.t('activerecord.models.collection.single')), new_collection_path,
:title => t('activerecord.actions.create'), :li_icon => 'icon-plus-sign'
@collections = Collection.popular.page(@page).per(@per_page)
respond_to do |format|
format.html
@ -16,7 +18,14 @@ class CollectionsController < ApplicationController
def show
@collection = Collection.find( params[:id] )
@albums = @collection.albums.order('title')
add_breadcrumb t('activerecord.models.collection.popular'), collections_path, :title => t('activerecord.models.collection.popular')
add_breadcrumb @collection.title, collection_path(@collection), :title => @collection.title
add_breadcrumb t('activerecord.actions.update', :model => I18n.t('activerecord.models.collection.single')), edit_collection_path,
:title => t('activerecord.actions.update', :model => I18n.t('activerecord.models.collection.single'))
add_breadcrumb t('activerecord.actions.destroy', :model => I18n.t('activerecord.models.collection.single')),collection_path(@collection),
:title => t('activerecord.actions.destroy', :model => I18n.t('activerecord.models.collection.single'))
@albums = @collection.albums.includes(:photos).where("photos.id NOT NULL").order('albums.rating_average desc').page(@page).per(@per_page)
respond_to do |format|
format.html
format.json { render :json => @collection }
@ -27,6 +36,8 @@ class CollectionsController < ApplicationController
def new
@collection = Collection.new
add_breadcrumb t('activerecord.models.collection.other').mb_chars.capitalize.to_s, collections_path, :title => t('activerecord.models.collection.other')
add_breadcrumb t('activerecord.actions.new', :model => I18n.t('activerecord.models.collection.one')), new_collection_path, :title => t('activerecord.actions.new')
end
def create
@ -45,6 +56,8 @@ class CollectionsController < ApplicationController
def update
@collection = Collection.find( params[:id])
add_breadcrumb t('activerecord.models.collection.popular'), collections_path, :title => t('activerecord.models.collection.popular')
add_breadcrumb t('activerecord.actions.create', :model => I18n.t('activerecord.models.collection.single')), new_collection_path, :title => t('activerecord.actions.create')
if @collection.update_attributes(params[:collection])
flash[:notice] = "Collection updated!"
redirect_to @collection

View File

@ -0,0 +1,16 @@
class HomeController < ApplicationController
skip_before_filter :authenticate_user!, :only => [:index]
add_breadcrumb t('home_page'), :root_path
def index
@collections = Collection.popular.limit(12)
@popular_photos = Photo.popular.limit(10)
respond_to do |format|
format.html
format.json { render :json => @collections }
format.xml { render :xml => @collections }
end
end
end

View File

@ -1,4 +1,6 @@
class LocaleController < ApplicationController
skip_before_filter :authenticate_user!, :only => [:set]
def set
if request.referer && request.referer.starts_with?('http://' + request.host)
session['return_to'] = request.referer

View File

@ -25,7 +25,7 @@ class PhotosController < ApplicationController
end
}
else
@photos = Photo.order("photos.id ASC")
@photos = Photo.popular.page(@page).per(@per_page)
end
respond_to do |format|
format.html
@ -148,4 +148,10 @@ class PhotosController < ApplicationController
redirect_to @photo
end
end
def rate
@photo = Photo.find(params[:id])
@photo.rate(params[:stars], current_user, params[:dimension])
render :json => {:id => @photo.wrapper_dom_id(params), :width => 125}
end
end

View File

@ -1,12 +1,13 @@
# Methods added to this helper will be available to all templates in the application.
module ApplicationHelper
=begin
def breadcrumbs(sep = "/", include_home = true)
levels = request.path.split('?')[0].split('/')
levels.delete_at(0)
#links = "You are here: "
links = content_tag('a', "HOME", :href => root_path ) if include_home
links = content_tag('li', (content_tag('a', t(:home_page), :href => root_path ) if include_home))
nocrumb = ["collections", "albums", "photos", "tags", "new", "edit", "tags"]
@ -15,12 +16,19 @@ module ApplicationHelper
level = level.gsub("-", " ")
if index+1 == levels.length
#links += " #{sep} #{level.upcase}" unless nocrumb.include?(level)
elsif !nocrumb.include?(level)
#elsif !nocrumb.include?(level)
links += " " + sep + " "
links += content_tag('a', level.upcase, :href => '/'+levels[0..index].join('/'))
links += content_tag('li', content_tag('a', level, :href => '/'+levels[0..index].join('/')))
end
end
content_tag("div", links, :id => "breadcrumb")
end
content_tag("ul", links, :class => "breadcrumb")
end
=end
def pluralize(string, count=nil, variants=nil)
# example variants for russian: # Russian.pluralize(3.14, "вещь", "вещи", "вещей", "вещи")
a,b,c,d=*variants
I18n.locale.eql?(:ru) ? Russian.pluralize(count, a,b,c,d) : string.pluralize
end
end

View File

@ -0,0 +1,2 @@
module HomeHelper
end

View File

@ -9,95 +9,96 @@ class Album < ActiveRecord::Base
validates :path, :presence => true, :uniqueness => true #, :message => "Album already exsists on disc"
validates :title, :presence => true #, :message => "can't be blank"
before_validation :ensure_path, :set_title
after_create :create_folders
after_destroy :destroy_folders
attr_accessor :tags
#attr_protected :path
scope :untouched, where("albums.id IN ( SELECT DISTINCT photos.album_id FROM photos WHERE photos.description IS NULL AND photos.id NOT IN ( SELECT photo_id FROM photo_tags) )").order('title')
scope :unused, where("albums.id NOT IN (SELECT album_id FROM collection_albums)")
scope :used, where("albums.id IN (SELECT album_id FROM collection_albums)")
scope :visible, lambda { where(:public => true) }
scope :popular, lambda{visible.includes(:photos).where("photos.id NOT NULL").order('albums.rating_average desc')}
scope :untouched, lambda{where("albums.id IN ( SELECT DISTINCT photos.album_id FROM photos WHERE photos.description IS NULL AND photos.id NOT IN ( SELECT photo_id FROM photo_tags) )").order('title')}
scope :unused, lambda{where("albums.id NOT IN (SELECT album_id FROM collection_albums)")}
scope :used, lambda{where("albums.id IN (SELECT album_id FROM collection_albums)")}
def to_param
"#{id}-#{title.parameterize}"
end
def ensure_path
self.path = self.title.parameterize unless self.path
end
def set_title
self.title = File.basename(self.path).titleize unless self.title || !self.path
end
def tags
# should maybe cache this to database?
# should maybe return array instead?
tags = Array.new
self.photos.map{ |photo|
if photo.tags.empty?
# photo has no tags => no unversial tags for this album
return
else
photo.tags
end
}.each_with_index{ |photo_tags,i|
# returns tag collection for each photo
if i == 0
tags = photo_tags
else
# combine arrays if they have identical tags.
# Will remove tags that are only tagged to one photo
#tags = tags & photo_tags
tags = tags & photo_tags
end
self.photos.map { |photo|
if photo.tags.empty?
# photo has no tags => no unversial tags for this album
return
else
photo.tags
end
}.each_with_index { |photo_tags, i|
# returns tag collection for each photo
if i == 0
tags = photo_tags
else
# combine arrays if they have identical tags.
# Will remove tags that are only tagged to one photo
#tags = tags & photo_tags
tags = tags & photo_tags
end
}
return tags
end
def tags=(tags)
tags = tags.split(" ").sort
current_tags = ( self.tags.nil? ? [] : self.tags.map{|tag|tag.title} )
current_tags = (self.tags.nil? ? [] : self.tags.map { |tag| tag.title })
return if tags == self.tags
# find tags that should be removed from this album - thus remove from all photos in album
# i.e. tags listed in self.tag_list but no in parameter tags
#current_tags.map {|tag|tag if !tags.include?(tag) }.compact
(current_tags - tags).each { |tag|
self.photos.each {|photo|
photo.untag( tag )
self.photos.each { |photo|
photo.untag(tag)
}
}
# add universial tags to all photos in album
(tags - current_tags).each do |tag|
self.photos.each { |photo|
photo.tag( tag )
photo.tag(tag)
}
end
end
def photo_tags
tags = Array.new
self.photos.each{ |photo|
self.photos.each { |photo|
tags = tags | photo.tags
}
return tags
end
end
protected
private
def create_folders
#Dir.mkdir( APP_CONFIG[:photos_path] + self.path ) unless File.exists?( APP_CONFIG[:photos_path] + self.path )
#Dir.mkdir( APP_CONFIG[:thumbs_path] + self.path ) unless File.exists?( APP_CONFIG[:thumbs_path] + self.path )
end
def destroy_folders
#puts "DELETE DIRECTORY " + APP_CONFIG[:photos_path] + self.path
#Dir.delete( APP_CONFIG[:photos_path] + self.path ) if File.exists?( APP_CONFIG[:photos_path] + self.path )

View File

@ -9,6 +9,12 @@ class Collection < ActiveRecord::Base
validates :title, :presence => true
scope :visible, where(:public => true)
scope :popular, lambda{visible.includes(:albums => :photos).where("photos.id NOT NULL").order('collections.rating_average desc')}
def photos_count
self.albums.includes(:photos).size
end
def to_param
"#{id}-#{title.parameterize}"

View File

@ -16,6 +16,7 @@ class Photo < ActiveRecord::Base
attr_accessor :tag_list
scope :visible, where(:public => true)
scope :popular, visible.order('rating_average desc')
scope :untouched, :conditions => "photos.description IS NULL AND photos.id NOT IN ( SELECT photo_id FROM photo_tags)", :include => :album
scope :previous, lambda { |p,a| { :conditions => ["id < :id AND album_Id = :album ", { :id => p, :album => a } ], :limit => 1, :order => "id DESC"} }
scope :next, lambda { |p,a| { :conditions => ["id > :id AND album_Id = :album ", { :id => p, :album => a } ], :limit => 1, :order => "id ASC"} }
@ -59,8 +60,7 @@ class Photo < ActiveRecord::Base
private
def set_title
a=self.attachment.file.basename
update_attribute(:title, a.titleize)
update_attribute(:title, self.attachment.file.basename.titleize)
self.title = self.attachment.file.basename.titleize unless self.title
end

View File

@ -49,7 +49,7 @@ class FileUploader < CarrierWave::Uploader::Base
# end
# Create different versions of your uploaded files
version :collection do
version :thumb do
process :resize_to_fill => [260, 180]
def store_dir
@ -57,13 +57,6 @@ class FileUploader < CarrierWave::Uploader::Base
end
end
version :album do
process :resize_to_fill => [100, 100]
def store_dir
ENV['STORAGE_PATH'] + "/thumbs/#{model.album.path}/#{model.id}"
end
end
######################################################################################################################
# Note

View File

@ -0,0 +1,28 @@
<div class="row">
<div class="span12">
<% @albums.in_groups_of(4).each do |group| %>
<% unless group.empty? %>
<ul class="thumbnails">
<% group.compact.each_with_index do |album, index| %>
<li class="span3">
<div class="thumbnail">
<%= image_tag album.photos.first.attachment.thumb.url %>
<div class="caption">
<h5 class="title"><%= album.title %></h5>
<em class="descr"><%= album.description %></em>
<div class="controls">
<p class="view-btn"><%= link_to 'View', (album_path(album) unless album.photos.empty?), {:class => 'btn btn-primary'} %></p>
<div class="tooltips">
<span rel="popover" class="icon-th icon-popover" data-content="<%= t(:photos_counter, :count => album.photos.count) %>"></span>
</div>
<%= ratings_for album %>
</div>
</div>
</div>
</li>
<% end %>
</ul>
<% end %>
<% end %>
</div>
</div>

View File

@ -1,19 +1,11 @@
<% for album in @albums %>
<div class="row">
<div class="title">
<%= render :partial => "photos/thumb", :locals => {:photo => album.photos.first } unless album.photos.empty? %>
<p><%= link_to album.title, album %></p>
</div>
<div class="image">
<%= render :partial => "photos/thumb", :collection => album.photos.find(:all, :limit => 5, :offset => 1), :as => :photo %>
</div>
</div>
<% end %>
<%= paginate @albums %>
<%= render 'row_collections' %>
<%= paginate @albums %>
<%= content_for :action_links do %>
<%= link_to "Show just the photos tagged with #{params[:q]}", photos_path(:q => params[:q]) if params[:q] %>
<% if has_role?("admin") %>
<%= " |&nbsp;" if params[:q] %>
<%= link_to "New album", new_album_path() %>
<% end %>
<%= link_to "Show just the photos tagged with #{params[:q]}", photos_path(:q => params[:q]) if params[:q] %>
<% if current_user and current_user.has_role?("admin") %>
<%= " |&nbsp;" if params[:q] %>
<%= link_to "New album", new_album_path() %>
<% end %>
<% end %>

View File

@ -1,60 +1,47 @@
<h2><%= @album.title %></h2>
<div id="multipleimages">
<table>
<% count = 0.0 %>
<% for photo in @album.photos.find(:all, :order => "Id ASC") %>
<% count += 1%>
<% if count == 1 || ( (count-1) / 4.0 == ( (count-1) / 4.0).to_i ) %><tr><% end %>
<td><%= link_to image_tag( photo.attachment.preview.url ), [@album.collections.first, @album, photo] %></td>
<% if count / 4.0 == (count / 4.0).to_i %></tr><% end %>
<% end %>
</table>
</div>
<%= render :partial => 'photos/row_collections' %>
<p><%= @album.description %></p>
<% unless @album.photo_tags.empty? %>
<p>Tagged with:
<% for tag in @album.photo_tags.map{|tag|tag.title}.sort %>
<%= link_to tag, album_tag_photos_path(@album, tag) %>
<% end %>
</p>
<p>Tagged with:
<% for tag in @album.photo_tags.map { |tag| tag.title }.sort %>
<%= link_to tag, album_tag_photos_path(@album, tag) %>
<% end %>
</p>
<% end %>
<% unless @album.collections.empty? %>
<p>Part of:
<% for collection in @album.collections.find(:all, :order => 'title') %>
<%= link_to collection.title, collection_path(collection) %>
<% end %>
</p>
<p>Part of:
<% for collection in @album.collections.order('title') %>
<%= link_to collection.title, collection_path(collection) %>
<% end %>
</p>
<% end %>
<% if has_role?("admin") %>
<p><%= @album.address %></p>
<% end %>
<% if has_role?("admin") %>
<p><%= @album.note %></p>
<% if current_user and current_user.has_role?("admin") %>
<p><%= @album.address %></p>
<p><%= @album.note %></p>
<% end %>
<%= content_for :action_links do %>
<% if has_role?("admin") %>
<% if params[:collection_id] %>
<%= link_to "PDF", collection_album_path(params[:collection_id],@album, :format => 'pdf') %> |&nbsp;
<%= link_to "Edit album", edit_collection_album_path(params[:collection_id],@album) %> |&nbsp;
<%= link_to "Edit all photos", edit_multiple_collection_album_photos_path(params[:collection_id],@album) %> |&nbsp;
<%= link_to "Edit untouched photos", untouched_collection_album_photos_path(params[:collection_id], @album) %> |&nbsp;
<%= link_to "Add photos", upload_collection_album_photos_path(params[:collection_id], @album) %>
<% else %>
<%= link_to "PDF", album_path(@album, :format => 'pdf') %> |&nbsp;
<%= link_to "Edit album", edit_album_path(@album) %> |&nbsp;
<%= link_to "Edit all photos", edit_multiple_album_photos_path(@album) %> |&nbsp;
<%= link_to "Edit untouched photos", untouched_album_photos_path(@album) %> |&nbsp;
<%= link_to "Add photos", upload_album_photos_path(@album) %>
<% end %>
<% if current_user and current_user.has_role?("admin") %>
<% if params[:collection_id] %>
<li><%= link_to "PDF", collection_album_path(params[:collection_id], @album, :format => 'pdf') %></li>
<li><%= link_to "Edit album", edit_collection_album_path(params[:collection_id], @album) %></li>
<li><%= link_to "Edit all photos", edit_multiple_collection_album_photos_path(params[:collection_id], @album) %></li>
<li><%= link_to "Edit untouched photos", untouched_collection_album_photos_path(params[:collection_id], @album) %></li>
<li><%= link_to "Add photos", upload_collection_album_photos_path(params[:collection_id], @album) %></li>
<% else %>
<li><%= link_to "PDF", album_path(@album, :format => 'pdf') %></li>
<li><%= link_to "Edit album", edit_album_path(@album) %></li>
<li><%= link_to "Edit all photos", edit_multiple_album_photos_path(@album) %></li>
<li><%= link_to "Edit untouched photos", untouched_album_photos_path(@album) %></li>
<li><%= link_to "Add photos", upload_album_photos_path(@album) %></li>
<% end %>
<% end %>
<% end %>
<% end %>

View File

@ -1,38 +1,40 @@
<%= form.label :title, :Title, {:class => 'big'} %><br />
<%= form.text_field :title, {:class => 'big'} %><br />
<fieldset>
<div class="control-group">
<%= form.label :title, t('activerecord.models.collection.attributes.title'), {:class => 'control-label'} %>
<div class="controls">
<%= form.text_field :title, {:class => 'input-xlarge'} %>
</div>
</div>
<%= form.label :description %><br />
<%= form.text_area :description %><br />
<div class="control-group">
<%= form.label :description, t('activerecord.models.collection.attributes.description'), {:class => 'control-label'} %>
<div class="controls">
<%= form.text_area :description, {:class => 'input-xlarge', :rows => 5} %>
</div>
</div>
<% unless @collection.albums.empty? %>
<%= form.label :albums %><br />
<div id="collection_albums">
<% for album in @collection.albums %>
<%= form.fields_for :album_list do |album_fields| %>
<span>
<%= image_tag "delete-24x24.png", :class => "delete", :alt => "Delete" -%>
<% unless @collection.albums.empty? %>
<%= form.label :albums %>
<% @collection.albums.each do |album| %>
<%= form.fields_for :album_list do |album_fields| %>
<%= image_tag "delete-24x24.png", :class => "delete", :alt => "Delete" -%>
<% if album.photos.empty? %>
<%= album.title %>
<% else %>
<%= image_tag album.photos.first.attachment.thumb.url, :alt => album.title %>
<% end %>
<%= album_fields.hidden_field album.id %>
<% end %>
<% end %>
<% if album.photos.empty? %>
<%= album.title %>
<% else %>
<%= image_tag album.photos.first.attachment.album.url, :alt => album.title %>
<% end %>
<%= album_fields.hidden_field album.id %>
</span>
<% end %>
<% end %>
</div>
<p class="clear">
<%
grouped_options = [
['Available albums',[['Choose album to add','']]],
['Not used', Album.unused.map{|album|[album.title, album.id]} ],
['In use', Album.used.map{|album|[album.title, album.id]} ]
]
grouped_options_for_select(grouped_options)
%>
<%= select_tag 'available_albums', grouped_options_for_select(grouped_options) %>
</p>
<% end %>
<%
grouped_options = [
['Available albums', [['Choose album to add', '']]],
['Not used', Album.unused.map { |album| [album.title, album.id] }],
['In use', Album.used.map { |album| [album.title, album.id] }]
]
grouped_options_for_select(grouped_options)
%>
<%= select_tag 'available_albums', grouped_options_for_select(grouped_options) %>
<% end %>
</fieldset>

View File

@ -0,0 +1,29 @@
<div class="row">
<div class="span12">
<% @collections.in_groups_of(4).each do |group| %>
<% unless group.empty? %>
<ul class="thumbnails">
<% group.compact.each_with_index do |collection, index| %>
<li class="span3">
<div class="thumbnail">
<%= image_tag collection.albums.first.photos.first.attachment.thumb.url %>
<div class="caption">
<h5 class="title"><%= collection.title %></h5>
<em class="descr"><%= collection.description %></em>
<div class="controls">
<p class="view-btn"><%= link_to 'View', (collection_path(collection) unless collection.albums.empty? || collection.albums.first.photos.empty?), {:class => 'btn btn-primary'} %></p>
<div class="tooltips">
<span rel="popover" class="icon-th-large icon-popover" data-content="<%= t(:albums_counter, :count => collection.albums.size) %>"></span>
<span rel="popover" class="icon-th icon-popover" data-content="<%= t(:photos_counter, :count => collection.photos_count) %>"></span>
</div>
<%= ratings_for collection %>
</div>
</div>
</div>
</li>
<% end %>
</ul>
<% end %>
<% end %>
</div>
</div>

View File

@ -1,36 +1,6 @@
<div class="row">
<%= render 'shared/home_slider' %>
</div>
<div class="clearfix"></div>
<div class="row">
<div class="span12">
<% @collections.in_groups_of(4).each do |group| %>
<% unless group.empty? %>
<ul class="thumbnails">
<% group.compact.each_with_index do |collection, index| %>
<li class="span3">
<div class="thumbnail">
<%= image_tag collection.albums.first.photos.first.attachment.collection.url %>
<div class="caption">
<h5><%= collection.title %></h5>
<p><%= collection.description %></p>
<p class="view-btn"><%= link_to 'View', (collection_path(collection) unless collection.albums.empty? || collection.albums.first.photos.empty?), {:class => 'btn btn-primary'} %></p>
<%= ratings_for collection %>
</div>
</div>
</li>
<% end %>
</ul>
<% end %>
<% end %>
</div>
</div>
<h1><%= t('activerecord.models.collection.pluralize') %></h1>
<%= paginate @collections %>
<%= render 'row_collections' %>
<%= paginate @collections %>
<%= content_for :action_links do %>
<% if current_user and current_user.has_role?("admin") %>
<%= link_to "New collection", new_collection_path %>
<% end %>
<% end %>

View File

@ -1,7 +1,8 @@
<h1>New collection</h1>
<%= form_for @collection do |f| %>
<%= form_for @collection, :html => {:class => 'form-horizontal'} do |f| %>
<legend><%= t('activerecord.actions.new', :model => I18n.t('activerecord.models.collection.one')) %></legend>
<%= f.error_messages %>
<%= render :partial => "form", :object => f %>
<%= f.submit "Create" %>
<div class="form-actions">
<%= f.button "Create", :class => 'btn btn-primary btn-large' %>
</div>
<% end %>

View File

@ -1,22 +1,12 @@
<h2><%= h @collection.title %></h2>
<p><%= h @collection.description %></p>
<h2><%= @collection.title %></h2>
<p><%= @collection.description %></p>
<% for album in @albums %>
<div class="row">
<div class="title">
<%= render :partial => "photos/thumb", :locals => {:photo => album.photos.first } unless album.photos.empty? %>
<p><%= link_to album.title, collection_album_path(@collection, album) %></p>
</div>
<div class="image">
<%= render :partial => "photos/thumb", :collection => album.photos.find(:all, :limit => 5, :offset => 1), :as => :photo %>
</div>
</div>
<% end %>
<%= render :partial => 'albums/row_collections' %>
<%= content_for :action_links do %>
<% if current_user and current_user.has_role?("admin") %>
<%= link_to "PDF", collection_path(@collection, :format => 'pdf') %> |&nbsp;
<%= link_to "Edit collection", edit_collection_path(@collection) %> |
<%= link_to "New album", new_collection_album_path(@collection) %>
<% end %>
<% if current_user and current_user.has_role?("admin") %>
<li><%= link_to "PDF", collection_path(@collection, :format => 'pdf') %></li>
<li><%= link_to "Edit collection", edit_collection_path(@collection) %></li>
<li><%= link_to "New album", new_collection_album_path(@collection) %></li>
<% end %>
<% end %>

View File

@ -0,0 +1,5 @@
<div class="row">
<%= render 'shared/home_slider' %>
</div>
<h2><%= t('activerecord.models.collection.popular') %></h2>
<%= render :partial => 'collections/row_collections' %>

View File

@ -0,0 +1,13 @@
<%# Link to the "First" page
- available local variables
url: url to the first page
current_page: a page object for the currently displayed page
num_pages: total number of pages
per_page: number of items to fetch per page
remote: data-remote
-%>
<% unless current_page.first? %>
<li class="first">
<%= link_to_unless current_page.first?, raw(t 'views.pagination.first'), url, :remote => remote %>
</li>
<% end %>

View File

@ -0,0 +1,8 @@
<%# Non-link tag that stands for skipped pages...
- available local variables
current_page: a page object for the currently displayed page
num_pages: total number of pages
per_page: number of items to fetch per page
remote: data-remote
-%>
<li class="page gap disabled"><a href="#" onclick="return false;"><%= raw(t 'views.pagination.truncate') %></a></li>

View File

@ -0,0 +1,13 @@
<%# Link to the "Last" page
- available local variables
url: url to the last page
current_page: a page object for the currently displayed page
num_pages: total number of pages
per_page: number of items to fetch per page
remote: data-remote
-%>
<% unless current_page.last? %>
<li class="last next"><%# "next" class present for border styling in twitter bootstrap %>
<%= link_to_unless current_page.last?, raw(t 'views.pagination.last'), url, {:remote => remote} %>
</li>
<% end %>

View File

@ -0,0 +1,13 @@
<%# Link to the "Next" page
- available local variables
url: url to the next page
current_page: a page object for the currently displayed page
num_pages: total number of pages
per_page: number of items to fetch per page
remote: data-remote
-%>
<% unless current_page.last? %>
<li class="next_page">
<%= link_to_unless current_page.last?, raw(t 'views.pagination.next'), url, :rel => 'next', :remote => remote %>
</li>
<% end %>

View File

@ -0,0 +1,12 @@
<%# Link showing page number
- available local variables
page: a page object for "this" page
url: url to this page
current_page: a page object for the currently displayed page
num_pages: total number of pages
per_page: number of items to fetch per page
remote: data-remote
-%>
<li class="page<%= ' active' if page.current? %>">
<%= link_to page, url, opts = {:remote => remote, :rel => page.next? ? 'next' : page.prev? ? 'prev' : nil} %>
</li>

View File

@ -0,0 +1,25 @@
<%# The container tag
- available local variables
current_page: a page object for the currently displayed page
num_pages: total number of pages
per_page: number of items to fetch per page
remote: data-remote
paginator: the paginator that renders the pagination tags inside
-%>
<%= paginator.render do -%>
<div class="pagination">
<ul>
<%= first_page_tag unless current_page.first? %>
<%= prev_page_tag unless current_page.first? %>
<% each_page do |page| -%>
<% if page.left_outer? || page.right_outer? || page.inside_window? -%>
<%= page_tag page %>
<% elsif !page.was_truncated? -%>
<%= gap_tag %>
<% end -%>
<% end -%>
<%= next_page_tag unless current_page.last? %>
<%= last_page_tag unless current_page.last? %>
</ul>
</div>
<% end -%>

View File

@ -0,0 +1,13 @@
<%# Link to the "Previous" page
- available local variables
url: url to the previous page
current_page: a page object for the currently displayed page
num_pages: total number of pages
per_page: number of items to fetch per page
remote: data-remote
-%>
<% unless current_page.first? %>
<li class="prev">
<%= link_to_unless current_page.first?, raw(t 'views.pagination.previous'), url, :rel => 'prev', :remote => remote %>
</li>
<% end %>

View File

@ -7,8 +7,9 @@
<%= render :partial => 'shared/nav_bar' %>
<div class="container">
<div class="row">
<div class="span12 notice"><%= flash[:notice] %></div>
<div class="span12">
<%= render :partial => 'shared/notifications' %>
<%= render_breadcrumbs %>
<%= yield %>
</div>
</div>

View File

@ -0,0 +1,22 @@
<div class="row">
<div class="span12">
<% @photos.in_groups_of(4).each do |group| %>
<% unless group.empty? %>
<ul class="thumbnails">
<% group.compact.each_with_index do |photo, index| %>
<li class="span3">
<div class="thumbnail">
<%= link_to image_tag(photo.attachment.thumb.url), photo.attachment.largest.url, :class => 'fancybox-thumb', :rel => "fancybox-thumb" %>
<div class="caption">
<h5 class="title"><%= photo.title %></h5>
<em class="descr"><%= photo.description %></em>
<%= ratings_for photo %>
</div>
</div>
</li>
<% end %>
</ul>
<% end %>
<% end %>
</div>
</div>

View File

@ -1 +1 @@
<%= link_to (image_tag eval('photo.attachment.' + (defined?(photosize) ? photosize : "album") + '.url')), [photo.album.collections.first, photo.album, photo] %>
<%= link_to image_tag(eval('photo.attachment.' + (defined?(photosize) ? photosize : "thumb") + '.url')), [photo.album.collections.first, photo.album, photo] %>

View File

@ -1,4 +1,7 @@
<ul><%= render :partial => 'photos/thumb', :collection => @photos, :as => :photo %></ul>
<%#= render :partial => 'photos/thumb', :collection => @photos, :as => :photo %>
<%= paginate @photos %>
<%= render :partial => 'photos/row_collections' %>
<%= paginate @photos %>
<%= content_for :action_links do %>
<%= link_to "Show albums containing photos tagged with #{params[:q]}", albums_path(:q => params[:q]) if params[:q] %>

View File

@ -10,8 +10,11 @@
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js" type="text/javascript"></script>
<![endif]-->
<%= yield :styles %>
<%= stylesheet_link_tag "application", :media => "all" %>
<%= javascript_include_tag "application" %>
<%= yield :head %>
<!-- For third-generation iPad with high-resolution Retina display: -->
<!-- Size should be 144 x 144 pixels -->
<%= favicon_link_tag 'images/apple-touch-icon-144x144-precomposed.png', :rel => 'apple-touch-icon-precomposed', :type => 'image/png', :sizes => '144x144' %>
@ -32,7 +35,6 @@
<!-- Size should be 32 x 32 pixels -->
<%= favicon_link_tag 'images/favicon.ico', :rel => 'shortcut icon' %>
<%= yield :head %>
<%= yield :javascript %>
<%= raw ajaxful_rating_style %>
<%= raw ajaxful_rating_script %>

View File

@ -1,11 +1,26 @@
<%= content_for :styles do %>
<%= stylesheet_link_tag "anythingslider/anythingslider" %>
<style type="text/css">
#home-slider {
height: 600px;
}
.slider-wrapper {
margin: 0 auto;
margin-bottom: 20px;
}
</style>
<% end %>
<%= content_for :head do %>
<%= stylesheet_link_tag "anythingslider/anythingslider", "anythingslider/theme-metallic", "anythingslider/animate" %>
<%#= stylesheet_link_tag "anythingslider/anythingslider", "anythingslider/theme-metallic", "anythingslider/animate" %>
<%= javascript_include_tag "anythingslider/jquery.anythingslider.min" %>
<script>
$(function () {
$('#home-slider').anythingSlider({
theme:'metallic',
// theme:'metallic',
// expand:true,
//resizeContents: false,
autoPlay:false
@ -14,18 +29,6 @@
});
</script>
<style type="text/css">
#home-slider {
height: 600px;
}
.slider-wrapper {
width: 100%;
margin: 0 auto;
margin-bottom: 20px;
}
</style>
<% end %>
<div class="span12 slider-wrapper">

View File

@ -6,15 +6,14 @@
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</a>
<a class="brand" href="#">Photomix</a>
<a class="brand" href="/">Photomix</a>
<div class="nav-collapse">
<ul class="nav">
<li class="active"><a href="#">Home</a></li>
<li><a href="#about">About</a></li>
<li><a href="#contact">Contact</a></li>
<li <%= "class='active'" if params['controller'].eql?("collections") %>><%= link_to pluralize(t('activerecord.models.collection.one'), 3, ["Коллекция", "Коллекции", "Коллекций"]), collections_path %></li>
<li <%= "class='active'" if params['controller'].eql?("albums") %>><%= link_to pluralize(t('activerecord.models.album'), 3, ["Альбом", "Альбомы", "Альбомов"]), albums_path %></li>
<li <%= "class='active'" if params['controller'].eql?("photos") %>><%= link_to pluralize(t('activerecord.models.photo'), 3, ["Фотография", "Фотографии", "Фотографий"]), photos_path %></li>
</ul>
<form action="" class="navbar-search pull-left">
<form action="" class="navbar-search pull-right">
<input type="text" placeholder="Search" class="search-query span2">
</form>
<%= render :partial => 'shared/user_links' %>

View File

@ -0,0 +1,13 @@
<% if flash[:alert] %>
<div class="alert alert-error">
<button class="close" data-dismiss="alert">×</button>
<strong><%= flash[:alert] %></strong>
</div>
<% end %>
<% if flash[:notice] %>
<div class="alert alert-success">
<button class="close" data-dismiss="alert">×</button>
<strong><%= flash[:notice] %></strong>
</div>
<% end %>

View File

@ -1,14 +1,19 @@
<% if current_user %>
<ul class="nav pull-right">
<li><%= link_to current_user.email, account_path %></li>
<li class="divider-vertical"></li>
<ul class="nav pull-left">
<li class="dropdown">
<a data-toggle="dropdown" class="dropdown-toggle" href="#">Actions <b class="caret"></b></a>
<a data-toggle="dropdown" class="dropdown-toggle" href="#"><%= t(:actions) %> <b class="caret"></b></a>
<ul class="dropdown-menu">
<li><%= link_to current_user.email, account_path %></li>
<li><%= link_to 'Logout', logout_path %></li>
<li class="divider"></li>
<li><%= link_to "New collection", new_collection_path %></li>
<li><%= link_to t("activerecord.actions.create", :model => I18n.t('activerecord.models.collection.single')), new_collection_path %></li>
<%= yield :action_links %>
</ul>
</li>
</ul>
<% else %>
<ul class="nav pull-right">
<li><%= link_to t(:login), login_path %></li>
<%= yield :action_links %>
</ul>
<% end %>

View File

@ -10,7 +10,7 @@ module Photomix
class Application < Rails::Application
# Custom directories with classes and modules you want to be autoloadable.
# config.autoload_paths += %W(#{config.root}/
# config.autoload_paths += %W(#{config.root}/ Dir["#{config.root}/lib/**/"]
config.autoload_paths += %W(#{config.root}/lib #{config.root}/app/middleware/)
config.active_record.observers = :secret_link_observer
config.encoding = "utf-8"

View File

@ -0,0 +1,9 @@
Kaminari.configure do |config|
config.default_per_page = 20
# config.window = 4
# config.outer_window = 0
# config.left = 0
# config.right = 0
# config.page_method_name = :page
# config.param_name = :page
end

View File

@ -1,5 +1,28 @@
# Sample localization file for English. Add more files in this directory for other locales.
# See http://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points.
en:
hello: "Hello world"
home_page: home
activerecord:
models:
user: user
collection:
one: "collection"
many: "collections"
other: "collections"
single: "collection"
popular: Popular Collections
album: Album
photo: Photo
photo_tag: Tag
actions:
create: "Create %{model}"
update: "Update %{model}"
destroy: "Destroy %{model}"
albums_counter:
one: "%{count} album"
many: "%{count} albums"
other: "%{count} album"
photos_counter:
one: "%{count} photo"
many: "%{count} photos"
other: "%{count} photos"

40
config/locales/ru.yml Normal file
View File

@ -0,0 +1,40 @@
ru:
home_page: "Главная"
views:
pagination:
first: "&laquo; первая"
last: "последняя &raquo;"
previous: "<<"
next: ">>"
truncate: "..."
activerecord:
models:
user: Пользователь
collection:
one: "коллекция"
few: "коллекции"
many: "коллекций"
other: "коллекции"
single: "коллекцию"
popular: Полулярные коллекции
album: Альбом
photo: Фотография
photo_tag: Тег
actions:
new: "Новая %{model}"
create: "Создать %{model}"
update: "Обновить %{model}"
destroy: "Удалить %{model}"
albums_counter:
one: "Содержит %{count} альбом"
few: "Содержит %{count} альбома"
many: "Содержит %{count} альбомов"
other: "Содержит %{count} альбомы"
photos_counter:
one: "Содержит %{count} фото"
few: "Содержит %{count} фото"
many: "Содержит %{count} фото"
other: "Содержит %{count} фото"

View File

@ -78,6 +78,6 @@ Photomix::Application.routes.draw do
match '/locale' => "locale#set"
root :to => "collections#index"
root :to => "home#index"
end

View File

@ -12,15 +12,16 @@ user = User.make! email: 'test@example.com', password: 'password', password_conf
confirmation_sent_at: (Time.now+3)
user.roles << Role.make!(name: 'admin')
user.save!
20.times.map { User.make! }
20.times.map { Collection.make! }
20.times.map { Album.make! }
20.times.map { Photo.make! }
10.times.map { CollectionAlbum.make! }
60.times.map { Collection.make! }
60.times.map { Album.make! }
60.times.map { Photo.make! }
30.times.map { CollectionAlbum.make! }
20.times.map{ Rate.make!(:collections) }
20.times.map{ Rate.make!(:albums) }
20.times.map{ Rate.make!(:photos) }
30.times.map{ Rate.make!(:collections) }
30.times.map{ Rate.make!(:albums) }
30.times.map{ Rate.make!(:photos) }
FileUtils.rm_rf "#{Rails.root}/tmp/attachments"

View File

@ -50,14 +50,14 @@ Collection.blueprint {
}
CollectionAlbum.blueprint {
album { Album.find(rand(1..20)) }
collection { Collection.find(rand(1..20)) }
album { Album.find(rand(1..60)) }
collection { Collection.find(rand(1..60)) }
}
Photo.blueprint {
title { Faker::Lorem.sentence(rand(3)) }
description { Faker::Lorem.sentence }
album { Album.find(rand(1..20)) }
album { Album.find(rand(1..60)) }
rating_average { rand(1..5) }
public { true }
attachment {
@ -75,19 +75,19 @@ Photo.blueprint {
}
Rate.blueprint(:collections) {
rateable { Collection.find(rand(1..20)) }
rateable { Collection.find(rand(1..60)) }
rater { User.find(rand(1..20)) }
stars { rand(1..5) }
}
Rate.blueprint(:albums) {
rateable { Album.find(rand(1..20)) }
rateable { Album.find(rand(1..60)) }
rater { User.find(rand(1..20)) }
stars { rand(1..5) }
}
Rate.blueprint(:photos) {
rateable { Photo.find(rand(1..20)) }
rateable { Photo.find(rand(1..60)) }
rater { User.find(rand(1..20)) }
stars { rand(1..5) }
}

View File

@ -0,0 +1,7 @@
require 'test_helper'
class HomeControllerTest < ActionController::TestCase
# test "the truth" do
# assert true
# end
end

View File

@ -0,0 +1,4 @@
require 'test_helper'
class HomeHelperTest < ActionView::TestCase
end

View File

@ -0,0 +1,84 @@
/*! Copyright (c) 2011 Brandon Aaron (http://brandonaaron.net)
* Licensed under the MIT License (LICENSE.txt).
*
* Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers.
* Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix.
* Thanks to: Seamus Leahy for adding deltaX and deltaY
*
* Version: 3.0.6
*
* Requires: 1.2.2+
*/
(function($) {
var types = ['DOMMouseScroll', 'mousewheel'];
if ($.event.fixHooks) {
for ( var i=types.length; i; ) {
$.event.fixHooks[ types[--i] ] = $.event.mouseHooks;
}
}
$.event.special.mousewheel = {
setup: function() {
if ( this.addEventListener ) {
for ( var i=types.length; i; ) {
this.addEventListener( types[--i], handler, false );
}
} else {
this.onmousewheel = handler;
}
},
teardown: function() {
if ( this.removeEventListener ) {
for ( var i=types.length; i; ) {
this.removeEventListener( types[--i], handler, false );
}
} else {
this.onmousewheel = null;
}
}
};
$.fn.extend({
mousewheel: function(fn) {
return fn ? this.bind("mousewheel", fn) : this.trigger("mousewheel");
},
unmousewheel: function(fn) {
return this.unbind("mousewheel", fn);
}
});
function handler(event) {
var orgEvent = event || window.event, args = [].slice.call( arguments, 1 ), delta = 0, returnValue = true, deltaX = 0, deltaY = 0;
event = $.event.fix(orgEvent);
event.type = "mousewheel";
// Old school scrollwheel delta
if ( orgEvent.wheelDelta ) { delta = orgEvent.wheelDelta/120; }
if ( orgEvent.detail ) { delta = -orgEvent.detail/3; }
// New school multidimensional scroll (touchpads) deltas
deltaY = delta;
// Gecko
if ( orgEvent.axis !== undefined && orgEvent.axis === orgEvent.HORIZONTAL_AXIS ) {
deltaY = 0;
deltaX = -1*delta;
}
// Webkit
if ( orgEvent.wheelDeltaY !== undefined ) { deltaY = orgEvent.wheelDeltaY/120; }
if ( orgEvent.wheelDeltaX !== undefined ) { deltaX = -1*orgEvent.wheelDeltaX/120; }
// Add event and delta to the front of the arguments
args.unshift(event, delta, deltaX, deltaY);
return ($.event.dispatch || $.event.handle).apply(this, args);
}
})(jQuery);