Compare commits
31 commits
Author | SHA1 | Date | |
---|---|---|---|
fe63f11068 | |||
309adafd48 | |||
0af713b765 | |||
b05879afdc | |||
c526882f27 | |||
ef55c642d0 | |||
b185c08481 | |||
68cd47abba | |||
5f5b2eca86 | |||
a7722cf8d5 | |||
bf80a200f0 | |||
5c131394aa | |||
2469225cda | |||
7caba3f464 | |||
2042f17a3d | |||
7e9754714a | |||
954e3b68ae | |||
0ab5ab468f | |||
b1ad108123 | |||
e59d11e1c9 | |||
ac9a8886de | |||
d996de1514 | |||
aedc18f834 | |||
0b7628dc95 | |||
3ae36b6689 | |||
b8a14725ee | |||
9c0ef432d0 | |||
1a2cbff99e | |||
25c8c3b5cb | |||
bd431ab2e3 | |||
0ed49f3021 |
3
.gitignore
vendored
|
@ -13,4 +13,7 @@ config/deploy
|
||||||
Capfile
|
Capfile
|
||||||
public/thumbs
|
public/thumbs
|
||||||
public/uploads
|
public/uploads
|
||||||
|
public/assets
|
||||||
vendor/cache
|
vendor/cache
|
||||||
|
.idea
|
||||||
|
.sass-cache
|
51
Gemfile
|
@ -1,23 +1,46 @@
|
||||||
source 'http://rubygems.org'
|
source 'http://rubygems.org'
|
||||||
|
|
||||||
gem 'rails', '3.2.3'
|
gem 'rails', '3.2.7'
|
||||||
|
gem 'sqlite3'
|
||||||
gem 'authlogic'
|
|
||||||
|
|
||||||
gem 'mime-types', :require => 'mime/types'
|
gem 'mime-types', :require => 'mime/types'
|
||||||
gem 'carrierwave'
|
gem 'carrierwave'
|
||||||
|
gem 'dynamic_form'
|
||||||
|
gem 'kaminari', :git => 'git://github.com/amatsuda/kaminari.git'
|
||||||
|
gem 'princely'
|
||||||
|
gem 'unicorn'
|
||||||
|
gem 'jquery-rails'
|
||||||
|
gem 'jquery-ui-rails'
|
||||||
|
gem 'twitter-bootstrap-rails', :git => 'git://github.com/seyhunak/twitter-bootstrap-rails.git'
|
||||||
|
gem 'ajaxful_rating_jquery', :git => 'git://github.com/greendog/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 'breadcrumbs_on_rails', :git => 'git://github.com/lloydk/breadcrumbs_on_rails.git'
|
||||||
|
gem 'russian', :git => 'git://github.com/yaroslav/russian.git'
|
||||||
|
|
||||||
# -- Heroku
|
gem "devise_omniauth_engine", :git=>"git://github.com/greendog/devise_omniauth_engine.git"
|
||||||
#gem 'heroku'
|
gem 'omniauth-twitter'
|
||||||
#gem 'pg'
|
gem 'omniauth-facebook'
|
||||||
|
gem 'omniauth-openid'
|
||||||
|
gem 'omniauth-google-apps'
|
||||||
|
gem 'omniauth-vkontakte', :git => 'git://github.com/mamantoha/omniauth-vkontakte.git'
|
||||||
|
gem 'cancan'
|
||||||
|
|
||||||
# -- Database
|
group :assets do
|
||||||
# SQLite:
|
gem 'sass-rails'
|
||||||
#gem 'sqlite3-ruby'
|
gem 'coffee-rails'
|
||||||
# MySQL:
|
gem 'uglifier'
|
||||||
#gem 'mysql2'
|
end
|
||||||
# PostgreSQL:
|
|
||||||
gem 'pg'
|
group :development do
|
||||||
|
gem 'ffaker'
|
||||||
|
gem 'machinist'
|
||||||
|
gem 'action_mailer_tls', :git => 'git://github.com/openrain/action_mailer_tls.git'
|
||||||
|
gem 'capistrano', :git => 'git://github.com/capistrano/capistrano.git'
|
||||||
|
gem 'capistrano-unicorn', :git => 'git://github.com/sosedoff/capistrano-unicorn.git'
|
||||||
|
gem 'rvm-capistrano'
|
||||||
|
gem 'capistrano_colors'
|
||||||
|
end
|
||||||
|
|
||||||
# -- Cloud storage
|
# -- Cloud storage
|
||||||
# AWS S3 support. Can be disabled if using local file system instead of cloud storage.
|
# AWS S3 support. Can be disabled if using local file system instead of cloud storage.
|
||||||
|
|
321
Gemfile.lock
|
@ -1,46 +1,158 @@
|
||||||
|
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/bryanmig/plupload-rails.git
|
||||||
|
revision: 6d07d0f7e05d0b3fdc9b03b49d3a7c3aa1cd703b
|
||||||
|
specs:
|
||||||
|
plupload-rails (1.0.6)
|
||||||
|
rails (~> 3.1)
|
||||||
|
|
||||||
|
GIT
|
||||||
|
remote: git://github.com/capistrano/capistrano.git
|
||||||
|
revision: 62a6cb723dc583468943fc642847791fb4ad2686
|
||||||
|
specs:
|
||||||
|
capistrano (2.12.0)
|
||||||
|
highline
|
||||||
|
net-scp (>= 1.0.0)
|
||||||
|
net-sftp (>= 2.0.0)
|
||||||
|
net-ssh (>= 2.0.14)
|
||||||
|
net-ssh-gateway (>= 1.1.0)
|
||||||
|
|
||||||
|
GIT
|
||||||
|
remote: git://github.com/greendog/ajaxful_rating_jquery.git
|
||||||
|
revision: ae3314d3067d9f13a62675fa08afa4ecd31a7828
|
||||||
|
specs:
|
||||||
|
ajaxful_rating_jquery (3.0.0.beta3)
|
||||||
|
|
||||||
|
GIT
|
||||||
|
remote: git://github.com/greendog/devise_omniauth_engine.git
|
||||||
|
revision: c46d449222133f709b5f0cafc31a57f1ae208f06
|
||||||
|
specs:
|
||||||
|
devise_omniauth_engine (1.0.0)
|
||||||
|
devise
|
||||||
|
omniauth
|
||||||
|
yettings
|
||||||
|
|
||||||
|
GIT
|
||||||
|
remote: git://github.com/lloydk/breadcrumbs_on_rails.git
|
||||||
|
revision: 310c40186b97dc816e22e9be7aac3b43dcef040b
|
||||||
|
specs:
|
||||||
|
breadcrumbs_on_rails (2.2.0)
|
||||||
|
|
||||||
|
GIT
|
||||||
|
remote: git://github.com/mamantoha/omniauth-vkontakte.git
|
||||||
|
revision: b2b9f62972911ba328538368d13407b01bc9f297
|
||||||
|
specs:
|
||||||
|
omniauth-vkontakte (1.0.9)
|
||||||
|
multi_json
|
||||||
|
omniauth (~> 1.1.0)
|
||||||
|
omniauth-oauth2 (~> 1.0)
|
||||||
|
|
||||||
|
GIT
|
||||||
|
remote: git://github.com/markbates/configatron.git
|
||||||
|
revision: 7a81defa5e1fb032b5ed62754d7e6d7bfecf07a2
|
||||||
|
specs:
|
||||||
|
configatron (2.9.1)
|
||||||
|
yamler (>= 0.1.0)
|
||||||
|
|
||||||
|
GIT
|
||||||
|
remote: git://github.com/openrain/action_mailer_tls.git
|
||||||
|
revision: 4c4db7e098d54b2239c1ce7c195417552718418c
|
||||||
|
specs:
|
||||||
|
action_mailer_tls (1.1.3)
|
||||||
|
|
||||||
|
GIT
|
||||||
|
remote: git://github.com/seyhunak/twitter-bootstrap-rails.git
|
||||||
|
revision: 908e150800610138e2b48738f842afb85b3a832e
|
||||||
|
specs:
|
||||||
|
twitter-bootstrap-rails (2.1.1)
|
||||||
|
actionpack (>= 3.1)
|
||||||
|
less-rails (~> 2.2.3)
|
||||||
|
railties (>= 3.1)
|
||||||
|
therubyracer (= 0.10.1)
|
||||||
|
|
||||||
|
GIT
|
||||||
|
remote: git://github.com/sosedoff/capistrano-unicorn.git
|
||||||
|
revision: bafc12cd8235307d30b5c85259914d17c5ece2d3
|
||||||
|
specs:
|
||||||
|
capistrano-unicorn (0.1.6)
|
||||||
|
capistrano
|
||||||
|
|
||||||
|
GIT
|
||||||
|
remote: git://github.com/yaroslav/russian.git
|
||||||
|
revision: e2dde13672bcee176f8b0be364a55ac256913231
|
||||||
|
specs:
|
||||||
|
russian (0.6.0)
|
||||||
|
i18n (>= 0.5.0)
|
||||||
|
|
||||||
GEM
|
GEM
|
||||||
remote: http://rubygems.org/
|
remote: http://rubygems.org/
|
||||||
specs:
|
specs:
|
||||||
actionmailer (3.2.3)
|
actionmailer (3.2.7)
|
||||||
actionpack (= 3.2.3)
|
actionpack (= 3.2.7)
|
||||||
mail (~> 2.4.4)
|
mail (~> 2.4.4)
|
||||||
actionpack (3.2.3)
|
actionpack (3.2.7)
|
||||||
activemodel (= 3.2.3)
|
activemodel (= 3.2.7)
|
||||||
activesupport (= 3.2.3)
|
activesupport (= 3.2.7)
|
||||||
builder (~> 3.0.0)
|
builder (~> 3.0.0)
|
||||||
erubis (~> 2.7.0)
|
erubis (~> 2.7.0)
|
||||||
journey (~> 1.0.1)
|
journey (~> 1.0.4)
|
||||||
rack (~> 1.4.0)
|
rack (~> 1.4.0)
|
||||||
rack-cache (~> 1.2)
|
rack-cache (~> 1.2)
|
||||||
rack-test (~> 0.6.1)
|
rack-test (~> 0.6.1)
|
||||||
sprockets (~> 2.1.2)
|
sprockets (~> 2.1.3)
|
||||||
activemodel (3.2.3)
|
activemodel (3.2.7)
|
||||||
activesupport (= 3.2.3)
|
activesupport (= 3.2.7)
|
||||||
builder (~> 3.0.0)
|
builder (~> 3.0.0)
|
||||||
activerecord (3.2.3)
|
activerecord (3.2.7)
|
||||||
activemodel (= 3.2.3)
|
activemodel (= 3.2.7)
|
||||||
activesupport (= 3.2.3)
|
activesupport (= 3.2.7)
|
||||||
arel (~> 3.0.2)
|
arel (~> 3.0.2)
|
||||||
tzinfo (~> 0.3.29)
|
tzinfo (~> 0.3.29)
|
||||||
activeresource (3.2.3)
|
activeresource (3.2.7)
|
||||||
activemodel (= 3.2.3)
|
activemodel (= 3.2.7)
|
||||||
activesupport (= 3.2.3)
|
activesupport (= 3.2.7)
|
||||||
activesupport (3.2.3)
|
activesupport (3.2.7)
|
||||||
i18n (~> 0.6)
|
i18n (~> 0.6)
|
||||||
multi_json (~> 1.0)
|
multi_json (~> 1.0)
|
||||||
arel (3.0.2)
|
arel (3.0.2)
|
||||||
authlogic (3.1.0)
|
bcrypt-ruby (3.0.1)
|
||||||
activerecord (>= 3.0.7)
|
|
||||||
activerecord (>= 3.0.7)
|
|
||||||
builder (3.0.0)
|
builder (3.0.0)
|
||||||
carrierwave (0.6.1)
|
cancan (1.6.8)
|
||||||
|
capistrano_colors (0.5.5)
|
||||||
|
carrierwave (0.6.2)
|
||||||
activemodel (>= 3.2.0)
|
activemodel (>= 3.2.0)
|
||||||
activesupport (>= 3.2.0)
|
activesupport (>= 3.2.0)
|
||||||
|
coffee-rails (3.2.2)
|
||||||
|
coffee-script (>= 2.2.0)
|
||||||
|
railties (~> 3.2.0)
|
||||||
|
coffee-script (2.2.0)
|
||||||
|
coffee-script-source
|
||||||
|
execjs
|
||||||
|
coffee-script-source (1.3.3)
|
||||||
|
commonjs (0.2.6)
|
||||||
|
devise (2.1.2)
|
||||||
|
bcrypt-ruby (~> 3.0)
|
||||||
|
orm_adapter (~> 0.1)
|
||||||
|
railties (~> 3.1)
|
||||||
|
warden (~> 1.2.1)
|
||||||
|
dynamic_form (1.1.4)
|
||||||
erubis (2.7.0)
|
erubis (2.7.0)
|
||||||
excon (0.13.2)
|
excon (0.15.5)
|
||||||
fog (1.3.1)
|
execjs (1.4.0)
|
||||||
|
multi_json (~> 1.0)
|
||||||
|
faraday (0.8.1)
|
||||||
|
multipart-post (~> 1.1)
|
||||||
|
ffaker (1.15.0)
|
||||||
|
fog (1.5.0)
|
||||||
builder
|
builder
|
||||||
excon (~> 0.13.0)
|
excon (~> 0.14)
|
||||||
formatador (~> 0.2.0)
|
formatador (~> 0.2.0)
|
||||||
mime-types
|
mime-types
|
||||||
multi_json (~> 1.0)
|
multi_json (~> 1.0)
|
||||||
|
@ -48,73 +160,182 @@ GEM
|
||||||
net-ssh (>= 2.1.3)
|
net-ssh (>= 2.1.3)
|
||||||
nokogiri (~> 1.5.0)
|
nokogiri (~> 1.5.0)
|
||||||
ruby-hmac
|
ruby-hmac
|
||||||
formatador (0.2.1)
|
formatador (0.2.3)
|
||||||
|
hashie (1.2.0)
|
||||||
|
highline (1.6.13)
|
||||||
hike (1.2.1)
|
hike (1.2.1)
|
||||||
|
httpauth (0.1)
|
||||||
i18n (0.6.0)
|
i18n (0.6.0)
|
||||||
journey (1.0.3)
|
journey (1.0.4)
|
||||||
json (1.6.6)
|
jquery-rails (2.0.2)
|
||||||
|
railties (>= 3.2.0, < 5.0)
|
||||||
|
thor (~> 0.14)
|
||||||
|
jquery-ui-rails (1.1.0)
|
||||||
|
jquery-rails
|
||||||
|
railties (>= 3.1.0)
|
||||||
|
json (1.7.4)
|
||||||
|
jwt (0.1.5)
|
||||||
|
multi_json (>= 1.0)
|
||||||
|
kgio (2.7.4)
|
||||||
|
less (2.2.1)
|
||||||
|
commonjs (~> 0.2.6)
|
||||||
|
less-rails (2.2.3)
|
||||||
|
actionpack (>= 3.1)
|
||||||
|
less (~> 2.2.0)
|
||||||
|
libv8 (3.3.10.4)
|
||||||
|
machinist (2.0)
|
||||||
mail (2.4.4)
|
mail (2.4.4)
|
||||||
i18n (>= 0.4.0)
|
i18n (>= 0.4.0)
|
||||||
mime-types (~> 1.16)
|
mime-types (~> 1.16)
|
||||||
treetop (~> 1.4.8)
|
treetop (~> 1.4.8)
|
||||||
mime-types (1.18)
|
mime-types (1.19)
|
||||||
mini_exiftool (1.3.1)
|
mini_exiftool (1.6.0)
|
||||||
mini_magick (3.4)
|
mini_magick (3.4)
|
||||||
subexec (~> 0.2.1)
|
subexec (~> 0.2.1)
|
||||||
multi_json (1.2.0)
|
multi_json (1.3.6)
|
||||||
|
multipart-post (1.1.5)
|
||||||
net-scp (1.0.4)
|
net-scp (1.0.4)
|
||||||
net-ssh (>= 1.99.1)
|
net-ssh (>= 1.99.1)
|
||||||
net-ssh (2.3.0)
|
net-sftp (2.0.5)
|
||||||
nokogiri (1.5.2)
|
net-ssh (>= 2.0.9)
|
||||||
pg (0.13.2)
|
net-ssh (2.5.2)
|
||||||
|
net-ssh-gateway (1.1.0)
|
||||||
|
net-ssh (>= 1.99.1)
|
||||||
|
nokogiri (1.5.5)
|
||||||
|
oauth (0.4.6)
|
||||||
|
oauth2 (0.8.0)
|
||||||
|
faraday (~> 0.8)
|
||||||
|
httpauth (~> 0.1)
|
||||||
|
jwt (~> 0.1.4)
|
||||||
|
multi_json (~> 1.0)
|
||||||
|
rack (~> 1.2)
|
||||||
|
omniauth (1.1.0)
|
||||||
|
hashie (~> 1.2)
|
||||||
|
rack
|
||||||
|
omniauth-facebook (1.4.1)
|
||||||
|
omniauth-oauth2 (~> 1.1.0)
|
||||||
|
omniauth-google-apps (0.0.2)
|
||||||
|
omniauth (~> 1.0)
|
||||||
|
omniauth-openid (~> 1.0)
|
||||||
|
ruby-openid-apps-discovery (~> 1.2.0)
|
||||||
|
omniauth-oauth (1.0.1)
|
||||||
|
oauth
|
||||||
|
omniauth (~> 1.0)
|
||||||
|
omniauth-oauth2 (1.1.0)
|
||||||
|
oauth2 (~> 0.8.0)
|
||||||
|
omniauth (~> 1.0)
|
||||||
|
omniauth-openid (1.0.1)
|
||||||
|
omniauth (~> 1.0)
|
||||||
|
rack-openid (~> 1.3.1)
|
||||||
|
omniauth-twitter (0.0.12)
|
||||||
|
multi_json (~> 1.3)
|
||||||
|
omniauth-oauth (~> 1.0)
|
||||||
|
orm_adapter (0.4.0)
|
||||||
polyglot (0.3.3)
|
polyglot (0.3.3)
|
||||||
|
princely (1.2.5)
|
||||||
rack (1.4.1)
|
rack (1.4.1)
|
||||||
rack-cache (1.2)
|
rack-cache (1.2)
|
||||||
rack (>= 0.4)
|
rack (>= 0.4)
|
||||||
|
rack-openid (1.3.1)
|
||||||
|
rack (>= 1.1.0)
|
||||||
|
ruby-openid (>= 2.1.8)
|
||||||
rack-ssl (1.3.2)
|
rack-ssl (1.3.2)
|
||||||
rack
|
rack
|
||||||
rack-test (0.6.1)
|
rack-test (0.6.1)
|
||||||
rack (>= 1.0)
|
rack (>= 1.0)
|
||||||
rails (3.2.3)
|
rails (3.2.7)
|
||||||
actionmailer (= 3.2.3)
|
actionmailer (= 3.2.7)
|
||||||
actionpack (= 3.2.3)
|
actionpack (= 3.2.7)
|
||||||
activerecord (= 3.2.3)
|
activerecord (= 3.2.7)
|
||||||
activeresource (= 3.2.3)
|
activeresource (= 3.2.7)
|
||||||
activesupport (= 3.2.3)
|
activesupport (= 3.2.7)
|
||||||
bundler (~> 1.0)
|
bundler (~> 1.0)
|
||||||
railties (= 3.2.3)
|
railties (= 3.2.7)
|
||||||
railties (3.2.3)
|
railties (3.2.7)
|
||||||
actionpack (= 3.2.3)
|
actionpack (= 3.2.7)
|
||||||
activesupport (= 3.2.3)
|
activesupport (= 3.2.7)
|
||||||
rack-ssl (~> 1.3.2)
|
rack-ssl (~> 1.3.2)
|
||||||
rake (>= 0.8.7)
|
rake (>= 0.8.7)
|
||||||
rdoc (~> 3.4)
|
rdoc (~> 3.4)
|
||||||
thor (~> 0.14.6)
|
thor (>= 0.14.6, < 2.0)
|
||||||
|
raindrops (0.10.0)
|
||||||
rake (0.9.2.2)
|
rake (0.9.2.2)
|
||||||
rdoc (3.12)
|
rdoc (3.12)
|
||||||
json (~> 1.4)
|
json (~> 1.4)
|
||||||
ruby-hmac (0.4.0)
|
ruby-hmac (0.4.0)
|
||||||
sprockets (2.1.2)
|
ruby-openid (2.2.0)
|
||||||
|
ruby-openid-apps-discovery (1.2.0)
|
||||||
|
ruby-openid (>= 2.1.7)
|
||||||
|
rvm-capistrano (1.2.5)
|
||||||
|
capistrano (>= 2.0.0)
|
||||||
|
sass (3.1.20)
|
||||||
|
sass-rails (3.2.5)
|
||||||
|
railties (~> 3.2.0)
|
||||||
|
sass (>= 3.1.10)
|
||||||
|
tilt (~> 1.3)
|
||||||
|
sprockets (2.1.3)
|
||||||
hike (~> 1.2)
|
hike (~> 1.2)
|
||||||
rack (~> 1.0)
|
rack (~> 1.0)
|
||||||
tilt (~> 1.1, != 1.3.0)
|
tilt (~> 1.1, != 1.3.0)
|
||||||
subexec (0.2.1)
|
sqlite3 (1.3.6)
|
||||||
thor (0.14.6)
|
subexec (0.2.2)
|
||||||
|
therubyracer (0.10.1)
|
||||||
|
libv8 (~> 3.3.10)
|
||||||
|
thor (0.15.4)
|
||||||
tilt (1.3.3)
|
tilt (1.3.3)
|
||||||
treetop (1.4.10)
|
treetop (1.4.10)
|
||||||
polyglot
|
polyglot
|
||||||
polyglot (>= 0.3.1)
|
polyglot (>= 0.3.1)
|
||||||
tzinfo (0.3.32)
|
tzinfo (0.3.33)
|
||||||
|
uglifier (1.2.7)
|
||||||
|
execjs (>= 0.3.0)
|
||||||
|
multi_json (~> 1.3)
|
||||||
|
unicorn (4.3.1)
|
||||||
|
kgio (~> 2.6)
|
||||||
|
rack
|
||||||
|
raindrops (~> 0.7)
|
||||||
|
warden (1.2.1)
|
||||||
|
rack (>= 1.0)
|
||||||
|
yamler (0.1.0)
|
||||||
|
yettings (0.1.1)
|
||||||
|
|
||||||
PLATFORMS
|
PLATFORMS
|
||||||
ruby
|
ruby
|
||||||
|
|
||||||
DEPENDENCIES
|
DEPENDENCIES
|
||||||
authlogic
|
action_mailer_tls!
|
||||||
|
ajaxful_rating_jquery!
|
||||||
|
breadcrumbs_on_rails!
|
||||||
|
cancan
|
||||||
|
capistrano!
|
||||||
|
capistrano-unicorn!
|
||||||
|
capistrano_colors
|
||||||
carrierwave
|
carrierwave
|
||||||
|
coffee-rails
|
||||||
|
configatron!
|
||||||
|
devise_omniauth_engine!
|
||||||
|
dynamic_form
|
||||||
|
ffaker
|
||||||
fog
|
fog
|
||||||
|
jquery-rails
|
||||||
|
jquery-ui-rails
|
||||||
|
kaminari!
|
||||||
|
machinist
|
||||||
mime-types
|
mime-types
|
||||||
mini_exiftool
|
mini_exiftool
|
||||||
mini_magick
|
mini_magick
|
||||||
pg
|
omniauth-facebook
|
||||||
rails (= 3.2.3)
|
omniauth-google-apps
|
||||||
|
omniauth-openid
|
||||||
|
omniauth-twitter
|
||||||
|
omniauth-vkontakte!
|
||||||
|
plupload-rails!
|
||||||
|
princely
|
||||||
|
rails (= 3.2.7)
|
||||||
|
russian!
|
||||||
|
rvm-capistrano
|
||||||
|
sass-rails
|
||||||
|
sqlite3
|
||||||
|
twitter-bootstrap-rails!
|
||||||
|
uglifier
|
||||||
|
unicorn
|
||||||
|
|
109
README
|
@ -1,109 +0,0 @@
|
||||||
== Welcome to Balder photo gallery
|
|
||||||
|
|
||||||
Made by Espen Antonsen.
|
|
||||||
|
|
||||||
Version 1.2.2 for Rails 3.1. See the rails2 branch for previous version.
|
|
||||||
|
|
||||||
http://balderapp.com
|
|
||||||
|
|
||||||
== Features
|
|
||||||
|
|
||||||
* Stores photos to disk in folders or on S3 (can run from Heroku...yay)
|
|
||||||
* Create multiple thumbnails of custom sizes
|
|
||||||
* Read and writes EXIF/IPTC title, description and keywords
|
|
||||||
* Organize in albums (as events in iPhoto)
|
|
||||||
* Combine albums in collections (as albums in iPhoto)
|
|
||||||
* Upload multiple photos
|
|
||||||
* Tag photos. Can also tag albums (actually all photos in album is tagged)
|
|
||||||
* User management with roles and permissions
|
|
||||||
* Geo-location of albums & photos with Google Maps integration.
|
|
||||||
|
|
||||||
== Requirements
|
|
||||||
|
|
||||||
Rails 3.1
|
|
||||||
|
|
||||||
Software
|
|
||||||
Default:
|
|
||||||
- ExifTool (required for Mini_EfixTool). Can be disabled. Default is to read EXIF tags but not write them to the file when database is updated as writing EXIF is slow. To enable just uncomment exif_write in photo.rb
|
|
||||||
Can be installed from: http://www.sno.phy.queensu.ca/~phil/exiftool/
|
|
||||||
- ImageMagicK. Carrierwave can use either RMagicK or MiniMagicK (default). To change resize option the correct gem must be used (specified in Gemfile) and change included setting for Carrierwave in file_uploader.rb
|
|
||||||
Can be installed from: http://www.imagemagick.org
|
|
||||||
Optional:
|
|
||||||
- ImageScience which requires FreeImage. Can be installed from: http://sourceforge.net/projects/freeimage/
|
|
||||||
|
|
||||||
Ruby Gems: See Gemfile
|
|
||||||
|
|
||||||
== Configuration
|
|
||||||
|
|
||||||
config/balder.rb has the following adjustable settings:
|
|
||||||
|
|
||||||
STORAGE_PATH Relative path to where the photos are stored. Default: uploads
|
|
||||||
Under the specified path two folders are used. "files" for original files and "thumbs" for generated thumbnails.
|
|
||||||
This can be adjusted in app/uploaders/file_uploader.rb
|
|
||||||
PRIVATE Require visitors to have a user and authenticate before viewing photos.
|
|
||||||
TITLE Title of site
|
|
||||||
HEROKU To be used on heroku.com. This will adjust carrierwave to save to Heroku's tmp area.
|
|
||||||
S3_KEY For saving files to Amazon S3 (required for Heroku)
|
|
||||||
S3_SECRET For saving files to Amazon S3 (required for Heroku)
|
|
||||||
S3_BUCKET For saving files to Amazon S3 (required for Heroku)
|
|
||||||
|
|
||||||
As these are environment variables you can easily add them to Heroku:
|
|
||||||
http://devcenter.heroku.com/articles/config-vars#rack_env_rails_env_merb_env
|
|
||||||
For a brief introduction to how to set up Balder on Heroku see:
|
|
||||||
http://blog.inspired.no/rails-photo-gallery-balder-on-heroku-and-s3-726
|
|
||||||
|
|
||||||
== Installation
|
|
||||||
|
|
||||||
1. Clone the project from GitHub or Gitorious:
|
|
||||||
GitHub: git clone git://github.com/espen/balder.git
|
|
||||||
2. Install required software listed above
|
|
||||||
3. 'bundle install' to install required gems.
|
|
||||||
4. Adjust the settings in balder.rb or as Heroku config variables (See configuration above)
|
|
||||||
5. Copy database file (not needed when hosting on Heroku):
|
|
||||||
cp config/database.example.yml config/database.yml
|
|
||||||
6. Create database user and edit database file. (unless on Heroku or using SQLite3)
|
|
||||||
7. rake db:create
|
|
||||||
8. rake db:migrate
|
|
||||||
9. Start up the project with your preferred web-server
|
|
||||||
|
|
||||||
=== Optional: add photos directly to disk
|
|
||||||
|
|
||||||
The gallery has a web-based upload tool. Alternatively you can upload files directly to the upload folder. This means you can import an existing folder based photo collection to Balder.
|
|
||||||
|
|
||||||
Put photos in containing folders(albums) in the specified gallery folder.
|
|
||||||
Hierarchy of folders is not fully supported.
|
|
||||||
|
|
||||||
This format is recommended:
|
|
||||||
|
|
||||||
./ski weekend in hemsedal/snow.jpg
|
|
||||||
./ski weekend in hemsedal/afterski.jpg
|
|
||||||
./trip to iran/beautiful girls in tehran.jpg
|
|
||||||
./trip to iran/mosque in yazd.jpg
|
|
||||||
./trip to iran/powder snow in dizin.jpg
|
|
||||||
|
|
||||||
Every time you manually add photos to disk you must scan by visiting /photos/scan or run ScanFiles.Scan(false) from the console.
|
|
||||||
|
|
||||||
== Version history
|
|
||||||
|
|
||||||
1.2.2
|
|
||||||
- Rails 3.1
|
|
||||||
|
|
||||||
1.2.1
|
|
||||||
- Using plupupload instead of uploadify for non-flash upload options. Can now use html5, normal form, silverlight, gears and browserplus for photo upload.
|
|
||||||
|
|
||||||
1.2.0
|
|
||||||
- New storage path: "/uploads/files/" instead of "/uploads/". Make sure you move your photos or adjust the storage path.
|
|
||||||
|
|
||||||
== TODO
|
|
||||||
|
|
||||||
- Testing...
|
|
||||||
|
|
||||||
== IDEAS
|
|
||||||
- Themes
|
|
||||||
- Improved UX
|
|
||||||
- Mobile/Tablet friendly display using CSS media queries
|
|
||||||
Patches welcome!
|
|
||||||
|
|
||||||
== Copyright and license info
|
|
||||||
|
|
||||||
This code is copyrighted by Espen Antonsen. The source code is available free under the MIT License.
|
|
157
README.md
Normal file
|
@ -0,0 +1,157 @@
|
||||||
|
Welcome to Balder photo gallery
|
||||||
|
===============================
|
||||||
|
|
||||||
|
Made by Espen Antonsen.
|
||||||
|
|
||||||
|
Version 1.2.3 for Rails 3.2. See the rails2 branch for previous version.
|
||||||
|
|
||||||
|
[http://balderapp.com](http://balderapp.com)
|
||||||
|
|
||||||
|
Features
|
||||||
|
========
|
||||||
|
|
||||||
|
* Stores photos to disk in folders or on S3 (can run from Heroku...yay)
|
||||||
|
* Create multiple thumbnails of custom sizes
|
||||||
|
* Read and writes EXIF/IPTC title, description and keywords
|
||||||
|
* Organize in albums (as events in iPhoto)
|
||||||
|
* Combine albums in collections (as albums in iPhoto)
|
||||||
|
* Upload multiple photos
|
||||||
|
* Tag photos. Can also tag albums (actually all photos in album is tagged)
|
||||||
|
* User management with roles and permissions
|
||||||
|
* Geo-location of albums & photos with Google Maps integration.
|
||||||
|
|
||||||
|
Requirements
|
||||||
|
============
|
||||||
|
|
||||||
|
Rails 3.2
|
||||||
|
|
||||||
|
Software
|
||||||
|
|
||||||
|
Default:
|
||||||
|
|
||||||
|
- **[ExifTool]** (required for *Mini_EfixTool*). Can be disabled. Default is to read EXIF tags but not write them to the file when database is updated as writing EXIF is slow. To enable just uncomment `exif_write in photo.rb`
|
||||||
|
- **[ImageMagicK]**. *Carrierwave* can use either *RMagicK* or *MiniMagicK* (default). To change resize option the correct gem must be used (specified in Gemfile) and change included setting for Carrierwave in `file_uploader.rb`
|
||||||
|
Optional:
|
||||||
|
- *ImageScience* which requires **[FreeImage]**.
|
||||||
|
|
||||||
|
Ruby Gems: See `Gemfile`
|
||||||
|
|
||||||
|
Configuration
|
||||||
|
=============
|
||||||
|
{#configuration}
|
||||||
|
|
||||||
|
`config/balder.rb` has the following adjustable settings:
|
||||||
|
|
||||||
|
STORAGE_PATH
|
||||||
|
: Relative path to where the photos are stored. Default: uploads
|
||||||
|
Under the specified path two folders are used. "files" for original files and "thumbs" for generated thumbnails.
|
||||||
|
This can be adjusted in app/uploaders/file_uploader.rb
|
||||||
|
PRIVATE
|
||||||
|
|
||||||
|
: Require visitors to have a user and authenticate before viewing photos.
|
||||||
|
|
||||||
|
TITLE
|
||||||
|
: Title of site
|
||||||
|
|
||||||
|
HEROKU
|
||||||
|
: To be used on heroku.com. This will adjust carrierwave to save to Heroku's tmp area.
|
||||||
|
|
||||||
|
S3_KEY
|
||||||
|
: For saving files to Amazon S3 (required for Heroku)
|
||||||
|
|
||||||
|
S3_SECRET
|
||||||
|
: For saving files to Amazon S3 (required for Heroku)
|
||||||
|
|
||||||
|
S3_BUCKET
|
||||||
|
: For saving files to Amazon S3 (required for Heroku)
|
||||||
|
|
||||||
|
As these are environment variables you can easily add them to Heroku:
|
||||||
|
http://devcenter.heroku.com/articles/config-vars#rack_env_rails_env_merb_env
|
||||||
|
For a brief introduction to how to set up Balder on Heroku see:
|
||||||
|
http://blog.inspired.no/rails-photo-gallery-balder-on-heroku-and-s3-726
|
||||||
|
|
||||||
|
Installation
|
||||||
|
============
|
||||||
|
|
||||||
|
1. Clone the project from GitHub or Gitorious:
|
||||||
|
|
||||||
|
git clone git://github.com/espen/balder.git # GitHup
|
||||||
|
|
||||||
|
2. Install required software listed above
|
||||||
|
3. `bundle install` to install required gems.
|
||||||
|
4. Adjust the settings in `balder.rb` or as Heroku config variables (See [configuration above](#configuration))
|
||||||
|
5. Copy database file (not needed when hosting on Heroku):
|
||||||
|
|
||||||
|
cp config/database.example.yml config/database.yml
|
||||||
|
|
||||||
|
6. Create database user and edit database file. (unless on Heroku or using SQLite3)
|
||||||
|
|
||||||
|
7. Create database:
|
||||||
|
|
||||||
|
rake db:create
|
||||||
|
|
||||||
|
8. Migrate database schema:
|
||||||
|
|
||||||
|
rake db:migrate
|
||||||
|
|
||||||
|
9. Start up the project with your preferred web-server
|
||||||
|
For example:
|
||||||
|
|
||||||
|
rails start # or:
|
||||||
|
passenger start
|
||||||
|
|
||||||
|
Optional: add photos directly to disk
|
||||||
|
-------------------------------------
|
||||||
|
|
||||||
|
The gallery has a web-based upload tool. Alternatively you can upload files directly to the upload folder. This means you can import an existing folder based photo collection to Balder.
|
||||||
|
|
||||||
|
Put photos in containing folders(albums) in the specified gallery folder.
|
||||||
|
Hierarchy of folders is not fully supported.
|
||||||
|
|
||||||
|
This format is recommended:
|
||||||
|
|
||||||
|
./ski weekend in hemsedal/snow.jpg
|
||||||
|
./ski weekend in hemsedal/afterski.jpg
|
||||||
|
./trip to iran/beautiful girls in tehran.jpg
|
||||||
|
./trip to iran/mosque in yazd.jpg
|
||||||
|
./trip to iran/powder snow in dizin.jpg
|
||||||
|
|
||||||
|
Every time you manually add photos to disk you must scan by visiting `/photos/scan` or run `ScanFiles.Scan(false)` from the console.
|
||||||
|
|
||||||
|
Version history
|
||||||
|
===============
|
||||||
|
|
||||||
|
v1.2.3
|
||||||
|
: Rails 1.2.3
|
||||||
|
|
||||||
|
v1.2.2
|
||||||
|
: Rails 3.1
|
||||||
|
|
||||||
|
v1.2.1
|
||||||
|
: Using plupupload instead of uploadify for non-flash upload options. Can now use html5, normal form, silverlight, gears and browserplus for photo upload.
|
||||||
|
|
||||||
|
v1.2.0
|
||||||
|
: New storage path: `/uploads/files/` instead of `/uploads/`. Make sure you move your photos or adjust the storage path.
|
||||||
|
|
||||||
|
TODO
|
||||||
|
====
|
||||||
|
|
||||||
|
- Testing...
|
||||||
|
|
||||||
|
IDEAS
|
||||||
|
=====
|
||||||
|
|
||||||
|
- Themes
|
||||||
|
- Improved UX
|
||||||
|
- Mobile/Tablet friendly display using CSS media queries
|
||||||
|
Patches welcome!
|
||||||
|
|
||||||
|
Copyright and license info
|
||||||
|
==========================
|
||||||
|
|
||||||
|
This code is copyrighted by Espen Antonsen.
|
||||||
|
The source code is available free under the MIT License.
|
||||||
|
|
||||||
|
[ImageMagicK]: http://www.imagemagick.org
|
||||||
|
[ExifTool]: http://www.sno.phy.queensu.ca/~phil/exiftool/
|
||||||
|
[FreeImage]: http://sourceforge.net/projects/freeimage/
|
2
Rakefile
|
@ -4,4 +4,4 @@
|
||||||
require File.expand_path('../config/application', __FILE__)
|
require File.expand_path('../config/application', __FILE__)
|
||||||
require 'rake'
|
require 'rake'
|
||||||
|
|
||||||
Balder::Application.load_tasks
|
Photomix::Application.load_tasks
|
||||||
|
|
BIN
app/assets/images/ajaxful_rating/star.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
app/assets/images/ajaxful_rating/star_small.png
Normal file
After Width: | Height: | Size: 302 B |
BIN
app/assets/images/anythingslider/arrows-metallic.png
Normal file
After Width: | Height: | Size: 17 KiB |
BIN
app/assets/images/anythingslider/arrows-minimalist.png
Normal file
After Width: | Height: | Size: 5.5 KiB |
BIN
app/assets/images/anythingslider/construction.gif
Normal file
After Width: | Height: | Size: 21 KiB |
BIN
app/assets/images/anythingslider/cs-portfolio.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
app/assets/images/anythingslider/default.png
Normal file
After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
59
app/assets/javascripts/application.js
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
// This is a manifest file that'll be compiled into including all the files listed below.
|
||||||
|
// Add new JavaScript/Coffee code in separate files in this directory and they'll automatically
|
||||||
|
// be included in the compiled file accessible from http://example.com/assets/application.js
|
||||||
|
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
||||||
|
// the compiled file.
|
||||||
|
//
|
||||||
|
//= require jquery
|
||||||
|
//= 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
|
||||||
|
//= require plupload.flash
|
||||||
|
//= require plupload.silverlight
|
||||||
|
//= require plupload.html4
|
||||||
|
//= require plupload.html5
|
||||||
|
//= require plupload.gears
|
||||||
|
//= require plupload.browserplus
|
||||||
|
//= require_tree .
|
||||||
|
|
||||||
|
|
||||||
|
$(document).ready(function () {
|
||||||
|
$('body').noisy({
|
||||||
|
'intensity':10,
|
||||||
|
'size':200,
|
||||||
|
'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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
4
app/assets/javascripts/bootstrap.js.coffee
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
jQuery ->
|
||||||
|
$("a[rel=popover]").popover()
|
||||||
|
$(".tooltip").tooltip()
|
||||||
|
$("a[rel=tooltip]").tooltip()
|
2
app/assets/javascripts/home.js
Normal 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.
|
91
app/assets/stylesheets/ajaxful_rating.css.scss
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
/*
|
||||||
|
* Style by Rogie http://www.komodomedia.com/blog/2007/01/css-star-rating-redux/
|
||||||
|
*/
|
||||||
|
|
||||||
|
.ajaxful-rating,
|
||||||
|
.ajaxful-rating a:hover,
|
||||||
|
.ajaxful-rating a:active,
|
||||||
|
.ajaxful-rating a:focus,
|
||||||
|
.ajaxful-rating .show-value {
|
||||||
|
background: url("/assets/ajaxful_rating/star.png") left -1000px repeat-x;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ajaxful-rating {
|
||||||
|
position: relative;
|
||||||
|
/*width: 125px; this is setted dynamically */
|
||||||
|
height: 25px;
|
||||||
|
overflow: hidden;
|
||||||
|
list-style: none;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
background-position: left top;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ajaxful-rating li {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ajaxful-rating a,
|
||||||
|
.ajaxful-rating span,
|
||||||
|
.ajaxful-rating .show-value {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
text-indent: -1000em;
|
||||||
|
height: 25px;
|
||||||
|
line-height: 25px;
|
||||||
|
outline: none;
|
||||||
|
overflow: hidden;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ajaxful-rating a:hover,
|
||||||
|
.ajaxful-rating a:active,
|
||||||
|
.ajaxful-rating a:focus {
|
||||||
|
background-position: left bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This section is generated dynamically.
|
||||||
|
Just add a call to the helper method 'ajaxful_rating_style' within
|
||||||
|
the head tags in your main layout
|
||||||
|
.ajaxful-rating .stars-1{
|
||||||
|
width: 20%;
|
||||||
|
z-index: 6;
|
||||||
|
}
|
||||||
|
.ajaxful-rating .stars-2{
|
||||||
|
width: 40%;
|
||||||
|
z-index: 5;
|
||||||
|
}
|
||||||
|
.ajaxful-rating .stars-3{
|
||||||
|
width: 60%;
|
||||||
|
z-index: 4;
|
||||||
|
}
|
||||||
|
.ajaxful-rating .stars-4{
|
||||||
|
width: 80%;
|
||||||
|
z-index: 3;
|
||||||
|
}
|
||||||
|
.ajaxful-rating .stars-5{
|
||||||
|
width: 100%;
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
.ajaxful-rating .show-value {
|
||||||
|
z-index: 1;
|
||||||
|
background-position: left center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* smaller star */
|
||||||
|
.ajaxful-rating.small {
|
||||||
|
/*width: 50px; this is setted dynamically */
|
||||||
|
height: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ajaxful-rating.small,
|
||||||
|
.ajaxful-rating.small a:hover,
|
||||||
|
.ajaxful-rating.small a:active,
|
||||||
|
.ajaxful-rating.small a:focus,
|
||||||
|
.ajaxful-rating.small .show-value {
|
||||||
|
background-image: url("/assets/ajaxful_rating/star_small.png");
|
||||||
|
line-height: 10px;
|
||||||
|
height: 10px;
|
||||||
|
}
|
191
app/assets/stylesheets/application.css.scss
Normal file
|
@ -0,0 +1,191 @@
|
||||||
|
/*
|
||||||
|
*= 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 #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: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
padding-top: 90px;
|
||||||
|
padding-bottom: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1, h2, h3, h4, h5, h6 {
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-inner {
|
||||||
|
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 !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 {
|
||||||
|
border-top-color: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar .nav {
|
||||||
|
margin-top: 5px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar .nav > li {
|
||||||
|
padding-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar .nav .divider-vertical {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar .nav > li > a {
|
||||||
|
color: #333333;
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar .nav > li > a:hover {
|
||||||
|
background-color: #FAFAFA;
|
||||||
|
color: #7B7B7B;
|
||||||
|
border: 0px solid #C9C9C9;
|
||||||
|
border-radius: 5px 5px 5px 5px;
|
||||||
|
-webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.5), 0 1px 0px rgba(255, 255, 255, 0.75);
|
||||||
|
-moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.5), 0 1px 0px rgba(255, 255, 255, 0.75);
|
||||||
|
box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.5), 0 1px 0px rgba(255, 255, 255, 0.75);
|
||||||
|
transition: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar .nav .active > a, .navbar .nav .active > a:hover {
|
||||||
|
background-color: #FAFAFA;
|
||||||
|
color: #7B7B7B;
|
||||||
|
border: 0;
|
||||||
|
border-radius: 5px 5px 5px 5px;
|
||||||
|
box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.5), 0 1px 0px rgba(255, 255, 255, 0.75);
|
||||||
|
transition: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar .nav .open > .dropdown-toggle, .navbar .nav .active > .dropdown-toggle, .navbar .nav .open.active > .dropdown-toggle {
|
||||||
|
background-color: #FAFAFA;
|
||||||
|
color: #7B7B7B;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar .nav .active > .dropdown-toggle:hover {
|
||||||
|
color: #7B7B7B;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-search {
|
||||||
|
margin-top: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-search .search-query {
|
||||||
|
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: normal;
|
||||||
|
line-height: 1.2;
|
||||||
|
color: #333;
|
||||||
|
background: #666;
|
||||||
|
background: rgba(255, 255, 255, 0.3);
|
||||||
|
border: 0;
|
||||||
|
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;
|
||||||
|
text-shadow: 0 1px 0 #ffffff;
|
||||||
|
background-color: #ffffff;
|
||||||
|
border: 0;
|
||||||
|
box-shadow: 0 0 3px rgba(0, 0, 0, 0.15);
|
||||||
|
outline: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ajaxful-rating-wrapper {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.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;
|
||||||
|
}
|
32
app/assets/stylesheets/bootstrap_and_overrides.css.less
vendored
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
@import "twitter/bootstrap/bootstrap";
|
||||||
|
body {
|
||||||
|
padding-top: 60px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@import "twitter/bootstrap/responsive";
|
||||||
|
|
||||||
|
// Set the correct sprite paths
|
||||||
|
@iconSpritePath: asset-path('twitter/bootstrap/glyphicons-halflings.png');
|
||||||
|
@iconWhiteSpritePath: asset-path('twitter/bootstrap/glyphicons-halflings-white.png');
|
||||||
|
|
||||||
|
// Set the Font Awesome (Font Awesome is default. You can disable by commenting below lines)
|
||||||
|
// Note: If you use asset_path() here, your compiled boostrap_and_overrides.css will not
|
||||||
|
// have the proper paths. So for now we use the absolute path.
|
||||||
|
@fontAwesomeEotPath: '/assets/fontawesome-webfont.eot';
|
||||||
|
@fontAwesomeWoffPath: '/assets/fontawesome-webfont.woff';
|
||||||
|
@fontAwesomeTtfPath: '/assets/fontawesome-webfont.ttf';
|
||||||
|
@fontAwesomeSvgPath: '/assets/fontawesome-webfont.svg';
|
||||||
|
|
||||||
|
// Font Awesome
|
||||||
|
@import "fontawesome";
|
||||||
|
|
||||||
|
// Your custom LESS stylesheets goes here
|
||||||
|
//
|
||||||
|
// Since bootstrap was imported above you have access to its mixins which
|
||||||
|
// you may use and inherit here
|
||||||
|
//
|
||||||
|
// If you'd like to override bootstrap's own variables, you can do so here as well
|
||||||
|
// See http://twitter.github.com/bootstrap/less.html for their names and documentation
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
// @linkColor: #ff0000;
|
3
app/assets/stylesheets/home.css.less
Normal 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/
|
|
@ -11,7 +11,7 @@
|
||||||
border: 1px solid #bababa;
|
border: 1px solid #bababa;
|
||||||
padding: 2px 8px 3px 20px;
|
padding: 2px 8px 3px 20px;
|
||||||
margin-right: 4px;
|
margin-right: 4px;
|
||||||
background: #f3f3f3 url('../img/buttons.png') no-repeat 0 center;
|
background: #f3f3f3 url(asset_path("buttons.png")) no-repeat 0 center;
|
||||||
outline: 0;
|
outline: 0;
|
||||||
|
|
||||||
/* Optional rounded corners for browsers that support it */
|
/* Optional rounded corners for browsers that support it */
|
||||||
|
@ -29,7 +29,7 @@
|
||||||
.plupload_disabled, a.plupload_disabled:hover {
|
.plupload_disabled, a.plupload_disabled:hover {
|
||||||
color: #737373;
|
color: #737373;
|
||||||
border-color: #c5c5c5;
|
border-color: #c5c5c5;
|
||||||
background: #ededed url('../img/buttons-disabled.png') no-repeat 0 center;
|
background: #ededed url(asset_path('buttons-disabled.png')) no-repeat 0 center;
|
||||||
cursor: default;
|
cursor: default;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@
|
||||||
|
|
||||||
.plupload_container {
|
.plupload_container {
|
||||||
padding: 8px;
|
padding: 8px;
|
||||||
background: url('../img/transp50.png');
|
background: url(asset_path('transp50.png'));
|
||||||
/*-moz-border-radius: 5px;*/
|
/*-moz-border-radius: 5px;*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,9 +54,9 @@
|
||||||
width: 98%;
|
width: 98%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.plupload_header {background: #2A2C2E url('../img/backgrounds.gif') repeat-x;}
|
.plupload_header {background: #2A2C2E url(asset_path('backgrounds.gif')) repeat-x;}
|
||||||
.plupload_header_content {
|
.plupload_header_content {
|
||||||
background: url('../img/backgrounds.gif') no-repeat 0 -317px;
|
background: url(asset_path('backgrounds.gif')) no-repeat 0 -317px;
|
||||||
min-height: 56px;
|
min-height: 56px;
|
||||||
padding-left: 60px;
|
padding-left: 60px;
|
||||||
color: #FFF;
|
color: #FFF;
|
||||||
|
@ -83,7 +83,7 @@
|
||||||
|
|
||||||
.plupload_filelist li {
|
.plupload_filelist li {
|
||||||
padding: 10px 8px;
|
padding: 10px 8px;
|
||||||
background: #F5F5F5 url('../img/backgrounds.gif') repeat-x 0 -156px;
|
background: #F5F5F5 url(asset_path('backgrounds.gif')) repeat-x 0 -156px;
|
||||||
border-bottom: 1px solid #DDD;
|
border-bottom: 1px solid #DDD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,20 +122,20 @@
|
||||||
height: 16px;
|
height: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
li.plupload_uploading {background: #ECF3DC url('../img/backgrounds.gif') repeat-x 0 -238px;}
|
li.plupload_uploading {background: #ECF3DC url(asset_path('backgrounds.gif')) repeat-x 0 -238px;}
|
||||||
li.plupload_done {color:#AAA}
|
li.plupload_done {color:#AAA}
|
||||||
|
|
||||||
li.plupload_delete a {
|
li.plupload_delete a {
|
||||||
background: url('../img/delete.gif');
|
background: url(asset_path('delete.gif'));
|
||||||
}
|
}
|
||||||
|
|
||||||
li.plupload_failed a {
|
li.plupload_failed a {
|
||||||
background: url('../img/error.gif');
|
background: url(asset_path('error.gif'));
|
||||||
cursor: default;
|
cursor: default;
|
||||||
}
|
}
|
||||||
|
|
||||||
li.plupload_done a {
|
li.plupload_done a {
|
||||||
background: url('../img/done.gif');
|
background: url(asset_path('done.gif'));
|
||||||
cursor: default;
|
cursor: default;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,14 +20,14 @@ div.plupload div.plupload_header {border-width: 0 0 1px 0; position: relative;}
|
||||||
}
|
}
|
||||||
|
|
||||||
.plupload_header_content {
|
.plupload_header_content {
|
||||||
background-image: url('../img/plupload.png');
|
background-image: url(asset_path('plupload.png'));
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-position: 8px center;
|
background-position: 8px center;
|
||||||
min-height: 56px;
|
min-height: 56px;
|
||||||
padding-left: 60px;
|
padding-left: 60px;
|
||||||
position:relative;
|
position:relative;
|
||||||
}
|
}
|
||||||
.plupload_header_content_bw {background-image: url('../img/plupload-bw.png');}
|
.plupload_header_content_bw {background-image: url(asset_path('plupload-bw.png'));}
|
||||||
.plupload_header_title {
|
.plupload_header_title {
|
||||||
font: normal 18px sans-serif;
|
font: normal 18px sans-serif;
|
||||||
padding: 6px 0 3px;
|
padding: 6px 0 3px;
|
||||||
|
@ -61,7 +61,6 @@ div.plupload div.plupload_header {border-width: 0 0 1px 0; position: relative;}
|
||||||
max-height: 180px;
|
max-height: 180px;
|
||||||
min-height: 168px;
|
min-height: 168px;
|
||||||
_height: 168px;
|
_height: 168px;
|
||||||
overflow-y: auto;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.plupload_file_size, .plupload_file_status {text-align: right;}
|
.plupload_file_size, .plupload_file_status {text-align: right;}
|
|
@ -1,5 +0,0 @@
|
||||||
class Admin::ApplicationController < ApplicationController
|
|
||||||
|
|
||||||
before_filter :require_role_admin
|
|
||||||
|
|
||||||
end
|
|
|
@ -1,47 +0,0 @@
|
||||||
class Admin::UsersController < Admin::ApplicationController
|
|
||||||
|
|
||||||
def index
|
|
||||||
@users = User.find(:all, :order => "Name, email")
|
|
||||||
end
|
|
||||||
|
|
||||||
def show
|
|
||||||
@user = User.find(params[:id])
|
|
||||||
end
|
|
||||||
|
|
||||||
def new
|
|
||||||
@user = User.new
|
|
||||||
end
|
|
||||||
|
|
||||||
def create
|
|
||||||
@user = User.new(params[:user])
|
|
||||||
if @user.save
|
|
||||||
flash[:notice] = "Account registered!"
|
|
||||||
redirect_to @user
|
|
||||||
else
|
|
||||||
render :action => :new
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def edit
|
|
||||||
@user = User.find(params[:id])
|
|
||||||
end
|
|
||||||
|
|
||||||
def update
|
|
||||||
@user = User.find(params[:id])
|
|
||||||
if @user.update_attributes(params[:user])
|
|
||||||
flash[:notice] = "Account updated!"
|
|
||||||
redirect_to @user
|
|
||||||
else
|
|
||||||
render :action => :edit
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def destroy
|
|
||||||
@user = User.find(params[:id])
|
|
||||||
if @user.destroy
|
|
||||||
redirect_to users_path
|
|
||||||
else
|
|
||||||
redirect_to @user
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,10 +1,15 @@
|
||||||
class AlbumsController < ApplicationController
|
class AlbumsController < ApplicationController
|
||||||
before_filter :check_public_access
|
before_filter :check_public_access
|
||||||
before_filter :require_role_admin, :only => [:untouched, :new, :create, :edit, :update, :destroy]
|
skip_before_filter :authenticate_user!, :only => [:index, :show]
|
||||||
|
|
||||||
def index
|
def index
|
||||||
|
add_breadcrumb t('activerecord.models.album.popular'), collections_path, :title => t('activerecord.models.album.popular')
|
||||||
|
add_breadcrumb t('activerecord.actions.create', :model => I18n.t('activerecord.models.album.single')), new_album_path,
|
||||||
|
:title => t('activerecord.actions.create', :model => I18n.t('activerecord.models.album.single')),
|
||||||
|
:li_icon => 'icon-plus-sign'
|
||||||
|
|
||||||
if params[:tag_id]
|
if params[:tag_id]
|
||||||
@albums = Album.find(:all, :conditions => [ "id IN ( SELECT DISTINCT photos.album_id FROM photos WHERE photos.id IN ( SELECT photo_id FROM photo_tags WHERE photo_tags.tag_id = :q) )", { :q => Tag.find( params[:tag_id] ).id } ], :order => 'title')
|
@albums = Album.where(:conditions => [ "id IN ( SELECT DISTINCT photos.album_id FROM photos WHERE photos.id IN ( SELECT photo_id FROM photo_tags WHERE photo_tags.tag_id = :q) )", { :q => Tag.find( params[:tag_id] ).id } ]).order('title')
|
||||||
elsif params[:q]
|
elsif params[:q]
|
||||||
#search = params[:q]
|
#search = params[:q]
|
||||||
#search = search.split("AND").map{|q|q.strip}
|
#search = search.split("AND").map{|q|q.strip}
|
||||||
|
@ -20,7 +25,7 @@ class AlbumsController < ApplicationController
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@albums = Album.find(:all, :order => 'title')
|
@albums = Album.popular.page(@page).per(@per_page)
|
||||||
end
|
end
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html
|
format.html
|
||||||
|
@ -40,6 +45,8 @@ class AlbumsController < ApplicationController
|
||||||
|
|
||||||
def show
|
def show
|
||||||
@album = Album.find( params[:id])
|
@album = Album.find( params[:id])
|
||||||
|
@photos = @album.photos.popular
|
||||||
|
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html
|
format.html
|
||||||
format.json { render :json => @album }
|
format.json { render :json => @album }
|
||||||
|
@ -99,4 +106,10 @@ class AlbumsController < ApplicationController
|
||||||
end
|
end
|
||||||
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
|
end
|
||||||
|
|
|
@ -2,80 +2,28 @@
|
||||||
# Likewise, all the methods added will be available for all controllers.
|
# Likewise, all the methods added will be available for all controllers.
|
||||||
|
|
||||||
class ApplicationController < ActionController::Base
|
class ApplicationController < ActionController::Base
|
||||||
|
layout 'bootstrap'
|
||||||
helper :all # include all helpers, all the time
|
helper :all # include all helpers, all the time
|
||||||
protect_from_forgery # See ActionController::RequestForgeryProtection for details
|
protect_from_forgery # See ActionController::RequestForgeryProtection for details
|
||||||
|
|
||||||
helper_method :current_user, :current_user_session
|
before_filter :set_locale
|
||||||
|
before_filter :authenticate_user!, :set_current_user
|
||||||
before_filter :setup
|
before_filter :setup, :set_pagination_params
|
||||||
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
# This hack is needed to access the current user in models. See http://rails-bestpractices.com/posts/47-fetch-current-user-in-models
|
||||||
|
def set_current_user
|
||||||
|
User.current = current_user
|
||||||
|
end
|
||||||
|
|
||||||
def setup
|
def setup
|
||||||
redirect_to new_account_path if User.all.length == 0
|
redirect_to new_account_path if User.all.size == 0
|
||||||
end
|
end
|
||||||
|
|
||||||
def check_public_access
|
def check_public_access
|
||||||
require_user if ENV['PRIVATE'] == 'true'
|
require_user if ENV['PRIVATE'] == 'true'
|
||||||
end
|
end
|
||||||
|
|
||||||
def current_user_session
|
|
||||||
return @current_user_session if defined?(@current_user_session)
|
|
||||||
@current_user_session = UserSession.find
|
|
||||||
end
|
|
||||||
|
|
||||||
def current_user
|
|
||||||
return @current_user if defined?(@current_user)
|
|
||||||
@current_user = current_user_session && current_user_session.user
|
|
||||||
end
|
|
||||||
|
|
||||||
def require_role(roles = [])
|
|
||||||
unless current_user && current_user.in_role?(*roles)
|
|
||||||
store_location
|
|
||||||
flash[:notice] = "You must have permission to access this page"
|
|
||||||
redirect_to account_path
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
||||||
def require_role_admin
|
|
||||||
return false if !require_user
|
|
||||||
return require_role("admin")
|
|
||||||
end
|
|
||||||
|
|
||||||
def require_permission(permissions = [])
|
|
||||||
return false if !require_user
|
|
||||||
unless current_user && current_user.has_permission?(*permissions)
|
|
||||||
store_location
|
|
||||||
flash[:notice] = "You must have permission to access this page"
|
|
||||||
redirect_to account_path
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
||||||
def require_user
|
|
||||||
unless current_user
|
|
||||||
store_location
|
|
||||||
flash[:notice] = "You must be logged in to access this page"
|
|
||||||
redirect_to login_path
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
||||||
def require_no_user
|
|
||||||
if current_user
|
|
||||||
store_location
|
|
||||||
flash[:notice] = "Already logged in. Please logout"
|
|
||||||
redirect_to account_path
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
||||||
def store_location
|
def store_location
|
||||||
session[:return_to] = request.fullpath
|
session[:return_to] = request.fullpath
|
||||||
end
|
end
|
||||||
|
@ -84,4 +32,20 @@ class ApplicationController < ActionController::Base
|
||||||
redirect_to(session[:return_to] || default)
|
redirect_to(session[:return_to] || default)
|
||||||
session[:return_to] = nil
|
session[:return_to] = nil
|
||||||
end
|
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
|
end
|
||||||
|
|
|
@ -1,9 +1,14 @@
|
||||||
class CollectionsController < ApplicationController
|
class CollectionsController < ApplicationController
|
||||||
before_filter :check_public_access
|
before_filter :check_public_access
|
||||||
before_filter :require_role_admin, :only => [:new, :create, :edit, :update, :destroy]
|
skip_before_filter :authenticate_user!, :only => [:index, :show]
|
||||||
|
add_breadcrumb I18n.t('home_page'), :root_path, :title => I18n.t('home_page')
|
||||||
|
|
||||||
def index
|
def index
|
||||||
@collections = Collection.find(:all, :order => 'title')
|
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|
|
respond_to do |format|
|
||||||
format.html
|
format.html
|
||||||
format.json { render :json => @collections }
|
format.json { render :json => @collections }
|
||||||
|
@ -13,7 +18,14 @@ class CollectionsController < ApplicationController
|
||||||
|
|
||||||
def show
|
def show
|
||||||
@collection = Collection.find( params[:id] )
|
@collection = Collection.find( params[:id] )
|
||||||
@albums = @collection.albums.find(:all, :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|
|
respond_to do |format|
|
||||||
format.html
|
format.html
|
||||||
format.json { render :json => @collection }
|
format.json { render :json => @collection }
|
||||||
|
@ -24,6 +36,10 @@ class CollectionsController < ApplicationController
|
||||||
|
|
||||||
def new
|
def new
|
||||||
@collection = Collection.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', :model => I18n.t('activerecord.models.collection.one'))
|
||||||
end
|
end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
|
@ -42,6 +58,8 @@ class CollectionsController < ApplicationController
|
||||||
|
|
||||||
def update
|
def update
|
||||||
@collection = Collection.find( params[:id])
|
@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])
|
if @collection.update_attributes(params[:collection])
|
||||||
flash[:notice] = "Collection updated!"
|
flash[:notice] = "Collection updated!"
|
||||||
redirect_to @collection
|
redirect_to @collection
|
||||||
|
@ -59,4 +77,10 @@ class CollectionsController < ApplicationController
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def rate
|
||||||
|
@collection = Collection.find(params[:id])
|
||||||
|
@collection.rate(params[:stars], current_user, params[:dimension])
|
||||||
|
render :json => {:id => @collection.wrapper_dom_id(params), :width => 125}
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
16
app/controllers/home_controller.rb
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
class HomeController < ApplicationController
|
||||||
|
skip_before_filter :authenticate_user!, :only => [:index]
|
||||||
|
|
||||||
|
add_breadcrumb I18n.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
|
16
app/controllers/locale_controller.rb
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
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
|
||||||
|
end
|
||||||
|
if params[:locale] && I18n.available_locales.include?(params[:locale].to_sym)
|
||||||
|
session[:locale] = I18n.locale = params[:locale].to_sym
|
||||||
|
flash.notice = t(:locale_changed)
|
||||||
|
else
|
||||||
|
flash[:error] = t(:locale_not_changed)
|
||||||
|
end
|
||||||
|
redirect_back_or_default(root_path)
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,17 +1,17 @@
|
||||||
class PhotosController < ApplicationController
|
class PhotosController < ApplicationController
|
||||||
before_filter :check_public_access
|
before_filter :check_public_access
|
||||||
before_filter :require_role_admin, :only => [:untouched, :upload, :new, :create, :edit, :update, :destroy, :scan]
|
skip_before_filter :authenticate_user!, :only => [:index, :show]
|
||||||
|
|
||||||
def index
|
def index
|
||||||
if params[:tag_id] && params[:album_id]
|
if params[:tag_id] && params[:album_id]
|
||||||
@tag = Tag.find_by_title!( params[:tag_id] )
|
@tag = Tag.find_by_title!( params[:tag_id] )
|
||||||
@photos = @tag.photos.find(:all, :conditions => ['photos.album_id = :album', {:album => Album.find(params[:album_id] ) } ], :order => "photos.id ASC")
|
@photos = @tag.photos.where(:conditions => ['photos.album_id = :album', {:album => Album.find(params[:album_id] ) } ]).order("photos.id ASC")
|
||||||
elsif params[:tag_id]
|
elsif params[:tag_id]
|
||||||
@tag = Tag.find_by_title!( params[:tag_id] )
|
@tag = Tag.find_by_title!( params[:tag_id] )
|
||||||
@photos = @tag.photos.find(:all, :order => "photos.id ASC")
|
@photos = @tag.photos.order("photos.id ASC")
|
||||||
elsif params[:album_id]
|
elsif params[:album_id]
|
||||||
@album = Album.find( params[:album_id])
|
@album = Album.find( params[:album_id])
|
||||||
@photos = @album.photos.find(:all, :order => "photos.id ASC")
|
@photos = @album.photos.order("photos.id ASC")
|
||||||
elsif params[:q]
|
elsif params[:q]
|
||||||
#search = params[:q]
|
#search = params[:q]
|
||||||
#search = search.split("AND").map{|q|q.strip}
|
#search = search.split("AND").map{|q|q.strip}
|
||||||
|
@ -25,7 +25,7 @@ class PhotosController < ApplicationController
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@photos = Photo.find(:all, :order => "photos.id ASC")
|
@photos = Photo.popular.page(@page).per(@per_page)
|
||||||
end
|
end
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html
|
format.html
|
||||||
|
@ -37,9 +37,9 @@ class PhotosController < ApplicationController
|
||||||
def untouched
|
def untouched
|
||||||
if params[:album_id]
|
if params[:album_id]
|
||||||
@album = Album.find( params[:album_id])
|
@album = Album.find( params[:album_id])
|
||||||
@photos = @album.photos.untouched
|
@photos = @album.photos.untouched.page(@page).per(@per_page)
|
||||||
else
|
else
|
||||||
@photos = Photo.untouched()
|
@photos = Photo.untouched().page(@page).per(@per_page)
|
||||||
end
|
end
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html
|
format.html
|
||||||
|
@ -77,10 +77,10 @@ class PhotosController < ApplicationController
|
||||||
|
|
||||||
def create
|
def create
|
||||||
@photo = Photo.new(params[:photo])
|
@photo = Photo.new(params[:photo])
|
||||||
@photo.file = params[:file]
|
@photo.attachment = params[:file]
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
if @photo.save
|
if @photo.save
|
||||||
format.html { render :text => "FILEID:" + @photo.file.album.url }
|
format.html { render :text => "FILEID:" + @photo.attachment.album.url }
|
||||||
format.xml { render :nothing => true }
|
format.xml { render :nothing => true }
|
||||||
else
|
else
|
||||||
format.html { render :text => "ERRORS:" + @photo.errors.full_messages.join(" "), :status => 500 }
|
format.html { render :text => "ERRORS:" + @photo.errors.full_messages.join(" "), :status => 500 }
|
||||||
|
@ -91,7 +91,7 @@ class PhotosController < ApplicationController
|
||||||
|
|
||||||
def edit
|
def edit
|
||||||
@photo = Photo.find( params[:id])
|
@photo = Photo.find( params[:id])
|
||||||
@tags = Tag.find(:all).map { |tag| tag.title }.join('\',\'')
|
@tags = Tag.all.map { |tag| tag.title }.join('\',\'')
|
||||||
end
|
end
|
||||||
|
|
||||||
def edit_multiple
|
def edit_multiple
|
||||||
|
@ -148,4 +148,10 @@ class PhotosController < ApplicationController
|
||||||
redirect_to @photo
|
redirect_to @photo
|
||||||
end
|
end
|
||||||
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
|
end
|
||||||
|
|
|
@ -1,24 +0,0 @@
|
||||||
class UserSessionsController < ApplicationController
|
|
||||||
before_filter :require_no_user, :only => [:new, :create]
|
|
||||||
before_filter :require_user, :only => :destroy
|
|
||||||
|
|
||||||
def new
|
|
||||||
@user_session = UserSession.new
|
|
||||||
end
|
|
||||||
|
|
||||||
def create
|
|
||||||
@user_session = UserSession.new(params[:user_session])
|
|
||||||
if @user_session.save
|
|
||||||
flash[:notice] = "Login successful!"
|
|
||||||
redirect_back_or_default account_path
|
|
||||||
else
|
|
||||||
render :new
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def destroy
|
|
||||||
current_user_session.destroy
|
|
||||||
flash[:notice] = "Logout successful!"
|
|
||||||
redirect_to root_path
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,7 +1,6 @@
|
||||||
class UsersController < ApplicationController
|
class UsersController < ApplicationController
|
||||||
before_filter :check_public_access
|
before_filter :check_public_access
|
||||||
before_filter :require_no_user, :only => [:new, :create]
|
skip_before_filter :authenticate_user!, :only => [:new, :create]
|
||||||
before_filter :require_user, :only => [:show, :edit, :update, :destroy]
|
|
||||||
skip_filter :setup
|
skip_filter :setup
|
||||||
|
|
||||||
def new
|
def new
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
# Methods added to this helper will be available to all templates in the application.
|
# Methods added to this helper will be available to all templates in the application.
|
||||||
module ApplicationHelper
|
module ApplicationHelper
|
||||||
|
|
||||||
|
=begin
|
||||||
def breadcrumbs(sep = "/", include_home = true)
|
def breadcrumbs(sep = "/", include_home = true)
|
||||||
levels = request.path.split('?')[0].split('/')
|
levels = request.path.split('?')[0].split('/')
|
||||||
levels.delete_at(0)
|
levels.delete_at(0)
|
||||||
|
|
||||||
#links = "You are here: "
|
#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"]
|
nocrumb = ["collections", "albums", "photos", "tags", "new", "edit", "tags"]
|
||||||
|
|
||||||
|
@ -15,12 +16,19 @@ module ApplicationHelper
|
||||||
level = level.gsub("-", " ")
|
level = level.gsub("-", " ")
|
||||||
if index+1 == levels.length
|
if index+1 == levels.length
|
||||||
#links += " #{sep} #{level.upcase}" unless nocrumb.include?(level)
|
#links += " #{sep} #{level.upcase}" unless nocrumb.include?(level)
|
||||||
elsif !nocrumb.include?(level)
|
#elsif !nocrumb.include?(level)
|
||||||
links += " " + sep + " "
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
content_tag("div", links, :id => "breadcrumb")
|
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
|
||||||
end
|
end
|
||||||
|
|
2
app/helpers/home_helper.rb
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
module HomeHelper
|
||||||
|
end
|
|
@ -1,9 +1,3 @@
|
||||||
module UsersHelper
|
module UsersHelper
|
||||||
def has_permission?(permissions = [])
|
|
||||||
return current_user && current_user.has_permission?(permissions)
|
|
||||||
end
|
|
||||||
|
|
||||||
def has_role?(roles = [])
|
|
||||||
return current_user && current_user.in_role?(roles)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
63
app/models/ability.rb
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
class Ability
|
||||||
|
include CanCan::Ability
|
||||||
|
|
||||||
|
def initialize(user)
|
||||||
|
self.clear_aliased_actions
|
||||||
|
|
||||||
|
alias_action :edit, :to => :update
|
||||||
|
alias_action :new, :to => :create
|
||||||
|
alias_action :new_action, :to => :create
|
||||||
|
alias_action :show, :to => :read
|
||||||
|
|
||||||
|
if user.has_role? 'admin'
|
||||||
|
can :manage, :all
|
||||||
|
else
|
||||||
|
#############################
|
||||||
|
can :read, User do |resource|
|
||||||
|
resource == user
|
||||||
|
end
|
||||||
|
can :update, User do |resource|
|
||||||
|
resource == user
|
||||||
|
end
|
||||||
|
can :create, User
|
||||||
|
##############################
|
||||||
|
can :read, Profile do |resource|
|
||||||
|
resource == user
|
||||||
|
end
|
||||||
|
can :update, Profile do |resource|
|
||||||
|
resource == user
|
||||||
|
end
|
||||||
|
can :create, Profile
|
||||||
|
###############################
|
||||||
|
can :read, Link do |resource|
|
||||||
|
resource == user
|
||||||
|
end
|
||||||
|
can :update, Link do |resource|
|
||||||
|
resource == user
|
||||||
|
end
|
||||||
|
can :create, Link
|
||||||
|
end
|
||||||
|
# Define abilities for the passed in user here. For example:
|
||||||
|
#
|
||||||
|
# user ||= User.new # guest user (not logged in)
|
||||||
|
# if user.admin?
|
||||||
|
# can :manage, :all
|
||||||
|
# else
|
||||||
|
# can :read, :all
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# The first argument to `can` is the action you are giving the user permission to do.
|
||||||
|
# If you pass :manage it will apply to every action. Other common actions here are
|
||||||
|
# :read, :create, :update and :destroy.
|
||||||
|
#
|
||||||
|
# The second argument is the resource the user can perform the action on. If you pass
|
||||||
|
# :all it will apply to every resource. Otherwise pass a Ruby class of the resource.
|
||||||
|
#
|
||||||
|
# The third argument is an optional hash of conditions to further filter the objects.
|
||||||
|
# For example, here the user can only update published articles.
|
||||||
|
#
|
||||||
|
# can :update, Article, :published => true
|
||||||
|
#
|
||||||
|
# See the wiki for details: https://github.com/ryanb/cancan/wiki/Defining-Abilities
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,4 +1,8 @@
|
||||||
class Album < ActiveRecord::Base
|
class Album < ActiveRecord::Base
|
||||||
|
extend Ext::GroupFor
|
||||||
|
|
||||||
|
ajaxful_rateable :stars => 5, :cache_column => :rating_average
|
||||||
|
|
||||||
has_many :photos, :dependent => :destroy
|
has_many :photos, :dependent => :destroy
|
||||||
has_many :collection_albums
|
has_many :collection_albums
|
||||||
has_many :collections, :through => :collection_albums
|
has_many :collections, :through => :collection_albums
|
||||||
|
@ -11,11 +15,12 @@ class Album < ActiveRecord::Base
|
||||||
after_destroy :destroy_folders
|
after_destroy :destroy_folders
|
||||||
|
|
||||||
attr_accessor :tags
|
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 :visible, lambda { where(:public => true) }
|
||||||
scope :unused, where("albums.id NOT IN (SELECT album_id FROM collection_albums)")
|
scope :popular, lambda{visible.includes(:photos).where("photos.id NOT NULL").order('albums.rating_average desc')}
|
||||||
scope :used, where("albums.id IN (SELECT album_id FROM collection_albums)")
|
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
|
def to_param
|
||||||
"#{id}-#{title.parameterize}"
|
"#{id}-#{title.parameterize}"
|
||||||
|
|
|
@ -1,10 +1,21 @@
|
||||||
class Collection < ActiveRecord::Base
|
class Collection < ActiveRecord::Base
|
||||||
|
extend Ext::GroupFor
|
||||||
|
|
||||||
|
ajaxful_rateable :stars => 5, :cache_column => :rating_average
|
||||||
|
|
||||||
has_many :collection_albums
|
has_many :collection_albums
|
||||||
has_many :albums, :through => :collection_albums
|
has_many :albums, :through => :collection_albums
|
||||||
attr_accessor :album_list
|
attr_accessor :album_list
|
||||||
|
|
||||||
validates :title, :presence => true
|
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
|
def to_param
|
||||||
"#{id}-#{title.parameterize}"
|
"#{id}-#{title.parameterize}"
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
class Permission < ActiveRecord::Base
|
|
||||||
# uncomment any of the following lines which is relevant to your application,
|
|
||||||
# or create your own with the name of the model which acts_as_permissible.
|
|
||||||
belongs_to :user
|
|
||||||
|
|
||||||
belongs_to :role
|
|
||||||
|
|
||||||
belongs_to :permissible, :polymorphic => true, :dependent => :destroy
|
|
||||||
|
|
||||||
validates_presence_of :permissible_id, :permissible_type, :action
|
|
||||||
validates_format_of :action, :with => /^[a-z_]+$/
|
|
||||||
validates_numericality_of :permissible_id
|
|
||||||
validates_uniqueness_of :action, :scope => [:permissible_id,:permissible_type]
|
|
||||||
|
|
||||||
def to_hash
|
|
||||||
self.new_record? ? {} : {self.action => self.granted}
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
|
@ -1,20 +1,22 @@
|
||||||
class Photo < ActiveRecord::Base
|
class Photo < ActiveRecord::Base
|
||||||
# TODO: path not used? it should be removed from the DB
|
extend Ext::GroupFor
|
||||||
|
|
||||||
|
ajaxful_rateable :stars => 5, :cache_column => :rating_average
|
||||||
|
|
||||||
belongs_to :album
|
belongs_to :album
|
||||||
has_many :photo_tags, :dependent => :destroy
|
has_many :photo_tags, :dependent => :destroy
|
||||||
has_many :tags, :through => :photo_tags
|
has_many :tags, :through => :photo_tags
|
||||||
|
|
||||||
mount_uploader :file, FileUploader
|
mount_uploader :attachment, FileUploader
|
||||||
|
|
||||||
validates :title, :presence => true
|
|
||||||
|
|
||||||
before_validation :set_title
|
|
||||||
before_create :exif_read
|
before_create :exif_read
|
||||||
#before_update :exif_write
|
before_update :exif_write
|
||||||
|
after_create :set_title, :set_visible
|
||||||
|
|
||||||
attr_accessor :tag_list
|
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 :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 :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"} }
|
scope :next, lambda { |p,a| { :conditions => ["id > :id AND album_Id = :album ", { :id => p, :album => a } ], :limit => 1, :order => "id ASC"} }
|
||||||
|
@ -39,7 +41,7 @@ class Photo < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
def tag_list
|
def tag_list
|
||||||
return self.tags.find(:all, :order => 'title').map{ |t| t.title }.sort.join(" ")
|
return self.tags.order('title').map{ |t| t.title }.sort.join(" ")
|
||||||
end
|
end
|
||||||
|
|
||||||
def tag_list=(tags)
|
def tag_list=(tags)
|
||||||
|
@ -57,12 +59,16 @@ class Photo < ActiveRecord::Base
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def set_visible
|
||||||
|
update_attribute(:public, true) unless self.public
|
||||||
|
end
|
||||||
|
|
||||||
def set_title
|
def set_title
|
||||||
self.title = self.file.file.basename.titleize unless self.title
|
update_attribute(:title, self.attachment.file.basename.titleize) unless self.title
|
||||||
end
|
end
|
||||||
|
|
||||||
def exif_read
|
def exif_read
|
||||||
photo = MiniExiftool.new(self.file.file.file)
|
photo = MiniExiftool.new(self.attachment.file.file)
|
||||||
self.longitude = photo.GPSLongitude if self.longitude.nil?
|
self.longitude = photo.GPSLongitude if self.longitude.nil?
|
||||||
self.latitude = photo.GPSLatitude if self.latitude.nil?
|
self.latitude = photo.GPSLatitude if self.latitude.nil?
|
||||||
self.title = photo.DocumentName if self.title.nil?
|
self.title = photo.DocumentName if self.title.nil?
|
||||||
|
@ -72,7 +78,7 @@ class Photo < ActiveRecord::Base
|
||||||
|
|
||||||
def exif_write
|
def exif_write
|
||||||
# should only write if tags are changed as images can be large and thus ExifTool will take a while to write to the file
|
# should only write if tags are changed as images can be large and thus ExifTool will take a while to write to the file
|
||||||
photo = MiniExiftool.new(self.file.file.file)
|
photo = MiniExiftool.new(self.attachment.file.file)
|
||||||
photo.GPSLongitude = self.longitude
|
photo.GPSLongitude = self.longitude
|
||||||
photo.GPSLatitude = self.latitude
|
photo.GPSLatitude = self.latitude
|
||||||
photo.DocumentName = self.title
|
photo.DocumentName = self.title
|
||||||
|
|
7
app/models/rate.rb
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
class Rate < ActiveRecord::Base
|
||||||
|
belongs_to :rater, :class_name => "User"
|
||||||
|
belongs_to :rateable, :polymorphic => true
|
||||||
|
validates_numericality_of :stars, :minimum => 1
|
||||||
|
|
||||||
|
attr_accessible :rate, :dimension
|
||||||
|
end
|
|
@ -1,12 +1,5 @@
|
||||||
class Role < ActiveRecord::Base
|
class Role < ActiveRecord::Base
|
||||||
has_many :role_memberships, :as => :roleable, :dependent => :destroy
|
attr_accessible :name
|
||||||
has_many :roles, :through => :role_memberships, :source => :role
|
|
||||||
|
|
||||||
has_many :roleables, :class_name => "RoleMembership", :foreign_key => "role_id", :dependent => :destroy
|
has_and_belongs_to_many :users
|
||||||
has_many :subroles, :through => :roleables, :source => :roleable, :source_type => 'Role'
|
|
||||||
has_many :users, :through => :roleables, :source => :roleable, :source_type => 'User'
|
|
||||||
|
|
||||||
validates :name, :presence => true, :uniqueness => true
|
|
||||||
|
|
||||||
acts_as_permissible
|
|
||||||
end
|
end
|
|
@ -1,36 +0,0 @@
|
||||||
class RoleMembership < ActiveRecord::Base
|
|
||||||
belongs_to :user
|
|
||||||
belongs_to :role
|
|
||||||
belongs_to :roleable, :polymorphic => true
|
|
||||||
|
|
||||||
validates_presence_of :roleable_id, :roleable_type, :role_id
|
|
||||||
validates_uniqueness_of :role_id, :scope => [:roleable_id, :roleable_type]
|
|
||||||
validates_numericality_of :roleable_id, :role_id
|
|
||||||
validates_format_of :roleable_type, :with => /^[A-Z]{1}[a-z0-9]+([A-Z]{1}[a-z0-9]+)*$/
|
|
||||||
validate :role_does_not_belong_to_itself_in_a_loop
|
|
||||||
|
|
||||||
protected
|
|
||||||
def role_does_not_belong_to_itself_in_a_loop
|
|
||||||
if roleable_type == "Role"
|
|
||||||
if role_id == roleable_id
|
|
||||||
errors.add_to_base("A role cannot belong to itself.")
|
|
||||||
else
|
|
||||||
if belongs_to_itself_through_other?(roleable_id, role_id)
|
|
||||||
errors.add_to_base("A role cannot belong to a role which belongs to it.")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def belongs_to_itself_through_other?(original_roleable_id, current_role_id)
|
|
||||||
if self.class.find(:first, :select => "id", :conditions => ["roleable_id=? AND roleable_type='Role' AND role_id=?",current_role_id,original_roleable_id])
|
|
||||||
return true
|
|
||||||
else
|
|
||||||
memberships = self.class.find(:all, :select => "role_id", :conditions => ["roleable_id=? AND roleable_type='Role'",current_role_id])
|
|
||||||
if memberships.any? {|membership| belongs_to_itself_through_other?(original_roleable_id,membership.role_id)}
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
end
|
|
7
app/models/secret_link_observer.rb
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
class SecretLinkObserver < ActiveRecord::Observer
|
||||||
|
observe :collection, :album, :photo
|
||||||
|
|
||||||
|
def before_create(record)
|
||||||
|
record.url = ::SecureRandom.hex(16)
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,4 +1,45 @@
|
||||||
class User < ActiveRecord::Base
|
class User < ActiveRecord::Base
|
||||||
acts_as_authentic
|
devise :database_authenticatable, :registerable, :confirmable, :token_authenticatable,
|
||||||
acts_as_permissible
|
:recoverable, :rememberable, :trackable, :validatable, :omniauthable, :lockable
|
||||||
|
|
||||||
|
attr_accessible :id, :name, :second_name, :surname, :email, :password, :password_confirmation, :remember_me, :userpic
|
||||||
|
|
||||||
|
ajaxful_rater
|
||||||
|
|
||||||
|
mount_uploader :userpic, UserpicUploader
|
||||||
|
|
||||||
|
has_and_belongs_to_many :roles
|
||||||
|
|
||||||
|
def small_url
|
||||||
|
userpic.url(:small)
|
||||||
|
end
|
||||||
|
|
||||||
|
alias_method :avatar, :small_url
|
||||||
|
|
||||||
|
def thumb_url
|
||||||
|
userpic.url(:thumb)
|
||||||
|
end
|
||||||
|
|
||||||
|
def original_url
|
||||||
|
userpic.url(:original)
|
||||||
|
end
|
||||||
|
|
||||||
|
##########################################################
|
||||||
|
# This hack is needed to access the current user in models.
|
||||||
|
#See http://rails-bestpractices.com/posts/47-fetch-current-user-in-models
|
||||||
|
def self.current
|
||||||
|
Thread.current[:user]
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.current=(user)
|
||||||
|
Thread.current[:user] = user
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.admin_created?
|
||||||
|
User.admin.count > 0
|
||||||
|
end
|
||||||
|
|
||||||
|
def has_role?(role_in_question)
|
||||||
|
roles.any? { |role| role.name == role_in_question.to_s }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
class UserSession < Authlogic::Session::Base
|
|
||||||
# configuration here, see documentation for sub modules of Authlogic::Session
|
|
||||||
def to_key
|
|
||||||
new_record? ? nil : [ self.send(self.class.primary_key) ]
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -2,6 +2,10 @@
|
||||||
|
|
||||||
class FileUploader < CarrierWave::Uploader::Base
|
class FileUploader < CarrierWave::Uploader::Base
|
||||||
|
|
||||||
|
@@generate_file_name = ''
|
||||||
|
@@original_filename = ''
|
||||||
|
|
||||||
|
|
||||||
# Include RMagick or ImageScience support
|
# Include RMagick or ImageScience support
|
||||||
# include CarrierWave::RMagick
|
# include CarrierWave::RMagick
|
||||||
# include CarrierWave::ImageScience
|
# include CarrierWave::ImageScience
|
||||||
|
@ -21,7 +25,15 @@ class FileUploader < CarrierWave::Uploader::Base
|
||||||
# This is a sensible default for uploaders that are meant to be mounted:
|
# This is a sensible default for uploaders that are meant to be mounted:
|
||||||
def store_dir
|
def store_dir
|
||||||
#{}"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
|
#{}"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
|
||||||
ENV['STORAGE_PATH'] + "/files/#{model.album.path}"
|
ENV['STORAGE_PATH'] + "/files/#{model.album.path}/#{model.id}"
|
||||||
|
end
|
||||||
|
|
||||||
|
def filename
|
||||||
|
unless @@original_filename == original_filename
|
||||||
|
@@original_filename = original_filename
|
||||||
|
@@generate_file_name = "#{::SecureRandom.hex(8)}#{File.extname(original_filename).downcase}" if original_filename
|
||||||
|
end
|
||||||
|
@@generate_file_name
|
||||||
end
|
end
|
||||||
|
|
||||||
# Provide a default URL as a default if there hasn't been a file uploaded
|
# Provide a default URL as a default if there hasn't been a file uploaded
|
||||||
|
@ -37,40 +49,50 @@ class FileUploader < CarrierWave::Uploader::Base
|
||||||
# end
|
# end
|
||||||
|
|
||||||
# Create different versions of your uploaded files
|
# Create different versions of your uploaded files
|
||||||
version :collection do
|
version :thumb do
|
||||||
process :resize_to_fill => [200, 200]
|
process :resize_to_fill => [260, 180]
|
||||||
|
|
||||||
def store_dir
|
def store_dir
|
||||||
ENV['STORAGE_PATH'] + "/thumbs/#{model.album.path}"
|
ENV['STORAGE_PATH'] + "/thumbs/#{model.album.path}/#{model.id}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
version :album do
|
|
||||||
process :resize_to_fill => [100, 100]
|
|
||||||
|
######################################################################################################################
|
||||||
|
# Note
|
||||||
|
# The default grid system provided in Bootstrap utilizes 12 columns that
|
||||||
|
# render out at widths of 724px, 940px (default without responsive CSS included), and 1170px.
|
||||||
|
# Below 767px viewports, the columns become fluid and stack vertically.
|
||||||
|
|
||||||
|
version :middle do
|
||||||
|
process :resize_to_fill => [742, 500]
|
||||||
|
|
||||||
def store_dir
|
def store_dir
|
||||||
ENV['STORAGE_PATH'] + "/thumbs/#{model.album.path}"
|
ENV['STORAGE_PATH'] + "/thumbs/#{model.album.path}/#{model.id}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
version :preview do
|
|
||||||
process :resize_to_fit => [210, 210]
|
version :large do
|
||||||
|
process :resize_to_fill => [940, 600]
|
||||||
|
|
||||||
def store_dir
|
def store_dir
|
||||||
ENV['STORAGE_PATH'] + "/thumbs/#{model.album.path}"
|
ENV['STORAGE_PATH'] + "/thumbs/#{model.album.path}/#{model.id}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
version :single do
|
|
||||||
process :resize_to_limit => [950, 950]
|
version :largest do
|
||||||
|
process :resize_to_fill => [1170, 600]
|
||||||
|
|
||||||
def store_dir
|
def store_dir
|
||||||
ENV['STORAGE_PATH'] + "/thumbs/#{model.album.path}"
|
ENV['STORAGE_PATH'] + "/thumbs/#{model.album.path}/#{model.id}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
######################################################################################################################
|
||||||
|
|
||||||
|
|
||||||
# Add a white list of extensions which are allowed to be uploaded,
|
# Add a white list of extensions which are allowed to be uploaded,
|
||||||
# for images you might use something like this:
|
# for images you might use something like this:
|
||||||
def extension_white_list
|
def extension_white_list
|
||||||
%w(jpg jpeg gif png bmp tiff)
|
%w(jpg jpeg gif png bmp tiff)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Override the filename of the uploaded files
|
|
||||||
# def filename
|
|
||||||
# "something.jpg" if original_filename
|
|
||||||
# end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
28
app/uploaders/userpic_uploader.rb
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
class UserpicUploader < CarrierWave::Uploader::Base
|
||||||
|
include CarrierWave::MiniMagick
|
||||||
|
|
||||||
|
def store_dir
|
||||||
|
"#{ENV['STORAGE_PATH']}/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}/original"
|
||||||
|
end
|
||||||
|
|
||||||
|
def filename
|
||||||
|
"#{::SecureRandom.hex(8)}#{File.extname(original_filename).downcase}" if original_filename
|
||||||
|
end
|
||||||
|
|
||||||
|
version :mini do
|
||||||
|
process :resize_to_fit => [50, 50]
|
||||||
|
|
||||||
|
def store_dir
|
||||||
|
"#{ENV['STORAGE_PATH']}/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}/mini"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
version :small do
|
||||||
|
process :resize_to_fit => [100, 100]
|
||||||
|
|
||||||
|
def store_dir
|
||||||
|
"#{ENV['STORAGE_PATH']}/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}/small"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -1,12 +0,0 @@
|
||||||
<%= form.label :name, 'Display name' %><br />
|
|
||||||
<%= form.text_field :name %><br />
|
|
||||||
<br />
|
|
||||||
<%= form.label :email %><br />
|
|
||||||
<%= form.text_field :email %><br />
|
|
||||||
<br/>
|
|
||||||
<%= form.label :password %><br />
|
|
||||||
<%= form.password_field :password %><br />
|
|
||||||
<br/>
|
|
||||||
<%= form.label :password_confirmation %><br />
|
|
||||||
<%= form.password_field :password_confirmation %><br />
|
|
||||||
<br/>
|
|
|
@ -1,15 +0,0 @@
|
||||||
<h1>Edit Account</h1>
|
|
||||||
|
|
||||||
<%= form_for @user do |f| %>
|
|
||||||
<%= f.error_messages %>
|
|
||||||
<%= render :partial => "form", :object => f %>
|
|
||||||
<%= f.submit "Update" %>
|
|
||||||
<% end %>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<%= content_for :action_links do %>
|
|
||||||
<%= link_to("Delete user", { :action => "destroy", :id => @user },
|
|
||||||
:confirm => "Are you sure you want to delete this user?",
|
|
||||||
:method => :delete) %>
|
|
||||||
<% end %>
|
|
|
@ -1,7 +0,0 @@
|
||||||
<% for user in @users %>
|
|
||||||
<h2><%= link_to user.name || user.email , user %></h2>
|
|
||||||
<% end %>
|
|
||||||
|
|
||||||
<%= content_for :action_links do %>
|
|
||||||
<%= link_to "New user", new_user_path %>
|
|
||||||
<% end %>
|
|
|
@ -1,7 +0,0 @@
|
||||||
<h1>Register</h1>
|
|
||||||
|
|
||||||
<%= form_for @user do |f| %>
|
|
||||||
<%= f.error_messages %>
|
|
||||||
<%= render :partial => "form", :object => f %>
|
|
||||||
<%= f.submit "Register" %>
|
|
||||||
<% end %>
|
|
|
@ -1,45 +0,0 @@
|
||||||
<p>
|
|
||||||
<b>Name:</b>
|
|
||||||
<%=h @user.name %>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<b>Email:</b>
|
|
||||||
<%=h @user.email %>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<b>Login count:</b>
|
|
||||||
<%=h @user.login_count %>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<b>Last request at:</b>
|
|
||||||
<%=h @user.last_request_at %>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<b>Last login at:</b>
|
|
||||||
<%=h @user.last_login_at %>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<b>Current login at:</b>
|
|
||||||
<%=h @user.current_login_at %>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<b>Last login ip:</b>
|
|
||||||
<%=h @user.last_login_ip %>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<b>Current login ip:</b>
|
|
||||||
<%=h @user.current_login_ip %>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
|
|
||||||
<%= content_for :action_links do %>
|
|
||||||
<%= link_to 'Edit', edit_user_path(@user) %>
|
|
||||||
<% end %>
|
|
|
@ -5,26 +5,59 @@
|
||||||
|
|
||||||
<div id="map_canvas"></div>
|
<div id="map_canvas"></div>
|
||||||
|
|
||||||
<%= hidden_field_tag :all_tags, "'#{Tag.find(:all).map { |tag| tag.title }.join('\',\'')}'" %>
|
<fieldset>
|
||||||
|
<%= hidden_field_tag :all_tags, "'#{Tag.all.map { |tag| tag.title }.join('\',\'')}'" %>
|
||||||
<%= hidden_field_tag :collection_id, params[:collection_id] %>
|
<%= hidden_field_tag :collection_id, params[:collection_id] %>
|
||||||
<%= form.hidden_field :id %>
|
<%= form.hidden_field :id %>
|
||||||
<%= form.hidden_field :latitude %>
|
<%= form.hidden_field :latitude %>
|
||||||
<%= form.hidden_field :longitude %>
|
<%= form.hidden_field :longitude %>
|
||||||
|
|
||||||
<%= form.label :title, :Title, {:class => 'big'} %><br />
|
<div class="control-group">
|
||||||
<%= form.text_field :title, {:class => 'big'} %><br />
|
<%= form.label :title, t('activerecord.models.album.attributes.title'), {:class => 'control-label'} %>
|
||||||
|
<div class="controls">
|
||||||
|
<%= form.text_field :title, {:class => 'input-xlarge'} %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<%= form.label :description %><br />
|
<div class="control-group">
|
||||||
<%= form.text_area :description %><br />
|
<%= form.label :description, t('activerecord.models.album.attributes.description'), {:class => 'control-label'} %>
|
||||||
|
<div class="controls">
|
||||||
|
<%= form.text_area :description, {:class => 'input-xlarge', :rows => 5} %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<%= form.label :address %><br />
|
<div class="control-group">
|
||||||
<%= form.text_area :address, { :rows => 3} %><br />
|
<%= form.label :public, t('activerecord.models.album.attributes.visible'), {:class => 'control-label'} %>
|
||||||
|
<div class="controls">
|
||||||
|
<label class="checkbox">
|
||||||
|
<%= check_box 'collection', :public %> <%= t(:make_visible_for_all) %>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<%= form.label :note %><br />
|
<div class="control-group">
|
||||||
<%= form.text_area :note %><br />
|
<%= form.label :address, t('activerecord.models.album.attributes.address'), {:class => 'control-label'} %>
|
||||||
|
<div class="controls">
|
||||||
|
<%= form.text_area :address, {:class => 'input-xlarge', :rows => 5} %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="control-group">
|
||||||
|
<%= form.label :note, t('activerecord.models.album.attributes.note'), {:class => 'control-label'} %>
|
||||||
|
<div class="controls">
|
||||||
|
<%= form.text_area :note, {:class => 'input-xlarge', :rows => 5} %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="control-group">
|
||||||
|
<%= form.label :tags, t('activerecord.models.album.attributes.tags'), {:class => 'control-label'} %>
|
||||||
|
<div class="controls">
|
||||||
|
<%= form.text_field :tags, {:class => 'input-xlarge', :autocomplete => "off", :class => 'tag_list', :value => (@album.tags.map{|tag|tag.title}.join(" ") unless @album.tags.nil?) } %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<%= form.label :tags %><br />
|
|
||||||
<%= form.text_field :tags, { :autocomplete => "off", :class => 'tag_list', :value => (@album.tags.map{|tag|tag.title}.join(" ") unless @album.tags.nil?) } %><br />
|
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
Contains: <%= @album.photos.count %> photos<br/>
|
Contains: <%= @album.photos.count %> photos<br/>
|
||||||
|
</fieldset>
|
28
app/views/albums/_row_collections.html.erb
Normal 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>
|
|
@ -1,18 +1,10 @@
|
||||||
<% for album in @albums %>
|
<%= paginate @albums %>
|
||||||
<div class="row">
|
<%= render 'row_collections' %>
|
||||||
<div class="title">
|
<%= paginate @albums %>
|
||||||
<%= 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 %>
|
|
||||||
|
|
||||||
<%= content_for :action_links do %>
|
<%= content_for :action_links do %>
|
||||||
<%= link_to "Show just the photos tagged with #{params[:q]}", photos_path(:q => params[:q]) if params[:q] %>
|
<%= link_to "Show just the photos tagged with #{params[:q]}", photos_path(:q => params[:q]) if params[:q] %>
|
||||||
<% if has_role?("admin") %>
|
<% if current_user and current_user.has_role?("admin") %>
|
||||||
<%= " | " if params[:q] %>
|
<%= " | " if params[:q] %>
|
||||||
<%= link_to "New album", new_album_path() %>
|
<%= link_to "New album", new_album_path() %>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
<h1>New Album</h1>
|
<%= form_for @album, :html => {:class => 'form-horizontal'} do |f| %>
|
||||||
|
<legend><%= t('activerecord.actions.new', :model => I18n.t('activerecord.models.album.one')) %></legend>
|
||||||
<%= form_for @album do |f| %>
|
|
||||||
<%= f.error_messages %>
|
<%= f.error_messages %>
|
||||||
<%= render :partial => "form", :object => f %>
|
<%= render :partial => "form", :object => f %>
|
||||||
<%= f.submit "Create" %>
|
<div class="form-actions">
|
||||||
|
<%= f.button "Create", :class => 'btn btn-primary btn-large' %>
|
||||||
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
|
@ -1,16 +1,5 @@
|
||||||
<h2><%= @album.title %></h2>
|
<h2><%= @album.title %></h2>
|
||||||
|
<%= render :partial => 'photos/row_collections' %>
|
||||||
<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.file.preview.url ), [@album.collections.first, @album, photo] %></td>
|
|
||||||
<% if count / 4.0 == (count / 4.0).to_i %></tr><% end %>
|
|
||||||
<% end %>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<p><%= @album.description %></p>
|
<p><%= @album.description %></p>
|
||||||
|
|
||||||
|
@ -24,36 +13,34 @@
|
||||||
|
|
||||||
<% unless @album.collections.empty? %>
|
<% unless @album.collections.empty? %>
|
||||||
<p>Part of:
|
<p>Part of:
|
||||||
<% for collection in @album.collections.find(:all, :order => 'title') %>
|
<% for collection in @album.collections.order('title') %>
|
||||||
<%= link_to collection.title, collection_path(collection) %>
|
<%= link_to collection.title, collection_path(collection) %>
|
||||||
<% end %>
|
<% end %>
|
||||||
</p>
|
</p>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
|
|
||||||
<% if has_role?("admin") %>
|
<% if current_user and current_user.has_role?("admin") %>
|
||||||
<p><%= @album.address %></p>
|
<p><%= @album.address %></p>
|
||||||
<% end %>
|
|
||||||
<% if has_role?("admin") %>
|
|
||||||
<p><%= @album.note %></p>
|
<p><%= @album.note %></p>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<%= content_for :action_links do %>
|
<%= content_for :action_links do %>
|
||||||
<% if has_role?("admin") %>
|
<% if current_user and current_user.has_role?("admin") %>
|
||||||
<% if params[:collection_id] %>
|
<% if params[:collection_id] %>
|
||||||
<%= link_to "PDF", collection_album_path(params[:collection_id],@album, :format => 'pdf') %> |
|
<li><%= link_to "PDF", collection_album_path(params[:collection_id], @album, :format => 'pdf') %></li>
|
||||||
<%= link_to "Edit album", edit_collection_album_path(params[:collection_id],@album) %> |
|
<li><%= link_to "Edit album", edit_collection_album_path(params[:collection_id], @album) %></li>
|
||||||
<%= link_to "Edit all photos", edit_multiple_collection_album_photos_path(params[:collection_id],@album) %> |
|
<li><%= link_to "Edit all photos", edit_multiple_collection_album_photos_path(params[:collection_id], @album) %></li>
|
||||||
<%= link_to "Edit untouched photos", untouched_collection_album_photos_path(params[:collection_id], @album) %> |
|
<li><%= link_to "Edit untouched photos", untouched_collection_album_photos_path(params[:collection_id], @album) %></li>
|
||||||
<%= link_to "Add photos", upload_collection_album_photos_path(params[:collection_id], @album) %>
|
<li><%= link_to "Add photos", upload_collection_album_photos_path(params[:collection_id], @album) %></li>
|
||||||
<% else %>
|
<% else %>
|
||||||
<%= link_to "PDF", album_path(@album, :format => 'pdf') %> |
|
<li><%= link_to "PDF", album_path(@album, :format => 'pdf') %></li>
|
||||||
<%= link_to "Edit album", edit_album_path(@album) %> |
|
<li><%= link_to "Edit album", edit_album_path(@album) %></li>
|
||||||
<%= link_to "Edit all photos", edit_multiple_album_photos_path(@album) %> |
|
<li><%= link_to "Edit all photos", edit_multiple_album_photos_path(@album) %></li>
|
||||||
<%= link_to "Edit untouched photos", untouched_album_photos_path(@album) %> |
|
<li><%= link_to "Edit untouched photos", untouched_album_photos_path(@album) %></li>
|
||||||
<%= link_to "Add photos", upload_album_photos_path(@album) %>
|
<li><%= link_to "Add photos", upload_album_photos_path(@album) %></li>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
|
@ -1,29 +1,41 @@
|
||||||
<%= form.label :title, :Title, {:class => 'big'} %><br />
|
<fieldset>
|
||||||
<%= form.text_field :title, {:class => 'big'} %><br />
|
<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 />
|
<div class="control-group">
|
||||||
<%= form.text_area :description %><br />
|
<%= 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>
|
||||||
|
|
||||||
|
<div class="control-group">
|
||||||
|
<%= form.label :public, t('activerecord.models.collection.attributes.visible'), {:class => 'control-label'} %>
|
||||||
|
<div class="controls">
|
||||||
|
<label class="checkbox">
|
||||||
|
<%= check_box 'collection', :public %> <%= t(:make_visible_for_all) %>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<% unless @collection.albums.empty? %>
|
<% unless @collection.albums.empty? %>
|
||||||
<%= form.label :albums %><br />
|
<%= form.label :albums %>
|
||||||
<div id="collection_albums">
|
<% @collection.albums.each do |album| %>
|
||||||
<% for album in @collection.albums %>
|
|
||||||
<%= form.fields_for :album_list do |album_fields| %>
|
<%= form.fields_for :album_list do |album_fields| %>
|
||||||
<span>
|
|
||||||
<%= image_tag "delete-24x24.png", :class => "delete", :alt => "Delete" -%>
|
<%= image_tag "delete-24x24.png", :class => "delete", :alt => "Delete" -%>
|
||||||
|
|
||||||
<% if album.photos.empty? %>
|
<% if album.photos.empty? %>
|
||||||
<%= album.title %>
|
<%= album.title %>
|
||||||
<% else %>
|
<% else %>
|
||||||
<%= image_tag album.photos.first.file.album.url, :alt => album.title %>
|
<%= image_tag album.photos.first.attachment.thumb.url, :alt => album.title %>
|
||||||
<% end %>
|
<% end %>
|
||||||
<%= album_fields.hidden_field album.id %>
|
<%= album_fields.hidden_field album.id %>
|
||||||
</span>
|
|
||||||
<% end %>
|
<% end %>
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
|
||||||
|
|
||||||
<p class="clear">
|
|
||||||
<%
|
<%
|
||||||
grouped_options = [
|
grouped_options = [
|
||||||
['Available albums', [['Choose album to add', '']]],
|
['Available albums', [['Choose album to add', '']]],
|
||||||
|
@ -33,6 +45,5 @@ grouped_options = [
|
||||||
grouped_options_for_select(grouped_options)
|
grouped_options_for_select(grouped_options)
|
||||||
%>
|
%>
|
||||||
<%= select_tag 'available_albums', grouped_options_for_select(grouped_options) %>
|
<%= select_tag 'available_albums', grouped_options_for_select(grouped_options) %>
|
||||||
</p>
|
|
||||||
|
|
||||||
<% end %>
|
<% end %>
|
||||||
|
</fieldset>
|
29
app/views/collections/_row_collections.html.erb
Normal 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>
|
|
@ -1,14 +1,6 @@
|
||||||
<div id="multipleimages">
|
<h1><%= t('activerecord.models.collection.pluralize') %></h1>
|
||||||
<% for collection in @collections %>
|
<%= paginate @collections %>
|
||||||
<div class="thumb">
|
<%= render 'row_collections' %>
|
||||||
<h3><%= link_to collection.title, collection %></h3>
|
<%= paginate @collections %>
|
||||||
<%= link_to (image_tag collection.albums.find(:first).photos.first.file.collection.url ), collection_path(collection) unless collection.albums.empty? || collection.albums.find(:first).photos.empty? %>
|
|
||||||
</div>
|
|
||||||
<% end %>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<%= content_for :action_links do %>
|
|
||||||
<% if has_role?("admin") %>
|
|
||||||
<%= link_to "New collection", new_collection_path %>
|
|
||||||
<% end %>
|
|
||||||
<% end %>
|
|
|
@ -1,7 +1,8 @@
|
||||||
<h1>New collection</h1>
|
<%= form_for @collection, :html => {:class => 'form-horizontal'} do |f| %>
|
||||||
|
<legend><%= t('activerecord.actions.new', :model => I18n.t('activerecord.models.collection.one')) %></legend>
|
||||||
<%= form_for @collection do |f| %>
|
|
||||||
<%= f.error_messages %>
|
<%= f.error_messages %>
|
||||||
<%= render :partial => "form", :object => f %>
|
<%= render :partial => "form", :object => f %>
|
||||||
<%= f.submit "Create" %>
|
<div class="form-actions">
|
||||||
|
<%= f.button "Create", :class => 'btn btn-primary btn-large' %>
|
||||||
|
</div>
|
||||||
<% end %>
|
<% end %>
|
|
@ -1,22 +1,12 @@
|
||||||
<h2><%= h @collection.title %></h2>
|
<h2><%= @collection.title %></h2>
|
||||||
<p><%= h @collection.description %></p>
|
<p><%= @collection.description %></p>
|
||||||
|
|
||||||
<% for album in @albums %>
|
<%= render :partial => 'albums/row_collections' %>
|
||||||
<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 %>
|
|
||||||
|
|
||||||
<%= content_for :action_links do %>
|
<%= content_for :action_links do %>
|
||||||
<% if has_role?("admin") %>
|
<% if current_user and current_user.has_role?("admin") %>
|
||||||
<%= link_to "PDF", collection_path(@collection, :format => 'pdf') %> |
|
<li><%= link_to "PDF", collection_path(@collection, :format => 'pdf') %></li>
|
||||||
<%= link_to "Edit collection", edit_collection_path(@collection) %> |
|
<li><%= link_to "Edit collection", edit_collection_path(@collection) %></li>
|
||||||
<%= link_to "New album", new_collection_album_path(@collection) %>
|
<li><%= link_to "New album", new_collection_album_path(@collection) %></li>
|
||||||
<% end %>
|
<% end %>
|
||||||
<% end %>
|
<% end %>
|
24
app/views/devise/_links.erb
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
<%- if controller_name != 'sessions' %>
|
||||||
|
<%= link_to t('devise.sign_in'), login_path %><br />
|
||||||
|
<% end -%>
|
||||||
|
|
||||||
|
<%- if devise_mapping.registerable? && controller_name != 'registrations' %>
|
||||||
|
<%= link_to t('devise.sign_up'), signup_path %><br />
|
||||||
|
<% end -%>
|
||||||
|
|
||||||
|
<%- if devise_mapping.recoverable? && controller_name != 'passwords' %>
|
||||||
|
<%= link_to t('devise.forgot_your_password'), new_password_path(resource_name) %><br />
|
||||||
|
<% end -%>
|
||||||
|
|
||||||
|
<%- if devise_mapping.confirmable? && controller_name != 'confirmations' %>
|
||||||
|
<%= link_to t('devise.send_confirmation_instructions'), new_confirmation_path(resource_name) %><br />
|
||||||
|
<% end -%>
|
||||||
|
|
||||||
|
<%- if devise_mapping.lockable? && resource_class.unlock_strategy_enabled?(:email) && controller_name != 'unlocks' %>
|
||||||
|
<%= link_to t('devise.send_unlock_instructions'), new_unlock_path(resource_name) %><br />
|
||||||
|
<% end -%>
|
||||||
|
<%- if devise_mapping.omniauthable? %>
|
||||||
|
<%- resource_class.omniauth_providers.each do |provider| %>
|
||||||
|
<%= link_to t('devise.sign_in_with', :provider => provider.to_s.titleize), omniauth_authorize_path(resource_name, provider) %><br />
|
||||||
|
<% end -%>
|
||||||
|
<% end -%>
|
12
app/views/devise/confirmations/new.html.erb
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<h2>Resend confirmation instructions</h2>
|
||||||
|
|
||||||
|
<%= form_for(resource, :as => resource_name, :url => confirmation_path(resource_name), :html => { :method => :post }) do |f| %>
|
||||||
|
<%= devise_error_messages! %>
|
||||||
|
|
||||||
|
<div><%= f.label :email %><br />
|
||||||
|
<%= f.email_field :email %></div>
|
||||||
|
|
||||||
|
<div><%= f.submit "Resend confirmation instructions" %></div>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<%= render "links" %>
|
|
@ -0,0 +1,5 @@
|
||||||
|
<p>Welcome <%= @resource.email %>!</p>
|
||||||
|
|
||||||
|
<p>You can confirm your account email through the link below:</p>
|
||||||
|
|
||||||
|
<p><%= link_to 'Confirm my account', confirmation_url(@resource, :confirmation_token => @resource.confirmation_token) %></p>
|
|
@ -0,0 +1,8 @@
|
||||||
|
<p>Hello <%= @resource.email %>!</p>
|
||||||
|
|
||||||
|
<p>Someone has requested a link to change your password, and you can do this through the link below.</p>
|
||||||
|
|
||||||
|
<p><%= link_to 'Change my password', edit_password_url(@resource, :reset_password_token => @resource.reset_password_token) %></p>
|
||||||
|
|
||||||
|
<p>If you didn't request this, please ignore this email.</p>
|
||||||
|
<p>Your password won't change until you access the link above and create a new one.</p>
|
7
app/views/devise/mailer/unlock_instructions.html.erb
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
<p>Hello <%= @resource.email %>!</p>
|
||||||
|
|
||||||
|
<p>Your account has been locked due to an excessive amount of unsuccessful sign in attempts.</p>
|
||||||
|
|
||||||
|
<p>Click the link below to unlock your account:</p>
|
||||||
|
|
||||||
|
<p><%= link_to 'Unlock my account', unlock_url(@resource, :unlock_token => @resource.unlock_token) %></p>
|
16
app/views/devise/passwords/edit.html.erb
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
<h2>Change your password</h2>
|
||||||
|
|
||||||
|
<%= form_for(resource, :as => resource_name, :url => password_path(resource_name), :html => { :method => :put }) do |f| %>
|
||||||
|
<%= devise_error_messages! %>
|
||||||
|
<%= f.hidden_field :reset_password_token %>
|
||||||
|
|
||||||
|
<div><%= f.label :password, "New password" %><br />
|
||||||
|
<%= f.password_field :password %></div>
|
||||||
|
|
||||||
|
<div><%= f.label :password_confirmation, "Confirm new password" %><br />
|
||||||
|
<%= f.password_field :password_confirmation %></div>
|
||||||
|
|
||||||
|
<div><%= f.submit "Change my password" %></div>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<%= render "links" %>
|
12
app/views/devise/passwords/new.html.erb
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<h2>Forgot your password?</h2>
|
||||||
|
|
||||||
|
<%= form_for(resource, :as => resource_name, :url => password_path(resource_name), :html => { :method => :post }) do |f| %>
|
||||||
|
<%= devise_error_messages! %>
|
||||||
|
|
||||||
|
<div><%= f.label :email %><br />
|
||||||
|
<%= f.email_field :email %></div>
|
||||||
|
|
||||||
|
<div><%= f.submit "Send me reset password instructions" %></div>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<%= render "links" %>
|
25
app/views/devise/registrations/edit.html.erb
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
<h2>Edit <%= resource_name.to_s.humanize %></h2>
|
||||||
|
|
||||||
|
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name), :html => { :method => :put }) do |f| %>
|
||||||
|
<%= devise_error_messages! %>
|
||||||
|
|
||||||
|
<div><%= f.label :email %><br />
|
||||||
|
<%= f.email_field :email %></div>
|
||||||
|
|
||||||
|
<div><%= f.label :password %> <i>(leave blank if you don't want to change it)</i><br />
|
||||||
|
<%= f.password_field :password, :autocomplete => "off" %></div>
|
||||||
|
|
||||||
|
<div><%= f.label :password_confirmation %><br />
|
||||||
|
<%= f.password_field :password_confirmation %></div>
|
||||||
|
|
||||||
|
<div><%= f.label :current_password %> <i>(we need your current password to confirm your changes)</i><br />
|
||||||
|
<%= f.password_field :current_password %></div>
|
||||||
|
|
||||||
|
<div><%= f.submit "Update" %></div>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<h3>Cancel my account</h3>
|
||||||
|
|
||||||
|
<p>Unhappy? <%= link_to "Cancel my account", registration_path(resource_name), :confirm => "Are you sure?", :method => :delete %>.</p>
|
||||||
|
|
||||||
|
<%= link_to "Back", :back %>
|
18
app/views/devise/registrations/new.html.erb
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
<h2>Sign up</h2>
|
||||||
|
|
||||||
|
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>
|
||||||
|
<%= devise_error_messages! %>
|
||||||
|
|
||||||
|
<div><%= f.label :email %><br />
|
||||||
|
<%= f.email_field :email %></div>
|
||||||
|
|
||||||
|
<div><%= f.label :password %><br />
|
||||||
|
<%= f.password_field :password %></div>
|
||||||
|
|
||||||
|
<div><%= f.label :password_confirmation %><br />
|
||||||
|
<%= f.password_field :password_confirmation %></div>
|
||||||
|
|
||||||
|
<div><%= f.submit "Sign up" %></div>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<%= render "links" %>
|
17
app/views/devise/sessions/new.html.erb
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
<h2><%= t("devise.sign_in") %></h2>
|
||||||
|
|
||||||
|
<%= form_for(resource, :as => resource_name, :url => session_path(resource_name)) do |f| %>
|
||||||
|
<div><%= f.label :email %><br />
|
||||||
|
<%= f.email_field :email %></div>
|
||||||
|
|
||||||
|
<div><%= f.label :password %><br />
|
||||||
|
<%= f.password_field :password %></div>
|
||||||
|
|
||||||
|
<% if devise_mapping.rememberable? -%>
|
||||||
|
<div><%= f.check_box :remember_me %> <%= f.label :remember_me %></div>
|
||||||
|
<% end -%>
|
||||||
|
|
||||||
|
<div><%= f.submit "Sign in" %></div>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<%= render "links" %>
|
12
app/views/devise/unlocks/new.html.erb
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<h2>Resend unlock instructions</h2>
|
||||||
|
|
||||||
|
<%= form_for(resource, :as => resource_name, :url => unlock_path(resource_name), :html => { :method => :post }) do |f| %>
|
||||||
|
<%= devise_error_messages! %>
|
||||||
|
|
||||||
|
<div><%= f.label :email %><br />
|
||||||
|
<%= f.email_field :email %></div>
|
||||||
|
|
||||||
|
<div><%= f.submit "Resend unlock instructions" %></div>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<%= render "links" %>
|
5
app/views/home/index.html.erb
Normal 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' %>
|
13
app/views/kaminari/_first_page.html.erb
Normal 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 %>
|
8
app/views/kaminari/_gap.html.erb
Normal 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>
|
13
app/views/kaminari/_last_page.html.erb
Normal 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 %>
|
13
app/views/kaminari/_next_page.html.erb
Normal 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 %>
|
12
app/views/kaminari/_page.html.erb
Normal 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>
|
25
app/views/kaminari/_paginator.html.erb
Normal 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 -%>
|
13
app/views/kaminari/_prev_page.html.erb
Normal 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 %>
|
|
@ -1,13 +1,7 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
<%= render :partial => 'shared/head' %>
|
||||||
<title><%= ENV['TITLE'] || "Photos" %></title>
|
|
||||||
<meta name="viewport" content="width=device-width">
|
|
||||||
<meta name="viewport" content="initial-scale=1.0">
|
|
||||||
<%= yield :head %>
|
|
||||||
<%= stylesheet_link_tag 'application' %>
|
|
||||||
<%= csrf_meta_tag %>
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="container">
|
<div id="container">
|
||||||
|
@ -43,7 +37,6 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<%= javascript_include_tag 'jquery-1.4.2.js', 'rails', 'balder' %>
|
|
||||||
<%= yield :javascript %>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
22
app/views/layouts/bootstrap.html.erb
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<%= render :partial => 'shared/head' %>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<%= render :partial => 'shared/nav_bar' %>
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="span12">
|
||||||
|
<%= render :partial => 'shared/notifications' %>
|
||||||
|
<%= render_breadcrumbs %>
|
||||||
|
<%= yield %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
<footer>
|
||||||
|
<p>© Photomix 2012</p>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -11,4 +11,4 @@
|
||||||
<%= form.label :description %><br />
|
<%= form.label :description %><br />
|
||||||
<%= form.text_area :description %><br />
|
<%= form.text_area :description %><br />
|
||||||
<br/>
|
<br/>
|
||||||
<p>On disk: ~/<%= @photo.file.path %></p>
|
<p>On disk: ~/<%= @photo.attachment.path %></p>
|
|
@ -1 +1 @@
|
||||||
<%= image_tag photo.file.single.url %><br/>
|
<%= image_tag photo.attachment.single.url %><br/>
|
22
app/views/photos/_row_collections.html.erb
Normal 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>
|
|
@ -1 +1 @@
|
||||||
<%= link_to (image_tag eval('photo.file.' + (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] %>
|
|
@ -1,6 +1,6 @@
|
||||||
<h1>Edit Photo</h1>
|
<h1>Edit Photo</h1>
|
||||||
|
|
||||||
<%= image_tag @photo.file.preview.url %>
|
<%= image_tag @photo.attachment.preview.url %>
|
||||||
|
|
||||||
<%= form_for @photo do |f| %>
|
<%= form_for @photo do |f| %>
|
||||||
<%= hidden_field_tag :collection_id, params[:collection_id] %>
|
<%= hidden_field_tag :collection_id, params[:collection_id] %>
|
||||||
|
|
|
@ -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 %>
|
<%= content_for :action_links do %>
|
||||||
<%= link_to "Show albums containing photos tagged with #{params[:q]}", albums_path(:q => params[:q]) if params[:q] %>
|
<%= link_to "Show albums containing photos tagged with #{params[:q]}", albums_path(:q => params[:q]) if params[:q] %>
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
<% end %>
|
<% end %>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<p><%= link_to_if @next, image_tag(@photo.file.single.url ), [ @photo.album.collections.first, @photo.album, @next] %></p>
|
<p><%= link_to_if @next, image_tag(@photo.attachment.single.url), [@photo.album.collections.first, @photo.album, @next] %></p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p><%= @photo.description %></p>
|
<p><%= @photo.description %></p>
|
||||||
|
@ -24,7 +24,7 @@
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<%= content_for :action_links do %>
|
<%= content_for :action_links do %>
|
||||||
<% if has_role?("admin") %>
|
<% if current_user and current_user.has_role?("admin") %>
|
||||||
<% if params[:collection_id] %>
|
<% if params[:collection_id] %>
|
||||||
<%= link_to "Edit photo", edit_collection_album_photo_path(params[:collection_id], params[:album_id], @photo) %>
|
<%= link_to "Edit photo", edit_collection_album_photo_path(params[:collection_id], params[:album_id], @photo) %>
|
||||||
<% else %>
|
<% else %>
|
||||||
|
|
|
@ -1,19 +1,13 @@
|
||||||
<%= content_for :javascript do %>
|
<%= content_for :javascript do %>
|
||||||
<style type="text/css">@import url(/javascripts/plupload/js/jquery.plupload.queue/css/jquery.plupload.queue.css);</style>
|
|
||||||
<%= javascript_include_tag "plupload/js/plupload.full.js" -%>
|
|
||||||
<%= javascript_include_tag "plupload/js/jquery.plupload.queue/jquery.plupload.queue.js" -%>
|
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
|
|
||||||
$("#uploader").pluploadQueue({
|
$("#uploader").pluploadQueue({
|
||||||
// General settings
|
|
||||||
runtimes:'flash,html5,browserplus,silverlight,gears',
|
runtimes:'flash,html5,browserplus,silverlight,gears',
|
||||||
url:'<%= photos_path %>',
|
url:'<%= photos_path %>',
|
||||||
max_file_size:'10mb',
|
max_file_size:'10mb',
|
||||||
multipart:true,
|
multipart:true,
|
||||||
multipart_params:{
|
multipart_params:{
|
||||||
'<%= get_session_key %>' : encodeURIComponent('<%= u cookies[get_session_key] %>'),
|
'<%= get_session_key %>':encodeURIComponent('<%= cookies[get_session_key] %>'),
|
||||||
'authenticity_token':'<%= form_authenticity_token %>',
|
'authenticity_token':'<%= form_authenticity_token %>',
|
||||||
'photo[album_id]':"<%= @album.id %>"
|
'photo[album_id]':"<%= @album.id %>"
|
||||||
},
|
},
|
||||||
|
@ -23,14 +17,14 @@ $(document).ready(function() {
|
||||||
|
|
||||||
// Specify what files to browse for
|
// Specify what files to browse for
|
||||||
filters:[
|
filters:[
|
||||||
{title : "Image files", extensions : "jpg,gif,png,bmp,jpeg,tif,tiff"}
|
{title:"Image files", extensions:"jpg,gif,png,bmp,jpeg,tif,tiff,JPG,GIF,PNG,BMP,JPEG,TIF,TIFF"}
|
||||||
],
|
],
|
||||||
|
|
||||||
// Flash settings
|
// Flash settings
|
||||||
flash_swf_url : '/javascripts/plupload/js/plupload.flash.swf',
|
flash_swf_url:'/assets/plupload.flash.swf',
|
||||||
|
|
||||||
// Silverlight settings
|
// Silverlight settings
|
||||||
silverlight_xap_url : '/javascripts/plupload/js/plupload.silverlight.xap',
|
silverlight_xap_url:'/assets/plupload.silverlight.xap',
|
||||||
|
|
||||||
// Post init events, bound after the internal events
|
// Post init events, bound after the internal events
|
||||||
init:{
|
init:{
|
||||||
|
@ -61,11 +55,9 @@ $(document).ready(function() {
|
||||||
if (uploader.total.uploaded == uploader.files.length)
|
if (uploader.total.uploaded == uploader.files.length)
|
||||||
$('form').submit();
|
$('form').submit();
|
||||||
});
|
});
|
||||||
|
|
||||||
uploader.start();
|
uploader.start();
|
||||||
} else
|
} else
|
||||||
alert('You must at least upload one file.');
|
alert('You must at least upload one file.');
|
||||||
|
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -77,8 +69,8 @@ $(document).ready(function() {
|
||||||
<div id="uploader">
|
<div id="uploader">
|
||||||
<p>You browser doesn't have Flash, Silverlight, Gears, BrowserPlus or HTML5 support.</p>
|
<p>You browser doesn't have Flash, Silverlight, Gears, BrowserPlus or HTML5 support.</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
<div id="thumbs"></div>
|
<div id="thumbs"></div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|
40
app/views/shared/_head.html.erb
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title><%= ENV['TITLE'] || "Photos" %></title>
|
||||||
|
<%= csrf_meta_tags %>
|
||||||
|
|
||||||
|
<!-- Le HTML5 shim, for IE6-8 support of HTML elements -->
|
||||||
|
<!--[if lt IE 9]>
|
||||||
|
<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' %>
|
||||||
|
|
||||||
|
<!-- For iPhone with high-resolution Retina display: -->
|
||||||
|
<!-- Size should be 114 x 114 pixels -->
|
||||||
|
<%#= favicon_link_tag 'images/apple-touch-icon-114x114-precomposed.png', :rel => 'apple-touch-icon-precomposed', :type => 'image/png', :sizes => '114x114' %>
|
||||||
|
|
||||||
|
<!-- For first- and second-generation iPad: -->
|
||||||
|
<!-- Size should be 72 x 72 pixels -->
|
||||||
|
<%#= favicon_link_tag 'images/apple-touch-icon-72x72-precomposed.png', :rel => 'apple-touch-icon-precomposed', :type => 'image/png', :sizes => '72x72' %>
|
||||||
|
|
||||||
|
<!-- For non-Retina iPhone, iPod Touch, and Android 2.1+ devices: -->
|
||||||
|
<!-- Size should be 57 x 57 pixels -->
|
||||||
|
<%#= favicon_link_tag 'images/apple-touch-icon-precomposed.png', :rel => 'apple-touch-icon-precomposed', :type => 'image/png' %>
|
||||||
|
|
||||||
|
<!-- For all other devices -->
|
||||||
|
<!-- Size should be 32 x 32 pixels -->
|
||||||
|
<%#= favicon_link_tag 'images/favicon.ico', :rel => 'shortcut icon' %>
|
||||||
|
|
||||||
|
<%= yield :javascript %>
|
||||||
|
<%= raw ajaxful_rating_style %>
|
||||||
|
<%= raw ajaxful_rating_script %>
|
40
app/views/shared/_home_slider.html.erb
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
<%= 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" %>
|
||||||
|
|
||||||
|
<%= javascript_include_tag "anythingslider/jquery.anythingslider.min" %>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
$(function () {
|
||||||
|
$('#home-slider').anythingSlider({
|
||||||
|
// theme:'metallic',
|
||||||
|
// expand:true,
|
||||||
|
//resizeContents: false,
|
||||||
|
autoPlay:false
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<div class="span12 slider-wrapper">
|
||||||
|
<ul id="home-slider">
|
||||||
|
<% @popular_photos.each do |photo| %>
|
||||||
|
<li><%= image_tag photo.attachment.largest.url %></li>
|
||||||
|
<% end %>
|
||||||
|
</ul>
|
||||||
|
</div>
|
24
app/views/shared/_nav_bar.html.erb
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
<div class="navbar navbar-fixed-top">
|
||||||
|
<div class="navbar-inner">
|
||||||
|
<div class="container">
|
||||||
|
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
|
||||||
|
<span class="icon-bar"></span>
|
||||||
|
<span class="icon-bar"></span>
|
||||||
|
<span class="icon-bar"></span>
|
||||||
|
</a>
|
||||||
|
<a class="brand" href="/">Photomix</a>
|
||||||
|
<div class="nav-collapse">
|
||||||
|
<ul class="nav">
|
||||||
|
<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-right">
|
||||||
|
<input type="text" placeholder="Search" class="search-query span2">
|
||||||
|
</form>
|
||||||
|
<%= render :partial => 'shared/user_links' %>
|
||||||
|
</div>
|
||||||
|
<!--/.nav-collapse -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
13
app/views/shared/_notifications.html.erb
Normal 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 %>
|
8
app/views/shared/_screen_resolution.html.erb
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
<a href="javascript:alert('Your screen resolution is '+screen.width+'x'+screen.height);">Click for your screen resolution</a>
|
||||||
|
<input type="hidden" id="resolution_screen" name="resolution_screen">
|
||||||
|
|
||||||
|
<%= content_for :action_links do %>
|
||||||
|
<% if current_user and current_user.has_role?("admin") %>
|
||||||
|
<%= link_to "New collection", new_collection_path %>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|