Compare commits
31 Commits
Author | SHA1 | Date |
---|---|---|
Denis Knauf | fe63f11068 | |
Denis Knauf | 309adafd48 | |
Alexander Negoda | 0af713b765 | |
Alexander Negoda | b05879afdc | |
Alexander Negoda | c526882f27 | |
Alexander Negoda | ef55c642d0 | |
Alexander Negoda | b185c08481 | |
Alexander Negoda | 68cd47abba | |
Alexander Negoda | 5f5b2eca86 | |
Alexander Negoda | a7722cf8d5 | |
Alexander Negoda | bf80a200f0 | |
Alexander Negoda | 5c131394aa | |
Alexander Negoda | 2469225cda | |
Alexander Negoda | 7caba3f464 | |
Alexander Negoda | 2042f17a3d | |
Alexander Negoda | 7e9754714a | |
Alexander Negoda | 954e3b68ae | |
Alexander Negoda | 0ab5ab468f | |
Alexander Negoda | b1ad108123 | |
Alexander Negoda | e59d11e1c9 | |
Alexander Negoda | ac9a8886de | |
Alexander Negoda | d996de1514 | |
Alexander Negoda | aedc18f834 | |
Alexander Negoda | 0b7628dc95 | |
Alexander Negoda | 3ae36b6689 | |
Espen Antonsen | b8a14725ee | |
Espen Antonsen | 9c0ef432d0 | |
Espen Antonsen | 1a2cbff99e | |
Espen Antonsen | 25c8c3b5cb | |
Espen Antonsen | bd431ab2e3 | |
Espen Antonsen | 0ed49f3021 |
|
@ -13,4 +13,7 @@ config/deploy
|
|||
Capfile
|
||||
public/thumbs
|
||||
public/uploads
|
||||
vendor/cache
|
||||
public/assets
|
||||
vendor/cache
|
||||
.idea
|
||||
.sass-cache
|
51
Gemfile
|
@ -1,23 +1,46 @@
|
|||
source 'http://rubygems.org'
|
||||
|
||||
gem 'rails', '3.2.3'
|
||||
|
||||
gem 'authlogic'
|
||||
|
||||
gem 'rails', '3.2.7'
|
||||
gem 'sqlite3'
|
||||
gem 'mime-types', :require => 'mime/types'
|
||||
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 'heroku'
|
||||
#gem 'pg'
|
||||
gem "devise_omniauth_engine", :git=>"git://github.com/greendog/devise_omniauth_engine.git"
|
||||
gem 'omniauth-twitter'
|
||||
gem 'omniauth-facebook'
|
||||
gem 'omniauth-openid'
|
||||
gem 'omniauth-google-apps'
|
||||
gem 'omniauth-vkontakte', :git => 'git://github.com/mamantoha/omniauth-vkontakte.git'
|
||||
gem 'cancan'
|
||||
|
||||
# -- Database
|
||||
# SQLite:
|
||||
#gem 'sqlite3-ruby'
|
||||
# MySQL:
|
||||
#gem 'mysql2'
|
||||
# PostgreSQL:
|
||||
gem 'pg'
|
||||
group :assets do
|
||||
gem 'sass-rails'
|
||||
gem 'coffee-rails'
|
||||
gem 'uglifier'
|
||||
end
|
||||
|
||||
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
|
||||
# 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
|
||||
remote: http://rubygems.org/
|
||||
specs:
|
||||
actionmailer (3.2.3)
|
||||
actionpack (= 3.2.3)
|
||||
actionmailer (3.2.7)
|
||||
actionpack (= 3.2.7)
|
||||
mail (~> 2.4.4)
|
||||
actionpack (3.2.3)
|
||||
activemodel (= 3.2.3)
|
||||
activesupport (= 3.2.3)
|
||||
actionpack (3.2.7)
|
||||
activemodel (= 3.2.7)
|
||||
activesupport (= 3.2.7)
|
||||
builder (~> 3.0.0)
|
||||
erubis (~> 2.7.0)
|
||||
journey (~> 1.0.1)
|
||||
journey (~> 1.0.4)
|
||||
rack (~> 1.4.0)
|
||||
rack-cache (~> 1.2)
|
||||
rack-test (~> 0.6.1)
|
||||
sprockets (~> 2.1.2)
|
||||
activemodel (3.2.3)
|
||||
activesupport (= 3.2.3)
|
||||
sprockets (~> 2.1.3)
|
||||
activemodel (3.2.7)
|
||||
activesupport (= 3.2.7)
|
||||
builder (~> 3.0.0)
|
||||
activerecord (3.2.3)
|
||||
activemodel (= 3.2.3)
|
||||
activesupport (= 3.2.3)
|
||||
activerecord (3.2.7)
|
||||
activemodel (= 3.2.7)
|
||||
activesupport (= 3.2.7)
|
||||
arel (~> 3.0.2)
|
||||
tzinfo (~> 0.3.29)
|
||||
activeresource (3.2.3)
|
||||
activemodel (= 3.2.3)
|
||||
activesupport (= 3.2.3)
|
||||
activesupport (3.2.3)
|
||||
activeresource (3.2.7)
|
||||
activemodel (= 3.2.7)
|
||||
activesupport (= 3.2.7)
|
||||
activesupport (3.2.7)
|
||||
i18n (~> 0.6)
|
||||
multi_json (~> 1.0)
|
||||
arel (3.0.2)
|
||||
authlogic (3.1.0)
|
||||
activerecord (>= 3.0.7)
|
||||
activerecord (>= 3.0.7)
|
||||
bcrypt-ruby (3.0.1)
|
||||
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)
|
||||
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)
|
||||
excon (0.13.2)
|
||||
fog (1.3.1)
|
||||
excon (0.15.5)
|
||||
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
|
||||
excon (~> 0.13.0)
|
||||
excon (~> 0.14)
|
||||
formatador (~> 0.2.0)
|
||||
mime-types
|
||||
multi_json (~> 1.0)
|
||||
|
@ -48,73 +160,182 @@ GEM
|
|||
net-ssh (>= 2.1.3)
|
||||
nokogiri (~> 1.5.0)
|
||||
ruby-hmac
|
||||
formatador (0.2.1)
|
||||
formatador (0.2.3)
|
||||
hashie (1.2.0)
|
||||
highline (1.6.13)
|
||||
hike (1.2.1)
|
||||
httpauth (0.1)
|
||||
i18n (0.6.0)
|
||||
journey (1.0.3)
|
||||
json (1.6.6)
|
||||
journey (1.0.4)
|
||||
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)
|
||||
i18n (>= 0.4.0)
|
||||
mime-types (~> 1.16)
|
||||
treetop (~> 1.4.8)
|
||||
mime-types (1.18)
|
||||
mini_exiftool (1.3.1)
|
||||
mime-types (1.19)
|
||||
mini_exiftool (1.6.0)
|
||||
mini_magick (3.4)
|
||||
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-ssh (>= 1.99.1)
|
||||
net-ssh (2.3.0)
|
||||
nokogiri (1.5.2)
|
||||
pg (0.13.2)
|
||||
net-sftp (2.0.5)
|
||||
net-ssh (>= 2.0.9)
|
||||
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)
|
||||
princely (1.2.5)
|
||||
rack (1.4.1)
|
||||
rack-cache (1.2)
|
||||
rack (>= 0.4)
|
||||
rack-openid (1.3.1)
|
||||
rack (>= 1.1.0)
|
||||
ruby-openid (>= 2.1.8)
|
||||
rack-ssl (1.3.2)
|
||||
rack
|
||||
rack-test (0.6.1)
|
||||
rack (>= 1.0)
|
||||
rails (3.2.3)
|
||||
actionmailer (= 3.2.3)
|
||||
actionpack (= 3.2.3)
|
||||
activerecord (= 3.2.3)
|
||||
activeresource (= 3.2.3)
|
||||
activesupport (= 3.2.3)
|
||||
rails (3.2.7)
|
||||
actionmailer (= 3.2.7)
|
||||
actionpack (= 3.2.7)
|
||||
activerecord (= 3.2.7)
|
||||
activeresource (= 3.2.7)
|
||||
activesupport (= 3.2.7)
|
||||
bundler (~> 1.0)
|
||||
railties (= 3.2.3)
|
||||
railties (3.2.3)
|
||||
actionpack (= 3.2.3)
|
||||
activesupport (= 3.2.3)
|
||||
railties (= 3.2.7)
|
||||
railties (3.2.7)
|
||||
actionpack (= 3.2.7)
|
||||
activesupport (= 3.2.7)
|
||||
rack-ssl (~> 1.3.2)
|
||||
rake (>= 0.8.7)
|
||||
rdoc (~> 3.4)
|
||||
thor (~> 0.14.6)
|
||||
thor (>= 0.14.6, < 2.0)
|
||||
raindrops (0.10.0)
|
||||
rake (0.9.2.2)
|
||||
rdoc (3.12)
|
||||
json (~> 1.4)
|
||||
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)
|
||||
rack (~> 1.0)
|
||||
tilt (~> 1.1, != 1.3.0)
|
||||
subexec (0.2.1)
|
||||
thor (0.14.6)
|
||||
sqlite3 (1.3.6)
|
||||
subexec (0.2.2)
|
||||
therubyracer (0.10.1)
|
||||
libv8 (~> 3.3.10)
|
||||
thor (0.15.4)
|
||||
tilt (1.3.3)
|
||||
treetop (1.4.10)
|
||||
polyglot
|
||||
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
|
||||
ruby
|
||||
|
||||
DEPENDENCIES
|
||||
authlogic
|
||||
action_mailer_tls!
|
||||
ajaxful_rating_jquery!
|
||||
breadcrumbs_on_rails!
|
||||
cancan
|
||||
capistrano!
|
||||
capistrano-unicorn!
|
||||
capistrano_colors
|
||||
carrierwave
|
||||
coffee-rails
|
||||
configatron!
|
||||
devise_omniauth_engine!
|
||||
dynamic_form
|
||||
ffaker
|
||||
fog
|
||||
jquery-rails
|
||||
jquery-ui-rails
|
||||
kaminari!
|
||||
machinist
|
||||
mime-types
|
||||
mini_exiftool
|
||||
mini_magick
|
||||
pg
|
||||
rails (= 3.2.3)
|
||||
omniauth-facebook
|
||||
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.
|
|
@ -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 'rake'
|
||||
|
||||
Balder::Application.load_tasks
|
||||
Photomix::Application.load_tasks
|
||||
|
|
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 302 B |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 5.5 KiB |
After Width: | Height: | Size: 21 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
|
@ -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
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
jQuery ->
|
||||
$("a[rel=popover]").popover()
|
||||
$(".tooltip").tooltip()
|
||||
$("a[rel=tooltip]").tooltip()
|
|
@ -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.
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
|
@ -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;
|
||||
padding: 2px 8px 3px 20px;
|
||||
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;
|
||||
|
||||
/* Optional rounded corners for browsers that support it */
|
||||
|
@ -29,7 +29,7 @@
|
|||
.plupload_disabled, a.plupload_disabled:hover {
|
||||
color: #737373;
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -44,7 +44,7 @@
|
|||
|
||||
.plupload_container {
|
||||
padding: 8px;
|
||||
background: url('../img/transp50.png');
|
||||
background: url(asset_path('transp50.png'));
|
||||
/*-moz-border-radius: 5px;*/
|
||||
}
|
||||
|
||||
|
@ -54,9 +54,9 @@
|
|||
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 {
|
||||
background: url('../img/backgrounds.gif') no-repeat 0 -317px;
|
||||
background: url(asset_path('backgrounds.gif')) no-repeat 0 -317px;
|
||||
min-height: 56px;
|
||||
padding-left: 60px;
|
||||
color: #FFF;
|
||||
|
@ -83,7 +83,7 @@
|
|||
|
||||
.plupload_filelist li {
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -122,20 +122,20 @@
|
|||
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_delete a {
|
||||
background: url('../img/delete.gif');
|
||||
background: url(asset_path('delete.gif'));
|
||||
}
|
||||
|
||||
li.plupload_failed a {
|
||||
background: url('../img/error.gif');
|
||||
background: url(asset_path('error.gif'));
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
li.plupload_done a {
|
||||
background: url('../img/done.gif');
|
||||
background: url(asset_path('done.gif'));
|
||||
cursor: default;
|
||||
}
|
||||
|
|
@ -20,14 +20,14 @@ div.plupload div.plupload_header {border-width: 0 0 1px 0; position: relative;}
|
|||
}
|
||||
|
||||
.plupload_header_content {
|
||||
background-image: url('../img/plupload.png');
|
||||
background-image: url(asset_path('plupload.png'));
|
||||
background-repeat: no-repeat;
|
||||
background-position: 8px center;
|
||||
min-height: 56px;
|
||||
padding-left: 60px;
|
||||
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 {
|
||||
font: normal 18px sans-serif;
|
||||
padding: 6px 0 3px;
|
||||
|
@ -61,7 +61,6 @@ div.plupload div.plupload_header {border-width: 0 0 1px 0; position: relative;}
|
|||
max-height: 180px;
|
||||
min-height: 168px;
|
||||
_height: 168px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.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
|
||||
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
|
||||
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]
|
||||
@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]
|
||||
#search = params[:q]
|
||||
#search = search.split("AND").map{|q|q.strip}
|
||||
|
@ -20,7 +25,7 @@ class AlbumsController < ApplicationController
|
|||
end
|
||||
}
|
||||
else
|
||||
@albums = Album.find(:all, :order => 'title')
|
||||
@albums = Album.popular.page(@page).per(@per_page)
|
||||
end
|
||||
respond_to do |format|
|
||||
format.html
|
||||
|
@ -40,6 +45,8 @@ class AlbumsController < ApplicationController
|
|||
|
||||
def show
|
||||
@album = Album.find( params[:id])
|
||||
@photos = @album.photos.popular
|
||||
|
||||
respond_to do |format|
|
||||
format.html
|
||||
format.json { render :json => @album }
|
||||
|
@ -98,5 +105,11 @@ class AlbumsController < ApplicationController
|
|||
redirect_to @album
|
||||
end
|
||||
end
|
||||
|
||||
def rate
|
||||
@album = Album.find(params[:id])
|
||||
@album.rate(params[:stars], current_user, params[:dimension])
|
||||
render :json => {:id => @album.wrapper_dom_id(params), :width => 125}
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -2,86 +2,50 @@
|
|||
# Likewise, all the methods added will be available for all controllers.
|
||||
|
||||
class ApplicationController < ActionController::Base
|
||||
layout 'bootstrap'
|
||||
helper :all # include all helpers, all the time
|
||||
protect_from_forgery # See ActionController::RequestForgeryProtection for details
|
||||
|
||||
helper_method :current_user, :current_user_session
|
||||
|
||||
before_filter :setup
|
||||
before_filter :set_locale
|
||||
before_filter :authenticate_user!, :set_current_user
|
||||
before_filter :setup, :set_pagination_params
|
||||
|
||||
|
||||
private
|
||||
|
||||
def setup
|
||||
redirect_to new_account_path if User.all.length == 0
|
||||
end
|
||||
|
||||
def check_public_access
|
||||
require_user if ENV['PRIVATE'] == 'true'
|
||||
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 set_current_user
|
||||
User.current = current_user
|
||||
end
|
||||
|
||||
def current_user_session
|
||||
return @current_user_session if defined?(@current_user_session)
|
||||
@current_user_session = UserSession.find
|
||||
end
|
||||
def setup
|
||||
redirect_to new_account_path if User.all.size == 0
|
||||
end
|
||||
|
||||
def current_user
|
||||
return @current_user if defined?(@current_user)
|
||||
@current_user = current_user_session && current_user_session.user
|
||||
end
|
||||
def check_public_access
|
||||
require_user if ENV['PRIVATE'] == 'true'
|
||||
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 store_location
|
||||
session[:return_to] = request.fullpath
|
||||
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 redirect_back_or_default(default)
|
||||
redirect_to(session[:return_to] || default)
|
||||
session[:return_to] = nil
|
||||
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
|
||||
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
|
||||
|
||||
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
|
||||
session[:return_to] = request.fullpath
|
||||
end
|
||||
|
||||
def redirect_back_or_default(default)
|
||||
redirect_to(session[:return_to] || default)
|
||||
session[:return_to] = nil
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -1,9 +1,14 @@
|
|||
class CollectionsController < ApplicationController
|
||||
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
|
||||
@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|
|
||||
format.html
|
||||
format.json { render :json => @collections }
|
||||
|
@ -13,7 +18,14 @@ class CollectionsController < ApplicationController
|
|||
|
||||
def show
|
||||
@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|
|
||||
format.html
|
||||
format.json { render :json => @collection }
|
||||
|
@ -24,6 +36,10 @@ class CollectionsController < ApplicationController
|
|||
|
||||
def new
|
||||
@collection = Collection.new
|
||||
add_breadcrumb t('activerecord.models.collection.other').mb_chars.capitalize.to_s, collections_path,
|
||||
:title => t('activerecord.models.collection.other')
|
||||
add_breadcrumb t('activerecord.actions.new', :model => I18n.t('activerecord.models.collection.one')), new_collection_path,
|
||||
:title => t('activerecord.actions.new', :model => I18n.t('activerecord.models.collection.one'))
|
||||
end
|
||||
|
||||
def create
|
||||
|
@ -42,6 +58,8 @@ class CollectionsController < ApplicationController
|
|||
|
||||
def update
|
||||
@collection = Collection.find( params[:id])
|
||||
add_breadcrumb t('activerecord.models.collection.popular'), collections_path, :title => t('activerecord.models.collection.popular')
|
||||
add_breadcrumb t('activerecord.actions.create', :model => I18n.t('activerecord.models.collection.single')), new_collection_path, :title => t('activerecord.actions.create')
|
||||
if @collection.update_attributes(params[:collection])
|
||||
flash[:notice] = "Collection updated!"
|
||||
redirect_to @collection
|
||||
|
@ -58,5 +76,11 @@ class CollectionsController < ApplicationController
|
|||
redirect_to @collection
|
||||
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
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
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
|
||||
if params[:tag_id] && params[:album_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]
|
||||
@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]
|
||||
@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]
|
||||
#search = params[:q]
|
||||
#search = search.split("AND").map{|q|q.strip}
|
||||
|
@ -25,7 +25,7 @@ class PhotosController < ApplicationController
|
|||
end
|
||||
}
|
||||
else
|
||||
@photos = Photo.find(:all, :order => "photos.id ASC")
|
||||
@photos = Photo.popular.page(@page).per(@per_page)
|
||||
end
|
||||
respond_to do |format|
|
||||
format.html
|
||||
|
@ -37,9 +37,9 @@ class PhotosController < ApplicationController
|
|||
def untouched
|
||||
if params[:album_id]
|
||||
@album = Album.find( params[:album_id])
|
||||
@photos = @album.photos.untouched
|
||||
@photos = @album.photos.untouched.page(@page).per(@per_page)
|
||||
else
|
||||
@photos = Photo.untouched()
|
||||
@photos = Photo.untouched().page(@page).per(@per_page)
|
||||
end
|
||||
respond_to do |format|
|
||||
format.html
|
||||
|
@ -77,10 +77,10 @@ class PhotosController < ApplicationController
|
|||
|
||||
def create
|
||||
@photo = Photo.new(params[:photo])
|
||||
@photo.file = params[:file]
|
||||
@photo.attachment = params[:file]
|
||||
respond_to do |format|
|
||||
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 }
|
||||
else
|
||||
format.html { render :text => "ERRORS:" + @photo.errors.full_messages.join(" "), :status => 500 }
|
||||
|
@ -91,7 +91,7 @@ class PhotosController < ApplicationController
|
|||
|
||||
def edit
|
||||
@photo = Photo.find( params[:id])
|
||||
@tags = Tag.find(:all).map { |tag| tag.title }.join('\',\'')
|
||||
@tags = Tag.all.map { |tag| tag.title }.join('\',\'')
|
||||
end
|
||||
|
||||
def edit_multiple
|
||||
|
@ -148,4 +148,10 @@ class PhotosController < ApplicationController
|
|||
redirect_to @photo
|
||||
end
|
||||
end
|
||||
|
||||
def rate
|
||||
@photo = Photo.find(params[:id])
|
||||
@photo.rate(params[:stars], current_user, params[:dimension])
|
||||
render :json => {:id => @photo.wrapper_dom_id(params), :width => 125}
|
||||
end
|
||||
end
|
||||
|
|
|
@ -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
|
||||
before_filter :check_public_access
|
||||
before_filter :require_no_user, :only => [:new, :create]
|
||||
before_filter :require_user, :only => [:show, :edit, :update, :destroy]
|
||||
skip_before_filter :authenticate_user!, :only => [:new, :create]
|
||||
skip_filter :setup
|
||||
|
||||
def new
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
# Methods added to this helper will be available to all templates in the application.
|
||||
module ApplicationHelper
|
||||
|
||||
=begin
|
||||
def breadcrumbs(sep = "/", include_home = true)
|
||||
levels = request.path.split('?')[0].split('/')
|
||||
levels.delete_at(0)
|
||||
|
||||
#links = "You are here: "
|
||||
links = content_tag('a', "HOME", :href => root_path ) if include_home
|
||||
links = content_tag('li', (content_tag('a', t(:home_page), :href => root_path ) if include_home))
|
||||
|
||||
nocrumb = ["collections", "albums", "photos", "tags", "new", "edit", "tags"]
|
||||
|
||||
|
@ -15,12 +16,19 @@ module ApplicationHelper
|
|||
level = level.gsub("-", " ")
|
||||
if index+1 == levels.length
|
||||
#links += " #{sep} #{level.upcase}" unless nocrumb.include?(level)
|
||||
elsif !nocrumb.include?(level)
|
||||
#elsif !nocrumb.include?(level)
|
||||
links += " " + sep + " "
|
||||
links += content_tag('a', level.upcase, :href => '/'+levels[0..index].join('/'))
|
||||
links += content_tag('li', content_tag('a', level, :href => '/'+levels[0..index].join('/')))
|
||||
end
|
||||
end
|
||||
|
||||
content_tag("div", links, :id => "breadcrumb")
|
||||
end
|
||||
content_tag("ul", links, :class => "breadcrumb")
|
||||
end
|
||||
=end
|
||||
|
||||
def pluralize(string, count=nil, variants=nil)
|
||||
# example variants for russian: # Russian.pluralize(3.14, "вещь", "вещи", "вещей", "вещи")
|
||||
a,b,c,d=*variants
|
||||
I18n.locale.eql?(:ru) ? Russian.pluralize(count, a,b,c,d) : string.pluralize
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
module HomeHelper
|
||||
end
|
|
@ -1,9 +1,3 @@
|
|||
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
|
||||
|
|
|
@ -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,99 +1,104 @@
|
|||
class Album < ActiveRecord::Base
|
||||
extend Ext::GroupFor
|
||||
|
||||
ajaxful_rateable :stars => 5, :cache_column => :rating_average
|
||||
|
||||
has_many :photos, :dependent => :destroy
|
||||
has_many :collection_albums
|
||||
has_many :collections, :through => :collection_albums
|
||||
|
||||
validates :path, :presence => true, :uniqueness => true #, :message => "Album already exsists on disc"
|
||||
validates :title, :presence => true #, :message => "can't be blank"
|
||||
|
||||
|
||||
before_validation :ensure_path, :set_title
|
||||
after_create :create_folders
|
||||
after_destroy :destroy_folders
|
||||
|
||||
attr_accessor :tags
|
||||
#attr_protected :path
|
||||
|
||||
scope :untouched, where("albums.id IN ( SELECT DISTINCT photos.album_id FROM photos WHERE photos.description IS NULL AND photos.id NOT IN ( SELECT photo_id FROM photo_tags) )").order('title')
|
||||
scope :unused, where("albums.id NOT IN (SELECT album_id FROM collection_albums)")
|
||||
scope :used, where("albums.id IN (SELECT album_id FROM collection_albums)")
|
||||
|
||||
scope :visible, lambda { where(:public => true) }
|
||||
scope :popular, lambda{visible.includes(:photos).where("photos.id NOT NULL").order('albums.rating_average desc')}
|
||||
scope :untouched, lambda{where("albums.id IN ( SELECT DISTINCT photos.album_id FROM photos WHERE photos.description IS NULL AND photos.id NOT IN ( SELECT photo_id FROM photo_tags) )").order('title')}
|
||||
scope :unused, lambda{where("albums.id NOT IN (SELECT album_id FROM collection_albums)")}
|
||||
scope :used, lambda{where("albums.id IN (SELECT album_id FROM collection_albums)")}
|
||||
|
||||
def to_param
|
||||
"#{id}-#{title.parameterize}"
|
||||
end
|
||||
|
||||
|
||||
def ensure_path
|
||||
self.path = self.title.parameterize unless self.path
|
||||
end
|
||||
|
||||
|
||||
def set_title
|
||||
self.title = File.basename(self.path).titleize unless self.title || !self.path
|
||||
end
|
||||
|
||||
|
||||
def tags
|
||||
# should maybe cache this to database?
|
||||
# should maybe return array instead?
|
||||
|
||||
|
||||
tags = Array.new
|
||||
self.photos.map{ |photo|
|
||||
if photo.tags.empty?
|
||||
# photo has no tags => no unversial tags for this album
|
||||
return
|
||||
else
|
||||
photo.tags
|
||||
end
|
||||
}.each_with_index{ |photo_tags,i|
|
||||
# returns tag collection for each photo
|
||||
if i == 0
|
||||
tags = photo_tags
|
||||
else
|
||||
# combine arrays if they have identical tags.
|
||||
# Will remove tags that are only tagged to one photo
|
||||
#tags = tags & photo_tags
|
||||
tags = tags & photo_tags
|
||||
end
|
||||
self.photos.map { |photo|
|
||||
if photo.tags.empty?
|
||||
# photo has no tags => no unversial tags for this album
|
||||
return
|
||||
else
|
||||
photo.tags
|
||||
end
|
||||
}.each_with_index { |photo_tags, i|
|
||||
# returns tag collection for each photo
|
||||
if i == 0
|
||||
tags = photo_tags
|
||||
else
|
||||
# combine arrays if they have identical tags.
|
||||
# Will remove tags that are only tagged to one photo
|
||||
#tags = tags & photo_tags
|
||||
tags = tags & photo_tags
|
||||
end
|
||||
}
|
||||
return tags
|
||||
end
|
||||
|
||||
|
||||
def tags=(tags)
|
||||
tags = tags.split(" ").sort
|
||||
current_tags = ( self.tags.nil? ? [] : self.tags.map{|tag|tag.title} )
|
||||
current_tags = (self.tags.nil? ? [] : self.tags.map { |tag| tag.title })
|
||||
return if tags == self.tags
|
||||
|
||||
|
||||
# find tags that should be removed from this album - thus remove from all photos in album
|
||||
# i.e. tags listed in self.tag_list but no in parameter tags
|
||||
#current_tags.map {|tag|tag if !tags.include?(tag) }.compact
|
||||
(current_tags - tags).each { |tag|
|
||||
self.photos.each {|photo|
|
||||
photo.untag( tag )
|
||||
self.photos.each { |photo|
|
||||
photo.untag(tag)
|
||||
}
|
||||
}
|
||||
|
||||
# add universial tags to all photos in album
|
||||
(tags - current_tags).each do |tag|
|
||||
self.photos.each { |photo|
|
||||
photo.tag( tag )
|
||||
photo.tag(tag)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def photo_tags
|
||||
tags = Array.new
|
||||
self.photos.each{ |photo|
|
||||
self.photos.each { |photo|
|
||||
tags = tags | photo.tags
|
||||
}
|
||||
return tags
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
private
|
||||
|
||||
|
||||
def create_folders
|
||||
#Dir.mkdir( APP_CONFIG[:photos_path] + self.path ) unless File.exists?( APP_CONFIG[:photos_path] + self.path )
|
||||
#Dir.mkdir( APP_CONFIG[:thumbs_path] + self.path ) unless File.exists?( APP_CONFIG[:thumbs_path] + self.path )
|
||||
end
|
||||
|
||||
|
||||
def destroy_folders
|
||||
#puts "DELETE DIRECTORY " + APP_CONFIG[:photos_path] + self.path
|
||||
#Dir.delete( APP_CONFIG[:photos_path] + self.path ) if File.exists?( APP_CONFIG[:photos_path] + self.path )
|
||||
|
|
|
@ -1,10 +1,21 @@
|
|||
class Collection < ActiveRecord::Base
|
||||
extend Ext::GroupFor
|
||||
|
||||
ajaxful_rateable :stars => 5, :cache_column => :rating_average
|
||||
|
||||
has_many :collection_albums
|
||||
has_many :albums, :through => :collection_albums
|
||||
attr_accessor :album_list
|
||||
|
||||
validates :title, :presence => true
|
||||
|
||||
scope :visible, where(:public => true)
|
||||
scope :popular, lambda{visible.includes(:albums => :photos).where("photos.id NOT NULL").order('collections.rating_average desc')}
|
||||
|
||||
def photos_count
|
||||
self.albums.includes(:photos).size
|
||||
end
|
||||
|
||||
def to_param
|
||||
"#{id}-#{title.parameterize}"
|
||||
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
|
||||
# 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
|
||||
has_many :photo_tags, :dependent => :destroy
|
||||
has_many :tags, :through => :photo_tags
|
||||
|
||||
mount_uploader :file, FileUploader
|
||||
|
||||
validates :title, :presence => true
|
||||
|
||||
before_validation :set_title
|
||||
mount_uploader :attachment, FileUploader
|
||||
|
||||
before_create :exif_read
|
||||
#before_update :exif_write
|
||||
before_update :exif_write
|
||||
after_create :set_title, :set_visible
|
||||
|
||||
attr_accessor :tag_list
|
||||
|
||||
|
||||
scope :visible, where(:public => true)
|
||||
scope :popular, visible.order('rating_average desc')
|
||||
scope :untouched, :conditions => "photos.description IS NULL AND photos.id NOT IN ( SELECT photo_id FROM photo_tags)", :include => :album
|
||||
scope :previous, lambda { |p,a| { :conditions => ["id < :id AND album_Id = :album ", { :id => p, :album => a } ], :limit => 1, :order => "id DESC"} }
|
||||
scope :next, lambda { |p,a| { :conditions => ["id > :id AND album_Id = :album ", { :id => p, :album => a } ], :limit => 1, :order => "id ASC"} }
|
||||
|
@ -39,7 +41,7 @@ class Photo < ActiveRecord::Base
|
|||
end
|
||||
|
||||
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
|
||||
|
||||
def tag_list=(tags)
|
||||
|
@ -57,12 +59,16 @@ class Photo < ActiveRecord::Base
|
|||
|
||||
private
|
||||
|
||||
def set_visible
|
||||
update_attribute(:public, true) unless self.public
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
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.latitude = photo.GPSLatitude if self.latitude.nil?
|
||||
self.title = photo.DocumentName if self.title.nil?
|
||||
|
@ -72,7 +78,7 @@ class Photo < ActiveRecord::Base
|
|||
|
||||
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
|
||||
photo = MiniExiftool.new(self.file.file.file)
|
||||
photo = MiniExiftool.new(self.attachment.file.file)
|
||||
photo.GPSLongitude = self.longitude
|
||||
photo.GPSLatitude = self.latitude
|
||||
photo.DocumentName = self.title
|
||||
|
|
|
@ -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
|
||||
has_many :role_memberships, :as => :roleable, :dependent => :destroy
|
||||
has_many :roles, :through => :role_memberships, :source => :role
|
||||
|
||||
has_many :roleables, :class_name => "RoleMembership", :foreign_key => "role_id", :dependent => :destroy
|
||||
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
|
||||
attr_accessible :name
|
||||
|
||||
has_and_belongs_to_many :users
|
||||
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
|
|
@ -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
|
||||
acts_as_authentic
|
||||
acts_as_permissible
|
||||
devise :database_authenticatable, :registerable, :confirmable, :token_authenticatable,
|
||||
: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
|
||||
|
|
|
@ -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,14 +2,18 @@
|
|||
|
||||
class FileUploader < CarrierWave::Uploader::Base
|
||||
|
||||
@@generate_file_name = ''
|
||||
@@original_filename = ''
|
||||
|
||||
|
||||
# Include RMagick or ImageScience support
|
||||
# include CarrierWave::RMagick
|
||||
# include CarrierWave::ImageScience
|
||||
include CarrierWave::MiniMagick
|
||||
include CarrierWave::MiniMagick
|
||||
# Choose what kind of storage to use for this uploader
|
||||
if ENV['S3_KEY']
|
||||
storage :fog
|
||||
|
||||
|
||||
def cache_dir
|
||||
"#{Rails.root.to_s}/tmp/uploads" if ENV['HEROKU'] == 'true'
|
||||
end
|
||||
|
@ -21,7 +25,15 @@ class FileUploader < CarrierWave::Uploader::Base
|
|||
# This is a sensible default for uploaders that are meant to be mounted:
|
||||
def store_dir
|
||||
#{}"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
|
||||
|
||||
# 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
|
||||
|
||||
# Create different versions of your uploaded files
|
||||
version :collection do
|
||||
process :resize_to_fill => [200, 200]
|
||||
def store_dir
|
||||
ENV['STORAGE_PATH'] + "/thumbs/#{model.album.path}"
|
||||
end
|
||||
end
|
||||
version :album do
|
||||
process :resize_to_fill => [100, 100]
|
||||
def store_dir
|
||||
ENV['STORAGE_PATH'] + "/thumbs/#{model.album.path}"
|
||||
end
|
||||
end
|
||||
version :preview do
|
||||
process :resize_to_fit => [210, 210]
|
||||
def store_dir
|
||||
ENV['STORAGE_PATH'] + "/thumbs/#{model.album.path}"
|
||||
end
|
||||
end
|
||||
version :single do
|
||||
process :resize_to_limit => [950, 950]
|
||||
def store_dir
|
||||
ENV['STORAGE_PATH'] + "/thumbs/#{model.album.path}"
|
||||
end
|
||||
end
|
||||
version :thumb do
|
||||
process :resize_to_fill => [260, 180]
|
||||
|
||||
def store_dir
|
||||
ENV['STORAGE_PATH'] + "/thumbs/#{model.album.path}/#{model.id}"
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
######################################################################################################################
|
||||
# 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
|
||||
ENV['STORAGE_PATH'] + "/thumbs/#{model.album.path}/#{model.id}"
|
||||
end
|
||||
end
|
||||
|
||||
version :large do
|
||||
process :resize_to_fill => [940, 600]
|
||||
|
||||
def store_dir
|
||||
ENV['STORAGE_PATH'] + "/thumbs/#{model.album.path}/#{model.id}"
|
||||
end
|
||||
end
|
||||
|
||||
version :largest do
|
||||
process :resize_to_fill => [1170, 600]
|
||||
|
||||
def store_dir
|
||||
ENV['STORAGE_PATH'] + "/thumbs/#{model.album.path}/#{model.id}"
|
||||
end
|
||||
end
|
||||
######################################################################################################################
|
||||
|
||||
|
||||
# Add a white list of extensions which are allowed to be uploaded,
|
||||
# for images you might use something like this:
|
||||
def extension_white_list
|
||||
%w(jpg jpeg gif png bmp tiff)
|
||||
end
|
||||
|
||||
# Override the filename of the uploaded files
|
||||
# def filename
|
||||
# "something.jpg" if original_filename
|
||||
# end
|
||||
|
||||
def extension_white_list
|
||||
%w(jpg jpeg gif png bmp tiff)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -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>
|
||||
|
||||
<%= hidden_field_tag :all_tags, "'#{Tag.find(:all).map { |tag| tag.title }.join('\',\'')}'" %>
|
||||
<%= hidden_field_tag :collection_id, params[:collection_id] %>
|
||||
<%= form.hidden_field :id %>
|
||||
<%= form.hidden_field :latitude %>
|
||||
<%= form.hidden_field :longitude %>
|
||||
<fieldset>
|
||||
<%= hidden_field_tag :all_tags, "'#{Tag.all.map { |tag| tag.title }.join('\',\'')}'" %>
|
||||
<%= hidden_field_tag :collection_id, params[:collection_id] %>
|
||||
<%= form.hidden_field :id %>
|
||||
<%= form.hidden_field :latitude %>
|
||||
<%= form.hidden_field :longitude %>
|
||||
|
||||
<%= form.label :title, :Title, {:class => 'big'} %><br />
|
||||
<%= form.text_field :title, {:class => 'big'} %><br />
|
||||
<div class="control-group">
|
||||
<%= 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 />
|
||||
<%= form.text_area :description %><br />
|
||||
<div class="control-group">
|
||||
<%= 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 />
|
||||
<%= form.text_area :address, { :rows => 3} %><br />
|
||||
<div class="control-group">
|
||||
<%= 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 />
|
||||
<%= form.text_area :note %><br />
|
||||
<div class="control-group">
|
||||
<%= 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>
|
||||
|
||||
<%= 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 />
|
||||
<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>
|
||||
|
||||
<br />
|
||||
Contains: <%= @album.photos.count %> photos<br/>
|
||||
|
||||
<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>
|
||||
|
||||
|
||||
<br />
|
||||
Contains: <%= @album.photos.count %> photos<br/>
|
||||
</fieldset>
|
|
@ -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,19 +1,11 @@
|
|||
<% for album in @albums %>
|
||||
<div class="row">
|
||||
<div class="title">
|
||||
<%= render :partial => "photos/thumb", :locals => {:photo => album.photos.first } unless album.photos.empty? %>
|
||||
<p><%= link_to album.title, album %></p>
|
||||
</div>
|
||||
<div class="image">
|
||||
<%= render :partial => "photos/thumb", :collection => album.photos.find(:all, :limit => 5, :offset => 1), :as => :photo %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
<%= paginate @albums %>
|
||||
<%= render 'row_collections' %>
|
||||
<%= paginate @albums %>
|
||||
|
||||
<%= content_for :action_links do %>
|
||||
<%= link_to "Show just the photos tagged with #{params[:q]}", photos_path(:q => params[:q]) if params[:q] %>
|
||||
<% if has_role?("admin") %>
|
||||
<%= " | " if params[:q] %>
|
||||
<%= link_to "New album", new_album_path() %>
|
||||
<% end %>
|
||||
<%= link_to "Show just the photos tagged with #{params[:q]}", photos_path(:q => params[:q]) if params[:q] %>
|
||||
<% if current_user and current_user.has_role?("admin") %>
|
||||
<%= " | " if params[:q] %>
|
||||
<%= link_to "New album", new_album_path() %>
|
||||
<% end %>
|
||||
<% end %>
|
|
@ -1,8 +1,9 @@
|
|||
<h1>New Album</h1>
|
||||
|
||||
<%= form_for @album do |f| %>
|
||||
<%= f.error_messages %>
|
||||
<%= render :partial => "form", :object => f %>
|
||||
<%= f.submit "Create" %>
|
||||
<%= form_for @album, :html => {:class => 'form-horizontal'} do |f| %>
|
||||
<legend><%= t('activerecord.actions.new', :model => I18n.t('activerecord.models.album.one')) %></legend>
|
||||
<%= f.error_messages %>
|
||||
<%= render :partial => "form", :object => f %>
|
||||
<div class="form-actions">
|
||||
<%= f.button "Create", :class => 'btn btn-primary btn-large' %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
|
@ -1,60 +1,47 @@
|
|||
<h2><%= @album.title %></h2>
|
||||
|
||||
<div id="multipleimages">
|
||||
<table>
|
||||
<% count = 0.0 %>
|
||||
<% for photo in @album.photos.find(:all, :order => "Id ASC") %>
|
||||
<% count += 1%>
|
||||
<% if count == 1 || ( (count-1) / 4.0 == ( (count-1) / 4.0).to_i ) %><tr><% end %>
|
||||
<td><%= link_to image_tag( photo.file.preview.url ), [@album.collections.first, @album, photo] %></td>
|
||||
<% if count / 4.0 == (count / 4.0).to_i %></tr><% end %>
|
||||
<% end %>
|
||||
</table>
|
||||
</div>
|
||||
<%= render :partial => 'photos/row_collections' %>
|
||||
|
||||
<p><%= @album.description %></p>
|
||||
|
||||
<% unless @album.photo_tags.empty? %>
|
||||
<p>Tagged with:
|
||||
<% for tag in @album.photo_tags.map{|tag|tag.title}.sort %>
|
||||
<%= link_to tag, album_tag_photos_path(@album, tag) %>
|
||||
<% end %>
|
||||
</p>
|
||||
<p>Tagged with:
|
||||
<% for tag in @album.photo_tags.map { |tag| tag.title }.sort %>
|
||||
<%= link_to tag, album_tag_photos_path(@album, tag) %>
|
||||
<% end %>
|
||||
</p>
|
||||
<% end %>
|
||||
|
||||
<% unless @album.collections.empty? %>
|
||||
<p>Part of:
|
||||
<% for collection in @album.collections.find(:all, :order => 'title') %>
|
||||
<%= link_to collection.title, collection_path(collection) %>
|
||||
<% end %>
|
||||
</p>
|
||||
<p>Part of:
|
||||
<% for collection in @album.collections.order('title') %>
|
||||
<%= link_to collection.title, collection_path(collection) %>
|
||||
<% end %>
|
||||
</p>
|
||||
<% end %>
|
||||
|
||||
|
||||
<% if has_role?("admin") %>
|
||||
<p><%= @album.address %></p>
|
||||
<% end %>
|
||||
<% if has_role?("admin") %>
|
||||
<p><%= @album.note %></p>
|
||||
<% if current_user and current_user.has_role?("admin") %>
|
||||
<p><%= @album.address %></p>
|
||||
<p><%= @album.note %></p>
|
||||
<% end %>
|
||||
|
||||
|
||||
|
||||
<%= content_for :action_links do %>
|
||||
<% if has_role?("admin") %>
|
||||
<% if params[:collection_id] %>
|
||||
<%= link_to "PDF", collection_album_path(params[:collection_id],@album, :format => 'pdf') %> |
|
||||
<%= link_to "Edit album", edit_collection_album_path(params[:collection_id],@album) %> |
|
||||
<%= link_to "Edit all photos", edit_multiple_collection_album_photos_path(params[:collection_id],@album) %> |
|
||||
<%= link_to "Edit untouched photos", untouched_collection_album_photos_path(params[:collection_id], @album) %> |
|
||||
<%= link_to "Add photos", upload_collection_album_photos_path(params[:collection_id], @album) %>
|
||||
<% else %>
|
||||
<%= link_to "PDF", album_path(@album, :format => 'pdf') %> |
|
||||
<%= link_to "Edit album", edit_album_path(@album) %> |
|
||||
<%= link_to "Edit all photos", edit_multiple_album_photos_path(@album) %> |
|
||||
<%= link_to "Edit untouched photos", untouched_album_photos_path(@album) %> |
|
||||
<%= link_to "Add photos", upload_album_photos_path(@album) %>
|
||||
<% end %>
|
||||
<% if current_user and current_user.has_role?("admin") %>
|
||||
<% if params[:collection_id] %>
|
||||
<li><%= link_to "PDF", collection_album_path(params[:collection_id], @album, :format => 'pdf') %></li>
|
||||
<li><%= link_to "Edit album", edit_collection_album_path(params[:collection_id], @album) %></li>
|
||||
<li><%= link_to "Edit all photos", edit_multiple_collection_album_photos_path(params[:collection_id], @album) %></li>
|
||||
<li><%= link_to "Edit untouched photos", untouched_collection_album_photos_path(params[:collection_id], @album) %></li>
|
||||
<li><%= link_to "Add photos", upload_collection_album_photos_path(params[:collection_id], @album) %></li>
|
||||
<% else %>
|
||||
<li><%= link_to "PDF", album_path(@album, :format => 'pdf') %></li>
|
||||
<li><%= link_to "Edit album", edit_album_path(@album) %></li>
|
||||
<li><%= link_to "Edit all photos", edit_multiple_album_photos_path(@album) %></li>
|
||||
<li><%= link_to "Edit untouched photos", untouched_album_photos_path(@album) %></li>
|
||||
<li><%= link_to "Add photos", upload_album_photos_path(@album) %></li>
|
||||
<% end %>
|
||||
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% end %>
|
|
@ -1,38 +1,49 @@
|
|||
<%= form.label :title, :Title, {:class => 'big'} %><br />
|
||||
<%= form.text_field :title, {:class => 'big'} %><br />
|
||||
<fieldset>
|
||||
<div class="control-group">
|
||||
<%= form.label :title, t('activerecord.models.collection.attributes.title'), {:class => 'control-label'} %>
|
||||
<div class="controls">
|
||||
<%= form.text_field :title, {:class => 'input-xlarge'} %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<%= form.label :description %><br />
|
||||
<%= form.text_area :description %><br />
|
||||
<div class="control-group">
|
||||
<%= form.label :description, t('activerecord.models.collection.attributes.description'), {:class => 'control-label'} %>
|
||||
<div class="controls">
|
||||
<%= form.text_area :description, {:class => 'input-xlarge', :rows => 5} %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<% unless @collection.albums.empty? %>
|
||||
<%= form.label :albums %><br />
|
||||
<div id="collection_albums">
|
||||
<% for album in @collection.albums %>
|
||||
<%= form.fields_for :album_list do |album_fields| %>
|
||||
<span>
|
||||
<%= image_tag "delete-24x24.png", :class => "delete", :alt => "Delete" -%>
|
||||
<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>
|
||||
|
||||
<% if album.photos.empty? %>
|
||||
<%= album.title %>
|
||||
<% else %>
|
||||
<%= image_tag album.photos.first.file.album.url, :alt => album.title %>
|
||||
<% end %>
|
||||
<%= album_fields.hidden_field album.id %>
|
||||
</span>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
<% unless @collection.albums.empty? %>
|
||||
<%= form.label :albums %>
|
||||
<% @collection.albums.each do |album| %>
|
||||
<%= form.fields_for :album_list do |album_fields| %>
|
||||
<%= image_tag "delete-24x24.png", :class => "delete", :alt => "Delete" -%>
|
||||
<% if album.photos.empty? %>
|
||||
<%= album.title %>
|
||||
<% else %>
|
||||
<%= image_tag album.photos.first.attachment.thumb.url, :alt => album.title %>
|
||||
<% end %>
|
||||
<%= album_fields.hidden_field album.id %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<p class="clear">
|
||||
<%
|
||||
grouped_options = [
|
||||
['Available albums',[['Choose album to add','']]],
|
||||
['Not used', Album.unused.map{|album|[album.title, album.id]} ],
|
||||
['In use', Album.used.map{|album|[album.title, album.id]} ]
|
||||
]
|
||||
grouped_options_for_select(grouped_options)
|
||||
%>
|
||||
<%= select_tag 'available_albums', grouped_options_for_select(grouped_options) %>
|
||||
</p>
|
||||
|
||||
<% end %>
|
||||
<%
|
||||
grouped_options = [
|
||||
['Available albums', [['Choose album to add', '']]],
|
||||
['Not used', Album.unused.map { |album| [album.title, album.id] }],
|
||||
['In use', Album.used.map { |album| [album.title, album.id] }]
|
||||
]
|
||||
grouped_options_for_select(grouped_options)
|
||||
%>
|
||||
<%= select_tag 'available_albums', grouped_options_for_select(grouped_options) %>
|
||||
<% end %>
|
||||
</fieldset>
|
|
@ -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">
|
||||
<% for collection in @collections %>
|
||||
<div class="thumb">
|
||||
<h3><%= link_to collection.title, collection %></h3>
|
||||
<%= 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>
|
||||
<h1><%= t('activerecord.models.collection.pluralize') %></h1>
|
||||
<%= paginate @collections %>
|
||||
<%= render 'row_collections' %>
|
||||
<%= paginate @collections %>
|
||||
|
||||
|
||||
<%= 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 do |f| %>
|
||||
<%= form_for @collection, :html => {:class => 'form-horizontal'} do |f| %>
|
||||
<legend><%= t('activerecord.actions.new', :model => I18n.t('activerecord.models.collection.one')) %></legend>
|
||||
<%= f.error_messages %>
|
||||
<%= render :partial => "form", :object => f %>
|
||||
<%= f.submit "Create" %>
|
||||
<div class="form-actions">
|
||||
<%= f.button "Create", :class => 'btn btn-primary btn-large' %>
|
||||
</div>
|
||||
<% end %>
|
|
@ -1,22 +1,12 @@
|
|||
<h2><%= h @collection.title %></h2>
|
||||
<p><%= h @collection.description %></p>
|
||||
<h2><%= @collection.title %></h2>
|
||||
<p><%= @collection.description %></p>
|
||||
|
||||
<% for album in @albums %>
|
||||
<div class="row">
|
||||
<div class="title">
|
||||
<%= render :partial => "photos/thumb", :locals => {:photo => album.photos.first } unless album.photos.empty? %>
|
||||
<p><%= link_to album.title, collection_album_path(@collection, album) %></p>
|
||||
</div>
|
||||
<div class="image">
|
||||
<%= render :partial => "photos/thumb", :collection => album.photos.find(:all, :limit => 5, :offset => 1), :as => :photo %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
<%= render :partial => 'albums/row_collections' %>
|
||||
|
||||
<%= content_for :action_links do %>
|
||||
<% if has_role?("admin") %>
|
||||
<%= link_to "PDF", collection_path(@collection, :format => 'pdf') %> |
|
||||
<%= link_to "Edit collection", edit_collection_path(@collection) %> |
|
||||
<%= link_to "New album", new_collection_album_path(@collection) %>
|
||||
<% end %>
|
||||
<% if current_user and current_user.has_role?("admin") %>
|
||||
<li><%= link_to "PDF", collection_path(@collection, :format => 'pdf') %></li>
|
||||
<li><%= link_to "Edit collection", edit_collection_path(@collection) %></li>
|
||||
<li><%= link_to "New album", new_collection_album_path(@collection) %></li>
|
||||
<% end %>
|
||||
<% end %>
|
|
@ -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 -%>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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" %>
|
|
@ -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" %>
|
|
@ -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 %>
|
|
@ -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" %>
|
|
@ -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" %>
|
|
@ -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" %>
|
|
@ -0,0 +1,5 @@
|
|||
<div class="row">
|
||||
<%= render 'shared/home_slider' %>
|
||||
</div>
|
||||
<h2><%= t('activerecord.models.collection.popular') %></h2>
|
||||
<%= render :partial => 'collections/row_collections' %>
|
|
@ -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 %>
|
|
@ -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>
|
|
@ -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 %>
|
|
@ -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 %>
|
|
@ -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>
|
|
@ -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 -%>
|
|
@ -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>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<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 %>
|
||||
<%= render :partial => 'shared/head' %>
|
||||
</head>
|
||||
<body>
|
||||
<div id="container">
|
||||
|
@ -43,7 +37,6 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<%= javascript_include_tag 'jquery-1.4.2.js', 'rails', 'balder' %>
|
||||
<%= yield :javascript %>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -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>
|
|
@ -1,14 +1,14 @@
|
|||
<%= content_for :javascript do %>
|
||||
<%= javascript_include_tag "tag/tag" -%>
|
||||
<%= javascript_include_tag "tag/tag" -%>
|
||||
<% end %>
|
||||
<%= hidden_field_tag :all_tags, @tags %>
|
||||
<%= form.label :title %><br />
|
||||
<%= form.text_field :title %><br />
|
||||
<br />
|
||||
<br/>
|
||||
<%= form.label :tag_list %><br />
|
||||
<%= form.text_field :tag_list, { :autocomplete => "off", :class => 'tag_list'} %><br />
|
||||
<br />
|
||||
<%= form.text_field :tag_list, {:autocomplete => "off", :class => 'tag_list'} %><br />
|
||||
<br/>
|
||||
<%= form.label :description %><br />
|
||||
<%= form.text_area :description %><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/>
|
|
@ -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,17 +1,17 @@
|
|||
<h1>Edit Photo</h1>
|
||||
|
||||
<%= image_tag @photo.file.preview.url %>
|
||||
|
||||
<%= image_tag @photo.attachment.preview.url %>
|
||||
|
||||
<%= form_for @photo do |f| %>
|
||||
<%= hidden_field_tag :collection_id, params[:collection_id] %>
|
||||
<%= hidden_field_tag :album_id, params[:album_id] %>
|
||||
<%= f.error_messages %>
|
||||
<%= render :partial => "form", :object => f %>
|
||||
<%= f.submit "Update" %>
|
||||
<%= hidden_field_tag :collection_id, params[:collection_id] %>
|
||||
<%= hidden_field_tag :album_id, params[:album_id] %>
|
||||
<%= f.error_messages %>
|
||||
<%= render :partial => "form", :object => f %>
|
||||
<%= f.submit "Update" %>
|
||||
<% end %>
|
||||
|
||||
<%= content_for :action_links do %>
|
||||
<%= link_to("Delete photo", { :action => "destroy", :id => @photo, :collection_id => params[:collection_id] },
|
||||
:confirm => "Are you sure you want to delete this photo?",
|
||||
:method => :delete) %>
|
||||
<%= link_to("Delete photo", {:action => "destroy", :id => @photo, :collection_id => params[:collection_id]},
|
||||
:confirm => "Are you sure you want to delete this photo?",
|
||||
:method => :delete) %>
|
||||
<% end %>
|
|
@ -1,15 +1,15 @@
|
|||
<%= form_for :photos, :url => update_multiple_photos_path, :html => { :method => :put } do |f| %>
|
||||
<% for photo in @photos %>
|
||||
<p>
|
||||
<%= f.fields_for photo, :index => photo.id do |p|%>
|
||||
<%= p.check_box :_delete %>
|
||||
<%= render :partial => "photos/thumb", :locals => {:photo => photo } %>
|
||||
<%= p.text_field :title %>
|
||||
<%= p.text_field :tags, :value => photo.tag_list %>
|
||||
<% end%>
|
||||
</p>
|
||||
<% end%>
|
||||
<p><%= f.submit "Submit" %></p>
|
||||
<%= form_for :photos, :url => update_multiple_photos_path, :html => {:method => :put} do |f| %>
|
||||
<% for photo in @photos %>
|
||||
<p>
|
||||
<%= f.fields_for photo, :index => photo.id do |p| %>
|
||||
<%= p.check_box :_delete %>
|
||||
<%= render :partial => "photos/thumb", :locals => {:photo => photo} %>
|
||||
<%= p.text_field :title %>
|
||||
<%= p.text_field :tags, :value => photo.tag_list %>
|
||||
<% end %>
|
||||
</p>
|
||||
<% end %>
|
||||
<p><%= f.submit "Submit" %></p>
|
||||
<% end %>
|
||||
|
||||
<br /><%= link_to "Back to #{@album.title}", @album %>
|
||||
<br/><%= link_to "Back to #{@album.title}", @album %>
|
|
@ -1,6 +1,9 @@
|
|||
<ul><%= render :partial => 'photos/thumb',:collection => @photos, :as => :photo %></ul>
|
||||
<%#= render :partial => 'photos/thumb', :collection => @photos, :as => :photo %>
|
||||
<%= paginate @photos %>
|
||||
<%= render :partial => 'photos/row_collections' %>
|
||||
<%= paginate @photos %>
|
||||
|
||||
<%= content_for :action_links do %>
|
||||
<%= link_to "Show albums containing photos tagged with #{params[:q]}", albums_path(:q => params[:q]) if params[:q] %>
|
||||
<%= link_to "Show all photos tagged with #{params[:tag_id]}", tag_photos_path(params[:tag_id]) if params[:tag_id] && params[:album_id] %>
|
||||
<%= link_to "Show albums containing photos tagged with #{params[:q]}", albums_path(:q => params[:q]) if params[:q] %>
|
||||
<%= link_to "Show all photos tagged with #{params[:tag_id]}", tag_photos_path(params[:tag_id]) if params[:tag_id] && params[:album_id] %>
|
||||
<% end %>
|
|
@ -1,34 +1,34 @@
|
|||
<h2><%= @photo.title%></h2>
|
||||
<h2><%= @photo.title %></h2>
|
||||
|
||||
<div id="fullimage">
|
||||
<div id="navigation">
|
||||
<p class="links">
|
||||
<% unless @previous.nil? %>
|
||||
<%= link_to "Previous", [ @photo.album.collections.first, @photo.album, @previous] %>
|
||||
<% unless @next.nil? %>
|
||||
|
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% unless @next.nil? %>
|
||||
<%= link_to "Next", [ @photo.album.collections.first, @photo.album, @next] %>
|
||||
<% end %>
|
||||
</p>
|
||||
</div>
|
||||
<p><%= link_to_if @next, image_tag(@photo.file.single.url ), [ @photo.album.collections.first, @photo.album, @next] %></p>
|
||||
<div id="navigation">
|
||||
<p class="links">
|
||||
<% unless @previous.nil? %>
|
||||
<%= link_to "Previous", [@photo.album.collections.first, @photo.album, @previous] %>
|
||||
<% unless @next.nil? %>
|
||||
|
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% unless @next.nil? %>
|
||||
<%= link_to "Next", [@photo.album.collections.first, @photo.album, @next] %>
|
||||
<% end %>
|
||||
</p>
|
||||
</div>
|
||||
<p><%= link_to_if @next, image_tag(@photo.attachment.single.url), [@photo.album.collections.first, @photo.album, @next] %></p>
|
||||
</div>
|
||||
|
||||
<p><%= @photo.description %></p>
|
||||
<p>Tagged with:
|
||||
<% for tag in @photo.tags.map{|tag|tag.title}.sort %>
|
||||
<%= link_to tag, tag_photos_path(tag) %>
|
||||
<% end %>
|
||||
<p>Tagged with:
|
||||
<% for tag in @photo.tags.map { |tag| tag.title }.sort %>
|
||||
<%= link_to tag, tag_photos_path(tag) %>
|
||||
<% end %>
|
||||
|
||||
<%= content_for :action_links do %>
|
||||
<% if has_role?("admin") %>
|
||||
<% if params[:collection_id] %>
|
||||
<%= link_to "Edit photo", edit_collection_album_photo_path(params[:collection_id], params[:album_id], @photo) %>
|
||||
<% else %>
|
||||
<%= link_to "Edit photo", edit_photo_path(@photo) %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<%= content_for :action_links do %>
|
||||
<% if current_user and current_user.has_role?("admin") %>
|
||||
<% if params[:collection_id] %>
|
||||
<%= link_to "Edit photo", edit_collection_album_photo_path(params[:collection_id], params[:album_id], @photo) %>
|
||||
<% else %>
|
||||
<%= link_to "Edit photo", edit_photo_path(@photo) %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% end %>
|
|
@ -1,12 +1,12 @@
|
|||
<%= form_for :photos, :url => update_multiple_photos_path, :html => { :method => :put } do |f| %>
|
||||
<% for photo in @photos %>
|
||||
<p>
|
||||
<%= f.fields_for photo do |p|%>
|
||||
<%= render :partial => "photos/thumb", :locals => {:photo => photo } %>
|
||||
<%= p.text_field :title, :index => photo.id %>
|
||||
<%= p.text_field :tags, :index => photo.id, :value => photo.tag_list %>
|
||||
<% end%>
|
||||
</p>
|
||||
<% end%>
|
||||
<p><%= f.submit "Submit" %></p>
|
||||
<%= form_for :photos, :url => update_multiple_photos_path, :html => {:method => :put} do |f| %>
|
||||
<% for photo in @photos %>
|
||||
<p>
|
||||
<%= f.fields_for photo do |p| %>
|
||||
<%= render :partial => "photos/thumb", :locals => {:photo => photo} %>
|
||||
<%= p.text_field :title, :index => photo.id %>
|
||||
<%= p.text_field :tags, :index => photo.id, :value => photo.tag_list %>
|
||||
<% end %>
|
||||
</p>
|
||||
<% end %>
|
||||
<p><%= f.submit "Submit" %></p>
|
||||
<% end %>
|
|
@ -1,86 +1,78 @@
|
|||
<%= 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">
|
||||
$(document).ready(function () {
|
||||
$("#uploader").pluploadQueue({
|
||||
runtimes:'flash,html5,browserplus,silverlight,gears',
|
||||
url:'<%= photos_path %>',
|
||||
max_file_size:'10mb',
|
||||
multipart:true,
|
||||
multipart_params:{
|
||||
'<%= get_session_key %>':encodeURIComponent('<%= cookies[get_session_key] %>'),
|
||||
'authenticity_token':'<%= form_authenticity_token %>',
|
||||
'photo[album_id]':"<%= @album.id %>"
|
||||
},
|
||||
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
|
||||
$("#uploader").pluploadQueue({
|
||||
// General settings
|
||||
runtimes : 'flash,html5,browserplus,silverlight,gears',
|
||||
url : '<%= photos_path %>',
|
||||
max_file_size : '10mb',
|
||||
multipart: true,
|
||||
multipart_params: {
|
||||
'<%= get_session_key %>' : encodeURIComponent('<%= u cookies[get_session_key] %>'),
|
||||
'authenticity_token' : '<%= form_authenticity_token %>',
|
||||
'photo[album_id]' : "<%= @album.id %>"
|
||||
},
|
||||
// Resize images on clientside if we can
|
||||
//resize : {width : 320, height : 240, quality : 90},
|
||||
|
||||
// Resize images on clientside if we can
|
||||
//resize : {width : 320, height : 240, quality : 90},
|
||||
// Specify what files to browse for
|
||||
filters:[
|
||||
{title:"Image files", extensions:"jpg,gif,png,bmp,jpeg,tif,tiff,JPG,GIF,PNG,BMP,JPEG,TIF,TIFF"}
|
||||
],
|
||||
|
||||
// Specify what files to browse for
|
||||
filters : [
|
||||
{title : "Image files", extensions : "jpg,gif,png,bmp,jpeg,tif,tiff"}
|
||||
],
|
||||
// Flash settings
|
||||
flash_swf_url:'/assets/plupload.flash.swf',
|
||||
|
||||
// Flash settings
|
||||
flash_swf_url : '/javascripts/plupload/js/plupload.flash.swf',
|
||||
// Silverlight settings
|
||||
silverlight_xap_url:'/assets/plupload.silverlight.xap',
|
||||
|
||||
// Silverlight settings
|
||||
silverlight_xap_url : '/javascripts/plupload/js/plupload.silverlight.xap',
|
||||
|
||||
// Post init events, bound after the internal events
|
||||
init : {
|
||||
// Post init events, bound after the internal events
|
||||
init:{
|
||||
|
||||
FileUploaded: function(up, file, info) {
|
||||
// Called when a file has finished uploading
|
||||
res = info.response;
|
||||
if (res.substring(0, 7) === "FILEID:") {
|
||||
var image = $('<img>').appendTo('#thumbs')
|
||||
image.css('display','none')
|
||||
image.attr('src', res.substring(7) )
|
||||
image.fadeIn('slow')
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
FileUploaded:function (up, file, info) {
|
||||
// Called when a file has finished uploading
|
||||
res = info.response;
|
||||
if (res.substring(0, 7) === "FILEID:") {
|
||||
var image = $('<img>').appendTo('#thumbs')
|
||||
image.css('display', 'none')
|
||||
image.attr('src', res.substring(7))
|
||||
image.fadeIn('slow')
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Client side form validation
|
||||
$('form').submit(function(e) {
|
||||
var uploader = $('#uploader').pluploadQueue();
|
||||
// Client side form validation
|
||||
$('form').submit(function (e) {
|
||||
var uploader = $('#uploader').pluploadQueue();
|
||||
|
||||
// Validate number of uploaded files
|
||||
if (uploader.total.uploaded == 0) {
|
||||
// Files in queue upload them first
|
||||
if (uploader.files.length > 0) {
|
||||
// When all files are uploaded submit form
|
||||
uploader.bind('UploadProgress', function() {
|
||||
if (uploader.total.uploaded == uploader.files.length)
|
||||
$('form').submit();
|
||||
});
|
||||
|
||||
uploader.start();
|
||||
} else
|
||||
alert('You must at least upload one file.');
|
||||
|
||||
e.preventDefault();
|
||||
}
|
||||
});
|
||||
})
|
||||
</script>
|
||||
// Validate number of uploaded files
|
||||
if (uploader.total.uploaded == 0) {
|
||||
// Files in queue upload them first
|
||||
if (uploader.files.length > 0) {
|
||||
// When all files are uploaded submit form
|
||||
uploader.bind('UploadProgress', function () {
|
||||
if (uploader.total.uploaded == uploader.files.length)
|
||||
$('form').submit();
|
||||
});
|
||||
uploader.start();
|
||||
} else
|
||||
alert('You must at least upload one file.');
|
||||
e.preventDefault();
|
||||
}
|
||||
});
|
||||
})
|
||||
</script>
|
||||
<% end %>
|
||||
|
||||
<form>
|
||||
<div id="uploader">
|
||||
<p>You browser doesn't have Flash, Silverlight, Gears, BrowserPlus or HTML5 support.</p>
|
||||
</div>
|
||||
<div id="uploader">
|
||||
<p>You browser doesn't have Flash, Silverlight, Gears, BrowserPlus or HTML5 support.</p>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
<br>
|
||||
<div id="thumbs"></div>
|
||||
<div id="thumbs"></div>
|
||||
</form>
|
||||
|
||||
<br><%= link_to "Edit uploaded photos", untouched_album_photos_path( @album ) %>
|
||||
<br><%= link_to "Edit uploaded photos", untouched_album_photos_path(@album) %>
|
||||
<br><%= link_to "Back to #{@album.title}", @album %>
|
|
@ -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 %>
|
|
@ -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>
|
|
@ -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>
|