From 1185bc43549129d3815973277deb8751b47b9eab Mon Sep 17 00:00:00 2001 From: Sami Samhuri Date: Wed, 15 Feb 2012 19:26:56 -0800 Subject: [PATCH] remove cruft, refactor --- Readme.md | 6 +- lib/class-ext.rb | 13 + lib/stormy.rb | 8 +- lib/stormy/controllers/accounts_controller.rb | 14 +- lib/stormy/controllers/admin_controller.rb | 118 +---- lib/stormy/controllers/projects_controller.rb | 123 ----- lib/stormy/controllers/public_controller.rb | 2 - lib/stormy/helpers/accounts.rb | 1 - lib/stormy/helpers/admin.rb | 16 +- lib/stormy/helpers/authorization.rb | 47 +- lib/stormy/helpers/utils.rb | 1 + lib/stormy/helpers/views.rb | 13 + lib/stormy/models/account.rb | 122 +---- lib/stormy/models/admin.rb | 124 ----- lib/stormy/models/base.rb | 353 ++++++++++--- lib/stormy/models/project.rb | 162 ------ lib/stormy/server.rb | 6 - public/css/edit-project.css | 86 ---- public/css/jquery.lightbox-0.5.css | 101 ---- public/css/projects.css | 35 -- public/css/uploadify.css | 52 -- public/images/add-photo.png | Bin 1088 -> 0 bytes public/images/lightbox-blank.gif | Bin 43 -> 0 bytes public/images/lightbox-btn-close.gif | Bin 700 -> 0 bytes public/images/lightbox-btn-next.gif | Bin 812 -> 0 bytes public/images/lightbox-btn-prev.gif | Bin 832 -> 0 bytes public/images/lightbox-ico-loading.gif | Bin 3990 -> 0 bytes public/images/logo.png | Bin 126880 -> 4099 bytes public/images/sign-up-now-button-hover.png | Bin 4788 -> 0 bytes public/images/sign-up-now-button.png | Bin 4686 -> 0 bytes public/js/account.js | 28 +- public/js/admin-project.js | 7 - public/js/edit-project.js | 215 -------- public/js/jquery.dragsort.js | 297 ----------- public/js/jquery.lightbox-0.5.js | 472 ------------------ public/js/jquery.uploadify.v2.1.4.js | 296 ----------- public/js/projects.js | 5 - public/js/sign-in.js | 2 - public/js/swfobject.js | 4 - public/uploadify/cancel.png | Bin 2960 -> 0 bytes public/uploadify/uploadify.swf | Bin 22894 -> 0 bytes test/common.rb | 43 -- test/controllers/test-accounts_controller.rb | 13 +- test/controllers/test-admin_controller.rb | 193 +------ test/controllers/test-projects_controller.rb | 262 ---------- test/fixtures/accounts.json | 2 + test/fixtures/admins.json | 12 - test/fixtures/projects.json | 14 - test/helpers/test-accounts.rb | 1 - test/helpers/test-admin.rb | 8 - test/helpers/test-authorization.rb | 113 +---- test/helpers/test-views.rb | 7 + test/models/test-account.rb | 48 +- test/models/test-admin.rb | 237 --------- test/models/test-base.rb | 29 +- test/models/test-project.rb | 160 ------ test/photos/wild-wacky-action-bike.jpg | Bin 22465 -> 0 bytes test/test-config.rb | 2 +- views/account.erb | 133 ++--- views/admin/accounts.erb | 2 - views/admin/admins.erb | 44 -- views/admin/layout.erb | 48 -- views/admin/project.erb | 45 -- views/admin/projects.erb | 18 - views/admin/sign-in.erb | 27 - views/contact.erb | 14 +- views/edit-project.erb | 80 --- views/email/error-notification.erb | 10 - views/error.erb | 2 +- views/faq.erb | 2 +- views/forgot-password.erb | 2 +- views/layout.erb | 118 +++-- views/not-found.erb | 10 +- views/projects.erb | 22 - views/reset-password.erb | 2 +- views/sign-in.erb | 71 ++- views/sign-up.erb | 82 ++- views/terms.erb | 14 +- 78 files changed, 682 insertions(+), 3937 deletions(-) create mode 100644 lib/class-ext.rb delete mode 100644 lib/stormy/controllers/projects_controller.rb delete mode 100644 lib/stormy/models/admin.rb delete mode 100644 lib/stormy/models/project.rb delete mode 100644 public/css/edit-project.css delete mode 100644 public/css/jquery.lightbox-0.5.css delete mode 100644 public/css/projects.css delete mode 100644 public/css/uploadify.css delete mode 100644 public/images/add-photo.png delete mode 100755 public/images/lightbox-blank.gif delete mode 100755 public/images/lightbox-btn-close.gif delete mode 100755 public/images/lightbox-btn-next.gif delete mode 100755 public/images/lightbox-btn-prev.gif delete mode 100755 public/images/lightbox-ico-loading.gif delete mode 100644 public/images/sign-up-now-button-hover.png delete mode 100644 public/images/sign-up-now-button.png delete mode 100644 public/js/admin-project.js delete mode 100644 public/js/edit-project.js delete mode 100644 public/js/jquery.dragsort.js delete mode 100644 public/js/jquery.lightbox-0.5.js delete mode 100644 public/js/jquery.uploadify.v2.1.4.js delete mode 100644 public/js/projects.js delete mode 100644 public/js/swfobject.js delete mode 100755 public/uploadify/cancel.png delete mode 100755 public/uploadify/uploadify.swf delete mode 100644 test/controllers/test-projects_controller.rb delete mode 100644 test/fixtures/admins.json delete mode 100644 test/fixtures/projects.json delete mode 100644 test/models/test-admin.rb delete mode 100644 test/models/test-project.rb delete mode 100644 test/photos/wild-wacky-action-bike.jpg delete mode 100644 views/admin/admins.erb delete mode 100644 views/admin/layout.erb delete mode 100644 views/admin/project.erb delete mode 100644 views/admin/projects.erb delete mode 100644 views/admin/sign-in.erb delete mode 100644 views/edit-project.erb delete mode 100644 views/projects.erb diff --git a/Readme.md b/Readme.md index 96b8aea..cfd25b7 100644 --- a/Readme.md +++ b/Readme.md @@ -3,22 +3,18 @@ A web server blueprint using Sinatra and Redis. Storm Weather is only a vague idea. Trying to nail down a lightweight blueprint for -projects that have user accounts and admin accounts. +projects that have user accounts. ## Models ### Account Model -### Admin Model - ## Controllers ### Account Controller -### Admin Controller - ### Public Controller diff --git a/lib/class-ext.rb b/lib/class-ext.rb new file mode 100644 index 0000000..c08d50d --- /dev/null +++ b/lib/class-ext.rb @@ -0,0 +1,13 @@ +# Copyright 2012 Sami Samhuri + +class Class + + def singleton + (class < e + rescue Account::DuplicateFieldError => e flash[:warning] = "That email address is already taken." session[:fields] = fields session[:fields]['terms'] = params['terms'] @@ -48,7 +48,7 @@ module Stormy end get '/sign-in' do - redirect '/projects' if authorized? && production? + redirect '/account' if authorized? && production? title 'Sign In' stylesheet 'sign-in' @@ -70,7 +70,7 @@ module Stormy else response.delete_cookie('remembered') end - url = session.delete(:original_url) || '/projects' + url = session.delete(:original_url) || '/account' redirect url else flash[:warning] = "Incorrect email address or password." @@ -121,7 +121,7 @@ module Stormy authorize! current_account.password = params['password'] current_account.save! - redirect '/projects' + redirect '/account' end get '/account' do @@ -186,7 +186,7 @@ module Stormy current_account.update({ params['id'] => params['value'] }) end ok - rescue Account::EmailTakenError => e + rescue Account::DuplicateFieldError => e fail('taken') rescue Account::InvalidDataError => e fail('invalid') diff --git a/lib/stormy/controllers/admin_controller.rb b/lib/stormy/controllers/admin_controller.rb index 74a28a1..d803b98 100644 --- a/lib/stormy/controllers/admin_controller.rb +++ b/lib/stormy/controllers/admin_controller.rb @@ -6,48 +6,7 @@ module Stormy get '/admin' do admin_authorize! title "Dashboard" - erb :'admin/dashboard', :layout => :'admin/layout' - end - - get '/admin/sign-in' do - title "Sign In" - script 'sign-in' - stylesheet 'sign-in' - erb :'admin/sign-in', :layout => :'admin/layout' - end - - post '/admin/sign-in' do - if id = Admin.check_password(params['email'], params['password']) - authorize_admin(id) - redirect session.delete(:original_url) || '/admin' - else - flash[:notice] = "Incorrect email address or password." - redirect '/admin/sign-in' - end - end - - post '/admin/sign-out' do - session.delete(:admin_id) - redirect '/admin' - end - - get '/admin/password' do - admin_authorize! - title 'Change password' - erb :'admin/password', :layout => :'admin/layout' - end - - post '/admin/password' do - admin_authorize! - if params['password'] == params['password_confirmation'] - current_admin.password = params['password'] - current_admin.save - flash[:notice] = "Password changed." - redirect '/admin' - else - flash[:warning] = "Passwords do not match." - redirect '/admin/password' - end + erb :'admin/dashboard' end @@ -60,7 +19,7 @@ module Stormy mark_last_listing title "Accounts" @accounts = Account.fetch_all.sort { |a,b| a.name <=> b.name } - erb :'admin/accounts', :layout => :'admin/layout' + erb :'admin/accounts' end get '/admin/account/:email' do |email| @@ -69,7 +28,7 @@ module Stormy mark_last_listing title "#{@account.name}'s Account" script 'admin-account' - erb :'admin/account', :layout => :'admin/layout' + erb :'admin/account' else flash[:notice] = "No account with email #{email}" redirect last_listing @@ -79,7 +38,7 @@ module Stormy get '/admin/sign-in-as/:email' do |email| admin_authorize! authorize_account(Account.id_from_email(email)) - redirect '/projects' + redirect '/account' end get '/admin/account/:email/delete' do |email| @@ -105,7 +64,7 @@ module Stormy if new_email != @account.email begin @account.update_email(new_email) - rescue Account::EmailTakenError => e + rescue Account::DuplicateFieldError => e flash[:warning] = "That email address is already taken." redirect '/admin/account/' + email end @@ -124,38 +83,6 @@ module Stormy end - ################ - ### Projects ### - ################ - - get '/admin/projects' do - admin_authorize! - mark_last_listing - title "Projects" - @projects = Project.fetch_all.sort { |a,b| a.id <=> b.id } - erb :'admin/projects', :layout => :'admin/layout' - end - - get '/admin/project/:id' do |id| - admin_authorize! - if @project = Project.fetch(id) - title "Project ##{id}" - title "#{title} (#{@project.name})" if @project.name - script 'admin-project' - erb :'admin/project', :layout => :'admin/layout' - else - flash[:notice] = "No such project (ID #{id})." - redirect last_listing - end - end - - get '/admin/project/:id/delete' do |id| - admin_authorize! - Project.delete!(id) - redirect last_listing - end - - ########### ### FAQ ### ########### @@ -170,7 +97,7 @@ module Stormy

Yes my son.

EOT end - erb :'admin/faq', :layout => :'admin/layout' + erb :'admin/faq' end post '/admin/faq' do @@ -180,38 +107,5 @@ module Stormy redirect '/admin/faq' end - - ###################### - ### Admin Accounts ### - ###################### - - get '/admin/admins' do - admin_authorize! - @admins = Admin.fetch_all.sort { |a,b| a.name <=> b.name } - @fields = session.delete(:fields) || {} - title 'Admin Accounts' - stylesheet 'admins' - erb :'admin/admins', :layout => :'admin/layout' - end - - post '/admin/admins' do - admin_authorize! - if params['password'] == params['password_confirmation'] - admin = Admin.create(params) - flash[:notice] = "Added #{params['name']} (#{params['email']}) as an admin." - else - session[:fields] = params.slice('name', 'email') - flash[:warning] = "Passwords do not match." - end - redirect '/admin/admins' - end - - get '/admin/admins/:id/delete' do |id| - admin_authorize! - Admin.delete!(id) - flash[:notice] = "Deleted." - redirect '/admin/admins' - end - end end diff --git a/lib/stormy/controllers/projects_controller.rb b/lib/stormy/controllers/projects_controller.rb deleted file mode 100644 index c52d244..0000000 --- a/lib/stormy/controllers/projects_controller.rb +++ /dev/null @@ -1,123 +0,0 @@ -# Copyright 2011 Beta Street Media - -module Stormy - class Server < Sinatra::Base - - get '/projects' do - authorize! - @projects = current_account.sorted_projects - title 'Projects' - stylesheet 'projects' - script 'projects' - erb :projects - end - - get '/project/:id' do |id| - authorize_project!(id) - if current_project.name.blank? - title "Project ID #{id}" - else - title current_project.name - end - stylesheet 'jquery.lightbox-0.5' - script 'jquery.lightbox-0.5' - script 'jquery.dragsort' - stylesheet 'edit-project' - script 'edit-project' - - # fuck IE - if request.user_agent.match(/msie/i) - stylesheet 'uploadify' - script 'swfobject' - script 'jquery.uploadify.v2.1.4' - end - - @errors = session.delete('errors') - @project = current_project - erb :'edit-project' - end - - post '/project/update' do - id = params['id'] - if admin_authorized? - current_project(id) - else - authorize_project!(id) - end - - begin - current_project.update(params) - - flash[:notice] = "Project saved." - rescue Project::InvalidDataError => e - flash[:warning] = "There are some errors with your project." - session['errors'] = e.fields - end - - redirect '/project/' + params['id'] - end - - post '/project/add-photo' do - content_type :json - id = params['id'] - if admin_authorized? - current_project(id) - else - authorize_project_api!(id) - end - - if photo = current_project.add_photo(params['photo'][:tempfile].path) - ok({ - 'n' => current_project.count_photos, - 'photo' => photo - }) - else - fail('limit') - end - end - - # fuck IE - post '/uploadify' do - content_type :json - authorize_project_api!(params['id']) - if photo = current_project.add_photo(params['Filedata'][:tempfile].path) - ok({ - 'n' => current_project.count_photos, - 'photo' => photo - }) - else - content_type 'text/plain' - bad_request - end - end - - post '/project/remove-photo' do - content_type :json - if admin_authorized? - current_project(params['id']) - else - authorize_project_api!(params['id']) - end - - current_project.remove_photo(params['photo_id']) - ok({ - 'photos' => current_project.photos - }) - end - - post '/project/photo-order' do - content_type :json - id = params['id'] - if admin_authorized? - current_project(id) - else - authorize_project_api!(id) - end - - current_project.photo_ids = params['order'] - current_project.save! - ok - end - - end -end diff --git a/lib/stormy/controllers/public_controller.rb b/lib/stormy/controllers/public_controller.rb index c073779..9e053cb 100644 --- a/lib/stormy/controllers/public_controller.rb +++ b/lib/stormy/controllers/public_controller.rb @@ -7,8 +7,6 @@ module Stormy get '/' do cache_control :public, :must_revalidate, :max_age => 60 stylesheet 'index' - stylesheet 'jquery.lightbox-0.5' - script 'jquery.lightbox-0.5' script 'index' erb :index end diff --git a/lib/stormy/helpers/accounts.rb b/lib/stormy/helpers/accounts.rb index 0f1f1d5..dc56ac7 100644 --- a/lib/stormy/helpers/accounts.rb +++ b/lib/stormy/helpers/accounts.rb @@ -25,7 +25,6 @@ module Stormy end def send_verification_mail(account = current_account, subject = nil) - account.create_email_verification_token body = erb(:'email/email-verification', :layout => :'email/layout', :locals => { :name => account.first_name, :email => account.email, diff --git a/lib/stormy/helpers/admin.rb b/lib/stormy/helpers/admin.rb index b35818e..e7ec214 100644 --- a/lib/stormy/helpers/admin.rb +++ b/lib/stormy/helpers/admin.rb @@ -10,21 +10,13 @@ module Stormy Account.count end - def num_admins - Models::Admin.count - end - - def num_projects - Project.count - end - # Used to redirect back to the most recent list of things. # - # i.e. someone goes to /admin -> /admin/account/foo -> /admin/project/007 - # if they delete that project they should go back to /admin/account/foo + # i.e. someone goes to /admin -> /admin/account/foo -> /admin/thing/007 + # if they delete that thing they should go back to /admin/account/foo # - # however if they go /admin -> /admin/projects -> /admin/project/007 - # and then delete that project they should go back to /admin/projects + # however if they go /admin -> /admin/things -> /admin/thing/007 + # and then delete that thing they should go back to /admin/things def last_listing session.delete(:last_listing) || '/admin' end diff --git a/lib/stormy/helpers/authorization.rb b/lib/stormy/helpers/authorization.rb index d57cff8..d4a1e9b 100644 --- a/lib/stormy/helpers/authorization.rb +++ b/lib/stormy/helpers/authorization.rb @@ -42,53 +42,14 @@ module Stormy end end - def current_project(id = nil) - if id - @current_project = Project.fetch(id) - else - @current_project - end - end - - def project_authorized? - current_project && current_account && current_project.account_id == current_account.id - end - - def authorize_project_api!(id) - authorize_api! - current_project(id) - throw(:halt, fail('no such project')) unless current_project - unless project_authorized? - content_type 'text/plain' - throw(:halt, not_authorized) - end - end - - def authorize_project!(id) - authorize! - current_project(id) - unless current_project && project_authorized? - flash[:warning] = 'No such project.' - redirect '/projects' - end - end - - def authorize_admin(id) - session[:admin_id] = id - end - - def deauthorize_admin - session.delete(:admin_id) - end - def admin_authorized? - session[:admin_id] && Models::Admin.exists?(session[:admin_id]) + authorized? && current_account.has_role?('admin') end def admin_authorize! unless admin_authorized? session[:original_url] = request.url - redirect '/admin' + redirect '/sign-in' end end @@ -99,10 +60,6 @@ module Stormy end end - def current_admin - @current_admin ||= Models::Admin.fetch(session[:admin_id]) - end - end end end diff --git a/lib/stormy/helpers/utils.rb b/lib/stormy/helpers/utils.rb index 99161b4..e24dffe 100644 --- a/lib/stormy/helpers/utils.rb +++ b/lib/stormy/helpers/utils.rb @@ -1,5 +1,6 @@ # Copyright 2012 Sami Samhuri +require 'json' require 'stormy/config' module Stormy diff --git a/lib/stormy/helpers/views.rb b/lib/stormy/helpers/views.rb index 2cbcf0f..e7e3dfd 100644 --- a/lib/stormy/helpers/views.rb +++ b/lib/stormy/helpers/views.rb @@ -64,6 +64,15 @@ module Stormy end end + def breadcrumbs + @breadcrumbs ||= [] + end + + def breadcrumb(crumb) + crumb[:path] ||= '/' + crumb[:name].downcase + breadcrumbs << crumb + end + def format_dollars(amount, currency = 'CAD') '%s $%.2f' % [currency, amount / 100.0] end @@ -116,6 +125,10 @@ module Stormy RDiscount.new(s.to_s).to_html end + def admin_page?(path = request.path_info) + path.starts_with?('/admin') + end + end end end diff --git a/lib/stormy/models/account.rb b/lib/stormy/models/account.rb index 269f7d1..3e44914 100644 --- a/lib/stormy/models/account.rb +++ b/lib/stormy/models/account.rb @@ -7,27 +7,26 @@ module Stormy module Models class Account < Base - class EmailTakenError < RuntimeError; end class IncorrectPasswordError < RuntimeError; end - name 'account' + Roles = %w[user admin] + + model_name 'account' field :id, :required => true - field :email, :type => :email, :required => true + field :email, :type => :email, :required => true, :unique => true field :first_name, :required => true, :updatable => true field :last_name, :required => true, :updatable => true field :phone, :type => :phone, :updatable => true - field :hashed_password, :required => true - field :password - field :created_timestamp, :type => :integer field :email_verification_token, :nullify_if_blank => true field :email_verified? + field :hashed_password, :required => true + field :password field :password_reset_token, :nullify_if_blank => true - - @@account_email_index_key = Stormy.key('index:account-email') + field :role, :required => true ### Class Methods @@ -41,18 +40,8 @@ module Stormy end end - def self.email_taken?(email) - !! redis.hget(@@account_email_index_key, email.to_s.strip.downcase) - end - - def self.fetch_by_email(email) - if id = id_from_email(email) - fetch(id) - end - end - def self.reset_password(email) - if key = key_from_email(email) + if key = key(id_from_email(email)) token = redis.hget(key, 'password_reset_token') if token.blank? token = UUID.generate @@ -75,12 +64,8 @@ module Stormy end end - def self.id_from_email(email) - redis.hget(@@account_email_index_key, email.strip.downcase) - end - def self.verify_email(email, token) - if key = key_from_email(email) + if key = key(id_from_email(email)) expected_token = redis.hget(key, 'email_verification_token') verified = token == expected_token if verified @@ -92,21 +77,12 @@ module Stormy end def self.email_verified?(email) - if key = key_from_email(email) + if key = key(id_from_email(email)) redis.hget(key, 'email_verified') == 'true' end end - ### Private Class Methods - - def self.key_from_email(email) - key(id_from_email(email)) - end - - private_class_method :key_from_email - - ### Instance Methods def initialize(fields = {}, options = {}) @@ -120,36 +96,20 @@ module Stormy end def create - raise EmailTakenError if email_taken? - - # new accounts get an id and timestamp - self.id = UUID.generate unless id.present? - self.created_timestamp = Time.now.to_i - + self.role = 'user' if role.blank? super - - create_email_verification_token - - # add to index - redis.hset(@@account_email_index_key, email.downcase, id) - - self end - def delete! - project_ids.each { |id| Project.delete!(id) } - super - redis.hdel(@@account_email_index_key, email.strip.downcase) + def has_role?(role) + Roles.index(self.role) >= Roles.index(role) end - def email_taken?(email = @email) - self.class.email_taken?(email) - end - - def create_email_verification_token - self.email_verification_token ||= UUID.generate - redis.hset(key, 'email_verification_token', email_verification_token) - email_verification_token + def email_verification_token + unless @email_verification_token + @email_verification_token = UUID.generate + redis.hset(key, 'email_verification_token', @email_verification_token) + end + @email_verification_token end def password @@ -167,41 +127,16 @@ module Stormy "#{first_name} #{last_name}" end - def count_projects - redis.scard(project_ids_key) - end - - def project_ids - redis.smembers(project_ids_key) - end - - def projects - project_ids.map { |pid| Project.fetch(pid) } - end - - def sorted_projects - @sorted_projects ||= projects.sort { |a,b| a.created_timestamp <=> b.created_timestamp } - end - - def add_project_id(id) - redis.sadd(project_ids_key, id) - end - - def remove_project_id(id) - redis.srem(project_ids_key, id) - end - def update_email(new_email) new_email = new_email.strip if email != new_email - raise EmailTakenError if new_email.downcase != email.downcase && email_taken?(new_email) - raise InvalidDataError.new({ 'email' => 'invalid' }) unless field_valid?('email', new_email) - if email.downcase != new_email.downcase - self.email_verified = false - redis.hdel(@@account_email_index_key, email.downcase) - redis.hset(@@account_email_index_key, new_email.downcase, id) - end + changed = new_email.downcase != email.downcase + raise DuplicateFieldError.new(:email => new_email) if changed && email_taken?(new_email) + raise InvalidDataError.new('email' => 'invalid') unless field_valid?('email', new_email) + self.email_verified = false if changed + remove_from_field_index(:email) if changed self.email = new_email + add_to_field_index(:email) if changed save! end end @@ -214,13 +149,6 @@ module Stormy self.password = new_password end - - private - - def project_ids_key - @project_ids_key ||= "#{key}:project-ids" - end - end end end \ No newline at end of file diff --git a/lib/stormy/models/admin.rb b/lib/stormy/models/admin.rb deleted file mode 100644 index 961073d..0000000 --- a/lib/stormy/models/admin.rb +++ /dev/null @@ -1,124 +0,0 @@ -# Copyright 2012 Sami Samhuri - -require 'bcrypt' -require 'uuid' - -module Stormy - module Models - class Admin < Base - - class EmailTakenError < RuntimeError; end - class IncorrectPasswordError < RuntimeError; end - - name 'admin' - - field :id, :required => true - - field :name, :required => true, :updatable => true - field :email, :type => :email, :required => true - field :hashed_password, :required => true - field :password - - @@admin_email_index_key = Stormy.key('index:admin-email') - - - ### Class Methods - - def self.key_from_email(email) - key(id_from_email(email)) - end - - def self.check_password(email, password) - id = id_from_email(email) - key = self.key(id) - if key - hashed_password = BCrypt::Password.new(redis.hget(key, 'hashed_password')) - id if hashed_password == password - end - end - - def self.email_taken?(email) - !! redis.hget(@@admin_email_index_key, email.to_s.strip.downcase) - end - - def self.fetch_by_email(email) - key = key_from_email(email) - new(redis.hgetall(key)) if key - end - - def self.id_from_email(email) - redis.hget(@@admin_email_index_key, email.strip.downcase) - end - - - ### Instance Methods - - def initialize(fields = {}, options = {}) - super(fields, options) - - if fields['hashed_password'] - self.hashed_password = BCrypt::Password.new(fields['hashed_password']) - else - self.password = fields['password'] - end - end - - def create - raise EmailTakenError if email_taken? - - self.id = UUID.generate unless id.present? - - super - - # add to index - redis.hset(@@admin_email_index_key, @email.downcase, @id) - - self - end - - def delete! - if super - redis.hdel(@@admin_email_index_key, @email.strip.downcase) - end - end - - def email_taken?(email = @email) - self.class.email_taken?(email) - end - - def password - @password ||= BCrypt::Password.new(hashed_password) - end - - def password=(new_password) - if new_password.present? - self.hashed_password = BCrypt::Password.create(new_password) - @password = nil - end - end - - def update_email(new_email) - new_email = new_email.strip - if email != new_email - raise EmailTakenError if new_email.downcase != email.downcase && email_taken?(new_email) - raise InvalidDataError.new({ 'email' => 'invalid' }) unless field_valid?('email', new_email) - if email.downcase != new_email.downcase - redis.hdel(@@admin_email_index_key, email.downcase) - redis.hset(@@admin_email_index_key, new_email.downcase, id) - end - self.email = new_email - save! - end - end - - def update_password(old_password, new_password) - hashed_password = BCrypt::Password.new(redis.hget(key, 'hashed_password')) - raise IncorrectPasswordError unless hashed_password == old_password - raise InvalidDataError.new({ 'password' => 'missing' }) if new_password.blank? - redis.hset(key, 'hashed_password', BCrypt::Password.create(new_password)) - self.password = new_password - end - - end - end -end \ No newline at end of file diff --git a/lib/stormy/models/base.rb b/lib/stormy/models/base.rb index 28529e7..b0ca47f 100644 --- a/lib/stormy/models/base.rb +++ b/lib/stormy/models/base.rb @@ -15,11 +15,18 @@ module Stormy end end + class DuplicateFieldError < RuntimeError + attr_reader :field + def initialize(field = nil) + @field = field + end + end + def self.clean_number(number) number.gsub(/[^\d]/, '').sub(/^1/, '') end - # Allows any 10 digit number in North America, or an empty field (for account creation). + # Allows any 10 digit number in North America, or an empty field PhoneNumberValidator = proc do |number| if number.present? clean_number(number).length == 10 @@ -48,7 +55,7 @@ module Stormy # Define or retrieve the name of this model. - def self.name(name = nil) + def self.model_name(name = nil) if name @model_name = name end @@ -61,20 +68,33 @@ module Stormy @fields ||= {} end + def self.inherit_from(parent) + fields.merge!(parent.fields) + parent.belongs_to_relationships.each do |key, value| + belongs_to_relationships[key] = value.dup + end + parent.has_many_relationships.each do |key, value| + has_many_relationships[key] = value.dup + end + end # Define fields like so: # # field :id, :type => :integer, :required => true - # field :name, :required => true, :updatable => true + # field :name, :required => true, :updatable => true, :indexed => true + # field :email, :required => true, :updatable => true, :unique => true # field :verified? # # Defaults: { # :type => :string, # :required => false, # :updatable => false, + # :accessors => true, # :validator => nil, # with some exceptions # :default => {}, - # :nullify_if_blank => false + # :nullify_if_blank => false, + # :indexed => false, + # :unique => false # } # # Types: :string, :integer, :boolean, :json, as well as @@ -91,12 +111,26 @@ module Stormy # JSON fields accept a :default option used to initialize # a JSON field, and also when a parse fails. # - # Attribute accessors are defined for each field and boolean - # fields get a predicate method as well, e.g. verified? + # Unless :accessors is false, attribute accessors are + # defined for each field. Boolean fields get a predicate + # method as well, e.g. verified? # # Changed fields are tracked and only changed fields are # persisted on a `save`. # + # If the :indexed option is truthy an index on that field + # will be created and maintained and there will be a class + # method to fetch objects by that field. + # + # e.g. fetch_by_name(name) + # + # If the :unique option is truthy then values for that field + # must be unique across all instances. This implies :indexed + # and adds a method to see if a value is taken, to the class + # and to instances. + # + # e.g. email_taken?(email) + # def self.field(name, options = {}) if name.to_s.ends_with?('?') options[:type] = :boolean @@ -106,79 +140,182 @@ module Stormy name = name.to_sym options[:type] ||= :string + unless options.has_key?(:accessors) + options[:accessors] = true + end + + if options[:unique] + options[:indexed] = true + end + case options[:type] when :email - options[:validator] ||= EmailAddressValidator + options[:validator] = EmailAddressValidator unless options.has_key?(:validator) options[:type] = :string when :phone - options[:validator] ||= PhoneNumberValidator + options[:validator] = PhoneNumberValidator unless options.has_key?(:validator) options[:type] = :string when :json - options[:default] ||= {} + options[:default] = {} unless options.has_key?(:default) end fields[name] = options - define_method(name) do - instance_variable_get("@#{name}") - end - case options[:type] - when :string - define_method("#{name}=") do |value| - s = - if options[:nullify_if_blank] && value.blank? - nil - else - value.to_s.strip - end - instance_variable_set("@#{name}", s) - changed_fields[name] = s - end - - when :integer - define_method("#{name}=") do |value| - i = value.to_i - instance_variable_set("@#{name}", i) - changed_fields[name] = i - end - - when :boolean - define_method("#{name}=") do |value| - b = value == 'true' || value == true - instance_variable_set("@#{name}", b) - changed_fields[name] = b - end - define_method("#{name}?") do + if options[:accessors] + define_method(name) do instance_variable_get("@#{name}") end - when :json - define_method(name) do - unless value = instance_variable_get("@#{name}") - value = options[:default].dup - send("#{name}=", value) - end - value - end - define_method("#{name}=") do |value| - obj = - if value.is_a?(String) - if value.length > 0 - JSON.parse(value) + case options[:type] + when :string + define_method("#{name}=") do |value| + s = + if options[:nullify_if_blank] && value.blank? + nil else - options[:default].dup + value.to_s.strip end - else - value + instance_variable_set("@#{name}", s) + changed_fields[name] = s + end + + when :integer + define_method("#{name}=") do |value| + i = value.to_i + instance_variable_set("@#{name}", i) + changed_fields[name] = i + end + + when :boolean + define_method("#{name}=") do |value| + b = value == 'true' || value == true + instance_variable_set("@#{name}", b) + changed_fields[name] = b + end + define_method("#{name}?") do + instance_variable_get("@#{name}") + end + + when :json + define_method(name) do + unless value = instance_variable_get("@#{name}") + value = options[:default].dup + send("#{name}=", value) end - instance_variable_set("@#{name}", obj) - changed_fields[name] = obj + value + end + define_method("#{name}=") do |value| + obj = + if value.is_a?(String) + if value.length > 0 + JSON.parse(value) + else + options[:default].dup + end + else + value + end + instance_variable_set("@#{name}", obj) + changed_fields[name] = obj + end + + else + define_method("#{name}=") do |value| + instance_variable_set("@#{name}", value) + changed_fields[name] = value + end + end + end # if options[:accessors] + + if options[:indexed] + index_key_method_name = "#{name}_index_key" + define_class_method(index_key_method_name) do + Stormy.key("index:#{model_name}-#{name}") + end + define_class_method("fetch_by_#{name}") do |value| + if id = send("id_from_#{name}", value) + fetch(id) + end end - else - define_method("#{name}=") do |value| - instance_variable_set("@#{name}", value) - changed_fields[name] = value + define_class_method("id_from_#{name}") do |value| + redis.hget(send(index_key_method_name), value.to_s.strip.downcase) + end + end + + if options[:unique] + define_class_method("#{name}_taken?") do |value| + !! send("id_from_#{name}", value) + end + + define_method("#{name}_taken?") do |value| + self.class.send("#{name}_taken?", value) + end + end + end + + + ##################### + ### Relationships ### + ##################### + + def self.has_many_relationships + @has_many_relationships ||= {} + end + + def self.has_many(things, options = {}) + thing = things.to_s.singularize + options[:class_name] ||= thing.capitalize + + has_many_relationships[thing] = options + + define_method("#{thing}_ids_key") do + ivar_name = "@#{thing}_ids_key" + unless ids_key = instance_variable_get(ivar_name) + ids_key = "#{key}:#{thing}-ids" + instance_variable_set(ivar_name, ids_key) + end + ids_key + end + private "#{thing}_ids_key" + + define_method("count_#{things}") do + redis.scard(send("#{thing}_ids_key")) + end + + define_method("#{thing}_ids") do + redis.smembers(send("#{thing}_ids_key")) + end + + define_method(things) do + klass = Stormy::Models.const_get(options[:class_name]) + send("#{thing}_ids").map { |id| klass.fetch(id) } + end + + define_method("add_#{thing}_id") do |id| + redis.sadd(send("#{thing}_ids_key"), id) + end + + define_method("remove_#{thing}_id") do |id| + redis.srem(send("#{thing}_ids_key"), id) + end + end + + def self.belongs_to_relationships + @belongs_to_relationships ||= {} + end + + def self.belongs_to(thing, options = {}) + options[:class_name] ||= thing.to_s.capitalize + + field "#{thing}_id".to_sym, :required => options[:required] + + belongs_to_relationships[thing] = options + + define_method(thing) do + klass = Stormy::Models.const_get(options[:class_name]) + if thing_id = send("#{thing}_id") + instance_variable_set("@#{thing}", klass.fetch(thing_id)) end end end @@ -246,14 +383,46 @@ module Stormy end def create + # check for unqiue fields + self.class.fields.each do |name, options| + if options[:unique] && send("#{name}_taken?", send(name)) + raise DuplicateFieldError.new(name => send(name)) + end + end + + if has_field?(:id) && field_required?(:id) + self.id = UUID.generate unless id.present? + end + + if has_field?(:created_timestamp) + self.created_timestamp = Time.now.to_i + end + # raises if invalid save - add_to_index + + add_to_indexes + + self.class.belongs_to_relationships.each do |thing, options| + if obj = send(thing) + obj.send("add_#{self.class.model_name}_id", id) + end + end + self end def delete! - if redis.srem(self.class.model_ids_key, id) + self.class.has_many_relationships.each do |thing, options| + klass = Stormy::Models.const_get(options[:class_name]) + send("#{thing}_ids").each { |id| klass.delete!(id) } + end + if remove_from_indexes + self.class.belongs_to_relationships.each do |thing, options| + if obj = send(thing) + obj.send("remove_#{self.class.model_name}_id", id) + end + end redis.del(key) end end @@ -280,6 +449,12 @@ module Stormy options[:validate] = true unless options.has_key?(:validate) fields.each do |name, value| if options[:all] || field_updatable?(name) + + # ensure uniqueness + if options[:unique] && send("#{name}_taken?", value) + raise DuplicateFieldError.new(name => value) + end + send("#{name}=", value) end end @@ -296,6 +471,10 @@ module Stormy end def save! + if has_field?(:updated_timestamp) + self.updated_timestamp = Time.now.to_i + end + # always update JSON fields because they can be updated without our knowledge field_names.each do |name| if field_type(name) == :json @@ -317,6 +496,7 @@ module Stormy end def validate + # check for invalid fields invalid_fields = field_names.inject({}) do |fields, name| if field_validates?(name) result = validate_field(name, send(name)) @@ -329,6 +509,10 @@ module Stormy end end + def fields + Hash[field_names.zip(field_names.map { |name| send(name) })] + end + private @@ -336,8 +520,39 @@ module Stormy @key ||= self.class.key(self.id) end - def add_to_index - redis.sadd(self.class.model_ids_key, self.id) + def model_name + @model_name ||= self.class.model_name + end + + def add_to_indexes + if redis.sadd(self.class.model_ids_key, id) + self.class.fields.each do |name, options| + add_to_field_index(name) if options[:indexed] + end + end + end + + def add_to_field_index(name) + index_key = self.class.send("#{name}_index_key") + redis.hset(index_key, send(name).to_s.strip.downcase, id) + end + + def remove_from_indexes + if redis.srem(self.class.model_ids_key, id) + success = true + self.class.fields.each do |name, options| + if options[:indexed] + success = success && remove_from_field_index(name) + end + break unless success + end + success + end + end + + def remove_from_field_index(name) + index_key = self.class.send("#{name}_index_key") + redis.hdel(index_key, send(name).to_s.strip.downcase) end def changed_fields @@ -348,6 +563,10 @@ module Stormy self.class.clean_number(number) end + def has_field?(name) + self.class.fields.has_key?(name.to_sym) + end + def field_names self.class.fields.keys end @@ -360,6 +579,10 @@ module Stormy self.class.fields[name.to_sym][:updatable] end + def field_required?(name) + self.class.fields[name.to_sym][:required] + end + def validate_field(name, value) valid = true reason = nil diff --git a/lib/stormy/models/project.rb b/lib/stormy/models/project.rb deleted file mode 100644 index a319b68..0000000 --- a/lib/stormy/models/project.rb +++ /dev/null @@ -1,162 +0,0 @@ -# Copyright 2012 Sami Samhuri - -require 'digest/sha1' -require 'fileutils' -require 'RMagick' - -module Stormy - module Models - class Project < Base - - # max width or height in pixels - MaxPhotoSize = 1200 - MaxPhotos = 10 - - name 'project' - - field :id, :required => true - - field :name, :required => true, :updatable => true - - field :account_id - field :created_timestamp, :type => :integer, :required => true - field :fizzled_timestamp, :type => :integer - field :funded_timestamp, :type => :integer - field :photo_ids, :type => :json, :default => [] - - @@project_name_index_key = Stormy.key('index:project-name') - - def self.fetch_by_name(name) - if id = id_from_name(name) - fetch(id) - end - end - - def self.id_from_name(name) - redis.hget(@@project_name_index_key, name.strip.downcase) - end - - def create - self.id = UUID.generate unless id.present? - self.created_timestamp = Time.now.to_i - - super - - # add to index - redis.hset(@@project_name_index_key, name.downcase, id) - - account.add_project_id(id) if account - - self - end - - def delete! - if super - remove_all_photos! - account.remove_project_id(id) if account - redis.hdel(@@project_name_index_key, name.strip.downcase) - end - end - - def funded? - funded_timestamp > 0 - end - - def funded! - self.funded_timestamp = Time.now.to_i - save! - end - - def fizzled? - fizzled_timestamp > 0 - end - - def fizzled! - self.fizzled_timestamp = Time.now.to_i - save! - end - - def count_photos - photo_ids.length - end - - def add_photo(path) - unless count_photos >= MaxPhotos - photo = Magick::Image.read(path).first - photo.auto_orient! - photo.change_geometry("#{MaxPhotoSize}x#{MaxPhotoSize}>") { |cols, rows, img| img.resize!(cols, rows) } - photo.format = 'jpg' - - FileUtils.mkdir_p(photo_dir) unless File.exists?(photo_dir) - - photo_id = Digest::SHA1.hexdigest(photo.to_blob) - photo.write(photo_path(photo_id)) { self.quality = 80 } - - photo_ids << photo_id - save! - - photo_data(photo_id) - end - end - - def remove_photo(photo_id) - path = photo_path(photo_id) - if i = photo_ids.index(photo_id) - photo_ids.delete_at(i) - end - FileUtils.rm(path) if File.exists?(path) && !photo_ids.include?(photo_id) - save! - end - - def photo_paths - photo_ids.map { |id| photo_path(id) } - end - - def photo_urls - photo_ids.map { |photo_id| "/photos/#{id}/#{photo_id}.jpg" } - end - - def photo_url(photo_id) - "/photos/#{id}/#{photo_id}.jpg" - end - - def photo_data(photo_id) - { - 'id' => photo_id, - 'url' => photo_url(photo_id) - } - end - - def photos - photo_ids.map { |id| photo_data(id) } - end - - def account - if account_id - @account ||= Account.fetch(account_id) - end - end - - - private - - def photo_dir - File.join(Stormy::PhotoDir, @id) - end - - def photo_path(id) - File.join(photo_dir, "#{id}.jpg") - end - - def photos_key - "#{key}:photos" - end - - def remove_all_photos! - FileUtils.rm_rf(photo_dir) if File.exists?(photo_dir) - self.photo_ids = [] - end - - end - end -end diff --git a/lib/stormy/server.rb b/lib/stormy/server.rb index ac7eabd..9186c38 100644 --- a/lib/stormy/server.rb +++ b/lib/stormy/server.rb @@ -7,15 +7,11 @@ require 'sinatra/cookie_thief' require 'sinatra/flash' require 'erubis' -require 'json' require 'pony' require 'redis' require 'redis-store' require 'uuid' -# Ruby extensions -require 'hash-ext' - require 'stormy/models' require 'stormy/controllers' require 'stormy/helpers' @@ -74,8 +70,6 @@ module Stormy if production? body = erb(:'email/error-notification', :layout => false, :locals => { :account => current_account, - :project => current_project, - :admin => current_admin, :error => env['sinatra.error'] }) Pony.mail({ diff --git a/public/css/edit-project.css b/public/css/edit-project.css deleted file mode 100644 index 07bf46a..0000000 --- a/public/css/edit-project.css +++ /dev/null @@ -1,86 +0,0 @@ -.section { width: 90% } - -#photo-form -{ height: 0 -; width: 0 -; opacity: 0 -; position: fixed -; top: 0 -} - -#upload-target -{ width: 0 -; height: 0 -; opacity: 0 -} - -.save -{ width: 90% -; margin: 1em auto -; text-align: right -} - -input.save-button -{ background-color: #092 -; border-color: #061 -} - -.save-button-spinner { display: none } - -table#project-info -{ width: 90% -; margin: 1em auto -} - -table#project-info th -{ color: #405e83 -; text-align: right -; vertical-align: top -; padding: 0.2em 0.5em 0.7em -} - -input[type="text"], -input[type="tel"], -input[type="url"] -{ padding: 0 0.2em -; border: #CCD3DB 1px solid -; font-size: 1em -; height: 1.5em -; margin: 0 -} - -textarea -{ border: #CCD3DB 1px solid -; font-size: 0.9em -; line-height: 1.2em -; padding: 0.3em -; margin: 0 -} - -#photos li -{ display: inline-block -; width: 72px -; height: 84px -; padding: 0 -; margin: 0.2em 0.25em 0.7em -; text-align: center -} - -li#add-photo-box { display: inline-block } -#photos li#add-photo-spinner { height: 18px } - -.add-photo { font-size: 0.8em } -a.add-photo { font-size: 0.9em } -.remove-photo { color: #900 } - -#ie-photo-uploaderQueue { display: none } - -#ie-photo-uploaderUploader -{ height: 64px -; width: 64px -} - -#drag-n-drop -{ padding-left: 3em -; font-style: italic -} diff --git a/public/css/jquery.lightbox-0.5.css b/public/css/jquery.lightbox-0.5.css deleted file mode 100644 index c7c3d1c..0000000 --- a/public/css/jquery.lightbox-0.5.css +++ /dev/null @@ -1,101 +0,0 @@ -/** - * jQuery lightBox plugin - * This jQuery plugin was inspired and based on Lightbox 2 by Lokesh Dhakar (http://www.huddletogether.com/projects/lightbox2/) - * and adapted to me for use like a plugin from jQuery. - * @name jquery-lightbox-0.5.css - * @author Leandro Vieira Pinho - http://leandrovieira.com - * @version 0.5 - * @date April 11, 2008 - * @category jQuery plugin - * @copyright (c) 2008 Leandro Vieira Pinho (leandrovieira.com) - * @license CCAttribution-ShareAlike 2.5 Brazil - http://creativecommons.org/licenses/by-sa/2.5/br/deed.en_US - * @example Visit http://leandrovieira.com/projects/jquery/lightbox/ for more informations about this jQuery plugin - */ -#jquery-overlay { - position: absolute; - top: 0; - left: 0; - z-index: 90; - width: 100%; - height: 500px; -} -#jquery-lightbox { - position: absolute; - top: 0; - left: 0; - width: 100%; - z-index: 100; - text-align: center; - line-height: 0; -} -#jquery-lightbox a img { border: none; } -#lightbox-container-image-box { - position: relative; - background-color: #fff; - width: 250px; - height: 250px; - margin: 0 auto; -} -#lightbox-container-image { padding: 10px; } -#lightbox-loading { - position: absolute; - top: 40%; - left: 0%; - height: 25%; - width: 100%; - text-align: center; - line-height: 0; -} -#lightbox-nav { - position: absolute; - top: 0; - left: 0; - height: 100%; - width: 100%; - z-index: 10; -} -#lightbox-container-image-box > #lightbox-nav { left: 0; } -#lightbox-nav a { outline: none;} -#lightbox-nav-btnPrev, #lightbox-nav-btnNext { - width: 49%; - height: 100%; - zoom: 1; - display: block; -} -#lightbox-nav-btnPrev { - left: 0; - float: left; -} -#lightbox-nav-btnNext { - right: 0; - float: right; -} -#lightbox-container-image-data-box { - font: 10px Verdana, Helvetica, sans-serif; - background-color: #fff; - margin: 0 auto; - line-height: 1.4em; - overflow: auto; - width: 100%; - padding: 0 10px 0; -} -#lightbox-container-image-data { - padding: 0 10px; - color: #666; -} -#lightbox-container-image-data #lightbox-image-details { - width: 70%; - float: left; - text-align: left; -} -#lightbox-image-details-caption { font-weight: bold; } -#lightbox-image-details-currentNumber { - display: block; - clear: left; - padding-bottom: 1.0em; -} -#lightbox-secNav-btnClose { - width: 66px; - float: right; - padding-bottom: 0.7em; -} \ No newline at end of file diff --git a/public/css/projects.css b/public/css/projects.css deleted file mode 100644 index 9d31100..0000000 --- a/public/css/projects.css +++ /dev/null @@ -1,35 +0,0 @@ - -table#projects -{ border-collapse: collapse -; margin: 0 auto 2em -} - -#projects td { padding: 0.3em 0 } -#projects th { text-align: center } - -#projects tr.headings th -{ color: #666 -; padding: 0.3em 0 0.8em -} - -#projects th.name, -#projects td.name -{ text-align: left } - -#projects tr.project { background-color: #dce1e8 } -#projects tr.project:nth-child(even) { background-color: #e4e8ed } -#projects tr.project:hover { background-color: #eee } - -#projects tr.project td -{ border-bottom: solid 1px #aaa -; padding: 0.5em 0 -} - -#projects tr.project.first td { border-top: solid 1px #aaa } - -#projects td.created { text-align: center } - -#projects td.name a -{ color: #333 -; font-size: 1.2em -} diff --git a/public/css/uploadify.css b/public/css/uploadify.css deleted file mode 100644 index 405f59c..0000000 --- a/public/css/uploadify.css +++ /dev/null @@ -1,52 +0,0 @@ -/* -Uploadify v2.1.4 -Release Date: November 8, 2010 - -Copyright (c) 2010 Ronnie Garcia, Travis Nickels - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ -.uploadifyQueueItem { - background-color: #F5F5F5; - border: 2px solid #E5E5E5; - font: 11px Verdana, Geneva, sans-serif; - margin-top: 5px; - padding: 10px; - width: 350px; -} -.uploadifyError { - background-color: #FDE5DD !important; - border: 2px solid #FBCBBC !important; -} -.uploadifyQueueItem .cancel { - float: right; -} -.uploadifyQueue .completed { - background-color: #E5E5E5; -} -.uploadifyProgress { - background-color: #E5E5E5; - margin-top: 10px; - width: 100%; -} -.uploadifyProgressBar { - background-color: #0099FF; - height: 3px; - width: 1px; -} \ No newline at end of file diff --git a/public/images/add-photo.png b/public/images/add-photo.png deleted file mode 100644 index 5d9c8c8b6b1df6e81271da2f65bbb3047d6b6fed..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1088 zcmV-G1i$-4Tx0C)j~RNrgUP!#^!Wu36$i#lf!2|j3%Ze&w*L!7p2SGvtw>Nd9_NSmf@ zT$;ut?S8Na*^6&F#dq-sKKTa>*@JI;k`2ZbVfd_wB24xov!0tYO(#d#()tZ$I5%3%!zLYh@BH>w}XODA7?mkV}ap}jU$$3 zG&Mk)3Bm`(LOM&hKscCb;PVaG&Vdx+MpZJHTQ(R_;DA31$+jOGBoLXk_De?ey1m!ik&_4G zH9n^))_*|$z4!HUisgBd@awc5jn(v9k~&t~+vLrrBg4dZQ9lDnLV}JQWGLW~LJVP= zW5lZXOcog;N~F?hbX0k=IMzETla}oqM|jC!4!B+x^;@#I_Tc-T-6hwKycLDTx1-om z?X`jFy0R0R8-I0SrK4`)H@W4T8*Qr#2vPou<*`U!Wy(*2QP*`g=8#jD{B;Y@GL-Hm zb`n?&x~%YC_$q7)PlXr4m%r4=&fcvN%Ybn#KC7Nn&Bp8{(oE9pWVpYI^+LuN`H(R~ zTAjWmO`M83^4d@fCkA(d>*nHIFV_d2yUbnT`nd?LE^;G|!WZ>Ld?E0@Grm4ww{M7H zr`x{MWb30bTI;*hk-DO>dX$gbC-yy#suLNqvA(f>RtPJ!qGM`Gvvf}Y10`)vm-7Xa z?-7Ixe2A_siI1ydSCCID3U8SVUY86>uSnT0use_K1GZDvUFKY)t}F* z)!pahe+zh{{06Bb3f97*Uorpy0NqJMK~#9!?borYfnglS@i(~wqdOoMU~*3`LI!73 z(lOX9$|R#Y)3KhEK_uhpoL&o2hDWZzORtE}ufFs1@3TEoc=JU7000000KomX-Yi1< zyLPe9N&PhezLujz=DEXhe>*_`r<3UDXYPOd3jhEB000000B}9PaMlZzRz8)=&0ON6(|Yq({SezI^%Y*|R54p4`8G z|IVE|w{G3Ke*OB@t5+{wx^(*V=@TbT?Ay0*`}XZywrtt7Y18`k>sPE;v3T*~dGqGY zo;`cov}qG3PVDdR@9F7jZ*OmEYHDa`sI9FnD=RB5E-oxA%*)Hm%*;$rPftlnNlHqJ zkB^Uyjg5+m3Jnbn4h{|o2=Mds^Y-@k^z?Ldb7LR`6o0ZXurvH;&;cm~`H6w;ze7WT zhmKVLi6uoRbFAiHSg}QNM$~#2#^;SaIV^5XhYKa-WLTaw7EPSeoxUZ&W*tAf%&o4( zmMs}FnZ=U&t@`p#;`)5z0}*FgxG7?Q+eP>#}Q0kG{s^ou20;n;V<17z*6xlW|Jw?=bOR#PEpA zg=KOFx5Rw`%jtY|_3ZS` zqUjnN13nacHVT_2ml!nlJA2OW%MmP8S=ga0=sH=)An?>j$~+u1KUln%@oJ3-U|ygRY{{;{vyg#@ zVe7)XGmJPB4>%ce-gMSF@xfy;(;UM9kqL%E%RL+UjM8k(gB06(gljgeIR7Z|k07_Y Yz?%8?E)08>7@u6ee}4b|UkVJ?0I^^iLI3~& diff --git a/public/images/lightbox-btn-next.gif b/public/images/lightbox-btn-next.gif deleted file mode 100755 index a0d4fcf84a784f2cf44c33084145dde5df294ccf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 812 zcmZ?wbhEHbv}aIYc*el+|NsBLfB*je{rl(7pWnZK|N8ao=g*%%e*F0U{rk6X-@bnR z`sK@)&!0bk_Uze{Cr=(ddi3DIgM0Vx-MMq;#*G`-u3fuy>C%M@7tWnKck0xs6DLj_ zJ9g~Qp+g4_9N4pG&#qm&wr$(CWy_Y$n>TOVxN-gZ^=sFzUA=ns%9SgZFJHcN>C(lE z7tftLclPYrGiT16IB{Zse}8XpZ+CZhdwY9pYio0Jb7Ny;LqkJdU0qdGRYgTbSy@?0 zNl8ILL0(>7PEJl%R#rwvMp{~0N=iynQc^-fLR?&2OiWBvR8&MnL|9l@NJvOfP*6ZX zfS;eAudlDSx3{OKr@OnmtE;QCvop}+41)kD{$ycfX9#A{0l5VfCk*WW8-jxwT3XxM zJ370%dpeqXCrq3)dCJsj(`U?_HG9t7dGi-6T(o$}(q+q6EMSyU6K`dbQDR_IP*vNm z&M%^|u7yignomt{TLh9X-vlT%qa~3Xe4)wGVP;i|rWZ3pVTZ!3`iIq!%NnqiVmI=~4yG?*UBuy@#qi_9lOv%EOFWqjwm)IFQ?j)3`1T=zfmcO{foI3W6sLtd zS4F+)nC;}rU*j;#AyW5g3x|3eXP|{qRNj;|3pfM diff --git a/public/images/lightbox-btn-prev.gif b/public/images/lightbox-btn-prev.gif deleted file mode 100755 index 040ee5992f7fdb9b51907cb4ba1c5570b1b5482a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 832 zcmZ?wbhEHbv}aIYc*el+|NsBLfB*je{rl(7pFe*5`1bAFmoHyFefsp_!-se8-o1MD z>gCIq&!0bk`t<4J$B!RAe0cx<{kwPX-oAbN)~#DNZrr$b?b?+qS1w$*aPHi>GiT16 zK7IP+$&<&AA3u8Z=;6bM4<0Ta{2P*ix)3mxNzb8`Sa(^n>T09oLRGG&6qJ`%9JS+CQRt>@9*vHZEbCBZf^0EX>c(&&|!v&d$!v%uG#9O-@cuN=iydNQjGz zi;0Peii(PehzJV{3keAc4h{|s4D|Q+_x1Jl_V)Jl^mKQ3cXD!aaBu(y1q0oI;!hSv zc7{j>9gxkSIALJ_-@wq++|t_C-qG3B78%*yKVf2j-=wM2rq7r;YxbPE^X4yDxM=Z` zrOTGDSUHZ{$*`cIU*V9G=mkL*$3~&B9F~NQE=O7f+$T8{d|+|! z5LB^I==tcv%)lM$(xcU&+%-wnv&x6z08`gQRsV((28G1VNlI>g4%W9mc+UCN{rKLQV#k0fcFk=e`pVK=5riUkZTAtTQ6isw#WRUmZ3z(a9R-j$e ze3FRFDrSywC%q{a3<^!By0Zf_LL_n(8yB!Rulm4I*~32ZbaR4DVcG)ssl5F2B6c2< z?&fr4Oo*`z)H=|_wuV)6!iF%%R#s*epBZ+t2Ny7lSgg8L*Lk3Uk?9ck4?hLV?=DPC dE8_S6+w=SThsUSq`|tm!>h(?3l#7MI8UW1vMEU># diff --git a/public/images/lightbox-ico-loading.gif b/public/images/lightbox-ico-loading.gif deleted file mode 100755 index 4f1429c06cb2ffd2910b038d06b01a4b3ee00a21..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3990 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 diff --git a/public/images/sign-up-now-button-hover.png b/public/images/sign-up-now-button-hover.png deleted file mode 100644 index 5d5af6a5375e960d5f5ea1384e26d32eb74dbc7f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4788 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 Q9{>OV07*qoM6N<$g2Dv%^Z)<= diff --git a/public/js/account.js b/public/js/account.js index 37b62f2..165e963 100644 --- a/public/js/account.js +++ b/public/js/account.js @@ -1,9 +1,9 @@ $(function() { $('#change-password-link').click(function() { - $(this).hide() - $('#change-password').show() - $('#password-changed').hide() + $(this).addClass('hidden') + $('#change-password').removeClass('hidden') + $('#password-changed').addClass('hidden') $('#old-password').focus() return false }) @@ -14,8 +14,8 @@ $(function() { }) $('#send-email-verification').click(function() { - $('#sending-email-verification').show() - $(this).hide() + $('#sending-email-verification').removeClass('hidden') + $(this).addClass('hidden') var self = this $.post('/account/send-email-verification', function(data) { if (data.status === 'ok') { @@ -29,8 +29,8 @@ $(function() { }).error(function() { alert('Failed to send verification email. Try again later.') }).complete(function() { - $('#sending-email-verification').hide() - $(self).show() + $('#sending-email-verification').addClass('hidden') + $(self).removeClass('hidden') }) return false }) @@ -43,14 +43,14 @@ function changePassword() { , confirmation = $('#password-confirmation').val() if ($.trim(oldPassword) && $.trim(newPassword) && newPassword === confirmation) { $('#change-password-form input[type="password"]').removeClass('error') - $('#change-password-form input[type="submit"]').hide() - $('#change-password-form .spinner').show() + $('#change-password-form input[type="submit"]').addClass('hidden') + $('#change-password-spinner').removeClass('hidden') $.post('/account/password', $('#change-password-form').serialize(), function(data) { if (data.status === 'ok') { $('input[type="password"]').val('') - $('#change-password').hide() - $('#change-password-link').show() - $('#password-changed').show() + $('#change-password').addClass('hidden') + $('#change-password-link').removeClass('hidden') + $('#password-changed').removeClass('hidden') } // incorrect old password else if (data.reason === 'incorrect') { @@ -72,8 +72,8 @@ function changePassword() { }).error(function(x) { alert('Failed to change password. Try again later.') }).complete(function() { - $('#change-password-form input[type="submit"]').show() - $('#change-password-form .spinner').hide() + $('#change-password-form input[type="submit"]').removeClass('hidden') + $('#change-password-spinner').addClass('hidden') }) } else { diff --git a/public/js/admin-project.js b/public/js/admin-project.js deleted file mode 100644 index c130eee..0000000 --- a/public/js/admin-project.js +++ /dev/null @@ -1,7 +0,0 @@ -$(function() { - - $('#delete').click(function() { - return confirm("Are you sure?") - }) - -}) diff --git a/public/js/edit-project.js b/public/js/edit-project.js deleted file mode 100644 index 906e52e..0000000 --- a/public/js/edit-project.js +++ /dev/null @@ -1,215 +0,0 @@ -$(function() { - - initTmpl() - - $('#name').blur(function() { - var name = $.trim($(this).val()) - if (name === this.placeholder) name = '' - $('.save-button').val('Save ' + (name || 'This Project')) - }) - - $('form#project').submit(validateProject) - - initLightBox() - - $('#photos').dragsort({ - dragSelector: 'li.photo' - , itemSelector: 'li.photo' - , dragEnd: updatePhotoOrder - , placeHolderTemplate: '

  • ' - , itemClicked: function(item) { $('a.thumbnail', item).click() } - }) - - var $photos = $('#photos-container') - , $addPhotoBox = $('#add-photo-box') - , $photoUploader = $('#photo-uploader') - - // fuck IE - if ($.browser.msie) { - $('#ie-photo-uploader').uploadify({ - 'uploader' : '/uploadify/uploadify.swf', - 'script' : '/uploadify', - 'multi' : false, - 'buttonImg' : '/images/add-photo.png', - 'method' : 'post', - 'cancelImg' : '/uploadify/cancel.png', - 'auto' : true, - 'fileExt' : ['jpg', 'jpeg', 'png'], - 'sizeLimit' : 10 * 1024 * 1024 * 1024, // 10 MB is way more than enough - 'scriptData' : { id: window.SI.projectId }, - - 'onComplete': function(_a, _b, _c, text) { - completePhotoUpload(text) - }, - 'onError': function() { - completePhotoUpload('fail') - }, - 'onOpen': function() { - $('#add-photo-spinner').remove() - $addPhotoBox.addClass('hidden').before('
  • ') - } - }) - } - - $('.add-photo').click(function() { - $photoUploader.focus().click() - return false - }) - - $photoUploader.change(function() { - $addPhotoBox.addClass('hidden').before('
  • ') - $('#photo-form').submit() - return false - }) - - $('#upload-target').load(function() { - completePhotoUpload($(this).contents().text()) - }) - - var photoTemplate = window.SI.tmpl($('#photo-template').html()) - - function completePhotoUpload(text) { - $('#add-photo-spinner').remove() - var photoForm = $('#photo-form').get(0) - if (photoForm) photoForm.reset() - try { - var response = JSON.parse(text) - if (response.status === 'ok') { - $addPhotoBox.before(photoTemplate(response.data.photo)) - initLightBox() - if (response.data.n >= 10) { - $addPhotoBox.addClass('hidden') - } - else { - $addPhotoBox.removeClass('hidden') - } - } - else { - $addPhotoBox.removeClass('hidden') - alert('Failed to add photo. Try again later.') - } - } - catch (e) { - $addPhotoBox.removeClass('hidden') - alert('Failed to add photo. Try again later.') - } - } - - - var removeCount = 0 - $('.remove-photo').live('click', function() { - var id = this.id - , photoId = id.replace(/^remove-photo-/, '') - , data = { id: window.SI.projectId, photo_id: photoId } - , spinnerId = 'remove-photo-spinner-' + photoId - , $this = $(this) - $this.hide().after('') - removeCount += 1 - $.post('/project/remove-photo', data, function(response) { - removeCount -= 1 - if (response.status === 'ok' && removeCount === 0) { - $addPhotoBox.removeClass('hidden') - $('li.photo').remove() - - $.each(response.data.photos, function(i, photo) { - $addPhotoBox.before(photoTemplate(photo)) - }) - - initLightBox() - } - else { - if (removeCount === 0) { - $('#' + spinnerId).remove() - $this.show() - alert('Failed to remove photo. Try again later.') - } - } - }).error(function() { - removeCount -= 1 - if (removeCount === 0) { - $('#' + spinnerId).remove() - $this.show() - alert('Failed to remove photo. Try again later.') - } - }) - return false - }) - -}) - -function initLightBox() { - $('#photos a.thumbnail').lightBox() - $('#photos a.thumbnail').live('click', function(){ console.dir(this) }) -} - -// Simple JavaScript Templating -// John Resig - http://ejohn.org/ - MIT Licensed -// http://ejohn.org/blog/javascript-micro-templating/ -function initTmpl() { - var cache = {} - - window.SI = window.SI || {} - window.SI.tmpl = function tmpl(str, data) { - // Figure out if we're getting a template, or if we need to - // load the template - and be sure to cache the result. - var fn = !/\W/.test(str) ? - cache[str] = cache[str] || - tmpl($('#' + str).html()) : - - // Generate a reusable function that will serve as a template - // generator (and which will be cached). - new Function("obj", - "var p=[],print=function(){p.push.apply(p,arguments)};" + - - // Introduce the data as local variables using with(){} - "with(obj){p.push('" + - - // Convert the template into pure JavaScript - str - .replace(/[\r\t\n]/g, " ") - .split("<%").join("\t") - .replace(/((^|%>)[^\t]*)'/g, "$1\r") - .replace(/\t=(.*?)%>/g, "',$1,'") - .split("\t").join("');") - .split("%>").join("p.push('") - .split("\r").join("\\'") - + "')}return p.join('')") - - // Provide some basic currying to the user - return data ? fn( data ) : fn - } -} - -function updatePhotoOrder() { - initLightBox() - var ids = [] - $('#photos li.photo').each(function() { - ids.push(this.id.replace('photo-', '')) - }) - var data = { id: window.SI.projectId, order: ids } - $.post('/project/photo-order', data, function(response) { - // noop - }).error(function() { - alert('Failed to reorder photos. Try again later.') - }) -} - -function validateProject() { - var valid = true - , nameField = $('#name') - - if ($.trim(nameField.val()).length === 0) { - valid = false - nameField.addClass('error').focus().select() - } - else { - nameField.removeClass('error') - } - - if (valid) { - $('.save-button').hide() - $('.save-button-spinner').show() - } - - return valid -} diff --git a/public/js/jquery.dragsort.js b/public/js/jquery.dragsort.js deleted file mode 100644 index 23e87c4..0000000 --- a/public/js/jquery.dragsort.js +++ /dev/null @@ -1,297 +0,0 @@ -// jQuery List DragSort v0.4 -// Website: http://dragsort.codeplex.com/ -// License: http://dragsort.codeplex.com/license - -(function($) { - - $.fn.dragsort = function(options) { - var opts = $.extend({}, $.fn.dragsort.defaults, options); - var lists = []; - var list = null, lastPos = null; - - this.each(function(i, cont) { - - if ($(cont).is("table") && $(cont).children().size() == 1 && $(cont).children().is("tbody")) - cont = $(cont).children().get(0); - - var newList = { - draggedItem: null, - placeHolderItem: null, - pos: null, - offset: null, - offsetLimit: null, - scroll: null, - container: cont, - - init: function() { - $(this.container).attr("data-listIdx", i).mousedown(this.grabItem) - $(this.container).children(opts.itemSelector).each(function(j) { $(this).attr("data-itemIdx", j); }); - }, - - grabItem: function(e) { - if (e.which != 1 || $(e.target).is(opts.dragSelectorExclude)) - return; - - var elm = e.target; - while (!$(elm).is("[data-listIdx='" + $(this).attr("data-listIdx") + "'] " + opts.dragSelector)) { - if (elm == this) return; - elm = elm.parentNode; - } - - if (list != null && list.draggedItem != null) - list.dropItem(); - - list = lists[$(this).attr("data-listIdx")]; - list.draggedItem = $(elm).closest(opts.itemSelector); - var mt = parseInt(list.draggedItem.css("marginTop")); - var ml = parseInt(list.draggedItem.css("marginLeft")); - list.offset = list.draggedItem.offset(); - list.offset.top = e.pageY - list.offset.top + (isNaN(mt) ? 0 : mt) - 1; - list.offset.left = e.pageX - list.offset.left + (isNaN(ml) ? 0 : ml) - 1; - list.draggedItem.startOffset = list.draggedItem.offset() - list.draggedItem.startTime = +new Date() - - if (!opts.dragBetween) { - var containerHeight = $(list.container).outerHeight() == 0 ? Math.max(1, Math.round(0.5 + $(list.container).children(opts.itemSelector).size() * list.draggedItem.outerWidth() / $(list.container).outerWidth())) * list.draggedItem.outerHeight() : $(list.container).outerHeight(); - list.offsetLimit = $(list.container).offset(); - list.offsetLimit.right = list.offsetLimit.left + $(list.container).outerWidth() - list.draggedItem.outerWidth(); - list.offsetLimit.bottom = list.offsetLimit.top + containerHeight - list.draggedItem.outerHeight(); - } - - var h = list.draggedItem.height(); - var w = list.draggedItem.width(); - var orig = list.draggedItem.attr("style"); - list.draggedItem.attr("data-origStyle", orig ? orig : ""); - if (opts.itemSelector == "tr") { - list.draggedItem.children().each(function() { $(this).width($(this).width()); }); - list.placeHolderItem = list.draggedItem.clone().attr("data-placeHolder", true); - list.draggedItem.after(list.placeHolderItem); - list.placeHolderItem.children().each(function() { $(this).css({ borderWidth:0, width: $(this).width() + 1, height: $(this).height() + 1 }).html(" "); }); - } else { - list.draggedItem.after(opts.placeHolderTemplate); - list.placeHolderItem = list.draggedItem.next().css({ height: h, width: w }).attr("data-placeHolder", true); - } - list.draggedItem.css({ position: "absolute", opacity: 0.8, "z-index": 999, height: h, width: w }); - - $(lists).each(function(i, l) { l.createDropTargets(); l.buildPositionTable(); }); - - list.scroll = { moveX: 0, moveY: 0, maxX: $(document).width() - $(window).width(), maxY: $(document).height() - $(window).height() }; - list.scroll.scrollY = window.setInterval(function() { - if (opts.scrollContainer != window) { - $(opts.scrollContainer).scrollTop($(opts.scrollContainer).scrollTop() + list.scroll.moveY); - return; - } - var t = $(opts.scrollContainer).scrollTop(); - if (list.scroll.moveY > 0 && t < list.scroll.maxY || list.scroll.moveY < 0 && t > 0) { - $(opts.scrollContainer).scrollTop(t + list.scroll.moveY); - list.draggedItem.css("top", list.draggedItem.offset().top + list.scroll.moveY + 1); - } - }, 10); - list.scroll.scrollX = window.setInterval(function() { - if (opts.scrollContainer != window) { - $(opts.scrollContainer).scrollLeft($(opts.scrollContainer).scrollLeft() + list.scroll.moveX); - return; - } - var l = $(opts.scrollContainer).scrollLeft(); - if (list.scroll.moveX > 0 && l < list.scroll.maxX || list.scroll.moveX < 0 && l > 0) { - $(opts.scrollContainer).scrollLeft(l + list.scroll.moveX); - list.draggedItem.css("left", list.draggedItem.offset().left + list.scroll.moveX + 1); - } - }, 10); - - list.setPos(e.pageX, e.pageY); - $(document).bind("selectstart", list.stopBubble); //stop ie text selection - $(document).bind("mousemove", list.swapItems); - $(document).bind("mouseup", list.dropItem); - if (opts.scrollContainer != window) - $(window).bind("DOMMouseScroll mousewheel", list.wheel); - return false; //stop moz text selection - }, - - setPos: function(x, y) { - var top = y - this.offset.top; - var left = x - this.offset.left; - - if (!opts.dragBetween) { - top = Math.min(this.offsetLimit.bottom, Math.max(top, this.offsetLimit.top)); - left = Math.min(this.offsetLimit.right, Math.max(left, this.offsetLimit.left)); - } - - this.draggedItem.parents().each(function() { - if ($(this).css("position") != "static" && (!$.browser.mozilla || $(this).css("display") != "table")) { - var offset = $(this).offset(); - top -= offset.top; - left -= offset.left; - return false; - } - }); - - if (opts.scrollContainer == window) { - y -= $(window).scrollTop(); - x -= $(window).scrollLeft(); - y = Math.max(0, y - $(window).height() + 5) + Math.min(0, y - 5); - x = Math.max(0, x - $(window).width() + 5) + Math.min(0, x - 5); - } else { - var cont = $(opts.scrollContainer); - var offset = cont.offset(); - y = Math.max(0, y - cont.height() - offset.top) + Math.min(0, y - offset.top); - x = Math.max(0, x - cont.width() - offset.left) + Math.min(0, x - offset.left); - } - - list.scroll.moveX = x == 0 ? 0 : x * opts.scrollSpeed / Math.abs(x); - list.scroll.moveY = y == 0 ? 0 : y * opts.scrollSpeed / Math.abs(y); - - this.draggedItem.css({ top: top, left: left }); - }, - - wheel: function(e) { - if (($.browser.safari || $.browser.mozilla) && list && opts.scrollContainer != window) { - var cont = $(opts.scrollContainer); - var offset = cont.offset(); - if (e.pageX > offset.left && e.pageX < offset.left + cont.width() && e.pageY > offset.top && e.pageY < offset.top + cont.height()) { - var delta = e.detail ? e.detail * 5 : e.wheelDelta / -2; - cont.scrollTop(cont.scrollTop() + delta); - e.preventDefault(); - } - } - }, - - buildPositionTable: function() { - var item = this.draggedItem == null ? null : this.draggedItem.get(0); - var pos = []; - $(this.container).children(opts.itemSelector).each(function(i, elm) { - if (elm != item) { - var loc = $(elm).offset(); - loc.right = loc.left + $(elm).width(); - loc.bottom = loc.top + $(elm).height(); - loc.elm = elm; - pos.push(loc); - } - }); - this.pos = pos; - }, - - dropItem: function() { - if (list.draggedItem == null) - return; - - list.placeHolderItem.before(list.draggedItem); - - //list.draggedItem.attr("style", "") doesn't work on IE8 and jQuery 1.5 or lower - //list.draggedItem.removeAttr("style") doesn't work on chrome and jQuery 1.6 (works jQuery 1.5 or lower) - var orig = list.draggedItem.attr("data-origStyle"); - list.draggedItem.attr("style", orig); - if (orig == "") - list.draggedItem.removeAttr("style"); - list.draggedItem.removeAttr("data-origStyle"); - list.placeHolderItem.remove(); - - $("[data-dropTarget]").remove(); - - window.clearInterval(list.scroll.scrollY); - window.clearInterval(list.scroll.scrollX); - - var changed = false; - $(lists).each(function() { - $(this.container).children(opts.itemSelector).each(function(j) { - if (parseInt($(this).attr("data-itemIdx")) != j) { - changed = true; - $(this).attr("data-itemIdx", j); - } - }); - }); - - var duration = +new Date() - list.draggedItem.startTime - , offset = list.draggedItem.offset() - , diffY = Math.abs(list.draggedItem.startOffset.top - offset.top) - , diffX = Math.abs(list.draggedItem.startOffset.left - offset.left) - , itemClicked = duration < 500 && diffX < 3 && diffY < 3 - - if (changed) - opts.dragEnd.apply(list.draggedItem); - else if (itemClicked) - opts.itemClicked(list.draggedItem) - - list.draggedItem = null; - $(document).unbind("selectstart", list.stopBubble); - $(document).unbind("mousemove", list.swapItems); - $(document).unbind("mouseup", list.dropItem); - if (opts.scrollContainer != window) - $(window).unbind("DOMMouseScroll mousewheel", list.wheel); - return false; - }, - - stopBubble: function() { return false; }, - - swapItems: function(e) { - if (list.draggedItem == null) - return false; - - list.setPos(e.pageX, e.pageY); - - var ei = list.findPos(e.pageX, e.pageY); - var nlist = list; - for (var i = 0; ei == -1 && opts.dragBetween && i < lists.length; i++) { - ei = lists[i].findPos(e.pageX, e.pageY); - nlist = lists[i]; - } - - if (ei == -1 || $(nlist.pos[ei].elm).attr("data-placeHolder")) - return false; - - if (lastPos == null || lastPos.top > list.draggedItem.offset().top || lastPos.left > list.draggedItem.offset().left) - $(nlist.pos[ei].elm).before(list.placeHolderItem); - else - $(nlist.pos[ei].elm).after(list.placeHolderItem); - - $(lists).each(function(i, l) { l.createDropTargets(); l.buildPositionTable(); }); - lastPos = list.draggedItem.offset(); - return false; - }, - - findPos: function(x, y) { - for (var i = 0; i < this.pos.length; i++) { - if (this.pos[i].left < x && this.pos[i].right > x && this.pos[i].top < y && this.pos[i].bottom > y) - return i; - } - return -1; - }, - - createDropTargets: function() { - if (!opts.dragBetween) - return; - - $(lists).each(function() { - var ph = $(this.container).find("[data-placeHolder]"); - var dt = $(this.container).find("[data-dropTarget]"); - if (ph.size() > 0 && dt.size() > 0) - dt.remove(); - else if (ph.size() == 0 && dt.size() == 0) { - //list.placeHolderItem.clone().removeAttr("data-placeHolder") crashes in IE7 and jquery 1.5.1 (doesn't in jquery 1.4.2 or IE8) - $(this.container).append(list.placeHolderItem.removeAttr("data-placeHolder").clone().attr("data-dropTarget", true)); - list.placeHolderItem.attr("data-placeHolder", true); - } - }); - } - }; - - newList.init(); - lists.push(newList); - }); - - return this; - }; - - $.fn.dragsort.defaults = { - itemClicked: function() { }, - itemSelector: "li", - dragSelector: "li", - dragSelectorExclude: "input, textarea, a[href]", - dragEnd: function() { }, - dragBetween: false, - placeHolderTemplate: "
  •  
  • ", - scrollContainer: window, - scrollSpeed: 5 - }; - -})(jQuery); diff --git a/public/js/jquery.lightbox-0.5.js b/public/js/jquery.lightbox-0.5.js deleted file mode 100644 index 5d68a6e..0000000 --- a/public/js/jquery.lightbox-0.5.js +++ /dev/null @@ -1,472 +0,0 @@ -/** - * jQuery lightBox plugin - * This jQuery plugin was inspired and based on Lightbox 2 by Lokesh Dhakar (http://www.huddletogether.com/projects/lightbox2/) - * and adapted to me for use like a plugin from jQuery. - * @name jquery-lightbox-0.5.js - * @author Leandro Vieira Pinho - http://leandrovieira.com - * @version 0.5 - * @date April 11, 2008 - * @category jQuery plugin - * @copyright (c) 2008 Leandro Vieira Pinho (leandrovieira.com) - * @license CCAttribution-ShareAlike 2.5 Brazil - http://creativecommons.org/licenses/by-sa/2.5/br/deed.en_US - * @example Visit http://leandrovieira.com/projects/jquery/lightbox/ for more informations about this jQuery plugin - */ - -// Offering a Custom Alias suport - More info: http://docs.jquery.com/Plugins/Authoring#Custom_Alias -(function($) { - /** - * $ is an alias to jQuery object - * - */ - $.fn.lightBox = function(settings) { - // Settings to configure the jQuery lightBox plugin how you like - settings = jQuery.extend({ - // Configuration related to overlay - overlayBgColor: '#000', // (string) Background color to overlay; inform a hexadecimal value like: #RRGGBB. Where RR, GG, and BB are the hexadecimal values for the red, green, and blue values of the color. - overlayOpacity: 0.8, // (integer) Opacity value to overlay; inform: 0.X. Where X are number from 0 to 9 - // Configuration related to navigation - fixedNavigation: false, // (boolean) Boolean that informs if the navigation (next and prev button) will be fixed or not in the interface. - // Configuration related to images - imageLoading: '/images/lightbox-ico-loading.gif', // (string) Path and the name of the loading icon - imageBtnPrev: '/images/lightbox-btn-prev.gif', // (string) Path and the name of the prev button image - imageBtnNext: '/images/lightbox-btn-next.gif', // (string) Path and the name of the next button image - imageBtnClose: '/images/lightbox-btn-close.gif', // (string) Path and the name of the close btn - imageBlank: '/images/lightbox-blank.gif', // (string) Path and the name of a blank image (one pixel) - // Configuration related to container image box - containerBorderSize: 10, // (integer) If you adjust the padding in the CSS for the container, #lightbox-container-image-box, you will need to update this value - containerResizeSpeed: 400, // (integer) Specify the resize duration of container image. These number are miliseconds. 400 is default. - // Configuration related to texts in caption. For example: Image 2 of 8. You can alter either "Image" and "of" texts. - txtImage: 'Image', // (string) Specify text "Image" - txtOf: 'of', // (string) Specify text "of" - // Configuration related to keyboard navigation - keyToClose: 'c', // (string) (c = close) Letter to close the jQuery lightBox interface. Beyond this letter, the letter X and the SCAPE key is used to. - keyToPrev: 'p', // (string) (p = previous) Letter to show the previous image - keyToNext: 'n', // (string) (n = next) Letter to show the next image. - // Don´t alter these variables in any way - imageArray: [], - activeImage: 0 - },settings); - // Caching the jQuery object with all elements matched - var jQueryMatchedObj = this; // This, in this context, refer to jQuery object - /** - * Initializing the plugin calling the start function - * - * @return boolean false - */ - function _initialize() { - _start(this,jQueryMatchedObj); // This, in this context, refer to object (link) which the user have clicked - return false; // Avoid the browser following the link - } - /** - * Start the jQuery lightBox plugin - * - * @param object objClicked The object (link) whick the user have clicked - * @param object jQueryMatchedObj The jQuery object with all elements matched - */ - function _start(objClicked,jQueryMatchedObj) { - // Hime some elements to avoid conflict with overlay in IE. These elements appear above the overlay. - $('embed, object, select').css({ 'visibility' : 'hidden' }); - // Call the function to create the markup structure; style some elements; assign events in some elements. - _set_interface(); - // Unset total images in imageArray - settings.imageArray.length = 0; - // Unset image active information - settings.activeImage = 0; - // We have an image set? Or just an image? Let´s see it. - if ( jQueryMatchedObj.length == 1 ) { - settings.imageArray.push(new Array(objClicked.getAttribute('href'),objClicked.getAttribute('title'))); - } else { - // Add an Array (as many as we have), with href and title atributes, inside the Array that storage the images references - for ( var i = 0; i < jQueryMatchedObj.length; i++ ) { - settings.imageArray.push(new Array(jQueryMatchedObj[i].getAttribute('href'),jQueryMatchedObj[i].getAttribute('title'))); - } - } - while ( settings.imageArray[settings.activeImage][0] != objClicked.getAttribute('href') ) { - settings.activeImage++; - } - // Call the function that prepares image exibition - _set_image_to_view(); - } - /** - * Create the jQuery lightBox plugin interface - * - * The HTML markup will be like that: -
    -
    - - -
    - * - */ - function _set_interface() { - // Apply the HTML markup into body tag - $('body').append('
    '); - // Get page sizes - var arrPageSizes = ___getPageSize(); - // Style overlay and show it - $('#jquery-overlay').css({ - backgroundColor: settings.overlayBgColor, - opacity: settings.overlayOpacity, - width: arrPageSizes[0], - height: arrPageSizes[1] - }).fadeIn(); - // Get page scroll - var arrPageScroll = ___getPageScroll(); - // Calculate top and left offset for the jquery-lightbox div object and show it - $('#jquery-lightbox').css({ - top: arrPageScroll[1] + (arrPageSizes[3] / 10), - left: arrPageScroll[0] - }).show(); - // Assigning click events in elements to close overlay - $('#jquery-overlay,#jquery-lightbox').click(function() { - _finish(); - }); - // Assign the _finish function to lightbox-loading-link and lightbox-secNav-btnClose objects - $('#lightbox-loading-link,#lightbox-secNav-btnClose').click(function() { - _finish(); - return false; - }); - // If window was resized, calculate the new overlay dimensions - $(window).resize(function() { - // Get page sizes - var arrPageSizes = ___getPageSize(); - // Style overlay and show it - $('#jquery-overlay').css({ - width: arrPageSizes[0], - height: arrPageSizes[1] - }); - // Get page scroll - var arrPageScroll = ___getPageScroll(); - // Calculate top and left offset for the jquery-lightbox div object and show it - $('#jquery-lightbox').css({ - top: arrPageScroll[1] + (arrPageSizes[3] / 10), - left: arrPageScroll[0] - }); - }); - } - /** - * Prepares image exibition; doing a image´s preloader to calculate it´s size - * - */ - function _set_image_to_view() { // show the loading - // Show the loading - $('#lightbox-loading').show(); - if ( settings.fixedNavigation ) { - $('#lightbox-image,#lightbox-container-image-data-box,#lightbox-image-details-currentNumber').hide(); - } else { - // Hide some elements - $('#lightbox-image,#lightbox-nav,#lightbox-nav-btnPrev,#lightbox-nav-btnNext,#lightbox-container-image-data-box,#lightbox-image-details-currentNumber').hide(); - } - // Image preload process - var objImagePreloader = new Image(); - objImagePreloader.onload = function() { - $('#lightbox-image').attr('src',settings.imageArray[settings.activeImage][0]); - // Perfomance an effect in the image container resizing it - _resize_container_image_box(objImagePreloader.width,objImagePreloader.height); - // clear onLoad, IE behaves irratically with animated gifs otherwise - objImagePreloader.onload=function(){}; - }; - objImagePreloader.src = settings.imageArray[settings.activeImage][0]; - }; - /** - * Perfomance an effect in the image container resizing it - * - * @param integer intImageWidth The image´s width that will be showed - * @param integer intImageHeight The image´s height that will be showed - */ - function _resize_container_image_box(intImageWidth,intImageHeight) { - // Get current width and height - var intCurrentWidth = $('#lightbox-container-image-box').width(); - var intCurrentHeight = $('#lightbox-container-image-box').height(); - // Get the width and height of the selected image plus the padding - var intWidth = (intImageWidth + (settings.containerBorderSize * 2)); // Plus the image´s width and the left and right padding value - var intHeight = (intImageHeight + (settings.containerBorderSize * 2)); // Plus the image´s height and the left and right padding value - // Diferences - var intDiffW = intCurrentWidth - intWidth; - var intDiffH = intCurrentHeight - intHeight; - // Perfomance the effect - $('#lightbox-container-image-box').animate({ width: intWidth, height: intHeight },settings.containerResizeSpeed,function() { _show_image(); }); - if ( ( intDiffW == 0 ) && ( intDiffH == 0 ) ) { - if ( $.browser.msie ) { - ___pause(250); - } else { - ___pause(100); - } - } - $('#lightbox-container-image-data-box').css({ width: intImageWidth }); - $('#lightbox-nav-btnPrev,#lightbox-nav-btnNext').css({ height: intImageHeight + (settings.containerBorderSize * 2) }); - }; - /** - * Show the prepared image - * - */ - function _show_image() { - $('#lightbox-loading').hide(); - $('#lightbox-image').fadeIn(function() { - _show_image_data(); - _set_navigation(); - }); - _preload_neighbor_images(); - }; - /** - * Show the image information - * - */ - function _show_image_data() { - $('#lightbox-container-image-data-box').slideDown('fast'); - $('#lightbox-image-details-caption').hide(); - if ( settings.imageArray[settings.activeImage][1] ) { - $('#lightbox-image-details-caption').html(settings.imageArray[settings.activeImage][1]).show(); - } - // If we have a image set, display 'Image X of X' - if ( settings.imageArray.length > 1 ) { - $('#lightbox-image-details-currentNumber').html(settings.txtImage + ' ' + ( settings.activeImage + 1 ) + ' ' + settings.txtOf + ' ' + settings.imageArray.length).show(); - } - } - /** - * Display the button navigations - * - */ - function _set_navigation() { - $('#lightbox-nav').show(); - - // Instead to define this configuration in CSS file, we define here. And it´s need to IE. Just. - $('#lightbox-nav-btnPrev,#lightbox-nav-btnNext').css({ 'background' : 'transparent url(' + settings.imageBlank + ') no-repeat' }); - - // Show the prev button, if not the first image in set - if ( settings.activeImage != 0 ) { - if ( settings.fixedNavigation ) { - $('#lightbox-nav-btnPrev').css({ 'background' : 'url(' + settings.imageBtnPrev + ') left 15% no-repeat' }) - .unbind() - .bind('click',function() { - settings.activeImage = settings.activeImage - 1; - _set_image_to_view(); - return false; - }); - } else { - // Show the images button for Next buttons - $('#lightbox-nav-btnPrev').unbind().hover(function() { - $(this).css({ 'background' : 'url(' + settings.imageBtnPrev + ') left 15% no-repeat' }); - },function() { - $(this).css({ 'background' : 'transparent url(' + settings.imageBlank + ') no-repeat' }); - }).show().bind('click',function() { - settings.activeImage = settings.activeImage - 1; - _set_image_to_view(); - return false; - }); - } - } - - // Show the next button, if not the last image in set - if ( settings.activeImage != ( settings.imageArray.length -1 ) ) { - if ( settings.fixedNavigation ) { - $('#lightbox-nav-btnNext').css({ 'background' : 'url(' + settings.imageBtnNext + ') right 15% no-repeat' }) - .unbind() - .bind('click',function() { - settings.activeImage = settings.activeImage + 1; - _set_image_to_view(); - return false; - }); - } else { - // Show the images button for Next buttons - $('#lightbox-nav-btnNext').unbind().hover(function() { - $(this).css({ 'background' : 'url(' + settings.imageBtnNext + ') right 15% no-repeat' }); - },function() { - $(this).css({ 'background' : 'transparent url(' + settings.imageBlank + ') no-repeat' }); - }).show().bind('click',function() { - settings.activeImage = settings.activeImage + 1; - _set_image_to_view(); - return false; - }); - } - } - // Enable keyboard navigation - _enable_keyboard_navigation(); - } - /** - * Enable a support to keyboard navigation - * - */ - function _enable_keyboard_navigation() { - $(document).keydown(function(objEvent) { - _keyboard_action(objEvent); - }); - } - /** - * Disable the support to keyboard navigation - * - */ - function _disable_keyboard_navigation() { - $(document).unbind(); - } - /** - * Perform the keyboard actions - * - */ - function _keyboard_action(objEvent) { - // To ie - if ( objEvent == null ) { - keycode = event.keyCode; - escapeKey = 27; - // To Mozilla - } else { - keycode = objEvent.keyCode; - escapeKey = objEvent.DOM_VK_ESCAPE; - } - // Get the key in lower case form - key = String.fromCharCode(keycode).toLowerCase(); - // Verify the keys to close the ligthBox - if ( ( key == settings.keyToClose ) || ( key == 'x' ) || ( keycode == escapeKey ) ) { - _finish(); - } - // Verify the key to show the previous image - if ( ( key == settings.keyToPrev ) || ( keycode == 37 ) ) { - // If we´re not showing the first image, call the previous - if ( settings.activeImage != 0 ) { - settings.activeImage = settings.activeImage - 1; - _set_image_to_view(); - _disable_keyboard_navigation(); - } - } - // Verify the key to show the next image - if ( ( key == settings.keyToNext ) || ( keycode == 39 ) ) { - // If we´re not showing the last image, call the next - if ( settings.activeImage != ( settings.imageArray.length - 1 ) ) { - settings.activeImage = settings.activeImage + 1; - _set_image_to_view(); - _disable_keyboard_navigation(); - } - } - } - /** - * Preload prev and next images being showed - * - */ - function _preload_neighbor_images() { - if ( (settings.imageArray.length -1) > settings.activeImage ) { - objNext = new Image(); - objNext.src = settings.imageArray[settings.activeImage + 1][0]; - } - if ( settings.activeImage > 0 ) { - objPrev = new Image(); - objPrev.src = settings.imageArray[settings.activeImage -1][0]; - } - } - /** - * Remove jQuery lightBox plugin HTML markup - * - */ - function _finish() { - $('#jquery-lightbox').remove(); - $('#jquery-overlay').fadeOut(function() { $('#jquery-overlay').remove(); }); - // Show some elements to avoid conflict with overlay in IE. These elements appear above the overlay. - $('embed, object, select').css({ 'visibility' : 'visible' }); - } - /** - / THIRD FUNCTION - * getPageSize() by quirksmode.com - * - * @return Array Return an array with page width, height and window width, height - */ - function ___getPageSize() { - var xScroll, yScroll; - if (window.innerHeight && window.scrollMaxY) { - xScroll = window.innerWidth + window.scrollMaxX; - yScroll = window.innerHeight + window.scrollMaxY; - } else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac - xScroll = document.body.scrollWidth; - yScroll = document.body.scrollHeight; - } else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari - xScroll = document.body.offsetWidth; - yScroll = document.body.offsetHeight; - } - var windowWidth, windowHeight; - if (self.innerHeight) { // all except Explorer - if(document.documentElement.clientWidth){ - windowWidth = document.documentElement.clientWidth; - } else { - windowWidth = self.innerWidth; - } - windowHeight = self.innerHeight; - } else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode - windowWidth = document.documentElement.clientWidth; - windowHeight = document.documentElement.clientHeight; - } else if (document.body) { // other Explorers - windowWidth = document.body.clientWidth; - windowHeight = document.body.clientHeight; - } - // for small pages with total height less then height of the viewport - if(yScroll < windowHeight){ - pageHeight = windowHeight; - } else { - pageHeight = yScroll; - } - // for small pages with total width less then width of the viewport - if(xScroll < windowWidth){ - pageWidth = xScroll; - } else { - pageWidth = windowWidth; - } - arrayPageSize = new Array(pageWidth,pageHeight,windowWidth,windowHeight); - return arrayPageSize; - }; - /** - / THIRD FUNCTION - * getPageScroll() by quirksmode.com - * - * @return Array Return an array with x,y page scroll values. - */ - function ___getPageScroll() { - var xScroll, yScroll; - if (self.pageYOffset) { - yScroll = self.pageYOffset; - xScroll = self.pageXOffset; - } else if (document.documentElement && document.documentElement.scrollTop) { // Explorer 6 Strict - yScroll = document.documentElement.scrollTop; - xScroll = document.documentElement.scrollLeft; - } else if (document.body) {// all other Explorers - yScroll = document.body.scrollTop; - xScroll = document.body.scrollLeft; - } - arrayPageScroll = new Array(xScroll,yScroll); - return arrayPageScroll; - }; - /** - * Stop the code execution from a escified time in milisecond - * - */ - function ___pause(ms) { - var date = new Date(); - curDate = null; - do { var curDate = new Date(); } - while ( curDate - date < ms); - }; - // Return the jQuery object for chaining. The unbind method is used to avoid click conflict when the plugin is called more than once - return this.unbind('click').click(_initialize); - }; -})(jQuery); // Call and execute the function immediately passing the jQuery object \ No newline at end of file diff --git a/public/js/jquery.uploadify.v2.1.4.js b/public/js/jquery.uploadify.v2.1.4.js deleted file mode 100644 index 2d20a43..0000000 --- a/public/js/jquery.uploadify.v2.1.4.js +++ /dev/null @@ -1,296 +0,0 @@ -/* -Uploadify v2.1.4 -Release Date: November 8, 2010 - -Copyright (c) 2010 Ronnie Garcia, Travis Nickels - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ - -if(jQuery)( - function(jQuery){ - jQuery.extend(jQuery.fn,{ - uploadify:function(options) { - jQuery(this).each(function(){ - var settings = jQuery.extend({ - id : jQuery(this).attr('id'), // The ID of the object being Uploadified - uploader : 'uploadify.swf', // The path to the uploadify swf file - script : 'uploadify.php', // The path to the uploadify backend upload script - expressInstall : null, // The path to the express install swf file - folder : '', // The path to the upload folder - height : 30, // The height of the flash button - width : 120, // The width of the flash button - cancelImg : 'cancel.png', // The path to the cancel image for the default file queue item container - wmode : 'opaque', // The wmode of the flash file - scriptAccess : 'sameDomain', // Set to "always" to allow script access across domains - fileDataName : 'Filedata', // The name of the file collection object in the backend upload script - method : 'POST', // The method for sending variables to the backend upload script - queueSizeLimit : 999, // The maximum size of the file queue - simUploadLimit : 1, // The number of simultaneous uploads allowed - queueID : false, // The optional ID of the queue container - displayData : 'percentage', // Set to "speed" to show the upload speed in the default queue item - removeCompleted : true, // Set to true if you want the queue items to be removed when a file is done uploading - onInit : function() {}, // Function to run when uploadify is initialized - onSelect : function() {}, // Function to run when a file is selected - onSelectOnce : function() {}, // Function to run once when files are added to the queue - onQueueFull : function() {}, // Function to run when the queue reaches capacity - onCheck : function() {}, // Function to run when script checks for duplicate files on the server - onCancel : function() {}, // Function to run when an item is cleared from the queue - onClearQueue : function() {}, // Function to run when the queue is manually cleared - onError : function() {}, // Function to run when an upload item returns an error - onProgress : function() {}, // Function to run each time the upload progress is updated - onComplete : function() {}, // Function to run when an upload is completed - onAllComplete : function() {} // Function to run when all uploads are completed - }, options); - jQuery(this).data('settings',settings); - var pagePath = location.pathname; - pagePath = pagePath.split('/'); - pagePath.pop(); - pagePath = pagePath.join('/') + '/'; - var data = {}; - data.uploadifyID = settings.id; - data.pagepath = pagePath; - if (settings.buttonImg) data.buttonImg = escape(settings.buttonImg); - if (settings.buttonText) data.buttonText = escape(settings.buttonText); - if (settings.rollover) data.rollover = true; - data.script = settings.script; - data.folder = escape(settings.folder); - if (settings.scriptData) { - var scriptDataString = ''; - for (var name in settings.scriptData) { - scriptDataString += '&' + name + '=' + settings.scriptData[name]; - } - data.scriptData = escape(scriptDataString.substr(1)); - } - data.width = settings.width; - data.height = settings.height; - data.wmode = settings.wmode; - data.method = settings.method; - data.queueSizeLimit = settings.queueSizeLimit; - data.simUploadLimit = settings.simUploadLimit; - if (settings.hideButton) data.hideButton = true; - if (settings.fileDesc) data.fileDesc = settings.fileDesc; - if (settings.fileExt) data.fileExt = settings.fileExt; - if (settings.multi) data.multi = true; - if (settings.auto) data.auto = true; - if (settings.sizeLimit) data.sizeLimit = settings.sizeLimit; - if (settings.checkScript) data.checkScript = settings.checkScript; - if (settings.fileDataName) data.fileDataName = settings.fileDataName; - if (settings.queueID) data.queueID = settings.queueID; - if (settings.onInit() !== false) { - jQuery(this).css('display','none'); - jQuery(this).after('
    '); - swfobject.embedSWF(settings.uploader, settings.id + 'Uploader', settings.width, settings.height, '9.0.24', settings.expressInstall, data, {'quality':'high','wmode':settings.wmode,'allowScriptAccess':settings.scriptAccess},{},function(event) { - if (typeof(settings.onSWFReady) == 'function' && event.success) settings.onSWFReady(); - }); - if (settings.queueID == false) { - jQuery("#" + jQuery(this).attr('id') + "Uploader").after('
    '); - } else { - jQuery("#" + settings.queueID).addClass('uploadifyQueue'); - } - } - if (typeof(settings.onOpen) == 'function') { - jQuery(this).bind("uploadifyOpen", settings.onOpen); - } - jQuery(this).bind("uploadifySelect", {'action': settings.onSelect, 'queueID': settings.queueID}, function(event, ID, fileObj) { - if (event.data.action(event, ID, fileObj) !== false) { - var byteSize = Math.round(fileObj.size / 1024 * 100) * .01; - var suffix = 'KB'; - if (byteSize > 1000) { - byteSize = Math.round(byteSize *.001 * 100) * .01; - suffix = 'MB'; - } - var sizeParts = byteSize.toString().split('.'); - if (sizeParts.length > 1) { - byteSize = sizeParts[0] + '.' + sizeParts[1].substr(0,2); - } else { - byteSize = sizeParts[0]; - } - if (fileObj.name.length > 20) { - fileName = fileObj.name.substr(0,20) + '...'; - } else { - fileName = fileObj.name; - } - queue = '#' + jQuery(this).attr('id') + 'Queue'; - if (event.data.queueID) { - queue = '#' + event.data.queueID; - } - jQuery(queue).append('
    \ -
    \ - \ -
    \ - ' + fileName + ' (' + byteSize + suffix + ')\ -
    \ -
    \ -
    \ -
    '); - } - }); - jQuery(this).bind("uploadifySelectOnce", {'action': settings.onSelectOnce}, function(event, data) { - event.data.action(event, data); - if (settings.auto) { - if (settings.checkScript) { - jQuery(this).uploadifyUpload(null, false); - } else { - jQuery(this).uploadifyUpload(null, true); - } - } - }); - jQuery(this).bind("uploadifyQueueFull", {'action': settings.onQueueFull}, function(event, queueSizeLimit) { - if (event.data.action(event, queueSizeLimit) !== false) { - alert('The queue is full. The max size is ' + queueSizeLimit + '.'); - } - }); - jQuery(this).bind("uploadifyCheckExist", {'action': settings.onCheck}, function(event, checkScript, fileQueueObj, folder, single) { - var postData = new Object(); - postData = fileQueueObj; - postData.folder = (folder.substr(0,1) == '/') ? folder : pagePath + folder; - if (single) { - for (var ID in fileQueueObj) { - var singleFileID = ID; - } - } - jQuery.post(checkScript, postData, function(data) { - for(var key in data) { - if (event.data.action(event, data, key) !== false) { - var replaceFile = confirm("Do you want to replace the file " + data[key] + "?"); - if (!replaceFile) { - document.getElementById(jQuery(event.target).attr('id') + 'Uploader').cancelFileUpload(key,true,true); - } - } - } - if (single) { - document.getElementById(jQuery(event.target).attr('id') + 'Uploader').startFileUpload(singleFileID, true); - } else { - document.getElementById(jQuery(event.target).attr('id') + 'Uploader').startFileUpload(null, true); - } - }, "json"); - }); - jQuery(this).bind("uploadifyCancel", {'action': settings.onCancel}, function(event, ID, fileObj, data, remove, clearFast) { - if (event.data.action(event, ID, fileObj, data, clearFast) !== false) { - if (remove) { - var fadeSpeed = (clearFast == true) ? 0 : 250; - jQuery("#" + jQuery(this).attr('id') + ID).fadeOut(fadeSpeed, function() { jQuery(this).remove() }); - } - } - }); - jQuery(this).bind("uploadifyClearQueue", {'action': settings.onClearQueue}, function(event, clearFast) { - var queueID = (settings.queueID) ? settings.queueID : jQuery(this).attr('id') + 'Queue'; - if (clearFast) { - jQuery("#" + queueID).find('.uploadifyQueueItem').remove(); - } - if (event.data.action(event, clearFast) !== false) { - jQuery("#" + queueID).find('.uploadifyQueueItem').each(function() { - var index = jQuery('.uploadifyQueueItem').index(this); - jQuery(this).delay(index * 100).fadeOut(250, function() { jQuery(this).remove() }); - }); - } - }); - var errorArray = []; - jQuery(this).bind("uploadifyError", {'action': settings.onError}, function(event, ID, fileObj, errorObj) { - if (event.data.action(event, ID, fileObj, errorObj) !== false) { - var fileArray = new Array(ID, fileObj, errorObj); - errorArray.push(fileArray); - jQuery("#" + jQuery(this).attr('id') + ID).find('.percentage').text(" - " + errorObj.type + " Error"); - jQuery("#" + jQuery(this).attr('id') + ID).find('.uploadifyProgress').hide(); - jQuery("#" + jQuery(this).attr('id') + ID).addClass('uploadifyError'); - } - }); - if (typeof(settings.onUpload) == 'function') { - jQuery(this).bind("uploadifyUpload", settings.onUpload); - } - jQuery(this).bind("uploadifyProgress", {'action': settings.onProgress, 'toDisplay': settings.displayData}, function(event, ID, fileObj, data) { - if (event.data.action(event, ID, fileObj, data) !== false) { - jQuery("#" + jQuery(this).attr('id') + ID + "ProgressBar").animate({'width': data.percentage + '%'},250,function() { - if (data.percentage == 100) { - jQuery(this).closest('.uploadifyProgress').fadeOut(250,function() {jQuery(this).remove()}); - } - }); - if (event.data.toDisplay == 'percentage') displayData = ' - ' + data.percentage + '%'; - if (event.data.toDisplay == 'speed') displayData = ' - ' + data.speed + 'KB/s'; - if (event.data.toDisplay == null) displayData = ' '; - jQuery("#" + jQuery(this).attr('id') + ID).find('.percentage').text(displayData); - } - }); - jQuery(this).bind("uploadifyComplete", {'action': settings.onComplete}, function(event, ID, fileObj, response, data) { - if (event.data.action(event, ID, fileObj, unescape(response), data) !== false) { - jQuery("#" + jQuery(this).attr('id') + ID).find('.percentage').text(' - Completed'); - if (settings.removeCompleted) { - jQuery("#" + jQuery(event.target).attr('id') + ID).fadeOut(250,function() {jQuery(this).remove()}); - } - jQuery("#" + jQuery(event.target).attr('id') + ID).addClass('completed'); - } - }); - if (typeof(settings.onAllComplete) == 'function') { - jQuery(this).bind("uploadifyAllComplete", {'action': settings.onAllComplete}, function(event, data) { - if (event.data.action(event, data) !== false) { - errorArray = []; - } - }); - } - }); - }, - uploadifySettings:function(settingName, settingValue, resetObject) { - var returnValue = false; - jQuery(this).each(function() { - if (settingName == 'scriptData' && settingValue != null) { - if (resetObject) { - var scriptData = settingValue; - } else { - var scriptData = jQuery.extend(jQuery(this).data('settings').scriptData, settingValue); - } - var scriptDataString = ''; - for (var name in scriptData) { - scriptDataString += '&' + name + '=' + scriptData[name]; - } - settingValue = escape(scriptDataString.substr(1)); - } - returnValue = document.getElementById(jQuery(this).attr('id') + 'Uploader').updateSettings(settingName, settingValue); - }); - if (settingValue == null) { - if (settingName == 'scriptData') { - var returnSplit = unescape(returnValue).split('&'); - var returnObj = new Object(); - for (var i = 0; i < returnSplit.length; i++) { - var iSplit = returnSplit[i].split('='); - returnObj[iSplit[0]] = iSplit[1]; - } - returnValue = returnObj; - } - } - return returnValue; - }, - uploadifyUpload:function(ID,checkComplete) { - jQuery(this).each(function() { - if (!checkComplete) checkComplete = false; - document.getElementById(jQuery(this).attr('id') + 'Uploader').startFileUpload(ID, checkComplete); - }); - }, - uploadifyCancel:function(ID) { - jQuery(this).each(function() { - document.getElementById(jQuery(this).attr('id') + 'Uploader').cancelFileUpload(ID, true, true, false); - }); - }, - uploadifyClearQueue:function() { - jQuery(this).each(function() { - document.getElementById(jQuery(this).attr('id') + 'Uploader').clearFileUploadQueue(false); - }); - } - }) -})(jQuery); \ No newline at end of file diff --git a/public/js/projects.js b/public/js/projects.js deleted file mode 100644 index 0107a80..0000000 --- a/public/js/projects.js +++ /dev/null @@ -1,5 +0,0 @@ -$(function() { - - // this space intentionally left blank - -}) diff --git a/public/js/sign-in.js b/public/js/sign-in.js index 8f6fc78..6be032e 100644 --- a/public/js/sign-in.js +++ b/public/js/sign-in.js @@ -1,7 +1,5 @@ $(function() { - $('input[name="email"]').focus() - $('#forgot-password-link').click(function() { window.location.href = '/forgot-password/' + $('#email').val() return false diff --git a/public/js/swfobject.js b/public/js/swfobject.js deleted file mode 100644 index 8eafe9d..0000000 --- a/public/js/swfobject.js +++ /dev/null @@ -1,4 +0,0 @@ -/* SWFObject v2.2 - is released under the MIT License -*/ -var swfobject=function(){var D="undefined",r="object",S="Shockwave Flash",W="ShockwaveFlash.ShockwaveFlash",q="application/x-shockwave-flash",R="SWFObjectExprInst",x="onreadystatechange",O=window,j=document,t=navigator,T=false,U=[h],o=[],N=[],I=[],l,Q,E,B,J=false,a=false,n,G,m=true,M=function(){var aa=typeof j.getElementById!=D&&typeof j.getElementsByTagName!=D&&typeof j.createElement!=D,ah=t.userAgent.toLowerCase(),Y=t.platform.toLowerCase(),ae=Y?/win/.test(Y):/win/.test(ah),ac=Y?/mac/.test(Y):/mac/.test(ah),af=/webkit/.test(ah)?parseFloat(ah.replace(/^.*webkit\/(\d+(\.\d+)?).*$/,"$1")):false,X=!+"\v1",ag=[0,0,0],ab=null;if(typeof t.plugins!=D&&typeof t.plugins[S]==r){ab=t.plugins[S].description;if(ab&&!(typeof t.mimeTypes!=D&&t.mimeTypes[q]&&!t.mimeTypes[q].enabledPlugin)){T=true;X=false;ab=ab.replace(/^.*\s+(\S+\s+\S+$)/,"$1");ag[0]=parseInt(ab.replace(/^(.*)\..*$/,"$1"),10);ag[1]=parseInt(ab.replace(/^.*\.(.*)\s.*$/,"$1"),10);ag[2]=/[a-zA-Z]/.test(ab)?parseInt(ab.replace(/^.*[a-zA-Z]+(.*)$/,"$1"),10):0}}else{if(typeof O.ActiveXObject!=D){try{var ad=new ActiveXObject(W);if(ad){ab=ad.GetVariable("$version");if(ab){X=true;ab=ab.split(" ")[1].split(",");ag=[parseInt(ab[0],10),parseInt(ab[1],10),parseInt(ab[2],10)]}}}catch(Z){}}}return{w3:aa,pv:ag,wk:af,ie:X,win:ae,mac:ac}}(),k=function(){if(!M.w3){return}if((typeof j.readyState!=D&&j.readyState=="complete")||(typeof j.readyState==D&&(j.getElementsByTagName("body")[0]||j.body))){f()}if(!J){if(typeof j.addEventListener!=D){j.addEventListener("DOMContentLoaded",f,false)}if(M.ie&&M.win){j.attachEvent(x,function(){if(j.readyState=="complete"){j.detachEvent(x,arguments.callee);f()}});if(O==top){(function(){if(J){return}try{j.documentElement.doScroll("left")}catch(X){setTimeout(arguments.callee,0);return}f()})()}}if(M.wk){(function(){if(J){return}if(!/loaded|complete/.test(j.readyState)){setTimeout(arguments.callee,0);return}f()})()}s(f)}}();function f(){if(J){return}try{var Z=j.getElementsByTagName("body")[0].appendChild(C("span"));Z.parentNode.removeChild(Z)}catch(aa){return}J=true;var X=U.length;for(var Y=0;Y0){for(var af=0;af0){var ae=c(Y);if(ae){if(F(o[af].swfVersion)&&!(M.wk&&M.wk<312)){w(Y,true);if(ab){aa.success=true;aa.ref=z(Y);ab(aa)}}else{if(o[af].expressInstall&&A()){var ai={};ai.data=o[af].expressInstall;ai.width=ae.getAttribute("width")||"0";ai.height=ae.getAttribute("height")||"0";if(ae.getAttribute("class")){ai.styleclass=ae.getAttribute("class")}if(ae.getAttribute("align")){ai.align=ae.getAttribute("align")}var ah={};var X=ae.getElementsByTagName("param");var ac=X.length;for(var ad=0;ad'}}aa.outerHTML='"+af+"";N[N.length]=ai.id;X=c(ai.id)}else{var Z=C(r);Z.setAttribute("type",q);for(var ac in ai){if(ai[ac]!=Object.prototype[ac]){if(ac.toLowerCase()=="styleclass"){Z.setAttribute("class",ai[ac])}else{if(ac.toLowerCase()!="classid"){Z.setAttribute(ac,ai[ac])}}}}for(var ab in ag){if(ag[ab]!=Object.prototype[ab]&&ab.toLowerCase()!="movie"){e(Z,ab,ag[ab])}}aa.parentNode.replaceChild(Z,aa);X=Z}}return X}function e(Z,X,Y){var aa=C("param");aa.setAttribute("name",X);aa.setAttribute("value",Y);Z.appendChild(aa)}function y(Y){var X=c(Y);if(X&&X.nodeName=="OBJECT"){if(M.ie&&M.win){X.style.display="none";(function(){if(X.readyState==4){b(Y)}else{setTimeout(arguments.callee,10)}})()}else{X.parentNode.removeChild(X)}}}function b(Z){var Y=c(Z);if(Y){for(var X in Y){if(typeof Y[X]=="function"){Y[X]=null}}Y.parentNode.removeChild(Y)}}function c(Z){var X=null;try{X=j.getElementById(Z)}catch(Y){}return X}function C(X){return j.createElement(X)}function i(Z,X,Y){Z.attachEvent(X,Y);I[I.length]=[Z,X,Y]}function F(Z){var Y=M.pv,X=Z.split(".");X[0]=parseInt(X[0],10);X[1]=parseInt(X[1],10)||0;X[2]=parseInt(X[2],10)||0;return(Y[0]>X[0]||(Y[0]==X[0]&&Y[1]>X[1])||(Y[0]==X[0]&&Y[1]==X[1]&&Y[2]>=X[2]))?true:false}function v(ac,Y,ad,ab){if(M.ie&&M.mac){return}var aa=j.getElementsByTagName("head")[0];if(!aa){return}var X=(ad&&typeof ad=="string")?ad:"screen";if(ab){n=null;G=null}if(!n||G!=X){var Z=C("style");Z.setAttribute("type","text/css");Z.setAttribute("media",X);n=aa.appendChild(Z);if(M.ie&&M.win&&typeof j.styleSheets!=D&&j.styleSheets.length>0){n=j.styleSheets[j.styleSheets.length-1]}G=X}if(M.ie&&M.win){if(n&&typeof n.addRule==r){n.addRule(ac,Y)}}else{if(n&&typeof j.createTextNode!=D){n.appendChild(j.createTextNode(ac+" {"+Y+"}"))}}}function w(Z,X){if(!m){return}var Y=X?"visible":"hidden";if(J&&c(Z)){c(Z).style.visibility=Y}else{v("#"+Z,"visibility:"+Y)}}function L(Y){var Z=/[\\\"<>\.;]/;var X=Z.exec(Y)!=null;return X&&typeof encodeURIComponent!=D?encodeURIComponent(Y):Y}var d=function(){if(M.ie&&M.win){window.attachEvent("onunload",function(){var ac=I.length;for(var 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 diff --git a/test/common.rb b/test/common.rb index c70953b..1a191a6 100644 --- a/test/common.rb +++ b/test/common.rb @@ -237,49 +237,6 @@ module Stormy end # Accounts - - module Admins - - include Stormy::Models - - def setup_admins - @admin_data ||= fixtures('admins')['sami'] - @admin = Admin.create(@admin_data) - end - - def teardown_admins - @admin.delete! - end - - end # Admins - - module Projects - - include Stormy::Models - - def projects - @projects ||= fixtures('projects') - end - - def setup_projects(options = {}) - account = options[:owner] || @existing_account - @existing_project_data = projects['stormy'] - if account - @existing_project_data['account_id'] = account.id - end - @existing_project = Project.create(@existing_project_data) - - @new_project_data = projects['dating-free'] - end - - def teardown_projects - Project.list_ids.each do |id| - Project.delete!(id) - end - end - - end # Projects - end # Helpers end diff --git a/test/controllers/test-accounts_controller.rb b/test/controllers/test-accounts_controller.rb index 1bea148..59810fc 100644 --- a/test/controllers/test-accounts_controller.rb +++ b/test/controllers/test-accounts_controller.rb @@ -7,7 +7,6 @@ require 'common' class AccountsControllerTest < Stormy::Test::ControllerCase include Stormy::Test::Helpers::Accounts - include Stormy::Test::Helpers::Projects def setup setup_accounts @@ -32,7 +31,7 @@ class AccountsControllerTest < Stormy::Test::ControllerCase def test_sign_up_with_valid_data post '/sign-up', @account_data - assert_redirected '/projects' + assert_redirected '/account' assert_equal 1, Pony.sent_mail.length assert mail = Pony.sent_mail.shift end @@ -80,17 +79,17 @@ class AccountsControllerTest < Stormy::Test::ControllerCase def test_sign_in_submit sign_in - assert_redirected '/projects' + assert_redirected '/account' end def test_sign_in_remember sign_in(@existing_account_data, 'remember' => 'on') - assert_redirected '/projects' + assert_redirected '/account' post '/sign-out' assert_redirected '/' - get '/projects' + get '/account' assert_ok # deletes remembered cookie @@ -154,7 +153,7 @@ class AccountsControllerTest < Stormy::Test::ControllerCase new_password = 'new password' post '/account/reset-password', { 'password' => new_password } - assert_redirected '/projects' + assert_redirected '/account' assert_equal @existing_account.id, Account.check_password(@existing_account.email, new_password) assert Account.fetch(@existing_account.id).password == new_password @@ -256,7 +255,7 @@ class AccountsControllerTest < Stormy::Test::ControllerCase def test_verify_email get "/account/verify/#{@existing_account.email}/#{@existing_account.email_verification_token}" assert_redirected '/account' - assert_nil Account.fetch(@existing_account.id).email_verification_token + assert redis.hget(@existing_account.id, 'email_verification_token').blank? end def test_verify_email_with_invalid_token_signed_in diff --git a/test/controllers/test-admin_controller.rb b/test/controllers/test-admin_controller.rb index 9fb0736..2ccbb41 100644 --- a/test/controllers/test-admin_controller.rb +++ b/test/controllers/test-admin_controller.rb @@ -7,89 +7,33 @@ require 'common' class AdminControllerTest < Stormy::Test::ControllerCase include Stormy::Test::Helpers::Accounts - include Stormy::Test::Helpers::Projects include Stormy::Helpers::Admin include Stormy::Helpers::FAQ include Stormy::Helpers::Utils - def admins - @admins ||= fixtures('admins') - end - def setup - @existing_admin_data = admins['sami'] - @existing_admin = Admin.create(@existing_admin_data) - - @admin_data = admins['freddy'] + setup_accounts end def teardown - post '/admin/sign-out' - Admin.list_ids.each do |id| - Admin.delete!(id) - end + post '/sign-out' + teardown_accounts end - def sign_in(admin = @existing_admin_data) - post '/admin/sign-in', admin + def sign_in(admin = @existing_account_data) + post '/sign-in', admin end - ##################### - ### Sign In & Out ### - ##################### - - def test_sign_in - get '/admin/sign-in' - assert_ok - end - - def test_sign_in_submit - sign_in - assert_redirected '/admin' - end - - def test_sign_in_with_invalid_credentials - sign_in(@admin_data) - assert_redirected '/admin/sign-in' - end - - def test_sign_in_redirect - sign_in - assert_redirected '/admin' - end - - def test_sign_out - post '/admin/sign-out' - assert_redirected '/admin' - end - - - ############################ - ### Dashboard & Password ### - ############################ + ################# + ### Dashboard ### + ################# def test_dashboard sign_in get '/admin' assert_ok - assert last_response.body.match(/Dashboard/) - end - - def test_change_password - sign_in - get '/admin/password' - assert_ok - - new_password = 'new password' - post '/admin/password', { 'password' => new_password, 'password_confirmation' => new_password } - assert_redirected '/admin' - @existing_admin.reload! - assert @existing_admin.password == new_password - - # incorrect confirmation - post '/admin/password', { 'password' => new_password, 'password_confirmation' => 'oops' } - assert_redirected '/admin/password' + assert last_response.body.match(/<title>[^<]*Dashboard[^<]*<\/title>/) end @@ -104,7 +48,6 @@ class AdminControllerTest < Stormy::Test::ControllerCase end def test_account - setup_accounts sign_in get '/admin/account/' + @existing_account.email @@ -113,12 +56,9 @@ class AdminControllerTest < Stormy::Test::ControllerCase get '/admin/account/not@an.account' # this was the previous listing, kind of weird but meh assert_redirected '/admin/account/' + @existing_account.email - - teardown_accounts end def test_update_account - setup_accounts sign_in # redirected to proper page when changing email addresses @@ -162,94 +102,34 @@ class AdminControllerTest < Stormy::Test::ControllerCase assert_equal 'Samson', @existing_account.first_name assert_equal 'Simpson', @existing_account.last_name assert_equal '+12501234567', @existing_account.phone - - teardown_accounts end def test_sign_in_as_user - setup_accounts sign_in get '/admin/sign-in-as/' + @existing_account.email assert_equal @existing_account.id, session[:id] - assert_redirected '/projects' - - teardown_accounts + assert_redirected '/account' end def test_delete_account - setup_accounts - setup_projects sign_in # make sure the last listing is marked so we are redirected correctly get '/admin/accounts' assert_ok - get "/admin/account/#{@existing_account.email}/delete" + @other_account = Account.create(@account_data) + get "/admin/account/#{@other_account.email}/delete" assert_redirected '/admin/accounts' - assert_nil Account.fetch(@existing_account.id) - assert_nil Project.fetch(@existing_project.id) + assert_nil Account.fetch(@other_account.id) # non-existent accounts are already gone, so no problem get "/admin/account/nobody@nowhere.net/delete" # this time the last listing was not marked, so we are redirected to the dashboard assert_redirected '/admin' - - teardown_projects - teardown_accounts - end - - - ################ - ### Projects ### - ################ - - def test_projects - setup_accounts - setup_projects - sign_in - - get '/admin/projects' - assert_ok - - teardown_projects - teardown_accounts - end - - def test_project - setup_accounts - setup_projects - sign_in - - # non-existent project - get '/admin/project/999' - assert_redirected '/admin' - - # existing project - get '/admin/project/' + @existing_project.id - assert_ok - - teardown_projects - teardown_accounts - end - - def test_delete_project - setup_accounts - setup_projects - sign_in - - # make sure the last listing is marked so we are redirected correctly - get '/admin/projects' - - get "/admin/project/#{@existing_project.id}/delete" - assert_redirected '/admin/projects' - assert_nil Project.fetch(@existing_project.id) - - teardown_projects - teardown_accounts end @@ -276,51 +156,4 @@ class AdminControllerTest < Stormy::Test::ControllerCase self.faq = original_faq end - - ###################### - ### Admin Accounts ### - ###################### - - def test_admins - sign_in - get '/admin/admins' - assert_ok - end - - def test_add_admin - sign_in - - password = 'password' - fields = { - 'name' => 'Freddy Kruger', - 'email' => 'freddy@example.com', - 'password' => password, - 'password_confirmation' => password - } - post '/admin/admins', fields - assert_redirected '/admin/admins' - admin = Admin.fetch_by_email('freddy@example.com') - assert admin.password == password - assert_equal fields['name'], admin.name - assert_equal fields['email'], admin.email - - # passwords do not match - fields = { - 'name' => 'Jason Vorhees', - 'email' => 'jason@example.com', - 'password' => 'my password', - 'password_confirmation' => 'not the same password' - } - post '/admin/admins', fields - assert_redirected '/admin/admins' - assert_nil Admin.fetch_by_email('jason@example.com') - end - - def test_delete_admin - sign_in - get "/admin/admins/#{@existing_admin.id}/delete" - assert_redirected '/admin/admins' - assert_equal 0, Admin.count - end - end diff --git a/test/controllers/test-projects_controller.rb b/test/controllers/test-projects_controller.rb deleted file mode 100644 index 19fcb75..0000000 --- a/test/controllers/test-projects_controller.rb +++ /dev/null @@ -1,262 +0,0 @@ -#!/usr/bin/env ruby -# -# Copyright 2011 Beta Street Media - -require 'common' - -class ProjectsControllerTest < Stormy::Test::ControllerCase - - include Stormy::Test::Helpers::Accounts - include Stormy::Test::Helpers::Admins - include Stormy::Test::Helpers::Projects - include Stormy::Helpers::Authorization - - def setup - header 'User-Agent', "rack/test (#{Rack::Test::VERSION})" - setup_accounts - setup_projects - sign_in - - @updated_project_data ||= { - :id => @existing_project.id, - :name => 'the super amazing project' - } - end - - def teardown - teardown_projects - teardown_accounts - end - - def create_other_account_and_project - @other_account = Account.create(@account_data) - @new_project_data['account_id'] = @other_account.id - @other_project = Project.create(@new_project_data) - end - - def photo_filenames - @photo_filenames ||= Dir[photo_file('*.jpg')] - end - - def add_photo(filename = photo_filenames.first) - post '/project/add-photo', { - :id => @existing_project.id, - :photo => Rack::Test::UploadedFile.new(filename, 'image/jpeg') - } - @existing_project.reload! - photo_id = @existing_project.photo_ids.last - assert_response_json_ok( - 'n' => @existing_project.count_photos, - 'photo' => { - 'id' => photo_id, - 'url' => @existing_project.photo_url(photo_id) - } - ) - end - - def add_all_photos - photo_filenames.each { |f| add_photo(f) } - end - - - ################## - ### Projects ### - ################## - - def test_projects - # must be authorized - sign_out - get '/projects' - assert_redirected '/sign-in' - - # now we can get the projects page - sign_in - get '/projects' - assert_ok - end - - def test_project - get "/project/#{@existing_project.id}" - assert_ok - end - - def test_project_without_a_name - @existing_project.name = '' - @existing_project.save! - get "/project/#{@existing_project.id}" - assert_ok - end - - def test_cannot_access_others_projects - create_other_account_and_project - get "/project/#{@other_project.id}" - assert_redirected '/projects' - follow_redirect! - assert_ok - assert last_response.body.match(/no such project/i) - end - - def test_update_project - data = @updated_project_data - post '/project/update', data - assert_redirected "/project/#{data[:id]}" - @existing_project.reload! - data.each do |name, value| - assert_equal value, @existing_project.send(name) - end - end - - def test_update_project_with_invalid_fields - expected_name = @existing_project.name - data = { - :id => @existing_project.id, - :name => '' - } - post '/project/update', data - assert_redirected "/project/#{data[:id]}" - @existing_project.reload! - assert_equal expected_name, @existing_project.name - end - - def test_update_project_by_admin - setup_admins - post '/admin/sign-in', @admin_data - - data = @updated_project_data - post '/project/update', data - assert_redirected "/project/#{data[:id]}" - - teardown_admins - end - - def test_cannot_update_others_projects - create_other_account_and_project - post '/project/update', { :id => @other_project.id } - assert_redirected '/projects' - follow_redirect! - assert_ok - assert last_response.body.match(/no such project/i) - end - - def test_add_photo - # also test /uploadify which is used for photo uploads in IE - %w[/project/add-photo /uploadify].each_with_index do |path, i| - post path, { - :id => @existing_project.id, - # /project/add-photo - :photo => Rack::Test::UploadedFile.new(photo_filenames.first, 'image/jpeg'), - # /uploadify - :Filedata => Rack::Test::UploadedFile.new(photo_filenames.first, 'image/jpeg') - } - @existing_project.reload! - photo_id = @existing_project.photo_ids[i] - assert_response_json_ok({ - 'n' => i + 1, - 'photo' => { - 'id' => photo_id, - 'url' => @existing_project.photo_url(photo_id) - } - }) - end - end - - def test_add_photo_fails_at_photo_limit - Project::MaxPhotos.times { add_photo } - - post '/project/add-photo', { - :id => @existing_project.id, - :photo => Rack::Test::UploadedFile.new(photo_filenames.first, 'image/jpeg'), - } - assert_response_json_fail('limit') - - post '/uploadify', { - :id => @existing_project.id, - :Filedata => Rack::Test::UploadedFile.new(photo_filenames.first, 'image/jpeg'), - } - assert_bad_request - end - - def test_add_photo_by_admin - setup_admins - post '/admin/sign-in', @admin_data - - post '/project/add-photo', { - :id => @existing_project.id, - :photo => Rack::Test::UploadedFile.new(photo_filenames.first, 'image/jpeg'), - } - @existing_project.reload! - photo_id = @existing_project.photo_ids.last - assert_response_json_ok({ - 'n' => 1, - 'photo' => { - 'id' => photo_id, - 'url' => @existing_project.photo_url(photo_id) - } - }) - - teardown_admins - end - - def test_remove_photo - add_photo - photo_id = @existing_project.photo_ids.last - post '/project/remove-photo', { - :id => @existing_project.id, - :photo_id => photo_id - } - @existing_project.reload! - assert_response_json_ok('photos' => []) - assert_equal 0, @existing_project.count_photos - end - - def test_remove_photo_by_admin - setup_admins - post '/admin/sign-in', @admin_data - - add_photo - photo_id = @existing_project.photo_ids.last - post '/project/remove-photo', { - :id => @existing_project.id, - :photo_id => photo_id - } - @existing_project.reload! - assert_response_json_ok('photos' => []) - assert_equal 0, @existing_project.count_photos - - teardown_admins - end - - def test_reorder_photos - add_all_photos - @existing_project.reload! - photo_ids = @existing_project.photo_ids - # move the first to the end - photo_ids.push(photo_ids.shift) - post '/project/photo-order', { - :id => @existing_project.id, - :order => photo_ids - } - @existing_project.reload! - assert_equal photo_ids, @existing_project.photo_ids - end - - def test_reorder_photos_by_admin - setup_admins - post '/admin/sign-in', @admin_data - - add_all_photos - @existing_project.reload! - photo_ids = @existing_project.photo_ids - # move the first to the end - photo_ids.push(photo_ids.shift) - post '/project/photo-order', { - :id => @existing_project.id, - :order => photo_ids - } - @existing_project.reload! - assert_equal photo_ids, @existing_project.photo_ids - - teardown_admins - end - -end diff --git a/test/fixtures/accounts.json b/test/fixtures/accounts.json index 926a257..f0b2a18 100644 --- a/test/fixtures/accounts.json +++ b/test/fixtures/accounts.json @@ -4,6 +4,7 @@ , "email" : "sami@example.com" , "phone" : "250-216-6216" , "password" : "super secret" + , "role" : "admin" } , "freddy": { @@ -12,5 +13,6 @@ , "email" : "freddy@example.com" , "phone" : "(250) 555-9999" , "password" : "even more secreter" + , "role" : "user" } } diff --git a/test/fixtures/admins.json b/test/fixtures/admins.json deleted file mode 100644 index 85244ba..0000000 --- a/test/fixtures/admins.json +++ /dev/null @@ -1,12 +0,0 @@ -{ "sami": { - "name" : "Sami" - , "email" : "sami@example.com" - , "password" : "super secret" - } - -, "freddy": { - "name" : "Freddy" - , "email" : "freddy@example.com" - , "password" : "even more secreter" - } -} diff --git a/test/fixtures/projects.json b/test/fixtures/projects.json deleted file mode 100644 index d18cb43..0000000 --- a/test/fixtures/projects.json +++ /dev/null @@ -1,14 +0,0 @@ -{ "stormy": { - "name" : "Stormy Weather" - } - -, "apps-for-you" : { - "name" : "Apps For You" - , "funded_timestamp" : 1328475981 - } - -, "dating-free" : { - "name" : "Dating Free" - , "fizzled_timestamp" : 1328475981 - } -} diff --git a/test/helpers/test-accounts.rb b/test/helpers/test-accounts.rb index 1d86e09..5648483 100644 --- a/test/helpers/test-accounts.rb +++ b/test/helpers/test-accounts.rb @@ -8,7 +8,6 @@ class AccountsHelperTest < Stormy::Test::HelperCase include Stormy::Helpers::Accounts include Stormy::Test::Helpers::Accounts - include Stormy::Test::Helpers::Projects def setup setup_accounts diff --git a/test/helpers/test-admin.rb b/test/helpers/test-admin.rb index 79b1424..35cdcd6 100644 --- a/test/helpers/test-admin.rb +++ b/test/helpers/test-admin.rb @@ -16,14 +16,6 @@ class AdminHelperTest < Stormy::Test::HelperCase assert_equal 0, num_accounts end - def test_num_admins - assert_equal 0, num_admins - end - - def test_num_projects - assert_equal 0, num_projects - end - def test_last_listing assert_equal '/admin', last_listing mark_last_listing '/admin/accounts' diff --git a/test/helpers/test-authorization.rb b/test/helpers/test-authorization.rb index b5385a3..63d3537 100644 --- a/test/helpers/test-authorization.rb +++ b/test/helpers/test-authorization.rb @@ -8,21 +8,16 @@ class AuthorizationHelperTest < Stormy::Test::HelperCase include Stormy::Helpers::Authorization include Stormy::Test::Helpers::Accounts - include Stormy::Test::Helpers::Admins - include Stormy::Test::Helpers::Projects def setup setup_accounts - setup_projects end def teardown deauthorize teardown_request teardown_accounts - teardown_projects @current_account = nil - @current_project = nil end def teardown_request @@ -69,7 +64,7 @@ class AuthorizationHelperTest < Stormy::Test::HelperCase end def url - '/projects' + '/account' end end end @@ -153,116 +148,31 @@ class AuthorizationHelperTest < Stormy::Test::HelperCase assert_equal @existing_account.id, current_account.id end - def test_current_project - assert_nil current_project - - current_project(@existing_project.id) - assert_equal @existing_project.id, current_project.id - end - - def test_project_authorized? - assert !project_authorized? - - current_project(@existing_project.id) - assert !project_authorized? - - authorize_account(@existing_account.id) - assert project_authorized? - - @current_account = nil - other_account = Account.create(@account_data) - authorize_account(other_account) - assert !project_authorized? - other_account.delete! - end - - def test_authorize_project_api! - assert_equal not_authorized, catch(:halt) { authorize_project_api!(@existing_project.id) } - assert_content_type 'text/plain' - @content_type = nil - - authorize_account(@existing_account.id) - authorize_project_api!(@existing_project.id) - - assert_equal fail('no such project'), catch(:halt) { authorize_project_api!('non-existent id') } - - @current_account = nil - other_account = Account.create(@account_data) - authorize_account(other_account.id) - assert_equal not_authorized, catch(:halt) { authorize_project_api!(@existing_project.id) } - assert_content_type 'text/plain' - other_account.delete! - end - - def test_authorize_project! - assert_redirected('/sign-in') { authorize_project!(@existing_project.id) } - assert !project_authorized? - - authorize_account(@existing_account.id) - assert_redirected('/projects') { authorize_project!('non-existent id') } - assert_equal 'No such project.', flash[:warning] - @redirect = nil - - authorize_project!(@existing_project.id) - assert_not_redirected - - @current_account = nil - other_account = Account.create(@account_data) - authorize_account(other_account.id) - assert_redirected('/projects') { authorize_project!(@existing_project.id) } - assert_equal 'No such project.', flash[:warning] - other_account.delete! - end - - def test_authorize_admin - setup_admins - authorize_admin(@admin.id) - assert_equal @admin.id, session[:admin_id] - assert admin_authorized? - teardown_admins - end - - def test_deauthorize_admin - setup_admins - authorize_admin(@admin.id) - - deauthorize_admin - assert !admin_authorized? - assert !session.has_key?(:admin_id) - teardown_admins - end - def test_admin_authorized? - setup_admins assert !admin_authorized? - authorize_admin(@admin.id) + authorize_account(@existing_account.id) assert admin_authorized? - @current_admin = nil - authorize_admin('does not exist') + @current_account = nil + authorize_account('does not exist') assert !admin_authorized? - teardown_admins end def test_admin_authorize! - setup_admins - authorize_admin(@admin.id) + authorize_account(@existing_account.id) admin_authorize! assert_not_redirected assert !session.has_key?(:original_url) - teardown_admins end def test_admin_authorize_redirects_to_sign_in - assert_redirected('/admin') { admin_authorize! } + assert_redirected('/sign-in') { admin_authorize! } assert_equal request.url, session[:original_url] end def test_admin_authorize_api! - setup_admins - authorize_admin(@admin.id) + authorize_account(@existing_account.id) assert_nil catch(:halt) { admin_authorize_api! } - teardown_admins end def test_admin_authorize_api_throws_if_unauthorized @@ -270,13 +180,4 @@ class AuthorizationHelperTest < Stormy::Test::HelperCase assert_content_type 'text/plain' end - def test_current_admin - setup_admins - assert_nil current_admin - - authorize_admin(@admin.id) - assert_equal @admin.id, current_admin.id - teardown_admins - end - end diff --git a/test/helpers/test-views.rb b/test/helpers/test-views.rb index ab5bf14..86454f4 100644 --- a/test/helpers/test-views.rb +++ b/test/helpers/test-views.rb @@ -203,4 +203,11 @@ class ViewsHelperTest < Stormy::Test::HelperCase assert_equal "<p>42</p>\n", markdown(42) end + def test_admin_page? + assert admin_page?('/admin') + assert admin_page?('/admin/accounts') + assert !admin_page?('/') + assert !admin_page?('/account') + end + end diff --git a/test/models/test-account.rb b/test/models/test-account.rb index bcec183..e345d9c 100644 --- a/test/models/test-account.rb +++ b/test/models/test-account.rb @@ -7,11 +7,9 @@ require 'common' class AccountTest < Stormy::Test::Case include Stormy::Test::Helpers::Accounts - include Stormy::Test::Helpers::Projects def setup setup_accounts - setup_projects @invalid_addresses = [ 'invalid email address', @@ -22,7 +20,6 @@ class AccountTest < Stormy::Test::Case end def teardown - teardown_projects teardown_accounts end @@ -75,7 +72,7 @@ class AccountTest < Stormy::Test::Case assert Account.verify_email(@existing_account.email, @existing_account.email_verification_token) account = Account.fetch(@existing_account.id) assert account.email_verified - assert !account.email_verification_token + assert !account.instance_variable_get('@email_verification_token') assert !Account.verify_email('non@existent.email', 'insignificant token') end @@ -90,15 +87,12 @@ class AccountTest < Stormy::Test::Case # no new token is generated if one is present token = @existing_account.email_verification_token - @existing_account.create_email_verification_token assert_equal @existing_account.email_verification_token, token # a token is generated if necessary Account.verify_email(@existing_account.email, @existing_account.email_verification_token) # clears token account = Account.fetch(@existing_account.id) - assert !account.email_verification_token - account.create_email_verification_token - assert account.email_verification_token + assert !account.instance_variable_get('@email_verification_token') assert account.email_verification_token != token end @@ -132,7 +126,7 @@ class AccountTest < Stormy::Test::Case end def test_create_with_existing_email - assert_raises Account::EmailTakenError do + assert_raises Account::DuplicateFieldError do Account.new(@existing_account_data).create end end @@ -195,46 +189,14 @@ class AccountTest < Stormy::Test::Case assert Account.fetch_by_email(@existing_account.email).nil?, 'Account was fetched by email after deletion' # indexes - assert !@existing_account.email_taken?, 'Account email is taken after deletion' + assert !@existing_account.email_taken?(@existing_account.email), 'Account email is taken after deletion' assert !Account.exists?(@existing_account.id), 'Account exists after deletion' - - # projects are deleted - assert_equal [], @existing_account.project_ids end def test_name assert_equal "#{@existing_account.first_name} #{@existing_account.last_name}", @existing_account.name end - def test_count_projects - assert_equal 1, @existing_account.count_projects - end - - def test_project_ids - assert_equal [@existing_project.id], @existing_account.project_ids - end - - def test_projects - assert_equal [@existing_project.id], @existing_account.projects.map { |p| p.id } - end - - def test_sorted_projects - # make sure created timestamp is in the future ... this stinks - sleep 1 - project = Project.create(@new_project_data.merge(:account_id => @existing_account.id)) - assert_equal [@existing_project.id, project.id], @existing_account.sorted_projects.map { |p| p.id } - end - - def test_add_project_id - @existing_account.add_project_id('fake-project-id') - assert_equal 2, @existing_account.count_projects - end - - def test_remove_project_id - @existing_account.remove_project_id(@existing_project.id) - assert_equal 0, @existing_account.count_projects - end - def test_update original_data = { 'id' => @existing_account.id, @@ -377,7 +339,7 @@ class AccountTest < Stormy::Test::Case # all should be updated check_account_fields(@existing_account, updated_data) - # restore fields required for project clean up + # restore fields required for clean up @existing_account.update!(original_data) end diff --git a/test/models/test-admin.rb b/test/models/test-admin.rb deleted file mode 100644 index 54e2984..0000000 --- a/test/models/test-admin.rb +++ /dev/null @@ -1,237 +0,0 @@ -#!/usr/bin/env ruby -# -# Copyright 2012 Sami Samhuri <sami@samhuri.net> - -require 'common' - -class AdminTest < Stormy::Test::Case - - def setup - admins = fixtures('admins') - @admin_data = admins['sami'] - @admin = Admin.create(@admin_data) - - @invalid_addresses = [ - 'invalid email address', - 'invalid@email@address', - 'invalid.email.address', - 'invalid.email@address' - ] - end - - def teardown - @admin.delete! - end - - - ### Class Methods - - def test_key_from_email - assert_equal @admin.send(:key), Admin.key_from_email(@admin.email) - assert_nil Admin.key_from_email('not a real email') - end - - def test_check_password - assert_equal @admin.id, Admin.check_password(@admin.email, @admin_data['password']) - assert_equal @admin.id, Admin.check_password(@admin.email.upcase, @admin_data['password']) - assert !Admin.check_password(@admin.email, 'incorrect password') - assert !Admin.check_password('non@existent.email', 'any password') - end - - def test_email_taken? - assert Admin.email_taken?(@admin.email) - assert !Admin.email_taken?('freddy@example.com'), "New email is reported as taken" - end - - def test_fetch_existing_by_id - admin = Admin.fetch(@admin.id) - assert admin - assert_equal @admin.id, admin.id - check_admin_fields(admin, @admin_data) - end - - def test_fetch_nonexistent_by_id - assert_nil Admin.fetch('this is not a real id') - end - - def test_fetch_existing_by_email - admin = Admin.fetch_by_email(@admin.email) - assert admin - assert_equal @admin.id, admin.id - check_admin_fields(admin, @admin_data) - end - - def test_fetch_nonexistent_by_email - assert_nil Admin.fetch_by_email('this is not a real email') - end - - def test_id_from_email - assert_equal @admin.id, Admin.id_from_email(@admin.email) - assert_nil Admin.id_from_email('not a real email') - end - - - ### Instance Methods - - def check_admin_fields(admin, fields) - fields.each do |key, expected| - if key == 'password' - assert admin.password == fields['password'], "<#{fields['password'].inspect}> expected but was <#{admin.password.inspect}>" - else - actual = admin.send(key) - assert_equal expected, actual, "#{key}: <#{expected.inspect}> expected but was <#{actual.inspect}>" - end - end - end - - def test_create - assert @admin - assert @admin.id - check_admin_fields(@admin, @admin_data) - - # indexes - assert Admin.fetch_by_email(@admin.email) - end - - def test_create_with_existing_email - assert_raises Admin::EmailTakenError do - Admin.new(@admin_data).create - end - end - - def test_create_with_missing_fields - # name - assert_raises Admin::InvalidDataError do - Admin.create({ 'email' => 'freddy@example.com', 'password' => 'secret password' }) - end - assert_raises Admin::InvalidDataError do - Admin.create({ 'name' => ' ', 'email' => 'freddy@example.com', 'password' => 'secret password' }) - end - - # email - assert_raises Admin::InvalidDataError do - Admin.create({ 'name' => 'Freddy', 'password' => 'secret password' }) - end - assert_raises Admin::InvalidDataError do - Admin.create({ 'name' => 'Freddy', 'email' => ' ', 'password' => 'secret password' }) - end - - # password - assert_raises Admin::InvalidDataError do - Admin.create({ 'name' => 'Freddy', 'email' => 'freddy@example.com' }) - end - assert_raises Admin::InvalidDataError do - Admin.create({ 'name' => 'Freddy', 'email' => 'freddy@example.com', 'password' => ' ' }) - end - end - - def test_create_with_invalid_fields - data = { - 'name' => 'Freddy', - 'password' => 'secret password' - } - - @invalid_addresses.each do |email| - data['email'] = email - assert_raises Admin::InvalidDataError do - Admin.create(data) - end - end - end - - def test_delete! - @admin.delete! - - assert Admin.fetch(@admin.id).nil?, 'Admin was fetched by id after deletion' - assert Admin.fetch_by_email(@admin.email).nil?, 'Admin was fetched by email after deletion' - - # indexes - assert !@admin.email_taken?, 'Admin email is taken after deletion' - assert !Admin.exists?(@admin.id), 'Admin exists after deletion' - end - - def test_update - original_data = { - 'id' => @admin.id, - 'email' => @admin.email, - } - - updated_data = { - # updatable - 'name' => 'Samson', - - # not updatable - 'id' => 'should be ignored', - 'email' => 'should be ignored', - 'password' => 'should be ignored', - } - @admin.update(updated_data) - - # should be updated - assert_equal updated_data['name'], @admin.name - - # should not be updated - assert_equal original_data['id'], @admin.id - assert_equal original_data['email'], @admin.email - assert @admin.password != updated_data['password'] - assert @admin.password == @admin_data['password'] - end - - def test_update_with_invalid_fields - assert_raises Admin::InvalidDataError do - @admin.update({ 'name' => ' ' }) - end - end - - def test_update_email - # pretend this address is verified - new_email = 'sami-different@example.com' - old_email = @admin.email - - # updates database immediately - @admin.update_email(new_email) - assert_equal new_email, @admin.email - assert_equal new_email, Admin.fetch(@admin.id).email - - # index is updated - assert Admin.email_taken?(new_email) - assert !Admin.email_taken?(old_email) - - # no change in address is a noop - @admin.update_email(new_email) - - # invalid addresses are rejected - @invalid_addresses.each do |email| - assert_raises Admin::InvalidDataError do - @admin.update_email(email) - end - end - end - - def test_update_email_changing_only_case - # change only the case - loud_email = @admin.email.upcase - @admin.update_email(loud_email) - assert_equal loud_email, @admin.email - - # is still indexed properly - assert Admin.email_taken?(loud_email) - end - - def test_update_password - old_password = @admin_data['password'] - new_password = 'the new password' - @admin.update_password(old_password, new_password) - assert @admin.password == new_password - assert Admin.fetch(@admin.id).password == new_password - - assert_raises Admin::IncorrectPasswordError do - @admin.update_password('incorrect', 'irrelevant') - end - - assert_raises Admin::InvalidDataError do - @admin.update_password(new_password, ' ') - end - end - -end diff --git a/test/models/test-base.rb b/test/models/test-base.rb index 1597f2d..eecd340 100644 --- a/test/models/test-base.rb +++ b/test/models/test-base.rb @@ -9,8 +9,10 @@ class ModelBaseTest < Stormy::Test::Case def setup @my_model_class = Class.new(Stormy::Models::Base) @my_model_class.class_eval do + model_name 'my_model' field :id, :required => true - field :name, :updatable => true, :required => true + field :name, :updatable => true, :required => true, :indexed => true + field :email, :required => true, :unique => true field :age, { :type => :integer, :required => true, @@ -18,14 +20,8 @@ class ModelBaseTest < Stormy::Test::Case :validator => proc { |n| n >= 18 } } field :verified, :type => :boolean - - def create - self.id = UUID.generate unless id.present? - super - end - end - @fields = { 'name' => 'Sami', 'age' => '29' } + @fields = { 'name' => 'Sami', 'age' => '29', 'email' => 'sami@samhuri.net' } @my_model = @my_model_class.create(@fields) end @@ -39,15 +35,16 @@ class ModelBaseTest < Stormy::Test::Case ### Class Methods def test_name - @my_model_class.name 'my_model' - assert_equal 'my_model', @my_model_class.name + @my_model_class.model_name 'my_model' + assert_equal 'my_model', @my_model_class.model_name end def test_id_field - # has id by default + # has id id_field = { :type => :string, - :required => true + :required => true, + :accessors => true } assert_equal(id_field, @my_model_class.fields[:id]) methods = %w[id id=] @@ -60,7 +57,9 @@ class ModelBaseTest < Stormy::Test::Case name_field = { :type => :string, :required => true, - :updatable => true + :updatable => true, + :accessors => true, + :indexed => true } assert_equal(name_field, @my_model_class.fields[:name]) methods = %w[name name=] @@ -85,7 +84,7 @@ class ModelBaseTest < Stormy::Test::Case end def test_verified_field - verified_field = { :type => :boolean } + verified_field = { :type => :boolean, :accessors => true } assert_equal(verified_field, @my_model_class.fields[:verified]) methods = %w[verified verified= verified?] methods.each do |name| @@ -125,7 +124,7 @@ class ModelBaseTest < Stormy::Test::Case def test_key id = @my_model.id - key = Stormy.key(@my_model_class.name, id) + key = Stormy.key(@my_model_class.model_name, id) assert_equal key, @my_model_class.key(id) end diff --git a/test/models/test-project.rb b/test/models/test-project.rb deleted file mode 100644 index 5a63e2a..0000000 --- a/test/models/test-project.rb +++ /dev/null @@ -1,160 +0,0 @@ -#!/usr/bin/env ruby -# -# Copyright 2011 Beta Street Media - -require 'common' - -JPEGHeader = "\xFF\xD8\xFF\xE0\u0000\u0010JFIF" - -class ProjectTest < Stormy::Test::Case - - include Stormy::Test::Helpers::Accounts - include Stormy::Test::Helpers::Projects - - def setup - setup_accounts - setup_projects - @test_photo_path = photo_file('wild-wacky-action-bike.jpg') - end - - def teardown - teardown_projects - teardown_accounts - end - - def check_project_fields(project, fields) - fields.each do |key, expected| - actual = project.send(key) - assert_equal expected, actual, "#{key}: <#{expected.inspect}> expected but was <#{actual.inspect}>" - end - end - - - ##################### - ### Class Methods ### - ##################### - - def test_fetch_by_name - project = Project.fetch_by_name(@existing_project.name) - assert project - assert_equal @existing_project.id, project.id - check_project_fields(project, @existing_project_data) - end - - def test_fetch_nonexistent_by_name - assert_nil Project.fetch_by_name('non-existent') - end - - - ######################## - ### Instance Methods ### - ######################## - - def test_create - assert @existing_project - assert @existing_project.id - check_project_fields(@existing_project, @existing_project_data) - - # ensure created time is set - # (timestamps may have been a second or two ago at this point, give some allowance for that) - created_delta = Time.now.to_i - @existing_project.created_timestamp - assert created_delta < 3 - - # adds iteslf to project id list on associated account - assert @existing_project.account.project_ids.include?(@existing_project.id) - end - - def test_save_with_missing_fields - Project.fields.each do |name, options| - if options[:required] - orig_value = @existing_project.send(name) - @existing_project.send("#{name}=", nil) - assert_raises Project::InvalidDataError, "#{name} should be required" do - @existing_project.save - end - empty_value = - case options[:type] - when :string - ' ' - when :integer - 0 - else - ' ' - end - @existing_project.send("#{name}=", empty_value) - assert_raises Project::InvalidDataError, "#{name} should be required" do - @existing_project.save - end - @existing_project.send("#{name}=", orig_value) - end - end - end - - def test_delete! - @existing_project.delete! - assert Project.fetch(@existing_project.id).nil?, 'Project was fetched by id after deletion' - assert !Project.exists?(@existing_project.id), 'Project exists after deletion' - - # removes iteslf from project id list on associated account - assert !@existing_project.account.project_ids.include?(@existing_project.id) - end - - def test_count_photos - 10.times do |i| - assert_equal i, @existing_project.count_photos - @existing_project.add_photo(@test_photo_path) - assert_equal i + 1, @existing_project.count_photos - end - end - - def test_add_photo - data = @existing_project.add_photo(@test_photo_path) - assert_equal 1, @existing_project.count_photos - path = @existing_project.send(:photo_path, data['id']) - assert File.exists?(path) - assert_equal JPEGHeader, File.read(path, JPEGHeader.length) - end - - def test_remove_photo - data = @existing_project.add_photo(@test_photo_path) - path = @existing_project.send(:photo_path, data['id']) - @existing_project.remove_photo(data['id']) - assert !File.exists?(path) - assert_equal 0, @existing_project.count_photos - end - - def test_photo_data - data = @existing_project.add_photo(@test_photo_path) - assert_equal data, @existing_project.photo_data(data['id']) - end - - def test_photo_urls - data = @existing_project.add_photo(@test_photo_path) - urls = @existing_project.photo_urls - assert_equal 1, urls.length - - url = urls.first - assert_equal "/photos/#{@existing_project.id}/#{data['id']}.jpg", url - assert_equal data['url'], url - end - - def test_photo_paths - @existing_project.add_photo(@test_photo_path) - assert_equal 1, @existing_project.photo_paths.length - end - - def test_photos - assert_equal [], @existing_project.photos - data = nil - 5.times do |i| - data = @existing_project.add_photo(@test_photo_path) - end - assert_equal [data] * 5, @existing_project.photos - end - - def test_account - assert @existing_project.account - assert_equal @existing_account.id, @existing_project.account.id - end - -end diff --git a/test/photos/wild-wacky-action-bike.jpg b/test/photos/wild-wacky-action-bike.jpg deleted file mode 100644 index 2fe6dfc96ec3bc57e210bc9d2960b08d7bf79189..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22465 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 BVygfE diff --git a/test/test-config.rb b/test/test-config.rb index bdfe6b0..e5de97e 100644 --- a/test/test-config.rb +++ b/test/test-config.rb @@ -38,7 +38,7 @@ class ConfigTest < Stormy::Test::Case def test_method_missing_get # (none yet) - # assert_equal defaults['demo_project_id'], @config.demo_project_id + # assert_equal defaults['foo_bar'], @config.foo_bar end def test_method_missing_get_default diff --git a/views/account.erb b/views/account.erb index dd2735a..e4713e0 100644 --- a/views/account.erb +++ b/views/account.erb @@ -1,65 +1,82 @@ -<h2 class="section-heading top">Account</h2> - <%== flash_message %> -<table id="account"> - <tr> - <th>First name</th> - <td><span id="first_name" class="editable"><%= @account.first_name %></span></td> - <td rowspan="4" class="edit-instructions"> - ← click to edit - </td> - </tr> - <tr> - <th>Last name</th> - <td><span id="last_name" class="editable"><%= @account.last_name %></span></td> - </tr> - <tr> - <th>Email</th> - <td> - <span id="email" class="editable-json"><%= @account.email %></span> - <span id="email-verified" class="verified <%= @account.email_verified? ? '' : 'hidden' %>">✓ Verified</span> - </td> - </tr> - <tr> - <th>Phone</th> - <td> - <span id="phone" class="editable"><%= @account.phone %></span> - </td> - </tr> -</table> +<div class="container"> + <div class="content"> -<p class="indented"><a href="#" id="change-password-link">Change my password</a></p> + <div class="row"> + <div class="fields span6"> + <h2>Your Account</h2> -<form action="/account/password" method="post" id="change-password-form"> -<table id="change-password"> - <tr> - <th><label for="old-password">Current password</label></th> - <td><input type="password" id="old-password" name="old-password" placeholder="Current password"></td> - </tr> - <tr> - <th><label for="new-password">New password</label></th> - <td><input type="password" id="new-password" name="new-password" placeholder="Secret"></td> - </tr> - <tr> - <th><label for="password-confirmation">Confirm</label></th> - <td><input type="password" id="password-confirmation" name="password-confirmation" placeholder="Again"></td> - </tr> - <tr> - <th></th> - <td align="right"> - <input type="submit" id="change-password-button" value="Change My Password"> - <img class="spinner" src="/images/spinner.gif"> - </td> - </tr> -</table> -</form> + <div class="clearfix"> + <p> + <strong>First name</strong> + <br> + <span id="first_name" class="editable"><%= @account.first_name %></span> + </p> + </div> -<p id="password-changed" class="indented">Password changed!</p> + <div class="clearfix"> + <p> + <strong>Last name</strong> + <br> + <span id="last_name" class="editable"><%= @account.last_name %></span> + </p> + </div> -<div id="email-verification" class="indented <%= @account.email_verified? ? 'hidden' : '' %>"> - <hr> - <p id="unverified-email" class="unverified">Your email address is unverified.</p> - <p><a href="#" id="send-email-verification">Send verification email</a></p> - <p id="sending-email-verification"><img src="/images/spinner.gif"> Sending...</p> + <div class="clearfix"> + <p> + <strong>Phone</strong> + <br> + <span id="phone" class="editable"><%= @account.phone %></span> + </p> + </div> + + <div class="clearfix"> + <span id="email-verified" class="verified <%= @account.email_verified? ? '' : 'hidden' %>">✓ Verified</span> + <p> + <strong>Email</strong> + <br> + <span id="email" class="editable-json"><%= @account.email %></span> + </p> + </div> + + <div id="email-verification" class="clearfix <%= @account.email_verified? ? 'hidden' : '' %>"> + <p id="unverified-email" class="unverified">Your email address is unverified.</p> + <p><button id="send-email-verification" class="btn">Send verification email</button></p> + <p id="sending-email-verification" class="hidden"><img src="/images/spinner.gif"> Sending...</p> + </div> + + </div> <!-- fields --> + + <div class="fields span6"> + <hr class="separator"> + + <h2>Password</h2> + + <form action="/account/password" method="post" id="change-password-form"> + <fieldset> + <div class="clearfix"> + <label for="old-password">Current password</label> + <input type="password" id="old-password" name="old-password" placeholder="Current password"> + </div> + <div class="clearfix"> + <label for="new-password">New password</label> + <input type="password" id="new-password" name="new-password" placeholder="Secret"> + </div> + <div class="clearfix"> + <label for="password-confirmation">Confirm</label> + <input type="password" id="password-confirmation" name="password-confirmation" placeholder="Again"> + </div> + <div class="clearfix"> + <input type="submit" id="change-password-button" class="btn" value="Change my password"> + <span id="change-password-spinner" class="hidden"><img class="spinner" src="/images/spinner.gif"> Changing...</span> + </div> + <p id="password-changed" class="notice hidden">Password changed!</p> + </fieldset> + </form> + + </div> <!-- fields --> + </div> <!-- row --> + + </div> </div> diff --git a/views/admin/accounts.erb b/views/admin/accounts.erb index eba9fdf..1d72b90 100644 --- a/views/admin/accounts.erb +++ b/views/admin/accounts.erb @@ -4,7 +4,6 @@ <th>Name</th> <th>Email</th> <th>Phone</th> - <th>Projects</th> </tr> <% for account in @accounts %> @@ -12,7 +11,6 @@ <td class="name"><a href="/admin/account/<%= account.email %>"><%= account.name %></a></td> <td><%= account.email %></td> <td><%= account.phone %></td> - <td><%= account.count_projects %></td> </tr> <% end %> </table> diff --git a/views/admin/admins.erb b/views/admin/admins.erb deleted file mode 100644 index 63bb771..0000000 --- a/views/admin/admins.erb +++ /dev/null @@ -1,44 +0,0 @@ -<p>Listing <%= @admins.length %> admin accounts</p> - -<table id="accounts" width="90%"> - <tr> - <th>Name</th> - <th>Email</th> - <th>Actions</th> - </tr> - - <% for admin in @admins %> - <tr> - <td class="name"><%= admin.name %></td> - <td><%= admin.email %></td> - <td><a href="/admin/admins/<%= admin.id %>/delete">Delete</a></td> - </tr> - <% end %> -</table> - -<h2>Add an admin</h2> -<form method="post"> - <table> - <tr> - <th>Name</th> - <td><input type="text" name="name" size="30" value="<%= @fields['name'] %>"></td> - </tr> - <tr> - <th>Email</th> - <td><input type="email" name="email" size="30" value="<%= @fields['email'] %>"></td> - </tr> - <tr> - <th>Password</th> - <td><input type="password" name="password" size="30"></td> - </tr> - <tr> - <th>Confirm</th> - <td><input type="password" name="password_confirmation" size="30"></td> - </tr> - <tr> - <td colspan="2" align="right"> - <input type="submit" value="Add admin"> - </td> - </tr> - </table> -</form> diff --git a/views/admin/layout.erb b/views/admin/layout.erb deleted file mode 100644 index 24075be..0000000 --- a/views/admin/layout.erb +++ /dev/null @@ -1,48 +0,0 @@ -<!doctype html> -<html lang="en"> - -<head> - <title><%= @page_title %> - Stormy Weather Admin - - - <% if @page_styles %> - <% for url in @page_styles %> - - <% end %> - <% end %> - - - - -

    <%= @page_title %>

    - -<% if current_admin %> -
    - Signed in as <%= current_admin.name %>. - Sign Out -
    - Change password -
    -
    - -<%== flash_message %> - - -<% end %> - -
    - <%== yield %> -
    - -<% for url in scripts %> - -<% end %> - - - diff --git a/views/admin/project.erb b/views/admin/project.erb deleted file mode 100644 index 723433a..0000000 --- a/views/admin/project.erb +++ /dev/null @@ -1,45 +0,0 @@ -

    << Projects

    - - - - - - - - - - - - - - - - - - - <% if @project.funded? %> - - - - - <% end %> - <% if @project.fizzled? %> - - - - - <% end %> -
    ID<%= @project.id %>
    Owner<%= @project.account.name %>
    Name<%= @project.name %>
    Created<%= format_date(Time.at(@project.created_timestamp)) %>
    Funded<%= format_date(Time.at(@project.funded_timestamp)) %>
    Fizzled<%= format_date(Time.at(@project.fizzled_timestamp)) %>
    - -

    Actions

    -

    - Delete this project -

    - -

    Photos

    -
    -<% for url in @project.photo_urls %> - -
    -<% end %> -
    diff --git a/views/admin/projects.erb b/views/admin/projects.erb deleted file mode 100644 index 17861da..0000000 --- a/views/admin/projects.erb +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - <% for project in @projects %> - - - - - <% end %> -
    NameOwnerCreatedFizzledFunded
    <%= project.name %><%= project.account.name %><%= format_date(Time.at(project.created_timestamp)) %> - <%= project.fizzled? ? format_date(Time.at(project.fizzled_timestamp)) : '-' %> - <%= project.funded? ? format_date(Time.at(project.funded_timestamp)) : '-' %> -
    diff --git a/views/admin/sign-in.erb b/views/admin/sign-in.erb deleted file mode 100644 index 46869a9..0000000 --- a/views/admin/sign-in.erb +++ /dev/null @@ -1,27 +0,0 @@ -<%== flash_message %> - -
    - - - - - - - - - - - - - - - - - -
    - -
    - - Signing in... -
    -
    diff --git a/views/contact.erb b/views/contact.erb index 2ecb652..3bcbcc5 100644 --- a/views/contact.erb +++ b/views/contact.erb @@ -1,12 +1,12 @@
    -

    About Us

    +

    About Us

    Made of 100% pure awesome. #winning

    -

    Contact Us

    +

    Contact Us

    <%== flash_message %> @@ -23,28 +23,28 @@
    -

    Email

    +

    Email

    Contact us via email.

    - + - + - +
    Technical support:tech@example.comtech@example.comapult.com
    Accounting support:accounts@example.comaccounts@example.comapult.com
    General inquiries:info@example.cominfo@example.comapult.com
    -

    Address and Phone

    +

    Address and Phone

    Or keep it old school.

    diff --git a/views/edit-project.erb b/views/edit-project.erb deleted file mode 100644 index d7e4000..0000000 --- a/views/edit-project.erb +++ /dev/null @@ -1,80 +0,0 @@ -

    Project Info

    - -<%== flash_message %> - - - - -
    - - -
    - - -
    - - -

    - - Saving... -

    - - - - - - - - -
    - -
    - - -

    Photos

    - - - -
    -
      - <% for photo in @project.photos %> -
    • - -
      - remove -
    • - <% end %> - -
    • - - - -
      - add photo - -
    • -
    -

    Drag and drop photos to change their order.

    -
    - -

    - - Saving... -

    - -
    - - diff --git a/views/email/error-notification.erb b/views/email/error-notification.erb index 2c9bfb1..30daaa4 100644 --- a/views/email/error-notification.erb +++ b/views/email/error-notification.erb @@ -8,21 +8,11 @@

    session: <%= session.inspect %>

    -<% if admin %> -

    Admin: <%= admin.name %> <<%= admin.email %>>

    -
    <%= admin.field_array %>
    -<% end %> - <% if account %>

    Account: <%= account.name %> <<%= account.email %>>

    <%= account.field_array %>
    <% end %> -<% if project %> -

    Project: <%= project.id %> (<%= project.name %>)

    -
    <%= project.field_array %>
    -<% end %> -
     <%= error.class %>: <%= error.message %>
     
    diff --git a/views/error.erb b/views/error.erb
    index 70e8174..1c20f05 100644
    --- a/views/error.erb
    +++ b/views/error.erb
    @@ -1,5 +1,5 @@
     
    -

    Oops

    +

    Oops

    diff --git a/views/faq.erb b/views/faq.erb index b59a439..b1c0e61 100644 --- a/views/faq.erb +++ b/views/faq.erb @@ -1,4 +1,4 @@ -

    Frequently Asked Questions

    +

    Frequently Asked Questions

    <%== @faq %> diff --git a/views/forgot-password.erb b/views/forgot-password.erb index 1864e52..0e5ea25 100644 --- a/views/forgot-password.erb +++ b/views/forgot-password.erb @@ -1,4 +1,4 @@ -

    Forgot Password

    +

    Forgot Password

    <%== flash_message %> diff --git a/views/layout.erb b/views/layout.erb index 769e4b1..6908241 100644 --- a/views/layout.erb +++ b/views/layout.erb @@ -3,9 +3,22 @@ - + + + - <%= @page_title ? @page_title + ' - ' : '' %>Stormy Weather + Stormy Weather<%= admin_page? ? ' Admin' : '' %><%= @page_title ? ' - ' + @page_title : '' %> + + + + + + + + + <% for url in stylesheets %> @@ -15,50 +28,87 @@ + + +<% if authorized? %>
    +<% end %> -
    - -
    + <% if breadcrumbs.size > 0 %> + + <% end %> - + <%== flash_message %> -
    - <%== yield %> -
    + <%== yield %> - + -
    +
    <% for url in scripts %> @@ -68,7 +118,7 @@ if (false) { var _gaq = _gaq || []; _gaq.push(['_setAccount', 'UA-XXXXXXXX-X']); - _gaq.push(['_setDomainName', 'example.com']); + _gaq.push(['_setDomainName', 'example.comapult.com']); _gaq.push(['_trackPageview']); (function() { diff --git a/views/not-found.erb b/views/not-found.erb index 1c73319..b84200a 100644 --- a/views/not-found.erb +++ b/views/not-found.erb @@ -1,15 +1,9 @@ -

    :(

    +

    :(

    Hmmm... We don't seem to have what you're looking for.

    - <% if authorized? %> - - <% else %> - - <% end %> - Ok fine, I'm outta here! - + Ok fine, I'm outta here!

    diff --git a/views/projects.erb b/views/projects.erb deleted file mode 100644 index 330dbe8..0000000 --- a/views/projects.erb +++ /dev/null @@ -1,22 +0,0 @@ -

    Projects

    - -<%== flash_message %> - -<% if @projects.empty? %> - -<% else %> - - - - - - <% first_project = true %> - <% @projects.each do |project| %> - - - - - <% first_project = false %> - <% end %> -
    NameCreated
    <%= project.name %><%= format_date(Time.at(project.created_timestamp)) %>
    -<% end %> diff --git a/views/reset-password.erb b/views/reset-password.erb index 6550586..35c3d3f 100644 --- a/views/reset-password.erb +++ b/views/reset-password.erb @@ -1,5 +1,5 @@ -

    Reset My Password

    +

    Reset My Password

    <%== flash_message %> diff --git a/views/sign-in.erb b/views/sign-in.erb index 6c19530..fc907d7 100644 --- a/views/sign-in.erb +++ b/views/sign-in.erb @@ -1,43 +1,40 @@ <%== flash_message %> -
    - +
    +
    +
    +
    - - - + +
    +
    + +
    +
    + +
    +
    + + +
    +
    + + Signing in... +
    +
    + - - - - + + + - - - - - - - - - - - - - - -
    - -
    - - -
    - - Signing in... -
    - Forgot your password? -
    +
    +

    Not a member yet? Sign Up! -

    - +

    +

    + Forgot your password? +

    +
    +
    diff --git a/views/sign-up.erb b/views/sign-up.erb index 8bf0a07..81f418c 100644 --- a/views/sign-up.erb +++ b/views/sign-up.erb @@ -1,5 +1,3 @@ -

    Please provide the following information in order to sign up.

    - <% if @errors %>